Background
The build-packages job is flaky because recursive packing starts overlapping builds that write to the same dist directories. The failures block npm package artifacts even though the test and initial build steps have passed.
Before packing, .github/workflows/main.yaml builds every non-example workspace package once with pnpm -r --filter='!./examples/**' run build:self. It then runs pnpm pack --recursive with enable-pre-post-scripts=true. Packing invokes each package's prepack script, and most packages implement prepack as pnpm build. Those build scripts use selectors such as @fedify/relay..., so each invocation rebuilds the package and its workspace dependencies. Several independent packing workers can therefore clean and regenerate the same dependency output at once.
Pack lifecycle scripts were enabled in c87db61 so that @fedify/fedify could materialize skills/fedify/SKILL.md before creating its tarball. Disabling every lifecycle script would bring that packaging bug back, so the fix needs to preserve the skill preparation without allowing concurrent builds to share output directories.
Evidence
The latest failure occurred in the build-packages job. While @fedify/relay was bundling src/mastodon.test.ts, tsdown could not resolve the @fedify/vocab-runtime workspace package:
[UNLOADABLE_DEPENDENCY] Could not load ../vocab-runtime/dist/mod.js
No such file or directory (os error 2)
The same log shows @fedify/vocab-runtime reporting Cleaning 92 files repeatedly during the pack step. One cleanup started at 09:11:52 UTC, and the relay build failed to read dist/mod.js at 09:11:55 UTC. The same error appeared in an earlier July 29 run and a July 26 run, while the identical command succeeded on July 27. The timing-dependent result makes this a build race rather than a consistently missing artifact.
This is related to #634, which fixed one manifestation by externalizing @fedify/fixture from test bundles. The new failure involves @fedify/vocab-runtime and shows that the underlying concurrent rebuild problem remains.
Reproduction
On a clean checkout with Node.js 22 and pnpm 10.28.0, run the same build and pack commands as CI:
mise deps
pnpm -r --filter='!./examples/**' run build:self
pnpm pack --recursive --filter='!./examples/**' \
--config.enable-pre-post-scripts=true
The race does not occur on every run, so the pack command may need to be repeated.
Expected behavior
Recursive packing should produce all npm tarballs deterministically after the workspace has been built. It should not rebuild the same output directory from concurrent lifecycle scripts. The @fedify/fedify tarball must still contain skills/fedify/SKILL.md.
Possible direction
The packaging path should ensure that only one build writes each dist directory. We could serialize package packing, or separate the one-time workspace build and Fedify skill materialization from the lifecycle scripts used by pnpm pack. .github/workflows/main.yaml and .github/workflows/publish-pr.yaml should use the same race-free path.
Background
The
build-packagesjob is flaky because recursive packing starts overlapping builds that write to the samedistdirectories. The failures block npm package artifacts even though the test and initial build steps have passed.Before packing, .github/workflows/main.yaml builds every non-example workspace package once with
pnpm -r --filter='!./examples/**' run build:self. It then runspnpm pack --recursivewithenable-pre-post-scripts=true. Packing invokes each package'sprepackscript, and most packages implementprepackaspnpm build. Thosebuildscripts use selectors such as@fedify/relay..., so each invocation rebuilds the package and its workspace dependencies. Several independent packing workers can therefore clean and regenerate the same dependency output at once.Pack lifecycle scripts were enabled in c87db61 so that
@fedify/fedifycould materialize skills/fedify/SKILL.md before creating its tarball. Disabling every lifecycle script would bring that packaging bug back, so the fix needs to preserve the skill preparation without allowing concurrent builds to share output directories.Evidence
The latest failure occurred in the
build-packagesjob. While@fedify/relaywas bundling src/mastodon.test.ts, tsdown could not resolve the@fedify/vocab-runtimeworkspace package:The same log shows
@fedify/vocab-runtimereportingCleaning 92 filesrepeatedly during the pack step. One cleanup started at 09:11:52 UTC, and the relay build failed to read dist/mod.js at 09:11:55 UTC. The same error appeared in an earlier July 29 run and a July 26 run, while the identical command succeeded on July 27. The timing-dependent result makes this a build race rather than a consistently missing artifact.This is related to #634, which fixed one manifestation by externalizing
@fedify/fixturefrom test bundles. The new failure involves@fedify/vocab-runtimeand shows that the underlying concurrent rebuild problem remains.Reproduction
On a clean checkout with Node.js 22 and pnpm 10.28.0, run the same build and pack commands as CI:
The race does not occur on every run, so the pack command may need to be repeated.
Expected behavior
Recursive packing should produce all npm tarballs deterministically after the workspace has been built. It should not rebuild the same output directory from concurrent lifecycle scripts. The
@fedify/fedifytarball must still contain skills/fedify/SKILL.md.Possible direction
The packaging path should ensure that only one build writes each
distdirectory. We could serialize package packing, or separate the one-time workspace build and Fedify skill materialization from the lifecycle scripts used bypnpm pack. .github/workflows/main.yaml and .github/workflows/publish-pr.yaml should use the same race-free path.