This is my preferred workflow on software projects. It likely isn’t a universal fit for all shapes and sizes but in my experience this or variants of it have worked well for me. This is just a slightly more opinionated version of Github Flow.
- Remove steps Keep thing simple. Complicated or even semi-complicated workflows attempting to “fix” perceived risks may just end up complicating matters by making the surface area for erring even larger. Also the more complicated the process, the greater the risk of dampened collaboration.
- Automate steps Do not waste time policing that rules are remembered and followed correctly. We’re human. What can go wrong will go wrong. Murphy told us that. Use tooling to stop thinking about this.
- Standardize along the cow path Use a simple approach that covers vast majority of cases. Edge cases ought to live in case-by-case procedures, rather than diluting the central pathway.
- Superset of a battle-tested pattern popularized by Github
- Avoids not-invented-here syndrome.
- Avoids unruly surprises for new engineers to your organization with contemporary expectations while at the same time equipping juniors to quickly redeploy in-house knowledge to the field.
- Can be used for repos both internal and open-source repos
- Aligns with the trend toward smaller teams working on smaller repos in microservice architectures.
- Makes developers happy.
- Encourages small quality changes since they’re easy to make. If change is laborious expect to see less of it and/or in larger batches. A poorly written documentation paragraph, a promiscuous function signature, a missing test case, a dependency upgrade, a refactor, … these sorts of things could be dissuaded by complexity and/or may more often be batched into unrelated pull-requests.
Master as base branch
- Aligns with tooling defaults (for example
- Makes it practically impossible to not know which brach to pull-request too for the vast majority of cases.
- Makes it so there is only one branch to protect (excepting the odd and few version branches).
- Enables a clean git history where it counts most.
- Reverting bad features becomes trivial.
- Is enforceable via tooling therefore automatically guaranteeing that mainline history will never become dirty (not-withstanding bad data entry at PR UI when merging)
- Frees developers to work quickly in their branch without wasted brain cycles about how inconsequential detail will affect mainline history. Nice commits still matter and they should be honed to make PRs easier to understand. But these two points don’t need to be mutually exclusive.
- Encourages PRs to be small, focused, releasable units of change which they need to be for a scalable and successful PR workflow anyways. This is behaviour the workflow should reinforce wherever possible.
- Individual commit history is still maintained on the PR itself for future auditing.
One level of branching
- Aligns with continuous delivery workflows where work should constantly be going to production on
- Makes it possible to use repo settings to automatically enforce repo settings. I have seen cases where the PR merge style used to mainline versus another branch type like releases had different policies. There is no way to enforce that on Github however so you end up with more complex branches with less guarantee.
Automate flow with natural cues
- Close issues automatically when PR merged ref.
- Automatically keep references to PR in commit message. PR contains the various feature branch commits unsquashed.
- Describe the semver effect in commit message to automate changelog later.
Originally published at blog.jasonkuhrt.com.