Skip to content

feat: switch to org-level reusable Claude Code workflow#134

Merged
don-petry merged 1 commit into
mainfrom
feat/reusable-claude-workflow
Apr 6, 2026
Merged

feat: switch to org-level reusable Claude Code workflow#134
don-petry merged 1 commit into
mainfrom
feat/reusable-claude-workflow

Conversation

@don-petry
Copy link
Copy Markdown
Collaborator

@don-petry don-petry commented Apr 6, 2026

Summary

  • Replaces inline claude.yml with a thin caller that delegates to petry-projects/.github/.github/workflows/claude-code-reusable.yml@main
  • Prompt, config, and GH_PAT_WORKFLOWS support are now maintained centrally in the org repo
  • No behavioral change — same triggers, same permissions, same Claude behavior

Why

Centralizes maintenance so prompt/config updates only need one change instead of 7. Also adds github_token with workflows write scope so Claude can push .github/workflows/ files (previously blocked).

Test plan

  • CI passes on this PR
  • After merge, label a compliance issue with claude and verify Claude creates a PR

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Streamlined internal automation workflow configuration by consolidating job logic into a centralized reusable workflow, reducing maintenance overhead.

Copilot AI review requested due to automatic review settings April 6, 2026 18:17
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

The .github/workflows/claude.yml workflow is being refactored to consolidate two jobs (claude and claude-issue) into a single claude-code job that delegates to a reusable workflow. This removes inlined conditional logic, configuration details, and direct action invocations.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow Consolidation
.github/workflows/claude.yml
Replaced two jobs (claude for PR/mention-driven automation and claude-issue for labeled-issue automation) with a single claude-code job that delegates to a reusable workflow at petry-projects/.github/.github/workflows/claude-code-reusable.yml@main. Removed inlined conditional logic, runs-on/timeout-minutes configuration, repository checkout step, and direct anthropic/claude-code-action invocations. Retained job-level permissions and added secrets: inherit for secret forwarding.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main change: switching from inline Claude Code workflow to an org-level reusable workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reusable-claude-workflow

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

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Apr 6, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots

See analysis details on SonarQube Cloud

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 refactors the repository’s Claude Code GitHub Actions workflow to delegate execution to an organization-level reusable workflow, aiming to centralize maintenance while keeping the same triggers/behavior.

Changes:

  • Replaces the prior inline claude.yml implementation (multiple jobs + steps) with a single reusable-workflow caller.
  • Updates workflow header comments to describe the delegation model.
  • Keeps a job-level permissions block in the caller workflow.

contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association))
runs-on: ubuntu-latest
timeout-minutes: 60
claude-code:
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

Job now delegates to a reusable workflow without any of the previous job-level if: guards (same-repo PR check + @claude author_association allowlist). If the reusable workflow doesn’t replicate those checks, this becomes a security regression (external users could trigger the automation via comments/PR review comments). Consider keeping the if: conditions here in the caller (or add an explicit note + link to where the checks live in the reusable workflow).

Suggested change
claude-code:
claude-code:
if: >-
${{
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '@claude') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' &&
contains(github.event.comment.body, '@claude') &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'issues' &&
github.event.issue.pull_request &&
github.event.label.name == '@claude' &&
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.sender.author_association))
}}

Copilot uses AI. Check for mistakes.
timeout-minutes: 60
claude-code:
uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@main
secrets: inherit
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

secrets: inherit passes all repository/environment secrets to the called workflow. Even if the org workflow is trusted, this is broader than necessary and increases blast radius if the reusable workflow is ever modified or misconfigured. Prefer passing only the required secrets (e.g., CLAUDE_CODE_OAUTH_TOKEN / GH_PAT_WORKFLOWS) explicitly.

Suggested change
secrets: inherit
secrets:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
GH_PAT_WORKFLOWS: ${{ secrets.GH_PAT_WORKFLOWS }}

Copilot uses AI. Check for mistakes.
Comment on lines 23 to 29
permissions:
contents: write
id-token: write
pull-requests: write
issues: write
actions: read
checks: read
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

PR description says this adds a token with workflows write scope so Claude can push .github/workflows/*, but this job’s permissions don’t include workflows: write. Because reusable workflows can’t elevate permissions beyond the caller, Claude still won’t be able to modify workflow files via GITHUB_TOKEN unless workflows: write is granted here (or you rely solely on a PAT).

Copilot uses AI. Check for mistakes.
runs-on: ubuntu-latest
timeout-minutes: 60
claude-code:
uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@main
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

uses: ...@main means the workflow behavior can change without any change in this repository (and can break builds or alter automation unexpectedly). Prefer pinning the reusable workflow to an immutable ref (tag or commit SHA) and updating intentionally when you want new behavior.

Suggested change
uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@main
uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@<PINNED_COMMIT_SHA>

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/claude.yml (2)

21-21: Security: Pin the reusable workflow to a specific SHA or tag instead of @main.

Referencing @main means any commit pushed to the org's reusable workflow immediately affects all caller repos without local review. An attacker with write access to petry-projects/.github could inject malicious steps that run with this workflow's elevated permissions.

Consider pinning to a commit SHA (e.g., @abc1234...) or a versioned tag, updating deliberately when changes are reviewed.

Example pinned reference
-    uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@main
+    uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@v1.0.0  # or SHA
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 21, The workflow call is pinned to
`@main` which is unsafe; replace the `uses:
petry-projects/.github/.github/workflows/claude-code-reusable.yml@main`
reference with a specific immutable ref (a commit SHA or a versioned tag) so the
reusable workflow is fixed to a reviewed revision; update the `uses:` value to
the chosen SHA or tag and document the chosen ref in the PR so future changes
require an explicit update.

22-22: secrets: inherit forwards all repository secrets to the reusable workflow.

This is valid and convenient, but be aware it grants the external workflow access to every secret defined in this repository. If the reusable workflow is compromised or modified maliciously (especially given the @main ref), secrets could be exfiltrated.

Ensure this is intentional and that the org workflow is trusted and access-controlled.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 22, The workflow currently uses
"secrets: inherit", which forwards all repo secrets to the reusable workflow;
replace this with an explicit secrets block listing only the secrets the
reusable workflow needs (e.g., secrets: { REQUIRED_SECRET: ${{
secrets.REQUIRED_SECRET }}, OTHER_SECRET: ${{ secrets.OTHER_SECRET }} }) and/or
remove inheritance, and also avoid calling the reusable workflow with an
unpinned ref like "@main" (pin to a specific tag or commit) so only intended
secrets are exposed to a trusted, fixed workflow; update the call site where
"secrets: inherit" is set and the reusable workflow ref to explicit secret
mappings and a pinned ref.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/claude.yml:
- Around line 23-29: The permissions block in the workflow is missing the
required workflows: write permission described in the PR; update the permissions
map (the permissions: block in .github/workflows/claude.yml) to include
workflows: write alongside contents: write, id-token: write, pull-requests:
write, issues: write, actions: read, checks: read so the generated github_token
can push to .github/workflows/, and ensure this permission is declared in this
reusable workflow (callers cannot elevate permissions for it).

---

Nitpick comments:
In @.github/workflows/claude.yml:
- Line 21: The workflow call is pinned to `@main` which is unsafe; replace the
`uses: petry-projects/.github/.github/workflows/claude-code-reusable.yml@main`
reference with a specific immutable ref (a commit SHA or a versioned tag) so the
reusable workflow is fixed to a reviewed revision; update the `uses:` value to
the chosen SHA or tag and document the chosen ref in the PR so future changes
require an explicit update.
- Line 22: The workflow currently uses "secrets: inherit", which forwards all
repo secrets to the reusable workflow; replace this with an explicit secrets
block listing only the secrets the reusable workflow needs (e.g., secrets: {
REQUIRED_SECRET: ${{ secrets.REQUIRED_SECRET }}, OTHER_SECRET: ${{
secrets.OTHER_SECRET }} }) and/or remove inheritance, and also avoid calling the
reusable workflow with an unpinned ref like "@main" (pin to a specific tag or
commit) so only intended secrets are exposed to a trusted, fixed workflow;
update the call site where "secrets: inherit" is set and the reusable workflow
ref to explicit secret mappings and a pinned ref.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3248253c-2c56-4f41-a663-cf86b307f007

📥 Commits

Reviewing files that changed from the base of the PR and between 7385a30 and a3e6b62.

📒 Files selected for processing (1)
  • .github/workflows/claude.yml

Comment on lines 23 to 29
permissions:
contents: write
id-token: write
pull-requests: write
issues: write
actions: read
checks: read
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing workflows: write permission contradicts PR objectives.

The PR description states this change "Adds a github_token with workflows write scope enabling Claude to push files into .github/workflows/". However, the permissions block does not include workflows: write. Without this permission, Claude will still be blocked from modifying workflow files.

If the intent is to grant this permission from within the reusable workflow, note that callers cannot grant more permissions than they themselves possess—the permission must be declared here.

Proposed fix to add the missing permission
     permissions:
       contents: write
       id-token: write
       pull-requests: write
       issues: write
       actions: read
       checks: read
+      workflows: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: write
id-token: write
pull-requests: write
issues: write
actions: read
checks: read
permissions:
contents: write
id-token: write
pull-requests: write
issues: write
actions: read
checks: read
workflows: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml around lines 23 - 29, The permissions block in
the workflow is missing the required workflows: write permission described in
the PR; update the permissions map (the permissions: block in
.github/workflows/claude.yml) to include workflows: write alongside contents:
write, id-token: write, pull-requests: write, issues: write, actions: read,
checks: read so the generated github_token can push to .github/workflows/, and
ensure this permission is declared in this reusable workflow (callers cannot
elevate permissions for it).

@don-petry don-petry merged commit a8b35eb into main Apr 6, 2026
26 of 28 checks passed
@don-petry don-petry deleted the feat/reusable-claude-workflow branch April 6, 2026 18:33
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.

2 participants