Skip to content
Latchkey

CI workflow (sveltejs/kit)

The CI workflow from sveltejs/kit, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: sveltejs/kit.github/workflows/ci.ymlLicense MITView source

What it does

This is the CI workflow from the sveltejs/kit 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

workflow (.yml)
name: CI

on:
  push:
    branches:
      - main
    paths-ignore: &paths_ignore
      - '.changeset/**'
      - '.githooks/**'
      - '.github/ISSUE_TEMPLATE/**'
      - '.github/copilot-instructions.md'
      - '.github/FUNDING.yml'
      - '.github/PULL_REQUEST_TEMPLATE.md'
      - 'documentation/**'
      - 'packages/*/CHANGELOG*.md'
      - 'packages/kit/src/types/synthetic/**'
      - 'AGENTS.md'
      - 'CLAUDE.md'
      - 'CONTRIBUTING.md'
      - 'FUNDING.json'
      - 'LICENSE'
      - 'README.md'
  pull_request:
    paths-ignore: *paths_ignore

env:
  # we call `pnpm playwright install` instead
  PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  lint-all:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
      - run: pnpm run lint
      - run: cd packages/kit && pnpm prepublishOnly && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed - please run prepublishOnly locally and commit the changes after you have reviewed them"; git diff; exit 1); }
      - run: pnpm run check
  test-kit:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - node-version: 18
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'baseline'
          - node-version: 20
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 22
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'beta'
    env:
      KIT_E2E_BROWSER: ${{matrix.e2e-browser}}
      MATRIX_VITE: ${{matrix.vite}}
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - name: setup overrides for matrix.vite
        if: matrix.vite != 'current'
        run:
          | # copies catalogs.vite-xxx to overrides in pnpm-workspace.yaml so the subsequent `pnpm install` enforces them
          yq -i '.overrides =.catalogs."vite-${{matrix.vite}}"' pnpm-workspace.yaml
          pnpm install --no-frozen-lockfile
          git checkout pnpm-lock.yaml pnpm-workspace.yaml # revert changes to pnpm files to avoid cache key changes
          pnpm --dir packages/kit ls vite
      - run: pnpm playwright install ${{ matrix.e2e-browser }}
      - run: pnpm run sync-all
      - run: pnpm test:kit
        env:
          NODE_OPTIONS: ${{matrix.node-version == 22 && '--experimental-strip-types' || ''}} # allows loading svelte.config.ts
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}-vite-${{matrix.vite}}
          path: test-results.tar.gz
  test-kit-cross-browser:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - node-version: 24
            os: windows-latest
            e2e-browser: 'chromium'
            mode: 'dev'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'firefox'
            mode: 'dev'
          - node-version: 24
            os: macOS-latest
            e2e-browser: 'webkit'
            mode: 'dev'
          - node-version: 24
            os: windows-latest
            e2e-browser: 'chromium'
            mode: 'build'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'firefox'
            mode: 'build'
          - node-version: 24
            os: macOS-latest
            e2e-browser: 'webkit'
            mode: 'build'
    env:
      KIT_E2E_BROWSER: ${{matrix.e2e-browser}}
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install ${{ matrix.e2e-browser }}
      - run: pnpm run sync-all
      - run: pnpm test:cross-platform:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-cross-platform-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-cross-platform-${{ matrix.mode }}-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}
          path: test-results-cross-platform-${{ matrix.mode }}.tar.gz
  test-kit-server-side-route-resolution:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - mode: 'dev'
          - mode: 'build'
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
      - run: pnpm playwright install chromium --no-shell
      - run: pnpm run sync-all
      - run: pnpm test:server-side-route-resolution:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-server-side-route-resolution-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-server-side-route-resolution-${{ matrix.mode }}-${{ github.run_id }}
          path: test-results-server-side-route-resolution-${{ matrix.mode }}.tar.gz
  test-kit-svelte-async:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - mode: 'dev'
          - mode: 'build'
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install chromium --no-shell
      - run: pnpm run sync-all
      - run: pnpm test:svelte-async:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-svelte-async-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-svelte-async-${{ matrix.mode }}-${{ github.run_id }}
          path: test-results-svelte-async-${{ matrix.mode }}.tar.gz
  test-others:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22, 24]
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install chromium --no-shell
      - run: cd packages/kit && pnpm prepublishOnly
      - run: pnpm run test:others
        env:
          NODE_OPTIONS: ${{matrix.node-version == 22 && '--experimental-strip-types' || ''}} # allows loading svelte.config.ts

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: CI
 
on:
  push:
    branches:
      - main
    paths-ignore: &paths_ignore
      - '.changeset/**'
      - '.githooks/**'
      - '.github/ISSUE_TEMPLATE/**'
      - '.github/copilot-instructions.md'
      - '.github/FUNDING.yml'
      - '.github/PULL_REQUEST_TEMPLATE.md'
      - 'documentation/**'
      - 'packages/*/CHANGELOG*.md'
      - 'packages/kit/src/types/synthetic/**'
      - 'AGENTS.md'
      - 'CLAUDE.md'
      - 'CONTRIBUTING.md'
      - 'FUNDING.json'
      - 'LICENSE'
      - 'README.md'
  pull_request:
    paths-ignore: *paths_ignore
 
env:
  # we call `pnpm playwright install` instead
  PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
 
# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true
 
permissions:
  contents: read # to fetch code (actions/checkout)
 
jobs:
  lint-all:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
      - run: pnpm run lint
      - run: cd packages/kit && pnpm prepublishOnly && { [ "`git status --porcelain=v1`" == "" ] || (echo "Generated types have changed - please run prepublishOnly locally and commit the changes after you have reviewed them"; git diff; exit 1); }
      - run: pnpm run check
  test-kit:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - node-version: 18
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'baseline'
          - node-version: 20
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 22
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'current'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'chromium'
            vite: 'beta'
    env:
      KIT_E2E_BROWSER: ${{matrix.e2e-browser}}
      MATRIX_VITE: ${{matrix.vite}}
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - name: setup overrides for matrix.vite
        if: matrix.vite != 'current'
        run:
          | # copies catalogs.vite-xxx to overrides in pnpm-workspace.yaml so the subsequent `pnpm install` enforces them
          yq -i '.overrides =.catalogs."vite-${{matrix.vite}}"' pnpm-workspace.yaml
          pnpm install --no-frozen-lockfile
          git checkout pnpm-lock.yaml pnpm-workspace.yaml # revert changes to pnpm files to avoid cache key changes
          pnpm --dir packages/kit ls vite
      - run: pnpm playwright install ${{ matrix.e2e-browser }}
      - run: pnpm run sync-all
      - run: pnpm test:kit
        env:
          NODE_OPTIONS: ${{matrix.node-version == 22 && '--experimental-strip-types' || ''}} # allows loading svelte.config.ts
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}-vite-${{matrix.vite}}
          path: test-results.tar.gz
  test-kit-cross-browser:
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - node-version: 24
            os: windows-latest
            e2e-browser: 'chromium'
            mode: 'dev'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'firefox'
            mode: 'dev'
          - node-version: 24
            os: macOS-latest
            e2e-browser: 'webkit'
            mode: 'dev'
          - node-version: 24
            os: windows-latest
            e2e-browser: 'chromium'
            mode: 'build'
          - node-version: 24
            os: ubuntu-latest
            e2e-browser: 'firefox'
            mode: 'build'
          - node-version: 24
            os: macOS-latest
            e2e-browser: 'webkit'
            mode: 'build'
    env:
      KIT_E2E_BROWSER: ${{matrix.e2e-browser}}
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install ${{ matrix.e2e-browser }}
      - run: pnpm run sync-all
      - run: pnpm test:cross-platform:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-cross-platform-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-cross-platform-${{ matrix.mode }}-${{ github.run_id }}-${{ matrix.os }}-${{ matrix.node-version }}-${{ matrix.e2e-browser }}
          path: test-results-cross-platform-${{ matrix.mode }}.tar.gz
  test-kit-server-side-route-resolution:
    runs-on: latchkey-small
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - mode: 'dev'
          - mode: 'build'
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
      - run: pnpm playwright install chromium --no-shell
      - run: pnpm run sync-all
      - run: pnpm test:server-side-route-resolution:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-server-side-route-resolution-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-server-side-route-resolution-${{ matrix.mode }}-${{ github.run_id }}
          path: test-results-server-side-route-resolution-${{ matrix.mode }}.tar.gz
  test-kit-svelte-async:
    runs-on: latchkey-small
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - mode: 'dev'
          - mode: 'build'
    steps:
      - run: git config --global core.autocrlf false
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install chromium --no-shell
      - run: pnpm run sync-all
      - run: pnpm test:svelte-async:${{ matrix.mode }}
      - name: Print flaky test report
        run: node scripts/print-flaky-test-report.js
      - name: Archive test results
        if: failure()
        shell: bash
        run: find packages -type d -name test-results -not -empty | tar -czf test-results-svelte-async-${{ matrix.mode }}.tar.gz --files-from=-
      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          retention-days: 3
          name: test-failure-svelte-async-${{ matrix.mode }}-${{ github.run_id }}
          path: test-results-svelte-async-${{ matrix.mode }}.tar.gz
  test-others:
    timeout-minutes: 30
    runs-on: latchkey-small
    strategy:
      matrix:
        node-version: [18, 20, 22, 24]
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
      - uses: ./.github/actions/node-setup
        with:
          node-version: ${{ matrix.node-version }}
      - run: pnpm playwright install chromium --no-shell
      - run: cd packages/kit && pnpm prepublishOnly
      - run: pnpm run test:others
        env:
          NODE_OPTIONS: ${{matrix.node-version == 22 && '--experimental-strip-types' || ''}} # allows loading svelte.config.ts
 

What changed

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:

This workflow runs 6 jobs (9 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow