Skip to content
Latchkey

Verify workflow (ueberdosis/tiptap)

The Verify workflow from ueberdosis/tiptap, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get caching, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: ueberdosis/tiptap.github/workflows/build.ymlLicense MITView source

What it does

This is the Verify workflow from the ueberdosis/tiptap 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: Verify

env:
  NODE_VERSION: 24
  PNPM_VERSION: 11.2.2
  PNPM_STORE_DIR: .pnpm-store

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

on:
  push:
    branches:
      - main
      - next
      - release/*
  pull_request:
    branches:
      - main
      - next
      - release/*

jobs:
  install-node-dependencies:
    name: Install node dependencies
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile --strict-peer-dependencies

      - name: Pack dependency artifacts
        run: |
          tar -czf /tmp/pnpm-store.tar.gz ${{ env.PNPM_STORE_DIR }}

      - name: Upload dependency artifacts
        uses: actions/upload-artifact@v7
        with:
          name: node-dependencies
          path: |
            /tmp/pnpm-store.tar.gz
          retention-days: 1

  check-linting-formatting:
    name: Check linting & formatting
    runs-on: ubuntu-latest
    needs: build-packages
    timeout-minutes: 15

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies

      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz

      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies

      - name: Run linting and formatting checks
        run: pnpm run lint

  build-packages:
    name: Build packages
    runs-on: ubuntu-latest
    needs: install-node-dependencies
    timeout-minutes: 20

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies

      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz

      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies

      - name: Build packages
        run: pnpm run build && pnpm run build:demos

      - name: Pack build artifacts
        run: tar -czf /tmp/build-output.tar.gz packages/*/dist packages-deprecated/*/dist demos/dist

      - name: Upload build artifacts
        uses: actions/upload-artifact@v7
        with:
          name: build-output
          path: /tmp/build-output.tar.gz
          retention-days: 1

  run-unit-tests:
    name: Run unit tests
    runs-on: ubuntu-latest
    needs: build-packages
    timeout-minutes: 20

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies

      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz

      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies

      - name: Download build artifacts
        uses: actions/download-artifact@v8
        with:
          name: build-output
          path: /tmp/build-output

      - name: Restore build output
        run: tar -xzf /tmp/build-output/build-output.tar.gz

      - name: Run unit tests
        run: pnpm run test:unit

  run-e2e-tests:
    name: Run e2e tests (shard ${{ matrix.shard }}/${{ matrix.total }})
    runs-on: ubuntu-latest
    needs: build-packages
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]
        total: [4]

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies

      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz

      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies

      - name: Download build artifacts
        uses: actions/download-artifact@v8
        with:
          name: build-output
          path: /tmp/build-output

      - name: Restore build output
        run: tar -xzf /tmp/build-output/build-output.tar.gz

      - name: Get Playwright version
        id: playwright-version
        run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT

      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v6
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}

      - name: Install Playwright browsers
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: pnpm exec playwright install --with-deps chromium

      - name: Install Playwright system deps
        if: steps.playwright-cache.outputs.cache-hit == 'true'
        run: pnpm exec playwright install-deps chromium

      - name: Run Playwright tests
        run: pnpm exec playwright test --project=chromium --shard=${{ matrix.shard }}/${{ matrix.total }}

      - name: Upload blob report
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: e2e-blob-report-${{ matrix.shard }}
          path: blob-report
          retention-days: 7

  merge-e2e-reports:
    name: Merge e2e reports
    runs-on: ubuntu-latest
    needs: run-e2e-tests
    if: always()
    timeout-minutes: 10

    steps:
      - uses: actions/checkout@v7

      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}

      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies

      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz

      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies

      - name: Download blob reports
        uses: actions/download-artifact@v8
        with:
          path: all-blob-reports
          pattern: e2e-blob-report-*
          merge-multiple: true

      - name: Merge into HTML report
        if: ${{ hashFiles('all-blob-reports/**') != '' }}
        run: pnpm exec playwright merge-reports --reporter html ./all-blob-reports

      - name: Upload merged HTML report
        uses: actions/upload-artifact@v7
        with:
          name: playwright-html-report
          path: playwright-report
          retention-days: 14

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: Verify
 
env:
  NODE_VERSION: 24
  PNPM_VERSION: 11.2.2
  PNPM_STORE_DIR: .pnpm-store
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
on:
  push:
    branches:
      - main
      - next
      - release/*
  pull_request:
    branches:
      - main
      - next
      - release/*
 
jobs:
  install-node-dependencies:
    name: Install node dependencies
    runs-on: latchkey-small
    timeout-minutes: 15
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --strict-peer-dependencies
 
      - name: Pack dependency artifacts
        run: |
          tar -czf /tmp/pnpm-store.tar.gz ${{ env.PNPM_STORE_DIR }}
 
      - name: Upload dependency artifacts
        uses: actions/upload-artifact@v7
        with:
          name: node-dependencies
          path: |
            /tmp/pnpm-store.tar.gz
          retention-days: 1
 
  check-linting-formatting:
    name: Check linting & formatting
    runs-on: latchkey-small
    needs: build-packages
    timeout-minutes: 15
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies
 
      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz
 
      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies
 
      - name: Run linting and formatting checks
        run: pnpm run lint
 
  build-packages:
    name: Build packages
    runs-on: latchkey-small
    needs: install-node-dependencies
    timeout-minutes: 20
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies
 
      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz
 
      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies
 
      - name: Build packages
        run: pnpm run build && pnpm run build:demos
 
      - name: Pack build artifacts
        run: tar -czf /tmp/build-output.tar.gz packages/*/dist packages-deprecated/*/dist demos/dist
 
      - name: Upload build artifacts
        uses: actions/upload-artifact@v7
        with:
          name: build-output
          path: /tmp/build-output.tar.gz
          retention-days: 1
 
  run-unit-tests:
    name: Run unit tests
    runs-on: latchkey-small
    needs: build-packages
    timeout-minutes: 20
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies
 
      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz
 
      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies
 
      - name: Download build artifacts
        uses: actions/download-artifact@v8
        with:
          name: build-output
          path: /tmp/build-output
 
      - name: Restore build output
        run: tar -xzf /tmp/build-output/build-output.tar.gz
 
      - name: Run unit tests
        run: pnpm run test:unit
 
  run-e2e-tests:
    name: Run e2e tests (shard ${{ matrix.shard }}/${{ matrix.total }})
    runs-on: latchkey-small
    needs: build-packages
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]
        total: [4]
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies
 
      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz
 
      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies
 
      - name: Download build artifacts
        uses: actions/download-artifact@v8
        with:
          name: build-output
          path: /tmp/build-output
 
      - name: Restore build output
        run: tar -xzf /tmp/build-output/build-output.tar.gz
 
      - name: Get Playwright version
        id: playwright-version
        run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
 
      - name: Cache Playwright browsers
        id: playwright-cache
        uses: actions/cache@v6
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}
 
      - name: Install Playwright browsers
        if: steps.playwright-cache.outputs.cache-hit != 'true'
        run: pnpm exec playwright install --with-deps chromium
 
      - name: Install Playwright system deps
        if: steps.playwright-cache.outputs.cache-hit == 'true'
        run: pnpm exec playwright install-deps chromium
 
      - name: Run Playwright tests
        run: pnpm exec playwright test --project=chromium --shard=${{ matrix.shard }}/${{ matrix.total }}
 
      - name: Upload blob report
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: e2e-blob-report-${{ matrix.shard }}
          path: blob-report
          retention-days: 7
 
  merge-e2e-reports:
    name: Merge e2e reports
    runs-on: latchkey-small
    needs: run-e2e-tests
    if: always()
    timeout-minutes: 10
 
    steps:
      - uses: actions/checkout@v7
 
      - name: Install pnpm
        uses: pnpm/action-setup@v5
        with:
          version: ${{ env.PNPM_VERSION }}
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: ${{ env.NODE_VERSION }}
 
      - name: Configure pnpm store
        run: pnpm config set store-dir ${{ github.workspace }}/${{ env.PNPM_STORE_DIR }}
 
      - name: Download dependency artifacts
        uses: actions/download-artifact@v8
        with:
          name: node-dependencies
          path: /tmp/node-dependencies
 
      - name: Restore pnpm store
        run: tar -xzf /tmp/node-dependencies/pnpm-store.tar.gz
 
      - name: Restore dependencies
        run: pnpm install --offline --frozen-lockfile --strict-peer-dependencies
 
      - name: Download blob reports
        uses: actions/download-artifact@v8
        with:
          path: all-blob-reports
          pattern: e2e-blob-report-*
          merge-multiple: true
 
      - name: Merge into HTML report
        if: ${{ hashFiles('all-blob-reports/**') != '' }}
        run: pnpm exec playwright merge-reports --reporter html ./all-blob-reports
 
      - name: Upload merged HTML report
        uses: actions/upload-artifact@v7
        with:
          name: playwright-html-report
          path: playwright-report
          retention-days: 14
 

What changed

1 third-party action is referenced by a movable tag. Pin it to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

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