feat(orchestrator): comprehensive artifact injection across all FSM phases #658
Workflow file for this run
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 Review | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, ready_for_review, reopened] | |
| # Optional: Only run on specific file changes | |
| # paths: | |
| # - "src/**/*.ts" | |
| # - "src/**/*.tsx" | |
| # - "src/**/*.js" | |
| # - "src/**/*.jsx" | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| claude-review: | |
| # Optional: Filter by PR author | |
| # if: | | |
| # github.event.pull_request.user.login == 'external-contributor' || | |
| # github.event.pull_request.user.login == 'new-developer' || | |
| # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' | |
| if: github.event.pull_request.head.repo.full_name == github.repository | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| id-token: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Run Claude Code Review | |
| id: claude-review | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| allowed_bots: '*' | |
| track_progress: true | |
| plugin_marketplaces: 'https://github.com/anthropics/claude-code.git' | |
| plugins: 'code-review@claude-code-plugins' | |
| claude_args: '--allowedTools mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)' | |
| prompt: | | |
| Review PR #${{ github.event.pull_request.number }} in ${{ github.repository }}. | |
| The PR branch is already checked out. Use `gh pr diff ${{ github.event.pull_request.number }}` to get the full diff and `gh pr view ${{ github.event.pull_request.number }}` for PR metadata. | |
| Review the full PR diff (not just the latest commits). Focus on: | |
| - Bugs and correctness issues | |
| - Security vulnerabilities | |
| - Performance concerns | |
| - Design and architecture | |
| Use inline comments for specific code issues. Post a top-level summary comment with your overall assessment using `gh pr comment`. | |
| Always post your review, even if this is a re-review after new commits were pushed. Review the full PR diff, not just the latest commits. | |
| # Review Gate — runs AFTER claude-review so it sees any new review threads | |
| # that Claude posted against the current PR head. If this lived in a separate | |
| # workflow that also triggered on `pull_request: synchronize`, it'd race the | |
| # reviewer and pass on stale (already-resolved) state from the previous commit. | |
| # Using `needs: [claude-review]` here orders the two jobs. | |
| # | |
| # `if: always()` keeps the gate running even when claude-review is skipped | |
| # (fork PRs) or fails — the gate still provides its unresolved-threads check. | |
| review-gate: | |
| name: Review Gate | |
| needs: [claude-review] | |
| if: ${{ always() && github.event_name == 'pull_request' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: read | |
| steps: | |
| - name: Check for unresolved review comments | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| # Fetch all review threads via GraphQL and check for unresolved ones | |
| UNRESOLVED=$(gh api graphql -f query=' | |
| query($owner: String!, $repo: String!, $pr: Int!) { | |
| repository(owner: $owner, name: $repo) { | |
| pullRequest(number: $pr) { | |
| reviewThreads(first: 100) { | |
| nodes { | |
| isResolved | |
| comments(first: 1) { | |
| nodes { | |
| author { login } | |
| body | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| ' -f owner="${{ github.repository_owner }}" \ | |
| -f repo="$(echo '${{ github.repository }}' | cut -d/ -f2)" \ | |
| -F pr="${PR_NUMBER}" \ | |
| --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)') | |
| if [ -z "$UNRESOLVED" ]; then | |
| echo "No unresolved review threads." | |
| exit 0 | |
| fi | |
| COUNT=$(echo "$UNRESOLVED" | jq -s 'length') | |
| echo "" | |
| echo "::error::$COUNT unresolved review thread(s) found. Resolve all review comments before merging." | |
| echo "" | |
| # Print details of unresolved threads | |
| echo "$UNRESOLVED" | jq -r '.comments.nodes[0] | " - \(.author.login): \(.body | split("\n") | .[0])"' | |
| echo "" | |
| exit 1 |