What do you think of Continuous Deployment, where you push code to main and, if the tests pass, that code is automatically deployed to production?
I realized I've been running a whole bunch of my own smaller projects that way for several years now and I absolutely love it, and now default to it for everything I build
@simon Tried it, like it, have two teams building platforms for a large UK government department that treat continuous deployment as the paved path on which we encourage the rest of the organisation to walk.
@simon It Depends. If you’ve got a test suite you trust, and the tooling to handle database migrations and feature flagging it’s great. Ship early, ship often.
If you don’t have those things you’re in for a whole world of pain.
@simon Initially I did CD where we built all of the code (into containers) but it didn’t trigger the rollout until I manually approved. Over time that actually became a burden and it never actually stopped me from making a mistake (if the tests pass, I assume everything works, I wouldn’t magically find another bug). So now everything automatically rolls out on a merge to main. I love it!
@simon Depends:
- Stateful application with database migrations: I want manual deploys
- Stateless applications: Continous deployment can work!
- Modules published to eg npm: Want to reduce noise by batching into mindful batches through manual deploys
@simon at work, we have devel, testing, staging, stable branches for the critical stuff, and for non-critical stuff we'll do a PR to test changes (PRs also build packages that can be deployed easily to devices), and once we're happy it's merged and deploys to production automatically. But, yes, everything builds a new package of some sort, and once something merges into stable branch, it goes into production automatically.
@simon for the last couple of real products I've worked on, either (a) paying customers thought we were deploying too often *already* or (b) additional testing on Physical Hardware was needed before actual production, even after engineering signoff. (At least we had "all tests pass before you can land on main" anyway, there, but software-only tests weren't enough.)
@simon we even do it (to the closest approximation) for our iOS app at my day job. Trunk based dev and If it’s in main it will be in the store within in a couple of days.
@simon Great for small projects.
On very large scale projects you should still do it but decouple deployment from release; i.e. feature flags, canaries, rolling deploys, etc. Database migrations are Very Hard and we start to get into record versioning and checklists to ensure reverts are safe.
Medium size projects have all the problems, but do not justify the fancy tooling so 🤷🏻♂️?? I tentatively think staging envs are a waste of time but YMMV
@simon i had it while on an AWS team and it was amazing. i thought all teams should operate like that. since then, i’ve hated the open source tooling so much, i never want to see CD again…but it really was well done at Amazon
@simon yoloing things into production goes against everything i stand for today
im on team slow roll - gradual deployments done one at a time are the way to go usually
@simon yes, but not main. Main is the gathering point. Anything merged into main (without loud announcements in the dev channel) is ready to go to prod, where it is deployed from
@simon We do that on a number of systems in our team but with the important conditions that:
- All new code is via human-reviewed PRs
- All PRs tests (unit & E2E) must pass in an identical pre-live env
Only when both of those are true is it possible to merge and auto-deploy. (we run the same tests in pre-live and live deploys too as a double check in case anything changed between PR and merge).
@simon I can only imagine the flurry of replies this got. Personally, so long as you've done the work around safety (super fast unit tests, checks and balanced on db changes, invested heavily into feature flagging, invested heavily into deployment and rollback/canarying) it's the only way to fly with a team of more than a couple.
@simon Over the past few months we’ve been introducing a household-name retailer to this with a new project and they are astonished. “How long to we can see that in prod?” “Oh, about twenty minutes” “No, production” “Yes” “How?” (And on…)
@simon It Is The Way(tm)…. At least on the pure TDD projects I run. Projects containing legacy code (as per Michael Feathers’ definition), absolutely no way.
@simon it also somewhat depends on how risky deployments are. For a typical web app, sure, ship it. Currently I’m working on distributed embedded devices, where I’m not at the level of confidence I feel would be needed to do automated releases on push to the entire fleet.
For high stakes systems an alternative I've used that gives much of the benefits while avoiding any risk is Continous Deployment to a staging environment - that way every change is instantly available for manual testing but there's still a deliberate "go live" moment with an extra human in the loop
@simon a big old it depends, internal libraries, CD, applications to staging CD, external libraries, people like to have understandable change sets, so I often batch changes, CD to a beta tag though
@simon See, my experience is that a (dedicated) staging environment *feels* like it reduces risk, but actually increases it: you’re more likely to treat production as a pet, and batch up changes from fear, where spinning up dedicated test environments before merging changes (or, better still, blue-green deploying) actually tests for issues explicitly. But, I’ll grant, requires more trust in the process, as well as more process being built.
@simon we go commit, deploy to stage, automated smoke tests, deploy to production for most of our sites.
We have one that has a really long deploy time that might break things when the site is under heavy load. For this we make use of the circle ci manual approval feature, but that's mostly to prevent accidental deploys rather than for QA
@simon This is what we do where I work, and it seems like the most sensible choice. The convenience of deploying automatically is going to be completely offset by that one bug that gets deployed, which would have been caught if it had sat in the staging environment for a few days first.
@simon agreed. I like to use proper semver tagging for projects that want that go-live step, with automatic deployment of the new tag. So even the go-live is completely hands-off once you’ve done the tag.
@simon I have become a feature flag convert! Ship code behind a feature flag, such that the system doesn’t change upon deployment. Then, ramp feature flag to a small percentage of requests and compare metrics against the “control” group.
@simon $dayjob has better test coverage than many projects, but our QA pros still find bugs. Other issues include risk of deadlock deploying schema changes on a large and active database, and customers who dislike being surprised by unannounced changes, even if we do think they're improvements. But automatic deploy to staging (well, scheduled twice a day, plus more on demand when requested) has been a huge win.
@simon Yeah for my work I'd wish we had CD at least into a QA. And one button push each for pilot/live. With very small increments and a fix forward approach by default (but rollback on button push available in rarer cases - though that might just be a git revert usually)
@stevemarshall yeah, I totally buy that. I think the staging environment option is good for when the test suite for an older system just isn't thorough enough to be trustworthy
@simon @stevemarshall the one time I worked on a system that had explicitly designed for a staging system for testing purposes had then (before my time there) also spun out testing, qa, qa2, qa3, etc, all of which showing subtle differences, all of which gave little confidence when a prod deploy happened such that manual QA had to happen AGAIN anyway
@simon Even then, I’d push for not having “a staging environment” and instead spinning up a new environment for each pull request. So instead of one staging environment, one per change. Does require the ability to spin up and tear down environments, though, and confidence that they won’t cost the earth.