4 Commits
Author SHA1 Message Date
Juan DenisandClaude Opus 5 35ddc7494b fix(agent): vendor the installers from the agent repo, and fail CI on drift
scripts/install.sh and scripts/install.ps1 are now VENDORED copies. The agent
repo owns them; this repo carries a copy only because the panel serves them off
its own disk at GET /api/v1/servers/install.sh|.ps1 and cannot link to another
repository.

Two copies of one file is what caused the second half of #101. When the agent
moved out of this monorepo it took its installer with it, and from then on there
were two -- actually four: the agent repo also carried a third, older pair under
its own scripts/ that nothing referenced. Each looked fine in isolation, nothing
ever compared them, and the panel went on serving one that downloaded from
`agent-v*` tags which exist in no repository. Unit tests are structurally blind
to this: they exercise whichever copy lives in their own repo and have no idea
another exists.

So:

  scripts/sync-agent-installers.sh     re-vendors from the agent repo (a sibling
                                       checkout if present, else the published
                                       branch), normalising to LF so this repo's
                                       .gitattributes can apply its own EOL rule
  scripts/test/check-installer-drift.sh fails, with the diff and the fix, if a
                                       vendored copy differs from canonical
                                       (EOL-insensitive: *.ps1 is checked out
                                       CRLF here and LF there, which is not drift)

The drift check runs nightly alongside the release-chain verification, since
both need to reach GitHub. Both scripts run locally against a sibling checkout,
so this works offline and before an agent change is published.

Both installers carry a provenance header naming the canonical location, so
anyone who opens the vendored copy to patch it is told where to patch instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 11:36:29 -04:00
Juan DenisandClaude Opus 5 4f12f8164d ci: boot the built image, and check the agent download URLs resolve
Issue #101 shipped because release.yml went straight from `build` to `push`
with nothing in between. The image was missing scripts/, so every containerised
panel 404'd its own enrollment URL, while the entire test suite stayed green --
pytest runs against the source tree, where the file always exists. Only booting
the artifact catches that class of bug.

scripts/test/smoke-docker-image.sh builds (or takes) an image, asserts the files
the panel reads at request time are present, boots it, and requests every route
that serves a file off disk. release.yml now builds amd64, runs it, and only
then pushes multi-arch (layers are cached, so the push reuses the build).
release-smoke.yml gets the same job on dev and PRs, and its path filters now
include Dockerfile, .dockerignore and scripts/ -- none of which used to trigger
it.

scripts/test/verify-agent-release-chain.sh covers the other half, which unit
tests structurally cannot: they stub curl, so they only ever prove the installer
is self-consistent, never that the URL it builds resolves to a real file. This
one reads the coordinates back out of the script, asks GitHub, downloads the
archive, verifies the checksum and confirms the tarball entry name the installer
moves. It runs nightly, and is also the tripwire for the reverse case -- the
agent repo changing its release naming and breaking the panel from the other
side of the repo split.

Both are plain scripts so the same check runs locally:
  bash scripts/test/smoke-docker-image.sh
  bash scripts/test/verify-agent-release-chain.sh

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 05:27:38 -04:00
Juan DenisandClaude Opus 4.8 ca354e228a harden(installer): raise Node floor to 20.19+/22.12+ for vite 8 + fix update.sh @BIND_HOST@
The vite 8 upgrade (dcf05d1) makes the frontend build require Node ^20.19.0 ||
>=22.12.0 — on anything older npm silently skips rolldown's native binary and
`npm run build` dies with a cryptic MODULE_NOT_FOUND. Servers that build the SPA
on-box (source install + every update) would break their next update. So:

- install.sh node_ready() now gates on the real vite 8 floor (was Node >=18) and
  provisions NodeSource 22 LTS when the host Node is too old.
- update.sh gains _node_build_ok(): build_frontend_bundle refuses (returns 1 →
  caller rolls back) and the Docker-host rebuild halts, both with an actionable
  "upgrade Node" message instead of a rolldown stack trace.
- Dockerfile + CI (release, release-smoke, extensions, scripts-nightly) bumped
  node 20 -> 22 so the shipped/pre-built bundle is built on a compatible Node.

Also fixes a pre-existing parity bug the operator caught: update.sh rendered the
systemd unit WITHOUT substituting @BIND_HOST@ (install.sh does), so an update
left the literal placeholder and gunicorn would fail to bind. update.sh now
substitutes it (loopback default, SERVERKIT_BIND_HOST override) like install.sh.

Tests: test_update.sh +3 (node-floor gate, build refusal on old Node,
@BIND_HOST@ substitution) — 48 passed / 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 20:17:48 -04:00
Juan DenisandClaude Fable 5 4874fa9161 ci(scripts): real install+update e2e gate, nightly tarball/from-release runs
The July 2 outage lived in update.sh's top-level run block — code the
unit matrix never executes. Close the blind spot:

- update-e2e (PR-gated): real install.sh on the runner VM, health
  probe, then THIS branch's update.sh --force with self-update
  disabled, re-probe; failure dumps /var/log/serverkit + journal
- scripts-nightly.yml: install from the built release tarball (proves
  the offline path + shipped-venv relocation), and install latest
  published release -> update to current checkout (carry-forward
  regressions same-version --force runs can't catch)
- advisory (non-gating) shellcheck --enable=all on install.sh/update.sh
- unit steps now also run test_cli.sh + test_agent_install.sh in both
  the ubuntu job and the 7-distro matrix

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 18:42:57 -04:00