Repository navigation
Conversation
The script passed workflow_id to listWorkflowRunsForRepo. That endpoint has no such parameter, so GitHub returned runs for every workflow in the repo. With fail-if-exists set, a release failed whenever anything in the repo sat in the requested status, a dependabot update included. Call listWorkflowRuns, which scopes to workflow_id, and fail clearly when the name does not resolve. Add non-terminal as a workflow-status, matching every run that has yet to finish. A run blocked by a concurrency group reports queued or pending depending on the trigger, so naming a single status leaves gaps. Add created-within-minutes to bound the lookback, so a run stuck in a non-terminal state stops blocking releases. It defaults to 0, which considers every run. Both inputs are additive and existing callers keep their behaviour. Inputs now reach the script through the environment, keeping them out of the source.
The checkout set fetch-tags and left fetch-depth at 1. git describe walks back from HEAD, so on a shallow clone it found nothing, the step fell back to v0.0.0, and the package version always differed. The guard passed whatever the real state was.
build-image and tag-image resolve <version>-<sha> from a checkout of ref. A caller passing a branch name gets the tip at the moment each job starts, so a merge landing mid-run shifts the tag between them. Report the commit this job pushed, so callers pin both to it.
Reading version and sha from ref resolves against the branch tip, which moves. A caller that already knows what build-image pushed passes it in as source-tag and skips the lookup.
Tallying a single page missed runs beyond the first hundred, which is the stuck-run case the lookback window exists for. Query each non-terminal status in turn and sum total_count, which covers every page. The API returns an empty list for a status it fails to recognise, so a typo in workflow-status passed the guard silently. Accept only documented values. Drop fetch-tags from check-tag-version-equality, since depth 0 brings tags. Make ref optional in tag-image and skip the checkout when source-tag is set.
Twelve repos depend on these workflows and nothing ran against them before they reached master. The status check carries the only real logic here, so read its script out of the workflow and run it against a stubbed octokit. 15 cases: workflow_id scoping, total_count past one page, non-terminal across all five states, an unrecognised status failing before any request, the lookback window, the 404 path, fail-if-exists, and error-message. A pull-request workflow runs them. actionlint stays for #21, since it reports findings across workflows this branch leaves alone.
This was referenced Aug 8, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four fixes to the guards these workflows provide, found while setting up CI in nexus-mutual-mcp.
check-workflow-status matched every workflow
The script passed
workflow_idtolistWorkflowRunsForRepo. That endpoint takes no such parameter, so GitHub returned runs for every workflow in the repo. Measured against membership-api:With
fail-if-exists: true, a release failed whenever anything in the repo sat in the requested status. Ten repos call this workflow.It now calls
listWorkflowRuns, which scopes toworkflow_id, and fails with a clear message when the name is missing. Inputs reach the script through the environment.A single status matched too few runs
workflow-status: non-terminalcovers every run that has yet to finish. A run blocked by a concurrency group reportsqueuedorpendingdepending on the trigger, so one status covers part of the range. It queries each ofqueued,in_progress,waiting,pendingandrequestedin turn and sumstotal_count, which spans every page.created-within-minutesbounds the lookback, so a run stuck in a non-terminal state clears and releases resume. It defaults to 0, which considers every run.Both inputs are additive. Existing callers keep their behaviour.
An unrecognised status passed the guard
The API answers an unknown
statuswith an empty list rather than an error, soworkflow-status: in_progresreported nothing and the release went ahead. Verified against a live repo:status=bogus_statusreturnstotal_count: 0. The input is now checked against the documented values.check-tag-version-equality passed unconditionally
The checkout set
fetch-tags: trueand leftfetch-depthat 1.git describe --tags --abbrev=0walks back from HEAD, so a shallow clone stopped short, the step fell back tov0.0.0, and the package version always differed.build-image and tag-image resolved a moving tag
Both compute
<version>-<sha>from a checkout ofref. A caller passing a branch name gets the tip at the moment each job starts, so a merge landing mid-run shifts the tag between them anddocker pullfails.bump.ymlreportscommit_sha, so callers pin the build to the commit the bump created.tag-image.ymlacceptssource-tag, so callers passneeds.build-image.outputs.image-tagstraight through.Verified
The rewritten script ran against mocked responses covering:
workflow_idscoping and the repo-level endpoint staying unused,total_countpast the first page,non-terminalacross all five states, finished runs going unqueried, an unknown status failing before any request, the window on and off, the 404 path,fail-if-exists: false, and a customerror-message.Each of the five non-terminal statuses was also checked against the live API, confirming GitHub accepts them as
statusfilters.All nine other callers pass
merge-to-dev-or-hotfix.yml, and that file exists in each of their repos, so the new 404 path affects none of them.These now run in CI.
test/check-workflow-status.test.jsreads thescriptblock out of the workflow and exercises it against a stubbed octokit, andpull-request.ymlruns it on every PR. That gives this repo its first automated check.actionlintstays for #21. It reports findings in workflows this branch leaves alone.The live-API checks above sit outside what a stubbed harness can prove, so they stay manual.
Every other caller passes
workflow-status: in_progress, which the new validation accepts.Left open
#17 needs a decision before it moves. Resetting the bump range means tagging at bump time, which
check-tag-version-equalityandgit-tag-github-releaseboth treat as a failure today. nexus-mutual-mcp works around it locally for now.Closes #16
Closes #18
Closes #19