A release checklist should reduce uncertainty, not create a ritual. The right checklist changes with the risk of the release, but the categories remain stable: code, data, identity, dependencies, operations, artifact integrity, rollout, and recovery.
Use this guide as a release gate. Mark an item not applicable only when you can explain why it does not affect the system.
Establish the release boundary
Identify exactly what will ship:
- Immutable source commit
- Frontend and backend build identifiers
- Database migrations
- Desktop or mobile artifacts
- Infrastructure configuration
- Feature flags
- Third-party dashboard changes
Compare the release commit with the currently deployed commit. Reviewing only the final pull request misses changes merged earlier in the release window.
Record the intended user outcome and the highest-risk failure mode. If you cannot describe both, the release boundary is not ready.
Verify repository integrity
- The working tree used for the build is clean.
- The release branch has the expected upstream and no accidental divergence.
- Generated artifacts, local databases, and credential files are excluded.
- Lockfiles match manifests and were produced by the supported package manager.
- Submodules or workspace packages point to intended revisions.
- Version numbers are consistent across manifests, installers, and updater metadata.
- Release notes use the same commit range as the build.
Build from a fresh checkout in production mode at least once. Local development caches can conceal undeclared dependencies.
Run checks in increasing scope
Begin with fast, precise checks and move outward:
npm run typecheck
npm test
npm run build
Add the equivalent format, lint, integration, contract, and end-to-end commands for the project. Do not accept a green aggregate command without confirming that it actually discovered the expected tests.
For each suite, verify:
- The command exited successfully.
- The expected number of tests ran.
- No suite was silently skipped.
- Test data points at an isolated environment.
- Production-only code paths were included where relevant.
A build warning about a missing dependency, large client bundle, or incompatible runtime is release work, not post-release housekeeping.
Review public and privileged API boundaries
- Every input is validated by an allowlist schema.
- Authentication is enforced before protected work begins.
- Authorization checks the resource, not only the route.
- Rate limits protect registration, recovery, feedback, and expensive endpoints.
- Errors return stable public codes without stack traces or internal paths.
- CORS permits exact known origins and required headers only.
- Timeouts and cancellation exist for outbound requests.
- Webhooks verify raw payload signatures and reject stale timestamps.
- Retryable operations are idempotent.
- Logs redact authorization, cookies, credentials, and personal content.
Exercise both the successful request and at least one invalid, unauthorized, forbidden, conflict, rate-limited, dependency-failure, and timeout path for high-risk endpoints.
Validate authentication and account recovery
Authentication failures have a disproportionate impact because they block every paid workflow.
- Registration requires verified email ownership before sensitive use.
- Passwords use a memory-hard algorithm with current parameters.
- Existing password hashes upgrade safely after a successful login.
- Access tokens are short-lived and refresh tokens rotate.
- Refresh-token reuse revokes the affected session family.
- Web refresh tokens use
HttpOnly,Secure, and appropriateSameSitecookies. - Desktop refresh tokens use the operating system's credential vault.
- Password reset and email verification tokens are one-time and expire.
- OAuth uses state and PKCE, and callback destinations are allowlisted.
- Users can inspect and revoke sessions.
- Sensitive administrative actions require recent password confirmation.
Multi-factor authentication can be optional, but the system must not claim it is enforced when it is not. Security behavior should match the documented product promise.
Validate database changes
- The migration applies to a production-like schema.
- Constraints and indexes match query behavior.
- Existing rows receive safe values.
- Application deployment order is compatible with the schema transition.
- Long-running backfills are separated from request-time migration work.
- A recovery plan exists for partial application.
- Destructive changes have an explicit data-retention decision.
- Analytics retention matches the product policy.
Cloudflare D1 uses SQLite semantics, so verify foreign keys, supported SQL, batch behavior, and query plans in D1 rather than assuming another database behaves identically.
Do not test a destructive migration against the only copy of important data. Export or back up the database before a risky change.
Check secrets and configuration
- No
.envfile, credential, private key, token, or connection string is tracked. - Every required variable appears in
env.examplewithout a real value. - Production secrets are stored in the deployment platform's secret manager.
- Public variables contain no privileged material.
- OAuth redirect URIs match the deployed hosts exactly.
- Cookie domains and CORS origins share the intended site boundary.
- Webhook signing secrets are independent from API credentials.
- Encryption and signing keys have a documented rotation procedure.
Scan both the repository history range and the final artifact. Removing a secret from the latest file does not remove it from Git history or a source map.
Verify the user interface under stress
- Loading states do not block unrelated actions.
- Empty states explain the next useful action.
- Errors are specific, recoverable, and accessible.
- Optimistic updates reconcile with server failure.
- Forms prevent duplicate submission.
- Focus moves correctly in dialogs and errors are announced.
- Keyboard navigation reaches every essential action.
- Layouts work at narrow widths and high zoom.
- Slow network and offline states do not corrupt local data.
- Dates, currency, and pluralization use the correct locale.
Run a production build in a clean browser profile. Extensions and retained storage can hide consent, onboarding, and authentication defects.
Inspect performance and observability
- Client bundles are split at meaningful route boundaries.
- Initial pages avoid unnecessary client-side JavaScript.
- Large lists are paginated or virtualized.
- Database queries use the expected indexes.
- Outbound requests have bounded payloads and timeouts.
- Health endpoints separate process liveness from dependency readiness.
- Logs carry request identifiers without sensitive payloads.
- Metrics distinguish traffic, errors, latency, and business outcomes.
- Alerts point to an actionable owner and recovery step.
Analytics should collect enough context to answer product questions without collecting source code, diffs, query contents, request bodies, credentials, or full referrer URLs.
Verify release artifacts
For each distributable artifact, record:
- Platform and architecture
- Filename and format
- Byte size
- SHA-256 checksum
- Code-signing or updater signature
- Storage key and public download behavior
- Minimum supported version
Download the artifact through the same public path a customer will use. Install or unpack that copy, verify its version, and run a smoke test. Testing a local build directory does not verify upload integrity, routing, or CDN behavior.
Prepare rollout and rollback
Define a rollout owner, start time, observation window, and stop condition. A useful stop condition is measurable: error rate, failed authentication, checkout failure, crash count, or a critical workflow regression.
The rollback plan must identify:
- Which application version will be restored
- Whether the database remains backward compatible
- Which feature flags can isolate the issue
- How cached assets and updater manifests will be corrected
- How customers will be informed
- Which evidence must be preserved for diagnosis
Never assume rollback means redeploying the previous artifact. A forward-only data migration can make that artifact incompatible.
Make the release decision explicit
At the end, state one of three outcomes:
- Ready: evidence is complete and residual risk is accepted.
- Ready with conditions: named checks will occur during a controlled rollout.
- Not ready: a specific unresolved risk blocks release.
Attach the commit, artifacts, check results, migration status, and rollback owner. The value of a checklist is not the boxes. It is the shared, inspectable basis for deciding to ship.