Skip to content

Branch Protection

The GitHub repository setting (not a file in this repo) that decides whether the CI checks in CI/CD actually block anything.

Overview

Nothing in this repository can enforce this — it's a GitHub setting only a repo admin can change — which is exactly why it's easy to add a CI check and forget that it isn't actually required anywhere. Without a ruleset or branch protection rule requiring each check by name, every check in CI/CD (build/test, real-Postgres integration, real-envtest, golangci-lint, gofmt, PR title, DCO) is purely informational: it can fail and a merge can still happen anyway.

GitHub's admin bypass permission is a separate setting from whether a check is required — an admin can have bypass and the checks can still be wired up as required, so they run and show pass/fail on every push and PR. The two aren't in tension; this page only covers the required-checks side.

Where to configure it

GitHub has two mechanisms; use whichever this repo already has active. A push rejected (or, for an admin with bypass, accepted with a Bypassed rule violations for refs/heads/main message) mentioning "rule violations" specifically means a ruleset is active, not classic branch protection:

  • Rulesets (current): Settings → Rules → Rulesets → edit (or create) the ruleset targeting main.
  • Classic branch protection: Settings → Branches → Branch protection rules → edit (or add) a rule for main.

Required status checks to add

These are the exact check names as they appear in the Checks tab (each is a job's name: field in the corresponding workflow file — see that file if a name ever needs to be cross-checked after an edit):

Check name Workflow Runs on
Build & Test .github/workflows/ci.yml push + PR to main
Integration tests (real PostgreSQL): postgres:16 .github/workflows/ci.yml push + PR to main
Integration tests (real PostgreSQL): postgres:17 .github/workflows/ci.yml push + PR to main
Integration tests (real PostgreSQL): postgres:18 .github/workflows/ci.yml push + PR to main
Controller tests (real kube-apiserver) .github/workflows/ci.yml push + PR to main
golangci-lint .github/workflows/go-quality.yml push + PR to main
gofmt .github/workflows/go-quality.yml push + PR to main
Enforce Conventional Commits title .github/workflows/pr-title.yml PR to main
Check sign-off (DCO) .github/workflows/dco.yml PR to main

Integration tests (real PostgreSQL) is now a postgres-version: [16, 17, 18] matrix (see Support Matrix), so it shows up as three separate checks above instead of one — require all three, not just one, or a regression against 17/18 only could still merge.

Integration tests (EDB Postgres): EDB Postgres Advanced Server (EPAS) / ... Extended Server (PGE) (also in ci.yml) are deliberately not in this list: that job is entirely skipped unless the EDB_SUBSCRIPTION_TOKEN repository secret is configured (see Support Matrix) and runs with continue-on-error: true even when it does run, so making it a required check would either block every fork PR (secret never present there) or silently pass on real failures — neither is what "required" should mean.

Manual E2E (real container) (e2e-manual.yml) is deliberately not in this list — it's workflow_dispatch-only, so it never runs against a PR and can't be a required check.

Extending protection to release-X.Y branches

Every release-X.Y maintenance branch (created automatically by release-branches.yml — see Backporting) is a real target branch for backport pull requests, so the same Build & Test / integration / golangci-lint / gofmt checks above apply there too, via ci.yml/go-quality.yml's release-* branch filter (see CI/CD). Whichever mechanism this repo uses (ruleset or classic branch protection), target it at release-* as a second rule/pattern alongside main's, requiring the same five rows from the table above — Enforce Conventional Commits title and Check sign-off (DCO) are the two exceptions, since those two checks are deliberately not extended to backport PRs (see Backporting: CI on backport pull requests for why) and so cannot be required there without blocking every backport PR from ever becoming mergeable.

Other settings worth enabling alongside the checks

  • Require a pull request before merging — confirm it's on and scoped to main.
  • Require branches to be up to date before merging — otherwise a status check can pass against a stale base and still land a broken merge.
  • Keep bypass scoped to repo admins only (not "everyone", not a public team) — bypass shouldn't be wider than "people who genuinely need to override CI".
  • Do not allow force pushes / Do not allow deletions — protects the commit history CI has already validated.
  • Require approvals — GitHub doesn't count a self-review as an approval, so this only makes sense once there's more than one maintainer or regular external contributors; turn it on (1 approval) at that point, per CONTRIBUTING.md's squash-merge policy.

See also

  • CI/CD — every check referenced in the table above.
  • Backporting — how release-X.Y branches come to exist and why two checks are deliberately excluded from them.
  • Roadmap — this is tracked there as an open operational follow-up.