Skip to content

chore: replace surgical native binary CI workaround with proper cross-platform lockfile #216

@NickMonrad

Description

@NickMonrad

Problem

The CI workflow currently works around npm/cli#4828 using a brittle surgical install step:

- name: Install missing Linux native binaries
  run: |
    get_ver() { node -p "JSON.parse(require('fs').readFileSync('node_modules/$1/package.json','utf8')).version"; }
    npm install --no-save --ignore-scripts \
      "@rolldown/binding-linux-x64-gnu@$(get_ver rolldown)" \
      "@rollup/rollup-linux-x64-gnu@$(get_ver rollup)" \
      "lightningcss-linux-x64-gnu@$(get_ver lightningcss)" \
      "@tailwindcss/oxide-linux-x64-gnu@$(get_ver @tailwindcss/oxide)"

This is fragile: any new dependency with Linux-native binaries will silently break CI until we manually add it here.

Root cause

macOS never resolves Linux-specific optional packages, so they're absent from package-lock.json. npm ci is strict and won't install them. The packages affected are those with platform-native .node binaries: rolldown, rollup, lightningcss, @tailwindcss/oxide.

Options to evaluate

  1. Generate the lockfile on Linux (e.g. run npm install in a scheduled CI job on a Linux runner and commit the result) — once-off fix, lockfile stays correct
  2. Use npm install --os=linux flag if/when npm supports cross-platform lockfile generation
  3. Switch to pnpm — pnpm handles optional platform deps correctly without this problem
  4. Use a .npmrc with os=linux to trick local installs into resolving Linux deps

Track: introduced as workaround in PR #213 (Vite 8 upgrade).

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogFuture enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions