Skip to content
Latchkey

Claude Code workflow (storybookjs/storybook)

The Claude Code workflow from storybookjs/storybook, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: storybookjs/storybook.github/workflows/claude.ymlLicense MITView source

What it does

This is the Claude Code workflow from the storybookjs/storybook repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude:
    # Only org OWNERs and MEMBERs may trigger Claude. author_association is set by
    # GitHub on the comment/review/issue payload; everything else (COLLABORATOR,
    # CONTRIBUTOR, FIRST_TIME_CONTRIBUTOR, NONE) is rejected.
    if: |
      (github.event_name == 'issue_comment' &&
        contains(github.event.comment.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.comment.author_association)) ||
      (github.event_name == 'pull_request_review_comment' &&
        contains(github.event.comment.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.comment.author_association)) ||
      (github.event_name == 'pull_request_review' &&
        contains(github.event.review.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.review.author_association)) ||
      (github.event_name == 'issues' && (
        (github.event.action == 'opened' &&
          contains(fromJSON('["OWNER", "MEMBER"]'), github.event.issue.author_association) &&
          (contains(github.event.issue.body, '`@claude`') || contains(github.event.issue.title, '`@claude`'))) ||
        (github.event.action == 'assigned' && github.event.assignee.login == 'claude')
      ))

    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 1
          persist-credentials: false

      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@a92e7c70a4da9793dc164451d829089dc057a464 # v1.0.159
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          assignee_trigger: 'claude'
          base_branch: 'next'
          prompt: 'Respect the PR description template and repository guidelines in AGENTS.md.'
          # Allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read

          # Tool permissions Claude needs to follow AGENTS.md (install, compile,
          # typecheck, lint, format, test). Bash is NOT allowed by default, so
          # without this Claude cannot run any of the repo's build/test commands.
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options
          claude_args: |
            --allowed-tools "Bash(yarn:*),Bash(cd:*),Bash(node:*),Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git show:*)"
            --disallowed-tools "Bash(yarn start),Bash(yarn task dev)"

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Claude Code
 
on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]
 
jobs:
  claude:
    timeout-minutes: 30
    # Only org OWNERs and MEMBERs may trigger Claude. author_association is set by
    # GitHub on the comment/review/issue payload; everything else (COLLABORATOR,
    # CONTRIBUTOR, FIRST_TIME_CONTRIBUTOR, NONE) is rejected.
    if: |
      (github.event_name == 'issue_comment' &&
        contains(github.event.comment.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.comment.author_association)) ||
      (github.event_name == 'pull_request_review_comment' &&
        contains(github.event.comment.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.comment.author_association)) ||
      (github.event_name == 'pull_request_review' &&
        contains(github.event.review.body, '@claude') &&
        contains(fromJSON('["OWNER", "MEMBER"]'), github.event.review.author_association)) ||
      (github.event_name == 'issues' && (
        (github.event.action == 'opened' &&
          contains(fromJSON('["OWNER", "MEMBER"]'), github.event.issue.author_association) &&
          (contains(github.event.issue.body, '`@claude`') || contains(github.event.issue.title, '`@claude`'))) ||
        (github.event.action == 'assigned' && github.event.assignee.login == 'claude')
      ))
 
    runs-on: latchkey-small
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 1
          persist-credentials: false
 
      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@a92e7c70a4da9793dc164451d829089dc057a464 # v1.0.159
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          assignee_trigger: 'claude'
          base_branch: 'next'
          prompt: 'Respect the PR description template and repository guidelines in AGENTS.md.'
          # Allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read
 
          # Tool permissions Claude needs to follow AGENTS.md (install, compile,
          # typecheck, lint, format, test). Bash is NOT allowed by default, so
          # without this Claude cannot run any of the repo's build/test commands.
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://code.claude.com/docs/en/cli-reference for available options
          claude_args: |
            --allowed-tools "Bash(yarn:*),Bash(cd:*),Bash(node:*),Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git show:*)"
            --disallowed-tools "Bash(yarn start),Bash(yarn task dev)"
 

What changed

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow