How to Hakyll CircleCI 2.0

Posted on

This post documents my CircleCI configuration that builds Hakyll site and publishes it to GitHub pages.

It is inspired by configurations found on the Internet.

Overview

Use FPComplete docker image

Docker is the simplest executor type on CircleCI.

This configuration reuses FPComplete’s image with stack to avoid custom installation scripts.

docker:
  - image: fpco/stack-build:lts

Cache compiled dependencies

The job is going to recompile all dependencies on every build because it is using clean docker image.

It takes around 20 minutes to build template Hakyll blog. With caching configuration building time drops to less than a minute.

- restore_cache:
    name: Restore Cached Dependencies
    keys:
      # find a cache for the same stack.yaml
      - stack-{{ .Branch }}-{{ checksum "stack.yaml" }}
      # when missing reuse from the same branch
      - stack-{{ .Branch }}-
      # when missing reuse the latest cache
      - stack-
- run:
    name: Resolve/Update Dependencies
    command: stack setup
    command: stack build --dependencies-only
- save_cache:
    name: Cache Dependencies
    key: stack-{{ .Branch }}-{{ checksum "stack.yaml" }}
    paths:
      - ~/.stack
      - ./.stack-work

Generate content

Builds site application and uses it to generate static content

- run:
    name: Build Site App
    command: stack build --pedantic
- run:
    name: Generate Static Site
    command: stack exec site build

Push _site content to GitHub pages

Here master branch is not used for version control but rather as production environment so it makes more sense to keep it clean and wipe previous site content by git push --force

- run:
    name: Publish GitHub Pages
    working_directory: './_site'
    command: |
      # initalize repo
      git init
      git config user.name  'CircleCI'
      git config user.email 'job@circleci.com'
      # add generated files
      git add .
      git commit -m "publish $CIRCLE_SHA1 [ci skip]"
      # push to pages branch
      git remote add origin "$CIRCLE_REPOSITORY_URL"
      git push --force origin master

Referrers