test(ci-guard): the job parser sees inline mappings and unquotes keys - #507
Merged
Conversation
Widening the pattern in the previous change left two spellings behind, and the
first attempt at this recorded them instead of closing them. Recording a hole in
a guard whose contract is "no job goes unseen" documents the defect and calls it
a decision.
A job written as an inline mapping — deploy: {runs-on: ubuntu-latest} — was
missed entirely. GitHub documents the value of jobs.<job_id> as a map of the
job's configuration data, and an inline mapping is a map, so this was a legal
workflow the guard could not see: the job could sit outside the gate's needs
with the build green. The pattern now accepts any tail after the colon, keeping
YAML's rule that a colon separates a key only when a space or line end follows.
Quotes around a key are YAML's encoding, not part of the id. Kept, they produced
an id that could never match the bare name in needs, so a legal workflow was
reported as having an unwatched job. They are stripped.
The key is still matched structurally rather than against GitHub's identifier
grammar. Filtering on the grammar is how a key becomes invisible, which is the
failure being removed; instead every job-level key is parsed and
everyJobIdIsOneGitHubWouldAccept fails on one GitHub would reject — a space in a
quoted key is not a rare-but-legal form, it is a malformed workflow, and the
guard now says so rather than passing it over.
DemchaAV
force-pushed
the
chore/job-parser-known-gaps
branch
from
August 4, 2026 16:51
101a0e5 to
746b2c9
Compare
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.
Why
You were right on both counts, and the first version of this PR was the wrong shape:
it recorded a hole in a guard whose contract is no job goes unseen, which documents
the defect and calls it a decision. Closing it does not need a YAML parser.
Verified the grammar at the source rather than assuming it. GitHub's workflow syntax
reference says a
<job_id>"must start with a letter or_and contain onlyalphanumeric characters,
-, or_", and that the value ofjobs.<job_id>is "a mapof the job's configuration data". That settles all three cases, and they are not the
same kind of thing:
deploy: {runs-on: ubuntu-latest}deploy"build-and-test":"build-and-test"— never matches the bare name inneeds, so a legal workflow is reported as having an unwatched jobbuild-and-test"security scan":security scan, then fails as an illegal job idThe inline mapping is the real hole: a map is what the documentation says the value is,
so that workflow is legal and the job was invisible. The quoted key was a false alarm on
a legal workflow — I had called it "loud failure", which was true but not a defence.
What
separates a key only when a space or a line end follows it.
unquoted(...)strips one matched surrounding pair, so"build-and-test"andbuild-and-testare the same id. Only a matched pair — a key merely containing aquote is untouched.
everyJobIdIsOneGitHubWouldAccept(new) fails on a job-level key GitHub wouldreject.
I did not take the suggested pattern, and the reason matters. Building the identifier
grammar into the matcher means anything off-grammar is skipped, which is exactly how a
job becomes invisible — the failure #505 removed. This keeps matching structural, so
every job-level key is parsed, and judges legality afterwards where it can be reported.
"security scan"is then a finding rather than a shrug: it is a malformed workflow, nota rare-but-legal form, so the guard names it instead of passing over it.
Tests
./mvnw -B -ntp clean verify→BUILD SUCCESS;javadoc:javadoc -pl :graph-compose-core→ exit 0.
CiGateCoverageGuardParsingTest5 → 9,CiGateCoverageGuardTest2 → 3.aJobWrittenAsAnInlineMappingIsSeenandaKeyThatIsNotALegalJobIdIsStillParsedRatherThanSkippedfail.quotesAroundAKeyAreNotPartOfTheJobIddoes not — that fix comes fromunquoted(...)rather than the pattern, and the two are independent.
ci.ymldeclares —architecture-and-documentation-guards,changes,build-and-test,examples-generation,binary-compat,perf-smoke,ci-gate,benchmark-diff— and nothing else, so widening the tail did not start matchingnested keys.
No production code changes.