From 4e7df2553d5a1844e2933a3b0db0c213c535913d Mon Sep 17 00:00:00 2001 From: Nathan Heaps Date: Mon, 27 Jul 2026 13:23:07 -0400 Subject: [PATCH] fix(apply-repo-settings): backfill GitHub's implicit pull_request defaults before diffing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub backfills two optional pull_request rule parameters that settings.yml often leaves unset: allowed_merge_methods (all three methods — merge, squash, rebase — regardless of what the repo itself allows) and required_reviewers (empty array). Neither default is declared in GitHub's OpenAPI schema or REST docs, so the ruleset diff treated their absence in settings.yml as a permanent mismatch against the live API response, even when nothing was actually misconfigured. Confirmed these defaults empirically rather than assuming them: read live rulesets on both nsheaps/greasemonkey-scripts and nsheaps/.github (which independently have allow_merge_commit:false at the repo level, yet both still return "merge" in allowed_merge_methods), and cross- checked GitHub's REST docs + OpenAPI schema, which state no default for either field. Backfill both fields on current vs. desired before the jq -S comparison (stacked on nsheaps/github-actions#95's ruleset-diff fix), only when actually absent so a genuine future restriction still registers as drift. Co-Authored-By: Claude Code (~/src/nsheaps/github-actions) --- .github/actions/apply-repo-settings/action.sh | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/actions/apply-repo-settings/action.sh b/.github/actions/apply-repo-settings/action.sh index 09f1990..2202553 100755 --- a/.github/actions/apply-repo-settings/action.sh +++ b/.github/actions/apply-repo-settings/action.sh @@ -169,7 +169,27 @@ apply_rulesets() { # set is identical but differently ordered. Sort bypass_actors by a # stable key (actor_type, actor_id) on both sides before the `-S` # comparison so ordering differences don't register as drift. - local ruleset_filter='{name, target, enforcement, conditions, rules, + # + # GitHub also backfills two `pull_request` rule parameters that + # settings.yml treats as optional and often omits: `allowed_merge_methods` + # (all three methods — merge, squash, rebase — regardless of what the + # repo itself allows; confirmed empirically against repos with + # allow_merge_commit:false that still get "merge" back) and + # `required_reviewers` (empty array). Neither default is stated in + # GitHub's OpenAPI schema or REST docs, so these are pinned from direct + # observation (nsheaps/greasemonkey-scripts + nsheaps/.github's own + # require-pr rulesets), not assumption. Backfill them on both sides + # only when actually absent (`// default`, not overwriting a real, + # explicitly-set value on either side) so a genuine future difference + # still registers as drift. + local ruleset_filter='{name, target, enforcement, + conditions, + rules: (.rules // [] | map( + if .type == "pull_request" then + .parameters.allowed_merge_methods |= (. // ["merge", "squash", "rebase"]) + | .parameters.required_reviewers |= (. // []) + else . end + )), bypass_actors: ((.bypass_actors // []) | sort_by(.actor_type, .actor_id))}' local current_norm desired_norm current_norm="$(gh api "/repos/${OWNER}/${REPO}/rulesets/${existing_id}" \