Files
Olli Paloviita 70f51674a3 feat(init): batch shared installs and fix pnpm 11 build approval
Install the dev dependencies that share install flags (@playwright/test,
@types/node, @playwright/cli) in a single command, keeping screenci
separate since pnpm needs --allow-build=ffmpeg-static. Resolves the
dependency graph twice instead of four times.

Make the generated island pnpm-workspace.yaml version-aware: pnpm 11
removed onlyBuiltDependencies in favour of allowBuilds, so a flagless
pnpm install on pnpm 11 silently skipped the ffmpeg-static build.
Resolve the pnpm version before writing the workspace file and emit the
matching approval key.

Add a pnpm 10 + 11 CI job (scripts/assert-ffmpeg-built.js) that runs
init and asserts the ffmpeg-static binary built, including a flagless
reinstall that relies only on the generated workspace approval.
2026-06-14 00:41:57 +03:00

52 lines
1.9 KiB
JavaScript

import { existsSync, statSync } from 'node:fs'
import { createRequire } from 'node:module'
import { resolve } from 'node:path'
// Verifies that ffmpeg-static's build (postinstall) script actually ran by
// resolving the bundled binary from the installed `screenci` package and
// checking the file exists and is non-empty.
//
// This catches package managers that silently skip dependency build scripts
// (pnpm 10/11 ignore them unless approved; npm 12 plans the same). A skipped
// script leaves ffmpeg-static exporting a path to a file that was never
// downloaded, so screenci's encoding fails only later at render time. Asserting
// the binary here turns that into a loud, immediate CI failure.
//
// Usage: node scripts/assert-ffmpeg-built.js <island-dir>
const islandDir = resolve(process.argv[2] ?? process.cwd())
// Seed a require from inside the island so module resolution matches what the
// generated project sees, then resolve ffmpeg-static the way screenci does
// (it is a transitive dependency, not a direct one).
const islandRequire = createRequire(resolve(islandDir, 'noop.js'))
let binaryPath
try {
const screenciEntry = islandRequire.resolve('screenci')
const screenciRequire = createRequire(screenciEntry)
binaryPath = screenciRequire('ffmpeg-static')
} catch (err) {
console.error(
`Could not resolve ffmpeg-static from screenci in ${islandDir}: ${err.message}`
)
process.exit(1)
}
if (typeof binaryPath !== 'string' || binaryPath.length === 0) {
console.error('ffmpeg-static did not export a binary path.')
process.exit(1)
}
if (!existsSync(binaryPath) || statSync(binaryPath).size === 0) {
console.error(
`ffmpeg-static binary missing or empty at ${binaryPath}. ` +
'The build/postinstall script was skipped by the package manager.'
)
process.exit(1)
}
console.log(
`ffmpeg-static binary present at ${binaryPath} (${statSync(binaryPath).size} bytes).`
)