This is something a lot of people still do in the name of simplicity or not requiring tooling on everyone's machines. A lot of projects still either add dist/
to .gitignore
or just prohibit users from checking in their changes to dist/
(that might arise from normal development or running a dist/
building script).
In other cases, built assets are checked in because some developers on your team might not have the necessary tooling installed on their machines. Why should Java developers have Node/IO.js installed on their machines? (i.e. if you're developing "monolithic" applications)
The main arguments I have against this:
- Why check in things that are generated anyway?
- Merge conflicts for minified/compressed files are stupid to resolve when rebasing/merging, because often you will just get blocked having to rebuild assets for no good reason.
- If you have normal merge conflicts to resolve, your effort to resolve them also includes building these assets and testing them again to see if they work.
Enough with the stupid intro, time to get to the how.
How
Add configuration for your CI tool
I use Travis on Github, so I add a .travis.yml
:
+script: bash build_helpers/buildDistFromTravis.sh
+env:
global:
- GH_REF: github.com/{{myusername}}/{{my-repo}}
- secure: {{encrypted key goes here}}
language: node_js
node_js:
- "0.10"
In Travis, you specify what script needs to be run by using the script
property. In this case, I am telling to run bash build_helpers/buildDistFromTravis.sh
.
See the Travis docs about adding encrypted keys
Add your shell script for what to do
In my case, I would be adding build_helpers/buildDistFromTravis.sh
, let's do that:
# !/bin/bash
set -e #Set errors to fail explicitly
# in Travis, the git version is 1.8.5, so we need to use rev-parse to get the name of the branch
branch_name="$(git rev-parse --abbrev-ref HEAD)"
# I only want to build and commit if I'm on master
if [ "$branch_name" == "master" ]
then
# build dist
npm run build-dist
# initialize and commit everything in pages
cd dist
git init
git config user.name "Travis"
git config user.email "Travis"
git add .
git commit -m "build dist assets and commit to dist"
# hide my output for security reasons
# force it because we want this to just actually work
# note, I'm pushing to a remote branch for the dist assets from master
git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:dist > /dev/null 2>&1
else
echo "Current branch is not master and dist will not be built or committed."
fi
Result
Simple enough, right? You can see how it worked out here:
My master branch: https://github.com/justinwoo/fixed-data-table/tree/master
My built dist branch: https://github.com/justinwoo/fixed-data-table/tree/dist
My Travis build logs: https://travis-ci.org/justinwoo/fixed-data-table/builds/49274669
With less than 10 minutes of work, we can get Travis to start building assets for our Github projects, and we can stop worrying about troubles we might run into with built asset conflicts and committing. Yay~
For tagged releases, you will probably want to still force adding your assets or publish them elsewhere, but this will work for our development process and for our edge asset users.
References
Domenic Denicola's original gist on auto-deploying to gh-pages with Travis: https://gist.github.com/domenic/ec8b0fc8ab45f39403dd
Travis docs about adding encrypted keys http://docs.travis-ci.com/user/encryption-keys/
Travis docs about customizing your builds: http://docs.travis-ci.com/user/customizing-the-build/