Skip to content

fix(release): repair the two failures that left v0.4.3 unsigned - #7

Merged
livingstaccato merged 2 commits into
mainfrom
fix/sbom-environment-markers
Aug 27, 2026
Merged

fix(release): repair the two failures that left v0.4.3 unsigned#7
livingstaccato merged 2 commits into
mainfrom
fix/sbom-environment-markers

Conversation

@livingstaccato

Copy link
Copy Markdown
Member

v0.4.3 reached PyPI but its GitHub release has 0 assets and no signatures. Two independent failures, one per commit here.

1. SBOM: marker matched as a substring instead of evaluated

scripts/sbom_from_wheel.sh demanded every Requires-Dist name appear in the SBOM, skipping only lines containing the literal "extra ==". That is a hand-rolled evaluation of one marker, blind to every other.

tzdata; sys_platform == "win32" carries no extra, so it was demanded on the ubuntu runner that builds the SBOM — where the marker correctly keeps it uninstalled:

SBOM lists 3 components but is missing 1 of provide-foundation's dependencies (tzdata) -- wrong environment

Two commits in the same release collided: 61f22308 added the closure proof, 74c6ba45 added the first conditional dependency this project has ever had. Neither was wrong alone, and no earlier release could have caught it.

Markers are now evaluated with packaging, against an empty extra (which is what makes extra == "cli" false — no extra was requested when the wheel was installed). The checker runs under the venv's own interpreter, because the only environment whose marker answers mean anything is the one the SBOM describes. packaging is installed after generation; that order is load-bearing, or it would be published as a component of the release.

Verified against a fresh uv build of 0.4.3:

result
main's script reproduces the CI failure verbatim, on macOS, same reason
this script SBOM describes provide-foundation 0.4.3 with 3 dependencies — attrs, structlog, tomli_w, and not packaging
drop structlog from the SBOM, re-check still fails, exit 1 — the check has not been weakened into always passing

2. Sigstore: signing aborts on a trust root that no longer verifies

Both signing steps pinned the action at v3.0.0 (July 2024), which installs sigstore ~= 3.0. sigstore-python 3.x bundles a TUF root that can no longer verify Sigstore's production root:

tuf.api.exceptions.UnsignedMetadataError: root was signed by 0/3 keys

raised from TrustedRoot.production() before anything is signed. It does not degrade — it aborts, which is why the release ended up with no artifacts attached.

Observed on the v0.4.3 repair dispatch (run 33049593932), which fetched the published artifacts from PyPI successfully and then died on signing.

v3.1.0 moved the action to sigstore-python 4.x for Rekor v2; v3.5.0 is current. rekor-version still defaults to 1 in the action's 3.x series, so bundle format is unchanged and the dist/*.sigstore.json upload glob is unaffected. Still pinned by SHA, with a note at both call sites recording why pinning back below v3.1.0 breaks signing.

After this merges

Re-dispatch release.yml with release_tag: v0.4.3 to attach and sign the bytes PyPI already holds. That path emits no SBOM by design, so v0.4.3 keeps signed artifacts without one; 0.4.4 onward gets both.

…g of one

The closure check read every Requires-Dist from the wheel and demanded each
name appear in the SBOM, skipping only lines containing the literal string
"extra ==". That is a hand-rolled evaluation of exactly one marker, and it is
blind to every other one.

`tzdata; sys_platform == "win32"` carries no extra, so it was demanded on the
ubuntu runner that builds the SBOM -- where it is correctly not installed,
because the marker says so. The job failed the v0.4.3 release with

  SBOM lists 3 components but is missing 1 of provide-foundation's
  dependencies (tzdata) -- wrong environment

Two commits in that same release collided: 61f2230 added this proof, and
74c6ba4 added the first conditional dependency this project has ever had.
Neither was wrong alone, and no earlier release could have caught it.

Markers are now evaluated with packaging, against an empty `extra` -- which is
what makes `extra == "cli"` false, since no extra was requested when the wheel
was installed. The checker runs under the venv's own interpreter rather than
the runner's, because the only environment whose marker answers mean anything
here is the one the SBOM describes.

packaging is installed after the SBOM is generated. That order is load-bearing:
this venv is the environment the document describes, so installing it earlier
would publish packaging as a component of the release.

An unparseable Requires-Dist now fails with the offending line rather than an
InvalidRequirement traceback.

Verified against a fresh `uv build` of 0.4.3:
  - main's script reproduces the CI failure verbatim, on macOS, same reason.
  - this one reports "describes provide-foundation 0.4.3 with 3 dependencies",
    listing attrs, structlog and tomli_w -- and not packaging.
  - dropping structlog from the generated SBOM still fails the check, so it
    has not been weakened into always passing.
…rifies

Both signing steps pinned sigstore/gh-action-sigstore-python at v3.0.0, from
July 2024. That version installs `sigstore ~= 3.0`, and sigstore-python 3.x
bundles a TUF root that can no longer verify Sigstore's production root:

  tuf.api.exceptions.UnsignedMetadataError: root was signed by 0/3 keys

raised from TrustedRoot.production() before anything is signed. Signing does
not degrade here, it aborts -- so a release reaches PyPI and the GitHub release
gets no artifacts and no signatures at all.

Seen on the v0.4.3 repair dispatch, which fetched the published artifacts from
PyPI successfully and then failed on the signing step.

v3.1.0 moved the action to sigstore-python 4.x for Rekor v2 compatibility;
v3.5.0 is current. `rekor-version` still defaults to 1 in the action's 3.x
series, so the bundles this produces keep the same format and the
`dist/*.sigstore.json` upload glob is unaffected.

Pinned by commit SHA as before, with a note at both call sites recording why
pinning back below v3.1.0 breaks signing.
@livingstaccato
livingstaccato merged commit 629ec2c into main Aug 27, 2026
9 checks passed
@livingstaccato
livingstaccato deleted the fix/sbom-environment-markers branch August 27, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant