๐ Delivery Practices a Software Team Actually Needs
Initial thoughts - 1. Why best practices matter? The outcomes - 2. Non-technical practices - the baseline - 3. Technical practices - the baseline - Version control for everything that ships - Peer code review - CI per feature branch - Modern testing strategy (trophy, test data, TDD) - Environment per feature branch - Documentation-as-code per branch - Continuous delivery (always releasable + automated deploy) - Monitoring and observability - Security shifted left - Simple design, refactoring, and managed debt - 4. Non-technical practices - elite - 5. Technical practices - elite - 6. Where to start (solo vs team) - Wrapping up - Further reading Continuous deployment is not a Netflix cosplay. It is a stack of practices that make shipping to production so routine it becomes boring. We map that stack along two axes: non-technical vs technical, and baseline vs elite - product habits first, elite last, because elite is not a universal target. Initial thoughts Most teams do not fail because they lack a manifesto on the wall. They fail because the advice arrives unsorted: microservices before CI is green, trunk-based theatre before anyone trusts the test suite, a "DevOps transformation" that is mostly a Slack channel named #ops-please-help . We organize practices the way high-performing delivery research does - product / lean / culture on one side, technical capabilities on the other - and we present them non-technical first, then technical, each split into baseline (what makes frequent deploys reachable) vs elite (what removes the remaining friction). Non-technical habits prevail: a perfect pipeline shipping the wrong thing is still waste. Elite practices come last because they are not a universal target - most teams get more from a boring baseline than from canary theatre on a flaky suite. A team of one (AI made that shape ordinary) can skip pairing, generative collaboration, and most of elite. It does not skip small batches, user feedback, WIP, or the technical baseline. Peer review without a peer means the pipeline is the other reviewer - the model does not join the on-call rotation. Evidence (DORA, craft, agile) supports the stack; it is not the pitch. The pitch is boring production: short lead time, frequent deploys, failures that are rare and recoverable, without heroics on Friday night. Each practice below: a short why, then concrete moves. 1. Why best practices matter? The outcomes You do not need elite labels on a slide. You need outcomes that speak to two audiences at once - the team doing the work, and the people holding the budget. The DORA research frames this as a win/win: the same practices that make delivery faster also make it calmer and cheaper. "Boring production" is the shorthand - short lead time, frequent deploys, failures that are rare and recoverable, without heroics on Friday night. Concretely, four outcomes describe that picture: - Changes reach production in hours or days, not months. - Deploys are routine - pipeline or one click, same artifact across environments. - Failures are uncommon and recovery is practiced, not invented under adrenaline. - Deploy (technical) and release (product) can be decoupled when needed. For the business, those four translate into the language decision-makers actually use: - Time-to-market: shorter lead time means ideas reach users faster - competitive advantage, not a quarterly slide. - Financial savings: fewer failed changes and faster recovery mean less rework, less incident cost, less overtime billed to a budget line someone watches. - Wellbeing: a generative, blameless culture with sustainable pace is not a perk - it is a delivery lever. Hero cultures are leading indicators of outages and resignations. Those outcomes are exactly what throughput and stability metrics try to capture. If you want numbers on a GitLab project, we once published GitLab: A Python Script Calculating DORA Metrics - useful as a mirror, not as a religion. Practices are inputs, and management does not buy inputs. A slide about trunk-based development will not move a CFO; "we cut lead time from three weeks to two days, halved our change-failure rate, and the on-call rotation stopped being a resignation letter" might. The whole stack below exists to make those outcomes move - and to keep them moving after the next reorg, not just for the one-quarter spike that earns a LinkedIn post. 2. Non-technical practices - the baseline Technical excellence ships the wrong thing beautifully if product and team habits are absent. These baseline habits do not require a VP of Transformation - and they come first for a reason. Small batches Slice work so feedback arrives while memory is fresh. Working in small batches is a product/process discipline as much as a git habit. Concrete: - Prefer MRs reviewable in under an hour. - Split stories by user-visible outcome, not by layer ("all the SQL this sprint"). - If a change needs a three-page risk essay, it was already too big last Tuesday. - Ship thin vertical slices; thicken later. Stakeholder and user feedback Early feedback tops almost every agile success list for a reason: without users in the loop, CD accelerates waste. Concrete: - Demo or expose something to a real user every iteration - even internal users count. - Keep a product owner / domain expert reachable within the sprint, not "next quarter." - Write backlog items as outcomes, not as technical chores in disguise. - Kill features nobody uses - the backlog is not a museum. Continuous improvement and WIP limits Retros without experiments are group therapy. WIP limits make queues visible. Concrete: - One process experiment per sprint, with a success check. - Cap WIP on the board; stop starting, start finishing. - Time-box spikes so research does not drift. - Track aging work items; anything older than a sprint deserves a decision: finish, cut, or kill. Generative collaboration High-trust, high-information-flow culture - Westrum's generative type - predicts delivery performance better than tool brand loyalty. Concrete: - Blameless postmortems; fix the system, not the person who typed the command. - Shared responsibility for quality and production of what you build. - Make asking for help cheaper than hiding (pairing budget, public channels). - Leaders say "I was wrong" in public. Culture is what happens after the slide deck leaves the room. Pairing and knowledge transfer Pairing is a social practice with technical side effects: fewer bus factors, faster onboarding, better reviews. Concrete: - Pair on unfamiliar or high-risk areas. - Rotate ownership so no module is a single-human crypt. - Write short ADRs when the why would otherwise leave with someone's badge. - Budget pairing time explicitly - "when we have time" means never. 3. Technical practices - the baseline This is where a solo developer (or a small team) gets the most impact per hour invested - once small batches and feedback are not actively sabotaging the loop. Version control for everything that ships If it can break production, it belongs in version control: app code, pipelines, infra-as-code, config that is not a secret, release notes next to the code they describe. Concrete: - Ban direct pushes to the default branch. - Put pipeline definitions in the repo; review them like product code. - Tag or record every production deploy so "what is live?" is a git question. - Secrets stay in a vault - version references, not the passwords themselves. (Dave's USB stick is not a HA strategy.) Peer code review The cheapest early defect filter we still have, and a knowledge pump. Seniors should not be the only reviewers - we argued that at length in Every Developer Should Review Code - Not Just Seniors. Concrete: - Every change to the default branch goes through a merge request. - Same-day review SLA; large MRs are a process failure, not a badge of honor. - Review for behavior, risk, and clarity - not semicolon theology. - Require at least one human approval; bots are assistants, not scapegoats. CI per feature branch Integrating only on main means the whole team pays for one person's surprise. A pipeline on every feature branch keeps the shared line green and leaves breakage with the author. Concrete: - Run build + tests on every MR / branch push. - Aim for feedback in minutes, not hours. - Fix red pipelines before starting new work. - Keep the default branch protected and green - broken main is a team-wide tax. Modern testing strategy (trophy, test data, TDD) "Automated tests" is too vague. Prefer a modern testing strategy: a testing trophy bias (static checks + many integration tests + fewer brittle E2E), managed test data, and TDD where design benefits. Concrete: - Agree the trophy shape for your stack; write mostly tests that give confidence without a flaky UI circus. - Gate merge on fast, trusted suites; keep E2E thin and stable. - Quarantine flaky tests within 48 hours - mute-and-forget turns green into fiction. - Provide disposable, seeded test data; never depend on a shared "QA database" that three teams mutate like a commons pasture. - Use TDD for new behavior and tricky logic: failing test โ minimal code โ refactor. Skip TDD on throwaway spikes. Environment per feature branch A green unit suite is not the same as "this feature works in a real stack." A green pipeline on main tells you the code integrates; it tells you nothing about whether the new endpoint actually answers in a real browser, against a real database, next to the other half-merged features of the sprint. An environment per branch (or ephemeral preview) closes that gap before merge - it turns "works on my machine" into "works on a machine that looks like prod," without a calendar invite. Concrete: - Deploy each long-lived feature branch to an isolated URL / namespace. - Use it for manual checks and a few targeted E2E runs. - Tear environments down automatically - zombie previews are how cloud bills invent folklore. - Prefer the same deploy path as production, with smaller
Comments
No comments yet. Start the discussion.