Postgres included. No credit card.Start free
Deployment · 3 min read

From GitHub Commit to Production: A CI/CD Checklist

Build a release path that tests, builds, deploys, verifies, and can recover from a bad change.

A commit is not a release

A production pipeline should answer four questions: which source was validated, which artifact was deployed, which environment received it, and whether that environment is healthy. A workflow that only runs npm run build answers the first question incompletely and none of the others.

Use a commit SHA as the source identifier and an image digest or similarly immutable artifact identifier as the build output. Avoid rebuilding a moving branch for production after staging passed; dependencies and generated files could have changed. Promote the artifact you actually tested.

Put gates in dependency order

Run fast validation first: formatting or lint, type check, unit tests, then the production build. Add integration tests for paths that touch a database or external service. Deployment depends on a successful artifact build. Post-deploy smoke checks then test the live URL and a meaningful transaction.

text
commit → validate → build artifact → staging → smoke test
       → production approval → deploy same artifact → smoke test

The approval gate is a team policy, not a substitute for technical checks. Small teams may deploy automatically from main; regulated teams may require a human release decision. In either case, the pipeline should record the artifact and result.

Give the pipeline only the access it needs

The GITHUB_TOKEN and deployment credentials are powerful. Scope workflow permissions explicitly. Put production credentials in a protected environment and avoid giving them to pull-request jobs from untrusted forks. Prefer short-lived cloud credentials via OIDC where supported. Pin third-party actions to reviewed commit SHAs for the strongest immutability.

yaml
permissions:
  contents: read

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test && npm run build

The tag in this compact example is convenient but movable. For a hardened production workflow, replace it with the action's verified full commit SHA. Also pin the Node version and cache strategy appropriate to your project.

Make failure visible

After deployment, check readiness, an authenticated or data-backed path, and the error rate. If those fail, stop the rollout or restore the last known-good artifact. Keep database changes compatible with rollback. A green CI run is not evidence that production served a request.

A release failure the build cannot catch

Assume a pull request adds a required PAYMENT_WEBHOOK_SECRET. Type checking and build pass because the variable is read only when the webhook route runs. The staging deploy also looks healthy if the readiness route ignores that integration. A post-deploy smoke test that sends a signed test webhook reveals the missing configuration before production users depend on it.

This does not mean every endpoint needs an expensive end-to-end test on each release. Choose a small set of representative paths that exercise external dependencies, authentication, and persistent writes. Pair them with a clear runtime configuration schema that fails early for values required at startup.

Keep deployment concurrency under control. Two commits arriving close together should not let an older artifact finish deploying after a newer one. Use environment-level serialization or cancel superseded runs. Record both attempted and successful releases so an incident responder knows what code actually served traffic.

Further reading

GitHub Actions workflow syntax defines jobs and environments. GitHub's secure-use guide covers permissions and action pinning. See also rollback planning.