Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ Licensed under the [MIT License][license-link]\
```

- Caveats: `bypass_actors` uses the **Admin** repository role (`actor_id: 5`), a global GitHub id that ports across repos as-is. The required status-check context (`Check pull request workflow status`) is matched by **name** and only turns green after `test-pull-request.yml` has run at least once. `gh ruleset` is read-only (list/view) - creation must go through `gh api -X POST` as above. If a field is rejected, edit the JSON and re-run the import.
- **Renaming or updating an existing ruleset needs a FULL-payload PUT, not a partial one.** `gh api -X PUT repos/<owner>/<repo>/rulesets/<id> -f name=develop` (name only) fails with `422 Unexpected parameter 'allowed_dismissal_actors'`: GitHub re-validates the stored `pull_request` rule on a partial update, and that rule carries fields the GET response does not return. To rename (e.g. legacy `Develop`/`Main` -> `develop`/`main`) or otherwise edit a ruleset, **GET it, change the field, and PUT the whole `{name, target, enforcement, bypass_actors, conditions, rules}` back** (the same writable-field subset used for export above). Back up the GET first and verify afterward that the rule types, `required_signatures`, `non_fast_forward`, and the required status-check context are all still present. Renaming is safe for *enforcement* - the required status-check binds by check name, not ruleset name, so a rename won't break CI - but the template still expects the exact `develop`/`main` names that `AGENTS.md` and these docs reference (which is precisely what a legacy `Develop`/`Main` repo is renaming *to*); the rename removes inconsistency, it isn't a license for arbitrary names.
- **Renaming or updating an existing ruleset needs a FULL-payload PUT, not a partial one.** `gh api -X PUT "repos/<owner>/<repo>/rulesets/<id>" -f name=develop` (name only) fails with `422 Unexpected parameter 'allowed_dismissal_actors'`: GitHub re-validates the stored `pull_request` rule on a partial update, and that rule carries fields the GET response does not return. To rename (e.g. legacy `Develop`/`Main` -> `develop`/`main`) or otherwise edit a ruleset, **GET it, change the field, and PUT the whole `{name, target, enforcement, bypass_actors, conditions, rules}` back** (the same writable-field subset used for export above). Back up the GET first and verify afterward that the rule types, `required_signatures`, `non_fast_forward`, and the required status-check context are all still present. Renaming is safe for *enforcement* - the required status-check binds by check name, not ruleset name, so a rename won't break CI - but the template still expects the exact `develop`/`main` names that `AGENTS.md` and these docs reference (which is precisely what a legacy `Develop`/`Main` repo is renaming *to*); the rename removes inconsistency, it isn't a license for arbitrary names.
- **Migrating a brownfield repo with unsigned history.** The shared `Require signed commits` rule (below) rejects any commit made before signing was enabled, so on a pre-existing repo the first `develop -> main` release is blocked the moment it tries to introduce that legacy history. The fix is to re-sign the legacy commits, but that rewrite is a non-fast-forward and the `Block force pushes` rule rejects it - **and the ruleset's admin bypass does not cover `git push --force` (GitHub honors ruleset bypass for UI/API operations, not git force-push).** So even the owner cannot complete the re-sign without temporarily relaxing the ruleset. This is a **one-time, maintainer-performed manual migration** - it deliberately uses the force-push that [AGENTS.md "Git and Commit Rules"](./AGENTS.md#git-and-commit-rules) forbids agents from running, so an AI agent must **never** execute this procedure; surface it to the maintainer instead. Procedure:

1. Re-sign the divergent history, preserving merge topology. Prefer a rebase, which re-signs each commit with your current key (`commit.gpgsign` / `-S`):
Expand Down