Before going further, I’ll start by saying that I’m a Git and Github noob, so if you have a better solution to achieve the same goal, give me a shout, I’ll be happy to hear it..!
A few weeks ago, I implemented a small bookmarklet to apply google-code-prettify anywhere on the Web.
I put the source code on Github and used the (awesome) Automatic Page Generator to quickly create a landing page to host my bookmarklet.
The generated page lives on the same repository, on a branch called gh-pages
.
At this point, my concern was the following: How could I include the bookmarklet link on gh-pages
branch from the source code living on the master
?
Basic (handmade™) workflow
In a first try, I could just copy/paste the minified source into an <a href="...">
link in my index.html
.
But what happens if I update the source?
I’ll probably have to deal with that kind of work flow:
1 | grunt # lint, concat and minifies source |
Rather boring, right? Totally agree! And that’s why I decided to dig a little further to see how I could automate this.
Automate the whole thing!
Avoiding copy / paste
Copy/paste a file from a branch to another may be acceptable if you do it only once. From there, it’s probably better to use the following:
1 | git checkout gh-pages # checkout gh-pages branch |
Updating HTML content
As mentioned earlier, I already used grunt.js to lint, concat and minify my source on the master
branch.
So I searched for a way to use grunt to update the HTML link. I quickly found grunt-replace, perfect fit for the job.
I ended up with an HTML source file, with a placeholder for the bookmarklet:
1 | <a href='@@bookmarklet'>Prettify</a> |
And a simple grunt replace
task, reading the minified source and generating an up-to-date index.html
1 | grunt.initConfig({ |
Introducing Git Hooks
Basically, Git Hooks allow you to automatically run custom scripts at any step in your workflow.
Hooks must be defined in the .git/hooks/
folder.
Placeholder files are already created, giving a pretty good idea about what’s possible or not.
1 | $ ls .git/hooks/ |
You only need to remove the .sample
extension to define a hook, then edit the script to create your own awesome automation.
Bringing the pieces together
In my case, I created a post-commit
script. Right after every new commit on the master
branch, this piece of code runs and does all the crappy work.
1 |
|
As both master
and gh-pages
branches are modified, they both need to be pushed on the remote repository.
I use git push --all
, which is fine if you don’t have any other updated branch. Otherwise, you’ll need a specific push for each branch.
Going further
I’d like to find a way to stop the script if the commit doesn’t occur on the master
branch, but I’m not sure how to do it…
I’ll probably also add a pre-commit
hook to lint/concat/minify the source.
Grunt.js already simplified this to a one liner, but I often forget to call it before committing changes.
(Grunt + Git Hooks) appears to be a nice couple with a huge time-saving potential. I’d like to have an opportunity to try it on a larger project and see how it goes.
References
- Easily keep gh-pages in sync with master by Lea Verou
- Github Pages Workflow by by Oli Studholme
- Git post-commit hook to keep master and gh-pages branch in sync