Skip to content

feat: apply-branch-protection — codify protoLabs ruleset defaults#11

Merged
mabry1985 merged 1 commit into
mainfrom
feat/apply-branch-protection
May 24, 2026
Merged

feat: apply-branch-protection — codify protoLabs ruleset defaults#11
mabry1985 merged 1 commit into
mainfrom
feat/apply-branch-protection

Conversation

@mabry1985
Copy link
Copy Markdown
Contributor

Summary

Closes #6 and #10. Adds a new CLI for adopting the protoLabs recommended branch protection ruleset across any repo in the org.

Two opinions, both off-by-default in GitHub's UI

1. required_status_checks is for correctness, not advisory signals (#10)

Drop LLM review bots (CodeRabbit, protoquinn[bot], etc.) from the required-checks list. Required checks should reflect build/test/lint — things that prove the code works. Bots already have a legitimate veto path via reviewDecision — their silence shouldn't block merges.

Live evidence from protoLabsAI/protoMaker#3745: PR shipped in <2 min, all CI passed, CodeRabbit hadn't posted a status yet, PR sat BLOCKED until a manual nudge. After dropping CodeRabbit from the required list, the same shape now merges cleanly.

2. strict_required_status_checks_policy: false for fast-moving repos (#6)

Strict mode forces a PR's branch to be up-to-date with main before merge. For solo-dev or small-team repos with linear PR stacks, that's an N×CI-cycle drag. The actual safety net is the test suite — stale branches that break main usually fail their own CI first.

What lands

Path What
bin/apply-branch-protection.mjs CLI entry point. Node ESM. Backed by gh api.
lib/branch-protection.mjs Pure functions: filter, merge, apply, strip read-only.
test/branch-protection.test.mjs 13 unit tests covering the lib.
docs/branch-protection-defaults.md Full rationale + flag reference + when-NOT-to-use list.
README.md New "Branch protection defaults" section + dev help.
package.json apply-branch-protection bin entry + smoke command.

Architecture note

Pure-functions split: lib does all decisions on JSON-in/JSON-out shapes, bin does I/O (fetch via gh api, print diff, optionally PUT). Tests cover the lib in isolation; bin is exercised via --help smoke and a dry-run against protoLabsAI/protoMaker that returns "no change" (verified post-#3745).

Defaults are intentionally minimal

DEFAULT_REQUIRED_CHECKS = ['build', 'test', 'checks']. Repo-specific rollups like ci-complete must be opted in via --required-checks, because silently requiring a context that a repo doesn't emit would block every PR in that repo.

Test plan

  • npm test — 18/18 pass (13 new + 5 existing code-review tests)
  • npm run lint — clean
  • npm run smoke — all 4 bin entries respond to --help
  • Live dry-run against protoLabsAI/protoMaker returns "no change" (correct, since #3745 already landed manually)

Usage examples

# Dry run (default)
npx @protolabsai/release-tools apply-branch-protection \\
  --repo protoLabsAI/myrepo --branch main

# Apply defaults
npx @protolabsai/release-tools apply-branch-protection \\
  --repo protoLabsAI/myrepo --branch main --apply

# Strict mode for larger teams
npx @protolabsai/release-tools apply-branch-protection \\
  --branch main --strict --apply

# Custom required checks (Rust)
npx @protolabsai/release-tools apply-branch-protection \\
  --required-checks cargo-test,cargo-clippy,cargo-fmt --apply

Closes #6
Closes #10

Adds a new CLI/bin entry for any protoLabs repo to adopt the recommended
branch protection ruleset with one command. Pairs two opinions that are
both off-by-default in GitHub's UI:

1. required_status_checks is for correctness, not advisory signals.
   Drop LLM review bots (CodeRabbit, protoquinn[bot], etc.) from the
   required-checks list. Bots already have a legitimate veto path via
   reviewDecision — their silence shouldn't block merges. Closes #10.

2. strict_required_status_checks_policy: false for fast-moving repos.
   Strict mode forces an N×CI-cycle drag on stacked work. The actual
   safety net is the test suite. Closes #6.

What lands:

  bin/apply-branch-protection.mjs   CLI entry point (Node ESM, gh-cli backed)
  lib/branch-protection.mjs         pure functions: filter, merge, apply, strip
  test/branch-protection.test.mjs   13 unit tests
  docs/branch-protection-defaults.md  full rationale + flag reference
  README.md                         section + dev help update
  package.json                      bin entry + smoke command

Pure-functions split: the lib does all decisions on JSON-in/JSON-out
shapes, the bin does I/O (fetch ruleset via `gh api`, print diff,
optionally PUT). Tests cover the lib in isolation; the bin is covered
by --help smoke + a dry-run against protoLabsAI/protoMaker that returns
"no change" (verified post-#3745 dismissal landed).

Defaults are intentionally minimal — build/test/checks. Repo-specific
rollups like ci-complete must be opted in via --required-checks, because
silently requiring a context that a repo doesn't emit would BLOCK every
PR there.

18/18 tests pass. Lint clean. Smoke clean.

Closes #6
Closes #10
@mabry1985 mabry1985 merged commit 2fe877d into main May 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant