170 lines
6.9 KiB
YAML
170 lines
6.9 KiB
YAML
name: Storybook Deploy
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
branch:
|
|
description: "Repository branch to publish (empty uses the selected workflow branch)"
|
|
type: string
|
|
default: ""
|
|
# Also exposed by Storybook Visual, which is already available on master.
|
|
workflow_call:
|
|
inputs:
|
|
branch:
|
|
type: string
|
|
default: ""
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
authorize:
|
|
name: Authorize Storybook publisher
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
sha: ${{ steps.source.outputs.sha }}
|
|
branch: ${{ steps.source.outputs.branch }}
|
|
branch_key: ${{ steps.source.outputs.branch_key }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
- name: Require CODEOWNER initiator and rerunner
|
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
|
|
with:
|
|
script: |
|
|
const authorize = require('./.github/scripts/authorize-storybook-deploy.cjs');
|
|
await authorize({ github, context });
|
|
|
|
- name: Pin requested repository branch
|
|
id: source
|
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
|
|
env:
|
|
SOURCE_BRANCH: ${{ inputs.branch }}
|
|
STORYBOOK_S3_BUCKET: ${{ vars.STORYBOOK_S3_BUCKET }}
|
|
STORYBOOK_PUBLIC_BASE_URL: ${{ vars.STORYBOOK_PUBLIC_BASE_URL }}
|
|
with:
|
|
script: |
|
|
const branch = process.env.SOURCE_BRANCH || context.ref.slice('refs/heads/'.length);
|
|
const { data } = await github.rest.git.getRef({ ...context.repo, ref: `heads/${branch}` });
|
|
if (data.ref !== `refs/heads/${branch}` || data.object.type !== 'commit') {
|
|
throw new Error('Select an existing branch in this repository.');
|
|
}
|
|
// With no source override, preserve the exact dispatched commit.
|
|
const sha = process.env.SOURCE_BRANCH ? data.object.sha : context.sha;
|
|
const { storybookDestination } = require('./.github/scripts/storybook-destination.cjs');
|
|
const destination = storybookDestination({ branch, sha,
|
|
runId: context.runId, runAttempt: process.env.GITHUB_RUN_ATTEMPT,
|
|
bucket: process.env.STORYBOOK_S3_BUCKET, baseUrl: process.env.STORYBOOK_PUBLIC_BASE_URL });
|
|
core.setOutput('sha', sha);
|
|
core.setOutput('branch_key', destination.branchKey);
|
|
core.setOutput('branch', branch);
|
|
|
|
build:
|
|
name: Build selected branch Storybook
|
|
permissions: {}
|
|
needs: authorize
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
outputs:
|
|
artifact_name: ${{ steps.artifact.outputs.name }}
|
|
env:
|
|
STORYBOOK_DISABLE_TELEMETRY: "1"
|
|
steps:
|
|
- name: Download public source without repository credentials
|
|
env:
|
|
SOURCE_SHA: ${{ needs.authorize.outputs.sha }}
|
|
run: |
|
|
[[ "$SOURCE_SHA" =~ ^[a-f0-9]{40}$ ]]
|
|
curl --fail --silent --show-error --location --retry 3 \
|
|
"https://codeload.github.com/paperclipai/paperclip/tar.gz/$SOURCE_SHA" \
|
|
--output "$RUNNER_TEMP/source.tar.gz"
|
|
tar -xzf "$RUNNER_TEMP/source.tar.gz" --strip-components=1
|
|
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6
|
|
with:
|
|
version: 9.15.4
|
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
|
|
with:
|
|
node-version: 24
|
|
package-manager-cache: false
|
|
- run: pnpm install --frozen-lockfile --ignore-scripts
|
|
- run: pnpm build-storybook
|
|
- name: Record source and validate output
|
|
id: artifact
|
|
env:
|
|
SOURCE_SHA: ${{ needs.authorize.outputs.sha }}
|
|
SOURCE_BRANCH: ${{ needs.authorize.outputs.branch }}
|
|
run: |
|
|
test -s ui/storybook-static/index.html
|
|
test -s ui/storybook-static/iframe.html
|
|
test -s ui/storybook-static/index.json
|
|
jq -n --arg sha "$SOURCE_SHA" --arg branch "$SOURCE_BRANCH" \
|
|
'{sha: $sha, branch: $branch}' > ui/storybook-static/deployment.json
|
|
echo "name=storybook-deploy-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "$GITHUB_OUTPUT"
|
|
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
with:
|
|
name: ${{ steps.artifact.outputs.name }}
|
|
path: ui/storybook-static
|
|
if-no-files-found: error
|
|
retention-days: 7
|
|
|
|
deploy:
|
|
name: Publish branch Storybook to S3
|
|
needs: [authorize, build]
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
concurrency:
|
|
group: storybook-deploy-${{ needs.authorize.outputs.branch_key }}
|
|
cancel-in-progress: false
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
environment:
|
|
name: storybook-deploy
|
|
url: ${{ steps.deployment.outputs.url }}
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
|
with:
|
|
persist-credentials: false
|
|
sparse-checkout: .github/scripts
|
|
- name: Recheck CODEOWNER access before publishing
|
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
|
|
with:
|
|
script: |
|
|
const authorize = require('./.github/scripts/authorize-storybook-deploy.cjs');
|
|
await authorize({ github, context });
|
|
- name: Download the successful build artifact
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
|
with:
|
|
name: ${{ needs.build.outputs.artifact_name }}
|
|
path: storybook-static
|
|
- name: Assume the Storybook-only uploader role
|
|
uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6
|
|
with:
|
|
role-to-assume: ${{ vars.STORYBOOK_AWS_ROLE_ARN }}
|
|
aws-region: ${{ vars.STORYBOOK_AWS_REGION }}
|
|
role-duration-seconds: 900
|
|
- name: Publish this branch preview
|
|
id: deployment
|
|
env:
|
|
SOURCE_SHA: ${{ needs.authorize.outputs.sha }}
|
|
SOURCE_BRANCH: ${{ needs.authorize.outputs.branch }}
|
|
STORYBOOK_S3_BUCKET: ${{ vars.STORYBOOK_S3_BUCKET }}
|
|
STORYBOOK_PUBLIC_BASE_URL: ${{ vars.STORYBOOK_PUBLIC_BASE_URL }}
|
|
run: node .github/scripts/publish-storybook.cjs
|
|
- name: Verify public build and stable branch URL
|
|
env:
|
|
BUILD_URL: ${{ steps.deployment.outputs.build_url }}
|
|
BRANCH_URL: ${{ steps.deployment.outputs.url }}
|
|
SOURCE_SHA: ${{ needs.authorize.outputs.sha }}
|
|
run: node .github/scripts/verify-storybook.cjs
|
|
- name: Upload deployment links
|
|
if: ${{ !cancelled() && steps.deployment.outcome == 'success' }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
|
with:
|
|
name: storybook-deployment-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: ${{ steps.deployment.outputs.report_path }}
|
|
if-no-files-found: error
|
|
retention-days: 30
|