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.