Skip to content

Run Playbooks as GitHub Actions

PLAYBOOK-MD/playbook-native is a GitHub Action that executes .playbook.md files in CI. It ships as a single Node 20 bundle, calls the Anthropic SDK directly step-by-step, and has no dependency on anthropics/claude-code-action. Pin it as @v1 and point it at a playbook in your repo.

When to reach for this

  • Event-driven automation — trigger a playbook on pull_request.opened, issues.opened, issue_comment.created, release.published, etc.
  • Scheduled reports — run a drift/summary/analytics playbook on a cron.
  • On-demand dispatch — let teammates trigger a playbook from the Actions UI with parameterized inputs.

Compared to Claude Code Routines, GitHub Actions gives you fine-grained event triggers (routines support a smaller set of GitHub events), pinned wire behavior, deterministic per-step logs in the job summary, and no dependency on Anthropic’s managed execution infrastructure.

Three-step setup

1. Commit your playbook

Place your .playbook.md anywhere in the repo. Convention:

your-repo/
├── playbooks/
│ └── my-workflow.playbook.md
└── .github/
└── workflows/
└── playbook.yml

2. Store your Anthropic key as a repo secret

Go to Settings → Secrets and variables → Actions → New repository secret and add ANTHROPIC_API_KEY. The workflow references it via ${{ secrets.ANTHROPIC_API_KEY }}.

3. Add the workflow

Minimal dispatch example:

name: Run playbook
on: [workflow_dispatch]
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: PLAYBOOK-MD/playbook-native@v1
with:
playbook: playbooks/my-workflow.playbook.md
inputs: |
topic: "Q2 launch"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Workflow templates

PR review / PR comment

on:
pull_request:
types: [opened, synchronize]
jobs:
summarize:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v5
- id: run
uses: PLAYBOOK-MD/playbook-native@v1
with:
playbook: playbooks/pr-summary.playbook.md
inputs: |
pr_title: ${{ github.event.pull_request.title }}
pr_body: ${{ github.event.pull_request.body }}
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('${{ steps.run.outputs.artifact-path }}', 'utf-8');
await github.rest.issues.createComment({
owner: context.repo.owner, repo: context.repo.repo,
issue_number: context.payload.pull_request.number, body,
});

Scheduled (cron)

on:
schedule:
- cron: '0 9 * * 1' # Monday 09:00 UTC
workflow_dispatch:
jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: PLAYBOOK-MD/playbook-native@v1
with:
playbook: playbooks/weekly-docs-drift.playbook.md
output-path: out/drift-${{ github.run_id }}.md
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

On-demand dispatch

on:
workflow_dispatch:
inputs:
topic:
description: 'Research topic'
required: true
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: PLAYBOOK-MD/playbook-native@v1
with:
playbook: playbooks/research.playbook.md
inputs: "topic: ${{ inputs.topic }}"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

Inputs and outputs

InputRequiredDefaultDescription
playbookyesPath to the .playbook.md file
inputsnoYAML block of input values
elicitnoYAML block of @elicit overrides keyed by step number
output-pathnoout/<run-id>.mdDestination for the final artifact
modelnoclaude-opus-4-7Anthropic model ID
strictnofalseFail on validation warnings
OutputDescription
artifact-pathPath to the written artifact
statusok, failed, or skipped
step-countNumber of steps executed
warningsNumber of warnings emitted

Capability matrix

Spec featureSupport
Title / Description / ## SYSTEMFull
Typed ## INPUTSFull
{{var}} interpolationFull
Sequential steps + context accumulationFull
## ARTIFACTS (all types)Full
Branching if/elif/elseFull
@output (basic / typed / enum)Full
@output(extract:"field")Full (deterministic parser)
@prompt(file:…)Full
@prompt(library:…)Not supported in v1 (requires MCP)
@prompt(mcp:server/name)Not supported in v1
@prompt({{var}})Full
@tool(name)Not supported in v1 (requires MCP)
@elicit(input|confirm|select)Autonomous defaults; overrides via elicit: input
BreakpointsNot supported (warning)

Playbooks using unsupported directives are rejected at pre-flight with an actionable error.

@elicit in autonomous runs

Native applies the same autonomous-mode defaults as Claude Code Routines when no override is provided:

  • @elicit(confirm, "…")"yes"
  • @elicit(select, "…", "A", "B", "C")"A" (first option)
  • @elicit(input, "…")""

Override any specific step by step number via the elicit: input:

with:
elicit: |
3: "no"
4: "Performance"

Composing pauses around the action

Unlike routines, GitHub Actions can pause on human input — but v1 doesn’t implement first-class pauses. Compose them around the action:

  • Environment gates (for confirm-style approvals): a downstream job with environment: <name-with-required-reviewers> blocks on approval via the Actions UI.
  • Third-party manual-approval actions (e.g. trstringer/manual-approval): precede the playbook with a step that opens an issue and polls for a response.

Authentication

playbook-native reads the Anthropic API key from the ANTHROPIC_API_KEY environment variable. Set it as a repo secret (Settings → Secrets and variables → Actions) and pass it through the workflow’s env: block. The action fails pre-flight with a clear message if the variable is missing.

Limitations

  • No MCP directives in v1 — see the capability matrix.
  • No first-class breakpoints — they emit a warning.
  • Per-run cost — every step is an Anthropic API call. Use strict: true in CI to fail fast on spec warnings before burning tokens.

Example playbooks

The gallery has a curated list of playbooks that run on native as-is.