From fb553b9425527ec19fe38b1dc2f175ad0a7948da Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Tue, 28 Apr 2026 18:53:02 -0400 Subject: [PATCH 01/12] ci: gate visual regression tests by path --- .github/workflows/main.yml | 47 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f3af6eb1f7..7cb998e4e3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,26 @@ on: branches: [develop, beta, main] jobs: + visual-regression-changes: + name: Visual Regression Changes + runs-on: ubuntu-latest + outputs: + should_run: ${{ steps.filter.outputs.visual == 'true' }} + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v5 + + - name: Detect visual regression changes + id: filter + uses: dorny/paths-filter@v3 + with: + filters: | + visual: + - 'packages/stacks-classic/**' + - '.github/workflows/**' + - 'package.json' + - 'package-lock.json' + build-and-test: name: ${{ matrix.command_description }} uses: ./.github/workflows/test.yml @@ -34,10 +54,6 @@ jobs: command: npm run test:a11y -w packages/stacks-classic -- --config web-test-runner.config.ci.mjs needs_lfs: false needs_playwright: true - - command_description: Visual Regression Tests - command: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs - needs_lfs: true - needs_playwright: false # we are using playwright docker image to run visual tests - command_description: Unit Tests (stacks-svelte) command: npm run test -w packages/stacks-svelte needs_lfs: false @@ -53,10 +69,29 @@ jobs: needs_lfs: ${{ matrix.needs_lfs }} secrets: inherit + visual-regression-tests: + name: Visual Regression Tests + needs: visual-regression-changes + if: needs.visual-regression-changes.outputs.should_run == 'true' + uses: ./.github/workflows/test.yml + with: + command: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs + command_description: Visual Regression Tests + needs_playwright: false # we are using playwright docker image to run visual tests + needs_lfs: true + secrets: inherit + release: name: Release (latest or beta) - if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' - needs: [build-and-test] + if: >- + ${{ + !cancelled() && + (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta') && + needs.build-and-test.result == 'success' && + needs.visual-regression-changes.result == 'success' && + (needs.visual-regression-tests.result == 'success' || needs.visual-regression-tests.result == 'skipped') + }} + needs: [build-and-test, visual-regression-changes, visual-regression-tests] runs-on: ubuntu-latest outputs: published: ${{ steps.changesets.outputs.published }} From 3e91c83bc911cfdd5213dc87a0384ed643b95df2 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Tue, 28 Apr 2026 19:01:56 -0400 Subject: [PATCH 02/12] ci: skip visual regression tests by path --- .github/workflows/main.yml | 51 ++++++++------------------------------ .github/workflows/test.yml | 27 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7cb998e4e3..fa2e358735 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,26 +7,6 @@ on: branches: [develop, beta, main] jobs: - visual-regression-changes: - name: Visual Regression Changes - runs-on: ubuntu-latest - outputs: - should_run: ${{ steps.filter.outputs.visual == 'true' }} - steps: - - name: ⬇️ Checkout - uses: actions/checkout@v5 - - - name: Detect visual regression changes - id: filter - uses: dorny/paths-filter@v3 - with: - filters: | - visual: - - 'packages/stacks-classic/**' - - '.github/workflows/**' - - 'package.json' - - 'package-lock.json' - build-and-test: name: ${{ matrix.command_description }} uses: ./.github/workflows/test.yml @@ -54,6 +34,13 @@ jobs: command: npm run test:a11y -w packages/stacks-classic -- --config web-test-runner.config.ci.mjs needs_lfs: false needs_playwright: true + - command_description: Visual Regression Tests + command: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs + needs_lfs: true + needs_playwright: false # we are using playwright docker image to run visual tests + changed_paths: | + run: + - 'packages/stacks-classic/**' - command_description: Unit Tests (stacks-svelte) command: npm run test -w packages/stacks-svelte needs_lfs: false @@ -67,31 +54,13 @@ jobs: command_description: ${{ matrix.command_description }} needs_playwright: ${{ matrix.needs_playwright }} needs_lfs: ${{ matrix.needs_lfs }} - secrets: inherit - - visual-regression-tests: - name: Visual Regression Tests - needs: visual-regression-changes - if: needs.visual-regression-changes.outputs.should_run == 'true' - uses: ./.github/workflows/test.yml - with: - command: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs - command_description: Visual Regression Tests - needs_playwright: false # we are using playwright docker image to run visual tests - needs_lfs: true + changed_paths: ${{ matrix.changed_paths || '' }} secrets: inherit release: name: Release (latest or beta) - if: >- - ${{ - !cancelled() && - (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta') && - needs.build-and-test.result == 'success' && - needs.visual-regression-changes.result == 'success' && - (needs.visual-regression-tests.result == 'success' || needs.visual-regression-tests.result == 'skipped') - }} - needs: [build-and-test, visual-regression-changes, visual-regression-tests] + if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' + needs: [build-and-test] runs-on: ubuntu-latest outputs: published: ${{ steps.changesets.outputs.published }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 726d81a4ec..7c9e2defd2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,6 +20,10 @@ on: description: 'Whether or not to checkout with LFS' type: boolean default: false + changed_paths: + description: 'Optional paths-filter config; command runs only when these paths change' + type: string + default: '' jobs: build-and-test: @@ -29,21 +33,39 @@ jobs: - name: ⬇️ Checkout uses: actions/checkout@v4 with: - lfs: ${{ inputs.needs_lfs }} + lfs: ${{ inputs.needs_lfs && inputs.changed_paths == '' }} + + - name: Detect relevant changes + id: changes + if: inputs.changed_paths != '' + uses: dorny/paths-filter@v3 + with: + filters: ${{ inputs.changed_paths }} + + - name: ⏭️ Skip ${{ inputs.command_description }} + if: steps.changes.outputs.run == 'false' + run: echo "No relevant files changed; skipping ${{ inputs.command_description }}." + + - name: ⬇️ Pull LFS assets + if: inputs.needs_lfs == true && steps.changes.outputs.run != 'false' + run: git lfs pull - name: ⎔ Setup node + if: steps.changes.outputs.run != 'false' uses: actions/setup-node@v4 with: node-version: 'lts/*' - name: 🏗 Install Dependencies + if: steps.changes.outputs.run != 'false' run: npm ci - name: 🏗 Install Playwright - if: inputs.needs_playwright == true + if: inputs.needs_playwright == true && steps.changes.outputs.run != 'false' run: npx playwright install --with-deps - name: 🔑 Setup SSH for private submodule + if: steps.changes.outputs.run != 'false' run: | mkdir -p ~/.ssh echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa @@ -52,6 +74,7 @@ jobs: SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - name: ▶️ ${{ inputs.command_description }} + if: steps.changes.outputs.run != 'false' run: ${{ inputs.command }} env: BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} From baa26bd443dda0096494524e6c17f00990645bab Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Tue, 28 Apr 2026 19:06:43 -0400 Subject: [PATCH 03/12] ci: scope visual regression path checks --- .github/workflows/main.yml | 65 ++++++++++++++++++++++++++++++++------ .github/workflows/test.yml | 27 ++-------------- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fa2e358735..f7ed5e6c9e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,13 +34,6 @@ jobs: command: npm run test:a11y -w packages/stacks-classic -- --config web-test-runner.config.ci.mjs needs_lfs: false needs_playwright: true - - command_description: Visual Regression Tests - command: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs - needs_lfs: true - needs_playwright: false # we are using playwright docker image to run visual tests - changed_paths: | - run: - - 'packages/stacks-classic/**' - command_description: Unit Tests (stacks-svelte) command: npm run test -w packages/stacks-svelte needs_lfs: false @@ -54,13 +47,67 @@ jobs: command_description: ${{ matrix.command_description }} needs_playwright: ${{ matrix.needs_playwright }} needs_lfs: ${{ matrix.needs_lfs }} - changed_paths: ${{ matrix.changed_paths || '' }} secrets: inherit + visual-regression-tests: + name: Visual Regression Tests + runs-on: ubuntu-latest + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v4 + + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v3 + with: + filters: | + run: + - 'packages/stacks-classic/**' + + - name: ⏭️ Skip Visual Regression Tests + if: steps.changes.outputs.run == 'false' + run: echo "No Stacks Classic files changed; skipping Visual Regression Tests." + + - name: ⬇️ Pull LFS assets + if: steps.changes.outputs.run == 'true' + run: git lfs pull + + - name: ⎔ Setup node + if: steps.changes.outputs.run == 'true' + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + + - name: 🏗 Install Dependencies + if: steps.changes.outputs.run == 'true' + run: npm ci + + - name: 🔑 Setup SSH for private submodule + if: steps.changes.outputs.run == 'true' + run: | + mkdir -p ~/.ssh + echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa + chmod og-rwx ~/.ssh/id_rsa + env: + SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} + + - name: ▶️ Visual Regression Tests + if: steps.changes.outputs.run == 'true' + run: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs + env: + BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} + + - name: ⬆️ Upload Visual Regression Test Results + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: visual-regression-test-results + path: packages/stacks-classic/screenshots + release: name: Release (latest or beta) if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' - needs: [build-and-test] + needs: [build-and-test, visual-regression-tests] runs-on: ubuntu-latest outputs: published: ${{ steps.changesets.outputs.published }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c9e2defd2..726d81a4ec 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,10 +20,6 @@ on: description: 'Whether or not to checkout with LFS' type: boolean default: false - changed_paths: - description: 'Optional paths-filter config; command runs only when these paths change' - type: string - default: '' jobs: build-and-test: @@ -33,39 +29,21 @@ jobs: - name: ⬇️ Checkout uses: actions/checkout@v4 with: - lfs: ${{ inputs.needs_lfs && inputs.changed_paths == '' }} - - - name: Detect relevant changes - id: changes - if: inputs.changed_paths != '' - uses: dorny/paths-filter@v3 - with: - filters: ${{ inputs.changed_paths }} - - - name: ⏭️ Skip ${{ inputs.command_description }} - if: steps.changes.outputs.run == 'false' - run: echo "No relevant files changed; skipping ${{ inputs.command_description }}." - - - name: ⬇️ Pull LFS assets - if: inputs.needs_lfs == true && steps.changes.outputs.run != 'false' - run: git lfs pull + lfs: ${{ inputs.needs_lfs }} - name: ⎔ Setup node - if: steps.changes.outputs.run != 'false' uses: actions/setup-node@v4 with: node-version: 'lts/*' - name: 🏗 Install Dependencies - if: steps.changes.outputs.run != 'false' run: npm ci - name: 🏗 Install Playwright - if: inputs.needs_playwright == true && steps.changes.outputs.run != 'false' + if: inputs.needs_playwright == true run: npx playwright install --with-deps - name: 🔑 Setup SSH for private submodule - if: steps.changes.outputs.run != 'false' run: | mkdir -p ~/.ssh echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa @@ -74,7 +52,6 @@ jobs: SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - name: ▶️ ${{ inputs.command_description }} - if: steps.changes.outputs.run != 'false' run: ${{ inputs.command }} env: BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} From bd7620330a05afec11a78d08b41076478ac7d7b5 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Tue, 28 Apr 2026 19:09:15 -0400 Subject: [PATCH 04/12] test: trigger visual regression path filter --- packages/stacks-classic/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/stacks-classic/README.md b/packages/stacks-classic/README.md index a85958417d..24979bc439 100644 --- a/packages/stacks-classic/README.md +++ b/packages/stacks-classic/README.md @@ -1,5 +1,7 @@ # Stacks + + [![ci status][gh-action-badge]][gh-action-url] [![npm version][npm-badge]][npm-url] Stacks is Stack Overflow’s design system. It includes the resources needed to create consistent, predictable interfaces and workflows that conform to Stack Overflow’s principles, design language, and best practices. @@ -26,4 +28,4 @@ To migrate from Stacks v1 to v2, see our [migration guide](/MIGRATION_GUIDE.md). [gh-action-url]: https://github.com/StackExchange/Stacks/actions/workflows/main.yml [gh-action-badge]: https://github.com/StackExchange/Stacks/actions/workflows/workflow.yml/badge.svg?branch=develop [npm-url]: https://npmjs.org/package/@stackoverflow/stacks -[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg \ No newline at end of file +[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg From ccec4b41febab4a8a9d6bc2b678a58e5b728d2d1 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 11:05:13 -0400 Subject: [PATCH 05/12] chore: trigger ci From a06b80f2cc22d18cd51f46b165cb7f806eeaa3d3 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 12:53:30 -0400 Subject: [PATCH 06/12] ci: preserve visual regression check name --- .github/workflows/main.yml | 54 +---------------- .github/workflows/test-visual-regression.yml | 61 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/test-visual-regression.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f7ed5e6c9e..d87f6f80cd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,58 +51,8 @@ jobs: visual-regression-tests: name: Visual Regression Tests - runs-on: ubuntu-latest - steps: - - name: ⬇️ Checkout - uses: actions/checkout@v4 - - - name: Detect relevant changes - id: changes - uses: dorny/paths-filter@v3 - with: - filters: | - run: - - 'packages/stacks-classic/**' - - - name: ⏭️ Skip Visual Regression Tests - if: steps.changes.outputs.run == 'false' - run: echo "No Stacks Classic files changed; skipping Visual Regression Tests." - - - name: ⬇️ Pull LFS assets - if: steps.changes.outputs.run == 'true' - run: git lfs pull - - - name: ⎔ Setup node - if: steps.changes.outputs.run == 'true' - uses: actions/setup-node@v4 - with: - node-version: 'lts/*' - - - name: 🏗 Install Dependencies - if: steps.changes.outputs.run == 'true' - run: npm ci - - - name: 🔑 Setup SSH for private submodule - if: steps.changes.outputs.run == 'true' - run: | - mkdir -p ~/.ssh - echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa - chmod og-rwx ~/.ssh/id_rsa - env: - SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - - - name: ▶️ Visual Regression Tests - if: steps.changes.outputs.run == 'true' - run: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs - env: - BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} - - - name: ⬆️ Upload Visual Regression Test Results - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: visual-regression-test-results - path: packages/stacks-classic/screenshots + uses: ./.github/workflows/test-visual-regression.yml + secrets: inherit release: name: Release (latest or beta) diff --git a/.github/workflows/test-visual-regression.yml b/.github/workflows/test-visual-regression.yml new file mode 100644 index 0000000000..2750a7b9ac --- /dev/null +++ b/.github/workflows/test-visual-regression.yml @@ -0,0 +1,61 @@ +name: Visual Regression Tests +run-name: Visual Regression Tests + +on: + workflow_call: + +jobs: + visual-regression-tests: + name: Visual Regression Tests + runs-on: ubuntu-latest + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v4 + + - name: Detect relevant changes + id: changes + uses: dorny/paths-filter@v3 + with: + filters: | + run: + - 'packages/stacks-classic/**' + + - name: ⏭️ Skip Visual Regression Tests + if: steps.changes.outputs.run == 'false' + run: echo "No Stacks Classic files changed; skipping Visual Regression Tests." + + - name: ⬇️ Pull LFS assets + if: steps.changes.outputs.run == 'true' + run: git lfs pull + + - name: ⎔ Setup node + if: steps.changes.outputs.run == 'true' + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + + - name: 🏗 Install Dependencies + if: steps.changes.outputs.run == 'true' + run: npm ci + + - name: 🔑 Setup SSH for private submodule + if: steps.changes.outputs.run == 'true' + run: | + mkdir -p ~/.ssh + echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa + chmod og-rwx ~/.ssh/id_rsa + env: + SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} + + - name: ▶️ Visual Regression Tests + if: steps.changes.outputs.run == 'true' + run: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs + env: + BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} + + - name: ⬆️ Upload Visual Regression Test Results + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: visual-regression-test-results + path: packages/stacks-classic/screenshots From 29f99d27aaed48c453b326b646c80cc2767ab53b Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 13:38:11 -0400 Subject: [PATCH 07/12] test: remove visual regression trigger --- packages/stacks-classic/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/stacks-classic/README.md b/packages/stacks-classic/README.md index 24979bc439..a85958417d 100644 --- a/packages/stacks-classic/README.md +++ b/packages/stacks-classic/README.md @@ -1,7 +1,5 @@ # Stacks - - [![ci status][gh-action-badge]][gh-action-url] [![npm version][npm-badge]][npm-url] Stacks is Stack Overflow’s design system. It includes the resources needed to create consistent, predictable interfaces and workflows that conform to Stack Overflow’s principles, design language, and best practices. @@ -28,4 +26,4 @@ To migrate from Stacks v1 to v2, see our [migration guide](/MIGRATION_GUIDE.md). [gh-action-url]: https://github.com/StackExchange/Stacks/actions/workflows/main.yml [gh-action-badge]: https://github.com/StackExchange/Stacks/actions/workflows/workflow.yml/badge.svg?branch=develop [npm-url]: https://npmjs.org/package/@stackoverflow/stacks -[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg +[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg \ No newline at end of file From 5ac6276df9adc54383c59e2367ba5e6333233f6d Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 14:44:21 -0400 Subject: [PATCH 08/12] ci: mark visual regression job skipped --- .github/workflows/main.yml | 29 +++++++++++---- .github/workflows/test-visual-regression.yml | 26 ++++---------- .github/workflows/test.yml | 38 +++++++++++++++++++- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d87f6f80cd..4f8e44b953 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,17 @@ on: branches: [develop, beta, main] jobs: + build: + name: Build + uses: ./.github/workflows/test.yml + with: + command: npm run build + command_description: Build + needs_playwright: false + needs_lfs: false + detect_visual_regression_changes: true + secrets: inherit + build-and-test: name: ${{ matrix.command_description }} uses: ./.github/workflows/test.yml @@ -14,10 +25,6 @@ jobs: fail-fast: false matrix: include: - - command_description: Build - command: npm run build - needs_lfs: false - needs_playwright: false - command_description: Lint command: npm run lint needs_lfs: false @@ -51,13 +58,23 @@ jobs: visual-regression-tests: name: Visual Regression Tests + needs: build uses: ./.github/workflows/test-visual-regression.yml + with: + should_run: ${{ needs.build.outputs.visual_regression_changed == 'true' }} secrets: inherit release: name: Release (latest or beta) - if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta' - needs: [build-and-test, visual-regression-tests] + if: >- + ${{ + !cancelled() && + (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta') && + needs.build.result == 'success' && + needs.build-and-test.result == 'success' && + (needs.visual-regression-tests.result == 'success' || needs.visual-regression-tests.result == 'skipped') + }} + needs: [build, build-and-test, visual-regression-tests] runs-on: ubuntu-latest outputs: published: ${{ steps.changesets.outputs.published }} diff --git a/.github/workflows/test-visual-regression.yml b/.github/workflows/test-visual-regression.yml index 2750a7b9ac..43b195fc5c 100644 --- a/.github/workflows/test-visual-regression.yml +++ b/.github/workflows/test-visual-regression.yml @@ -3,43 +3,32 @@ run-name: Visual Regression Tests on: workflow_call: + inputs: + should_run: + description: 'Whether to run visual regression tests' + type: boolean + required: true jobs: visual-regression-tests: name: Visual Regression Tests + if: inputs.should_run == true runs-on: ubuntu-latest steps: - name: ⬇️ Checkout uses: actions/checkout@v4 - - - name: Detect relevant changes - id: changes - uses: dorny/paths-filter@v3 with: - filters: | - run: - - 'packages/stacks-classic/**' - - - name: ⏭️ Skip Visual Regression Tests - if: steps.changes.outputs.run == 'false' - run: echo "No Stacks Classic files changed; skipping Visual Regression Tests." - - - name: ⬇️ Pull LFS assets - if: steps.changes.outputs.run == 'true' - run: git lfs pull + lfs: true - name: ⎔ Setup node - if: steps.changes.outputs.run == 'true' uses: actions/setup-node@v4 with: node-version: 'lts/*' - name: 🏗 Install Dependencies - if: steps.changes.outputs.run == 'true' run: npm ci - name: 🔑 Setup SSH for private submodule - if: steps.changes.outputs.run == 'true' run: | mkdir -p ~/.ssh echo -e "${SUBMODULE_SSH_KEY//_/\\n}" > ~/.ssh/id_rsa @@ -48,7 +37,6 @@ jobs: SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - name: ▶️ Visual Regression Tests - if: steps.changes.outputs.run == 'true' run: npm run test:visual:ci -w packages/stacks-classic -- --config ./visual-runner/stacks-classic-runner-config/web-test-runner.config.ci.mjs env: BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 726d81a4ec..8f9801a46d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,11 +20,21 @@ on: description: 'Whether or not to checkout with LFS' type: boolean default: false + detect_visual_regression_changes: + description: 'Whether to output if packages/stacks-classic changed' + type: boolean + default: false + outputs: + visual_regression_changed: + description: 'Whether packages/stacks-classic changed' + value: ${{ jobs.build-and-test.outputs.visual_regression_changed }} jobs: build-and-test: name: ${{ inputs.command_description }} runs-on: ubuntu-latest + outputs: + visual_regression_changed: ${{ steps.command.outputs.visual_regression_changed }} steps: - name: ⬇️ Checkout uses: actions/checkout@v4 @@ -52,7 +62,33 @@ jobs: SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - name: ▶️ ${{ inputs.command_description }} - run: ${{ inputs.command }} + id: command + run: | + ${{ inputs.command }} + + if [ "${{ inputs.detect_visual_regression_changes }}" = "true" ]; then + if [ "${{ github.event_name }}" = "pull_request" ]; then + git fetch --no-tags --prune --depth=1 origin "${{ github.base_ref }}" + changed_files="$(git diff --name-only "origin/${{ github.base_ref }}" HEAD)" + elif [ -n "${{ github.event.before }}" ] && [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then + git fetch --no-tags --prune --depth=1 origin "${{ github.event.before }}" || true + changed_files="$(git diff --name-only "${{ github.event.before }}" HEAD)" + else + changed_files="$(git diff --name-only HEAD^ HEAD || true)" + fi + + visual_regression_changed=false + while IFS= read -r changed_file; do + case "$changed_file" in + packages/stacks-classic/*) + visual_regression_changed=true + break + ;; + esac + done <<< "$changed_files" + + echo "visual_regression_changed=$visual_regression_changed" >> "$GITHUB_OUTPUT" + fi env: BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} From bd843896e072f09c44fcc2240366263796aa164e Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 14:49:23 -0400 Subject: [PATCH 09/12] test: trigger visual regression run --- packages/stacks-classic/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/stacks-classic/README.md b/packages/stacks-classic/README.md index a85958417d..44fcb8e4e0 100644 --- a/packages/stacks-classic/README.md +++ b/packages/stacks-classic/README.md @@ -1,5 +1,7 @@ # Stacks + + [![ci status][gh-action-badge]][gh-action-url] [![npm version][npm-badge]][npm-url] Stacks is Stack Overflow’s design system. It includes the resources needed to create consistent, predictable interfaces and workflows that conform to Stack Overflow’s principles, design language, and best practices. @@ -26,4 +28,4 @@ To migrate from Stacks v1 to v2, see our [migration guide](/MIGRATION_GUIDE.md). [gh-action-url]: https://github.com/StackExchange/Stacks/actions/workflows/main.yml [gh-action-badge]: https://github.com/StackExchange/Stacks/actions/workflows/workflow.yml/badge.svg?branch=develop [npm-url]: https://npmjs.org/package/@stackoverflow/stacks -[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg \ No newline at end of file +[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg From 5aeb4d444d80cb7ec620b25e3c8c3ac65e96a629 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 14:53:14 -0400 Subject: [PATCH 10/12] ci: update node actions --- .github/workflows/main.yml | 2 +- .github/workflows/test-visual-regression.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4f8e44b953..a5d8c794fd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -81,7 +81,7 @@ jobs: steps: - uses: actions/checkout@v5 - name: Setup Node.js environment - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: lts/* cache: "npm" diff --git a/.github/workflows/test-visual-regression.yml b/.github/workflows/test-visual-regression.yml index 43b195fc5c..dfcae2292f 100644 --- a/.github/workflows/test-visual-regression.yml +++ b/.github/workflows/test-visual-regression.yml @@ -16,12 +16,12 @@ jobs: runs-on: ubuntu-latest steps: - name: ⬇️ Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: lfs: true - name: ⎔ Setup node - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 'lts/*' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8f9801a46d..7d930f9295 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,12 +37,12 @@ jobs: visual_regression_changed: ${{ steps.command.outputs.visual_regression_changed }} steps: - name: ⬇️ Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: lfs: ${{ inputs.needs_lfs }} - name: ⎔ Setup node - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 'lts/*' From b69ece2fbe1eda4adb3e785cc92d2197eec58fab Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 14:56:09 -0400 Subject: [PATCH 11/12] ci: detect visual regression changes early --- .github/workflows/main.yml | 21 +++-------- .github/workflows/test-visual-regression.yml | 25 +++++++++---- .github/workflows/test.yml | 38 +------------------- 3 files changed, 25 insertions(+), 59 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a5d8c794fd..d23e36ace1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,17 +7,6 @@ on: branches: [develop, beta, main] jobs: - build: - name: Build - uses: ./.github/workflows/test.yml - with: - command: npm run build - command_description: Build - needs_playwright: false - needs_lfs: false - detect_visual_regression_changes: true - secrets: inherit - build-and-test: name: ${{ matrix.command_description }} uses: ./.github/workflows/test.yml @@ -25,6 +14,10 @@ jobs: fail-fast: false matrix: include: + - command_description: Build + command: npm run build + needs_lfs: false + needs_playwright: false - command_description: Lint command: npm run lint needs_lfs: false @@ -58,10 +51,7 @@ jobs: visual-regression-tests: name: Visual Regression Tests - needs: build uses: ./.github/workflows/test-visual-regression.yml - with: - should_run: ${{ needs.build.outputs.visual_regression_changed == 'true' }} secrets: inherit release: @@ -70,11 +60,10 @@ jobs: ${{ !cancelled() && (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/beta') && - needs.build.result == 'success' && needs.build-and-test.result == 'success' && (needs.visual-regression-tests.result == 'success' || needs.visual-regression-tests.result == 'skipped') }} - needs: [build, build-and-test, visual-regression-tests] + needs: [build-and-test, visual-regression-tests] runs-on: ubuntu-latest outputs: published: ${{ steps.changesets.outputs.published }} diff --git a/.github/workflows/test-visual-regression.yml b/.github/workflows/test-visual-regression.yml index dfcae2292f..39485b0852 100644 --- a/.github/workflows/test-visual-regression.yml +++ b/.github/workflows/test-visual-regression.yml @@ -3,16 +3,29 @@ run-name: Visual Regression Tests on: workflow_call: - inputs: - should_run: - description: 'Whether to run visual regression tests' - type: boolean - required: true jobs: + changes: + name: Detect Changes + runs-on: ubuntu-latest + outputs: + should_run: ${{ steps.filter.outputs.run }} + steps: + - name: ⬇️ Checkout + uses: actions/checkout@v5 + + - name: Detect Stacks Classic changes + id: filter + uses: dorny/paths-filter@v4 + with: + filters: | + run: + - 'packages/stacks-classic/**' + visual-regression-tests: name: Visual Regression Tests - if: inputs.should_run == true + needs: changes + if: needs.changes.outputs.should_run == 'true' runs-on: ubuntu-latest steps: - name: ⬇️ Checkout diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7d930f9295..df1c4a8a6d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,21 +20,11 @@ on: description: 'Whether or not to checkout with LFS' type: boolean default: false - detect_visual_regression_changes: - description: 'Whether to output if packages/stacks-classic changed' - type: boolean - default: false - outputs: - visual_regression_changed: - description: 'Whether packages/stacks-classic changed' - value: ${{ jobs.build-and-test.outputs.visual_regression_changed }} jobs: build-and-test: name: ${{ inputs.command_description }} runs-on: ubuntu-latest - outputs: - visual_regression_changed: ${{ steps.command.outputs.visual_regression_changed }} steps: - name: ⬇️ Checkout uses: actions/checkout@v5 @@ -62,33 +52,7 @@ jobs: SUBMODULE_SSH_KEY: ${{ secrets.SUBMODULE_SSH_KEY }} - name: ▶️ ${{ inputs.command_description }} - id: command - run: | - ${{ inputs.command }} - - if [ "${{ inputs.detect_visual_regression_changes }}" = "true" ]; then - if [ "${{ github.event_name }}" = "pull_request" ]; then - git fetch --no-tags --prune --depth=1 origin "${{ github.base_ref }}" - changed_files="$(git diff --name-only "origin/${{ github.base_ref }}" HEAD)" - elif [ -n "${{ github.event.before }}" ] && [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then - git fetch --no-tags --prune --depth=1 origin "${{ github.event.before }}" || true - changed_files="$(git diff --name-only "${{ github.event.before }}" HEAD)" - else - changed_files="$(git diff --name-only HEAD^ HEAD || true)" - fi - - visual_regression_changed=false - while IFS= read -r changed_file; do - case "$changed_file" in - packages/stacks-classic/*) - visual_regression_changed=true - break - ;; - esac - done <<< "$changed_files" - - echo "visual_regression_changed=$visual_regression_changed" >> "$GITHUB_OUTPUT" - fi + run: ${{ inputs.command }} env: BETTER_AUTH_SECRET: ${{ secrets.AUTH_SECRET || 'ci-build-placeholder-secret' }} From ec365b478a9ac21907dc1f6909a3109663300f42 Mon Sep 17 00:00:00 2001 From: Dan Cormier Date: Wed, 29 Apr 2026 15:03:09 -0400 Subject: [PATCH 12/12] test: remove visual regression run trigger --- packages/stacks-classic/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/stacks-classic/README.md b/packages/stacks-classic/README.md index 44fcb8e4e0..a85958417d 100644 --- a/packages/stacks-classic/README.md +++ b/packages/stacks-classic/README.md @@ -1,7 +1,5 @@ # Stacks - - [![ci status][gh-action-badge]][gh-action-url] [![npm version][npm-badge]][npm-url] Stacks is Stack Overflow’s design system. It includes the resources needed to create consistent, predictable interfaces and workflows that conform to Stack Overflow’s principles, design language, and best practices. @@ -28,4 +26,4 @@ To migrate from Stacks v1 to v2, see our [migration guide](/MIGRATION_GUIDE.md). [gh-action-url]: https://github.com/StackExchange/Stacks/actions/workflows/main.yml [gh-action-badge]: https://github.com/StackExchange/Stacks/actions/workflows/workflow.yml/badge.svg?branch=develop [npm-url]: https://npmjs.org/package/@stackoverflow/stacks -[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg +[npm-badge]: https://img.shields.io/npm/v/@stackoverflow/stacks.svg \ No newline at end of file