From ff6b470eb4b0e30cca23fc5bebb366c26375790b Mon Sep 17 00:00:00 2001 From: John Kurkowski Date: Sat, 13 Jun 2026 18:09:55 -0700 Subject: [PATCH 1/5] Split CI checks from Netlify previews Run tests and visual regression in GitHub Actions, publish production from GitHub Actions after they pass, and leave Netlify deploy previews build-only. --- .github/workflows/vrt.yml | 54 +++++++++++++++++++++++++++++++++++++-- README.md | 11 ++++---- netlify.toml | 3 ++- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/.github/workflows/vrt.yml b/.github/workflows/vrt.yml index 288c690..7d110a4 100644 --- a/.github/workflows/vrt.yml +++ b/.github/workflows/vrt.yml @@ -1,7 +1,28 @@ -on: [push] +name: CI + +on: [push, pull_request] jobs: - build: + test: + runs-on: ubuntu-latest + name: Test + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version-file: '.nvmrc' + + - name: Install dependencies + run: npm install + + - name: Test + run: npm test + + visual-regression: runs-on: ubuntu-latest name: Lost Pixel @@ -27,3 +48,32 @@ jobs: uses: lost-pixel/lost-pixel@v3.22.0 env: LOST_PIXEL_API_KEY: ${{ secrets.LOST_PIXEL_API_KEY }} + + deploy-production: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + name: Deploy production + needs: [test, visual-regression] + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version-file: '.nvmrc' + + - name: Install dependencies + run: npm install + + - name: Build app + run: npm run build + + - name: Deploy to Netlify + run: > + npx --yes netlify-cli deploy --prod --dir=dist --site + "$NETLIFY_SITE_ID" --auth "$NETLIFY_AUTH_TOKEN" + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} diff --git a/README.md b/README.md index 79e94e0..f278416 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,14 @@ Source for [johnkurkowski.com](https://johnkurkowski.com). npm test -Tests are run in CI and must pass prior to deployment. +Tests are run in GitHub Actions and must pass before production deploys. [Lost Pixel](https://app.lost-pixel.com/) visual regression review is run during -CI, but does not block deployment. If there are visual differences in your -build, they require manual, asynchronous review. Before push, you can preview -Lost Pixel's snapshots against your running local server in production mode. +CI and must pass before production deploys. Netlify deploy previews run build +only; production deploys are published by GitHub Actions after tests and visual +regression pass. Before push, you can preview Lost Pixel's snapshots against +your running local server in production mode. npm run build - npm run serve & + npm run preview & npx lost-pixel local diff --git a/netlify.toml b/netlify.toml index 6a6f728..ee3d645 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,3 +1,4 @@ [build] - command = "npm test && npm run build" + command = "npm run build" + ignore = "[ \"$CONTEXT\" = \"production\" ]" publish = "dist/" From b2b0eb303180afc3cc762879d1540808ca1e445f Mon Sep 17 00:00:00 2001 From: John Kurkowski Date: Sat, 13 Jun 2026 23:44:50 -0700 Subject: [PATCH 2/5] Fix docs --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f278416..4aba4ec 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,11 @@ Source for [johnkurkowski.com](https://johnkurkowski.com). npm test -Tests are run in GitHub Actions and must pass before production deploys. +Tests are run in CI and must pass before production deploy, i.e. pushes to +trunk. Branches deploy regardless of CI passing. -[Lost Pixel](https://app.lost-pixel.com/) visual regression review is run during -CI and must pass before production deploys. Netlify deploy previews run build -only; production deploys are published by GitHub Actions after tests and visual -regression pass. Before push, you can preview Lost Pixel's snapshots against -your running local server in production mode. +Before push, you can preview [Lost Pixel](https://app.lost-pixel.com/) VRT's +snapshots against your running local server in production mode. npm run build npm run preview & From fcbddae96454559e9b641221521415df08be5971 Mon Sep 17 00:00:00 2001 From: John Kurkowski Date: Sat, 13 Jun 2026 23:51:28 -0700 Subject: [PATCH 3/5] Limit workflow token permissions Restrict the default GitHub Actions token to read-only repository contents for CI and Netlify deploy jobs. --- .github/workflows/vrt.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/vrt.yml b/.github/workflows/vrt.yml index 7d110a4..6c0e1d2 100644 --- a/.github/workflows/vrt.yml +++ b/.github/workflows/vrt.yml @@ -2,6 +2,9 @@ name: CI on: [push, pull_request] +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest From 17d2d993e3584797b40ba01a6e5a1a1e3afd345c Mon Sep 17 00:00:00 2001 From: John Kurkowski Date: Sat, 13 Jun 2026 23:59:08 -0700 Subject: [PATCH 4/5] Allow Lost Pixel to report status Keep the workflow token read-only for repository contents, but restore status write access for the visual regression action. --- .github/workflows/vrt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/vrt.yml b/.github/workflows/vrt.yml index 6c0e1d2..3c3a4e5 100644 --- a/.github/workflows/vrt.yml +++ b/.github/workflows/vrt.yml @@ -4,6 +4,7 @@ on: [push, pull_request] permissions: contents: read + statuses: write jobs: test: From 62e4bd7c0828b85e2143b8c35b1ea8897cc5899f Mon Sep 17 00:00:00 2001 From: John Kurkowski Date: Sun, 14 Jun 2026 00:08:02 -0700 Subject: [PATCH 5/5] Skip duplicate Lost Pixel branch runs Run visual regression only for pull requests and master pushes so Lost Pixel does not receive separate push and pull_request uploads for the same commit. --- .github/workflows/vrt.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/vrt.yml b/.github/workflows/vrt.yml index 3c3a4e5..bea1db3 100644 --- a/.github/workflows/vrt.yml +++ b/.github/workflows/vrt.yml @@ -27,6 +27,7 @@ jobs: run: npm test visual-regression: + if: github.event_name == 'pull_request' || github.ref == 'refs/heads/master' runs-on: ubuntu-latest name: Lost Pixel