Branchprotector
branchprotector configures github branch protection according to a specified policy.
Policy configuration
Extend the primary prow config.yaml
document to include a top-level
branch-protection
key that looks like the following:
branch-protection:
orgs:
kubernetes:
repos:
test-infra:
# Protect all branches in kubernetes/test-infra
protect: true
# Always allow the org's oncall-team to push
restrictions:
teams: ["oncall-team"]
# Ensure that the extra-process-followed github status context passes.
# In addition, adds any required prow jobs (aka always_run: true)
required_status_checks:
contexts: ["extra-process-followed"]
presubmits:
kubernetes/test-infra:
- name: fancy-job-name
context: fancy-job-name
always_run: true
spec: # podspec that runs job
This config will:
- Enable protection for every branch in the
kubernetes/test-infra
repo. - Require
extra-process-followed
andfancy-job-name
status contexts to pass before allowing a merge- Although it will always allow
oncall-team
to merge, even if required contexts fail. - Note that
fancy-job-name
is pulled in automatically from thepresubmits
config for the repo, if one exists.
- Although it will always allow
Updating
- Send PR with
config.yaml
changes - Merge PR
- Done!
Make changes to the policy by modifying config.yaml
in your favorite text
editor and then send out a PR. When the PR merges prow pushes the updated config
. The branchprotector applies the new policies the next time it runs (within
24hrs).
Advanced configuration
Fields
See branch_protection.go
and GitHub’s protection api for a complete list of fields allowed
inside branch-protection
and their meanings. The format is:
branch-protection:
# default policy here
orgs:
foo:
# this is the foo org policy
protect: true # enable protection
enforce_admins: true # rules apply to admins
required_linear_history: true # enforces a linear commit Git history
allow_force_pushes: true # permits force pushes to the protected branch
allow_deletions: true # allows deletion of the protected branch
required_pull_request_reviews:
dismiss_stale_reviews: false # automatically dismiss old reviews
dismissal_restrictions: # allow review dismissals
users:
- her
- him
teams:
- them
- those
require_code_owner_reviews: true # require a code owner approval
required_approving_review_count: 1 # number of approvals
required_status_checks:
strict: false # require pr branch to be up to date
contexts: # checks which must be green to merge
- foo
- bar
restrictions: # restrict who can push to the repo
apps:
- github-prow-app
users:
- her
- him
teams:
- them
- those
Scope
It is possible to define a policy at the
branch-protection
, org
, repo
or branch
level. For example:
branch-protection:
# Protect unless overridden
protect: true
# If protected, always require the cla status context
required_status_checks:
contexts: ["cla"]
orgs:
unprotected-org:
# Disable protection unless overridden (overrides parent setting of true)
protect: false
repos:
protected-repo:
protect: true
# Inherit protect-by-default config from parent
# If protected, always require the tested status context
required_status_checks:
contexts: ["tested"]
branches:
secure:
# Protect the secure branch (overrides inhereted parent setting of false)
protect: true
# Require the foo status context
required_status_checks:
contexts: ["foo"]
different-org:
# Inherits protect-by-default: true setting from above
The general rule for how to compute child values is:
- If the child value is
null
or missing, inherit the parent value. - Otherwise:
- List values (like
contexts
), create a union of the parent and child lists. - For bool/int values (like
protect
), the child value replaces the parent value.
- List values (like
So in the example above:
- The
secure
branch inunprotected-org/protected-repo
- enables protection (set a branch level)
- requires
foo
tested
cla
status contexts (the latter two are appended by ancestors)
- All other branches in
unprotected-org/protected-repo
- disable protection (inherited from org level)
- All branches in all other repos in
unprotected-org
- disable protection (set at org level)
- All branches in all repos in
different-org
- Enable protection (inherited from branch-protection level)
- Require the
cla
context to be green to merge (appended by parent)
Developer docs
Run unit tests
go test ./cmd/branchprotector
Run locally
go run ./cmd/branchprotector --help
, which will tell you about the
current flags.
Do a dry run (which will not make any changes to github) with something like the following command:
go run ./cmd/branchprotector \
--config-path=/path/to/config.yaml \
--github-token-path=/path/to/my-github-token
This will say how the binary will actually change github if you add a
--confirm
flag.
Deploy local changes to dev cluster
Run things like the following:
# Build image locally and push it to <YOUR_REGISTRY>
make push-single-image PROW_IMAGE=cmd/branchprotector REGISTRY=<YOUR_REGISTRY>
This will build an image with your local changes, and push it to <YOUR_REGISTRY>
.
Or, if you just want to build an image but not to push, run the following:
# Build image locally
make build-single-image PROW_IMAGE=cmd/branchprotector
This will build an image with your local changes, without pushing it to anywhere.
Deploy cronjob to production
branchprotector image is automatically built as part of prow, see “How to update the cluster” for more details.
Branchprotector runs as a prow periodic job, for example ci-test-infra-branchprotector.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.