Skip to content

feat(rulesets): relocate release-channel-tags to .github as targeted org standard (#596)#609

Merged
don-petry merged 5 commits into
mainfrom
fix/596-release-channel-tags-org-standard
Jul 4, 2026
Merged

feat(rulesets): relocate release-channel-tags to .github as targeted org standard (#596)#609
don-petry merged 5 commits into
mainfrom
fix/596-release-channel-tags-org-standard

Conversation

@don-petry

@don-petry don-petry commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

What

Realizes the first slice of #596standards live only in .github — for the release-channel-tags ruleset, and generalizes it per review.

  • standards/rulesets/release-channel-tags.json (new) — the tag ruleset is now a codified org standard owned by .github.
    • Generic rule refs/tags/** instead of an enumerated namespace list (which drifted every time a new reusable/agent channel was added). On the reusable-hosting meta-repos every tag is a release tag, so "protect all tags" matches intent exactly.
    • Rules are update + deletion only — creation stays free, so dev-lead autocut can still cut new vX.Y.Z tags; only moving a channel pointer or deleting a tag needs bypass.
    • Bypass actors: OrganizationAdmin + automation Integration 3167543 + release-manager App 4193127 (all always), so channel promotion / autocut work. (This matches the live ruleset on .github-private, which was just updated to add 4193127.)
  • scripts/apply-rulesets.sh — the no-name default is now the FLEET_RULESETS allowlist (code-quality, pr-quality), not "every *.json in the dir". Without this, adding release-channel-tags.json would sweep it onto every repo via --all / --repo. It is now applied only when named explicitly.
  • README + bats updated — 17/17 green.

Apply plan (post-merge, targeted to the two meta-repos only)

GH_TOKEN=<admin> bash scripts/apply-rulesets.sh --repo petry-projects/.github         release-channel-tags
GH_TOKEN=<admin> bash scripts/apply-rulesets.sh --repo petry-projects/.github-private release-channel-tags

Not in this PR (follow-ups for #596)

  • Move bootstrap-new-repo.sh into .github (+ reconcile the divergent apply-repo-settings.sh copies).
  • Delete the duplicate .github-private/scripts/apply-rulesets.sh and the repo-local .github/rulesets/release-channel-tags.json.

Refs #596.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new managed ruleset for tag-based release channel controls.
    • Default ruleset application now targets only the standard fleet-wide policies, with the tag ruleset applied only when explicitly requested.
  • Bug Fixes

    • Prevented the tag ruleset from being included in broad bulk application runs.
    • Clarified allowed tag update and deletion behavior while preserving tag creation.
  • Documentation

    • Updated ruleset ownership and scope guidance across internal documentation.

…org standard (#596)

Make release-channel-tags a codified org standard owned by .github (per #596:
standards live only in .github), and generalize it from an enumerated namespace
list to a single generic rule.

- standards/rulesets/release-channel-tags.json: new. Generic include refs/tags/**
  (protects every channel pointer + version tag on the reusable-hosting meta-repos
  from unauthorized update/deletion; creation stays free so autocut can still cut
  new version tags). Carries OrgAdmin + automation Integration 3167543 + the
  release-manager App 4193127 as always-bypass, so channel promotion / dev-lead
  autocut can move channel tags.
- scripts/apply-rulesets.sh: the no-name default is now the FLEET_RULESETS
  allowlist (code-quality, pr-quality), NOT "every *.json" — so the targeted tag
  ruleset never leaks into --all / --repo fleet runs. release-channel-tags is
  applied only when named explicitly.
- tests + README updated (17/17 bats green).

Targeted apply (post-merge), to the two meta-repos only:
  apply-rulesets.sh --repo petry-projects/.github         release-channel-tags
  apply-rulesets.sh --repo petry-projects/.github-private release-channel-tags

Refs #596. Follow-ups: move bootstrap-new-repo.sh into .github and delete the
duplicate .github-private applier + repo-local ruleset JSON.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xAMAj4bRUEz53wYih8UFD
@don-petry don-petry requested a review from a team as a code owner July 4, 2026 14:23
Copilot AI review requested due to automatic review settings July 4, 2026 14:23
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new release-channel-tags ruleset JSON targeting tag refs, changes scripts/apply-rulesets.sh to apply a default FLEET_RULESETS allowlist (code-quality, pr-quality) instead of all JSON files unless explicitly named, updates related documentation, and adds bats test coverage.

Changes

Release-channel-tags ruleset and fleet allowlist

Layer / File(s) Summary
Ruleset definition
standards/rulesets/release-channel-tags.json
New ruleset targeting refs/tags/** with update/deletion rules and bypass actors including OrganizationAdmin and two integration apps.
Fleet allowlist selection logic
scripts/apply-rulesets.sh
Adds FLEET_RULESETS=(code-quality pr-quality) default; main() now applies only this allowlist unless a ruleset is explicitly named, validating named files exist.
Test coverage
test/scripts/apply-rulesets/apply-rulesets.bats
Adds tests asserting release-channel-tags.json shape and that default apply excludes it while explicit naming includes it.
Ownership and scope documentation
AGENTS.md, standards/github-settings.md, standards/rulesets/README.md
Updates docs to state all rulesets (including release-channel-tags) are centrally codified under standards/rulesets/, clarifies .github-private should not define rulesets, and documents the fleet allowlist/targeted scope model.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ApplyRulesetsScript
  participant RulesetsDirectory
  participant GitHubAPI

  User->>ApplyRulesetsScript: run apply --repo (no ruleset names)
  ApplyRulesetsScript->>ApplyRulesetsScript: select FLEET_RULESETS (code-quality, pr-quality)
  ApplyRulesetsScript->>RulesetsDirectory: validate each *.json exists
  ApplyRulesetsScript->>GitHubAPI: apply code-quality.json, pr-quality.json

  User->>ApplyRulesetsScript: run apply --repo release-channel-tags (explicit name)
  ApplyRulesetsScript->>RulesetsDirectory: validate release-channel-tags.json exists
  ApplyRulesetsScript->>GitHubAPI: apply release-channel-tags.json
Loading

Possibly related issues

Possibly related PRs

  • petry-projects/.github#10: Original PR adding the github-settings.md standards document that this PR revises for ruleset source-of-truth and repo boundaries.
  • petry-projects/.github#576: Prior update to the same AGENTS.md/github-settings.md governance boundaries and release-channel-tags exception that this PR extends into scripts and a new ruleset file.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: moving the release-channel-tags ruleset into .github as a targeted org standard.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/596-release-channel-tags-org-standard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry don-petry enabled auto-merge (squash) July 4, 2026 14:24

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a targeted ruleset, release-channel-tags.json, to protect release tags from unauthorized updates and deletions. To prevent this targeted ruleset from being applied fleet-wide by default, the apply-rulesets.sh script is updated to use an explicit allowlist (FLEET_RULESETS) for default runs, rather than applying all JSON files in the directory. Tests and documentation are updated accordingly. Feedback on the changes suggests declaring the global array FLEET_RULESETS as readonly to prevent accidental modification, especially since the script is sourced by the test suite.

Comment thread scripts/apply-rulesets.sh Outdated
@don-petry don-petry disabled auto-merge July 4, 2026 14:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR relocates the release-channel-tags repository ruleset into .github as a codified org standard and adjusts the ruleset applier so targeted rulesets are not accidentally applied fleet-wide.

Changes:

  • Add standards/rulesets/release-channel-tags.json as a generic refs/tags/** tag ruleset (update/deletion only) with the intended bypass actors.
  • Change scripts/apply-rulesets.sh default behavior to apply only the FLEET_RULESETS allowlist (code-quality, pr-quality) unless names are explicitly provided.
  • Extend Bats tests and the rulesets README to cover the new targeted ruleset and the new default selection behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/scripts/apply-rulesets/apply-rulesets.bats Adds coverage for the new tag ruleset JSON and for the new “fleet allowlist only” default behavior.
standards/rulesets/release-channel-tags.json Introduces the codified release-channel-tags tag ruleset under .github standards.
standards/rulesets/README.md Documents release-channel-tags alongside fleet rulesets and explains targeted vs default application behavior.
scripts/apply-rulesets.sh Prevents unintended fleet-wide application by defaulting to an explicit allowlist when no ruleset names are provided.

Comment thread standards/rulesets/README.md
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 4, 2026
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 4, 2026
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — fix-bot-comment (applied)

Changes committed and pushed.

@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry don-petry enabled auto-merge (squash) July 4, 2026 14:31
… rulesets need Team plan)

Captures that release-channel-tags (and code/pr-quality) are organization-level
in intent — org-scoped bypass actors, org-wide protection — but replicated
per-repo by apply-rulesets.sh because native /orgs/{org}/rulesets is a Team-plan
feature and petry-projects is on Free (403 'Upgrade to GitHub Team').

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015xAMAj4bRUEz53wYih8UFD
@don-petry don-petry disabled auto-merge July 4, 2026 14:33
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry don-petry enabled auto-merge (squash) July 4, 2026 14:35

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 776ebfa3a1e706d992c234dac217130d67c735c9
Review mode: triage-approved (single reviewer)

Summary

Relocates the release-channel-tags tag ruleset into .github/standards/rulesets/ as a codified org standard (first slice of #596) and hardens scripts/apply-rulesets.sh so the no-name default applies only the FLEET_RULESETS allowlist (code-quality, pr-quality) instead of every *.json — preventing the targeted tag ruleset from being swept fleet-wide. Docs (AGENTS.md, github-settings.md, rulesets README) updated consistently; 2 new bats tests cover the new JSON and the allowlist default (17/17 green).

Linked issue analysis

Refs #596 (open): this PR delivers the first slice — standards live only in .github — and is explicit that applier consolidation, bootstrap-new-repo.sh relocation, and deletion of the duplicate .github-private applier/ruleset are follow-ups. No closing reference is claimed, which is correct for a partial slice. The change substantively advances the issue.

Findings

  • No blocking findings.
  • Risk classified MEDIUM: new org-policy artifact (release-channel-tags.json) plus non-trivial selection-logic change in apply-rulesets.sh. Not HIGH: no auth/secret/credential code; the ruleset adds protection (update+deletion on refs/tags/**, creation free) and its bypass actors (OrgAdmin, Integration 3167543, release-manager App 4193127) match the already-live ruleset on .github-private per the PR body.
  • Applier change is defensive and correct: names default to the readonly FLEET_RULESETS allowlist, each name validated against an existing JSON, unknown names still error. Bats tests explicitly assert release-channel-tags is NOT applied by default and IS applied when named.
  • Both bot review threads resolved: gemini-code-assist readonly-array suggestion applied (readonly FLEET_RULESETS); Copilot doc-consistency finding fixed in AGENTS.md + standards/github-settings.md.
  • Secret scan: run_secret_scanning MCP tool not available in this environment; gitleaks CI check passed. No secrets in the diff (IDs 3167543/4193127 are public App identifiers, not credentials).
  • package-lock.json name churn (pr-595 → pr-609) is cosmetic.

CI status

All required checks green: ShellCheck, Lint, Agent Security Scan, Secret scan (gitleaks), CodeQL, SonarCloud (Quality Gate passed, 0 issues/hotspots), Apply Rulesets Tests (lint + bats), AgentShield, npm audit, dependency audit. Skipped checks are conditional ecosystem audits (pip/pnpm/cargo/govulncheck) and dependabot-automerge — expected. mergeStateStatus is BEHIND main (branch needs update before merge), which is not a review blocker.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

@sonarqubecloud

sonarqubecloud Bot commented Jul 4, 2026

Copy link
Copy Markdown

@don-petry don-petry disabled auto-merge July 4, 2026 14:39
@don-petry

Copy link
Copy Markdown
Contributor Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
Issues addressed: 0
- Quality Gate passed with 0 new issues, 0 hotspots — no actionable findings
Files changed: none (no fixes needed)
Skipped (informational): SonarCloud success report
```
**Status:** PR is clean. No changes required. Ready for merge pending CI completion.

@don-petry don-petry enabled auto-merge (squash) July 4, 2026 14:39
@don-petry don-petry merged commit aba68f6 into main Jul 4, 2026
21 of 22 checks passed
@don-petry don-petry deleted the fix/596-release-channel-tags-org-standard branch July 4, 2026 14:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/apply-rulesets.sh (1)

139-166: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

--all can be combined with a targeted ruleset name, bypassing the safety net this PR adds.

FLEET_RULESETS only guards the default (no-name) case. Nothing stops --all release-channel-tags from sweeping this targeted ruleset (and its release-manager bypass grant) across every repo in the org — the exact outcome this PR set out to prevent. No test covers this combination either.

🛡️ Proposed guard
   local files=()
   if [ "${`#names`[@]}" -eq 0 ]; then names=("${FLEET_RULESETS[@]}"); fi
+  if [ "$all" = true ]; then
+    local n
+    for n in "${names[@]}"; do
+      case " ${FLEET_RULESETS[*]} " in
+        *" ${n} "*) ;;
+        *) echo "::error::'${n}' is a targeted ruleset and cannot be applied with --all; use --repo instead" >&2; return 2 ;;
+      esac
+    done
+  fi
   local n
   for n in "${names[@]}"; do
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/apply-rulesets.sh` around lines 139 - 166, The `apply-rulesets` flow
still allows `--all` to be used with an explicit targeted ruleset name, which
bypasses the new safety guard. Update the argument handling in
`apply-rulesets.sh` so the `--all` path only permits the default allowlisted
fleet rulesets and rejects any explicit names like `release-channel-tags` before
calling `apply_repo`. Add a test covering the `--all` plus named-ruleset
combination to ensure it fails with an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@standards/github-settings.md`:
- Around line 128-134: The “only sanctioned rulesets” statement in
github-settings.md is now ambiguous because the section also introduces
release-channel-tags as a separate codified ruleset. Update the surrounding
wording in this section to clearly scope that claim to branch-protection
rulesets only, using the existing ruleset names referenced here (`pr-quality`,
`code-quality`, and `release-channel-tags`) so it no longer reads like a
contradiction.

---

Outside diff comments:
In `@scripts/apply-rulesets.sh`:
- Around line 139-166: The `apply-rulesets` flow still allows `--all` to be used
with an explicit targeted ruleset name, which bypasses the new safety guard.
Update the argument handling in `apply-rulesets.sh` so the `--all` path only
permits the default allowlisted fleet rulesets and rejects any explicit names
like `release-channel-tags` before calling `apply_repo`. Add a test covering the
`--all` plus named-ruleset combination to ensure it fails with an error.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 19df586d-24f4-481f-b6bc-fb2615bb6e5e

📥 Commits

Reviewing files that changed from the base of the PR and between 42df7d3 and 228f5aa.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • AGENTS.md
  • scripts/apply-rulesets.sh
  • standards/github-settings.md
  • standards/rulesets/README.md
  • standards/rulesets/release-channel-tags.json
  • test/scripts/apply-rulesets/apply-rulesets.bats

Comment on lines +128 to +134
The codified ruleset JSONs are the source of truth for all rulesets;
`scripts/apply-rulesets.sh` (and any org automation consuming it) applies them to each repo.
As **org-wide compliance policy they are owned by `petry-projects/.github`**, and
their canonical home is `standards/rulesets/`. Do **not** author them in
their canonical home is `standards/rulesets/`. Do **not** author rulesets in
`petry-projects/.github-private` — that repo is scoped to agents/skills and their
reusable assets. The only ruleset that belongs there is `release-channel-tags`
(it protects `.github-private`'s own `pr-review/**` / `dev-lead/**` release tags).
reusable assets. All rulesets, including targeted ones like `release-channel-tags`,
are defined in `.github/standards/rulesets/`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider scoping the "only sanctioned rulesets" line for clarity.

The unchanged sentence above ("pr-quality and code-quality are the only sanctioned rulesets") sits in the same section that now lists release-channel-tags as a third codified ruleset (lines 155-159). It's technically about branch-protection consolidation (tags aren't in scope there), but as written it reads as contradicting the new content just below it.

✏️ Suggested clarification (outside reviewed range, at line 142)
-**`pr-quality` and `code-quality` are the only sanctioned rulesets.** Legacy
+**`pr-quality` and `code-quality` are the only sanctioned *branch-protection* rulesets.** Legacy
 `protect-branches` rulesets and ad-hoc `main` rulesets are deprecated: they

Also applies to: 155-159

🧰 Tools
🪛 LanguageTool

[uncategorized] ~134-~134: The official name of this software platform is spelled with a capital “H”.
Context: ... release-channel-tags, are defined in .github/standards/rulesets/. See the repo-boun...

(GITHUB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@standards/github-settings.md` around lines 128 - 134, The “only sanctioned
rulesets” statement in github-settings.md is now ambiguous because the section
also introduces release-channel-tags as a separate codified ruleset. Update the
surrounding wording in this section to clearly scope that claim to
branch-protection rulesets only, using the existing ruleset names referenced
here (`pr-quality`, `code-quality`, and `release-channel-tags`) so it no longer
reads like a contradiction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants