Git is a great tool which enables teams to work together and deploy code, but it's not all happiness and ponies. What if you need to deploy a single hotfix into your prod build, without pushing in any more of the code that has been written since your last depoy? How can you roll back to an older version of your code? What if you want to deploy all the changes that exist in staging to production but the environments are so far apart at this point merging code is scary. With the right git flow this is a breeze, but with the wrong git flow this can be a nightmare, or my life for the past couple years.
In this post I will assume that you at least have a basic understanding of how git works, if not you can get a quick git tutorial.
A very slimmed down and common issue we used to run into is, we have our main development branch and a staging branch that updates the site our client can see. We are doing all our work in master and then every so often make merges into staging with all the changes so the client can see the updates. Then inevitably someone makes a minor hotfix change into staging so now master and staging have different code in them. Now we're ready to deploy all staging code to live, so now we need to pull our staging code into our production branch. But now what happens to that staging hotfix that happened, that's now gone in master and you're going to lose it your next deploy unless you cherry pick that back in. A visual representation of what you've made is this.
A simple tool you can use to follow along or learn more of how git works, and what I've used to generate these git screenshots is here https://git-school.github.io/visualizing-git
We don't need to get too into the weeds about all the weird things and issues you can run into with git, I'm sure you've encountered them before. We at Code Koalas have moved all of our ongoing projects to follow the flow of, master branch, feature branches off a master, rebase your branch before merging and releases for staging and production are tags on master. It's as simple as that!
Here is the step by step process of the normal git flow you'd follow for everyday use.
- Pull down latest code on
master
- Check out your new branch
- We follow a format where branch names should include the ticket number in them.
CK-204
- We follow a format where branch names should include the ticket number in them.
- Do all your work.
- Git add your code with a good commit message also including the ticket number
CK-204: added new feature
- Check out
master
branch and pull latest code - Go back to your branch and
rebase
it off latestmaster
git rebase -i master
- Push up your code
- Make a merge request into
master
squashing commits if it is really just one feature change and closing out your branch on merge acceptance
This flow helps your merge request from having phantom line adds or extra code you don't need. Also rebasing it means you will resolve all the conflicts locally before you push it up.
Great now you're ready to deploy this code to your staging environment, all you do is either create a tag based off master locally or in your remove git software (gitlab, github or whatever) and call it RC-v1.0.0
or whatever your version number is. We then have pipelines that build based off tags and if rc-*
it will build and deploy to staging.
Deploying to production is the same as for staging. If everything in master needs to go live great, create a tag but this time call it release-v1.0.0
and same as before it auto deploys. If you only need a couple changes based off the last release or rc you will follow our hot fix flow which takes a previous tag and add just the commits you actually want.
- Create a branch off the tag you want to base this new tag off of.
- If it's a hot fix grab the last full release then we will just add the few extra lines needed.
- You then pull in the code you need into that branch
- You could make a hotfix based off that branch and merge it in, then rebase it off master and merge it to master.
- You could cherry pick in just all the new commits that have happened into master and add those in. That's the good part about putting ticket numbers in your commit messages.
- Then create your new tag based off this branch.
- If it's a hotfix we do the same release tag we based it off of but add -hotfix-1
- That code will deploy based off the pipeline and tags.
That's really it, it's really simple but has made deploying code to prod no longer scary. It's cleaned up the difference between environments so getting your code into staging then into production isn't painful. Most importantly for us it's allowed us to have multiple features being built at the same time and putting one on pause and being able to deploy one of those features and not the other.