Skip to content

Conversation

@bartlomieju
Copy link
Member

Removed usage of claude-code-action and instead install claude directly.

@coderabbitai
Copy link

coderabbitai bot commented Nov 21, 2025

Walkthrough

Replaces the single claude-code-action@v1 invocation with a multi-step GitHub Actions pipeline: checkout repo, setup Node.js, install @anthropic/claude-code-cli via npm, create /tmp/prompt.txt containing formatted issue data and triage instructions (handling manual vs automatic triggers), configure GitHub CLI auth, and run the Claude Code CLI with the generated prompt. Removes the inline claude_args prompt and drops id-token: write permission.

Sequence Diagram

sequenceDiagram
    actor GH as GitHub Actions
    participant WF as Workflow
    participant Checkout as actions/checkout
    participant Node as actions/setup-node
    participant NPM as npm (install claude-code-cli)
    participant PromptFile as /tmp/prompt.txt
    participant GHCLI as gh CLI (auth)
    participant CLAUDE as claude-code CLI

    rect rgb(245,245,245)
    Note over WF: Old flow (single action)
    GH->>WF: trigger workflow
    WF->>CLAUDE: claude-code-action@v1 (inline prompt)
    CLAUDE->>CLAUDE: execute triage
    end

    rect rgb(235,245,235)
    Note over WF: New flow (multi-step pipeline)
    GH->>WF: trigger workflow
    WF->>Checkout: checkout repository
    WF->>Node: setup Node.js
    WF->>NPM: npm install `@anthropic/claude-code-cli`
    WF->>PromptFile: write /tmp/prompt.txt (issue + instructions)
    WF->>GHCLI: configure/auth gh CLI
    PromptFile-->>CLAUDE: provide prompt file
    WF->>CLAUDE: run claude-code CLI with prompt file
    CLAUDE->>CLAUDE: execute triage
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Verify prompt generation templating and proper escaping in /tmp/prompt.txt.
  • Check Node.js version selection and npm install reliability.
  • Validate GH CLI configuration and secret usage (GH_HOST, token) for security.
  • Confirm claude-code CLI installation/invocation and error handling/logging.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: rewriting the issue triage workflow from using a single action to a multi-step pipeline with direct Claude CLI installation.
Description check ✅ Passed The description directly relates to the changeset, accurately summarizing the core change of removing claude-code-action and installing Claude directly.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f876aa1 and 2c49dac.

📒 Files selected for processing (1)
  • .github/workflows/issue_triage.yml (1 hunks)
🔇 Additional comments (1)
.github/workflows/issue_triage.yml (1)

21-54: Environment variables properly used for untrusted context—good security posture.

The refactoring to use environment variables (lines 33–38) for GitHub event data correctly addresses the past review concern about script injection. The conditional logic (lines 46–54) cleanly separates manual-trigger and automatic-trigger paths.

However, I need to verify the Claude Code CLI package name and syntax before merging.

Please verify:

  1. Package name: Is @anthropic-ai/claude-code (line 30) the correct npm package? If not, provide the correct package name.
  2. CLI syntax: Is the command syntax claude --print "$(cat /tmp/prompt.txt)" --allowedTools "..." (lines 110–111) correct for this CLI?

You can verify this by checking the package's npm page or running npm info @anthropic-ai/claude-code to confirm the version and exported binaries.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.github/workflows/issue_triage.yml (1)

33-39: Simplify GitHub CLI setup.

The GitHub CLI is pre-installed on ubuntu-latest runners. The fallback installation is good for resilience, but the inline shell script is verbose. Consider using the official cli/cli action or a simpler approach if the fallback is truly necessary.

If you want to keep the fallback logic, consider extracting it into a separate script or using a cleaner conditional:

-      - name: Setup GitHub CLI
-        run: |
-          gh --version || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
-          && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
-          && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
-          && sudo apt update \
-          && sudo apt install gh -y)
+      - name: Setup GitHub CLI
+        run: |
+          command -v gh >/dev/null 2>&1 || (
+            curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
+            sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
+            echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
+            sudo apt update && \
+            sudo apt install -y gh
+          )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e59d37f and f4106b7.

📒 Files selected for processing (1)
  • .github/workflows/issue_triage.yml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: test debug linux-x86_64
  • GitHub Check: test debug linux-aarch64
  • GitHub Check: test debug windows-x86_64
  • GitHub Check: test debug macos-aarch64
  • GitHub Check: test debug macos-x86_64
  • GitHub Check: lint debug linux-x86_64
  • GitHub Check: lint debug windows-x86_64
  • GitHub Check: lint debug macos-x86_64
  • GitHub Check: build libs
🔇 Additional comments (3)
.github/workflows/issue_triage.yml (3)

22-102: Overall workflow structure looks reasonable.

The refactoring from claude-code-action to direct CLI invocation is clean and gives better control over environment setup, tool restrictions, and prompt management. Once the format() syntax issue is fixed, the workflow should execute properly.


99-102: --allowedTools syntax is correct.

The syntax "Bash(gh issue:*),Bash(gh search:*)" is valid—comma-separated scoped patterns with wildcards inside parentheses are supported. No changes needed.


47-49: Fix invalid GitHub Actions expression syntax on the prompt file creation.

Line 47 uses format('TITLE: {0}\nBODY: {1}...', ...), but GitHub Actions does not provide a format() function. This will cause a syntax error when the workflow is parsed. Use standard GitHub Actions conditional syntax instead.

Apply this diff to fix the conditional logic:

-          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: {0}
-          BODY: {1}
-          AUTHOR: {2}', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}
+          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: %s\nBODY: %s\nAUTHOR: %s', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}

Actually, if format() is not available, rewrite the conditional block to handle both cases separately:

-          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: {0}
-          BODY: {1}
-          AUTHOR: {2}', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}
+          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || 'TITLE: ' + github.event.issue.title + '\nBODY: ' + github.event.issue.body + '\nAUTHOR: ' + github.event.issue.user.login }}

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/issue_triage.yml (2)

32-38: Simplify GitHub CLI setup.

The ubuntu-latest runner includes GitHub CLI pre-installed. The verbose conditional setup with apt installation is unnecessary and adds complexity. Either remove this step entirely or use the official cli/gh-actions/setup-gh action for consistency with GitHub's recommendations.

       - name: Setup GitHub CLI
-        run: |
-          gh --version || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
-          && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
-          && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
-          && sudo apt update \
-          && sudo apt install gh -y)
+        run: gh --version

Or simply remove the step if gh is guaranteed to be available on ubuntu-latest.


29-30: Add error handling for Claude CLI installation.

If the npm installation fails, the workflow continues to the next step without stopping. Consider adding explicit error handling or using set -e in the run script to fail fast.

       - name: Install Claude Code CLI
-        run: npm install -g @anthropic-ai/claude-code
+        run: |
+          set -e
+          npm install -g @anthropic-ai/claude-code
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4106b7 and 7247d97.

📒 Files selected for processing (1)
  • .github/workflows/issue_triage.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/issue_triage.yml

43-43: "github.event.issue.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)


43-43: "github.event.issue.body" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)

🔇 Additional comments (2)
.github/workflows/issue_triage.yml (2)

92-101: Verify secret availability and add explicit error handling.

The workflow references secrets.DENOBOT_PAT for both GITHUB_TOKEN and GH_TOKEN, but there's no check to ensure it's available. Add safeguards or document the requirement clearly.

Confirm that DENOBOT_PAT is defined in the repository secrets and consider adding a pre-flight check:

       - name: Run Claude Code Triage
         env:
           ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
           GITHUB_TOKEN: ${{ secrets.DENOBOT_PAT }}
           GH_TOKEN: ${{ secrets.DENOBOT_PAT }}
+          REQUIRED_SECRETS: ${{ secrets.ANTHROPIC_API_KEY != '' && secrets.DENOBOT_PAT != '' && 'true' || 'false' }}
         run: |
+          if [ "$REQUIRED_SECRETS" != "true" ]; then
+            echo "Error: Required secrets (ANTHROPIC_API_KEY, DENOBOT_PAT) are not configured"
+            exit 1
+          fi
           claude-code \
             --mode auto \
             --allowedTools "Bash(gh issue:*),Bash(gh search:*)" \
             --prompt "$(cat /tmp/prompt.txt)"

46-48: Invalid GitHub Actions expression syntax.

Line 46 uses format() which does not exist in GitHub Actions expression syntax. This will cause the workflow to fail at runtime. Use conditional expressions with string concatenation instead.

-          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: {0}
-          BODY: {1}
-          AUTHOR: {2}', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}
+          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: %s\nBODY: %s\nAUTHOR: %s', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}

Actually, GitHub Actions expressions don't support format(). Rewrite this using only conditional logic:

-          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: {0}
-          BODY: {1}
-          AUTHOR: {2}', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}
+          ${{ github.event_name == 'workflow_dispatch' && 'This workflow was manually triggered to triage an existing issue. First, fetch the issue details using: `gh issue view [ISSUE_NUMBER] --repo denoland/deno --json number,title,body,author`' || format('TITLE: %s\nBODY: %s\nAUTHOR: %s', github.event.issue.title, github.event.issue.body, github.event.issue.user.login) }}

For workflows, you'll need to pass the issue details via separate environment variables and then reference them in the prompt. See the next comment for the proper approach.

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.github/workflows/issue_triage.yml (1)

32-38: GitHub CLI setup is defensive but potentially redundant.

Since gh is already pre-installed on ubuntu-latest, the setup script will succeed on the first check in most cases. However, the defensive fallback installation is reasonable for portability. Consider optimizing by caching or early-exit if gh is already available, though this is not critical since the check itself is fast.

If you want to optimize, you could write it as:

      - name: Setup GitHub CLI
-       run: |
-         gh --version || (curl -fsSL ... && sudo apt install gh -y)
+       run: gh --version && echo "GitHub CLI already installed" || (echo "Installing GitHub CLI..." && curl -fsSL ... && sudo apt install gh -y)

Or simply trust the pre-installed version and remove this step entirely.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7247d97 and bf3e45c.

📒 Files selected for processing (1)
  • .github/workflows/issue_triage.yml (1 hunks)
🔇 Additional comments (3)
.github/workflows/issue_triage.yml (3)

40-62: Proper handling of untrusted context values with environment variables.

The refactored code correctly addresses the prior security concern by moving github.event.issue fields into environment variables (lines 43-45) before using them in the script. The conditional logic properly handles both automatic (webhook) and manual triggers—using env vars only when they're populated, and instructing Claude to fetch details for manual runs.

The quoted heredocs and env var references maintain data integrity and follow GitHub Actions security best practices.


108-116: Good security posture on Claude invocation.

The restricted --allowedTools constrains Claude to only gh issue and gh search commands, which is appropriate for the triage task. Secrets are properly passed through environment variables, and the prompt file is cleanly injected via command substitution.


29-30: No issues found. The package @anthropic-ai/claude-code is the official Anthropic package and correctly provides the claude command used in the workflow.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
.github/workflows/issue_triage.yml (1)

32-38: Consider simplifying the GitHub CLI setup.

GitHub CLI is pre-installed on ubuntu-latest, so the defensive installation logic here is not strictly necessary. You can simplify this to just verify it exists or trust the default setup. That said, the current approach is safe and self-healing if the environment changes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf3e45c and 3248a60.

📒 Files selected for processing (1)
  • .github/workflows/issue_triage.yml (1 hunks)
🔇 Additional comments (3)
.github/workflows/issue_triage.yml (3)

40-62: Good security improvements on context variable handling.

The environment variables approach correctly addresses the previous security concern. Untrusted context values (github.event.issue.*) are now passed through the env: block and referenced as shell variables, preventing potential injection issues. The quoted heredoc syntax further hardens this against unintended expansion.


108-115: The Claude Code CLI invocation syntax is correct.

The --print flag and --allowedTools syntax used in the workflow are valid. The --print flag runs Claude Code in non-interactive mode and prints the final result, and the --allowedTools flag accepts a comma-separated string with tool patterns like Bash(gh issue:*) and Bash(gh search:*), which matches your implementation exactly.


29-30: No changes needed—Claude Code CLI package and command are correct.

The web search confirms the package name @anthropic-ai/claude-code is correct (the AI summary was inaccurate). The claude command is the proper entry point, so the invocation at line 114 will work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant