# CI workflow (vitejs/vite)

> The CI workflow from vitejs/vite, explained and optimized by Latchkey.

Source: https://latchkey.dev/workflows/vitejs-vite-ci  
Upstream: [vitejs/vite](https://github.com/vitejs/vite/blob/main/.github/workflows/ci.yml) (.github/workflows/ci.yml), licence MIT

## What it does

This is the CI workflow from the vitejs/vite 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

```yaml
name: CI

env:
  # 7 GiB by default on GitHub, setting to 6 GiB
  # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
  NODE_OPTIONS: --max-old-space-size=6144
  # install playwright binary manually (because pnpm only runs install script once)
  PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
  # Vitest auto retry on flaky segfault
  VITEST_SEGFAULT_RETRY: 3

# Remove default permissions of GITHUB_TOKEN for security
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions: {}

on:
  push:
    branches:
      - main
      - release/*
      - feat/*
      - fix/*
      - perf/*
      - "v[0-9]+" # v1, v2, ...
      - "v[0-9]+.[0-9]+" # v4.0, v4.1, ...
  pull_request:
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

jobs:
  changed:
    name: Get changed files
    runs-on: ubuntu-slim
    outputs:
      should_skip: ${{ steps.changed-files.outputs.only_changed == 'true' }}

    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
        with:
          # Assume PRs are less than 50 commits
          fetch-depth: 50
          persist-credentials: false

      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
        with:
          files: |
            docs/**
            .github/**
            !.github/workflows/ci.yml
            packages/create-vite/template**
            **.md

  test:
    needs: changed
    if: needs.changed.outputs.should_skip != 'true'
    timeout-minutes: 20
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        node_version: [20, 22, 24, 26]
        include:
          # Active LTS + other OS
          - os: macos-latest
            node_version: 24
          - os: windows-latest
            # use older minor to workaround https://github.com/nodejs/node/issues/63638
            node_version: 24.15.0
      fail-fast: false

    name: "Build&Test: node-${{ matrix.node_version }}, ${{ matrix.os }}"
    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
        with:
          persist-credentials: false

      - name: Install pnpm
        uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9

      - name: Set node version to ${{ matrix.node_version }}
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
        with:
          node-version: ${{ matrix.node_version }}
          cache: "pnpm"

      - name: Install deps
        run: pnpm install

      # Install playwright's binary under custom directory to cache
      - name: (non-windows) Set Playwright path and Get playwright version
        if: runner.os != 'Windows'
        run: |
          echo "PLAYWRIGHT_BROWSERS_PATH=$HOME/.cache/playwright-bin" >> $GITHUB_ENV
          PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright-chromium | jq --raw-output '.[0].devDependencies["playwright-chromium"].version')"
          echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
      - name: (windows) Set Playwright path and Get playwright version
        if: runner.os == 'Windows'
        run: |
          echo "PLAYWRIGHT_BROWSERS_PATH=$HOME\.cache\playwright-bin" >> $env:GITHUB_ENV
          $env:PLAYWRIGHT_VERSION="$(pnpm ls --depth 0 --json -w playwright-chromium | jq --raw-output '.[0].devDependencies["playwright-chromium"].version')"
          echo "PLAYWRIGHT_VERSION=$env:PLAYWRIGHT_VERSION" >> $env:GITHUB_ENV

      - name: Cache Playwright's binary
        uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
        with:
          key: ${{ runner.os }}-playwright-bin-v1-${{ env.PLAYWRIGHT_VERSION }}
          path: ${{ env.PLAYWRIGHT_BROWSERS_PATH }}
          restore-keys: |
            ${{ runner.os }}-playwright-bin-v1-

      - name: Install Playwright
        # does not need to explicitly set chromium after https://github.com/microsoft/playwright/issues/14862 is solved
        run: pnpm playwright install chromium

      - name: Build
        run: pnpm run build

      - name: Test unit
        run: pnpm run test-unit

      - name: Test serve
        run: pnpm run test-serve

      - name: Test build
        run: pnpm run test-build

  test-passed:
    if: (!cancelled() && !failure())
    needs: test
    runs-on: ubuntu-slim
    name: Build & Test Passed or Skipped
    steps:
      - run: echo "Build & Test Passed or Skipped"

  test-failed:
    if: (!cancelled() && failure())
    needs: test
    runs-on: ubuntu-slim
    name: Build & Test Failed
    steps:
      - run: echo "Build & Test Failed"

  lint:
    timeout-minutes: 10
    runs-on: ubuntu-latest
    name: "Lint: node-24, ubuntu-latest"
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
        with:
          persist-credentials: false

      - name: Install pnpm
        uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9

      - name: Set node version to 24
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
        with:
          node-version: 24
          cache: "pnpm"

      - name: Install deps
        run: pnpm install

      - name: Build
        run: pnpm run build

      - name: Lint
        run: pnpm run lint

      - name: Check formatting
        run: pnpm format && git diff --exit-code

      - name: Typecheck
        run: pnpm run typecheck

      - name: Test docs
        run: pnpm run test-docs

      # From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions
      - name: Check workflow files
        run: |
          bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
          ./actionlint -color -shellcheck=""
```

## FAQ

### What does the CI workflow (vitejs/vite) workflow do?

This is the CI workflow from the vitejs/vite 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 Node.js workflow grades A. Paste your own workflow into the Latchkey grader to see its grade and the exact fixes.

### How can I improve this Node.js workflow?

Add job timeouts. Latchkey applies these automatically on managed runners when you point runs-on at Latchkey.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
