GitHub Actions
How driftless uses GitHub Actions to keep docs and tests in sync with your code.
driftless scaffolds two GitHub Actions workflows during driftless init. You don't write these by hand — the CLI generates them based on your selected capabilities.
Required Secret
Both workflows need an ANTHROPIC_API_KEY secret in your repository. Go to Settings → Secrets
and variables → Actions → New repository secret and add your Anthropic API key as
ANTHROPIC_API_KEY. Without it, the workflows skip gracefully but won't do anything.
Workflows
Doc Update (driftless-doc-update.yml)
Triggers on every pull request. Uses claude-code-action to:
- Read the PR diff
- Identify which user-facing features changed
- Find documentation in your output directory that covers those features
- Update any stale docs to match the new behavior
- Post a PR comment summarizing what changed
This workflow is installed when you select the doc-generator capability.
Test Generation (driftless-test-gen.yml)
Also triggers on every pull request. Uses claude-code-action to:
- Read the PR diff
- Identify genuinely new user-facing flows (not modifications to existing ones)
- Generate missing e2e tests using your installed e2e-writer skill
- Post a PR comment summarizing what was generated and what was skipped
This workflow is installed when you select the e2e-writer capability.
Operational Edge Handlers
Both workflows share the same set of guards that handle CI edge cases. These are generated automatically — you don't need to configure them.
Bot Loop Prevention
if: >-
!endsWith(github.actor, '[bot]')GitHub Actions exposes github.actor for every run. Bot accounts (like the one claude-code-action uses to push commits) have names ending in [bot]. This condition prevents infinite loops where the workflow triggers itself by pushing a commit that re-triggers the workflow.
Fork PR Detection
- name: Skip fork PRs
if: github.event.pull_request.head.repo.fork == true
run: |
echo "::notice::Skipping driftless: fork PRs cannot access secrets."
exit 0Fork PRs can't access your repository secrets. Instead of failing with a confusing auth error, the workflow detects forks and exits cleanly with a notice annotation.
API Key Check
- name: Check for API key
if: github.event.pull_request.head.repo.fork != true
env:
HAS_KEY: ${{ secrets.ANTHROPIC_API_KEY != '' }}
run: |
if [ "$HAS_KEY" != "true" ]; then
echo "::warning::ANTHROPIC_API_KEY secret is not set. Skipping driftless doc update."
exit 0
fiIf ANTHROPIC_API_KEY is missing or empty, the workflow exits with a warning annotation instead of crashing. This lets you merge the workflow file before adding the secret.
PR Branch Checkout
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0Two things happen here:
ref: head.ref— checks out the PR branch directly, not the merge commit. This is required so claude-code-action can push follow-up commits (doc updates or new test files) back to the PR branch.fetch-depth: 0— fetches full git history. The agent needs this to rungit diff HEAD~1and understand what changed in the PR.
Generated Workflow Structure
Here's the overall shape of a generated workflow (doc-update shown, test-gen is identical in structure):
name: Driftless Doc Update
on:
pull_request:
jobs:
update-docs:
if: >-
!endsWith(github.actor, '[bot]')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- name: Skip fork PRs
# ... fork detection guard
- name: Check for API key
# ... API key guard
- name: Checkout PR branch
# ... full-history checkout
- name: Update stale documentation
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
# ... staleness detection prompt generated from your config
claude_args: "--allowedTools bash,read,write,edit"The permissions block grants contents: write (to push commits), pull-requests: write (to post PR comments), and id-token: write (for OIDC auth).
What You Control
The prompts embedded in each workflow are generated from your .driftless.json config:
outputDir— tells the agent where to find/write documentationtestPaths— tells the agent which test file patterns to scanskillsDir— tells the agent where to find skill definitions for formatting conventionscapabilities— determines which workflows get installed (doc-generator,e2e-writer, or both)
If you change these config values, re-run driftless init to regenerate the workflows.
Troubleshooting CI
If a workflow isn't running or behaving unexpectedly, see the Troubleshooting page for common issues including missing API keys, permission errors, and how to read debug logs.