Skip to content

Commit

Permalink
ci(GHA): Handle Chromatic builds in PRs from forks
Browse files Browse the repository at this point in the history
This changes how Chromatic is invoked in order to make it compatible with forks.

It is now triggered using the workflow_run event using a pre-built Storybook, so that it can be run in a trusted environment without exposing secrets to untrusted code.

This also fixes the reporting of Chromatic status for normal PRs.

Finally, this change also fixes running of Chromatic for Dependabot PRs as Chromatic was being run against master in this case.
  • Loading branch information
jpveooys committed Apr 13, 2022
1 parent 49b1df8 commit 6bd055c
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 51 deletions.
45 changes: 0 additions & 45 deletions .github/workflows/automerge.yml

This file was deleted.

24 changes: 18 additions & 6 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,10 @@ jobs:
yarn --cwd packages/design-tokens build
yarn --cwd packages/design-tokens test
Test_visual_regression:
# See post_built_and_test.yml for details about how this is used
Build_storybook:
runs-on: ubuntu-latest
needs: [Build_icon_library, Test_react-component-library]
# https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/
if: ${{ github.actor != 'dependabot[bot]' }}
needs: [Build_icon_library]
steps:
- name: Git clone repository
uses: actions/checkout@v3
Expand All @@ -241,7 +240,20 @@ jobs:
with:
name: dist

- name: Run visual regression tests
- name: Build Storybook
env:
CHROMATIC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
CHROMATIC_BRANCH: ${{ github.head_ref || github.ref_name }}
CHROMATIC_SLUG: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
run: |
tar -xzf dist.tar.gz && mv distil packages/icon-library/dist && mv distdt packages/design-tokens/dist
yarn --cwd packages/react-component-library chromatic --project-token=${{secrets.CHROMATIC_TOKEN}} --ci
yarn --cwd packages/react-component-library storybook:static
echo "$CHROMATIC_SHA" > packages/react-component-library/.static_storybook/sha
echo "$CHROMATIC_BRANCH" > packages/react-component-library/.static_storybook/branch
echo "$CHROMATIC_SLUG" > packages/react-component-library/.static_storybook/slug
- name: Upload Storybook artefact
uses: actions/upload-artifact@v3
with:
name: storybook-static
path: packages/react-component-library/.static_storybook
69 changes: 69 additions & 0 deletions .github/workflows/post_build_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Post Build & Test

on:
workflow_run:
types:
- completed
workflows:
- 'Build & Test'

jobs:
# This runs Chromatic visual regression tests without exposing secrets to untrusted code from
# third-party PRs.
#
# For more details, see:
# https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
Test_visual_regression:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success'
steps:
- name: Git clone repository
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Cache Node modules
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}

- name: Install dependencies
run: |
yarn install --frozen-lockfile
- name: Download pre-built Storybook
uses: actions/github-script@v6
with:
script: |
const { downloadStorybookArtifact } = await import('${{ github.workspace }}/scripts/github-actions/downloadStorybookArtifact.mjs')
await downloadStorybookArtifact({ github, context })
- name: Unzip pre-built Storybook
run: |
unzip storybook-static.zip -d packages/react-component-library/.static_storybook
echo "CHROMATIC_SHA=$(<packages/react-component-library/.static_storybook/sha)" >> $GITHUB_ENV
echo "CHROMATIC_BRANCH=$(<packages/react-component-library/.static_storybook/branch)" >> $GITHUB_ENV
echo "CHROMATIC_SLUG=$(<packages/react-component-library/.static_storybook/slug)" >> $GITHUB_ENV
- name: Fetch original ref
run: |
git fetch origin "+$CHROMATIC_SHA"
- name: Run visual regression tests
run: |
cd packages/react-component-library
npm exec --no -- chromatic --project-token=${{secrets.CHROMATIC_TOKEN}} --storybook-build-dir=.static_storybook
Automerge:
name: Merge Dependabot PR's
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
needs: [Test_visual_regression]
steps:
- name: Auto merge Dependabot minor and patch version bumps
uses: defencedigital/design-system-mergeme-action@master
with:
GITHUB_TOKEN: ${{ secrets.MERGE_BOT }}
PRESET: DEPENDABOT_MINOR
31 changes: 31 additions & 0 deletions scripts/github-actions/downloadStorybookArtifact.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import fs from 'fs'

/**
* Used by .github/workflows/post_build_and_test.yml
*
* Based on
* https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow
*/
export const downloadStorybookArtifact = async ({ github, context }) => {
const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: context.payload.workflow_run.id,
})

const matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
return artifact.name === 'storybook-static'
})[0]

const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
})

fs.writeFileSync(
`${process.env.GITHUB_WORKSPACE}/storybook-static.zip`,
Buffer.from(download.data)
)
}

0 comments on commit 6bd055c

Please sign in to comment.