diff --git a/.github/workflows/claude-code-actions.yml b/.github/workflows/claude-code-actions.yml deleted file mode 100644 index 2b88c219..00000000 --- a/.github/workflows/claude-code-actions.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Claude Code Integration - -on: - issue_comment: - types: [ created ] - pull_request_review_comment: - types: [ created ] - -jobs: - claude-integration: - uses: basicmachines-co/claude-code-github-action/.github/workflows/claude-full.yml@v0.11.0 - with: - issue-label: 'claude-fix' # Optional: customize the trigger label - secrets: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - PERSONAL_ACCESS_TOKEN: ${{ secrets.CLAUDE_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 00000000..a2c5974e --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,81 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + steps: + - name: Check organization membership + id: check_membership + uses: actions/github-script@v7 + with: + script: | + let actor; + if (context.eventName === 'issue_comment') { + actor = context.payload.comment.user.login; + } else if (context.eventName === 'pull_request_review_comment') { + actor = context.payload.comment.user.login; + } else if (context.eventName === 'pull_request_review') { + actor = context.payload.review.user.login; + } else if (context.eventName === 'issues') { + actor = context.payload.issue.user.login; + } + + console.log(`Checking membership for user: ${actor}`); + + try { + const membership = await github.rest.orgs.getMembershipForUser({ + org: 'basicmachines-co', + username: actor + }); + + console.log(`Membership status: ${membership.data.state}`); + + // Allow if user is a member (public or private) or admin + const allowed = membership.data.state === 'active' && + (membership.data.role === 'member' || membership.data.role === 'admin'); + + core.setOutput('is_member', allowed); + + if (!allowed) { + core.notice(`User ${actor} is not a member of basicmachines-co organization`); + } + } catch (error) { + console.log(`Error checking membership: ${error.message}`); + core.setOutput('is_member', false); + core.notice(`User ${actor} is not a member of basicmachines-co organization`); + } + + - name: Checkout repository + if: steps.check_membership.outputs.is_member == 'true' + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + if: steps.check_membership.outputs.is_member == 'true' + id: claude + uses: anthropics/claude-code-action@beta + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + allowed_tools: Bash(uv run pytest),Bash(uv run ruff check . --fix),Bash(uv run ruff format .),Bash(uv run pyright),Bash(make test),Bash(make lint),Bash(make format),Bash(make type-check),Bash(make check),Read,Write,Edit,MultiEdit,Glob,Grep,LS \ No newline at end of file