chore: The expression regex misses an expression containing braces #35
Labels
No labels
priority/P0
priority/P1
priority/P2
priority/P3
size/L
size/M
size/S
size/XL
size/XS
state/done
state/in-progress
state/in-review
state/needs-refinement
state/ready
type/bug
type/chore
type/feature
type/refactor
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
amtronics/platform-actions#35
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
check-actions.pysubstitutes${{ ... }}before runningbash -n, using:[^}]*stops at the first}, so an expression containing one is not matched and reachesbash -nunsubstituted:Found while mutation-testing the checker in #34: deleting the substitution entirely did not fail the suite, and probing why turned up this.
Latent. No action in this repository uses an expression containing a brace, and an unsubstituted expression does not reliably make
bash -nfail — so today the consequence is a body checked in a form the runner will never see, rather than a false result. It becomes real if such an expression is added and happens to be a shape bash rejects.Scope
Acceptance criteria
${{ fromJSON('{"a":1}').a }}, when the checker substitutes, then the whole expression is replaced and no${{remains.${{, when the checker runs, then it does not hang or consume the rest of the file.test-check-actions.py, when the change lands, then they still pass unchanged.Notes
[^}]*was presumably chosen to stay non-greedy across multiple expressions on one line — the third row above is the case a naive.*would break by merging two expressions into one. Whatever replaces it has to keep that, which is why it is a criterion rather than an afterthought.Picking this up —
expirohas had no runner contact with Docker Hub for six hours, so this repository is still the only place work finishes.The change is one line.
\$\{\{[^}]*\}\}becomes\$\{\{.*?\}\}withDOTALL. Non-greedy to the first}}keeps the property[^}]*was presumably chosen for — two expressions on one line stay two matches rather than merging into one — while no longer stopping at a brace inside the expression.Why
DOTALLis not incidental.[^}]already matched newlines, so a multi-line expression was being substituted;.without the flag would not, and dropping it would be a silent regression the existing cases do not cover. That is the one way this change could quietly make things worse, so it gets a test of its own.The limit I am accepting rather than solving. Non-greedy still stops at the first
}}, so an expression containing a literal}}inside a string —${{ fromJSON('{{"a":1}}') }}— is cut short. Matching braces properly needs a parser rather than a regex, and no action in the fleet or in GitHub's own documentation writes one; the honest answer is to document the boundary, not to build the parser.Four cases go into
test-check-actions.py— braces inside, two on a line, multi-line, unclosed — and I will run the mutation pass on the new branch as well as the existing eleven, since a regex change that the suite cannot detect is exactly the thing #34 was about.