feat: Add lifecycle hook infrastructure for automated quality gates #37727
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Claude Code Assistant | |
| on: | |
| # Comment-based triggers - respond to @claude mentions | |
| issue_comment: | |
| types: [created] | |
| pull_request_review_comment: | |
| types: [created] | |
| pull_request_review: | |
| types: [submitted] | |
| # Issue triggers - respond to new issues or assignments | |
| issues: | |
| types: [opened, assigned, labeled] | |
| # PR triggers - enable autonomous work on PRs directly | |
| # This allows Claude to respond to new PRs without waiting for comments | |
| # Includes 'labeled' to support label_trigger activation | |
| pull_request: | |
| types: [opened, reopened, synchronize, ready_for_review, labeled] | |
| # Manual trigger for on-demand Claude invocation | |
| workflow_dispatch: | |
| # Permissions for autonomous operation | |
| # See: https://github.com/anthropics/claude-code-action | |
| permissions: | |
| contents: write # Read/write repository files, create commits and branches | |
| issues: write # Read/write issues, add comments and labels | |
| pull-requests: write # Read/write PRs, create reviews, merge | |
| id-token: write # Required for OIDC authentication to get GitHub App token | |
| actions: write # Approve and trigger workflow runs autonomously | |
| checks: write # Create and update check runs for CI feedback | |
| statuses: write # Update commit statuses for build/test results | |
| jobs: | |
| # ADR-006 Compliance: Authorization logic in dedicated script for testability | |
| # See: tests/workflows/test_claude_authorization.py | |
| check-authorization: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| authorized: ${{ steps.auth-check.outputs.authorized }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Check Claude authorization | |
| id: auth-check | |
| shell: bash | |
| env: | |
| # Safe: Using environment variables to prevent command injection | |
| # See: https://github.blog/security/vulnerability-research/how-to-catch-github-actions-workflow-injections-before-attackers-do/ | |
| EVENT_NAME: ${{ github.event_name }} | |
| ACTOR: ${{ github.actor }} | |
| # Author association from various event types | |
| # For workflow_dispatch: actor must have write access to trigger, so we default to MEMBER | |
| # For pull_request: use PR author association | |
| AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association || github.event.review.author_association || github.event.issue.author_association || github.event.pull_request.author_association || (github.event_name == 'workflow_dispatch' && 'MEMBER') || '' }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| REVIEW_BODY: ${{ github.event.review.body }} | |
| ISSUE_BODY: ${{ github.event.issue.body }} | |
| ISSUE_TITLE: ${{ github.event.issue.title }} | |
| PR_BODY: ${{ github.event.pull_request.body }} | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| set +e | |
| authorized=$(python3 ./tests/workflows/test_claude_authorization.py \ | |
| --event-name "$EVENT_NAME" \ | |
| --actor "$ACTOR" \ | |
| --author-association "$AUTHOR_ASSOCIATION" \ | |
| --comment-body "$COMMENT_BODY" \ | |
| --review-body "$REVIEW_BODY" \ | |
| --issue-body "$ISSUE_BODY" \ | |
| --issue-title "$ISSUE_TITLE" \ | |
| --pr-body "$PR_BODY" \ | |
| --pr-title "$PR_TITLE") | |
| exit_code=$? | |
| set -e | |
| if [ "$exit_code" -ne 0 ]; then | |
| echo "::error::Authorization check script failed with exit code $exit_code." | |
| echo "::error::This indicates a script error, not an authorization denial." | |
| echo "::error::Review the step output above for specific error messages." | |
| echo "::error::Check the Actions summary 'Claude Authorization Check' section if available." | |
| exit 1 | |
| fi | |
| # Validate output format to prevent silent failures from unexpected values | |
| authorized=$(echo "$authorized" | tr -d '[:space:]') | |
| if [ "$authorized" != "true" ] && [ "$authorized" != "false" ]; then | |
| echo "::error::Authorization check returned unexpected value: '$authorized'. Expected 'true' or 'false'." | |
| echo "::error::This may indicate the script exited without producing valid output." | |
| exit 1 | |
| fi | |
| echo "authorized=$authorized" >> "$GITHUB_OUTPUT" | |
| claude-response: | |
| needs: check-authorization | |
| runs-on: ubuntu-latest | |
| if: needs.check-authorization.outputs.authorized == 'true' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 1 | |
| - name: Setup code environment | |
| uses: ./.github/actions/setup-code-env | |
| with: | |
| gh-token: ${{ github.token }} | |
| enable-git-hooks: true | |
| skip-autofix: 0 | |
| # Pin to SHA - https://github.com/anthropics/claude-code-action/releases/tag/v1.0.80 | |
| # Fixes orphaned installer processes causing race conditions (Issue #804) | |
| - uses: anthropics/claude-code-action@38ec876110f9fbf8b950c79f534430740c3ac009 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| # Trigger configuration | |
| trigger_phrase: "@claude" | |
| assignee_trigger: "@me" | |
| label_trigger: "claude" | |
| # Allow specific trusted bot users to trigger the action | |
| # Dependency management bots | |
| # GitHub automation bots | |
| # AI coding assistant bots (permitted to mention @claude for collaboration) | |
| allowed_bots: "dependabot[bot],renovate[bot],github-actions[bot],copilot[bot],coderabbitai[bot],cursor[bot],gemini-ai[bot],claude-ai[bot],amazonq[bot],tabnine[bot]" | |
| # Branch configuration | |
| base_branch: "main" | |
| branch_prefix: "claude/" | |
| # Enable progress tracking for visibility | |
| # Note: track_progress is only supported for specific pull_request actions | |
| # (opened, synchronize, ready_for_review, reopened) - not for 'labeled' | |
| track_progress: ${{ github.event.action != 'labeled' }} | |
| # Enable commit signing for security | |
| use_commit_signing: true |