Last active
December 3, 2019 17:00
-
-
Save JoshCheek/91133b3703c10b135cd42c331f89e700 to your computer and use it in GitHub Desktop.
Trunk Based Development
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Trunk Based Development | |
======================= | |
Disclaimer: | |
I've never done this on a deployed flagship app at a job. | |
Words: | |
Continuous integration: all code is merged frequently (perhaps several times per day to once every few days) | |
Continuous delivery: the integrated code is delivered (tested and deployable) | |
Continuous deployment: the deliverable code is deployed (shipped) | |
Release: feature is available to users | |
What: | |
* Avoid long-lived branches | |
* Merge into trunk/master extremely frequently (ideally multiple times a day) | |
Why: Continuous integration | |
* Code doesn't diverge | |
* Risk is lower because everything works together always, rather than figuring out how to integrate some big branch | |
* Few/no merge conflicts | |
* Faster pace of iteration | |
* Not waiting on some viable code languishing in an unmerged branch | |
* Not scrambling to merge everything at the end of a sprint | |
* Implies ZDD because everything must always work (vs creating the new code and then trying to figure out how to deploy it later, once you begin thinking about integrating) | |
* Each logical piece of code is smaller (eg there shouldn't be 20 parallel lines of ancestry as you scroll through history) | |
* Avoid large languishing branches | |
How: | |
* Develop new behaviour side-by-side with the old behaviour | |
* Use feature flags to toggle between old and new behaviour | |
* Once the new behaviour is trusted and ready, flip the flag over | |
* Then remove the old behaviour and the flag | |
Constraints: | |
* Trust test suite | |
* Trust your colleagues | |
* Understand risks around your code and take appropriate precautions | |
* Keep tests green (avoid breaking the build, as that will halt deployment) | |
* Always be release ready (you can commit unfinished code as long as it can be released) | |
* Deploy either continuously or from tags on trunk/master or from branches off of master (https://trunkbaseddevelopment.com/branch-for-release/atscale.png) | |
* QA is about flipping the feature on (releasability, not deployability) | |
* Deployment needs to be inexpensive (ie automated, stable, and quick) | |
Implication: | |
* The branching exists in the code via the feature flags instead of in the branches | |
* Features being developed work together with preexisting code | |
* Shipped code does not need to be perfect until the flag's default is flipped to "on" | |
* Decouple database changes from the code that depends on them (basically the ZDD stuff) | |
Issues addressed: | |
* Commits that depend on commits that aren't merged | |
* Juggling branches | |
* Difficulty switching branches | |
* Fewer open tickets (less overhead) | |
* Smaller chunks of work (less risk, easier to code review) | |
* Feature flagging is useful in general (eg a/b testing, bandit testing, flipping problematic features off) | |
* Less need for everything to be perfect before merging (because cost of merging is lower) | |
* Decouples releasing a feature from deploying it (ie you can flip the feature on by changing the flag instead of by deploying) | |
* Can deploy old functionality and new functionality in tandem | |
* Turn features on on a specific date, or for subsets of users, or for QA | |
* Turn features back off if they go awry | |
* Batched deployments (GitHub's trains) | |
* Lack of discoverability (due to shipping the entire feature at the end, rather than allowing incremental exploration / experimentation throughout the development process) | |
Why branch at all? | |
* To facilitate code review | |
* Some companies choose pairing over code review and then directly merge into master (though broken builds become more costly) | |
* You could try to spike something destructive on a branch, but you would presumably not merge that back in | |
* Some changes may need to be large and atomic (eg a Rails upgrade may require many changes) | |
Examples: | |
* Google does trunk based development (with a monorepo) and ~35,000 devs | |
Monitor: | |
* Lead time (https://www.youtube.com/watch?v=aNgWjSAjjtg ~23:00) for each deploy, how long ago were the deployed commits made? | |
Talks: | |
* Https://www.youtube.com/watch?v=aNgWjSAjjtg | |
Proposal: | |
* Try it on an epic first and once it stabilizes, then expand it to everything | |
* Some tooling will likely need to be created or added (eg if feature flags are toggled on a per-user or per-request basis, then that context needs to be passed around, potentially to other services, potentially to a background job) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment