CI Checks & Rollback Safety Nets: Guarding Live Deployments | Darshil
Darshil walks through two GitHub Actions workflows guarding a live medical diagnosis app: an automatic CI check that can only warn, and a manual, double-guarded rollback that switches Cloud Run traffic back to a known-good image.
Darshil walks through two GitHub Actions workflows built to guard a live medical diagnosis application: one that checks every pull request automatically, and one that undoes a bad deployment on command. The video is a plain account of what each workflow actually catches, and just as importantly, where each one's authority stops.
What the CI pipeline actually runs
The CI workflow fires automatically whenever a pull request is opened or updated against dev, stage, or master, no push trigger, no manual button, nothing for a person to remember. It runs four steps in order: check out the PR's exact code, install Node 20, run a locked npm ci install, then lint. Lint is set to continue-on-error on purpose, since a style warning should not block the pipeline the way a real failure should. The last two steps are stricter: run the Vitest suite covering the diagnosis-merging logic and token storage, and build the same Vite build that produces the real bundle, which is not continue-on-error, a failing test or a failing build fails the whole job.
The limit of a red X
Darshil is direct about what CI cannot do: it can show a red X on a pull request, but it cannot stop the merge button from being clicked. Real enforcement needs GitHub's paid branch-protection feature, and the org's free plan only allows that on public repos, not an option here, since the codebase touches patient diagnosis logic. He demonstrates this directly on PR-2: a test assertion is deliberately changed to something obviously wrong. Checkout, node install, and lint all pass; the test step fails at about 20 seconds; a red X lands on the PR. The merge button stays clickable. It is a warning, not a block.
The rollback pipeline: a deliberate, manual decision
Because CI catches a bug before merge but does nothing once something bad is already live, a second workflow handles rollback: switching a running environment back to a version that already worked, without rebuilding anything. Unlike CI's automatic PR trigger, or the deploy workflow's automatic tag trigger, rollback only runs when someone deliberately clicks a button and supplies two inputs, which environment, and the exact version tag to restore. That friction is intentional; a rollback is a decision, never an accident.
Two guards before anything happens
Before touching the running environment, the workflow checks that the version tag actually matches the chosen environment: dev only accepts dev tags, stage only accepts stage tags, master only accepts bare version tags. Pick dev but type a stage tag by mistake, and it stops immediately with a clear error instead of rolling back the wrong environment. The second guard looks up the exact image tag in Artifact Registry before deploying anything, a typo like dev0.01 instead of dev-0.0.1 fails here, loudly, rather than partway through an actual deployment to a live service. Only after both guards pass does it run the same gcloud run deploy command the deploy workflow uses, pointed at the old image instead of a freshly built one, which is why it finishes much faster than a real deploy.
Key takeaways
- CI runs automatically on every pull request but can only warn, the free-tier plan cannot block a merge on a private repo.
- The CI pipeline's steps, in order: checkout, Node install, lint (continue-on-error), Vitest, Vite build (both blocking).
- Rollback only runs when a person deliberately triggers it with an environment and a version tag.
- Guard one checks the tag matches the environment; guard two checks the exact image exists in Artifact Registry.
- Rollback repoints Cloud Run traffic to an existing image rather than rebuilding, which is why it is fast.
Who this is for
Engineers maintaining a live service on a limited GitHub plan who need to understand exactly what automated checks protect against, and why a separate, deliberately manual rollback path is what actually recovers from a bad deploy.
Chapters
- 0:00Introduction to the CI and rollback pipelines
- 0:15CI pipeline steps: Node setup, linting, Vitest, and compiler builds
- 0:35The limits of GitHub's free-tier branch protection
- 0:50Real failure walkthrough on PR-2
- 1:05The Rollback pipeline: Why rollbacks are deliberate, manual decisions
- 1:20Double-guard validation: Environment tag matching and Artifact Registry lookups
- 1:40Rapid Cloud Run target switching without rebuilding the container
- 1:55Summary: Pairing automatic warnings with manual, strict rollbacks
Full transcript(auto-generated, with timestamps)
Introduction to the CI and rollback pipelines
[0:00]Habari, this is Darell. Two more workflows now guard Meta's aggregation front end. One that checks every pull request automatically. The other that undoes a bad deploy on command. Here's what each one actually catches and where each one's authority stops. Start with when CI even runs. It fires on a pull
CI pipeline steps: Node setup, linting, Vitest, and compiler builds
[0:17]Request into dev stage or master opened or updated. No push trigger, no manual button. Nobody has to remember to run it. GitHub does it the moment a PR exists. Four steps in in order. Pull down the PR's exact code. Install node 20. Run npmi for a locked reproducible install. Then lint. Lint is set to
The limits of GitHub's free-tier branch protection
[0:36]Continue on error on purpose. A style warning shouldn't block the pipeline the way a real failure should. The last two steps are different. Run tests vitist covering the diagnosis merging logic in the O token storage. And this one is not continue on error. A failing test fails
Real failure walkthrough on PR-2
[0:51]The whole job. Then build the same vite build that produces the real bundle. a final check that the app still compiles, not just passes tests. Here's the limit worth knowing. CI can show a red X on a PR. It cannot stop the merge button from
The Rollback pipeline: Why rollbacks are deliberate, manual decisions
[1:05]Being clicked. Real enforcement needs GitHub's paid branch protection feature and this org's free plan only allows that on public repo is not an option here given the codebase touches patient diagnosis logic. Proved it directly on PR-2. One test assertion was
Double-guard validation: Environment tag matching and Artifact Registry lookups
[1:20]Deliberately changed to something obviously wrong. CI ran checkout node install and lint all passed then run tests failed at about 20 seconds and a red X landed on the PR. The merge button still clickable. Just a yellow warning, not a block. CI catches a bug before merge. It does nothing once something bad is already live. For that, a second
Rapid Cloud Run target switching without rebuilding the container
[1:40]Workflow, roll back switch a running environment back to a version that already worked without rebuilding anything. Unlike CI's automatic PR trigger or deploys automatic tag trigger, roll back runs only when someone deliberately clicks a button. It asks for two inputs, which environment
Summary: Pairing automatic warnings with manual, strict rollbacks
[1:56]And the exact version tag to restore. That's on purpose. A roll back is a decision, never an accident. Before touching anything, it checks the version tag actually matches the chosen environment. Dev only accepts dev tags. Stage only, stage v master only a bare v. Pick dev, but type a stage tag by mistake and it stops right here with a clear error instead of rolling back the wrong environment. Second guard, it looks up the exact image tag in artifact registry before deploying anything. A typo like dev0.01 instead of dev 0 0.1 fails here, loudly, not partway through an actual deployment to a live service. Only after both guards pass does it actually act the same G-Cloud run deploy used by the deploy workflow, pointed at the old image instead of a freshly built one. Cloud Run creates a new revision and routes live traffic to it, typically finishing much faster than a real deploy since nothing gets rebuilt. End to end.
A person clicks run workflow picks the environment and version. The inputs get validated. The image gets verified and only then does cloud run get repointed. Every step before the actual deploy exists to catch a mistake before it reaches a live doctoring service. So two workflows two different jobs. CI runs on every PR automatically and can only warn someone still has to look at the check before merging. Roll back runs only when a person deliberately triggers it and only after two separate guards pass. automatic and lenient paired with manual and strict that pairing is the actual safety net, not either one alone. Your turn. If your own pipeline has a check that only warns instead of blocking, look for whether a manual undo path exists, too. If a test can fail and still let emerge through, a guarded roll back workflow is what actually protects the live service, not the check by itself. Continuous integration and roll back. This is Darel.
More from Humanitarians AI Fellows
4:00Darshil Explains: Building a Tag-Based CI/CD Pipeline on Google Cloud
1:59How to Log Your Week with AI (Recap vs Highlight Reel) | Agrima
2:24Testing Gordy: Running a 5-Stage AI Tool Review | Yatra
4:04How AI is Quietly Saving Small Nonprofit Teams | Agrima
2:49The AI Saturation Crisis on LinkedIn | Yatra Rawat
2:12