mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-09 01:35:18 +02:00
The CODEOWNERS required checks blocked every PR — the real root cause was a name mismatch, compounded by a path filter: - branch-protection.json required the contexts `CODEOWNERS / drift` and `CODEOWNERS / noedit` (the GitHub UI "workflow / job-id" display form), but the jobs report check-run names from their `name:` fields — "CODEOWNERS matches source" / "CODEOWNERS not hand-edited". The required contexts therefore never matched any reported check and sat permanently pending. - The workflow was also path-filtered to CODEOWNERS files, so it didn't even run for most PRs. Net effect: with both required checks unsatisfiable, every PR could only land via admin override (e.g. #140). Fixes: - A: drop the `paths:` filter so the workflow runs on every PR and both required contexts always report. - name fix: point branch-protection.json at the actual job names verbatim, and add a doc note that the contexts must equal the job `name:` values. - B: the `drift` job now re-renders and, on same-repo PRs, auto-commits the regenerated artifacts back to the branch (mirrors the openapi.json job in ci.yml); forks / manual runs strict-check instead. Contributors no longer run the script by hand. - D: render-codeowners.py also generates a "who owns what" path->owners + roles table spliced into docs/dev/codeowners.md between markers, so the human-readable view never drifts. Idempotent; CODEOWNERS output unchanged. - docs: correct the stale `enforce_admins: true` line (JSON and live are false). NOTE: the branch-protection.json change only takes effect after an admin runs `./scripts/apply-branch-protection.sh` (deliberate manual step, per docs/dev/branch-protection.md). Until then `main` still requires the old mismatched contexts, so this PR itself needs an admin-override merge — the last one that should be necessary. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
110 lines
4.7 KiB
YAML
110 lines
4.7 KiB
YAML
name: CODEOWNERS
|
|
|
|
# Runs on EVERY pull request (no paths filter). The two jobs below are
|
|
# required status checks on `main`; a path-filtered required check never
|
|
# reports for PRs outside the filter and leaves them permanently "pending"
|
|
# (the trap that forced admin-override merges). Always-run + cheap
|
|
# short-circuit is what keeps them honest.
|
|
on:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
# `drift` auto-commits the regenerated artifacts back to same-repo PR
|
|
# branches, so it needs write access.
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
# NOTE: the job `name:` values below ("CODEOWNERS matches source" /
|
|
# "CODEOWNERS not hand-edited") ARE the status-check contexts that
|
|
# .github/branch-protection.json must list verbatim. Renaming a job here
|
|
# is a branch-protection change — update the JSON and re-apply.
|
|
drift:
|
|
name: CODEOWNERS matches source
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v5.0.1
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5.4.0
|
|
with:
|
|
python-version: '3.13'
|
|
|
|
- name: Install PyYAML
|
|
run: pip install pyyaml
|
|
|
|
- name: Re-render CODEOWNERS + ownership docs
|
|
run: python3 .github/scripts/render-codeowners.py
|
|
|
|
# Same-repo PR: push the regenerated artifacts back so contributors
|
|
# never have to run the script locally. Mirrors the openapi.json
|
|
# auto-commit in ci.yml (separate shallow clone of the head branch so
|
|
# the pushed commit carries only the regenerated files).
|
|
- name: Commit regenerated artifacts to PR branch
|
|
if: |
|
|
github.event_name == 'pull_request' &&
|
|
github.event.pull_request.head.repo.full_name == github.repository
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
if git diff --quiet -- .github/CODEOWNERS docs/dev/codeowners.md; then
|
|
echo "CODEOWNERS and ownership docs already in sync."
|
|
exit 0
|
|
fi
|
|
tmp=$(mktemp -d)
|
|
git clone --depth 1 --branch "${{ github.head_ref }}" \
|
|
"https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git" \
|
|
"$tmp"
|
|
cp .github/CODEOWNERS "$tmp/.github/CODEOWNERS"
|
|
cp docs/dev/codeowners.md "$tmp/docs/dev/codeowners.md"
|
|
cd "$tmp"
|
|
if git diff --quiet -- .github/CODEOWNERS docs/dev/codeowners.md; then
|
|
echo "Head branch already matches; nothing to push."
|
|
exit 0
|
|
fi
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
git add .github/CODEOWNERS docs/dev/codeowners.md
|
|
git commit -m "chore: regenerate CODEOWNERS + ownership docs"
|
|
git push
|
|
|
|
# Fork PR / workflow_dispatch: cannot push back, so enforce drift
|
|
# strictly. The contributor runs the script and commits the result.
|
|
- name: Verify in sync (forks / manual runs)
|
|
if: |
|
|
!(github.event_name == 'pull_request' &&
|
|
github.event.pull_request.head.repo.full_name == github.repository)
|
|
run: |
|
|
if ! git diff --quiet -- .github/CODEOWNERS docs/dev/codeowners.md; then
|
|
echo "::error::Generated CODEOWNERS / ownership docs are out of sync with .github/codeowners-roles.yml."
|
|
echo "::error::Run \`python3 .github/scripts/render-codeowners.py\` and commit the result."
|
|
echo "--- diff ---"
|
|
git --no-pager diff -- .github/CODEOWNERS docs/dev/codeowners.md
|
|
exit 1
|
|
fi
|
|
echo "Generated artifacts are in sync with their source."
|
|
|
|
noedit:
|
|
name: CODEOWNERS not hand-edited
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v5.0.1
|
|
with:
|
|
# Need history so we can diff against the PR base.
|
|
fetch-depth: 0
|
|
|
|
- name: Reject hand-edits to generated file
|
|
# Only meaningful for PRs (needs a base to diff against).
|
|
if: github.event_name == 'pull_request'
|
|
run: |
|
|
base="origin/${{ github.base_ref }}"
|
|
git fetch origin "${{ github.base_ref }}" --quiet
|
|
changed=$(git diff --name-only "$base" HEAD)
|
|
edited_generated=$(echo "$changed" | grep -E '^\.github/CODEOWNERS$' || true)
|
|
edited_source=$(echo "$changed" | grep -E '^\.github/codeowners-roles\.yml$' || true)
|
|
if [ -n "$edited_generated" ] && [ -z "$edited_source" ]; then
|
|
echo "::error::This PR edits .github/CODEOWNERS but not its source .github/codeowners-roles.yml."
|
|
echo "::error::Edit the yml and regenerate via \`python3 .github/scripts/render-codeowners.py\`."
|
|
exit 1
|
|
fi
|
|
echo "CODEOWNERS edits accompany source edits (or no CODEOWNERS edits in this PR)."
|