Skip to content
Latchkey

How to Verify the Deployed Version Matches the Git SHA in GitHub Actions

A deploy can report success while an old image still serves traffic, so verify a /version endpoint returns the same commit SHA the workflow built.

Bake the commit SHA into the build, expose it at /version, then in a verify step fetch that value and assert it equals github.sha before promoting.

Steps

  • Inject github.sha into the build (env var or build arg).
  • Serve it from a /version JSON endpoint.
  • After deploy, fetch /version and compare against ${{ github.sha }}.

Workflow

.github/workflows/ci.yml
- name: Verify deployed commit
  env:
    BASE: ${{ vars.DEPLOY_URL }}
    EXPECTED: ${{ github.sha }}
  run: |
    ACTUAL=$(curl -sf "$BASE/version" | jq -r .sha)
    echo "expected=$EXPECTED actual=$ACTUAL"
    if [ "$ACTUAL" != "$EXPECTED" ]; then
      echo "deployed version does not match; aborting"; exit 1
    fi

Gotchas

  • A CDN or reverse proxy may cache /version; request with a cache-busting header or Cache-Control: no-cache.
  • If the SHA does not match, do not promote; roll back to the known-good version.

Verify it actually works

A workflow that runs is not a workflow that works. Confirm the behaviour on a real event rather than on a manual dispatch, because trigger conditions, permissions, and context values all differ between the two.

Terminal
# 1. validate the file before pushing
docker run --rm -v "$(pwd):/repo" --workdir /repo rhysd/actionlint:latest -color

# 2. trigger the real event, not workflow_dispatch
git commit --allow-empty -m "ci: verify trigger" && git push

# 3. watch it and read the conclusion, not just the colour
gh run watch
gh run view --log-failed

What usually goes wrong first

  • The workflow file must exist on the default branch before scheduled or dispatch triggers appear at all.
  • GITHUB_TOKEN permissions default to read-only in many organisations. Declare a permissions: block listing every scope the job needs.
  • Fork pull requests get a read-only token and no access to secrets, regardless of workflow configuration.
  • actions/checkout gives you depth 1 on a detached HEAD, so anything needing history or a branch name needs fetch-depth: 0.

Frequently asked questions

How do I verify the Deployed Version Matches the Git SHA in GitHub Actions?
Bake the commit SHA into the build, expose it at /version, then in a verify step fetch that value and assert it equals github.sha before promoting.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card