Hello! Today I will write about how to automate blog deployment using TravisCI with bash scripts.
When I first started writing blog using pelican my workflow look as follows:
After some time, I know that there must be the way to automate such boring stuff. So I started looking around my pelican folder and I found Makefile.
This makefile is used to manage all these things that I am doing manually into bash script so it is perfect!
Let's look into content of makefile, what is worth seeing is command devserver:
devserver:
ifdef PORT
$(BASEDIR)/develop_server.sh restart $(PORT)
else
$(BASEDIR)/develop_server.sh restart
endif
So whenever you specify $(PORT) or not the same command will be used: develop_server.sh restart. So what we have in restart?
elif [[ $1 == "restart" ]]; then
shut_down
start_up $port
and start_up:
1 function start_up(){
2 local port=$1
3 echo "Starting up Pelican and HTTP server"
4 shift
5 echo $PELICANOPTS
6 $PELICAN --debug --autoreload -r $INPUTDIR -o $OUTPUTDIR -s $CONFFILE $PELICANOPTS &
7 pelican_pid=$!
8 echo $pelican_pid > $PELICAN_PID
9 cd $OUTPUTDIR
10 $PY -m pelican.server $port &
11 srv_pid=$!
12 echo $srv_pid > $SRV_PID
13 cd $BASEDIR
14 sleep 1
15 if ! alive $pelican_pid ; then
16 echo "Pelican didn't start. Is the Pelican package installed?"
17 return 1
18 elif ! alive $srv_pid ; then
19 echo "The HTTP server didn't start. Is there another service using port" $port "?"
20 return 1
21 fi
22 echo 'Pelican and HTTP server processes now running in background.'
23 }
In line 6 is normal pelican command like:
pelican --debug --autoreload -r personal_blog/content -o personal_blog/output -s personal_blog/pelicanconf.py
Is is running pelican in debug mode with auto reload taking post content from personal_blog/content. It generate output to personal_blog/output with settings from personal_blog/pelicanconf.py.
After that script enters the $OUTPUTDIR and starts the pelican server by $PY -m pelican.server $port.
But what if I wanted to publish my work into GitHub Pages? There is command for that in Makefile
github: publish
ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
git push origin $(GITHUB_PAGES_BRANCH)
It is using ghp-import. Ghp-import is python application that allows pushing content to GitHub branches. Why is that important? The GitHub pages are organized in that way:
| Type of site | Page address | Publishing branch |
| User Pages site | username.github.io | master |
| Project Pages site owned by a user account | username.github.io/projectname | gh-pages |
Table taken from GitHub Pages help.
As you can see to publish content on GitHub Pages you have to push either to master and you can see is under krzysztofzuraw.github.io or to gh-pages and go to krzysztofzuraw.github.io/personal-blog. As I wanted building process of my blog to be automated I choose second option: on master I will have all settings and content that is be used to render HTML will be on gh-pages branch.
So to automate I need TravisCI. After connecting service to your GitHub account, let's enable it for given project:
And on the next screen enable repository for what you want to trigger Travis. After this click on wheel next to the name of the repo. In next page setup two environmental variables:
GH_TOKEN is your token generated from this page. Click there on Generate new token and in next screen make sure you add token description and scope for public_repo:
After generating token add it to Travis. The another variable in Travis TRAVIS_REPO_SLUG is in the form of username/project-name so in my case it was krzysztofzuraw/personal-blog. After setting up these variables add the following file .travis.yml to the main root of your pelican blog project with following content:
language: python
branches:
only:
- master
install:
- pip install pelican
- pip install ghp-import
- pip install pelican_gist
script:
- make publish github
It tells Travis to install pelican, ghp-import and pelican_gist (plugin for gists in pelican) and then it runs make publish github.
To make it work I need to change one thing in Makefile:
github: publish
ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
git push -fq https://${GH_TOKEN}@github.com/$(TRAVIS_REPO_SLUG).git $(GITHUB_PAGES_BRANCH)
The change is that I push to repo using GH_TOKEN not username so Travis is able to do it.
So right now when I push my commits to master branch the Travis starts building my blog!
Cover image by Manjith Kainickara under CC BY-SA 2.0.
Hello! Spring has come so I decided that I need to changes- so I change my blog engine to pelican.
This blog will be about small compassion between three static site generators and why I choose pelican.
What are static site generators?
Basically they are engines that generates web sites using only static content. So there is no need for any backend or database at all. Most of static site generators allow writing posts in markdown or rst formats.
When I started writing this blog I used a Nikola. What is it? It python powered static site generator. I has a lot of features 'out of the box':
I really enjoyed working with Nikola, but I changed it to another engine because I was overwhelmed by a lot of options that I don't need. Also community is not huge but it is very helpful.
Then I moved to Jekyll. This is ruby static site generator. What I like about jekyll is support for github pages. Also is the most popular static site generator with a lot of community and themes. What I don't like is it doesn't have support for tags out of the box. I know that it can be done by some ruby code, but I like this feature to be build in. Moreover while you 'upload' your entire catalog with jekyll configuration your custom plugins don't work. You have to stick to these provided in github.
So I decided to move to pelican. What I like so far is that I have some more freedom to customize engine than in nikola and I have out of the box support for tags. But there is thing: pelican only generates content. So you have to serve it somehow. To do this I run simple python server. I don't like this approach- I want it to be automatic. I will write next blog post about how to do this. Stay tuned!
Cover image by Manjith Kainickara under CC BY-SA 2.0.