It seems common practice to have a staging and production branches for deploying your code. A common pattern is to push (or pull request) to these branches, then merge the changes. Then, some system watching this branch will notice, and deploy to the appropriate environment. (Another way this is done is with tags, but I will not get into it here.)
For us it is slightly different. At least for one of our projects we have multiple deployments, where each can be on a different environment. In addition, it is useful to have multiple staging environments for use by our R&D and product teams, and multiple “pre-production” environments for use by our lab team. So we have staging, staging2, staging3, and lab, lab2, and possibly soon lab3 as well.
One problem with merging to deploy, is that merges create a new commit ID. Rebases are even worse in that regard. When I’m deploying version 1.5 to staging2, I definitely don’t want to change version 1.5, and I want the commit ID to be identical to the one in the version 1.5 branch. When you merge, you accrue merge commits, that are different between various deployments.
So our solution to these problems:
- All deployment branches are named deploy/ENV_NAME, e.g. deploy/lab or deploy/staging.
- In order to deploy say, release/release1.5 to deploy/staging, we follow the following instructions:
- Find out the the commit hash of the last commit of the branch to be deployed. You can do this in the Github UI by switching to this branch, or run something like:
git log origin/release/release1.5 --pretty=%H -1
git push -f origin COMMIT_HASH:deploy/staging
This last command is the interesting one. It tells git to have the deploy/staging branch on origin to point to COMMIT_HASH. This is incredibly useful – with this all your deployments of a given version will have exactly the same hash, which will easy version tracking.
The downside is that our git history doesn’t reflect deployment history – but that’s ok – it shouldn’t. It should only reflect only the code history. Deployment history is kept by our deployment software – in our case Jenkins.
I’m interested in learning of more deployment strategies. How do your deployment environment look like? Are you SaaS with a single production? Cloud based with dedicated servers per customers? On premise? What deployment approach works for you?