Skip to content

chore(asf): enable required-status-checks protection on main#204

Merged
potiuk merged 1 commit into
apache:mainfrom
potiuk:asf-yaml-main-protection
May 18, 2026
Merged

chore(asf): enable required-status-checks protection on main#204
potiuk merged 1 commit into
apache:mainfrom
potiuk:asf-yaml-main-protection

Conversation

@potiuk

@potiuk potiuk commented May 18, 2026

Copy link
Copy Markdown
Member

Summary

main on this repo is currently unprotected (verified — GET /branches/main/protection returns 404; no rulesets attached). The prior .asf.yaml comment said "branch protections are configured directly in GitHub for now", but inspection showed no direct-on-GitHub rule was ever created. This PR moves branch-protection ownership into .asf.yaml where it sits next to the rest of the repo config; ASF Infra reconciles it within a few minutes of merge.

What lands

A new protected_branches: main: block in .asf.yaml, with eleven required status checks — every workflow that runs on every PR, named with its exact job context:

Workflow Required context(s)
codeql.yml (post-#203) Analyze (python), Analyze (actions)
zizmor.yml zizmor
pre-commit.yml prek
tests.yml (matrix) pytest (oauth-draft), pytest (generate-cve-json), pytest (skill-validator), pytest (privacy-llm-checker), pytest (privacy-llm-redactor), pytest (vulnogram-oauth-api), pytest (sandbox-lint)

Plus:

  • strict: false — merging on main does not invalidate every other open PR.
  • required_linear_history: true — matches the existing enabled_merge_buttons.squash: true.
  • required_conversation_resolution: true — blocks merge while any review thread is unresolved (independent of the approval requirement).
  • required_signatures: false — external contributors without GPG/SSH signing must remain able to contribute.

What's intentionally NOT required

  • asf-allowlist-check — path-filtered to .github/**.
  • lint .claude/settings.json against baseline (sandbox-lint) — path-filtered to .claude/settings.json + tools/sandbox-lint/** + .github/workflows/sandbox-lint.yml.
  • lychee (link-check) — runs on every PR but external link rot is a maintenance concern handled by the daily scheduled run, not a merge-blocker.

Classic branch protection has no "only require if run" semantics — a path-filtered job that doesn't post a status would block every PR that didn't touch the filtered paths. The three above are excluded for that reason.

Temporary posture — no approval requirement (yet)

required_pull_request_reviews: is deliberately omitted. The .asf.yaml block carries a prominent TEMPORARY POSTURE — REVISIT AT PMC FORMATION comment so this doesn't get forgotten. Rationale: the framework is in its bootstrap phase under the Airflow PMC umbrella with a small committer set (MISSION.md); requiring approvals at this stage would block routine maintainer self-merges. Status checks alone gate merges in the interim.

When the project establishes its own PMC, that block must be re-added with required_approving_review_count: 1 (or higher), dismiss_stale_reviews tuned to the new committer / CODEOWNERS shape, and any code-owner requirements the new PMC chooses to set.

Test plan

  • After merge, wait ~5 min for ASF Infra to reconcile, then gh api repos/apache/airflow-steward/branches/main/protection returns a non-404 payload listing the eleven contexts above.
  • Open a follow-up trivial PR (e.g. a typo fix) and confirm the "Merge" button is gated on the eleven checks — and confirm that no approval is required and the maintainer can self-merge once all checks pass.
  • Open a follow-up PR with an unresolved review thread; confirm merge is blocked even with checks green (validates required_conversation_resolution).
  • Confirm path-filtered workflows (asf-allowlist-check, sandbox-lint) being skipped on an unrelated PR does NOT block merging (validates the omission rationale).
  • Sanity: a non-squash merge attempt is rejected (validates required_linear_history together with the squash-only enabled_merge_buttons).
  • At PMC formation, file a follow-up PR adding required_pull_request_reviews: and remove the TEMPORARY POSTURE comment.

Generated-by: Claude Code (Opus 4.7)

ASF Infra was previously not configuring any branch protection on
`main` for this repo — verified via the GitHub protection API
(`branches/main/protection` → 404, `branches/main.protected` →
false) and confirmed by the prior `.asf.yaml` comment ("No
`protected_branches:` block by design"). The comment also said
"configured directly in GitHub for now", but inspection shows no
direct-on-GitHub rule was ever created. This change moves
branch-protection ownership into `.asf.yaml` where it sits next to
the rest of the repo config.

What landed in `.asf.yaml`:

- New `protected_branches: main:` block.

- `required_status_checks` lists the eleven contexts that run on
  every PR against `main` (so they always post a status — a
  prerequisite for classic branch-protection's
  required-checks model, which lacks "require only if run"
  semantics):

    * Analyze (python)
    * Analyze (actions)
    * zizmor
    * prek
    * pytest (oauth-draft)
    * pytest (generate-cve-json)
    * pytest (skill-validator)
    * pytest (privacy-llm-checker)
    * pytest (privacy-llm-redactor)
    * pytest (vulnogram-oauth-api)
    * pytest (sandbox-lint)

  Path-filtered workflows (`asf-allowlist-check`, sandbox-lint's
  `lint .claude/settings.json against baseline`) are deliberately
  excluded — making them required would block any PR that didn't
  touch the filtered paths. `lychee` (link-check) is also
  excluded; external link rot is a maintenance concern handled
  by the daily scheduled run, not a merge-blocker.

  `strict: false` so a merge to `main` does not invalidate every
  other open PR — standard ASF multi-contributor practice.

- `required_linear_history: true` matches the existing
  `enabled_merge_buttons.squash: true` setting — squash is the
  only enabled merge mode.

- `required_conversation_resolution: true` blocks merge while
  any review thread is unresolved. Bites independently of the
  approval requirement.

- `required_signatures: false` — external contributors without
  configured GPG/SSH signing would otherwise be blocked from
  contributing.

- `required_pull_request_reviews:` deliberately OMITTED for now,
  with a prominent TEMPORARY POSTURE block in the .asf.yaml
  comments calling out that approvals MUST be re-enabled when the
  project establishes its own PMC. The framework is in bootstrap
  under the Airflow PMC umbrella with a small committer set
  (MISSION.md); requiring approvals at this stage would block
  routine maintainer self-merges. Status checks alone gate
  merges in the interim.

ASF Infra reconciles `.asf.yaml` within a few minutes of merge.
The very next PR against `main` will block on all eleven status
checks — including a maintainer's own PRs — but no approval is
required for self-merge during this temporary posture.

Generated-by: Claude Code (Opus 4.7)
@potiuk potiuk merged commit 54a2ce4 into apache:main May 18, 2026
12 checks 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

Development

Successfully merging this pull request may close these issues.

1 participant