Skip to content

fix(release): ship the installer's companions so 1.2.0 installs and upgrades from 1.1.0 - #3

Merged
iitzSeriZdev merged 2 commits into
mainfrom
claude/fix-release-packaging
Sep 24, 2026
Merged

iitzSeriZdev merged 2 commits into
mainfrom
claude/fix-release-packaging

Conversation

@iitzSeriZdev

Copy link
Copy Markdown
Owner

What this changes

Fixes the release blocker found while preparing 1.2.0 (flagged in #2). A release built from main could not be installed or upgraded to.

The bug. installer/lib/row-template.sh loads lib/transaction.sh and panels/ at start-up and aborted without them. tools/make-release.sh shipped only the library.

  • Fresh install: install.sh loads the payload's library and stopped with FAIL panel interface missing.
  • Upgrade from 1.1.0: row-template update runs the installed 1.1.0 code. Its updater copies only template.html, VERSION, lib/row-template.sh and bin/row-template. After that, every row-template command died. No release can change what that updater copies, so the new library has to cope with the files being absent.

The fix. Installer and release code only (installer/lib/row-template.sh, tools/make-release.sh); nothing else is redesigned.

  • Packaging: the library declares its companions in RT_INSTALLER_COMPANIONS. make-release.sh reads that line and ships the files under lib/ and panels/, covered by the payload's SHA256SUMS.
  • Install and update: the companions are installed atomically next to the library. The library and its companions are treated as one unit:
    • a payload that has the library but is missing a companion, or has one that fails its checksum, is refused before anything changes;
    • the list comes from the payload's own library, so updating to the v1.1.0 release (a deliberate downgrade), whose library declares none, still works;
    • each declared path must be a plain .sh file directly in lib/ or panels/, and the list is never glob-expanded.
  • Loading: a missing companion is now treated differently from a broken one.
    • Missing (what the 1.1.0 updater leaves): the library loads without that layer, and rt_installer_complete reports the gap. No command uses either layer today.
    • Present but fails to load: still aborts at start-up, as before.
  • Completing the upgrade:
    • row-template update always re-applies the latest release, so running it once more installs the design store and the companions.
    • verify now warns "installer components are missing … run 'row-template update' to complete the installation", and its missing-store failure names the same fix.
    • The manager's update menu no longer calls an incomplete install "up to date": it offers the re-install and defaults to yes.
  • Unchanged: uninstall (it already removes the whole install root), legacy backup and rollback, install.sh, bin/row-template, and every existing test.

What an operator on 1.1.0 experiences

  1. row-template update. The 1.1.0 updater installs 1.2.0; the page updates and branding is kept, but only Row is available.
  2. row-template update again. This time the 1.2.0 code completes the install: all 15 designs and the installer components.

row-template verify shows whether step 2 is still needed. The release notes and CHANGELOG should say this; I'll add it to #2.

How it was checked

  • npm test: 651/651 pass (12 new) in a fresh clone
  • npm run verify passes
  • npm run lint:sh: 10 scripts clean. The warning count is unchanged from main (6).
  • installer-backup-reader 28/28, installer-transaction 49/49
  • Fresh install, using the real tarball from make-release.sh: extract it and load the payload's own library, exactly as install.sh does, then run rt_cmd_install. Result: companions, all 15 designs, branding, a clean verify, and the installed CLI runs.
  • Upgrade from v1.1.0, driven by the actual v1.1.0 updater. tests/fixtures/installer-1.1.0/row-template.sh is the tagged v1.1.0 library byte for byte, with its sha256 pinned by the test. It installs 1.1.0 and then runs its rt_cmd_update against the real release. After that the CLI runs, verify reports the install incomplete, and both row-template update and the manager's update menu complete it, with branding kept throughout.
  • Unit tests: missing versus broken companions; refusal before any change; checksum mismatch; the v1.1.0 payload is still accepted; hostile path declarations are refused.
  • Against the unfixed code: all 5 new release tests fail, as do 6 of the 7 installer tests. The seventh guards behaviour that must not change: a broken companion still stops the load.
  • Safety: the panel is stubbed (detected, no database, service calls do nothing), so no test can touch a real 3X-UI. install.sh itself isn't run because it requires root. Everything after its root check is exercised.

Before you submit

🤖 Generated with Claude Code

https://claude.ai/code/session_011QC3E9ChkFK7sDFBTfwNJ3


Generated by Claude Code

…dater

A release built from main could not be installed or upgraded to.
installer/lib/row-template.sh sources lib/transaction.sh and panels/ at
load time and aborted without them, but tools/make-release.sh shipped
only the library:

- Fresh install: install.sh sources $PAYLOAD/lib/row-template.sh, which
  stopped with "FAIL panel interface missing".
- Upgrade from 1.1.0: `row-template update` runs the INSTALLED 1.1.0
  library, whose updater copies only template.html, VERSION,
  lib/row-template.sh and bin/row-template. Afterwards every
  row-template command died loading the new library. No release can
  change what that updater copies.

Packaging
- The library declares its companions in RT_INSTALLER_COMPANIONS, and
  make-release.sh reads that line, so packaging cannot drift from what
  the installer loads. They ship under lib/ and panels/ and are covered
  by the payload's inner SHA256SUMS.

Install and update
- The library and its companions are one unit. rt_payload_companions
  reads the list from the PAYLOAD's own library, so the v1.1.0 payload,
  whose library declares none, still installs (a deliberate downgrade
  keeps working). Each declared path must be a plain .sh file directly
  in lib/ or panels/; the line is split with read, never glob-expanded.
- A payload with a library but a missing or checksum-mismatched
  companion is refused before anything changes.
- rt_cmd_install and rt_cmd_update install the companions atomically
  next to the library. A payload without a library (as before) leaves
  the installed set alone.

Loading
- ABSENT is not BROKEN. A missing panels/ or transaction.sh (the state
  the 1.1.0 updater leaves) now loads without that layer: the loader
  returns 2 and rt_installer_complete reports the gap. No command calls
  either layer, and a future caller must check rt_installer_complete
  first. A layer that is present but will not load still aborts at
  source time, as before.

Completing an upgrade
- `row-template update` always re-applies the latest release, so
  running it once more installs the design store and the companions.
- `verify` warns "installer components are missing ... run
  'row-template update' to complete the installation", and its
  missing-store failure now names the same remedy.
- The manager's update menu no longer calls an incomplete install "up
  to date"; it offers the re-install and defaults to yes.

Uninstall already removes the whole install root, so panels/ goes with
it. Legacy backup and rollback are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QC3E9ChkFK7sDFBTfwNJ3
tests/release.test.mjs, against the real tarball from make-release.sh:
- the payload ships the library with every companion, byte-identical
  and in SHA256SUMS, the declared list equals the files on disk, and
  the packaged library loads both layers from the extracted payload;
- a fresh install from the extracted payload, sourcing the payload's
  own library as install.sh does, leaves a complete, working manager
  (companions, all designs, branding, `verify`, the installed CLI);
- the upgrade from v1.1.0: install with the v1.1.0 library, then run
  ITS rt_cmd_update against the release directory. The CLI still runs,
  `verify` reports the install incomplete and names the remedy, and
  both `row-template update` and the manager's update menu complete it,
  with branding kept throughout.

The v1.1.0 updater is the real one: tests/fixtures/installer-1.1.0 is
installer/lib/row-template.sh from tag v1.1.0, byte for byte (sha256
pinned by the test), vendored so the suite runs without git history.

tests/installer.test.mjs pins the rules underneath:
- the library loads with companions absent and says so; a companion
  that is present but broken still stops it from loading;
- install and update refuse a library without its companions, or a
  companion that fails its checksum, before changing anything;
- a payload whose own library declares no companions (v1.1.0) is still
  accepted;
- a declaration may name only plain files in lib/ or panels/.

The panel stays stubbed (detected, no database, service no-ops), so no
test can reach a real 3X-UI. Run against the unfixed code, every new
test fails except the broken-companion guard, which pins behaviour that
must not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QC3E9ChkFK7sDFBTfwNJ3
iitzSeriZdev pushed a commit that referenced this pull request Sep 24, 2026
Follows #3, which ships lib/transaction.sh and
panels/ in the release and lets an install that 1.1.0's updater left
incomplete be completed:

- CHANGELOG 1.2.0, Compatibility: updating from 1.1.0 takes two runs of
  `row-template update`. The first is 1.1.0's own updater, which copies
  only the library and the command; the second, by 1.2.0, installs every
  design and the remaining installer files. `verify` reports whether the
  second run is needed. (This statement was held back until it could be
  verified; #3's upgrade test drives exactly this path with the real
  v1.1.0 updater.)
- CHANGELOG 1.2.0, Internal: the release ships the companions, and an
  incomplete payload is refused.
- PROVENANCE.md: the payload table gains panels/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011QC3E9ChkFK7sDFBTfwNJ3
@iitzSeriZdev
iitzSeriZdev merged commit 8f7c140 into main Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants