Skip to content

Commit d48fbd3

Browse files
committed
feat(ci): add @claude GitHub Action workflow
Add a general-purpose @claude mention action so team members can ask Claude to answer questions, implement changes, and debug issues directly from issue and PR comments. Includes cross-repo context (cloud + claude) and workspace sync. Write-access authorization is enforced natively by the action.
1 parent 05804d0 commit d48fbd3

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

.github/workflows/claude.yml

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Claude
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
9+
concurrency:
10+
group: claude-${{ github.event.pull_request.number || github.event.issue.number }}
11+
cancel-in-progress: false
12+
13+
jobs:
14+
claude:
15+
name: Claude
16+
if: |
17+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && github.event.comment.user.type != 'Bot') ||
18+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && github.event.comment.user.type != 'Bot')
19+
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: write
23+
pull-requests: write
24+
issues: write
25+
26+
steps:
27+
- name: Generate cross-repo token
28+
id: app-token
29+
uses: actions/create-github-app-token@v2
30+
with:
31+
app-id: ${{ secrets.CLOUD_DISPATCH_APP_ID }}
32+
private-key: ${{ secrets.CLOUD_DISPATCH_APP_PRIVATE_KEY }}
33+
owner: shellhub-io
34+
repositories: shellhub,cloud,claude,team
35+
36+
# For issue_comment events, github.event.pull_request.head.sha is
37+
# unavailable (the payload only has github.event.issue). Resolve the
38+
# PR head SHA via the REST API so the correct ref is checked out.
39+
- name: Resolve PR head ref
40+
id: pr-ref
41+
if: github.event_name == 'pull_request_review_comment' || (github.event_name == 'issue_comment' && github.event.issue.pull_request)
42+
env:
43+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
PR_SHA: ${{ github.event.pull_request.head.sha }}
45+
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
46+
REPO: ${{ github.repository }}
47+
run: |
48+
if [[ -n "$PR_SHA" ]]; then
49+
echo "sha=$PR_SHA" >> "$GITHUB_OUTPUT"
50+
else
51+
SHA=$(curl -s -H "Authorization: Bearer $GH_TOKEN" \
52+
-H "Accept: application/vnd.github+json" \
53+
"https://api.github.com/repos/$REPO/pulls/$PR_NUMBER" | jq -r '.head.sha')
54+
if [[ -z "$SHA" || "$SHA" == "null" ]]; then
55+
echo "::error::Failed to resolve PR head SHA for PR #$PR_NUMBER"
56+
exit 1
57+
fi
58+
echo "sha=$SHA" >> "$GITHUB_OUTPUT"
59+
fi
60+
61+
- name: Checkout shellhub
62+
uses: actions/checkout@v6
63+
with:
64+
ref: ${{ steps.pr-ref.outputs.sha || '' }}
65+
66+
- name: Determine cloud branch
67+
id: cloud-branch
68+
if: github.event_name == 'pull_request_review_comment' || (github.event_name == 'issue_comment' && github.event.issue.pull_request)
69+
env:
70+
HEAD_REF: ${{ github.head_ref || github.event.pull_request.head.ref }}
71+
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
72+
APP_TOKEN: ${{ steps.app-token.outputs.token }}
73+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
74+
REPO: ${{ github.repository }}
75+
run: |
76+
if [[ -n "$HEAD_REF" ]]; then
77+
BRANCH="$HEAD_REF"
78+
else
79+
BRANCH=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json headRefName --jq '.headRefName') || {
80+
echo "::warning::Failed to resolve PR head ref name, falling back to master"
81+
true
82+
}
83+
BRANCH="${BRANCH:-master}"
84+
fi
85+
if curl -sf -H "Authorization: Bearer $APP_TOKEN" \
86+
"https://api.github.com/repos/shellhub-io/cloud/branches/$BRANCH" > /dev/null 2>&1; then
87+
echo "ref=$BRANCH" >> "$GITHUB_OUTPUT"
88+
else
89+
echo "ref=master" >> "$GITHUB_OUTPUT"
90+
fi
91+
92+
- name: Checkout cloud (context)
93+
uses: actions/checkout@v6
94+
with:
95+
repository: shellhub-io/cloud
96+
token: ${{ steps.app-token.outputs.token }}
97+
ref: ${{ steps.cloud-branch.outputs.ref || 'master' }}
98+
fetch-depth: 1
99+
path: cloud
100+
101+
- name: Checkout claude config
102+
uses: actions/checkout@v6
103+
with:
104+
repository: shellhub-io/claude
105+
token: ${{ steps.app-token.outputs.token }}
106+
fetch-depth: 1
107+
path: claude
108+
109+
- name: Setup workspace context
110+
run: |
111+
"$GITHUB_WORKSPACE/claude/workspace.sh" sync -w "$GITHUB_WORKSPACE" --project shellhub
112+
113+
- name: Run Claude
114+
timeout-minutes: 60
115+
uses: anthropics/claude-code-action@v1
116+
with:
117+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
118+
github_token: ${{ steps.app-token.outputs.token }}
119+
trigger_phrase: "@claude"
120+
prompt: |
121+
When asked to create a GitHub issue, route it to the correct repository:
122+
- Community or open-source ShellHub issues → shellhub-io/shellhub (this repo)
123+
- Cloud or enterprise-specific issues → shellhub-io/team

0 commit comments

Comments
 (0)