Skip to content

publish loop is alphabetical, not topological — a mid-run failure can publish a package ahead of its own dependencies #46

Description

@yakimoto

publish-npm.yml publishes packages in alphabetical order, under set -euo pipefail. A failure partway through the loop leaves every package before it already on npm — including packages published ahead of their own dependencies.

The loop

for dir in packages/*/; do ...          # validation pass — alphabetical
while IFS= read -r dir; do ...          # publish pass — same order
  ( cd "$dir" && pnpm publish --access public --provenance ... )

packages/*/ expands in lexical order. Dependency edges don't respect it.

Two concrete inversions

package depends on sorts
@wave-av/adk @wave-av/kernel adk first, kernel 23rd
@wave-av/sdk 11 of its 44 deps sdk before search, sentiment, signage, slides, studio-ai, studio, transcribe, usb, vault, voice, zoom

npm does not verify that a package's dependencies exist at publish time. So if the run dies after sdk and before zoom — a network blip, a registry 5xx, one package failing validation late, a cancelled job — @wave-av/sdk@3.0.0 is live and permanently broken: its dependencies were never published, and an npm version cannot be replaced once taken. The only remedy is to burn the version and publish a new one.

The same applies to adk, which sorts first in the whole workspace and depends on kernel.

Why the existing guards don't cover it

#45 makes validation atomic — the release is decided in full before anything publishes, so no package ships against a known-bad sibling. But the publish pass itself is still sequential and non-transactional. Atomic validation doesn't make execution atomic; it just means everything entering the loop was fine at the time.

Suggested fix

Publish in topological order. The repo already computes it — the build and pack steps use pnpm -r --filter "@wave-av/*", which topo-sorts:

- name: "Build all packages (pnpm -r topo-sorts: core then products then umbrella)"
  run: pnpm -r --filter "@wave-av/*" build

So the ordering is available; the publish loop just doesn't consume it. Either drive the publish from pnpm -r directly, or have the validation pass emit publishable in dependency order instead of directory order.

A cheaper partial mitigation, if the full fix is too invasive: publish the umbrella last, since it is the package with the most inbound edges. That fixes sdk and leaves adk/kernel broken, so it's a stopgap rather than a repair.

Not fixing in #45

#45 is scoped to release validation and is already testable without CI. This one changes publish execution, and I can't verify an ordering change while org Actions are billing-locked — the failure mode it prevents is exactly a partially-executed publish, which is not something to ship on reasoning alone. Filing so it isn't lost.

Context: #42, #44, #45.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageOn the board but missing Type/Area/Priority

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions