Files
PaperClipAI/doc/STORYBOOK-DEPLOYMENT.md
T
DottaandPaperclip a20ecce409 feat: publish CODEOWNER-approved Storybook branch previews (#13226)
## Thinking Path

> - Paperclip helps people manage AI agents for work.
> - Maintainers use Storybook to review the board UI.
> - Reviews need public previews of selected repository branches.
> - Each branch needs its own URL so previews do not replace each other.
> - This pull request adds manual, CODEOWNER-controlled publishing to S3
and CloudFront.
> - The action returns stable branch links and permanent build links in
its summary and a Markdown artifact.

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The existing Storybook build and manual visual-review workflow.

**Current behavior**

The repository has no manual branch-preview publisher. A single GitHub
Pages site cannot support independent publishers without combining their
output.

**Proposed behavior**

A CODEOWNER selects a source branch and approves publication. Each
branch has a stable CloudFront URL. A completed build becomes the branch
target only after its upload succeeds. The action attaches
`storybook-deployment.md` with the preview links and source commit.

**Reason and benefit**

Maintainers can share multiple branch previews at the same time. Branch
builds have no repository token permissions or AWS credentials.
Dependency caching and install hooks are disabled. The publisher cannot
write runner dashboard files or delete objects.

**Breaking changes**

None. Normal visual checks keep their existing behavior. This does not
change application code or GitHub Pages settings.

**Additional context**

Searched public issues and PRs for Storybook deployment work. No
duplicate deployment proposal was found. This is maintainer
infrastructure, not a roadmap-level core feature.

## What Changed

- Add `Storybook Deploy` with a source-branch input and a manual entry
through `Storybook Visual`.
- Check the original actor and rerunner against default-branch
CODEOWNERS. Require a protected deployment environment with CODEOWNER
reviewers.
- Separate public-source builds with no repository permissions from an
OIDC publisher restricted to the Storybook S3 prefix.
- Publish distinct branch URLs and retain build URLs. Preserve Storybook
deep links across the branch redirect.
- Add the run summary, a downloadable Markdown deployment report,
focused tests, and operator setup docs and IAM policies.

## Verification

- `node --test scripts/__tests__/storybook-deploy.test.mjs`: 19 tests
pass.
- `actionlint .github/workflows/storybook-deploy.yml
.github/workflows/storybook-visual.yml`: passes.
- [Feature branch live publication and deployment-only
rerun](https://github.com/paperclipai/paperclip/actions/runs/34533202273):
passed.
- [Master branch live
publication](https://github.com/paperclipai/paperclip/actions/runs/34533204743):
passed.
- Both public branch URLs render a component story without browser
errors. A deployment-only rerun updates only the selected branch entry
and preserves the previous build URL.
- AWS policy simulation allows Storybook uploads and denies dashboard
writes and object deletion.
- Full local typechecking passes. Full local tests, build, and
current-head PR checks are running.
- [Revised build and Markdown artifact
validation](https://github.com/paperclipai/paperclip/actions/runs/34605623088):
passed. Downloaded the report and verified its branch URL, build URL,
and source commit.
- The public verifier also checks that the stable branch URL points to
this build and rejects stale targets.

## Risks

- Storybook previews are public. Maintainers must publish only public UI
fixtures.
- Retained builds accumulate until an operator prunes them.
- Environment reviewers must stay synchronized with CODEOWNERS. The
workflow fails closed if its environment loses required protection.
- The existing CloudFront distribution is shared with runner reports.
Separate S3 prefixes and a dedicated role prevent the publisher from
overwriting those reports.

## Model Used

OpenAI GPT-6 via Codex, with reasoning, shell tools, and browser
verification. The exact runtime model ID and context-window size are not
exposed in this session.

## Checklist


- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-09-11 09:13:55 -05:00

3.6 KiB

Storybook branch hosting

The Storybook Deploy workflow publishes public static Storybook builds to the existing private S3 bucket behind CloudFront. It does not deploy to GitHub Pages.

Current destination

  • AWS account: 078455283791, region us-east-1
  • Bucket: paperclipai-runner-e2e-history-078455283791-us-east-1
  • Allowed upload prefix: storybook/branches/
  • Distribution: E3GTU28BBO2SFR
  • Public origin: https://d1p6rlowie26tp.cloudfront.net
  • Role: arn:aws:iam::078455283791:role/paperclip-storybook-github

The distribution's default behavior disables edge caching and rewrites directory URLs to index.html. Stable branch indexes send no-cache; unique build objects send immutable. No invalidations or CloudFront write permissions are needed.

GitHub configuration

Create environment storybook-deploy with required reviewers set to the individual CODEOWNERS accounts. Disable administrator bypass, allow self-review, and allow repository branches. Keep these reviewers synchronized with CODEOWNERS. The workflow rejects environments with no required reviewers, non-owner reviewers or administrator bypass enabled. The AWS role trusts only this repository and this environment, so a branch cannot obtain upload access through an unprotected environment.

Set repository variables:

Variable Value
STORYBOOK_AWS_ROLE_ARN arn:aws:iam::078455283791:role/paperclip-storybook-github
STORYBOOK_AWS_REGION us-east-1
STORYBOOK_S3_BUCKET paperclipai-runner-e2e-history-078455283791-us-east-1
STORYBOOK_PUBLIC_BASE_URL https://d1p6rlowie26tp.cloudfront.net

No stored AWS access keys are needed. Leave the runner dashboard variables and GitHub Pages configuration unchanged.

Operator setup

Use the paperclip-dev operator AWS profile. Review the checked-in policies in .github/storybook-deploy/ before applying them. The existing GitHub OIDC provider must be present in this account.

aws sts get-caller-identity --profile paperclip-dev
aws iam create-role --profile paperclip-dev \
  --role-name paperclip-storybook-github \
  --assume-role-policy-document file://.github/storybook-deploy/trust-policy.json
aws iam put-role-policy --profile paperclip-dev \
  --role-name paperclip-storybook-github --policy-name StorybookBranchUpload \
  --policy-document file://.github/storybook-deploy/upload-policy.json

For an existing role, use update-assume-role-policy instead of create-role. Add the statement from cloudfront-read-statement.json to the existing bucket policy's Statement array. Preserve every other statement, including the HTTPS requirement and runner report access. Keep all S3 public-access blocks enabled; only CloudFront receives read access to this public-content prefix.

The role has no delete, bucket policy, IAM, CloudFront, or root-object permissions. The workflow never runs sync --delete. Builds accumulate; any retention cleanup must preserve the build referenced by each branch entry.

Verification

node --test scripts/__tests__/storybook-deploy.test.mjs
actionlint .github/workflows/storybook-deploy.yml .github/workflows/storybook-visual.yml

Dispatch two source branches, approve each deployment, and check their distinct branch URLs and each build's deployment.json. Redeploy one branch and confirm its stable URL now points to the new build while the other branch is unchanged. The publisher checks the public build metadata against the selected source SHA and verifies that the public branch entry points to this exact build. It retries brief propagation delays and fails if the branch URL remains stale.