Publish signed releases with a verified OpenAPI contract label - #10
Merged
Merged
Conversation
Consumers pin this image by digest and read io.github.gh-aw-router.openapi-sha256 to confirm the running container serves the contract they validated against. The Dockerfile never set that label, so any image built outside the local test harness was unusable. The label now comes from an OPENAPI_SHA256 build argument, and the build copies openapi.yaml in and checks it with sha256sum, so the label cannot drift from the shipped contract. The release workflow is workflow_dispatch only. It reads the version from the package instead of bumping it, so a release follows a reviewed version change, and it refuses to run if the tag exists. It builds amd64 first and runs the container contract suite against that exact image, then pushes linux/amd64 and linux/arm64, signs with cosign, attests an SPDX SBOM, and re-inspects the published labels against the patterns consumers enforce. A release that consumers would reject therefore fails here instead.
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.
Adds a release pipeline and the provenance label consumers need, plus the refreshed cost routing tables.
Why
Consumers pin this image by digest and read
io.github.gh-aw-router.openapi-sha256to confirm the running container serves the contract they validated against. The Dockerfile never set that label. Only the local test harness injected it with--label, so any image built by CI would have been rejected at startup.The label cannot drift
The label now comes from an
OPENAPI_SHA256build argument. The build copiesopenapi.yamlinto the image and checks it withsha256sum --check --strict, so a mismatch fails the build rather than shipping a label that lies about the contract. Verified both directions locally: the correct digest produces the label, and a wrong one fails the build step.tests/test_container.pycomputes the digest from the repository and asserts the built image carries it, so the existingcontainerCI job exercises this on every push.Release workflow
workflow_dispatchonly, with adry_runinput that builds and verifies without publishing.It reads the version from the package rather than bumping it, so a release is a deliberate follow-up to a reviewed version change, and it refuses to run if the tag already exists. The Dockerfile already asserts the build argument matches
__version__.Order matters in one place: it builds amd64 and runs the container contract suite against that exact image through
GH_AW_ROUTER_TEST_IMAGEbefore pushing anything. After publishing it pulls by digest and re-inspects the labels against the same patterns consumers enforce, and confirms both platforms are present. A release that consumers would reject fails here instead of at run time.The image is signed with cosign and carries an attested SPDX SBOM. All actions are pinned by SHA.
Routing tables
routing/cost-*.jsonare refreshed with current pricing and model data. Separate commit.Verification
ruff format --check,ruff check,ty checkcleantest_isolated_sourcefails only on the author machine, where public PyPI is TLS-intercepted; it downloads fromfiles.pythonhosted.orgdirectly and will pass in CI