Skip to content

Commit cc624bc

Browse files
feat: add reusable Claude AI workflow templates
Add centralized, reusable GitHub Actions workflows for Claude AI automation: - claude-executor.yml: Configurable execution engine with custom tool allowlists, timeouts, and runner specifications - claude-orchestrator.yml: Orchestrates all Claude triggers (comments, PRs, issues) with configurable prompts and conditional logic Key features: - Parameterized inputs for repository-specific customization - Support for interactive (@claude mentions) and automatic modes - Configurable allowed tools for different repository types - Flexible timeout and runner configuration - Comprehensive trigger event handling This enables DRY implementation of Claude workflows across all dotCMS repositories while maintaining repository-specific configurations. Usage example: ```yaml jobs: claude: uses: dotCMS/claude-workflows/.github/workflows/claude-orchestrator.yml@main with: allowed_tools: | Bash(terraform plan) Bash(git status) secrets: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ``` 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> Resolves: dotCMS/dotcat#213
1 parent 56fab4c commit cc624bc

2 files changed

Lines changed: 215 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
# Claude Executor Workflow (Reusable)
3+
#
4+
# PURPOSE: This is the execution engine that runs Claude AI actions.
5+
# This is the reusable version that will be hosted in dotCMS/claude-workflows
6+
#
7+
# WHY: This workflow contains the shared configuration and execution logic
8+
# for all Claude interactions. It's designed to be reusable across different
9+
# repositories and trigger scenarios.
10+
#
11+
# ROLE:
12+
# - Sets up the execution environment (permissions, timeouts, runner)
13+
# - Configures the anthropics/claude-code-action with configurable allowed tools
14+
# - Handles the actual Claude AI interaction
15+
# - Provides a single source of truth for Claude execution configuration
16+
#
17+
# USAGE: Called by orchestrator workflows with different parameters
18+
# for interactive vs automatic modes and different tool configurations.
19+
20+
name: Claude Executor (Reusable)
21+
22+
on:
23+
workflow_call:
24+
inputs:
25+
trigger_mode:
26+
description: 'Mode of trigger - interactive or automatic'
27+
required: true
28+
type: string
29+
direct_prompt:
30+
description: 'Direct prompt for automatic reviews'
31+
required: false
32+
type: string
33+
default: ''
34+
allowed_tools:
35+
description: 'Custom allowed tools configuration'
36+
required: false
37+
type: string
38+
default: |
39+
Bash(git status)
40+
Bash(git diff)
41+
timeout_minutes:
42+
description: 'Timeout in minutes for the Claude execution'
43+
required: false
44+
type: number
45+
default: 15
46+
runner:
47+
description: 'GitHub runner to use'
48+
required: false
49+
type: string
50+
default: 'ubuntu-latest'
51+
secrets:
52+
ANTHROPIC_API_KEY:
53+
required: true
54+
55+
jobs:
56+
claude:
57+
runs-on: ${{ inputs.runner }}
58+
timeout-minutes: ${{ inputs.timeout_minutes }}
59+
permissions:
60+
contents: write
61+
pull-requests: write
62+
issues: write
63+
id-token: write
64+
65+
steps:
66+
- name: Checkout repository
67+
uses: actions/checkout@v4
68+
with:
69+
fetch-depth: 1
70+
71+
- name: Run Claude Code
72+
id: claude
73+
uses: anthropics/claude-code-action@beta
74+
with:
75+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
76+
direct_prompt: ${{ inputs.direct_prompt }}
77+
allowed_tools: ${{ inputs.allowed_tools }}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
# Claude Orchestrator Workflow (Reusable)
3+
#
4+
# PURPOSE: This workflow orchestrates all Claude AI interactions by handling
5+
# different trigger types and routing them to the appropriate execution mode.
6+
# This is the reusable version that will be hosted in dotCMS/claude-workflows
7+
#
8+
# WHY: Consolidates all Claude triggers into a single workflow to prevent
9+
# duplicate runs while maintaining clear separation between interactive
10+
# and automatic modes. Designed to be reusable across different repositories.
11+
#
12+
# ROLE:
13+
# - Handles all trigger events (issues, comments, PR reviews, PR changes)
14+
# - Routes to appropriate execution mode based on trigger type
15+
# - Manages conditional logic to prevent duplicate workflow runs
16+
# - Applies configurable path exclusions
17+
# - Orchestrates between interactive (@claude mentions) and automatic modes
18+
#
19+
# USAGE: This is a reusable orchestrator that can be called from any repository
20+
# with repository-specific configurations.
21+
22+
name: Claude Orchestrator (Reusable)
23+
24+
on:
25+
workflow_call:
26+
inputs:
27+
automatic_review_prompt:
28+
description: 'Custom prompt for automatic PR reviews'
29+
required: false
30+
type: string
31+
default: |
32+
Please review this pull request and provide feedback on:
33+
- Code quality and best practices
34+
- Potential bugs or issues
35+
- Performance considerations
36+
- Security concerns
37+
- Test coverage
38+
39+
Be constructive and helpful in your feedback.
40+
allowed_tools:
41+
description: 'Custom allowed tools configuration'
42+
required: false
43+
type: string
44+
default: |
45+
Bash(git status)
46+
Bash(git diff)
47+
timeout_minutes:
48+
description: 'Timeout in minutes for Claude execution'
49+
required: false
50+
type: number
51+
default: 15
52+
runner:
53+
description: 'GitHub runner to use'
54+
required: false
55+
type: string
56+
default: 'ubuntu-latest'
57+
executor_workflow_ref:
58+
description: 'Reference to the executor workflow'
59+
required: false
60+
type: string
61+
default: 'dotCMS/claude-workflows/.github/workflows/claude-executor.yml@main'
62+
secrets:
63+
ANTHROPIC_API_KEY:
64+
required: true
65+
66+
jobs:
67+
# Interactive Claude mentions in comments
68+
claude-comment-mention:
69+
if: |
70+
(github.event_name == 'issue_comment' && (contains(github.event.comment.body, '@claude') || contains(github.event.comment.body, '@Claude') || contains(github.event.comment.body, '@CLAUDE'))) ||
71+
(github.event_name == 'pull_request_review_comment' && (contains(github.event.comment.body, '@claude') || contains(github.event.comment.body, '@Claude') || contains(github.event.comment.body, '@CLAUDE')))
72+
uses: ${{ inputs.executor_workflow_ref }}
73+
with:
74+
trigger_mode: interactive
75+
allowed_tools: ${{ inputs.allowed_tools }}
76+
timeout_minutes: ${{ inputs.timeout_minutes }}
77+
runner: ${{ inputs.runner }}
78+
secrets:
79+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
80+
81+
# Interactive Claude mentions in PR reviews
82+
claude-review-mention:
83+
if: |
84+
github.event_name == 'pull_request_review' && (contains(github.event.review.body, '@claude') || contains(github.event.review.body, '@Claude') || contains(github.event.review.body, '@CLAUDE'))
85+
uses: ${{ inputs.executor_workflow_ref }}
86+
with:
87+
trigger_mode: interactive
88+
allowed_tools: ${{ inputs.allowed_tools }}
89+
timeout_minutes: ${{ inputs.timeout_minutes }}
90+
runner: ${{ inputs.runner }}
91+
secrets:
92+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
93+
94+
# Interactive Claude mentions in issues
95+
claude-issue-mention:
96+
if: |
97+
github.event_name == 'issues' &&
98+
((contains(github.event.issue.body, '@claude') || contains(github.event.issue.body, '@Claude') || contains(github.event.issue.body, '@CLAUDE')) ||
99+
(contains(github.event.issue.title, '@claude') || contains(github.event.issue.title, '@Claude') || contains(github.event.issue.title, '@CLAUDE')))
100+
uses: ${{ inputs.executor_workflow_ref }}
101+
with:
102+
trigger_mode: interactive
103+
allowed_tools: ${{ inputs.allowed_tools }}
104+
timeout_minutes: ${{ inputs.timeout_minutes }}
105+
runner: ${{ inputs.runner }}
106+
secrets:
107+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
108+
109+
# Interactive Claude mentions in PR titles/bodies
110+
claude-pr-mention:
111+
if: |
112+
github.event_name == 'pull_request' &&
113+
((contains(github.event.pull_request.title, '@claude') || contains(github.event.pull_request.title, '@Claude') || contains(github.event.pull_request.title, '@CLAUDE')) ||
114+
(contains(github.event.pull_request.body, '@claude') || contains(github.event.pull_request.body, '@Claude') || contains(github.event.pull_request.body, '@CLAUDE')))
115+
uses: ${{ inputs.executor_workflow_ref }}
116+
with:
117+
trigger_mode: interactive
118+
allowed_tools: ${{ inputs.allowed_tools }}
119+
timeout_minutes: ${{ inputs.timeout_minutes }}
120+
runner: ${{ inputs.runner }}
121+
secrets:
122+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
123+
124+
# Automatic PR reviews (no @claude mention)
125+
claude-automatic-review:
126+
if: |
127+
github.event_name == 'pull_request' &&
128+
!contains(github.event.pull_request.title, '@claude') && !contains(github.event.pull_request.title, '@Claude') && !contains(github.event.pull_request.title, '@CLAUDE') &&
129+
!contains(github.event.pull_request.body, '@claude') && !contains(github.event.pull_request.body, '@Claude') && !contains(github.event.pull_request.body, '@CLAUDE')
130+
uses: ${{ inputs.executor_workflow_ref }}
131+
with:
132+
trigger_mode: automatic
133+
direct_prompt: ${{ inputs.automatic_review_prompt }}
134+
allowed_tools: ${{ inputs.allowed_tools }}
135+
timeout_minutes: ${{ inputs.timeout_minutes }}
136+
runner: ${{ inputs.runner }}
137+
secrets:
138+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

0 commit comments

Comments
 (0)