GitHub Actions
TL;DR: Automate Storybook deployments on every push with GitHub Actions.
What You'll Learn
- How the generated workflows work
- How to customize deployment triggers
- How to handle different environments
Prerequisites
- [ ] Completed the Quick Start setup
- [ ] Repository with GitHub Actions enabled
Example Workflows
The setup skill can adapt workflows to your repository. The init command generates two workflow files and commits and pushes them. The examples below show basic hosting; generated templates also include coverage and analysis steps. For searchable components, keep those steps as described under Index components for MCP.
Main Deployment (.github/workflows/deploy-storybook.yml)
Deploys to production on pushes to main:
name: Deploy Storybook
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Storybook
run: npm run build-storybook
- name: Deploy to Scry
env:
STORYBOOK_DEPLOYER_API_URL: ${{ vars.SCRY_API_URL }}
STORYBOOK_DEPLOYER_API_KEY: ${{ secrets.SCRY_API_KEY }}
STORYBOOK_DEPLOYER_PROJECT: ${{ vars.SCRY_PROJECT_ID }}
STORYBOOK_DEPLOYER_VERSION: latest
run: npx @scrymore/scry-deployer --dir ./storybook-static --deploy-version latestPR Preview (.github/workflows/deploy-pr-preview.yml)
Deploys previews for pull requests:
name: Deploy PR Preview
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
deploy:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build Storybook
run: npm run build-storybook
- name: Deploy Preview
id: deploy
env:
STORYBOOK_DEPLOYER_API_URL: ${{ vars.SCRY_API_URL }}
STORYBOOK_DEPLOYER_API_KEY: ${{ secrets.SCRY_API_KEY }}
STORYBOOK_DEPLOYER_PROJECT: ${{ vars.SCRY_PROJECT_ID }}
STORYBOOK_DEPLOYER_VERSION: pr-${{ github.event.pull_request.number }}
run: |
npx @scrymore/scry-deployer --dir ./storybook-static --deploy-version pr-${{ github.event.pull_request.number }}
echo "url=${{ vars.SCRY_VIEW_URL || 'https://view.scrymore.com' }}/${{ vars.SCRY_PROJECT_ID }}/pr-${{ github.event.pull_request.number }}/" >> $GITHUB_OUTPUT
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const url = '${{ steps.deploy.outputs.url }}';
const body = `## 🚀 Storybook Preview Deployed\n\n**Preview URL:** ${url}\n\n📌 **Details:**\n- **Commit:** \`${{ github.sha }}\`\n- **Branch:** \`${{ github.head_ref }}\`\n\n> This preview will be updated automatically on each commit.`;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c => c.body.includes('Storybook Preview Deployed'));
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body
});
}Index components for MCP
Use --with-analysis with coverage enabled to capture and upload the metadata and screenshots needed by search. Install the Playwright browser used by the coverage runner before deploying. The deployer's generated templates include this step; ensure its browser version matches your installed runner if you customize the dependencies.
Keep these settings for PRs that need searchable previews too. A draft-PR --no-coverage condition prevents the metadata path from running. For a basic hosting-only workflow such as the examples above, indexing is not enabled.
Check both the upload result and a project-filtered MCP search. Processing is asynchronous, so components may become searchable after the Storybook is already live. The setup skill can configure and check this complete path.
Repository Variables
Set these in Settings → Secrets and variables → Actions → Variables:
| Variable | Description | Example |
|---|---|---|
SCRY_PROJECT_ID | Your project identifier | my-storybook |
SCRY_API_URL | Upload service endpoint | https://upload.scrymore.com |
SCRY_VIEW_URL | CDN viewer URL | https://view.scrymore.com |
Repository Secrets
Set these in Settings → Secrets and variables → Actions → Secrets:
| Secret | Description |
|---|---|
SCRY_API_KEY | Your project API key |
Security
Never commit API keys to your repository. Always use GitHub Secrets.
Customizing Workflows
Different Build Commands
If your build command differs from build-storybook:
- name: Build Storybook
run: npm run storybook:build # Your custom commandAdditional Build Steps
Add steps before deployment:
- name: Run Tests
run: npm test
- name: Lint
run: npm run lint
- name: Build Storybook
run: npm run build-storybookDeploy on Tags
Deploy on release tags:
on:
push:
tags:
- 'v*'
# In deploy step:
STORYBOOK_DEPLOYER_VERSION: ${{ github.ref_name }}Matrix Builds
Deploy multiple Storybooks:
jobs:
deploy:
strategy:
matrix:
storybook: [main, components, patterns]
steps:
# ...
- name: Deploy
env:
STORYBOOK_DEPLOYER_PROJECT: my-project-${{ matrix.storybook }}
run: npx @scrymore/scry-deployer --dir ./storybook-${{ matrix.storybook }}Conditional Deployment
Deploy only when Storybook files change:
on:
push:
branches: [main]
paths:
- 'src/**/*.stories.*'
- '.storybook/**'
- 'package.json'Environment Variables Reference
| Variable | CLI Flag | Description |
|---|---|---|
STORYBOOK_DEPLOYER_DIR | --dir | Build directory |
STORYBOOK_DEPLOYER_PROJECT | --project | Project ID |
STORYBOOK_DEPLOYER_VERSION | --version | Version string |
STORYBOOK_DEPLOYER_API_KEY | --api-key | API key |
STORYBOOK_DEPLOYER_API_URL | --api-url | API endpoint |
TIP
The SCRY_ prefix also works for all variables and takes precedence.
Troubleshooting
"Workflow not triggered"
Check that:
- Workflow file is in
.github/workflows/ - Branch name matches trigger conditions
- GitHub Actions is enabled for the repository
"Secrets not available"
For pull requests from forks, secrets are not available by default. Consider:
- Using environment-based secrets
- Requiring approval for fork PRs
"Build fails"
Check that:
build-storybookscript exists inpackage.json- Dependencies are correctly installed
- Node.js version matches your project requirements
Next Steps
- PR Previews - Configure preview comments
- Notifications - Add Slack/Teams notifications
- Troubleshooting - Common issues and solutions