From f721b689a3c04d9e7cc8471a0836afb79c0affe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20GS=20Pereira?= Date: Wed, 2 Sep 2026 08:51:46 -0300 Subject: [PATCH 1/2] chore(release): bring the version fields back into agreement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit APP_VERSION and package.json read 4.2.12 while package-lock.json was left at 4.2.10; on the editor, release/app/package.json sat at 4.2.2 and its lockfile at 4.1.4. The release procedure bumps the first two by hand and nothing bumps or checks the rest. No release ever shipped wrong: release.yml takes the version from the tag and runs `npm version` at the root and in release/app before packaging. A LOCAL editor package build did take release/app's stale value, because electron-builder reads that file — `directories.app` points at it — not the root one. CLAUDE.md said the opposite, so it is corrected here and now tells the reader to bump with `npm version`, which updates the lockfiles that hand edits miss. Version fields only. No dependency added, removed or upgraded. DOPE-601 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01RwPir1KyYzcqAeaaAvqPNb --- CLAUDE.md | 17 ++++++++++++----- package-lock.json | 4 ++-- release/app/package-lock.json | 4 ++-- release/app/package.json | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 3226b1aac..a63904952 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -290,11 +290,18 @@ The About modal renders it directly; the web build writes it into `version.json` **Bump `APP_VERSION` — never `package.json` alone.** Make the identical one-line edit in BOTH repos, and set `package.json.version` to the same value in both so they can't drift. Roles: `APP_VERSION` is what the user sees in the About dialog; -`package.json.version` is what electron-builder stamps on the desktop binary and -what the release tag `vX.Y.Z` must match. Bumping only `package.json` leaves the -About dialog stuck on the old version — **this mistake shipped 4.2.7 and 4.2.8 -with About still showing 4.2.6.** If the two ever disagree, `APP_VERSION` is -authoritative; fix it to match. +the release tag `vX.Y.Z` is what the release workflow builds from. Bumping only +`package.json` leaves the About dialog stuck on the old version — **this mistake +shipped 4.2.7 and 4.2.8 with About still showing 4.2.6.** If the two ever +disagree, `APP_VERSION` is authoritative; fix it to match. + +In the editor, electron-builder reads **`release/app/package.json`**, not the root +one — `electron-builder.json` sets `directories.app` to `release/app`. The release +workflow runs `npm version ` at the root AND in `release/app`, so a tagged +release is always correct; a LOCAL package build is not, and takes whatever +`release/app/package.json` happens to say. Use `npm version --no-git-tag-version +--allow-same-version` in both places rather than editing by hand: it updates each +lockfile too, which hand edits miss (see DOPE-601). Release order: bump `APP_VERSION` + `package.json` (both repos, same value) → PR to `development` → merge → promote `development`→`main` on both → tag `vX.Y.Z` on diff --git a/package-lock.json b/package-lock.json index 1aa2fe285..c73629142 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-plc-editor", - "version": "4.2.10", + "version": "4.2.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-plc-editor", - "version": "4.2.10", + "version": "4.2.12", "hasInstallScript": true, "license": "GPL-3.0", "dependencies": { diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 360c060af..8142018fc 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-plc-editor", - "version": "4.1.4", + "version": "4.2.12", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-plc-editor", - "version": "4.1.4", + "version": "4.2.12", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/release/app/package.json b/release/app/package.json index e2f51913f..de3513a0e 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "open-plc-editor", - "version": "4.2.2", + "version": "4.2.12", "description": "OpenPLC Editor - IDE capable of creating programs for the OpenPLC Runtime", "license": "MIT", "author": { From a90bafeed19fa8c940f27cf605d932856eb3436c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20GS=20Pereira?= Date: Wed, 2 Sep 2026 11:29:14 -0300 Subject: [PATCH 2/2] docs(release): restate the tag invariant and fix the source-of-truth comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review on #724 / #1074. The earlier correction paired `APP_VERSION` with the git tag and kept "if the two ever disagree, fix it to match" — which has no actionable subject, since a pushed tag cannot be fixed. Worse, it dropped a real invariant: `release.yml` stamps the binary from the tag while About renders `APP_VERSION`, so tagging v4.3.0 against APP_VERSION 4.2.12 ships an installer labelled 4.3.0 whose About says 4.2.12 — the 4.2.7 / 4.2.8 failure wearing a different hat. The roles sentence goes back to naming `APP_VERSION` and `package.json.version`, and the tag invariant is stated on its own, with the warning that it must be checked before tagging. "A tagged release is always correct" also overstated it. `release.yml` resolves the version as dispatch input, then tag, then root `package.json` — so a `workflow_dispatch` with an empty input stamps whatever the repo happens to say, the exact drift this branch repaired. Scoped to tag-triggered runs, with both exceptions named. `app-version.ts` carried the same wrong claim this branch set out to correct — "the editor's electron-builder reads `package.json.version`" — in the file a developer actually opens to bump the version, and it is byte-identical shared surface, so leaving it meant another coordinated mirror PR later. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_011JAMx8mRf2ig4YFfs2gmsM --- CLAUDE.md | 22 +++++++++++++++------- src/frontend/data/constants/app-version.ts | 6 ++++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a63904952..4c592a45d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -290,16 +290,24 @@ The About modal renders it directly; the web build writes it into `version.json` **Bump `APP_VERSION` — never `package.json` alone.** Make the identical one-line edit in BOTH repos, and set `package.json.version` to the same value in both so they can't drift. Roles: `APP_VERSION` is what the user sees in the About dialog; -the release tag `vX.Y.Z` is what the release workflow builds from. Bumping only -`package.json` leaves the About dialog stuck on the old version — **this mistake -shipped 4.2.7 and 4.2.8 with About still showing 4.2.6.** If the two ever -disagree, `APP_VERSION` is authoritative; fix it to match. +`package.json.version` is what a local build stamps. Bumping only `package.json` +leaves the About dialog stuck on the old version — **this mistake shipped 4.2.7 +and 4.2.8 with About still showing 4.2.6.** If those two disagree, `APP_VERSION` +is authoritative; fix `package.json` to match. + +**The release tag must equal `APP_VERSION` too.** `release.yml` stamps the binary +from the tag while About renders `APP_VERSION`, so tagging `v4.3.0` while +`APP_VERSION` is 4.2.12 ships an installer named 4.3.0 whose About dialog says +4.2.12 — the same failure in a different disguise. Check before tagging: a pushed +tag cannot be "fixed to match". In the editor, electron-builder reads **`release/app/package.json`**, not the root one — `electron-builder.json` sets `directories.app` to `release/app`. The release -workflow runs `npm version ` at the root AND in `release/app`, so a tagged -release is always correct; a LOCAL package build is not, and takes whatever -`release/app/package.json` happens to say. Use `npm version --no-git-tag-version +workflow runs `npm version ` at the root AND in `release/app`, so a +*tag-triggered* release is always correct. Two cases are not: a LOCAL package +build takes whatever `release/app/package.json` says, and a `workflow_dispatch` +run with an empty `version` input falls back to root `package.json` +(`release.yml`, version resolution). Use `npm version --no-git-tag-version --allow-same-version` in both places rather than editing by hand: it updates each lockfile too, which hand edits miss (see DOPE-601). diff --git a/src/frontend/data/constants/app-version.ts b/src/frontend/data/constants/app-version.ts index f3ea7e622..72743d747 100644 --- a/src/frontend/data/constants/app-version.ts +++ b/src/frontend/data/constants/app-version.ts @@ -11,8 +11,10 @@ * Consumers: * - the About modal renders this directly (both apps); * - the web build writes it into `version.json` (`version` field); - * - the editor's electron-builder reads `package.json.version`, kept equal - * to this value by `release.yml`. + * - the editor's electron-builder reads `release/app/package.json` + * (`electron-builder.json` sets `directories.app`), which `release.yml` + * keeps equal to the tag — NOT this constant. Keep the tag equal to this + * value, or the installer and the About dialog disagree. * * NOTE: this is the human-facing semver only. The web "force update" check * compares a per-deploy `BUILD_ID` (git commit SHA), not this version, so a