diff --git a/.governance-version b/.governance-version index 79127d8..6a5e98a 100644 --- a/.governance-version +++ b/.governance-version @@ -1 +1 @@ -v1.2.0 +v1.2.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0665b31..f89008c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the org-wide governance in this repository are documented The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/): a **major** bump means a rule change that can newly block merges in consuming repos; **minor** adds rules or tooling that are backwards-compatible; **patch** is clarification only. +## [1.2.1] - 2026-07-27 + +### Fixed + +- `apply_rulesets.sh` now refuses to apply the required-checks ruleset to a repo until `cla.yml` exists on that repo's default branch, instead of creating a merge deadlock (the same bootstrapping bug already fixed once for this repo itself in 1.0.1/1.0.2, reintroduced when retrofitting a new repo — `claude-skills` — without following the documented sequencing) +- `docs/runbook.md`: repo onboarding steps for existing repos now state the merge-then-ruleset ordering explicitly + ## [1.2.0] - 2026-07-08 ### Added diff --git a/docs/runbook.md b/docs/runbook.md index cb32a32..d51cb72 100644 --- a/docs/runbook.md +++ b/docs/runbook.md @@ -16,7 +16,7 @@ How to operate the `traverse-framework` org governance. Written so any agent or 3. Enable settings: `gh api -X PATCH repos/traverse-framework/ -F allow_auto_merge=true -F delete_branch_on_merge=true`, plus `PUT .../private-vulnerability-reporting` and `PUT .../vulnerability-alerts`. 4. Confirm with `scripts/org/audit_compliance.sh`. -For a repo not born from the template, run `scripts/org/rollout_governance.sh ` to PR the required files in. +For a repo not born from the template — i.e. retrofitting governance onto an existing repo — the sequencing matters and `apply_rulesets.sh` now enforces it automatically: run `rollout_governance.sh ` first, **merge that PR**, and only then run `apply_rulesets.sh ` for the required-checks ruleset. Applying required-checks before `cla.yml` exists on the default branch makes the `cla / cla` check impossible to ever satisfy — it's a `pull_request_target` workflow that only executes using the definition already on the base branch — which permanently blocks every PR including the one meant to fix it. The script now skips that ruleset with a clear message if `cla.yml` isn't there yet, instead of creating the deadlock. ## Routine operation diff --git a/scripts/org/apply_rulesets.sh b/scripts/org/apply_rulesets.sh index f53ecfb..69f7e32 100755 --- a/scripts/org/apply_rulesets.sh +++ b/scripts/org/apply_rulesets.sh @@ -42,6 +42,20 @@ fi for file in "${files[@]}"; do name="$(jq -r .name "$file")" for repo in "${repos[@]}"; do + # Guard against the exact bootstrapping bug this script caused once + # already: the required-checks ruleset requires the `cla / cla` context, + # which is a pull_request_target workflow — it only executes using the + # workflow definition already on the base branch. Applying this ruleset + # before cla.yml exists there permanently blocks every PR (including + # the one meant to add cla.yml), because the named check can never fire. + if [ "$name" = "traverse-governance-required-checks" ]; then + if ! gh api "repos/$ORG/$repo/contents/.github/workflows/cla.yml" \ + --jq .path >/dev/null 2>&1; then + echo "SKIPPED '$name' on $ORG/$repo: .github/workflows/cla.yml not on the default branch yet." >&2 + echo " Merge the governance rollout PR first, then re-run this ruleset alone (-f)." >&2 + continue + fi + fi existing_id="$(gh api "repos/$ORG/$repo/rulesets" --jq \ ".[] | select(.name == \"$name\") | .id" 2>/dev/null || true)" if [ -n "$existing_id" ]; then