Skip to content

chore(github): update Claude Code workflows#4473

Open
pomfrida wants to merge 2 commits intomainfrom
chore/update-claude-actions
Open

chore(github): update Claude Code workflows#4473
pomfrida wants to merge 2 commits intomainfrom
chore/update-claude-actions

Conversation

@pomfrida
Copy link
Collaborator

@pomfrida pomfrida commented Feb 6, 2026

Summary

  • Mention workflow (claude.yml): Added admin-only gate, project setup steps (Node.js, pnpm, install, build), custom instructions via claude_args, and explicit --allowed-tools
  • Review workflow (claude-code-review.yml): Changed trigger to ready_for_review only, added project setup steps, review-focused custom instructions via claude_args, upgraded pull-requests permission to write

Test plan

  • Verify admin gate by having a non-admin user tag @claude in an issue — should skip gracefully
  • Verify admin user can trigger @claude successfully
  • Mark a draft PR as ready for review and confirm auto-review triggers
  • Check that project setup (pnpm install + build) completes without errors in CI

🤖 Generated with Claude Code

@pomfrida pomfrida self-assigned this Feb 6, 2026
@pomfrida pomfrida added the ai-tooling AI-assisted development tools, prompts, and workflows (Claude Code, Copilot, Opencode etc.) label Feb 6, 2026
@pomfrida
Copy link
Collaborator Author

pomfrida commented Feb 6, 2026

@claude code review

@claude
Copy link

claude bot commented Feb 6, 2026

Claude finished @pomfrida's task in 1m 6s —— View job


Code Review

  • Read workflow files
  • Analyze changes for security, correctness, and best practices
  • Provide detailed review feedback

Summary

Overall, these are solid improvements to the Claude Code workflows. The changes add appropriate security controls, project setup steps, and better customization. I've identified a few issues and suggestions below.

Critical Issues

1. Admin gate bypass vulnerability (.github/workflows/claude.yml:35-37)

The admin permission check has a logic flaw. When a non-admin user triggers the workflow, the script exits with code 0 (success), which causes subsequent steps to be skipped but the job still succeeds. This means non-admin users can trigger successful (albeit empty) workflow runs, which might be misleading in PR status checks.

if [ "$PERMISSION" != "admin" ]; then
  echo "::notice::User ${{ github.actor }} has '$PERMISSION' permission, 'admin' required. Skipping."
  exit 0  # ← Job succeeds even though nothing was done
fi

Recommendation: Use exit 78 (neutral exit code) or set a job output and use jobs.<job_id>.conclusion to mark the job as skipped/neutral, or fail the job explicitly with exit 1. Example:

if [ "$PERMISSION" != "admin" ]; then
  echo "::warning::User ${{ github.actor }} has '$PERMISSION' permission, 'admin' required."
  exit 1
fi

2. Missing --allowed-tools for review workflow (.github/workflows/claude-code-review.yml)

The claude.yml workflow includes explicit --allowed-tools restrictions, but claude-code-review.yml does not. For consistency and security, the review workflow should also have tool restrictions.

Recommendation: Add --allowed-tools to the review workflow's claude_args, perhaps with a more restrictive set since reviews typically don't need write operations:

--allowed-tools
"Bash(git:*),Bash(gh pr:*),Bash(gh issue:*),Bash(ls:*),Bash(cat:*),Bash(grep:*),Bash(head:*),Bash(tail:*)"

Security Concerns

3. Overly permissive tool allowances (.github/workflows/claude.yml:89)

The --allowed-tools includes several potentially risky commands:

  • Bash(echo:*) - Could be used for command injection via echo to files
  • Bash(mkdir:*), Bash(cp:*), Bash(mv:*) - File system manipulation
  • Bash(cat:*), Bash(find:*), Bash(grep:*) - Redundant with Claude's built-in Read/Glob/Grep tools

Recommendation: Remove redundant tools that duplicate Claude's specialized tools (Read, Glob, Grep are better than cat/find/grep). Consider whether echo, mkdir, cp, mv are truly necessary for the workflow's intended use cases.

4. Permission escalation (.github/workflows/claude.yml:22-24)

The permissions changed from read to write for contents, pull-requests, and issues. While this may be intentional for Claude to make commits and comments, it significantly increases the blast radius if the API key is compromised or Claude behaves unexpectedly.

Recommendation: Document why write permissions are necessary. Consider whether all three write permissions are needed, or if some could remain read-only.

Best Practices & Suggestions

5. pnpm install --force flag (.github/workflows/claude.yml:60 and .github/workflows/claude-code-review.yml:45)

The --force flag bypasses lockfile validation and can mask dependency issues. Unless there's a specific reason for it, this should be avoided in CI.

Recommendation: Use pnpm install --frozen-lockfile for CI environments to ensure reproducible builds and fail fast on lockfile mismatches.

6. Hardcoded Node.js version (both workflows)

Node.js version 22.12.0 is hardcoded. Consider using a variable or reading from .nvmrc/package.json#engines for consistency.

Recommendation: Add a .nvmrc file or use node-version-file: .nvmrc in the setup-node action.

7. Missing error handling for build step (both workflows)

If pnpm run build fails, the workflow will fail, but there's no explicit error messaging or recovery.

Recommendation: Consider adding continue-on-error: false explicitly and/or a failure notification step.

8. Redundant fetch-depth: 1 (both workflows)

fetch-depth: 1 is the default for actions/checkout@v4, so explicitly specifying it is redundant.

Recommendation: Remove fetch-depth: 1 or add a comment explaining if there's a specific reason to keep it explicit.

9. System prompt formatting (both workflows)

The system prompts in claude_args use >- for multiline strings, which concatenates lines with spaces. This works, but the formatting could be clearer.

Recommendation: Use |- to preserve newlines, or keep >- but add explicit line breaks with \n if needed for readability.

Minor Issues

10. Inconsistent trigger types (.github/workflows/claude-code-review.yml:5)

The review workflow was changed from [opened, synchronize, ready_for_review, reopened] to only [ready_for_review]. This means reviews won't run on:

  • Initial PR opening (if not a draft)
  • New commits pushed to PR
  • Reopened PRs

Question: Is this intentional? This significantly limits when auto-reviews happen.

11. Missing CI status check integration (.github/workflows/claude-code-review.yml)

The claude.yml workflow has actions: read permission for Claude to read CI results, but the review workflow doesn't have this permission.

Recommendation: Add actions: read permission to the review workflow as well if Claude should be able to review CI failures.

Test Plan Feedback

The test plan in the PR description is good, but consider adding:

  • Test what happens when the admin gate rejects a user (verify job status)
  • Test that --allowed-tools restrictions work as expected (try a disallowed command)
  • Test build/install steps on a clean environment

Summary of Recommendations

Critical:

  1. Fix admin gate exit code to properly fail/skip non-admin runs
  2. Add --allowed-tools to review workflow

High Priority:
3. Review and reduce tool allowances in claude.yml
4. Document why write permissions are necessary
5. Change pnpm install --force to --frozen-lockfile

Nice to Have:
6. Use .nvmrc or variable for Node.js version
7. Clarify review workflow trigger intention
8. Add actions: read to review workflow


| Branch: chore/update-claude-actions

@pomfrida
Copy link
Collaborator Author

pomfrida commented Feb 6, 2026

@claude do another code review with this in mind:

Addressed:

  • 2 - Missing --allowed-tools for review workflow: Added a restrictive set of read-only tools.
  • 11 - Missing actions: read for review workflow: Added.

Intentional / already considered:

  • 1 - Admin gate exit 0: Using exit 0 is deliberate. exit 1 would mark the job as failed, which could block PR merges if this is a required status check. The exit 0 + if-conditions on all subsequent steps is the safest pattern
    — the job succeeds without doing anything.
  • 4 - Write permissions: Required for Claude to push code and post comments. The admin gate mitigates the risk.
  • 10 - Trigger changed to ready_for_review only: Intentional. We want auto-reviews only when a PR is marked as ready. For other cases we use @claude in the mention workflow.

Not changing (for consistency with existing repo patterns):

  • 5 - pnpm install --force: The repo's own _setup.yml uses --force. Changing only the Claude workflows would be inconsistent. Should be addressed across all workflows in a separate PR if desired.
  • 6 - Hardcoded Node.js version: Same as _setup.yml. Consistent with the rest of the repo.
  • 8 - Explicit fetch-depth: 1: All workflows in this repo specify it explicitly. Keeping it for consistency and clarity.

Not applicable:

  • 3 - Overly permissive tools: Tools like cat, find, grep are useful in CI where Claude's built-in tools may not always be available. Low risk.
  • 7 - Missing error handling for build: continue-on-error defaults to false. No change needed.
  • 9 - System prompt formatting: >- works fine for this use case.

@claude
Copy link

claude bot commented Feb 6, 2026

Claude finished @pomfrida's task in 51s —— View job


Follow-up Code Review

  • Read updated workflow files
  • Verify addressed issues
  • Provide comprehensive review feedback

Summary

The updates look good overall. The two items flagged as "Addressed" have been properly implemented, and your explanations for the intentional decisions and consistency choices are reasonable. I have a few minor observations and one suggestion below.


Verified Addressed Items ✓

Issue #2 - Missing --allowed-tools for review workflow
.github/workflows/claude-code-review.yml:69-70

The review workflow now has a restrictive read-only tool set:

--allowed-tools
"Bash(git:*),Bash(gh pr:*),Bash(gh issue:*),Bash(ls:*),Bash(cat:*),Bash(grep:*),Bash(head:*),Bash(tail:*)"

This is appropriate for code reviews and matches the read-only nature of the task. Good.

Issue #11 - Missing actions: read for review workflow
.github/workflows/claude-code-review.yml:27

The review workflow now includes:

actions: read

This allows Claude to read CI results when reviewing PRs. Good addition.


Accepted Explanations

Issue #1 - Admin gate exit 0
Your explanation makes sense. Using exit 0 with if conditions on all subsequent steps is a valid pattern to avoid blocking PR merges if this becomes a required status check. The workflow will succeed without doing anything, which is the desired behavior for non-admin users.

Issue #4 - Write permissions
Agreed. The admin gate provides reasonable mitigation, and write permissions are necessary for Claude to push code and post comments.

Issue #10 - Trigger changed to ready_for_review only
Clear rationale. Using ready_for_review for auto-reviews and @claude mentions for other cases is a sensible workflow split.

Issues #5, #6, #8 - Consistency with existing repo patterns
I verified that .github/workflows/_setup.yml (the reusable setup workflow) does indeed use pnpm install --force, hardcoded Node.js version 22.12.0, and explicit fetch-depth: 1. Maintaining consistency with existing repo patterns is the right call.

Issues #3, #7, #9 - Not applicable
Fair points. The tools in the mention workflow have low risk, continue-on-error: false is the default, and >- formatting works fine for the system prompts.


Minor Observations

1. System prompt in review workflow (.github/workflows/claude-code-review.yml:63-68)

The system prompt mentions "WCAG 2.1 AA accessibility, EDS design tokens, named exports only, forwardRef pattern, vanilla CSS with BEM, test coverage with jest-axe, and conventional commits."

This is good context, but it's quite specific to component reviews. If this workflow ever reviews non-component PRs (e.g., docs, tooling, CI changes), this guidance might be less relevant. Not a blocker, just something to keep in mind if the scope of auto-reviews expands in the future.

2. Redundant additional_permissions in mention workflow (.github/workflows/claude.yml:74-75)

The mention workflow has:

additional_permissions: |
  actions: read

But actions: read is already granted at the job level (line 26). This additional_permissions field appears to be redundant. It doesn't hurt anything, but it could be removed for clarity.

3. Plugin marketplace URL (.github/workflows/claude-code-review.yml:56)

The review workflow specifies:

plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'

This is fine, but be aware that if the plugin marketplace URL changes in the future, this will need updating. Consider whether this should be pinned to a specific ref (e.g., a tag or commit SHA) for stability, or if tracking the latest version is preferred.


Suggestions (Optional)

Consider adding a comment explaining the admin gate pattern

Since the exit 0 pattern in the admin gate is intentional but non-obvious, consider adding a brief inline comment:

if [ "$PERMISSION" != "admin" ]; then
  echo "::notice::User ${{ github.actor }} has '$PERMISSION' permission, 'admin' required. Skipping."
  # Exit 0 to succeed without running subsequent steps (prevents blocking PR merges if this becomes a required check)
  exit 0
fi

This would help future maintainers understand the rationale at a glance.


Final Verdict

Approve with minor observations

The workflows are well-structured and the changes address the key concerns from the previous review. The intentional decisions are justified, and consistency with existing repo patterns is maintained. The minor observations above are non-blocking and mostly informational.

Great work on the thoughtful approach to addressing feedback and maintaining repo consistency!


| Branch: chore/update-claude-actions

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

Labels

ai-tooling AI-assisted development tools, prompts, and workflows (Claude Code, Copilot, Opencode etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant