diff --git a/.github/workflows/ai-issue-triage.yml b/.github/workflows/ai-issue-triage.yml index d1ca622..fe40603 100644 --- a/.github/workflows/ai-issue-triage.yml +++ b/.github/workflows/ai-issue-triage.yml @@ -19,7 +19,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 # Skip bot-created issues - if: github.event.issue.user.login != 'github-actions[bot]' && github.event.issue.user.login != 'dependabot[bot]' + if: >- + github.event.issue.user.login != 'claude[bot]' && + github.event.issue.user.login != 'github-actions[bot]' && + github.event.issue.user.login != 'dependabot[bot]' permissions: issues: write contents: read @@ -30,7 +33,7 @@ jobs: ISSUE_TITLE: ${{ github.event.issue.title }} ISSUE_BODY: ${{ github.event.issue.body }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: sparse-checkout: | agents/ @@ -51,7 +54,7 @@ jobs: id: bedrock if: env.BEDROCK_CONFIGURED == 'true' continue-on-error: true - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@58dbe8ed6879f0d3b02ac295b20d5fdfe7733e0c # v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} use_bedrock: "true" @@ -90,7 +93,7 @@ jobs: env.ANTHROPIC_KEY_SET == 'true' && (env.BEDROCK_CONFIGURED != 'true' || steps.bedrock.outcome != 'success') continue-on-error: true - uses: anthropics/claude-code-action@v1 + uses: anthropics/claude-code-action@58dbe8ed6879f0d3b02ac295b20d5fdfe7733e0c # v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} diff --git a/.github/workflows/issue-to-pr.yml b/.github/workflows/issue-to-pr.yml index 9710a2e..981fc7d 100644 --- a/.github/workflows/issue-to-pr.yml +++ b/.github/workflows/issue-to-pr.yml @@ -6,7 +6,7 @@ name: Issue to PR on: issues: - types: [opened] + types: [labeled] permissions: contents: write @@ -29,8 +29,9 @@ jobs: name: Validate Issue runs-on: ubuntu-latest timeout-minutes: 5 - # Skip bot-created issues + # Only run when 'ai-implement' label is applied; skip bot-created issues if: >- + github.event.label.name == 'ai-implement' && github.event.issue.user.login != 'claude[bot]' && github.event.issue.user.login != 'github-actions[bot]' && github.event.issue.user.login != 'dependabot[bot]' @@ -82,18 +83,33 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} + - name: Verify actor permissions + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + with: + script: | + const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.actor + }); + const allowed = ['admin', 'write']; + if (!allowed.includes(data.permission)) { + core.setFailed(`Actor ${context.actor} has '${data.permission}' permission, needs 'write' or 'admin'`); + } + core.info(`Actor ${context.actor} verified with '${data.permission}' permission`); + - name: Setup Node.js - uses: actions/setup-node@v6 + uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6 with: node-version: 20 - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: '3.11' @@ -182,7 +198,7 @@ jobs: - name: Upload patch artifact if: steps.detect.outputs.has_changes == 'true' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: name: issue-fix-patch path: /tmp/patch/issue-fix.patch @@ -208,15 +224,15 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: '3.11' - name: Download patch - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: issue-fix-patch path: /tmp/patch @@ -325,7 +341,7 @@ jobs: - name: Upload clean patch if: steps.final.outputs.passed == 'true' - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 with: name: issue-fix-clean-patch path: /tmp/clean-patch/issue-fix-clean.patch @@ -348,13 +364,13 @@ jobs: # ---- Success path ---- - name: Checkout repository if: needs.guardrails.outputs.passed == 'true' - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Download clean patch if: needs.guardrails.outputs.passed == 'true' - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: issue-fix-clean-patch path: /tmp/clean-patch @@ -366,7 +382,7 @@ jobs: - name: Create Draft PR id: create if: needs.guardrails.outputs.passed == 'true' - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8 with: token: ${{ secrets.GITHUB_TOKEN }} branch: issue-fix/${{ github.event.issue.number }}-${{ github.run_id }} @@ -450,12 +466,12 @@ jobs: steps: - name: Checkout scripts - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: sparse-checkout: .github/scripts - name: Setup Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: '3.12'