ci: publish bridges on a merged version bump, and flag drift when they aren't - #35
Merged
Conversation
agentmail-mcp 1.0.1 fixed a silent-startup regression on 2026-07-21 and then sat on main unpublished for a week while npm kept serving the broken 1.0.0. Both publish workflows are workflow_dispatch, so nothing turned "merged but unreleased" into a signal — the customer found it before we did. - Compare packages/npm-stdio-bridge and python/stdio-bridge versions against npm's and PyPI's latest in the existing public-surface audit, naming the workflow to run when they disagree. - Run the live surface audit daily instead of weekly; a weekly window is the same blind spot that hid this for seven days. - Self-test covers the local version reads, so a moved path or renamed key fails fast instead of silently reporting agreement. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01544GeWAAQvSawpyS7BbnqV
|
Deployment #101 deployed successfully
Deployed on Manufact.com |
Detection alone still left a human to remember the dispatch. The merged version bump is the release intent and is already reviewed in the PR, so publish on it and keep dispatch for out-of-band releases. - Trigger on pushes to main that touch packages/npm-stdio-bridge/package.json. - Resolve the version from package.json; a dispatch that disagrees with it fails instead of publishing something nobody asked for. - Skip publishing when the version is already on npm, so a dependency or description edit to package.json is a no-op rather than an EPUBLISHCONFLICT. - Smoke-test npx -y agentmail-mcp@<version> from a clean cache and require it to reach its own argument check. 1.0.0 exited 0 with no output through the bin symlink npx uses, so "the publish succeeded" never meant "it starts". This was a documented manual step; with no human left in the loop it has to run here. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01544GeWAAQvSawpyS7BbnqV
Same treatment as publish-npm.yml so neither bridge depends on someone remembering a dispatch. - Trigger on pushes to main that touch python/stdio-bridge/pyproject.toml. - Skip the publish job when the version is already on PyPI, so an edit that doesn't bump the version is a no-op instead of a rejected re-upload. - Stop pinning 1.0.0 in the artifact smoke test and read the expected version from pyproject instead. Pinned, it would have failed the build job on the first bump — that is, on every release the automation now fires for. The existing pre-publish smoke test already installs each distribution into a clean virtualenv and runs the console script, so there is no post-publish check here as there is for npm. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01544GeWAAQvSawpyS7BbnqV
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
agentmail-mcp1.0.1 fixed a silent-startup regression on 2026-07-21, then sat onmainunpublished for a week while npm kept serving the broken 1.0.0. Both publish workflows wereworkflow_dispatch-only, so shipping depended on someone remembering, and "merged but never published" produced no signal anywhere. A customer (T-590) found it before we did.The startup bug itself was already covered —
artifact.test.mjsspawns the bridge through a real symlink and asserts it starts. The gap was entirely the release step.What
Publish on the merged version bump. The bump is the release intent and is already reviewed in the PR, so
publish-npm.ymlandpublish-pypi.ymlnow trigger on pushes tomaintouching their respective manifests. Dispatch still works for out-of-band releases.Don't misfire. If the version is already on the registry, publishing is skipped — so a dependency or description edit to
package.json/pyproject.tomlis a no-op instead of anEPUBLISHCONFLICTor a rejected PyPI re-upload. A dispatch whose typed version disagrees withpackage.jsonnow fails instead of publishing something nobody asked for.Prove it starts. After publishing, npm runs
npx -y agentmail-mcp@<version>from a clean cache and requires it to reach its own argument check. 1.0.0 exited 0 with no output through the bin symlinknpxuses, so "the publish succeeded" never implied "it runs".release.mddocumented this as a manual step; with no human left in the loop it has to run in CI. PyPI already installs each distribution into a clean virtualenv and runs the console script pre-publish, so it needs no post-publish equivalent.Unpin the PyPI smoke test. It asserted
== "1.0.0", which would have failed the build job on the first bump — i.e. on every release this automation now fires for. It reads the expected version frompyproject.tomlinstead.Backstop. The public-surface audit now compares both bridges against npm's and PyPI's
latestand names the workflow to run when they disagree, catching a failed publish or a bump that never released. It runs daily rather than weekly — a weekly window is the same blind spot that hid this for seven days.Verification
fetch:npm publishes 1.0.0 but the repo ships 1.0.1 — run the 'Publish npm bridge' workflow. PyPI was genuinely in sync and correctly stays quiet; a 503 from either registry is reported, not swallowed.smoke-artifacts.shrun end-to-end viauvas CI does — builds both distributions, installs each, passes with the version read frompyproject.toml.--self-testcovers the local version reads, so a moved path or renamed key fails fast instead of quietly reporting agreement.Note
live-surfacesis schedule/dispatch-only and so skips on PRs; the drift check was verified locally as above.🤖 Generated with Claude Code
https://claude.ai/code/session_01544GeWAAQvSawpyS7BbnqV