Sign and publish mswin binary packages to cache.ruby-lang.org - #137
Open
hsbt wants to merge 17 commits into
Open
Sign and publish mswin binary packages to cache.ruby-lang.org#137hsbt wants to merge 17 commits into
hsbt wants to merge 17 commits into
Conversation
Generates pub/ruby/binaries/index.json from the objects under mswin64/, following the pymanager (PEP 773) feed shape with ruby-build style tags. Regenerated from scratch on every run so the index heals itself from S3 state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wraps SignPath signing behind a zip-in/zip-out contract so the signing backend stays swappable. Signature verification covers only the PE files built from the Ruby tree; vcpkg DLLs stay unsigned under the SignPath Foundation OSS program, as documented in SIGNING.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mswin-build learns to consume the draft tarball from the Packages artifact of the same run, skipping the release-index check that the not-yet-published tarball cannot pass, and exposes the package name as an output. draft-release builds the zip from it, signs it under the manually approved signing environment, and stages it as pub/tmp/ruby-<version>-x64-mswin64_140-draft.zip. The mswin jobs are kept out of the release job needs so a packaging failure never blocks the source release. remove-tmp-package cleans up the staged zip alongside the tarballs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Promotes the staged mswin zip to pub/ruby/binaries/mswin64/ when ruby/ruby publish dispatches publish-binaries. The destination is append-only; a fixed package is reissued under a revisioned name instead of overwriting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mswin-release becomes the backfill path: it signs the zip built from an already published tarball and uploads it straight to pub/ruby/binaries/mswin64/ with the same overwrite refusal, then regenerates the index. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dev builds are published unsigned under immutable date+commit names, pruned to the newest 30, and reflected in the binaries index. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A reissued zip like ruby-4.0.5-1-x64-mswin64_140.zip was parsed as a prerelease, so it never received the 4.0.5 resolution tags while the broken original kept them. Only the highest revision of a version now carries the resolution tags. Prereleases get channel: prerelease, keeping clients that treat the first release entry as latest stable from picking an rc. Builds are also sorted version-first instead of by upload date, so a backfilled old release cannot shadow a newer one for consumers picking the first tag match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SIGNING.md promises revisioned reissues but the workflows could not produce one. mswin-release now takes a REVISION input and mswin-build appends it to the package name, which also becomes the zip root, so the append-only bucket accepts the fixed package under a fresh name. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sorting the whole file name orders lexically by version, which misorders pruning once 4.9 and 4.10 dev builds coexist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The README still claimed publishing to cache.ruby-lang.org was not wired up, and described mswin-release as ending at an Actions artifact. Neither is true once this pipeline lands. The setup that signing depends on lives in repository settings, so it was invisible: without a `signing` environment GitHub silently creates an unprotected one and the approval gate SIGNING.md describes does not exist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A mistyped revision reached S3 unchecked. `9x` produced a name the index regex rejects, which fails index generation for every workflow until someone deletes the object by hand, and `abc` parsed as a prerelease suffix so a reissue silently kept the plain tags on the package it was meant to replace. `git rev-parse --short=10` is a lower bound and lengthens an ambiguous prefix, which breaks the dev name the same way. Both are now caught before the name is used. Skipped signing also now logs a warning, since publishing unsigned was otherwise indistinguishable from a normal green run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A reissue left the original with an empty tag list, so nothing could resolve it, contradicting the documented contract that older revisions resolve by their revisioned exact name. Numbering the first publication revision 0 gives it that name. Sorting compared Gem::Version alone, and its string segments order "4.1.0.dev" below "4.1.0.preview1" alphabetically, sinking today snapshot beneath a months-old preview and breaking the newest-first guarantee. Version, then channel rank, then revision now decide, with the commit as a tie-breaker so the order is total. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A draft tag gets re-cut freely, and signing at draft time spent a SignPath signing request and a human approval on every re-cut. Worse, each re-cut silently overwrote a staged zip that had already been signed and approved, so what publish promoted was not necessarily what anyone approved. draft-release now stages the zip unsigned and verifies the build checksum instead of regenerating it, keeping the build witness intact until signing. publish-binaries takes the staged zip, verifies it against that witness, signs it under the signing environment, and uploads the signed bytes. Index regeneration and staging cleanup move to a separate job so a transient failure there can be re-run without tripping the append-only guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
signtool verify /pa only asks whether the chain is trusted, so any certificate the default policy accepts passed, and /q threw away the reason when it did not. /tw now enforces the RFC 3161 timestamp that SIGNING.md promises, an optional thumbprint pins the certificate to ours once SignPath issues it, and a failed check re-runs verbose so the log distinguishes a missing signature from an untrusted chain. mswin-release also gains a precheck job, so dispatching an already published version fails in seconds instead of after an hour of build time and a signing approval. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`aws s3 ls` splits on whitespace, so a name containing a space yielded a truncated key, and any object whose third dash-separated field was not a date sorted as the oldest and was deleted first. The listing now goes through list-objects-v2 and candidates must match the dev name pattern. What gets deleted is recorded in the step summary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dropping null keys meant a dev entry had `commit` but no `revision`, a first release had neither, and a reissue had `revision` but no `commit`, so `schema: 1` guaranteed nothing and consumers had to probe for each key. Entries now always carry every key. `date` also meant two different things, a commit date for dev builds and an upload date for releases. It is now `commit_date` and `published_at`. Entries gained `name`, the zip root directory, which was a documented part of the package contract that consumers could only recover by parsing the URL. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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 mswin zip packages built here have so far only existed as workflow artifacts. This wires them into the release pipeline.
draft-release.ymlbuilds the zip from the draft tarball, signs the Ruby-built PE files through SignPath under the manually approvedsigningenvironment, and stages it aspub/tmp/ruby-<version>-x64-mswin64_140-draft.zip. These jobs never block the source release.A new
publish-binaries.yml, dispatched by ruby/ruby's publish workflow, promotes the staged zip to the append-onlypub/ruby/binaries/mswin64/. It also regeneratespub/ruby/binaries/index.json, a pymanager-style feed with ruby-build style tags forrbto resolve installs against.Daily snapshots are published unsigned under
dev/, keeping the newest 30.mswin-release.ymlremains as the backfill path for already released tarballs.Until the SignPath project is provisioned, the signing step is skipped and packages ship unsigned with
signed: falsein the index. SeeSIGNING.mdfor the signing policy.🤖 Generated with Claude Code