Setting up a Pelican Blog on Github Pages with Travis-CI using MacOS High Sierra

Posted by Sergio Lopez on Thu 22 March 2018 in tutorials

Intro

Setting up this blog was not a difficult task, but it did some digging around the internet to get everything up and running the way my brother and I visioned our blog. I'm going to document the steps I followed from start to finish, combined from all those resources, so that anyone wanting to setup something similar can do so!

Configure Mac High Sierra 10.13

Bash profile setup

First thing is to make sure that we update the PATH to ensure that any Homebrew installations take precedence over stock macOS binaries.

Open your .bash_profile using:

$ vim ~/.bash_profile

then add:

# Ensure user-installed binaries take precedence
export PATH=/usr/local/share/python:$PATH
# Load .bashrc if it exists
test -f ~/.bashrc && source ~/.bashrc

Type :wq to write and save the .bash_profile

To have the directives take effect in the current session, without a restart needed. Type the following

$ source ~/.bash_profile

Homebrew Install

Homebrew allows you to install stuff you need, quick and easy, that Apple didn't.

To install paste the following in the terminal:

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Run the following:

$ brew doctor

To ensure that it installed correctly and see if anything needs to be addressed

Python Install

Now that Homebrew is installed, we can use it to install Python 2.7

$ brew install python@2

Now, check what pythons are found on your OSX by typing:

$ which -a python

There should be one python found at /usr/bin/ (the Apple python) and one at /usr/local/bin/ which is the Homebrew python.

$ which python

will show you, which python is found first in your $PATH and will be executed when you invoke python.

Virtualenv Install

When you're working on python projects, you might run into the scenario where one project requires a specific version of a package and another project could require a newer version of that package. Now this could cause an issue if they were all installed globally, in order to get around that I recommend we install Virtualenv

$ pip2 install virtualenv

Once that is installed, we should create a directory to store our virtual environments.

$ mkdir -p ~/Virtualenvs

Restricting Pip to Virtual Environments

To ensure that pip will not install a package in global but only if a virtual environment is active, we need to create/update the pip configuration file.

$ mkdir -p ~/Library/Application\ Support/pip

We’ll then open Pip’s configuration file

$ vim ~/Library/Application\ Support/pip/pip.conf

add the following lines:

[install]
require-virtualenv = true

[uninstall]
require-virtualenv = true

Create Pelican Virtual Environment

With our MacOS configured we can now install pelican. First we create the virtual environment:

$ cd ~/Virtualenvs
$ virtualenv pelican

and activate it via:

$ cd pelican
$ source bin/activate

Install pelican using pip2:

$ pip2 install pelican markdown typogrify

Setting up GitHub Pages

To create a Github user page, make sure you're logged into github and create and initialize two new repositories:

yourusername.github.blog and yourusername.github.io

The yourusername.github.blog repository will hold the source code of the blog and the yourusername.github.io repository will hold the output HTML files that pelican generates.

Next, you'll clone your yourusername.github.blog branch into your projects folder, if you don't have one. Go ahead and create one.

$ mkdir -p ~/Projects/
$ cd ~/Projects/
$ git clone https://github.com/yourusername/yourusername.github.blog.git

Setting up Pelican

Once Pelican has been installed, and your repositories are set up, you can create a skeleton project via the pelican-quickstart command. First we need to switch to the directory of our project.

$ cd ~/Projects/yourusername.github.blog

initiate pelican using the command:

$ pelican-quickstart

It should ask you a series of questions:

$ Where do you want to create your new web site? [.] ./
$ What will be the title of this web site? blog
$ Who will be the author of this web site? Your Name
$ What will be the default language of this web site? [pt] en
$ Do you want to specify a URL prefix? e.g., http://example.com   (Y/n) n
$ Do you want to enable article pagination? (Y/n) y
$ How many articles per page do you want? [10] 10
$ What is your time zone? 
$ Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y 
$ Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) n
$ Do you want to upload your website using FTP? (y/N) n
$ Do you want to upload your website using SSH? (y/N) n
$ Do you want to upload your website using Dropbox? (y/N) n
$ Do you want to upload your website using S3? (y/N) n
$ Do you want to upload your website using Rackspace Cloud Files? (y/N) n
$ Do you want to upload your website using GitHub Pages? (y/N) y
$ Is this your personal page (yourusername.github.io)? (y/N) y
Done. Your new project is available at /home/yourusername/yourusername.github.io

Picking a theme

The next step is to pick a theme for the blog, we can use this site Pelican Themes to see live examples of themes.

Once a theme is picked you need create a submodule of the theme you want. Clone the pelican-themes repository into a submodule of yourusername.github.blog. For this example, I'm using the Flexi :

$ git submodule add git@github.com:alexandrevicenzi/Flex.git Flex
$ git submodule init
$ git submodule update

Now you should have your pelican-themes repository stored at ~/Projects/yourusername.github.blog/Flex. To use one of the themes, edit your Pelican settings file pelicanconf.py to include this line:

THEME = "./Flex"

Save the changes and regenerate your site by using the make command

$ make devserver

Which will simultaneously run Pelican in regeneration mode as well as serve the output at http://localhost:8000. Once you are done viewing your changes, you should stop the development server via:

$ make stopserver

Add Custom Domain to Blog

To use a custom domain with GitHub Pages, you need to put the domain of your site (e.g., blog.example.com) inside a CNAME file at the root of your site. To do this, create the content/extra/ directory and add a CNAME file to it. Then use the STATIC_PATHS setting to tell Pelican to copy this file to your output directory. For example:

STATIC_PATHS = ['images', 'extra/CNAME']
EXTRA_PATH_METADATA = {'extra/CNAME': {'path': 'CNAME'},}

Setting up Apex domain DNS

You can set up an apex domain through your DNS provider and GitHub Pages' servers will automatically create redirects between them. For example, your site can be found at www.example.com or example.com.

  1. Contact your DNS provider for detailed instructions on how to set up A records.

  2. Follow your DNS provider's instructions to create two A records that point your custom domain to the following IP addresses:

    192.30.252.153

    192.30.252.154

  3. To confirm that your DNS record is set up correctly, use the dig command with your custom domain. Using a custom domain as an example:

$ dig +noall +answer example.com
 example.com.   73  IN  A 192.30.252.153
 example.com.   73  IN  A 192.30.252.154

Setting up GitHub Actions

Instead of using Travis CI, we recommend using GitHub Actions for CI/CD. GitHub Actions integrates seamlessly with your GitHub repository and allows you to automate the deployment of your Pelican blog.

Create a GitHub Actions Workflow

  1. Create a .github/workflows directory in your repository if it doesn't already exist.
  2. Inside this directory, create a file named deploy.yml with the following content:
name: Deploy Pelican Blog
on:
  push:
    branches:
      - master

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Build the site
        run: make html

      - name: Pushes to another repository
        uses: cpina/github-action-push-to-another-repository@main
        env:
          SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
        with:
          source-directory: 'output'
          destination-github-username: ${ secrets.GITHUB_USERNAME }
          destination-repository-name: ${ secrets.GITHUB_REPO }
          user-email: ${ secrets.GITHUB_EMAIL }
          target-branch: main

Explanation of the Workflow

  • Trigger: The workflow runs whenever there is a push to the master branch.
  • Steps:
  • Check out repository: Clones the repository to the runner.
  • Set up Python: Installs Python 3.9 on the runner.
  • Install dependencies: Installs the required Python packages listed in requirements.txt.
  • Build the site: Runs the make html command to generate the static site files.
  • Deploy to GitHub Pages: Uses the peaceiris/actions-gh-pages action to deploy the generated files in the output directory to the gh-pages branch.

Update Your requirements.txt

Ensure your requirements.txt includes the necessary dependencies:

pelican
Markdown
typogrify
fabric

Remove Travis CI Configuration

If you were previously using Travis CI, remove the .travis.yml file and any related scripts (e.g., deploy.sh) from your repository.


With GitHub Actions, your blog will automatically deploy to GitHub Pages whenever you push changes to the master branch. This setup is simpler and more integrated than using Travis CI.

References

Below are a list of links or other guides that have helped me get to this point.

https://hackercodex.com/guide/mac-development-configuration/

https://hackercodex.com/guide/python-development-environment-on-mac-osx/

https://superuser.com/questions/915810/pip-not-working-on-hombrew-python-2-7-install

http://docs.getpelican.com/en/3.6.3/install.html

https://github.com/getpelican/pelican-themes

https://git-scm.com/docs/gitmodules

https://github.com/getpelican/pelican/blob/master/docs/tips.rst

https://help.github.com/articles/using-a-custom-domain-with-github-pages/

https://zonca.github.io/2013/09/automatically-build-pelican-and-publish-to-github-pages.html

https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/

https://docs.travis-ci.com/user/github-oauth-scopes