The installer needs CI that reacts when a component publishes a release. Adds
that as section 7, folded into version tracking because the bundle IS the compat
matrix -- which closes the "where does the compat matrix live" gap section 7
previously left open.
- 7.1 Bundle manifest: CI publishes an exact, protocol-checked combination of
component versions; the installer resolves against it at run time and
--bundle <tag> pins one. A link release regenerates JSON and leaves the
installer binary untouched, so operators don't re-download the installer for a
sidecar patch and the repo doesn't accumulate releases with identical code.
Two compose-time gates: sidecar PROTOCOL_VERSION must equal the overlay
manifest's declared version, and every asset's SHA256 must match.
- 7.2 Triggers: each component's release job POSTs to the installer's
workflow-dispatch endpoint (link's release.yml already declares
workflow_dispatch and already holds a write:repository token), plus a nightly
cron so a missed dispatch self-heals. repository_dispatch avoided -- support
is uncertain on this Gitea version.
- 7.3 Stale overlay: dispatch, don't wait. Components self-release on merge to
their own main, so the release normally already exists. If main is ahead with
*releasable* commits (docs:/chore: correctly cut nothing), fire that repo's
workflow, compose from what exists now, warn loudly, and let the nightly fold
in the result. Dispatching another repo's workflow is fine -- it still runs
its own gates -- but polling it is not, since Gitea's dispatch endpoint
returns no run handle.
Bundle CI becomes a Phase 0 deliverable, since Phase 1 resolves what to install
from the bundle. `update` now moves between checked combinations rather than two
independently-latest artifacts.
Co-Authored-By: Claude <noreply@anthropic.com>
Design of record for a deployment tool that takes a stock ServUO install and
configures it for Runic Gateway. Supersedes the informal overview it grew from,
which described a ServUO integration that does not match how servuo-plugins
actually ships.
Corrections that change the design:
- There is no RunicGateway.dll and no Plugins/ dir. The plugin ships as C#
source compiled by ServUO at boot, so the step is a hash-compare sync of
overlay/ -- but a successful copy does not mean a working bridge, because
ScriptCompiler.Compile() ignores dotnet build's exit code and reloads the
stale Scripts.dll.
- Stock ServUO files ARE modified, by three diffs in patches/. Made an opt-in,
skippable tier: git apply against a hand-modified shard will fail, and the
EventSink.cs patch needs a full core solution rebuild.
- Config paths collided with what the sidecar actually reads. Split ownership:
sidecar.toml stays the sidecar's schema, install.json is the installer's.
Service definitions pin UOLINK_CONFIG and UOLINK_DB_PATH, since the sidecar
writes relative to CWD and would land in VirtualStore under Program Files.
- The token handoff was missing entirely -- the largest "installed it and
nothing happened" failure mode.
- deploy.ps1 cannot be the cross-platform deployer; it stays the developer tool.
Decisions: public audience, unsigned binaries anchored on SHA256SUMS, Rust,
release-tarball plugin distribution, printed token handoff, new installer repo,
warn-and-skip on non-57.4 ServUO, and an uninstall that never edits the shard
tree -- it prints the files to delete and the hunks to revert.
Phases 0-5, with Phase 0 (a release workflow for servuo-plugins, which has
none today) gating everything else. Two open questions remain in section 8.
Co-Authored-By: Claude <noreply@anthropic.com>