Skip to content

fix: harden release-guard workflow and prevent race condition#4776

Open
bryanbeverly wants to merge 6 commits intotrufflesecurity:mainfrom
bryanbeverly:fix/release-guard-gh-repo
Open

fix: harden release-guard workflow and prevent race condition#4776
bryanbeverly wants to merge 6 commits intotrufflesecurity:mainfrom
bryanbeverly:fix/release-guard-gh-repo

Conversation

@bryanbeverly
Copy link

@bryanbeverly bryanbeverly commented Feb 27, 2026

Summary

  • The release-guard.yml workflow's unset-latest job fails because the gh CLI cannot infer the repository — there is no actions/checkout step and no GH_REPO env var, so gh falls back to looking for a local .git directory which doesn't exist.
  • This adds GH_REPO: ${{ github.repository }} to the step's environment so gh knows which repo to target without needing a checkout.
  • In release.yml, the "Mark release as latest" step now passes github.ref_name through an env var instead of interpolating it directly into the shell command.
  • The guard now checks the Release workflow run status before acting: if the pipeline already succeeded for this tag, the guard skips — preventing a race where a delayed guard run could revert a legitimate release. If the pipeline failed or never ran (manual release), the guard proceeds normally.
  • Adds actions: read permission so the guard can query workflow run status.
  • Event context (release.tag_name) is also passed through an env var for consistency.

Failed run: https://github.com/trufflesecurity/trufflehog/actions/runs/22491672284

Test plan

  • Verify both workflow files are valid YAML
  • Create a test release to confirm the workflows pass with the fixes

Note

Low Risk
Workflow-only changes; main risk is mis-detecting the release run status or tag and skipping/restoring latest incorrectly.

Overview
Prevents the release-guard.yml workflow from erroneously unsetting latest by first checking whether the release.yml workflow already succeeded for the tag and skipping the guard in that case.

Fixes gh CLI targeting and quoting by adding actions: read permission, setting GH_REPO/RELEASE_TAG env vars (no checkout needed), and updating release.yml to pass the tag via TAG env var when running gh release edit.

Written by Cursor Bugbot for commit 0452247. This will update automatically on new commits. Configure here.

The `gh` CLI commands fail with "fatal: not a git repository" because
the workflow never checks out the repo and gh cannot infer the
repository context. Setting GH_REPO avoids the need for a checkout step.

Fixes the failure in: https://github.com/trufflesecurity/trufflehog/actions/runs/22491672284

Made-with: Cursor
@bryanbeverly bryanbeverly requested a review from a team February 27, 2026 16:01
Use an intermediate environment variable for github.ref_name instead
of interpolating it directly into the shell command.

Made-with: Cursor
Check the Release workflow run status before deciding to unset latest.
If the pipeline completed successfully for this tag, the latest flag was
set intentionally and the guard should not undo it. This prevents a race
where a delayed guard run could revert a legitimate release.

Also passes event context through env vars and adds actions:read
permission for gh run list.

Made-with: Cursor
@bryanbeverly bryanbeverly changed the title fix: add GH_REPO env to release-guard workflow fix: harden release-guard workflow and prevent race condition Feb 27, 2026
steps:
- name: Restore previous release as latest if needed
run: |
TAG="$RELEASE_TAG"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand why we've got two separate vars here. Can't we just use RELEASE_TAG throughout the code in this run? If I'm reading it correctly, this is just an alias, which is confusing since it's inconsistent with the env. Or am I misunderstanding something?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, this was vestigial and there's nothing gained from it. Removed.

bryanbeverly and others added 3 commits March 6, 2026 16:37
Addresses review feedback from sysread — the TAG variable was just an
alias for RELEASE_TAG, adding confusion without benefit.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants