Skip to content

Build: package scripts that swallow their exit status #180

Description

@JumpLink

The mechanism

A package script whose entire body is a single gjsify … command exits 0 no matter what that command did.

Measured on the pinned CLI 0.16.3 — runScript in @gjsify/cli/dist/cli.gjs.mjs:

let Y = isGjs() ? gjsifyInProcessArgv(I, a) : null;
if (Y) {
  try { const { runCli } = await import(...); await runCli(Y); }
  catch (e) { logger.error(e.message); process.exit(1); }
  process.exit(process.exitCode == null ? 0 : Number(process.exitCode));
}

gjsifyInProcessArgv returns non-null only when the body tokenizes as one plain gjsify … command (tokenizeSimpleCommand bails on any of |&;<>`$()\ * ? { } [ ] ~ # !). On that path the sub-command runs in-process and the wrapper exits with process.exitCode ?? 0 — and gjsify build and gjsify run report failure without setting process.exitCode. Anything with a shell operator takes the spawn path and the status survives. gjsify tsc is unaffected because it spawns gjs.

Reproduction:

"p1": "gjsify run /tmp/throws.gen.js"                  -> gjsify workspace <pkg> p1  == exit 0
"p2": "gjsify run /tmp/throws.gen.js && echo SECOND"   -> exit 1, SECOND not printed
"p3": "gjs -m /tmp/throws.gen.js"                      -> exit 1
"p4": "exit 7"                                         -> exit 1

What is still affected

#178 chained the leaves in learn, translations and examples, which is where it was actively hiding failures (the tutorial artifact check and the catalog check both exited 0 while reporting problems). These remain:

  • packages/app-gnome: build:gjs, build:resources, build:schema — so gjsify workspace @learn6502/app-gnome build reports success when the bundle, the gresource or the GSettings schema failed to build. This one ships.
  • packages/app-web: build:app (and therefore build).
  • packages/cli: build.
  • root: build (gjsify foreach --topological-dev build), check (gjsify foreach -t check), setup, start:*, format, lint — worth measuring whether foreach propagates before changing anything.

check scripts that are gjsify tsc … (core, common-ui, app-web, app-android, app-gnome's check:typescript) were measured and do propagate — verified by introducing a type error and getting exit 1.

Fix

Upstream, in gjsify: the in-process path should take the sub-command's status rather than reading a process.exitCode its commands never set. Until that lands, AGENTS.md (§ Package scripts) records the rule so the chains are not "simplified" back into single-command steps.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions