Skip to content
Latchkey

CI workflow (thedotmack/claude-mem)

The CI workflow from thedotmack/claude-mem, explained and optimized by Latchkey.

D

CI health: D - needs work

Point runs-on at Latchkey and get caching, run de-duplication, 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: thedotmack/claude-mem.github/workflows/ci.ymlLicense Apache-2.0View source

What it does

This is the CI workflow from the thedotmack/claude-mem repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: CI

on:
  pull_request:
  push:
    branches: [main]

jobs:
  build:
    name: typecheck · build · test · bundle-size
    runs-on: ubuntu-latest
    timeout-minutes: 25
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Bun (worker runtime + test runner)
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      # The repo intentionally gitignores package-lock.json (.gitignore), so
      # `cache: 'npm'` and `npm ci` (both require a committed lockfile) cannot
      # be used here - matches windows.yml / npm-publish.yml, which install the
      # same way.
      - name: Install dependencies
        run: npm install --no-audit --no-fund

      - name: Typecheck
        run: npm run typecheck

      # `npm run build` runs scripts/build-hooks.js, which enforces the worker
      # bundle-size guardrail (WORKER_SERVICE_MAX_BYTES, see #2584) and the MCP
      # server budget. A bundle that grows past threshold fails here → fails CI.
      - name: Build (includes bundle-size guardrails)
        run: npm run build

      # The in-process server-runtime smoke test (tests/server/server-runtime-smoke.test.ts,
      # #2550) runs here with no Docker: it boots the server HTTP surface in
      # process, loads a mode, creates a key, makes an authed request, and
      # checks the viewer responds. This gives every PR real server-runtime
      # coverage. The full pg+redis e2e is the docker-gated job below.
      - name: Test
        run: bun test

  clean-room-deps:
    name: clean-room dependency closure smoke
    runs-on: ubuntu-latest
    timeout-minutes: 25
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Bun (worker runtime + test runner)
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      # See note in the build job: no committed root lockfile, so npm install.
      - name: Install dependencies
        run: npm install --no-audit --no-fund

      # Run the frozen-lockfile drift check against the COMMITTED tree BEFORE
      # `npm run build` regenerates plugin/package.json + plugin/bun.lock (via
      # gen-plugin-lockfile.cjs). If a contributor changed plugin deps (through
      # scripts/build-hooks.js) but committed a stale plugin/bun.lock, the
      # committed pair is out of sync and --frozen-lockfile fails here.
      - name: Verify plugin lockfile is in sync (frozen-lockfile drift check)
        working-directory: plugin
        run: bun install --frozen-lockfile --ignore-scripts

      - name: Build
        run: npm run build

      # Clean-room install + import smoke test (plan-10): installs the packed
      # tarball into a throwaway dir and verifies the dependency closure resolves
      # and imports outside the dev tree.
      - name: Clean-room dependency closure smoke
        run: npm run smoke:clean-room

  server-runtime-e2e-docker:
    name: server-runtime e2e (docker · pg + valkey)
    runs-on: ubuntu-latest
    timeout-minutes: 30
    # Docker is available on ubuntu-latest GitHub runners. This job runs the
    # full server-runtime e2e (#2550): real Postgres + Valkey, queue durability,
    # restart recovery, and revoked-key denial. It does not gate PRs from the
    # `build` job; a failure here surfaces a server-runtime regression before a
    # user can file one (plan-07 test matrix).
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      # See note in the build job: no committed lockfile, so npm install.
      - name: Install dependencies
        run: npm install --no-audit --no-fund

      - name: Verify Docker is available
        run: docker compose version

      - name: Server-runtime Docker e2e
        run: npm run e2e:server:docker

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: CI
 
on:
  pull_request:
  push:
    branches: [main]
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build:
    name: typecheck · build · test · bundle-size
    runs-on: latchkey-small
    timeout-minutes: 25
    steps:
      - uses: actions/checkout@v4
 
      - uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: '20'
 
      - name: Install Bun (worker runtime + test runner)
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      # The repo intentionally gitignores package-lock.json (.gitignore), so
      # `cache: 'npm'` and `npm ci` (both require a committed lockfile) cannot
      # be used here - matches windows.yml / npm-publish.yml, which install the
      # same way.
      - name: Install dependencies
        run: npm install --no-audit --no-fund
 
      - name: Typecheck
        run: npm run typecheck
 
      # `npm run build` runs scripts/build-hooks.js, which enforces the worker
      # bundle-size guardrail (WORKER_SERVICE_MAX_BYTES, see #2584) and the MCP
      # server budget. A bundle that grows past threshold fails here → fails CI.
      - name: Build (includes bundle-size guardrails)
        run: npm run build
 
      # The in-process server-runtime smoke test (tests/server/server-runtime-smoke.test.ts,
      # #2550) runs here with no Docker: it boots the server HTTP surface in
      # process, loads a mode, creates a key, makes an authed request, and
      # checks the viewer responds. This gives every PR real server-runtime
      # coverage. The full pg+redis e2e is the docker-gated job below.
      - name: Test
        run: bun test
 
  clean-room-deps:
    name: clean-room dependency closure smoke
    runs-on: latchkey-small
    timeout-minutes: 25
    steps:
      - uses: actions/checkout@v4
 
      - uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: '20'
 
      - name: Install Bun (worker runtime + test runner)
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      # See note in the build job: no committed root lockfile, so npm install.
      - name: Install dependencies
        run: npm install --no-audit --no-fund
 
      # Run the frozen-lockfile drift check against the COMMITTED tree BEFORE
      # `npm run build` regenerates plugin/package.json + plugin/bun.lock (via
      # gen-plugin-lockfile.cjs). If a contributor changed plugin deps (through
      # scripts/build-hooks.js) but committed a stale plugin/bun.lock, the
      # committed pair is out of sync and --frozen-lockfile fails here.
      - name: Verify plugin lockfile is in sync (frozen-lockfile drift check)
        working-directory: plugin
        run: bun install --frozen-lockfile --ignore-scripts
 
      - name: Build
        run: npm run build
 
      # Clean-room install + import smoke test (plan-10): installs the packed
      # tarball into a throwaway dir and verifies the dependency closure resolves
      # and imports outside the dev tree.
      - name: Clean-room dependency closure smoke
        run: npm run smoke:clean-room
 
  server-runtime-e2e-docker:
    name: server-runtime e2e (docker · pg + valkey)
    runs-on: latchkey-small
    timeout-minutes: 30
    # Docker is available on ubuntu-latest GitHub runners. This job runs the
    # full server-runtime e2e (#2550): real Postgres + Valkey, queue durability,
    # restart recovery, and revoked-key denial. It does not gate PRs from the
    # `build` job; a failure here surfaces a server-runtime regression before a
    # user can file one (plan-07 test matrix).
    steps:
      - uses: actions/checkout@v4
 
      - uses: actions/setup-node@v4
        with:
          cache: 'npm'
          node-version: '20'
 
      - name: Install Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
 
      # See note in the build job: no committed lockfile, so npm install.
      - name: Install dependencies
        run: npm install --no-audit --no-fund
 
      - name: Verify Docker is available
        run: docker compose version
 
      - name: Server-runtime Docker e2e
        run: npm run e2e:server:docker
 

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 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow