on master help sign in
hakyll/web/tutorials/github-pages-tutorial.md
181 lines 5.6 kB history raw
1---
2title: Using Hakyll with GitHub Pages
3author: Erik Stevenson
4type: article
5---
7## Introduction
9[GitHub Pages](http://pages.github.com) has become a popular static website hosting solution due to its simplicity. Simply push a couple files to a repository and it's off to the races.
11Working with Hakyll on a GitHub Pages-hosted website is complicated slightly due to Hakyll outputting files to a ```_site``` subdirectory, our desire to have the source code as well as the compiled site stored in a single repository, and our desire to automate it.
13This guide will walkthrough the creation and setup of a GitHub site that has two independent branches.
151. ```master``` - This is where your site lives. It's what you see when you go to ```https://<your repo>.github.io```. This branch *needs* to be called master.
162. ```develop``` - This is where your website's source is. That's all your Haskell code, your posts and templates, etc, and it's where you do work from. This name was chosen arbitrarily and can be freely substituted for any name of your choosing.
18When you're finished, you will be able to, with one command, refresh your website's contents and send any changes to your GitHub Page.
20In the interest of keeping this guide as simple as possible, I'll be making a few assumptions.
221. Haskell is being used with [Stack](http://docs.haskellstack.org/en/stable/README/).
232. Creating a user/organization site (vice a project site).
243. You haven't changed Hakyll's default output directory of '_site/'.
26These instructions should be easy to adapt for any situation though.
28## GitHub Setup
301. If required, create a new repository for your blog.
312. If required, create a ```master``` branch.
322. If applicable/desired, create/add to your repository any files that your site needs that will not be produced by your Hakyll project. For example, ```CNAME``` as outlined [here](https://help.github.com/articles/setting-up-your-pages-site-repository/).
333. Create a ```.gitignore``` file with at a minimum, the following entries:
35```
36_cache/
37_site/
38.stack-work/
39```
41## Local setup
431. If required, create a new Hakyll project. If you're a stack user, there is a Hakyll template available that makes this step easy.
45```stack new myblog hakyll-template```
472. Create a ```.gitignore``` file in your blog's directory with at a minimum, the same directories listed as in the GitHub repository.
483. Use the following git commands to setup your local repository.
50```
51git init
52# create new branch called develop and switch to it.
53git checkout -b develop
54# track all the source files for our blog.
55git add .
56# make our first commit
57git commit -m "initial commit."
58# and add the GitHub repository as a remote.
59git remote add origin <URL to your GitHub pages repository>
60```
62## Deployment
64So everything's all setup and we're ready to deploy.
66> **Note:** Performing the following commands from your ```develop``` branch is recommended since you will end up back in that branch at the end.
68Temporarily save any uncommitted changes that may exist in the current branch.
70```
71git stash
72```
74Ensure we are in the correct branch.
76```
77git checkout develop
78```
80Get a clean build of our site.
82```
83stack exec myblog clean
84stack exec myblog build
85```
87Update the local list of remote branches to ensure we're able to checkout the branch we want in the next step.
89```
90git fetch --all
91```
93Switch to the `master` branch.
95> **Note:** Checking out this branch does not overwrite the files that Hakyll just produced because we have '_site' listed in both .gitignore files.
97```
98git checkout -b master --track origin/master
99```
101Next, copy the freshly made contents of '_site' over the old ones.
103> **Note:** Deleting a file from your site's source will not remove it from your `master` repository if it has already been published. An alternative to `cp` is discussed at the end of this guide.
105```
106cp -a _site/. .
107```
109Commit our changes.
111```
112git add -A
113git commit -m "Publish."
114```
116And send them to GitHub.
118```
119git push origin master:master
120```
122Final clean up and return to the original state.
124```
125git checkout develop
126git branch -D master
127git stash pop
128```
130## Putting it all together
132Below is a complete listing of all the commands used to automate deployment to Github Pages. A `deployCommand` can be set as part of Hakyll's configuration options. More information and an example is provided [here](https://jaspervdj.be/hakyll/reference/Hakyll-Core-Configuration.html).
134```
135# Temporarily store uncommited changes
136git stash
138# Verify correct branch
139git checkout develop
141# Build new files
142stack exec myblog clean
143stack exec myblog build
145# Get previous files
146git fetch --all
147git checkout -b master --track origin/master
149# Overwrite existing files with new files
150cp -a _site/. .
152# Commit
153git add -A
154git commit -m "Publish."
156# Push
157git push origin master:master
159# Restoration
160git checkout develop
161git branch -D master
162git stash pop
163```
165*And that's it.*
167## Removing old files with `rsync`
169Earlier it was mentioned a flaw is that deleted files will persist in the published site until deleted manually. This is easily overcome by using `rsync` instead of `cp`.
171```
172rsync -a --filter='P _site/' \
173 --filter='P _cache/' \
174 --filter='P .git/' \
175 --filter='P .gitignore' \
176 --filter='P .stack-work' \
177 --delete-excluded \
178 _site/ .
179```
181The only drawback this approach has is the requirement that *every* file in your site "go through" Hakyll. Fortunately, in many cases this is not an issue.