feat: declarative GitHub state in deploy/ (Crossplane, consumed by platform)#39
Merged
Conversation
…rtifact
Add deploy/ holding the devantler-tech org's GitHub configuration as
Crossplane managed resources (provider-upjet-github, namespaced v2
repo.github.m.upbound.io). The platform cluster onboards this repo as the
github-config tenant: it verifies the cosign signature and reconciles the
live org to match these manifests.
- deploy/repositories/{platform,ksail}.yaml — first repos, Observe-first
(read-only adoption; no recreation/deletion risk)
- .github/workflows/cd.yaml — on v* tags, publishes deploy/ as a
cosign-signed OCI artifact to ghcr.io/devantler-tech/github-config/manifests
(manifests-only, no container image; name is github-config because .github
is an invalid OCI path component)
See devantler-tech/platform docs/github-management.md for the architecture
and the GitHub App credential setup (maintainer-gated).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- pin fluxcd/flux2/action to a commit SHA (v2.8.8) per the blanket hash-pinning policy (was @main) - move github.ref_name/sha/repositoryUrl into step env so they are never expanded into the shell script body (template-injection finding) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the inline flux-push + cosign-sign implementation with a call to devantler-tech/reusable-workflows/.github/workflows/publish-manifests.yaml, the generic manifests-only OCI publish lifted into the shared library (reusable-workflows#319). Keeps the github-config OCI name override and the v* tag trigger; drops the duplicated checkout/flux/cosign/auth steps. Signing now happens inside the reusable workflow, so the cosign OIDC subject becomes the reusable workflow's path — the platform github-config OCIRepository verifier is updated to match in platform#2039. Pinned @main until reusable-workflows cuts a release including the new workflow; then pin to the release SHA (Renovate-managed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…policy) The .github repo's zizmor blanket policy requires hash-pinned `uses:`, so `@main` is rejected. Pin to the reusable-workflows#319 branch head SHA that introduces publish-manifests.yaml. Re-pin to the release commit SHA once #319 merges and cuts a release (Renovate-managed thereafter). The platform verifier matches `@.+$`, so the ref does not affect cosign verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The org ruleset requires the `CI - Required Checks` status on every PR, but this repo only had cd.yaml (tag-only), so nothing produced that context and PRs stayed merge-BLOCKED. Add a CI workflow that validates the deploy/ kustomize build on pull_request/merge_group and ends with the required gate job (aggregate-job-checks). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mit) cd.yaml pinned the reusable workflow to 44742c4f — the pre-release branch head of reusable-workflows#319. That PR is now merged and released (v5.6.1), so the old SHA is unreachable from any branch/tag (zizmor impostor-commit alert #15, and it would fail to resolve at runtime). Re-pin to the v5.6.1 release commit f974f62a, which is reachable from the tag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jun 15, 2026
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 a
deploy/directory holding the devantler-tech org's GitHub configuration as Crossplane managed resources, and a workflow to publish it as a cosign-signed OCI artifact. The platform cluster onboards this repo as thegithub-configtenant (platform#2039) — it verifies the signature, then Flux + Crossplane reconcile the live org to match these manifests (and revert out-of-band UI edits). Goal: manage GitHub declaratively instead of via the UI.Contents
deploy/repositories/{platform,ksail}.yaml— the first managed repos as namespacedRepositoryresources (repo.github.m.upbound.io/v1alpha1), Observe-first (managementPolicies: [\"Observe\"]): read-only adoption that mirrors live state intostatus.atProviderand never writes — zero risk of recreating or deleting the real repos. Namespaced MRs have nodeletionPolicy; "never delete" is later expressed by omittingDeletefrommanagementPolicies..github/workflows/cd.yaml— onv*tags, publishesdeploy/as a cosign-signed OCI artifact toghcr.io/devantler-tech/github-config/manifests(manifests-only — no container image). The OCI name isgithub-configbecause.githubis an invalid OCI path component (leading dot); the platform'sOCIRepositorycosign-verifies this workflow's identity.How it fits together
deploy/managed resourcesgithub-confignamespace/SA/Role + namespacedProviderConfig+ cosign-verifiedOCIRepository/Kustomizationinfrastructure/github/app), materialized via ESONamespaced (Crossplane v2) managed resources let the platform apply these with a namespace-scoped tenant ServiceAccount + plain Role — no cluster RBAC — so
.githubis a genuinely isolated tenant.Adoption flow (after merge + platform setup)
v*release → artifact published + signed.github-configtenant pulls + verifies it; the two repos reconcile in Observe mode;status.atProvidermirrors live GitHub.spec.forProvider, promotemanagementPoliciesto all-except-Delete, then roll the rest of the org over incrementally.See platform
docs/github-management.md. Gated on the maintainer creating the org GitHub App + seeding its credentials (details in that doc / the platform PR).🤖 Generated with Claude Code