mirror of
https://github.com/twentyhq/twenty.git
synced 2026-06-11 17:37:18 -04:00
197 lines
8.4 KiB
YAML
197 lines
8.4 KiB
YAML
name: Claude Code
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
pull_request_review_comment:
|
|
types: [created]
|
|
pull_request_review:
|
|
types: [submitted]
|
|
issues:
|
|
types: [opened]
|
|
repository_dispatch:
|
|
types: [claude-core-team-issues]
|
|
|
|
permissions: {}
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.issue.number || github.event.pull_request.number || github.event.client_payload.issue_number }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
claude:
|
|
if: |
|
|
(
|
|
github.event_name == 'issue_comment' &&
|
|
contains(github.event.comment.body, '@claude') &&
|
|
github.event.comment.user.type != 'Bot' &&
|
|
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
|
|
) ||
|
|
(
|
|
github.event_name == 'pull_request_review_comment' &&
|
|
contains(github.event.comment.body, '@claude') &&
|
|
github.event.comment.user.type != 'Bot' &&
|
|
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
|
|
) ||
|
|
(
|
|
github.event_name == 'pull_request_review' &&
|
|
contains(github.event.review.body, '@claude') &&
|
|
github.event.review.user.type != 'Bot' &&
|
|
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)
|
|
) ||
|
|
(
|
|
github.event_name == 'issues' &&
|
|
github.event.action == 'opened' &&
|
|
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
|
|
contains(fromJson('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association)
|
|
)
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
issues: write
|
|
id-token: write
|
|
services:
|
|
postgres:
|
|
image: postgres:16
|
|
env:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: postgres
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
redis:
|
|
image: redis
|
|
ports:
|
|
- 6379:6379
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Install dependencies
|
|
uses: ./.github/actions/yarn-install
|
|
- name: Run Claude Code
|
|
id: claude-code
|
|
uses: anthropics/claude-code-action@dde2242db6af13460b916652159b6ba19a598f30 # v1
|
|
with:
|
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
additional_permissions: |
|
|
actions: read
|
|
claude_args: '--max-turns 200 --model opus --allowedTools "Edit,Write,WebFetch,Bash(bash packages/twenty-utils/setup-dev-env.sh),Bash(npx nx *),Bash(npx jest *),Bash(yarn *),Bash(git *),Bash(gh *),Bash(sed *),Bash(python3 *),Bash(rm *),Bash(find *),Bash(grep *),Bash(cat *),Bash(ls *),Bash(head *),Bash(tail *),Bash(wc *),Bash(sort *),Bash(uniq *),Bash(mkdir *),Bash(cp *),Bash(mv *),Bash(touch *),Bash(chmod *),Bash(echo *),Bash(curl *),Bash(cd *),Bash(pwd *),Bash(diff *),Bash(xargs *),Bash(awk *),Bash(cut *),Bash(tee *),Bash(tr *)"'
|
|
settings: |
|
|
{
|
|
"env": {
|
|
"PG_DATABASE_URL": "postgres://postgres:postgres@localhost:5432/default"
|
|
}
|
|
}
|
|
- name: Post Create-PR link if Claude ran out of turns
|
|
if: failure()
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
BRANCH=$(git branch --show-current)
|
|
if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "" ]; then
|
|
exit 0
|
|
fi
|
|
AHEAD=$(git rev-list --count main.."$BRANCH" 2>/dev/null || echo "0")
|
|
if [ "$AHEAD" = "0" ]; then
|
|
exit 0
|
|
fi
|
|
EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
|
if [ -n "$EXISTING_PR" ]; then
|
|
exit 0
|
|
fi
|
|
ISSUE_NUMBER="${{ github.event.issue.number || github.event.pull_request.number }}"
|
|
ENCODED_BRANCH=$(python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=''))" "$BRANCH")
|
|
PR_URL="https://github.com/${{ github.repository }}/compare/main...${ENCODED_BRANCH}?quick_pull=1"
|
|
BODY="⚠️ Claude ran out of turns before creating a PR. Work has been pushed to [\`$BRANCH\`](https://github.com/${{ github.repository }}/tree/$ENCODED_BRANCH).\n\n[**Create PR →**]($PR_URL)"
|
|
if [ -n "$ISSUE_NUMBER" ]; then
|
|
gh issue comment "$ISSUE_NUMBER" --body "$(echo -e "$BODY")"
|
|
fi
|
|
|
|
claude-cross-repo:
|
|
if: github.event_name == 'repository_dispatch'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
issues: write
|
|
id-token: write
|
|
services:
|
|
postgres:
|
|
image: postgres:16
|
|
env:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: postgres
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
redis:
|
|
image: redis
|
|
ports:
|
|
- 6379:6379
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Install dependencies
|
|
uses: ./.github/actions/yarn-install
|
|
- name: Build prompt from dispatch payload
|
|
id: prompt
|
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
|
with:
|
|
script: |
|
|
const p = context.payload.client_payload;
|
|
let prompt;
|
|
if (p.comment_body) {
|
|
prompt = `You are responding to a comment on issue #${p.issue_number} ("${p.issue_title}") in the ${p.repo_full_name} repository.\n\nThe comment by @${p.sender} says:\n\n${p.comment_body}\n\nIssue body:\n\n${p.issue_body}\n\nPlease help with this request. The code you are working with is the twenty codebase (this repository).`;
|
|
} else {
|
|
prompt = `You are responding to issue #${p.issue_number} ("${p.issue_title}") in the ${p.repo_full_name} repository, opened by @${p.sender}.\n\nIssue body:\n\n${p.issue_body}\n\nPlease help with this request. The code you are working with is the twenty codebase (this repository).`;
|
|
}
|
|
core.setOutput('prompt', prompt);
|
|
core.setOutput('repo', p.repo_full_name);
|
|
core.setOutput('issue_number', p.issue_number);
|
|
- name: Run Claude Code
|
|
id: claude
|
|
uses: anthropics/claude-code-action@dde2242db6af13460b916652159b6ba19a598f30 # v1
|
|
with:
|
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
prompt: ${{ steps.prompt.outputs.prompt }}
|
|
additional_permissions: |
|
|
actions: read
|
|
claude_args: '--max-turns 200 --model opus --allowedTools "Edit,Write,WebFetch,Bash(bash packages/twenty-utils/setup-dev-env.sh),Bash(npx nx *),Bash(npx jest *),Bash(yarn *),Bash(git *),Bash(gh *),Bash(sed *),Bash(python3 *),Bash(rm *),Bash(find *),Bash(grep *),Bash(cat *),Bash(ls *),Bash(head *),Bash(tail *),Bash(wc *),Bash(sort *),Bash(uniq *),Bash(mkdir *),Bash(cp *),Bash(mv *),Bash(touch *),Bash(chmod *),Bash(echo *),Bash(curl *),Bash(cd *),Bash(pwd *),Bash(diff *),Bash(xargs *),Bash(awk *),Bash(cut *),Bash(tee *),Bash(tr *)"'
|
|
settings: |
|
|
{
|
|
"env": {
|
|
"PG_DATABASE_URL": "postgres://postgres:postgres@localhost:5432/default"
|
|
}
|
|
}
|
|
- name: Dispatch response to ci-privileged
|
|
if: always()
|
|
env:
|
|
GH_TOKEN: ${{ secrets.CI_PRIVILEGED_DISPATCH_TOKEN }}
|
|
REPO: ${{ steps.prompt.outputs.repo }}
|
|
ISSUE_NUMBER: ${{ steps.prompt.outputs.issue_number }}
|
|
RUN_ID: ${{ github.run_id }}
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
run: |
|
|
gh api repos/twentyhq/ci-privileged/dispatches \
|
|
-f event_type=claude-cross-repo-response \
|
|
-f "client_payload[repo]=$REPO" \
|
|
-f "client_payload[issue_number]=$ISSUE_NUMBER" \
|
|
-f "client_payload[run_id]=$RUN_ID" \
|
|
-f "client_payload[run_url]=$RUN_URL"
|