Skip to content

docker-release: gh release create fails with GH_TOKEN unset — image publishes, GitHub Release does not #63

Description

@blairham

Symptom

docker-release.yml@main builds and pushes the image successfully, then fails the job on the last step:

#41 pushing manifest for .../understudy:e0dec01@sha256:9774d6c7... 0.2s done
#41 DONE 7.7s
==> advanced release marker refs/releases/image/understudy
==> changelog written to dist/CHANGELOG.md
+ gh release create v0.0.135 --title 'understudy 0.0.135' --notes-file dist/CHANGELOG.md
gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable. Example:
  env:
    GH_TOKEN: ${{ github.token }}
stevedore: gh release create: gh: exit status 4

Run: https://github.com/pinpredict/understudy/actions/runs/32501519025 (tag v0.0.135)

Why it matters more than a red check

The failure is partial and misleading. The image is published — understudy:0.0.135 and :e0dec01 are both in ECR, pushed at 16:17:46Z — but the job reports failure, so:

  • a red release run does not mean "nothing shipped", which is the natural reading;
  • consumers resolving the highest semver tag (k5s tag: latest) pick the new image up regardless, while the GitHub Release page it should be documented on does not exist;
  • the changelog is generated (dist/CHANGELOG.md) and then discarded with the job.

I created the missing Release by hand for v0.0.135, so that one is patched up — the workflow bug is not.

This is a regression, and it is org-wide

understudy's three previous releases all have Release objects (v0.0.132 / v0.0.133 / v0.0.134, the last on 2026-08-20T21:42Z — about 18 h before this run). Nothing changed in the caller: understudy pins uses: pinpredict/.github/.github/workflows/docker-release.yml@main with secrets: inherit, unchanged across all four tags.

Because the pin is @main, whatever changed in the shared workflow between those two runs affects every repo that releases through it, not just understudy.

Where to look

gh exit 4 with that message means GH_TOKEN/GITHUB_TOKEN is simply absent from the step's environment — not a permissions denial (that surfaces differently). Two candidates:

  1. the env: block carrying the token to the stevedore step was dropped or renamed;
  2. stevedore resolves the token from its own .stevedore.yaml secret declaration (understudy declares secrets: [{id: gh_token, ...}]), and the mapping from the workflow secret to that id broke.

understudy's caller comment already notes the gh_token secret id is declared in .stevedore.yaml, so (2) seems the likelier of the two.

Suggested guard

Whatever the fix, the step ordering is worth revisiting: pushing the image before the Release step means a failure here always leaves the two halves disagreeing. Either create the Release before the push, or make the job's failure mode not straddle a completed publish.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions