Skip to content

pi-dispatch v0.8.0

Choose a tag to compare

@github-actions github-actions released this 04 Aug 12:46
· 518 commits to main since this release
617d930

Two batches land together: /dispatch becomes the way you set pi-dispatch up, and a documentation audit that turned into six code fixes.

/dispatch is the front door now

pi install npm:@edgehero/pi-dispatch-admin   # then, inside pi:  /dispatch

With nothing configured, /dispatch used to offer you a yes/no. It now takes you straight into guided setup, and the opening choice is the consent, so nothing runs before you pick one. In order: a deployment folder, a Docker check with per OS pointers (checked first, so no bandwidth is spent on a host where up cannot work anyway), the pinned runtime, pi-dispatch up running its own prompts in your terminal, an optional worker service, an optional trigger edge (receiver service, docker compose profile, or the polling command printed), and an optional first trigger for the repo you are sitting in. Every step shows what it will do, asks first, and can be declined. Nothing is written into your repo and no credential passes through a dialog.

Re running setup is also the upgrade path: when a deployment's runtime falls behind the console's pin, one notice per process points you back at /dispatch setup. A deployment whose queue is merely down keeps the unreachable banner instead, because setup belongs where there is nothing, never over an outage.

Fixed: service units were broken for every npm install

pi-dispatch service install rendered units whose paths pointed at nothing whenever the package came from npm. The renderer derived a "repo root" two directories above its own module, which in an npm layout is the @edgehero scope directory, so ExecStart, EnvironmentFile, the log paths and the wrapper path were all wrong. Tests passed because they injected a correct root, and no npm layout fixture existed.

Units now anchor on your deployment folder for state (WorkingDirectory, .env, logs) and on the installed package for code, so the same command is correct from a checkout and from an npm install. npm layout fixtures now exist, so the seam that hid this cannot hide it again.

If you installed a service on 0.1.1, re run pi-dispatch service install --force.

Forge only deployments can boot the receiver

GitHub was the one unconditional arm: the receiver resolved a GitHub identity and required WEBHOOK_SECRET on every boot, while GitLab, Forgejo and Azure were already gated on your triggers file naming them. A GitLab only deployment could not start without a gh login it never uses and a secret it never verifies, and all three forge docs described a setup that stops at that wall.

One value now gates the secret, the identity boot gate and the / route together. An unconfigured forge answers 404, not 401, because an endpoint that answers is an endpoint you can believe is armed. Forge only deployments carrying a dummy WEBHOOK_SECRET purely to boot can drop it.

Azure work item triggers fire past page one

The Graph has no lookup by email endpoint, so the work item path fetches the organization's user list and filters locally. It read exactly one page, so an actor further down was a determinate 204 refusal, indistinguishable from a stranger being correctly refused, in every organization big enough to matter. The walk now follows the continuation token, bounded at 20 pages, and reaching the bound reports indeterminate rather than unauthorized: 503, and Azure redelivers. An actor genuinely absent from a list that ends is still 204.

Sessions fail closed instead of quietly doing nothing

An armed "resume": true under a deployment with no PI_SESSIONS_DIR used to run, persist nothing, and exit 0. Four documents promised a refusal there, including SECURITY.md and doctor's own fix text, and no code performed one, so green runs taught you the feature was on while it was off. It is now refused as sessions-dir-unset before the token mint, the clone and the budget reservation, with a comment naming both ways out.

"resume": true on a cron trigger is refused when the file loads, since the session store reaches only the forge preparers, so an armed local job staged nothing and exited 0 as though it had. It is worded "not yet covered" rather than impossible, because the local key already exists and nothing reaches it.

Two smaller fixes

  • doctor warns when a scaffolded pause-windows.json is never read. init scaffolds it and the panel writes windows to it, but the worker reads only PI_PAUSE_WINDOWS_FILE, so you could add a window, see it listed, and watch every job run straight through it.
  • Dockerfile.azure defaults to an image that exists. It pointed at a name this project has never published, so the documented build failed on the pull unless you passed --build-arg.

pi compatibility is strategy now, not luck

The peer range widens to "*", which is what pi's own packaging docs prescribe for host provided packages, so plain npm consumers stop hitting ERESOLVE. A runtime advisory names an untested pi version on your first /dispatch of a session, and it is never a refusal: the capability probe stays the only hard gate. A weekly canary installs the latest pi into a scratch directory (never the repo root, so the pinned assertions keep asserting the pin) and fails CI when any API member or type the console uses disappears.

Images carry a version tag

ghcr.io/edgehero/pi-job:0.8.0 and ghcr.io/edgehero/pi-dispatch-receiver:0.8.0 now publish alongside latest, so a deployment or a derived image can pin a tag that never moves.

Docs

Triggers lead both READMEs now, ahead of the architecture, the overlay and the panel, because that is what starts a job. New docs/workflows.md answers what a workflow is here, how a staged pi extension reaches a job, how one actually gets triggered inside a non interactive container, and where its state survives (a cron job keeps it, a forge job does not).

The audit behind this release read every docs file against the implementation and fixed about sixty defects. Four mattered because the docs promised protections the code did not deliver: SECURITY.md's CI integrity claim, which does not hold under the shipped default gh auth; "non root" attributed to the worker's docker run argv when it is a property of the image; "every write pops a confirmation" when three tools have none; and the session refusal above, specified and never implemented.

Packages

@edgehero/pi-dispatch 0.1.2, @edgehero/pi-dispatch-receiver 0.1.1, @edgehero/pi-dispatch-admin 0.5.0.