feat: emit branch-protection.json from the manifest#238
Merged
Conversation
Signed-off-by: Joshua Temple <joshua.temple@stablekernel.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.
Problem
Operators protecting a cascade-managed trunk had to hand-assemble the GitHub branch-protection PUT body and guess which status-check contexts were safe to require. Requiring the wrong context (one that never reports) silently blocks every pull request.
Fix
Adds a new top-level command,
cascade branch-protection, in a newinternal/branchprotectionpackage. It emits a JSON wrapper with two keys:protection(the exact body to PUT torepos/{owner}/{repo}/branches/{branch}/protection) andoperator_todo(sibling guidance that is never sent to GitHub). cascade emits the file; the operator applies it. cascade never calls the GitHub API.Flags:
--config/-c,--manifest-key,--branch(defaultmain),--output/-o(default stdout,-also stdout). The command is emit-on-demand and is not added to the verify-tracked Plan set.Contexts derivation and the safety invariant
GitHub records a check-run context under a job's
name:. The requiredcontextscontain only the cascade-controlledSetupandFinalizesteps jobs, whose names cascade emits and now reads from sharedgenerate.SetupJobName/generate.FinalizeJobNameconstants (so a rename updates both the generated workflow and the emitted contexts in lockstep). Both jobs are unconditional (setup has noif:, finalize usesalways()), so they always report, which is what makes them safe to require. Because of this, the.protectionobject applied verbatim never creates a required check that can never report, so it never blocks a pull request on its own.The reusable-workflow caller jobs (validate, build, deploy) are deliberately omitted from
contexts: cascade knows each caller's<DisplayName>but not the inner job name GitHub appends to form the real<DisplayName> / <inner-job>context, and that inner job lives in the operator's reusable workflow. Requiring a bare prefix would never match and would block every pull request, so those prefixes are surfaced underoperator_todo.complete_these_contextsas<DisplayName> / <inner-job>placeholders for the operator to complete. With no callbacks, that array is emitted as an empty list for output stability.Verification
go build ./cmd/... ./internal/...clean.go test ./... -count=1: all packages pass (generator output stays byte-identical after the constant refactor).golangci-lint run ./...: no issues.contextsfor a validate+build+deploy manifest, each surfaced as a placeholder inoperator_todo), determinism, JSON round-trip, defaults, andrestrictions: nullpresent.NewCommand()end to end against a temp manifest. No Dockere2e/scenarios/scenario fits: this change emits no workflow and no schema field, so there is no committed workflow fixture for testcontainers+gitea+act to exercise. The integration test follows theverify_clean_test.goprecedent and notes this in a comment.Defaults match the existing hotfix branch-protection advisory (
required_approving_review_count: 1,enforce_admins: true). No new manifest field;CurrentSchemaVersionunchanged.Closes #5