Integration Tests workflow (tailwindlabs/tailwindcss)
The Integration Tests workflow from tailwindlabs/tailwindcss, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get caching, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Integration Tests workflow from the tailwindlabs/tailwindcss repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Integration Tests
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
env:
NODE_VERSION: 24
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
tests:
strategy:
fail-fast: false
matrix:
runner:
- name: Windows
os: windows-latest
- name: Linux
os: namespace-profile-default
- name: macOS
os: macos-14
integration:
- upgrade
- vite
- cli
- postcss
- oxide
- webpack
# Exclude windows and macos from being built on feature branches
run-all:
- ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.body, '[ci-all]') }}
exclude:
- run-all: false
runner:
name: Windows
- run-all: false
runner:
name: macOS
runs-on: ${{ matrix.runner.os }}
timeout-minutes: 30
name: ${{ matrix.runner.name }} / ${{ matrix.integration }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: ${{ env.NODE_VERSION }}
# Cargo already skips downloading dependencies if they already exist
- name: Cache cargo
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
# Cache the `oxide` Rust build
- name: Cache oxide build
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: |
./crates/node/*.node
./crates/node/*.wasm
./crates/node/index.d.ts
./crates/node/index.js
./crates/node/browser.js
./crates/node/tailwindcss-oxide.wasi-browser.js
./crates/node/tailwindcss-oxide.wasi.cjs
./crates/node/wasi-worker-browser.mjs
./crates/node/wasi-worker.mjs
key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}
- name: Setup WASM target
run: rustup target add wasm32-wasip1-threads
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
env:
CARGO_PROFILE_RELEASE_LTO: 'off'
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: 'lld-link'
- name: Test ${{ matrix.integration }}
run: pnpm run test:integrations ./integrations/${{ matrix.integration }}
env:
GITHUB_WORKSPACE: ${{ github.workspace }}
notify:
if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }}
needs: tests
runs-on: ubuntu-latest
steps:
- name: Notify Discord
uses: discord-actions/message@5c7149c81a83146e5d01f142be1bf87a61831c4d # v2
with:
webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }}
message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.'
The same workflow, on Latchkey
Estimated ~20% faster on cache hits, plus fewer wasted runs and a safer supply chain. Added and changed lines are highlighted.
name: Integration Tests on: push: branches: [main] pull_request: permissions: contents: read env: NODE_VERSION: 24 concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: tests: strategy: fail-fast: false matrix: runner: - name: Windows os: windows-latest - name: Linux os: namespace-profile-default - name: macOS os: macos-14 integration: - upgrade - vite - cli - postcss - oxide - webpack # Exclude windows and macos from being built on feature branches run-all: - ${{ github.ref == 'refs/heads/main' || contains(github.event.pull_request.body, '[ci-all]') }} exclude: - run-all: false runner: name: Windows - run-all: false runner: name: macOS runs-on: ${{ matrix.runner.os }} timeout-minutes: 30 name: ${{ matrix.runner.name }} / ${{ matrix.integration }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 - run: | git config --global user.name "github-actions[bot]" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Use Node.js ${{ env.NODE_VERSION }} uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: cache: 'npm' node-version: ${{ env.NODE_VERSION }} # Cargo already skips downloading dependencies if they already exist - name: Cache cargo uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/.cargo/registry/index/ ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} # Cache the `oxide` Rust build - name: Cache oxide build uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ./crates/node/*.node ./crates/node/*.wasm ./crates/node/index.d.ts ./crates/node/index.js ./crates/node/browser.js ./crates/node/tailwindcss-oxide.wasi-browser.js ./crates/node/tailwindcss-oxide.wasi.cjs ./crates/node/wasi-worker-browser.mjs ./crates/node/wasi-worker.mjs key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }} - name: Setup WASM target run: rustup target add wasm32-wasip1-threads - name: Install dependencies run: pnpm install - name: Build run: pnpm run build env: CARGO_PROFILE_RELEASE_LTO: 'off' CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: 'lld-link' - name: Test ${{ matrix.integration }} run: pnpm run test:integrations ./integrations/${{ matrix.integration }} env: GITHUB_WORKSPACE: ${{ github.workspace }} notify: timeout-minutes: 30 if: ${{ always() && github.ref == 'refs/heads/main' && needs.tests.result == 'failure' }} needs: tests runs-on: latchkey-small steps: - name: Notify Discord uses: discord-actions/message@5c7149c81a83146e5d01f142be1bf87a61831c4d # v2 with: webhookUrl: ${{ secrets.DISCORD_WEBHOOK_URL }} message: 'The [most recent ${{ github.workflow }} workflow](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>) on the `main` branch has failed.'
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cache dependency installs on the setup step so they are served from cache.
- Add a job timeout so a hung step cannot burn hours of runner time.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 2 jobs (19 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.