Repository navigation
feat(distribute): predict protected branches before any write on GitLab and Gitea - #18
Merged
Merged
Conversation
…ab and Gitea
A new optional platform.PushGuard tells which branches a protection rule keeps the write identity from pushing to at all. GitLab's writer reads the project's protected branches (one request; the project and its access level only when a rule matches the sync branch); Gitea's and Forgejo's read GET branches/{b} of each sync branch that exists (protected, user_can_push). When a decision pushes, distribute and distribute --dry-run ask it and block the target rules:protected-branch before any write, with a warning naming the rule; memory upkeep stays. Rules the writer cannot read still show at the push, refused before anything is written. plan, whose reader is no PushGuard, is unchanged.
GitLab applies the most permissive of the protected branches that match a branch, to pushes and force pushes alike (docs.gitlab.com, protected branches and protection rules). doctor's rules check took the strictest instead and could fail a branch another rule lets the writer push to, or warn about force pushes another rule allows; both checks now use one verdict per branch.
The fake platform models it: a Ruleset with NoPush refuses every push with GitLab's message, and WithPushGuard makes the writer report those branches. Tests: the drivers' NoPush and GitLab's verdict over several rules, a conformance case, TestRunProtectedBranch (dry run and distribute blocked, an open pull request kept, the push-time refusal without the guard or with hidden rules), and the live TestProtectedBranch on GitLab (a dry run, and two rules where the permissive one wins) and on Gitea and Forgejo.
Gitea and Forgejo leave effective_branch_protection_name out for a writer without admin rights, so a protected branch's warning names the branch alone. The live tests now expect that, and a dry run on GitLab reports opened with an empty reason.
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.
distribute --dry-runpromised to predict branch rules with the write account, but on GitLab, Gitea and Forgejo a protected sync branch showed only at the push. This predicts it, and fixes howdoctorjudges GitLab's protected branches.Protected branches before any write. A new optional
platform.PushGuardlists the branches a protection rule keeps the write identity from pushing to at all:GET branches/{b}of each sync branch that exists (protected,user_can_push, which the server works out for the caller). The API knows existing branches only, so a protection of a sync branch not created yet still shows at its first push.When a decision pushes,
distributeanddistribute --dry-runask the writer and block the targetrules:protected-branchbefore any write, with a warning naming the branch and, where the platform shows it, the rule. Memory upkeep stays, and an open pull request is left as it is. What the writer cannot read still meets the rule at the push, which refuses it with nothing written.plan, whose reader is noPushGuard, is unchanged.GitLab: the most permissive rule wins. GitLab applies the most permissive of the protected branches that match a branch, to pushes and force pushes alike (protected branches, protection rules).
doctortook the strictest instead, so it could fail a branch another rule lets the writer push to, or warn about force pushes another rule allows. Both checks now share one verdict per branch. The live test confirms it on CE 18.11: a sync branch undertouchmark/*for Maintainers alone and its own rule for Developers with force pushes is delivered and rebuilt.Tests.
NoPushand GitLab's verdict over several rules.PushGuardcase.Ruleset.NoPushrefuses pushes with GitLab's message, andWithPushGuardmakes the writer report them.TestRunProtectedBranch: a dry run anddistributeblocked before writing, an open pull request kept, and the push-time refusal without the guard or with hidden rules.TestProtectedBranch: on GitLab, a dry run predicting the block and the permissive pair. A new test on Gitea and Forgejo: a protection added after the pull request opened is predicted, and one before the sync branch exists is refused at the push.Checked locally.
golang:1.27with-race:distribute,platform/...,cli,report.scripts/e2e/gitlab.sh --run 'TestProtectedBranch|TestDoctor|TestConformance'passes.scripts/e2e/gitea.sh --run 'TestProtectedBranch|TestDistribute'passes on Gitea 28.1.0 and 1.27.3 and Forgejo 16.0.5.