Post

Git hooks: automatic assemble and publish your Jekyll Blog site on push command

In this article, I will do an overview on how to apply git hook logic to automatically build and publish in background Jekyll Blog site once git push command is triggered.

Git Hooks is a powerful mechanism that allows to include additional logic to basic git operations, i.e. validation, enrichment of commit objects. Multiple add-ons can perform verification, for example, to make sure that you have not committed AWS credentials in your code repository. Other add-ons are doing verification that license is present in the code, etc. Hooks mechanism can be operated on both sides - git client and the server. Each side has its limitations in supported actions. The detailed list of git hooks with explanation is available on git official site

Once I have completed adding the article into my Blog - it is formatted and verified locally, I want to publish these changes and deploy them into github-pages.

First, I have prepared Makefile with different targets that are doing a build of my Jekyll blog, cleanup of _site directory and publish to www my Blog. And I was calling this Makefile targets from CLI, like make run or make publish when I wanted to run Jekyll locally or publish changes to www.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Makefile
...
publish: build
	$(call colorecho,"Publishing the site to $(GITHUB_PAGES_REPO)")
	cd $(BUILD_DIR) && \
	git init && \
	git remote add origin $(GITHUB_PAGES_REPO) && \
	git add . && \
	git commit -m "PUBLISH BLOG VER: $(COMMIT_HASH)" && \
	git push -f -u origin main \

build: clean
	$(call colorecho, "Building _site content...")
	JEKYLL_ENV=production bundle exec jekyll build
...

Please note that I’m including .env file into Makefile. File .env contains extracted properties in a single location, they are referenced in Makefile, for example, $(COMMIT_HASH)

Due to My Blog is under git version control system, I noticed that publish to www is done almost after git push command: I’m doing local changes in the article or blog configuration with a group of local commits. Once these changes have passed verification locally I’m doing git push to the remote repo and also publishing to WWW. So I decided that publish to WWW will be maintained automatically by git hooks.

Hooks are located in .git/hooks directory

1
2
3
4
5
$ ls -l
-rwxr-xr-x   1 rtsypuk  staff   58 Dec 23 08:09 commit-msg
-rwxr-xr-x   1 rtsypuk  staff   58 Dec 23 08:09 pre-commit
-rwxr-xr-x   1 rtsypuk  staff  166 Dec 25 10:23 pre-push
-rwxr-xr-x   1 rtsypuk  staff   66 Dec 23 08:09 prepare-commit-msg

These files should have permission for execution.

Now we added pre-push git hook that triggers Makefile publish target. export TERM=’xterm’ line is added to allow git hooks be triggered from IntelliJIDEA UI (it does not propagate TERM variable and causes hook failure at the current release)

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

export TERM='xterm'

echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

echo Triggering pre-push hook to deploy Jekyll Blog
make publish

With this chain I have set up the following flow: on git push command of my changeset to a remote repository, pre-push hook will build the Jekyll bundle and upload _site folder with compiled html content data to my repository that is represented as personal github-pages.

sequenceDiagram
    participant BE as BlogEditor
    participant LG as LocalGit
    participant MF as MakeFile
    participant RG as RemotelGit
    participant RGP as RemotelGitHubPages
    autonumber
    Note right of BE: Let's add a new blog post!
    loop Editing the blog
        BE->>BE: Add blog post edit
        BE->>LG: git commit
    end
    Note right of LG: Post is ready to publish!
    LG-->>RG: push changes to remote git origin
    LG->>LG: invokes pre-push hook
    LG->>MF: build blog
    MF->>MF: compile blog locally
    MF->>RGP: git push to GitHub pages repo latest compiled blog version
    RGP-->>RGP: autoredeploy static hosting content
    Note right of RGP: Latest version is live!

Now there is no need to trigger additional action. I’m working in interactive actions by committing each mutation in configuration or the code in the local repository and these actions are not published. Only git push operation is hooked and performs Jekyll Deploy to www in background.

And I enjoy this “Blog-as-a-Code” approach.

This post is licensed under CC BY 4.0 by the author.