Branch protection for main¶
Configure a repository ruleset (Settings -> Rules -> Rulesets) that targets the default branch. Rulesets are preferred over classic branch protection: they apply to administrators too, and OpenSSF Scorecard reads them.
Current state (2026-10-22)¶
This ruleset is not configured yet. On CD-LC/vegaduta today:
gh api repos/CD-LC/vegaduta/rulesetsreturns[], andgh api repos/CD-LC/vegaduta/branches/main/protectionreturns 404 "Branch not protected". Nothing stops a push tomainthat skipped CI, a force push, or a merge without green checks. The rule in GOVERNANCE.md and CONTRIBUTING.md is kept by the maintainer, not by GitHub.- OpenSSF Scorecard reports Branch-Protection 0 and Code-Review 0 for the same reason (no ruleset, and changesets without a second reviewer). Creating the ruleset raises the first; the second stays low while one maintainer merges their own pull requests (see "While there is only one maintainer" below).
- The
@CD-LC/maintainersteam named in.github/CODEOWNERShas to exist before "require review from code owners" can work.gh api repos/CD-LC/vegaduta/codeowners/errorsreports "Unknown owner" for every rule until it does.
What the repository owner must do, in this order:
- Create the public team
maintainersin theCD-LCorganization, add the project lead, and give it Write on the repository (repo-setup.md). Check:gh api repos/CD-LC/vegaduta/codeowners/errors --jq '.errors | length'prints0. - Open any pull request so
CI OKandCodeQL OKreport once (a check name is offered in the picker only after it has reported; see "After the first run"). - Create the ruleset on the default branch as described below.
- Verify:
gh api repos/CD-LC/vegaduta/rules/branches/main --jq 'length'prints a number above 0, and a direct push tomainis refused.
Until step 3 is done, treat every statement below as the intended configuration, not as a description of what GitHub enforces.
Required status checks¶
Require exactly these check names, with "require branches to be up to date" enabled:
| Check | Workflow | What it covers |
|---|---|---|
CI OK |
ci.yml |
Every CI job the change's paths trigger (core, the Java Agent SDK, SDK clients and consumer contracts, web, Python incl. the lock-drift check and the other Python services, Node services, shellcheck, hadolint, compose, Helm, and docs links when docs change), plus the always-on jobs: Static gates and Secret scan (gitleaks) (from static-gates.yml, called by ci.yml), DCO sign-off and Dependency review (pull requests only; skipped while the repository is private, see repo-setup.md). Jobs skipped by path filters count as passed; a failed or cancelled job fails it. |
CodeQL OK |
codeql.yml |
CodeQL for java-kotlin, javascript-typescript and python. Runs on every pull request, including docs-only changes, so it always reports. While code scanning is unavailable (a private repository without Advanced Security) the analysis is skipped and CodeQL OK passes; see repo-setup.md. |
Do not require the individual job names (core (Maven verify, JDK 21),
Analyze (python), ...). Path-filtered jobs do not run on every pull request,
and a required check that never reports blocks the merge forever
("Expected - waiting for status to be reported"). The two aggregators above
always report.
Advisory jobs (the http-gateway example suite, the whole-tree ruff run) are
continue-on-error and never block.
Other rules¶
- Require a pull request before merging; 1 approval; dismiss stale approvals
when new commits are pushed; require approval of the most recent push;
require review from code owners (see
.github/CODEOWNERS). - Block force pushes and branch deletion. Require linear history if you merge with squash or rebase.
- Code scanning: optionally add the "Require code scanning results" rule
(CodeQL, errors and above) in addition to the
CodeQL OKcheck. - Bypass list: empty. Scorecard's Branch-Protection check scores admin bypass lower, and every change should go through the same checks.
While there is only one maintainer¶
GitHub does not let an author approve their own pull request. Until a second maintainer exists (GOVERNANCE.md, "Interim rule"), set the required approvals to 0 but keep "require a pull request" and the two required checks, so every change still goes through CI. Restore 1 approval when the second maintainer is appointed.
After the first run¶
A check name appears in the ruleset's picker only after it has reported once.
Push a branch and open a pull request first, then add CI OK and CodeQL OK.