Skip to content

Publish tread to crates.io and npm - #17

Merged
viict merged 5 commits into
masterfrom
feat/publish
Aug 13, 2026
Merged

Publish tread to crates.io and npm#17
viict merged 5 commits into
masterfrom
feat/publish

Conversation

@viict

@viict viict commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Ships tread from two package managers, and wires the release to keep doing it.

tread is now on crates.io, and @viict/tread on npm. This branch is what makes
the next tag publish to both without hands.

The npm package is a launcher, not a copy

It carries no binary. On first run it fetches the archive this release already
publishes
— the same .tar.gz or .zip a person downloads by hand and that
install.sh verifies — checks it against SHA256SUMS, and only then reads the
binary out of it. The release is not asked to carry a second, npm-shaped copy of
every build.

Reading the archives is the launcher's own work: node has zlib built in and no
archive reader, so lib/unpack.js walks a tar's 512-byte headers and a zip's
central directory in ~130 lines. That keeps the package's dependency count where
the rest of the project keeps it — at zero.

Not a postinstall download: that is dead weight under npm ci --ignore-scripts
and pnpm's default script blocking, where the package installs and the binary
silently never arrives. Fetching at first run costs a moment once and works
everywhere.

The binary is state, not cache, so it lives under the platform's data
directory — a cache is something the OS may delete, and a tread that
evaporates leaves an offline machine unable to read anything:

Platform Location
Linux $XDG_DATA_HOME/tread/<version>/, else ~/.local/share/tread/<version>/
macOS ~/Library/Application Support/tread/<version>/
Windows %LOCALAPPDATA%\tread\<version>\

A version is a directory, so upgrading needs no invalidation rule. TREAD_BINARY
points at a tread you already have and skips all of it — one global install
shared by several accounts, or a runner with no route out.

Release

Two jobs, both authenticating by trusted publishing, so no long-lived secret
lives in the workflow. The crate job refuses a tag that disagrees with
Cargo.toml (a crates.io version can never be republished) and skips a version
the registry already has, so re-tagging stays green — which the release job above
it already supported. The npm job waits on the GitHub release, because the
launcher it publishes reads its binary from there.

Cargo.toml also grows an exclude: cargo package includes untracked files,
so anything sitting in a working tree ships with an --allow-dirty publish and
can never be deleted again.

Verified

  • The launcher end to end against the published v0.3.0 release, from a clean
    cache: fetch, verify, extract, run. 0.43s cold, 0.06s warm.
  • npx @viict/tread from the public registry, unauthenticated, renders.
  • Extraction checked against the real v0.3.0 assets: the extracted Linux binary
    runs and reports its version; the extracted .exe is a valid PE32+.
  • cargo test: 1587 passing, unchanged — nothing here touches Rust.
  • npm pack: 4 files, 6.8 kB, no binary.

Before the next tag

Cargo.toml must be bumped to the version being tagged, and npm trusted
publishing configured for @viict/tread (repo, workflow release.yml,
environment Packaging).

viict added 5 commits August 13, 2026 20:16
cargo package includes untracked files, so a private sample sitting in the
working tree ships with a --allow-dirty publish and can never be deleted
again. Name the exclusions instead of relying on the dirty check.
The package carries no binary. On first run it fetches the archive the
releases page already publishes, checks it against SHA256SUMS, and only
then reads the binary out of it — so npm costs the release nothing and
delivers the same bytes install.sh does. TREAD_BINARY skips all of it.
Both registries authenticate by trusted publishing, so no long-lived
secret lives in the workflow. The crate job refuses a tag that disagrees
with Cargo.toml, because a crates.io version can never be republished,
and skips a version the registry already has so a retag stays green. The
npm job waits on the GitHub release, since the launcher it publishes
reads its binary from there.
@viict
viict merged commit 0fe5b95 into master Aug 13, 2026
7 checks passed
@viict viict self-assigned this Aug 13, 2026
@viict
viict deleted the feat/publish branch August 13, 2026 20:20
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