Skip to content

v0.2.3

Choose a tag to compare

@github-actions github-actions released this 28 Aug 14:13
· 48 commits to main since this release

Say when a run cannot drain, and stop ignoring a nested config block

Two reports, both about the runner going quiet where it should speak.

bin/helix.js already told you when a finished run could not drain, but
ream test does not go through it — it goes through
@c9up/helix-plugin-ream, which just returned. So the summary printed,
every test green, and then nothing: no prompt, no output, and under a CI
timeout an exit 124 scored as a failure. The guard is extracted here as
armDrainGuard so the plugin runs the same code. bin/helix.js keeps
its own copy on purpose — it calls the guard from the error path too,
where the build may never have been imported, and an exit handler that
can fail to load is worse than a duplicated one.

Separately, a config whose settings sit under a tests block — the
shape of reamrc.ts, and of adonisrc.ts before it — was read as one
unknown key and dropped. Nothing said so: the declared bootstrap was
ignored and the conventional tests/bootstrap.ts ran in its place. In
the reported case that bootstrap starts the application, so 25 tests
that needed no server opened one and then hung — the first bug,
triggered by a file that had nothing to do with them. The nested form is
now read, with the flat one winning where both carry a key so a working
config keeps working.

Release the work that landed after the last published version

The registry now carries the version this package.json was still on, so
everything committed since ships under the next one rather than
retroactively changing what a published version means.

Build the cross-platform matrix only when the version moves

The five-runner matrix exists to produce the prebuilt binaries a release
ships. It ran on every push to main, rebuilding artefacts nobody
downloads — five runners, every time, for a comment fix.

A version-gate job now compares the package version at HEAD^ with
the one at HEAD and the matrix runs only when they differ. Anything
that is not a push passes the gate unconditionally, so workflow_dispatch
— how a release is actually cut — is unaffected, and so is publish,
which still waits on the full matrix. A missing HEAD^ reads as a bump:
erring towards building is the safe direction.

The test signal deliberately does NOT move with it. quality and the
cargo/integration jobs were already independent of the matrix, but
vitest ran INSIDE it, so gating the matrix alone would have quietly
taken the TypeScript suite off every ordinary push. A ts-tests job now
runs it on ubuntu, building its own napi binary rather than waiting on a
gated artefact. On a push without a bump that leaves typecheck, lint,
cargo and vitest — one runner instead of five.

Derive the native TypeScript surface from the Rust

The hand-written interface describing the .node binary was a second
description of the same thing, and nothing on this side noticed when the
first one changed: a pub fn could gain a parameter, stop being async
or change its return with the declaration still claiming otherwise.

napi-derive can emit the declarations itself. Its type-def feature
writes one JSON line per #[napi] item while cargo compiles;
scripts/build-napi-types.mjs collects them and
scripts/generate-napi-types.mjs turns them into
src/native/generated.ts. build:napi regenerates it, and the
TypeScript side consumes it instead of restating it.

Three things the generation had to handle:

  • type-def APPENDS to its output file, so a parallel cargo build
    interleaves the writes and definitions go missing, silently, leaving
    the generated file short. Crates are built one at a time, and a crate
    that emits nothing fails the script rather than producing a partial
    surface.
  • A Rust doc example holding a cron expression (0 */5 * * *) closes
    the generated comment early. Every */ is escaped except the one
    that legitimately closes the block — escaping that one breaks the
    file just as thoroughly.
  • The driver is Node rather than bash, because build:napi also runs
    on the Windows prebuild runner: a Git Bash mktemp path is not
    something the native proc-macro can write to, and the type-def file
    would come back empty with nothing to explain why.

The generated file is a .ts holding only ambient declarations rather
than a .d.ts, so tsc carries it into dist/native/ and the
reference from the emitted declarations still resolves for consumers.


Changes since v0.2.2.