Skip to content

Commit 796281e

Browse files
committed
chore(release): 0.8.0, and give both images a tag that does not move
main has been carrying two unreleased batches: the default-route work from issue #96 (including the fix for service units that were broken under every npm deployment) and the six code defects from issue #99. The published versions matched the repo exactly, so release.yml has been running green and skipping every publish. This bumps all four so a merge actually ships. root 0.7.0 -> 0.8.0 cuts the v0.8.0 product release (repo-release.yml) worker 0.1.1 -> 0.1.2 the sessions gate, the cron refusal, doctor's warning receiver 0.1.0 -> 0.1.1 conditional GitHub arm, Azure Graph pagination admin 0.4.0 -> 0.5.0 the wizard becomes the default route The two literals in setup-wizard.ts move with them, which is what the anti-drift tests exist to force: the wizard installs a PINNED runtime and a PINNED receiver, so a bump that missed them would print an install command for a version that no longer matches the console. Two tests spell the receiver pin out on purpose rather than interpolating it, so both were updated by hand; that is the pin being visible working as designed, not a maintenance tax to remove. Docker gets the part it was missing. Both images were tagged `latest` and the git sha and nothing else, so there was no such thing as releasing a version of them: an operator could either track a moving tag or copy a sha. Both workflows now also tag the PRODUCT version from the root package.json, and both rebuild when that version changes, so v0.8.0 publishes ghcr.io/edgehero/pi-job:0.8.0 and ghcr.io/edgehero/pi-dispatch-receiver:0.8.0 alongside latest. docs/job-image.md records the trade honestly: a pinned base is right for a derived image whose layer assumes something about it, and the cost is that a pin does not pick up a security rebuild. Signed-off-by: Rob Boerman <robboerman@live.nl>
1 parent 11373c1 commit 796281e

10 files changed

Lines changed: 37 additions & 13 deletions

File tree

.github/workflows/image.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
# No secret required: GHCR auth uses the built-in GITHUB_TOKEN (packages: write). One-time after the first
99
# successful run: make the ghcr.io/edgehero/pi-job package Public in the org's package settings, otherwise
1010
# `docker pull` needs auth.
11+
#
12+
# Tags: `latest`, the git `sha`, and the PRODUCT version from the root package.json (so a release cuts a
13+
# tag that never moves, and a deployment can pin `ghcr.io/edgehero/pi-job:<version>` instead of tracking latest).
1114

1215
name: image
1316

@@ -16,6 +19,7 @@ on:
1619
branches: [main]
1720
paths:
1821
- "image/**"
22+
- "package.json" # the ROOT one: a product version bump republishes under its own tag
1923
- ".github/workflows/image.yml"
2024
# Manual re-run (available once this file is on the default branch).
2125
workflow_dispatch: {}
@@ -46,13 +50,18 @@ jobs:
4650
username: ${{ github.actor }}
4751
password: ${{ secrets.GITHUB_TOKEN }}
4852

53+
- name: Resolve the product version (the tag operators can pin)
54+
id: v
55+
run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
56+
4957
- name: Tags + labels
5058
id: meta
5159
uses: docker/metadata-action@v5
5260
with:
5361
images: ${{ env.IMAGE }}
5462
tags: |
5563
type=raw,value=latest
64+
type=raw,value=${{ steps.v.outputs.version }}
5665
type=sha
5766
5867
- name: Build + push (amd64 + arm64)

.github/workflows/receiver-image.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# No secret required: GHCR auth uses the built-in GITHUB_TOKEN (packages: write). One-time after the first
1111
# successful run: make the ghcr.io/edgehero/pi-dispatch-receiver package Public in the org's package
1212
# settings, otherwise `docker pull` needs auth.
13+
#
14+
# Tags: `latest`, the git `sha`, and the PRODUCT version from the root package.json (so a release cuts a
15+
# tag that never moves, and a deployment can pin `ghcr.io/edgehero/pi-dispatch-receiver:<version>` instead of tracking latest).
1316

1417
name: receiver-image
1518

@@ -21,6 +24,7 @@ on:
2124
- "worker/src/**"
2225
- "worker/package.json"
2326
- "package-lock.json"
27+
- "package.json" # the ROOT one: a product version bump republishes under its own tag
2428
- ".github/workflows/receiver-image.yml"
2529
# Manual re-run (available once this file is on the default branch).
2630
workflow_dispatch: {}
@@ -51,13 +55,18 @@ jobs:
5155
username: ${{ github.actor }}
5256
password: ${{ secrets.GITHUB_TOKEN }}
5357

58+
- name: Resolve the product version (the tag operators can pin)
59+
id: v
60+
run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"
61+
5462
- name: Tags + labels
5563
id: meta
5664
uses: docker/metadata-action@v5
5765
with:
5866
images: ${{ env.IMAGE }}
5967
tags: |
6068
type=raw,value=latest
69+
type=raw,value=${{ steps.v.outputs.version }}
6170
type=sha
6271
6372
- name: Build + push (amd64 + arm64)

admin/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@edgehero/pi-dispatch-admin",
3-
"version": "0.4.0",
3+
"version": "0.5.0",
44
"description": "Operator console (a pi extension) + skill for pi-dispatch: run the pi coding agent as a self-hosted service. A /dispatch TUI for the queue, spend caps, run history, editable GitHub, GitLab, Forgejo and Azure DevOps triggers (cron/label/comment/PR/MR/work item), and scheduled pause windows — plus AI-operable, human-confirmed controls. Runs against a live pi-dispatch deployment.",
55
"keywords": [
66
"pi-package",

admin/src/setup-wizard.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ type Notify = ((message: string, type?: string) => void) | undefined;
5252
* version, so a release bump stays atomic: bump the worker and the test fails here until this literal
5353
* follows in the same change.
5454
*/
55-
export const RUNTIME_VERSION = "0.1.1";
55+
export const RUNTIME_VERSION = "0.1.2";
5656

5757
/**
5858
* The `@edgehero/pi-dispatch-receiver` version the trigger-edge step installs -- pinned for exactly the
@@ -62,7 +62,7 @@ export const RUNTIME_VERSION = "0.1.1";
6262
* independently (the receiver's dependency range on the runtime is `^`), and pretending otherwise would
6363
* install a version that does not exist the first time they diverge.
6464
*/
65-
export const RECEIVER_VERSION = "0.1.0";
65+
export const RECEIVER_VERSION = "0.1.1";
6666

6767
/** The two npm package names, spelled once. Literals of this module -- see npmInstallArgsFor's argument. */
6868
const RUNTIME_PKG = "@edgehero/pi-dispatch";

admin/test/setup-wizard.test.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ test("wizard: the edge's service answer installs the PINNED receiver, then the -
803803
assert.equal(attached.length, 2, "the npm install and the unit install — nothing else");
804804
assert.equal(attached[0].argv0, "npm", "posix npm, per npmSpawnOptions");
805805
assert.deepEqual(attached[0].args, mod.npmInstallArgsFor(RECEIVER_PKG, mod.RECEIVER_VERSION));
806-
assert.ok(attached[0].args.includes(`${RECEIVER_PKG}@0.1.0`), "the pinned name@version token, spelled out");
806+
assert.ok(attached[0].args.includes(`${RECEIVER_PKG}@0.1.1`), "the pinned name@version token, spelled out");
807807
assert.equal(attached[0].cwd, dir, "installed into the deployment dir, by cwd");
808808
assert.deepEqual(
809809
JSON.parse(readFileSync(join(dir, "package.json"), "utf8")),
@@ -817,7 +817,7 @@ test("wizard: the edge's service answer installs the PINNED receiver, then the -
817817
assert.equal(attached[1].cwd, dir);
818818

819819
const c = seen.confirm.find((x) => /receiver/i.test(x.title));
820-
assert.match(c.message, new RegExp(`${RECEIVER_PKG.replace("/", "\\/")}@0\\.1\\.0`), "the confirm shows the exact pin");
820+
assert.match(c.message, new RegExp(`${RECEIVER_PKG.replace("/", "\\/")}@0\\.1\\.1`), "the confirm shows the exact pin");
821821
assert.match(c.message, /service install --receiver/, "and the unit command it will run after");
822822
assert.ok(c.message.includes(dir), "and names the cwd");
823823
assert.ok(reachedFirstTrigger(seen), "the wizard continued to step 11");

docs/job-image.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ a second thing to forget to bump. Re-declare only a label whose truth your layer
3636
single re-declared `dev.pi-dispatch.forges` with `azure` appended (see
3737
[azure-devops.md](azure-devops.md), which also names the `--build-arg BASE=…` you need).
3838

39+
**Pin the base if you would rather not track `latest`.** Every published build also carries the **product
40+
version** as a tag (`ghcr.io/edgehero/pi-job:0.8.0`) and the git `sha`, and neither ever moves, while
41+
`latest` follows `main`. The receiver image is tagged the same way. A pinned base is the honest choice for a
42+
derived image whose layer assumes something about the base; the cost is that a pin does not pick up a
43+
security rebuild, so bump it deliberately.
44+
3945
**Copy `image/Dockerfile` and add to it.** You inherit every property in the checklist below for free, and
4046
the only thing you own is your own `RUN apt-get install …` layer. Prefer this over the layer above only when
4147
you need to change something *inside* the base build (a different base distro, a different pi pin).

package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pi-dispatch",
3-
"version": "0.7.0",
3+
"version": "0.8.0",
44
"private": true,
55
"description": "A containerized job harness for the pi coding agent",
66
"license": "MIT",

receiver/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@edgehero/pi-dispatch-receiver",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"type": "module",
55
"description": "Webhook receiver for pi-dispatch: the always-on edge that verifies GitHub, GitLab, Forgejo and Azure DevOps deliveries and enqueues (at most) one job per event for the worker.",
66
"keywords": [

worker/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@edgehero/pi-dispatch",
3-
"version": "0.1.1",
3+
"version": "0.1.2",
44
"type": "module",
55
"description": "Self-hosted job harness for the pi coding agent: a BullMQ worker that drains the queue, mints scoped forge tokens, and runs one container per job — plus the pi-dispatch CLI (init, up, doctor, service).",
66
"keywords": [

0 commit comments

Comments
 (0)