Delivery, Observability, and Rollback Loop
Practical 17 - Delivery, Observability, and Rollback Loop
Related: Chapter 17 · Lecture slides · Appendix C: Production Deployment Checklist
Objective
Design, execute, and rehearse an automated, safe front-end delivery and operational loop. Rather than treating deployment as an unverified “push to production” or assuming that passing tests guarantee operational safety, you will construct a delivery pipeline that:
- Builds an immutable, content-hashed artifact tied to an exact Git commit SHA.
- Enforces strict CI verification gates, including automated secret scanning and bundle size budgets.
- Injects immutable release identity metadata to correlate runtime client telemetry.
- Instruments a PII-safe client-side observability collector that captures unhandled exceptions, Core Web Vitals, and user interaction breadcrumbs.
- Executes a simulated production incident and rollback rehearsal, verifying that reverting the deployed static assets does not break local client state compatibility or corrupt backend data contracts.
Workspace Setup
Initialize a modern delivery sandbox using Vite, TypeScript, and a lightweight local static web server to simulate CDN and edge environments:
Stage-by-Stage Implementation
Stage 1: Immutable Reproducible Artifact & Manifest Generation
In continuous delivery, you must build once and promote the exact same artifact across preview, staging, and production environments. Never rebuild assets from source for each separate environment.
- Configure Content-Hashed Asset Bundling (
vite.config.ts): Ensure all JavaScript, CSS, and asset filenames include cryptographic content hashes ([name].[hash].js). This guarantees that older versions can remain cached indefinitely on the CDN without cache collisions during rolling deployments. - Generate
release-manifest.jsonat Build Time: Write a build hook inscripts/generate-manifest.jsthat records:releaseId: The Git commit hash (or simulated semantic release identifier, e.g.v2.4.0-a9f3c1).buildTimestamp: ISO 8601 UTC timestamp.environment: Target tier (preview,staging, orproduction).entrypointChunk: The exact hashed path of the primary entry bundle (assets/index-a9f3c1b8.js).bundleSizes: File size breakdown to detect unexpected code bloat.
Stage 2: Automated CI Verification & Secret Scanning
A reliable delivery pipeline halts before publishing if code violates quality gates or leaks private security credentials.
- Implement Bundle Budget Enforcement (
scripts/check-budget.js): Read the compiled output indist/assets/. If total uncompressed JavaScript exceeds 200 KB, fail the build with an actionable error. - Pre-Commit Secret Scanning Gate (
scripts/scan-secrets.js): Front-end client bundles are public to the entire internet. Write an automated scan regex that searches all source files and environment files (.env*) for:- Private keys (
BEGIN PRIVATE KEY,AWS_SECRET_ACCESS_KEY). - Unprefixed environment variables. Only variables explicitly prefixed with
VITE_PUBLIC_orNEXT_PUBLIC_may be included in client bundles. - Ensure that if an engineer attempts to commit a database password or private stripe key, the CI check exits with code 1.
- Private keys (
Stage 3: Preview Environments & Release Identity Injection
To diagnose production issues without guessing which code version a user is running, embed immutable release identity metadata directly into the client runtime.
- Inject Runtime Release Metadata (
src/config/release.ts): Expose an immutable global object onwindow.__RELEASE_INFO__containing the release version, commit SHA, and environment name. - Private Source Map Handling:
Configure Vite to generate source maps (
sourcemap: "hidden"). The.mapfiles are generated on disk for upload to a secure, private error-tracking server (e.g., Sentry), but the//# sourceMappingURL=comment is stripped from the public bundle. This allows on-call engineers to read de-minified stack traces without exposing proprietary code to the public web.
Stage 4: Client Observability, Telemetry & PII Masking
Server logs only capture HTTP requests that successfully reach the backend; they cannot detect client runtime crashes, syntax errors, or UI thread freezes.
Implement a lightweight, zero-dependency client telemetry module (src/observability/telemetry.ts):
- Global Unhandled Error Capture:
Listen to
window.onerrorandwindow.onunhandledrejection. Extract the error name, message, stack trace, and active route. - User Interaction Breadcrumbs: Maintain a ring buffer of the last 15 user actions (clicks on buttons, route changes, API request start/finish markers) to reconstruct user journeys leading up to a crash.
- Data Minimization & PII Redaction:
Before beaconing any error payload, scrub:
- Form inputs with
type="password", name"card", or name"nationalId". - Query parameter tokens (e.g.
?token=...,?key=...).
- Form inputs with
- Resilient Beaconing:
Transmit telemetry using
navigator.sendBeacon("/api/telemetry/errors", JSON.stringify(payload)), ensuring messages are delivered even if the user immediately closes the browser tab.
Stage 5: Simulated Disaster Rehearsal & Safe Rollback
A rollback plan that has never been tested is not a rollback plan - it is wishful thinking. In this stage, you will rehearse a full incident recovery cycle:
- Inject a Fatal Production Regression into v2.4:
In
src/pages/ApplicationForm.ts, inject a syntax or runtime exception that triggers when users click “Submit Application” (e.g. invoking an undefined function or invalid regular expression). - Observe the Canary Failure:
Simulate user traffic hitting the deployed application. Verify that client telemetry records the error spike, tags it with
v2.4.0-a9f3c1, and captures the relevant breadcrumb trail. - Execute the Rollback:
Trigger the rollback script (
scripts/rollback.shor local routing switch) to point the edge web server back to the v2.3.0 directory. - Data Compatibility Verification:
Verify what a “successful rollback” actually means:
- Artifact Rollback vs Data Compatibility: Confirm that users who loaded v2.4 did not have their local client state (
localStorage['app_draft']) corrupted into an unparseable schema that crashes v2.3. - API Schema Backwards-Compatibility: Confirm that any pending backend requests sent by v2.4 can still be processed or cleanly rejected without breaking v2.3 client sessions.
- Artifact Rollback vs Data Compatibility: Confirm that users who loaded v2.4 did not have their local client state (
- Draft a Blameless Post-Mortem: Document the incident timeline: Time to Detect (TTD), Time to Mitigate (TTM), root cause, and preventative CI gate additions.
Verification & Self-Assessment
Run your delivery verification battery:
Observable Verification Criteria
| Verification Item | Action | Expected Pass Output |
|---|---|---|
| Reproducible Artifact | Inspect dist/ | All asset files contain content hashes; release-manifest.json matches commit SHA |
| Secret Scanning | Inject dummy private key into source and run scanner | CI build aborts with exit code 1; identifies file and offending line |
| Bundle Budget | Run scripts/check-budget.js | Confirms JavaScript bundle size is within the 200 KB threshold |
| Telemetry PII Scrubbing | Submit form with email and password, inspect telemetry payload | Password and token fields are completely redacted ([REDACTED]) |
| Rehearsed Rollback | Execute rollback script | Traffic reverts to previous release in under 60 seconds; no local client crashes |
| Appendix C Audit | Cross-reference Appendix C Checklist | All Section 1 (Build Integrity) and Section 5 (Observability) items checked |
Grading Rubric
| Criterion | Points | Evaluation Requirement |
|---|---|---|
| Artifact Reproducibility | 20% | Production bundle uses immutable content hashes; generates complete release-manifest.json. |
| CI Gates & Secret Scanning | 20% | CI pipeline enforces type checks, bundle budgets, and blocks leaked private credentials. |
| Release Identity & Source Maps | 20% | Injects window.__RELEASE_INFO__; source maps are generated for private server upload without public leakage. |
| Client Observability & PII Safety | 20% | Global error handlers capture exceptions and breadcrumbs via sendBeacon; scrubs PII before transmission. |
| Incident Rehearsal & Rollback | 20% | Simulates production incident, executes rollback, validates localStorage schema compatibility, and writes post-mortem. |