Skip to content

Commit 45b94aa

Browse files
Merge pull request #3648 from opral/add-claude-github-actions-1752542058963
Add Claude Code GitHub Workflow
2 parents d8d33e9 + 5b34f3e commit 45b94aa

File tree

4 files changed

+170
-0
lines changed

4 files changed

+170
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Push Claude Dispatcher to Subrepos
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- '.github/workflows/claude-dispatcher.yml'
8+
workflow_dispatch:
9+
inputs:
10+
repos:
11+
description: 'Comma-separated list of repos to sync (e.g., opral/inlang-paraglide-js,opral/inlang-sdk)'
12+
required: false
13+
14+
jobs:
15+
push-to-repos:
16+
runs-on: ubuntu-latest
17+
strategy:
18+
matrix:
19+
repo:
20+
# Add your issue tracker repos here
21+
- opral/inlang-paraglide-js
22+
- opral/inlang-sdk
23+
# Add more repos as needed
24+
steps:
25+
- name: Checkout monorepo
26+
uses: actions/checkout@v4
27+
with:
28+
path: monorepo
29+
30+
- name: Checkout target repo
31+
uses: actions/checkout@v4
32+
with:
33+
repository: ${{ matrix.repo }}
34+
token: ${{ secrets.MONOREPO_DISPATCH_TOKEN }}
35+
path: target-repo
36+
37+
- name: Copy dispatcher and push
38+
run: |
39+
# Copy the dispatcher
40+
cp monorepo/.github/workflows/claude-dispatcher.yml target-repo/.github/workflows/
41+
42+
cd target-repo
43+
44+
# Configure git
45+
git config user.name "GitHub Actions"
46+
git config user.email "[email protected]"
47+
48+
# Check if there are changes
49+
if git diff --quiet; then
50+
echo "No changes in ${{ matrix.repo }}"
51+
exit 0
52+
fi
53+
54+
# Commit and push
55+
git add .github/workflows/claude-dispatcher.yml
56+
git commit -m "chore: sync Claude dispatcher from monorepo"
57+
git push origin main
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Claude Dispatcher
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
issues:
7+
types: [opened]
8+
pull_request_review_comment:
9+
types: [created]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
dispatch-to-monorepo:
15+
if: |
16+
(contains(github.event.comment.body || github.event.issue.body || github.event.review.body || '', '@claude'))
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Post initial comment
20+
id: comment
21+
uses: actions/github-script@v7
22+
with:
23+
script: |
24+
const comment = await github.rest.issues.createComment({
25+
owner: context.repo.owner,
26+
repo: context.repo.repo,
27+
issue_number: context.issue.number,
28+
body: '🤖 Claude is processing your request...'
29+
});
30+
return comment.data.id;
31+
32+
- name: Dispatch to Monorepo
33+
uses: peter-evans/repository-dispatch@v3
34+
with:
35+
token: ${{ secrets.MONOREPO_DISPATCH_TOKEN || secrets.GITHUB_TOKEN }}
36+
repository: ${{ github.repository == 'opral/monorepo' && 'opral/monorepo' || 'opral/monorepo' }}
37+
event-type: claude-request
38+
client-payload: |
39+
{
40+
"issue_number": "${{ github.event.issue.number }}",
41+
"issue_title": "${{ github.event.issue.title }}",
42+
"issue_body": "${{ github.event.issue.body }}",
43+
"comment_body": "${{ github.event.comment.body || github.event.review.body }}",
44+
"issue_url": "${{ github.event.issue.html_url }}",
45+
"repository": "${{ github.repository }}",
46+
"sender": "${{ github.event.sender.login }}",
47+
"comment_id": "${{ steps.comment.outputs.result }}",
48+
"is_monorepo": "${{ github.repository == 'opral/monorepo' }}"
49+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Claude Unified Handler
2+
3+
on:
4+
# Handle dispatched requests from all repos (including monorepo itself)
5+
repository_dispatch:
6+
types: [claude-request]
7+
8+
jobs:
9+
claude:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
issues: write
15+
id-token: write
16+
actions: read
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 1
22+
23+
- name: Run Claude Code
24+
id: claude
25+
uses: anthropics/claude-code-action@beta
26+
with:
27+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
28+
29+
# Direct prompt with the request from the subrepo
30+
direct_prompt: |
31+
Handle this request from ${{ github.event.client_payload.repository }}#${{ github.event.client_payload.issue_number }}:
32+
33+
${{ github.event.client_payload.comment_body || github.event.client_payload.issue_body }}
34+
35+
IMPORTANT: When creating a PR, you MUST include "Closes ${{ github.event.client_payload.issue_url }}" in the PR description.
36+
The original issue is at: ${{ github.event.client_payload.issue_url }}
37+
Focus on changes that relate to the specific subrepo package mentioned in the request.
38+
39+
- name: Update comment in source repo
40+
if: always() && github.event.client_payload.comment_id
41+
uses: actions/github-script@v7
42+
with:
43+
github-token: ${{ secrets.MONOREPO_DISPATCH_TOKEN }}
44+
script: |
45+
const [owner, repo] = '${{ github.event.client_payload.repository }}'.split('/');
46+
const commentId = '${{ github.event.client_payload.comment_id }}';
47+
48+
let body = '❌ Claude encountered an error processing your request.';
49+
50+
if ('${{ steps.claude.outcome }}' === 'success') {
51+
body = '✅ Claude has processed your request. Check the monorepo for the PR.';
52+
}
53+
54+
await github.rest.issues.updateComment({
55+
owner: owner,
56+
repo: repo,
57+
comment_id: parseInt(commentId),
58+
body: body
59+
});

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Opral Monorepo Claude Instructions
2+
3+
- Read the [./contributing.md](./contributing.md) for navigating the monorepo.
4+
- The monorepo uses `pnpm`. Don't use `npm` or `yarn`.
5+
- If you want to test a specific code file, it's easiest to cwd into the package directory and run `pnpm exec vitest run <filter>`.

0 commit comments

Comments
 (0)