fix(ci): use exact-name match for required check-runs (no regex)#54
Merged
StefanSteiner merged 1 commit intoMay 27, 2026
Conversation
Both `release.yml`'s `verify` job and `npm-build-publish.yml`'s
`verify-ci` job used jq's `test()` against a regex-shaped `REQUIRED`
variable to pick out the canonical CI check-runs to wait on. The
regex contained `\(`, `\)`, and `\+` to escape parens and a plus
inside the names like `test (ubuntu-latest)` and
`hyperdb-api-node (build + smoke)`.
Bash strips one layer of backslash from a single-quoted string... no,
wait — single quotes preserve backslashes literally. The actual
breakage chain is:
bash: REQUIRED='...test \(ubuntu-latest\)...'
(single quotes preserve `\(` literally)
bash: --jq "[... select(.name | test(\"$REQUIRED\"))]"
(double quotes preserve `\(` again)
jq: receives `... test ( ... ` containing `\(`
and parses the `\` as the start of an escape sequence
which is not valid jq syntax.
Result: every release.yml and npm-build-publish.yml run that hit the
verify-ci step exited immediately with:
failed to parse jq expression (line 1, column 133)
[.check_runs[] | select(.name | test("...test \(ubuntu-latest\)..."))]
^ unexpected token "\\"
The v0.2.2 release surfaced this — both publish workflows failed in
9-11 seconds and no crates.io / npm publish happened.
Fix: drop the regex entirely. Use exact-name set membership against a
JSON array of required check-run names. jq's `index()` handles
ordinary string equality with no escaping. Names like
`test (ubuntu-latest)` and `hyperdb-api-node (build + smoke)` are
matched verbatim — no parens, no plus, no backslashes anywhere.
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.
Summary
Both
release.yml'sverifyjob andnpm-build-publish.yml'sverify-cijob poll GitHub's check-runs API for a canonical list of required CI checks, then gate the release/publish on all of them being green. They built that list as a regex-shaped string and fed it to jq'stest(). The regex contained\(,\), and\+to escape parens and a literal plus in check-run names liketest (ubuntu-latest)andhyperdb-api-node (build + smoke).The escapes survive bash's single quotes and the double-quoted
--jqargument unchanged, so jq receives... test \(ubuntu-latest\) ...— and jq parses\as the start of an unrecognized escape sequence. Both publish workflows fail in ~10 seconds with:This surfaced when I tried to release v0.2.2: the manually-created GitHub Release fired both
release.ymlandnpm-build-publish.yml, both crashed in the verify-ci step, and no crates.io or npm publish happened. v0.2.0 and v0.2.1 had hit the same bug — past releases that did make it out went via different paths (manually-published tarballs / hand-edited workflows during the release-pipeline rebuild).Fix
Drop the regex entirely. Use exact-name set membership against a JSON array of required check-run names:
jq'sindex()does ordinary string equality — no escaping, no regex, no Oniguruma to argue with. Names with parens and pluses match verbatim. Same shape applied to both workflows so they stay parallel.Test plan
fix:commit) runs the verify-ci step and emits anAttempt 1/30: total=10 completed=10 failed=0line, thenCI passed (10 required check-runs completed successfully).instead of the jq parse error.release.ymlandnpm-build-publish.ymlreach their actual publish steps.Followups
npm view hyperdb-mcp-darwin-arm64 versions --jsonandcargo search hyperdb-mcpthat the v0.2.2 tag's binaries finally make it out (or whether we need to manually re-trigger the v0.2.2 publish workflows by re-publishing the GitHub Release).autorelease: pendinglabel drift is a separate recurring problem (memory note:project_release_please_label_check.md). Whenever a release-please run completes successfully but no release PR appears, the prior release PR is stuck onautorelease: pending. Worth a separate hardening PR.