Merge pull request #64 from constk/develop #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Branch protection sync | |
| # Applies the declarative branch-protection configuration in | |
| # .github/branch-protection/*.json to main and develop. See that directory's | |
| # README for rationale and the trigger matrix. | |
| on: | |
| schedule: | |
| # Weekly drift re-assertion, Monday 06:00 UTC. Same slot as the security | |
| # workflow and Dependabot for governance-activity clustering. | |
| - cron: "0 6 * * 1" | |
| workflow_dispatch: | |
| push: | |
| branches: [main] | |
| paths: | |
| - .github/branch-protection/** | |
| - .github/workflows/branch-protection.yml | |
| permissions: | |
| contents: read | |
| # Serialise concurrent applies. A scheduled run, a manual dispatch, and a | |
| # push landing around the same time could otherwise race on the same PUT. | |
| # cancel-in-progress: false — never interrupt a protection apply mid-flight. | |
| concurrency: | |
| group: branch-protection-sync | |
| cancel-in-progress: false | |
| jobs: | |
| apply: | |
| name: Apply ${{ matrix.branch }} protection | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| branch: [main, develop] | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Verify token is configured | |
| env: | |
| GH_TOKEN: ${{ secrets.BRANCH_PROTECTION_TOKEN }} | |
| run: | | |
| if [ -z "$GH_TOKEN" ]; then | |
| echo "::error::BRANCH_PROTECTION_TOKEN secret is not set." | |
| echo "::error::See docs/DEVELOPMENT.md#branch-protection-sync-setup." | |
| exit 1 | |
| fi | |
| - name: Snapshot current protection (before) | |
| env: | |
| GH_TOKEN: ${{ secrets.BRANCH_PROTECTION_TOKEN }} | |
| run: | | |
| # May 404 if protection doesn't exist yet (first run). That's fine. | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "/repos/${{ github.repository }}/branches/${{ matrix.branch }}/protection" \ | |
| > before.json 2>/dev/null || echo '{"note": "no protection set before run"}' > before.json | |
| - name: Apply ${{ matrix.branch }} protection | |
| env: | |
| GH_TOKEN: ${{ secrets.BRANCH_PROTECTION_TOKEN }} | |
| run: | | |
| gh api \ | |
| --method PUT \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| "/repos/${{ github.repository }}/branches/${{ matrix.branch }}/protection" \ | |
| --input ".github/branch-protection/${{ matrix.branch }}.json" | |
| - name: Snapshot current protection (after) | |
| env: | |
| GH_TOKEN: ${{ secrets.BRANCH_PROTECTION_TOKEN }} | |
| run: | | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "/repos/${{ github.repository }}/branches/${{ matrix.branch }}/protection" \ | |
| > after.json | |
| - name: Summary (with before → after diff) | |
| if: always() | |
| run: | | |
| { | |
| echo "### Branch protection: ${{ matrix.branch }}" | |
| echo "" | |
| echo "**Config source:** \`.github/branch-protection/${{ matrix.branch }}.json\`" | |
| echo "" | |
| echo "**Before → after diff** (empty block = no drift was present):" | |
| echo "" | |
| echo '```diff' | |
| diff -u before.json after.json || true | |
| echo '```' | |
| echo "" | |
| echo "Review current state at https://github.com/${{ github.repository }}/settings/branches" | |
| } >> "$GITHUB_STEP_SUMMARY" |