feat(cli): embed private dependency tarballs into Playwright code bundles [RED-855] [ship] - #1435
Merged
Merged
Conversation
sorccu
force-pushed
the
simo/red-855-embed-private-dep-tarballs
branch
5 times, most recently
from
August 13, 2026 07:29
8caa271 to
79eeeb3
Compare
sorccu
force-pushed
the
simo/red-855-embed-private-dep-tarballs
branch
2 times, most recently
from
August 18, 2026 07:23
3c2e150 to
7b7ad3c
Compare
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>
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>
…e upload size limit The API rejects an oversized code bundle upload with HTTP 413, which previously surfaced as a raw "Payload content length greater than maximum allowed: <bytes>" message. Map 413 responses to a typed PayloadTooLargeError and convert it at the upload site into a BundleTooLargeError that names the bundle size, the server-reported limit (parsed from the response rather than hard-coded), and how to reduce the bundle — mentioning embedded packages only when the bundle actually contains them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sorccu
force-pushed
the
simo/red-855-embed-private-dep-tarballs
branch
from
August 20, 2026 06:27
7b7ad3c to
5401953
Compare
…hash [RED-855] Changing checks.embeddedPackages with an unchanged lockfile previously left the code bundle's cacheHash identical, so runners reused a stale cached install and the new embedded tarball set was never exercised. The resolved embed set (name@version + lockfile integrity) now contributes embedded-package records to the hash; projects without embedded packages keep byte-identical digests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… [RED-855] The embedded-packages option moves out of 'checks' into a new top-level 'bundle.packages' config section, which upcoming auto-detection options (RED-862) will expand. The option has not shipped in any release, so there is no back-compat alias. A misshapen 'bundle' or 'bundle.packages' value is rejected at config load instead of silently disabling embedding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Trim the option docs to what a user needs: entry syntax, the transitive-dependency requirement, npm/pnpm-only support, and the cache-invalidation behavior. Internal mechanics (archive paths, cache directories, tarball sourcing) no longer leak into the config surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…855] When several bundle.packages.embed entries fail validation, the diagnostic now groups them under per-problem headings (invalid entries, not found, wrong pinned version with the available versions listed, not embeddable with reasons) and names the lockfile once — and only when entries were actually resolved against it. Headers are pre-wrapped to survive the command renderer's 78-column re-wrap. Also removes the wildcard match announcement previously written raw to stderr during bundling, which interrupted styled command output; the selection is debug-logged during planning instead. Selections needing attention already surface louder: a pattern matching nothing is a fatal validation issue and unfetchable matches produce a warning diagnostic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linear: RED-855
What
Adds a
bundle.packages.embedconfig option (a new top-levelbundle.packagessection, which the RED-862 auto-detection options will expand) 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 (RED-856) is already deployed, so this feature is releasable.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):bundle.packages.embed?: string[](package names embed every lockfile version;name@versionpins an exact version; initially added aschecks.embeddedPackagesand moved before release), with runtime shape validation at config load — including rejecting a misshapenbundleorbundle.packagesvalue that would otherwise silently disable embedding — and plumbing throughProjectParseOpts→Sessionfor deploy/test/validate/pw-test/parse-project.src/services/embedded-packages/) — lockfile enumeration (pnpm-lock.yamlv6/v9,package-lock.jsonv2/v3, with precise reasons for git/file/workspace/integrity-less entries),.npmrcparsing with scope-aware registry resolution, nerf-dart auth matching andnpm_config_*env layering, SRI integrity helpers, and a content-addressed per-user tarball cache with a read-only npm-cache (cacache) lookup tier.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
assignProxyhelper, credentials redacted from errors). Downloads are cached under the workspace root'snode_modules/.cache/checkly(persisted automatically by CI setups that cachenode_modules; a per-user cache dir is the read/write fallback;CHECKLY_CACHE_DIRoverrides), so nothing user-visible lands in the project outsidenode_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 (workspacevsunfetchable), with npm/pnpm links pointing outside the workspace classified as unfetchable.Dependency cache invalidation — the resolved embed set (
name@version+ lockfile integrity) is mixed into the code bundle'scacheHashas a newembedded-package:record type, so changingbundle.packages.embedinvalidates the runner's install cache even when the lockfile is unchanged (previously the hash covered only lockfile +package.json+.npmrc+caching.dependencyCache.version, so an edited embed list silently reused a stale cached install). Projects without embedded packages keep byte-identical digests, and a new cross-language parity fixture pins all optional record groups in order for the terraform-provider-checkly mirror.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,
.npmrcproxy/cafile/strict-sslkeys not honored (proxy env vars work).Other changes
Payload content length greater than maximum allowed: <bytes>message. Since embedded tarballs can grow bundles toward that limit, the CLI now maps 413 to a typed error and reports the bundle size, the server-reported limit (parsed from the response, never hard-coded client-side), and remediation steps — mentioningbundle.packages.embedonly when the bundle actually embeds packages.Testing
CHECKLY_CACHE_DIRassert the archive contains the contract paths (including subdirectory Playwright configs and version-pin filtering) and that a package missing from the lockfile fails validation.cacheHashdiffers between two embed lists.🤖 Generated with Claude Code