You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A changelog-fragment-only merge publishes all three packages without ever running release-ci #944
release-ci.yml's PR paths and putitoutthere's publish globs disagree about fragment directories, in the direction that skips verification but keeps publishing.
rust changelog fragment edit
release-ci.yml (PR-time precheck)
excluded — !packages/rust/changelog.d/**, so no build precheck runs
putitoutthere.toml (push-time publish)
packages/rust/** matches → publishesdirsql-rust, and depends_on cascades to dirsql-py and dirsql-npm
So a PR that adds only a changelog fragment merges having never run the release build matrix, and then republishes all three packages on main.
Pre-existing for python and ts — release-ci.yml has excluded their fragment dirs for some time. #834 extended the same exclusion to rust for consistency, which also extends this mismatch to rust. Not introduced by that epic, but now uniform across all three.
Two things worth separating
The verification gap. A fragment-only change cannot plausibly break a build, so skipping the precheck is low-risk in practice. This half is close to harmless.
The pointless release. This is the real cost. A merge that changes nothing but a markdown file cuts a release of three packages whose artifacts are byte-identical to the previous version. That burns the full cross-compile matrix, consumes version numbers, and puts no-op releases in front of users on crates.io, PyPI and npm.
Note that #939 (excluding fragment dirs from the crate archive) does not fix this. Excluding fragments from the .crate stops them shipping; it does not stop putitoutthere detecting a change under packages/rust/** and republishing.
Options
Exclude fragment dirs from the publish globs — mirror release-ci.yml's exclusions in putitoutthere.toml, so a fragment-only change is genuinely a no-op for release. Needs a check that putitoutthere's glob syntax supports negation; verify at the pinned @v0 sha rather than assuming.
Leave publishing as-is and re-add fragments to release-ci.yml — restores the precheck but keeps the no-op releases. Fixes the lesser half.
Accept and document — if a no-op release per changelog fragment is considered acceptable, say so where the globs are defined so this isn't rediscovered.
First option looks right, contingent on negation being supported.
Notes
Surfaced while auditing which globs fan into which workflow for #834. Not an observed incident — no bad release has been traced to it — so this is a correctness/cost question rather than a live bug.
This is no longer hypothetical, and the scope is wider than fragment dirs.
Observed.#971 merged as 3ec31c6 at 18:02Z and fired Release run 371. Its only changes under packages/ were two new gate-config files — packages/python/testing-conventions.toml and packages/ts/testing-conventions.toml — plus comment edits in the root config; no SDK source, no fragment. packages/python/** and packages/ts/** matched, so dirsql-py and dirsql-npm published artifacts byte-identical to the previous version. So the "Not an observed incident" note at the bottom can come off.
A second non-shipping class. The issue is framed around changelog.d/ / migrations.d/, but package-root testing-conventions.toml has the same property and is not covered by any exclusion anywhere:
path
ships in the artifact?
release-ci.yml PR precheck
publish globs
packages/<pkg>/changelog.d/**
no
excluded
matches → publishes
packages/<pkg>/testing-conventions.toml
no
not excluded
matches → publishes
It differs from the fragment case in one way worth noting for option 2: this one does run the precheck, so only the "pointless release" half applies — but it is strictly worse in frequency terms, because gate config is edited whenever a lane's scope changes, and #933 just made these files a permanent fixture of both SDK packages rather than a one-off.
Bearing on the options. Option 1 (negation in the publish globs) now needs to cover both classes, not just fragment dirs — !packages/*/testing-conventions.toml alongside !packages/*/changelog.d/**. Still contingent on the same unanswered question: whether putitoutthere's glob syntax supports negation, verified at the pinned @v0 sha. If it does not, the alternative for this class specifically is to move the two configs out of the package subtrees and point each lane's config: input at the new path — the workflows already pass it explicitly, so that is a two-line change, but it gives up the package-local placement that internals/checks and the embeddings plugin established (neither of which is published, which is why the cost never showed up there).
I introduced this in #971 without checking the release globs against the new file paths, and should have flagged it on the PR.
Activity
thekevinbot commentedon Aug 20, 2026
This is no longer hypothetical, and the scope is wider than fragment dirs.
Observed. #971 merged as
3ec31c6at 18:02Z and fired Release run 371. Its only changes underpackages/were two new gate-config files —packages/python/testing-conventions.tomlandpackages/ts/testing-conventions.toml— plus comment edits in the root config; no SDK source, no fragment.packages/python/**andpackages/ts/**matched, sodirsql-pyanddirsql-npmpublished artifacts byte-identical to the previous version. So the "Not an observed incident" note at the bottom can come off.A second non-shipping class. The issue is framed around
changelog.d//migrations.d/, but package-roottesting-conventions.tomlhas the same property and is not covered by any exclusion anywhere:release-ci.ymlPR precheckpackages/<pkg>/changelog.d/**packages/<pkg>/testing-conventions.tomlIt differs from the fragment case in one way worth noting for option 2: this one does run the precheck, so only the "pointless release" half applies — but it is strictly worse in frequency terms, because gate config is edited whenever a lane's scope changes, and #933 just made these files a permanent fixture of both SDK packages rather than a one-off.
Bearing on the options. Option 1 (negation in the publish globs) now needs to cover both classes, not just fragment dirs —
!packages/*/testing-conventions.tomlalongside!packages/*/changelog.d/**. Still contingent on the same unanswered question: whether putitoutthere's glob syntax supports negation, verified at the pinned@v0sha. If it does not, the alternative for this class specifically is to move the two configs out of the package subtrees and point each lane'sconfig:input at the new path — the workflows already pass it explicitly, so that is a two-line change, but it gives up the package-local placement thatinternals/checksand the embeddings plugin established (neither of which is published, which is why the cost never showed up there).I introduced this in #971 without checking the release globs against the new file paths, and should have flagged it on the PR.
Generated by Claude Code