feat: add publish-manifests reusable workflow (manifests-only OCI publish)#319
Merged
Conversation
…lish) Lift the generic "publish a Kubernetes manifests directory as a cosign-signed OCI artifact, with no container image build" pattern into a shared reusable workflow, so manifests-only repos stop carrying it inline. It is the manifests-only sibling of publish-app.yaml: checkout → flux push artifact (semver tag, e.g. 1.2.3 from v1.2.3) → tag latest → resolve the pushed digest → keyless cosign sign by digest (Fulcio/Rekor via GitHub OIDC). Inputs: oci-name (override the github.repository-derived OCI name for repos whose name is an invalid OCI path component, e.g. .github → devantler-tech/github-config), deploy-path (default ./deploy), and dry-run (CI interface validation). Auth uses the GHCR-scoped GITHUB_TOKEN — no secrets required. Because signing runs inside this reusable workflow, the cosign certificate identity (OIDC subject) is this workflow's path (.../publish-manifests.yaml@<ref>), not the caller's — verifiers must match that. Documented in the README and reflected in the first consumer (devantler-tech/.github cd.yaml) and its platform OCIRepository verifier. Wired into ci.yaml as a dry-run [Test] job (non-gating publish workflow ⇒ happy-path coverage is complete) and registered in ci-required-checks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
🎉 This PR is included in version 5.6.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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.
What
Adds
publish-manifests.yaml— a reusable workflow that publishes a Kubernetes manifests directory to GHCR as a cosign-signed OCI artifact with no container image build. It is the manifests-only sibling ofpublish-app.yaml.This lifts a generic pattern that currently lives inline in two places:
devantler-tech/.githubcd.yaml— publishesdeploy/(Crossplane GitHub state) viaflux push artifact+cosign sign(.github#39).devantler-tech/platformcd.yaml— publishesplatform/manifestsviaksail workload push+cosign sign.Per the portfolio principle of lifting generic patterns into shared libraries, the manifests-only publish belongs here so every such repo inherits one vetted, pinned implementation.
Behaviour
Modelled on
publish-app.yaml, minus the docker build and image-digest-pin steps:vX.Y.Ztag → checkout.docker/login-action(GHCR viaGITHUB_TOKEN).publish-app.yaml).flux push artifact oci://<registry>/<name>/manifests:<version>(version = tag with thevstripped, e.g.1.2.3) →flux tag artifact … --tag latest.docker buildx imagetools inspect) andcosign signby digest, keyless (Fulcio/Rekor via GitHub OIDC).Inputs
oci-name${{ github.repository }}<owner>/<name>), no registry prefix //manifestssuffix. Override when the repo name is an invalid OCI path component — e.g..github(leading dot) →devantler-tech/github-config.deploy-path./deploydry-runfalseAuth uses the GHCR-scoped
GITHUB_TOKEN— no secrets required.Cosign identity (load-bearing for consumers)
Because signing runs inside this reusable workflow, the cosign certificate identity (OIDC
subject) is this workflow's path —https://github.com/devantler-tech/reusable-workflows/.github/workflows/publish-manifests.yaml@<ref>— not the caller's. This matches howpublish-app.yaml-signed artifacts already verify in platform (…/publish-app.yaml@.+$). Verifiers (OCIRepository.verify.matchOIDCIdentity) must match thepublish-manifests.yamlsubject.Validation
actionlintclean onpublish-manifests.yaml. (The two pre-existingcode-qualitypermission notes inci.yamlare unrelated — actionlint's bundled scope list is stale.)ci.yamlas adry-run[Test]job and registered inci-required-checks(needs+job-results). A publish workflow is non-gating, so happy-path coverage is complete perAGENTS.md.Coordinated cutover (do not merge in isolation)
This is the first of three coupled changes for the
github-configartifact. The cosign signer and verifier must flip together:reusable-workflowsversion.cd.yamlcallspublish-manifests.yaml(pin to the release SHA once cut;@mainuntil then).k8s/providers/hetzner/github/sync.yamlverify.matchOIDCIdentity.subject→…/publish-manifests.yaml@.+$.The
github-configartifact is not in production yet (both #39 and #2039 are drafts), so there is no live verification to break — but #39 and #2039 must land together so the verified identity always matches the signer.Follow-up (separate PR): migrate platform's own
cd.yaml(ksail workload push) to this workflow once itsplatform/manifestsOCIRepository verifier is cut over in the same coordinated way. It additionally does SBOM/SLSA attestation, so it's a larger, separate change.🤖 Generated with Claude Code