Skip to content

Commit e6bab03

Browse files
authored
ci(common): configure Claude workflow with Opus model, custom prompt, and tool permissions (#1831)
* ci(common): configure Claude workflow to use Opus model Add --model opus flag to claude_args to ensure the workflow uses Claude Opus instead of the default Sonnet model. Using the model alias 'opus' ensures automatic use of the latest Opus version. * ci(common): configure Claude workflow with custom system prompt and permissions - Use Opus model by default via --model opus flag - Override system prompt to show only PR metadata (no verbose body) - Enable uv, gh, git tools for pr-review skill compatibility - Custom prompt builder extracts PR context from GitHub webhook - Supports both pull_request and issue_comment events The pr-review skill can now: - Use uv run scripts/gh_pr.py for PR operations - Post real GitHub reviews with inline comments - Use gh CLI for all GitHub operations * fix(ci): resolve security and shellcheck issues in workflow - Pass GitHub context variables via env to prevent script injection - Use block redirect for GITHUB_ENV writes (SC2129) - Quote all variable references to prevent word splitting (SC2086) - Addresses security concerns from GitHub Actions linter
1 parent 22fe3f9 commit e6bab03

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

.github/workflows/claude.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,96 @@ jobs:
5858
env:
5959
GH_TOKEN: ${{ secrets.CLAUDE_ACCESS_TOKEN }}
6060

61+
- name: Build custom system prompt
62+
id: custom_prompt
63+
run: |
64+
# Extract PR metadata from webhook payload
65+
if [[ "$EVENT_NAME" == "pull_request" ]] || [[ -n "$ISSUE_PR_URL" ]]; then
66+
# For pull_request events
67+
if [[ "$EVENT_NAME" == "pull_request" ]]; then
68+
PR_TITLE="$PR_TITLE_INPUT"
69+
PR_AUTHOR="$PR_AUTHOR_INPUT"
70+
PR_HEAD="$PR_HEAD_INPUT"
71+
PR_BASE="$PR_BASE_INPUT"
72+
PR_STATE="$PR_STATE_INPUT"
73+
PR_ADDITIONS="$PR_ADDITIONS_INPUT"
74+
PR_DELETIONS="$PR_DELETIONS_INPUT"
75+
PR_COMMITS="$PR_COMMITS_INPUT"
76+
PR_FILES="$PR_FILES_INPUT"
77+
else
78+
# For issue_comment on PRs - need to fetch PR data
79+
PR_NUMBER="$ISSUE_NUMBER_INPUT"
80+
PR_DATA=$(gh pr view "$PR_NUMBER" --json title,author,headRefName,baseRefName,state,additions,deletions,commits)
81+
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
82+
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
83+
PR_HEAD=$(echo "$PR_DATA" | jq -r '.headRefName')
84+
PR_BASE=$(echo "$PR_DATA" | jq -r '.baseRefName')
85+
PR_STATE=$(echo "$PR_DATA" | jq -r '.state')
86+
PR_ADDITIONS=$(echo "$PR_DATA" | jq -r '.additions')
87+
PR_DELETIONS=$(echo "$PR_DATA" | jq -r '.deletions')
88+
PR_COMMITS=$(echo "$PR_DATA" | jq -r '.commits | length')
89+
PR_FILES=$(gh pr view "$PR_NUMBER" --json files | jq '.files | length')
90+
fi
91+
92+
# Build formatted context
93+
FORMATTED_CONTEXT="PR Title: ${PR_TITLE}
94+
PR Author: ${PR_AUTHOR}
95+
PR Branch: ${PR_HEAD} -> ${PR_BASE}
96+
PR State: ${PR_STATE^^}
97+
PR Additions: ${PR_ADDITIONS}
98+
PR Deletions: ${PR_DELETIONS}
99+
Total Commits: ${PR_COMMITS}
100+
Changed Files: ${PR_FILES} files"
101+
102+
# Build system prompt
103+
SYSTEM_PROMPT="You are Claude, an AI assistant designed to help with GitHub issues and pull requests. Think carefully as you analyze the context and respond appropriately. Here's the context for your current task:
104+
105+
<formatted_context>
106+
${FORMATTED_CONTEXT}
107+
</formatted_context>"
108+
else
109+
# For issues
110+
ISSUE_TITLE="$ISSUE_TITLE_INPUT"
111+
ISSUE_AUTHOR="$ISSUE_AUTHOR_INPUT"
112+
ISSUE_STATE="$ISSUE_STATE_INPUT"
113+
114+
FORMATTED_CONTEXT="Issue Title: ${ISSUE_TITLE}
115+
Issue Author: ${ISSUE_AUTHOR}
116+
Issue State: ${ISSUE_STATE^^}"
117+
118+
SYSTEM_PROMPT="You are Claude, an AI assistant designed to help with GitHub issues and pull requests. Think carefully as you analyze the context and respond appropriately. Here's the context for your current task:
119+
120+
<formatted_context>
121+
${FORMATTED_CONTEXT}
122+
</formatted_context>"
123+
fi
124+
125+
# Save to environment file for next step (using block redirect)
126+
{
127+
echo "CUSTOM_SYSTEM_PROMPT<<EOF"
128+
echo "$SYSTEM_PROMPT"
129+
echo "EOF"
130+
} >> "$GITHUB_ENV"
131+
env:
132+
GH_TOKEN: ${{ secrets.CLAUDE_ACCESS_TOKEN }}
133+
EVENT_NAME: ${{ github.event_name }}
134+
ISSUE_PR_URL: ${{ github.event.issue.pull_request }}
135+
# Pull request event variables
136+
PR_TITLE_INPUT: ${{ github.event.pull_request.title }}
137+
PR_AUTHOR_INPUT: ${{ github.event.pull_request.user.login }}
138+
PR_HEAD_INPUT: ${{ github.event.pull_request.head.ref }}
139+
PR_BASE_INPUT: ${{ github.event.pull_request.base.ref }}
140+
PR_STATE_INPUT: ${{ github.event.pull_request.state }}
141+
PR_ADDITIONS_INPUT: ${{ github.event.pull_request.additions }}
142+
PR_DELETIONS_INPUT: ${{ github.event.pull_request.deletions }}
143+
PR_COMMITS_INPUT: ${{ github.event.pull_request.commits }}
144+
PR_FILES_INPUT: ${{ github.event.pull_request.changed_files }}
145+
# Issue event variables
146+
ISSUE_NUMBER_INPUT: ${{ github.event.issue.number }}
147+
ISSUE_TITLE_INPUT: ${{ github.event.issue.title }}
148+
ISSUE_AUTHOR_INPUT: ${{ github.event.issue.user.login }}
149+
ISSUE_STATE_INPUT: ${{ github.event.issue.state }}
150+
61151
- name: Run Claude Code
62152
uses: anthropics/claude-code-action@a017b830c03e23789b11fb69ed571ea61c12e45c # 2026-01-16
63153
with:
@@ -68,3 +158,7 @@ jobs:
68158
zama-developer@zama-marketplace
69159
# Prompt: empty string for comments (action extracts text after @claude)
70160
prompt: ""
161+
claude_args: |
162+
--model opus
163+
--allowedTools "Bash(uv),Bash(gh),Bash(git),Read,Edit,Write,Glob,Grep,Task"
164+
--system-prompt "${{ env.CUSTOM_SYSTEM_PROMPT }}"

0 commit comments

Comments
 (0)