Skip to content

feat(cli): embed private dependency tarballs into Playwright code bundles [RED-855] - #1435

Open
sorccu wants to merge 6 commits into
mainfrom
simo/red-855-embed-private-dep-tarballs
Open

feat(cli): embed private dependency tarballs into Playwright code bundles [RED-855]#1435
sorccu wants to merge 6 commits into
mainfrom
simo/red-855-embed-private-dep-tarballs

Conversation

@sorccu

@sorccu sorccu commented Aug 12, 2026

Copy link
Copy Markdown
Member

Linear: RED-855

What

Adds a checks.embeddedPackages config option that embeds npm registry tarballs into the Playwright Check Suite code bundle at .checkly/embedded-packages/*.tgz, so runners can install packages they cannot fetch themselves (e.g. from a private registry that is only reachable from the customer's network). The runner half that serves the embedded tarballs through a local registry during install is a separate change (RED-856); do not cut a CLI release containing this feature before that runner support is deployed.

How

Three commits, one per layer (plus follow-ups: platform-independent npm-cache tests for Windows CI, and moving the tarball cache to node_modules/.cache/checkly):

  1. Config optionchecks.embeddedPackages?: string[] (package names embed every lockfile version; name@version pins an exact version), with runtime shape validation at config load and plumbing through ProjectParseOptsSession for deploy/test/validate/pw-test/parse-project.
  2. Services (src/services/embedded-packages/) — lockfile enumeration (pnpm-lock.yaml v6/v9, package-lock.json v2/v3, with precise reasons for git/file/workspace/integrity-less entries), .npmrc parsing with scope-aware registry resolution, nerf-dart auth matching and npm_config_* env layering, SRI integrity helpers, and a content-addressed per-user tarball cache with a read-only npm-cache (cacache) lookup tier.
  3. Wiring — a memoized session-level materializer shared by validation and bundling; project validation resolves the configured entries against the lockfile before any bundling (grouped fatal diagnostics); Playwright bundling appends the verified tarballs at the contract path via explicit archive paths, independent of workspace layout.

Tarballs are always the verbatim registry artifact, verified against the lockfile's integrity hash, sourced through CLI cache → npm cacache → registry download (proxy-aware via the existing assignProxy helper, credentials redacted from errors). Downloads are cached under the workspace root's node_modules/.cache/checkly (persisted automatically by CI setups that cache node_modules; a per-user cache dir is the read/write fallback; CHECKLY_CACHE_DIR overrides), so nothing user-visible lands in the project outside node_modules. The pnpm store cannot serve as a source because it retains only unpacked per-file blobs, not original tarballs.

Wildcards (added after review of the initial version): entries may contain * wildcards — @acme/*, acme-*, @acme/*-utils — where each * matches any run of characters except /, so a pattern never crosses the scope separator; wildcards combine with exact version pins and resolve against the lockfile only. Matches a spec cannot embed are skipped (workspace members silently; git/file/URL and integrity-less dependencies via a non-fatal warning diagnostic, since the runner must fetch those itself), while a spec whose only matches cannot be embedded — or that matches nothing — remains an error. Each wildcard announces what it selected during bundling. Excluded lockfile entries now carry a structured kind (workspace vs unfetchable), with npm/pnpm links pointing outside the workspace classified as unfetchable.

Deliberate v1 limits (documented; follow-ups tracked in Linear): only explicitly listed packages are embedded (no auto-detection, including transitive private deps — see the stacked follow-up PR), no yarn/bun lockfiles, .npmrc proxy/cafile/strict-ssl keys not honored (proxy env vars work).

Testing

  • 110+ new unit tests (spec parsing, npmrc/registry/auth, lockfile enumeration, cache, materializer against a local HTTP registry covering auth, integrity mismatch, cache tiers).
  • Offline integration tests: fixtures with committed deterministic tarballs pre-seeded into a temp CHECKLY_CACHE_DIR assert the archive contains the contract paths (including subdirectory Playwright configs and version-pin filtering) and that a package missing from the lockfile fails validation.
  • Full suite: 1966 passed (including 30+ wildcard parse/match/plan tests). Manual smoke test against registry.npmjs.org: bundled tarball byte-identical to the lockfile integrity; warm-cache re-run skips the download.

🤖 Generated with Claude Code

@sorccu
sorccu force-pushed the simo/red-855-embed-private-dep-tarballs branch 5 times, most recently from 8caa271 to 79eeeb3 Compare August 13, 2026 07:29
sorccu and others added 5 commits August 14, 2026 14:20
Adds the config surface for embedding private dependency tarballs into
the Playwright Check Suite code bundle: a TSDoc'd checks.embeddedPackages
option (package names or name@exact-version pins), runtime shape
validation at config load, a reusable spec parser, and plumbing through
ProjectParseOpts into Session for deploy, test, validate, pw-test and
debug parse-project.

Scaffolding only: resolution/fetch services and bundling wiring land in
follow-up commits on this branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pure services that turn checks.embeddedPackages entries into verified
registry tarballs: lockfile enumeration (pnpm-lock.yaml v6/v9,
package-lock.json v2/v3, with precise reasons for git/file/workspace/
integrity-less entries), .npmrc parsing with scope-aware registry
resolution, nerf-dart auth matching and npm_config_* env layering, SRI
integrity helpers, a content-addressed per-user tarball cache
(CHECKLY_CACHE_DIR override, atomic writes, self-healing corrupt
entries) with a read-only npm cacache lookup tier, and a memoized
materializer running the CLI cache -> npm cache -> registry download
source chain with proxy-aware axios and credential-redacted errors.

Consumed by the Playwright bundler in the next commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…es [RED-855]

Wires the embedded-packages services into the CLI: a memoized
session-level materializer shared by validation and bundling, project
validation that resolves checks.embeddedPackages against the lockfile
before any bundling (grouped, readable diagnostics; skipped when the
project has no Playwright checks), and Playwright bundling that appends
the verified tarballs at the runner contract path
.checkly/embedded-packages/<name>@<version>.tgz via explicit archive
paths, independent of workspace layout.

Includes offline integration tests driven by a pre-seeded
CHECKLY_CACHE_DIR with committed deterministic tarball fixtures, plus
TSDoc and AI-context documentation.

The runner half that serves the embedded tarballs during install is
RED-856; CLI releases containing this feature must wait for it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t [RED-855]

The materializer cacache test seeded a fake npm cache at ~/.npm, but on
Windows npm caches under %LOCALAPPDATA%\npm-cache, so the lookup missed
and the test fell through to a recorded network request. Pin the
location via npm_config_cache, which production honors on every
platform, and add direct coverage for the win32 LOCALAPPDATA lookup
branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…[RED-855]

The embedded-packages cache now defaults to the workspace root's
node_modules/.cache/checkly — the conventional tool-cache location that
incremental installs leave alone and node_modules-caching CI setups
persist automatically — so warm caches travel with the project instead
of living in a per-user directory. The cache is multi-root: reads also
consult the per-user platform directory, and writes fall back to it
when the project location is not writable (e.g. a read-only checkout),
with CHECKLY_CACHE_DIR remaining the single-location override.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sorccu
sorccu force-pushed the simo/red-855-embed-private-dep-tarballs branch from 79eeeb3 to 20c3a23 Compare August 14, 2026 05:22
Entries may now contain * wildcards (@acme/*, acme-*, @acme/*-utils),
each matching any run of characters except /, so a pattern never
crosses the scope separator. Wildcards resolve against the workspace
lockfile only and combine with exact version pins. Matches that cannot
be embedded are skipped — workspace members silently, git/file/URL and
integrity-less dependencies via a warning diagnostic — while a spec
whose only matches cannot be embedded, or that matches nothing at all,
remains an error. Each wildcard announces what it selected during
bundling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant