Let's stop checking in built assets and `dist/` to `master`.


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:

1. Why check in things that are generated anyway?
2. 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.
3. 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](http://docs.travis-ci.com/) on Github, so I add a `.travis.yml`:

```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](http://docs.travis-ci.com/user/encryption-keys/)

## Add your shell script for what to do

In my case, I would be adding `build_helpers/buildDistFromTravis.sh`, let's do that:

```sh
#!/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/