Software staging clusters only grow. As production accrues more services, staging’s costs ramp up. And maintaining a single, massive, production-like staging may no
longer be the right answer. But several, small staging clusters—each fit for their purpose—offers
a more maintainable, cheaper alternative. Each reason for having a staging cluster requires a different level
of “production-likeness” to fit its use. You could put Apache and PHP on raspberry pi and call it Wikipedia’s
“staging.” And that’d be a fine place to demo a MediaWiki patch. But to be
confident deploying that patch into Wikipedia’s production: (to
paraphrase “Jaws” 🦈): you’re gonna need a bigger staging . In the 1970s, the pasta sauce brand Ragu tasked the psychophysicist
Howard Moskowitz with finding the perfect pasta sauce.1 Moskowitz concluded the perfect pasta sauce doesn’t exist—it depends
on each individual’s wants and needs. There is no perfect pasta
sauce; there are only perfect pasta sauces. Howard’s work is why you’ll find Ragu
Old World Style® next to Ragu
Chunky Garden Vegetable next to 10s of other Ragus. And much like pasta sauce2: there can be no
perfect staging; only perfect stagings. The requirements for a staging cluster depend on its use. Staging is a trade-off: resources (money, people, time) against
asymptotically approaching actual production. The closer you get to production, the higher the costs and
complexity. Setting up a staging server should be easy. If it is
not easy, you already have a problem in your infrastructure, you just
don’t know it yet – Patrick McKenzie 🐉, Staging
Servers, Source Control & Deploy Workflows, And Other Stuff Nobody
Teaches You Configuration management should make it easy to rebuild production
from scratch. Otherwise, you’ve got a disaster in the offing. This creates an environment suitable for demos and end-to-end test
automation. But organizations are evolving away from using pre-production staging
to build deployment confidence. They’ve replaced their high-cost staging with a mix of canary
deployments and advanced feature
flagging. Small environments with narrow scope—like testing or demoing—seem
like a reasonable trade-off of cost vs. benefit. But using pre-production staging as insurance for your
deployments—requiring snapshots of production data and maybe even
replayed traffic—seems too. darn. expensive. This is an anecdote related by
Malcolm Gladwell in a 2007 Ted Talk, “Choice,
Happiness, and Spaghetti Sauce↩︎ There’s a joke here about “spaghetti
code” that I’m too lazy to find.↩︎ github is a perfectly fine hosting site, and it does a number of
other things well too, but merges is not one of those things. Git possesses parts of a decent software
forge. When git was developed by the Linux kernel community, they already
had bug tracking, documentation, and a mailing list, so (unlike fossil)
git has none of those things. Enter GitHub. It uses “issues” for bug tracking and discussion, and
its code browser is unrivaled. But for all of its features, GitHub implements only a subset of git.
For instance, GitHub lacks the default merge strategy of git—the
fast-forward merge. And after some pondering I realized there’s a good reason for that:
it’s a cop-out. I want clean history, but that really means (a) clean and (b)
history. Git log will always suck for someone. An eternal war rages between team “git log should be clean” vs. team
“git log should have an accurate history.” If a branch can be fast-forwarded, But if a branch has conflicts, you’ll need to fix them and create a
merge commit to say what you did—team history. Sometimes there’s a merge commit; sometimes not: Madness. When you mash “merge” in GitHub it never executes plain
And sussing out what git command it will run is kafkaesque. I spent
some time mapping all the checkboxes and merge strategies into something
you could type into bash. There is a distinction between
By not using the “merge if necessary” strategy of
This is a contrived example of a “criss-cross
merge”↩︎ In GitLab this is “Merge Commit with
Semi-linear history” which seems like a nicer UI vs the buried option to
“Require linear history”. This option mitigates some of the pain of an
ugly git log.↩︎🍝 There is no perfect staging; there are only perfect stagings
💱 Staging trades cost vs. production-likeness
🔁 Production should be reproducable
📚 Further reading
git log
can be clean or accurate, not both
git merge --no-ff
* (refs/heads/B)
* * Merge 'C' into 'B'
* |\
* | | * (refs/heads/C -- git revert B8)
* | | * Merge 'B' into 'C'
* | |/|
* | |/
* |/|
* * | B8
* | * C3
* |/
* * A (refs/heads/A)
git merge --ff-only
or
git rebase && git merge
(extreme clean freaks add
the --squash
option)git log
is easy to read,
git revert
requires no thought.Why is
git merge
bad?git merge
opted out.git merge
sticks the
commits on the end of the branch and never tells you there was a
merge—team clean.What does GitHub do?
git merge
.
command
GitHub
Alignment
git merge
not implemented
¯\_(ツ)_/¯
git merge --ff-only
not implemented
✨ Team Clean
git rebase && git merge --ff-only
Rebase and Merge
✨ Team Clean
git merge --no-ff
Create a merge commit
📚 Team History
git merge --squash --ff-only BRANCH
Squash and merge
✨ Team Clean
git merge --is-ancestor && git merge --no-ff
Create a merge commit + Require
linear history
✨ Team Clean2
git rebase && git merge --ff-only
and
git merge --ff-only
. Rebasing modifies the commit—you end
up with a different SHA1.git merge
, GitHub forces you to choose a side in the
eternal war. And that’s a good thing.
Posted
Posted