fix(sql): validate referential actions, and repair the publishing workflow#5
Merged
Conversation
JustGodWork
force-pushed
the
fix/audit-followup
branch
from
July 22, 2026 00:45
87f1943 to
510d900
Compare
JustGodWork
force-pushed
the
fix/ddl-actions-and-ci
branch
from
July 22, 2026 00:45
e0d4492 to
62981a9
Compare
JustGodWork
force-pushed
the
fix/audit-followup
branch
from
July 22, 2026 01:00
510d900 to
591e71f
Compare
JustGodWork
force-pushed
the
fix/ddl-actions-and-ci
branch
from
July 22, 2026 01:00
be40904 to
dffbe86
Compare
JustGodWork
force-pushed
the
fix/audit-followup
branch
from
July 22, 2026 01:06
591e71f to
37030f3
Compare
Both were upper-cased and concatenated straight into the FOREIGN KEY
clause, so anything in them landed in the DDL:
belongsTo("users", { key = "user_id", onDelete = "cascade, add x int" })
-> FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
ON DELETE CASCADE, ADD X INT
This was the last unvalidated identifier path in the SQL builder, and it
matters as soon as a schema is generated from configuration. Actions now
go through a whitelist, on the model of safe_op and safe_dir, and accept
the usual spellings (set null, set_null, SET NULL).
Three defects in the publishing workflow, all pre-existing. Merging a PR into master fired the workflow twice: once as a push to master, once as pull_request/closed with merged == true. The concurrency group did not collapse them, because github.ref differs between the two (refs/heads/master and refs/pull/N/merge), so both jobs rebuilt and both raced to push. The pull_request run could not push anyway: on that event the checkout is on a detached HEAD, and a bare `git push` fails with "You are not currently on a branch" as soon as dist/ has changed. The pull_request trigger is gone, since the push to master already covers the merge, the concurrency group is a constant, and the push carries an explicit refspec. The comment claimed the actor check was the primary loop guard. It never fired: actions/checkout persists SUBMODULES_PAT, so the bot's push is attributed to the PAT owner. What actually breaks the loop is the "[skip ci]" in the commit message, which GitHub honours by not creating a run. The check is removed and the comment says what really happens. Open pull requests are covered by test.yml, which publishes nothing.
JustGodWork
force-pushed
the
fix/ddl-actions-and-ci
branch
from
July 22, 2026 01:07
dffbe86 to
1ba866b
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.
The two items left open after the audit follow-up. Based on #4.
Referential actions were concatenated into the DDL unvalidated
onDeleteandonUpdatewere upper-cased and appended verbatim to the FOREIGN KEY clause:This was the last unvalidated path left in the SQL builder after the operator and sort-direction whitelists, and it matters as soon as a schema is built from configuration rather than written by hand. Actions now go through a whitelist (CASCADE, RESTRICT, NO ACTION, SET NULL, SET DEFAULT) and accept the usual spellings:
set null,set_null,SET NULL.The publishing workflow fired twice per merge and could not push
Three pre-existing defects in
build.yml:Merging a PR into master triggered the workflow twice, once as a
pushto master and once aspull_request/closedwithmerged == true. The concurrency group did not collapse them becausegithub.refdiffers between the two events (refs/heads/masterversusrefs/pull/N/merge), so both jobs rebuilt and both raced to push the same commit.The
pull_requestrun could not have pushed anyway: on that eventactions/checkoutleaves a detached HEAD, and the baregit pushfails withYou are not currently on a branchas soon asdist/has actually changed, which is the normal case.The comment presented
github.actor != 'github-actions[bot]'as the primary guard against an infinite build loop. It never fired:actions/checkoutpersistsSUBMODULES_PAT, so the bot's push is attributed to the PAT owner, never to the bot. The only thing breaking the loop was the[skip ci]in the commit message, described in the comment as a mere "second safety net". Anyone editing that message would have re-armed the loop while believing the actor check protected them.Fixed by keeping a single trigger (the push to master already covers a merge), making the concurrency group a constant, pushing with an explicit refspec, and dropping the check that did nothing. The comment now describes the guard that actually works.
Note
On a push to master,
test.ymlandbuild.ymlboth build and run the suites, so the work is duplicated. It is harmless, and it does mean the bundle is verified twice before publication, buttest.ymlcould dropmasterfrom its push trigger if you would rather save the minutes.Suite: 364 passing, 357 before this branch.