Publish all language packages reliably and surface registry status as badges#26
Merged
Publish all language packages reliably and surface registry status as badges#26
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: #25
Captures the registry probe (npm 200, PyPI/crates.io/NuGet 404), the four relevant CI runs as JSON evidence, and a root-cause write-up of the silent publish-skip pattern that left Rust and C# auto-releases green while publishing nothing, plus the git-tag gate that prevents retries.
Adds shields.io live registry badges so a reader can immediately see whether a given package is published and at what version. The root README also documents that a "not found" badge means the publish never happened.
Auto-release jobs for Python, Rust and C# previously checked the local Git tag to decide whether to publish. Once the workflow itself created that tag the gate flipped to "already released" forever, even though the package never actually reached PyPI / crates.io / NuGet (silent skip when the publish secret was missing). * Replace the tag check with an HTTP probe of the registry (200 = already published; otherwise publish). The pipeline is now self-healing. * Promote missing CARGO_REGISTRY_TOKEN / NUGET_API_KEY from a "::warning:: exit 0" to a "::error:: exit 1" so secrets-not-configured is impossible to mistake for success. * On retry, treat crates.io's "already uploaded/exists" as a non-fatal outcome to keep the pipeline idempotent. * For PyPI publish, enable verbose + skip-existing so first-publish diagnostics surface and re-runs are idempotent. See docs/case-studies/issue-25/README.md for the failure timeline and root-cause analysis.
The python.yml workflow passes --tag-prefix python-v to this script in both auto-release (line 255) and manual-release (line 336) jobs, but the script's argparse did not declare the option, so any release attempt would fail with "unrecognized arguments". This adds the flag with default "v" (preserving prior behavior for direct callers) and propagates it through create_release() to build the tag. Mirrors the rust/scripts/create-github-release.mjs and csharp/scripts/create-github-release.mjs interface, which both expose --tag-prefix with language-specific defaults. Refs: docs/case-studies/issue-25/README.md
The JS workflow's any-code-changed detector flags non-JS workflow file edits as code changes, which forces a changeset on this PR even though no JS source moves. Marking as patch because js/README.md was touched (badges) and that does ship to npm via the README field.
Member
Author
Working session summaryFinal state confirmed:
PR: #26 The PR fixes #25 by:
This summary was automatically extracted from the AI working session output. |
Member
Author
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost: $10.624658📊 Context and tokens usage:Claude Opus 4.7: (3 sub-sessions)
Total: (4.0K new + 380.7K cache writes + 13.0M cache reads) input tokens, 69.8K output tokens, $10.624658 cost 🤖 Models used:
📎 Log file uploaded as Gist (4732KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
Member
Author
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
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.
Fixes #25.
Summary
The repository advertises four language packages but only the npm one was actually
on its registry. Rust, C# and Python were silently failing to publish because their
release pipelines either swallowed missing-token errors or considered the local git
tag the source of truth for "is this version on the registry". The first publish
of every non-JS package therefore never went out, and the CI badge stayed green.
This PR makes the publish step honest, makes the "should we publish" decision look
at the registry instead of a local tag, and adds visible registry-version badges so
publication failures show up in the README without any custom logic.
The full investigation, evidence, and rationale are in
docs/case-studies/issue-25/README.md.Changes
.github/workflows/{python,rust,csharp}.yml)Python,
crates.ioAPI for Rust, NuGet flat-container.nuspecendpoint forC#. A 200 means "skip"; a 404 means "publish". Self-healing on retry.
CARGO_REGISTRY_TOKEN/CARGO_TOKENis unset; C# now hard-fails whenNUGET_API_KEYis unset (instead ofecho+exit 0).cargo publishis wrapped to treat "already uploaded" / "crate version isalready uploaded" as success (race-tolerant).
pypa/gh-action-pypi-publishnow runs withverbose: trueandskip-existing: truefor the same reason.python/scripts/create_github_release.py)--tag-prefixargument (defaultv). The Python workflow alreadypassed
--tag-prefix python-v, but the script ignored unknown args, so theGitHub release would have been created with the wrong tag once the publish
step started succeeding.
README.mdgets a "Package versions" block with shields.io badges thatpull from npm / PyPI / crates.io / NuGet, each linking to the registry page.
license badge for parity.
docs/case-studies/issue-25/)fix design, and reproducibility script.
Tag/release convention
vjs/scripts/create-github-release.mjs(default)python-vpython.yml→create_github_release.py --tag-prefixrust-vrust.yml→create-github-release.mjs --tag-prefixcsharp-vcsharp.yml→create-github-release.mjs --tag-prefixReproduction / verification
registry-*evidence files in the case-study folder.Test plan
python/scripts/create_github_release.py --helplists--tag-prefix.main.mainpush should publish the missing 0.2.0 packages(or visibly fail if a registry secret is still missing — which is now
the desired behaviour, not a silent skip).
Out of scope / follow-ups
NUGET_API_KEY,CARGO_REGISTRY_TOKEN) andthe PyPI Trusted Publisher binding is repo-admin work and is documented in
the case study.
rust-ai-driven-development-pipeline-templateand
csharp-ai-driven-development-pipeline-templateis documented in thecase study; this PR does not file them.