Skip to content
Latchkey

CI workflow (sveltejs/kit)

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

A

CI health: A - excellent

The optimized version below adds job timeouts.

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: latchkey-small    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: latchkey-small    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

  • Run on Latchkey managed runners with one line (runs-on), which apply the fixes below automatically and self-heal transient failures. This example uses latchkey-small; pick the runner size that fits the job.
  • 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
  • End-to-end and browser tests

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

Frequently asked questions

What does the CI workflow (sveltejs/kit) workflow do?
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.
What CI health grade does this workflow get?
This Automation and other workflow grades A. Paste your own workflow into the Latchkey grader to see its grade and the exact fixes.
How can I improve this Automation and other workflow?
Apply job timeouts. Latchkey applies these automatically on managed runners when you point runs-on at Latchkey.

References