[MERGE AFTER 0.10 RELEASE] ci(publish): install only the package being published - #1440
Merged
Conversation
The publish job ran yarn install at the repo root, whose workspaces glob is packages/* + apps/* + apps/legacy/*. Building one package pulled 1659 packages and 597.4 MiB for eight React Native example apps that are never built: 164s of a 197s job, against 19s for bob and tsc. yarn workspaces focus installs only this package's tree. It is built into Yarn 4, the same command family as the workspaces foreach already used in CI, so no plugin is needed. Measured locally: 709 packages, 71.29 MiB. Also stopped the postinstall native download (RNET_SKIP_DOWNLOAD), which this job has no use for since it runs bob and tsc and the files list excludes third-party/include from the tarball, and stopped the second install: the workflow installed, then create-package.sh installed again.
The satellite workflow passed 'yarn install --immutable && yarn workspace react-native-executorch prepare' as its install command, so each of the three runs paid for the same whole-monorepo install as the core job, plus the core package's postinstall native download on top. Each satellite declares react-native-executorch as a workspace:* devDependency, so focusing on the satellite pulls the core workspace in with it and the core prepare still runs. Verified locally from a clean node_modules for all three: core prepare succeeds and each satellite's tsc exits 0.
All three satellites pointed tsBuildInfoFile at ./lib/typescript inside outDir, and their files list ships all of lib/, so every published tarball carried tsconfig.tsbuildinfo: TypeScript's incremental build cache, useless to consumers and a third of the packed size. Found while checking the 0.10.0 dry run of the bare fetcher: 18 files, one of them the build info. Moving it to .cache/, which is already gitignored and outside outDir, packs 17. The core package was never affected; it sets no tsBuildInfoFile.
barhanc
approved these changes
Sep 8, 2026
…looks like a version The override guard required a leading letter, on the theory that this ruled out semver. It did not. npm's actual rule is that a dist-tag must not parse as a semver range, and every example this input documented passes the old check and fails at npm: v0.8 parses as >=0.8.0 <0.9.0-0, v0.10.0 as 0.10.0. The 0.10.0 dry run hit exactly this, ten steps in, after building and packing the tarball. Ask semver instead of approximating it, and say what to use instead. The package resolves from the repo root under the focused install this branch introduces, and the check runs after that step. Also rewrote the input description: it said 'e.g. v0.8', which is one of the values npm refuses, and did not say the field is the npm dist-tag rather than the git tag to publish from.
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.
Warning
Do not merge until 0.10.0 is released. This touches the publish path, and there is no reason to carry that risk the day before shipping.
Description
The publish job ran
yarn installat the repo root, whose workspaces glob ispackages/*+apps/*+apps/legacy/*. Building one package pulled dependencies for eight React Native example apps that are never built.From the 0.10.0 dry run:
yarn workspaces focusinstalls only the package's own tree. It is built into Yarn 4, the same command family as theworkspaces foreachalready used in CI, so no plugin is needed.yarn install(root)yarn workspaces focusThe satellite workflow had the same problem: it passed
yarn install --immutable && yarn workspace react-native-executorch prepareas its install command, so each of the three runs paid for the whole monorepo too. Each satellite declaresreact-native-executorchas aworkspace:*devDependency, so focusing on the satellite pulls the core workspace in with it and the corepreparestill runs.Two smaller fixes alongside it:
RNET_SKIP_DOWNLOAD=1. The job runs bob and tsc, and thefileslist excludesthird-party/includefrom the tarball, so the postinstall native download bought nothing and printed two "coreml is iOS-only" warnings on a Linux runner.create-package.sh. The script now skips it whenRNE_SKIP_INSTALLis set, so a local run is unchanged.Also: the satellite tarballs shipped a build cache
Found while reading the 0.10.0 bare-fetcher dry run. All three satellites pointed
tsBuildInfoFileat./lib/typescript/tsconfig.tsbuildinfo, insideoutDir, and theirfileslist ships all oflib/. So every published tarball carried TypeScript's incremental build cache: 1 of 18 files and roughly a third of the packed bytes, useless to consumers.Moved it to
.cache/, which is outsideoutDirand already gitignored. Rebuilt and packed locally: 18 files becomes 17, nothing else changes. The core package was never affected, it sets notsBuildInfoFile.Also: the dist-tag guard let through every tag it documented
The
dist-tagoverride validated with^[a-zA-Z][a-zA-Z0-9._-]*$, on the theory that requiring a leading letter ruled out semver. npm's actual rule is that a dist-tag must not parse as a semver range, and the input's own documented example fails it:v0.8(the documented example)>=0.8.0 <0.9.0-0v0.10.00.10.0latest,legacy,v0-8The 0.10.0 dry run hit this, failing at npm ten steps in, after the build and pack. Now it asks
semverand names a form that works. Verified against 11 inputs:v0.10.0,v0.10,v0.8,0.8,1.xand*are rejected with the parsed range in the message;latest,legacy,executorch-nightly,v0-8andnextpass.semverresolves from the repo root under the focused install this branch introduces, and the check runs after that step.The input description also said "e.g. v0.8" and never said the field is the npm dist-tag rather than the git tag to publish from. Both fixed.
Trade-off
focusdoes not accept--immutable, so this job stops asserting that the lockfile is in sync. CI already asserts it on every pull request, and a release publishes from a branch that passed. Verified separately thatfocusleavesyarn.lockuntouched, so nothing is silently rewritten.Introduces a breaking change?
Type of change
Tested on
Testing instructions
Locally, a focused install plus
yarn prepareproduces alib/identical to the one in the published 0.10.0 tarball: 496 files, same paths. The full install measured locally at 1660 packages / 597.08 MiB / 1.6 GB on disk, matching what CI reports. For the satellites, each was verified from a cleannode_modules: the corepreparesucceeds and every satellite'stscexits 0. Every static import insrc/andlegacy/src/resolves from the package's own dependencies (@kesha-antonov/react-native-background-downloaderis a runtimerequire()in a try/catch, so tsc never needs it).The full pack could not be run locally because
create-package.shchecks out the phonemis submodule, which needs git-lfs. Before merging, run the core publish workflow from this branch withrelease-type: latestanddry-run: true, and confirm the tarball is still 1020 files / 1.5 MB (1021 withLICENSEonce #1437 lands).Checklist