demo: keep the demo rig's uMod plugins current (auto-update between wipes) #235

Open
opened 2026-11-01 01:45:29 -06:00 by wtclaude · 1 comment
Member

Plan approved by the org lead 2026-11-01. Not built yet. The demo rig keeps its uMod plugins at umod.org's current release. An update released between wipes lands at the next wipe.

What is there now (checked 2026-11-01, read-only)

  • The demo rig (rust-oxide, 6eb9d621) has 21 plugins in oxide/plugins.
    • Five are ours and arrive with the bundle: RunicGateway, RunicGatewayZones, RunicGatewayRaids, RunicGatewayDomes and RunicNPC.
    • Sixteen are third-party: ZoneManager, ZoneDomes, ZLevelsRemastered, TruePVE, RaidableBases, PopupNotifications, NpcSpawn, Kits, GuardedCrate, Economics, DynamicPVP, DangerousTreasures, CopyPaste, BetterChat, Backpacks and AutoDoors.
    • umod.org answered 404 for NpcSpawn, so it is not a uMod plugin. The others were rate-limited before they answered.
  • demo-wipe.yml runs every 2 h.
    • rig.mjs plan compares the bundle with state/bundle.json on the host.
    • restore writes the bundle's plugins while the rig is stopped.
    • The baseline restores only oxide/data, oxide/config and the save, so oxide/plugins survives every wipe.
  • umod.org's API: https://umod.org/plugins/<slug>.json gives latest_release_version, latest_release_version_checksum, latest_release_at and download_url. Kits answered 4.4.10, released 2026-09-27.
  • umod.org rate-limits hard. It sends x-ratelimit-limit: 1 and a Retry-After of about 60 s. A burst of 16 requests got 429 for all but one, and a request 65 s later was still refused. The CI treats umod.org as scarce.

Decisions (2026-11-01)

  1. Cadence: every 6 hours. A separate scheduled workflow runs at 01:00, 07:00, 13:00 and 19:00 UTC, away from the even-hour wipes.
  2. A bad update: roll back, pin, open an issue. The smoke check after a wipe looks for Loaded plugin <Name> v<new> and for a compile error.
    • If the plugin did not load, the next step puts the last-good .cs back.
    • That version is marked skipped in the record. The next umod.org release is tried again.
    • A website issue names the plugin, the version and the error.
  3. Scope: discovered from the rig.
    • Every .cs in oxide/plugins is covered, except the bundle's files.
    • A 404 from umod.org marks a plugin onUmod: false. It stays listed and is never asked about or updated again (Codefling plugins, such as NpcSpawn).
    • A plugin added to the demo later is covered without a code change.

The build

  • The record: state/umod.json, on the demo host beside bundle.json. For each plugin it holds { slug, onUmod, version, checksum, releasedAt, checkedAt, applied, skipped }. Last-good copies are kept in state/umod/good/, and downloaded updates wait in state/umod/pending/.
  • node rig.mjs umod-check:
    • It lists the rig's plugins and asks umod.org about each one.
    • Requests are spaced and wait out any Retry-After.
    • It downloads a .cs only when the checksum differs from the record, then verifies the file against the checksum (if umod's checksum turns out to be of something else, the build says so).
    • A 429 or a network error changes nothing, and that plugin is asked again next pass.
    • It never fails a wipe, and it never touches the rig except to list files.
  • restore: while the rig is stopped, at the same point as the bundle, it writes each pending .cs and moves the old file to good/.
  • smoke: confirms each updated plugin loaded, or does the rollback described in decision 2.
  • Docs: docs/website/DEMO_MODE.md §7 gains this section. The demo README is updated.

Open for the build

  • Runner time. The record lives on the demo host, so the check runs on the demo-site runner. That runner is also the org's general CI runner, with capacity 1.
    • A 20-minute pass (15 plugins, one request every ~70 s) would hold that slot four times a day.
    • Proposed: check part of the list on each run. Example: 4 plugins per run, every 2 h, each run ~4 minutes. Each plugin is then still checked about every 8 h.
    • The org lead decides before the build.
  • Confirm which of the 15 are on umod.org. The first pass records it.

Found while working on runicnpc-rust#20, where the org lead added "uMod dependencies are updated before a test" to the workspace rules. That rule excludes the demo rig, which this issue covers instead.

**Plan approved by the org lead 2026-11-01. Not built yet.** The demo rig keeps its uMod plugins at umod.org's current release. An update released between wipes lands at the next wipe. ## What is there now (checked 2026-11-01, read-only) - The demo rig (`rust-oxide`, `6eb9d621`) has 21 plugins in `oxide/plugins`. - Five are ours and arrive with the bundle: RunicGateway, RunicGatewayZones, RunicGatewayRaids, RunicGatewayDomes and RunicNPC. - Sixteen are third-party: ZoneManager, ZoneDomes, ZLevelsRemastered, TruePVE, RaidableBases, PopupNotifications, NpcSpawn, Kits, GuardedCrate, Economics, DynamicPVP, DangerousTreasures, CopyPaste, BetterChat, Backpacks and AutoDoors. - umod.org answered 404 for NpcSpawn, so it is not a uMod plugin. The others were rate-limited before they answered. - `demo-wipe.yml` runs every 2 h. - `rig.mjs plan` compares the bundle with `state/bundle.json` on the host. - `restore` writes the bundle's plugins while the rig is stopped. - The baseline restores only `oxide/data`, `oxide/config` and the save, so `oxide/plugins` survives every wipe. - **umod.org's API:** `https://umod.org/plugins/<slug>.json` gives `latest_release_version`, `latest_release_version_checksum`, `latest_release_at` and `download_url`. Kits answered 4.4.10, released 2026-09-27. - **umod.org rate-limits hard.** It sends `x-ratelimit-limit: 1` and a `Retry-After` of about 60 s. A burst of 16 requests got 429 for all but one, and a request 65 s later was still refused. The CI treats umod.org as scarce. ## Decisions (2026-11-01) 1. **Cadence: every 6 hours.** A separate scheduled workflow runs at 01:00, 07:00, 13:00 and 19:00 UTC, away from the even-hour wipes. 2. **A bad update: roll back, pin, open an issue.** The smoke check after a wipe looks for `Loaded plugin <Name> v<new>` and for a compile error. - If the plugin did not load, the next step puts the last-good `.cs` back. - That version is marked skipped in the record. The next umod.org release is tried again. - A website issue names the plugin, the version and the error. 3. **Scope: discovered from the rig.** - Every `.cs` in `oxide/plugins` is covered, except the bundle's files. - A 404 from umod.org marks a plugin `onUmod: false`. It stays listed and is never asked about or updated again (Codefling plugins, such as NpcSpawn). - A plugin added to the demo later is covered without a code change. ## The build - **The record:** `state/umod.json`, on the demo host beside `bundle.json`. For each plugin it holds `{ slug, onUmod, version, checksum, releasedAt, checkedAt, applied, skipped }`. Last-good copies are kept in `state/umod/good/`, and downloaded updates wait in `state/umod/pending/`. - **`node rig.mjs umod-check`:** - It lists the rig's plugins and asks umod.org about each one. - Requests are spaced and wait out any `Retry-After`. - It downloads a `.cs` only when the checksum differs from the record, then verifies the file against the checksum (if umod's checksum turns out to be of something else, the build says so). - A 429 or a network error changes nothing, and that plugin is asked again next pass. - It never fails a wipe, and it never touches the rig except to list files. - **`restore`:** while the rig is stopped, at the same point as the bundle, it writes each pending `.cs` and moves the old file to `good/`. - **`smoke`:** confirms each updated plugin loaded, or does the rollback described in decision 2. - **Docs:** `docs/website/DEMO_MODE.md` §7 gains this section. The demo README is updated. ## Open for the build - **Runner time.** The record lives on the demo host, so the check runs on the `demo-site` runner. That runner is also the org's general CI runner, with capacity 1. - A 20-minute pass (15 plugins, one request every ~70 s) would hold that slot four times a day. - Proposed: check part of the list on each run. Example: 4 plugins per run, every 2 h, each run ~4 minutes. Each plugin is then still checked about every 8 h. - The org lead decides before the build. - Confirm which of the 15 are on umod.org. The first pass records it. Found while working on runicnpc-rust#20, where the org lead added "uMod dependencies are updated before a test" to the workspace rules. That rule excludes the demo rig, which this issue covers instead.
Author
Member

Decision 4, runner time (org lead, 2026-11-01): a rolling split. Each run checks 4 plugins, every 2 hours. The onUmod: true plugins are checked in a fixed rotation, oldest checkedAt first, so each one is asked about roughly every 8 hours. A run takes about 4 minutes on the demo-site runner. This replaces the 6-hourly full pass in decision 1.

  • The run is offset from the even-hour wipes (for example, at :30 on odd hours) so the two never queue behind each other.
  • On the first run, onUmod is not yet known. The rotation starts with the plugins that have no record, and the 404s (Codefling) fall out of the rotation as they are found.
  • A 429 ends the run early. The plugins it did not reach stay first in line for the next run.
**Decision 4, runner time (org lead, 2026-11-01): a rolling split.** Each run checks 4 plugins, every 2 hours. The `onUmod: true` plugins are checked in a fixed rotation, oldest `checkedAt` first, so each one is asked about roughly every 8 hours. A run takes about 4 minutes on the `demo-site` runner. This replaces the 6-hourly full pass in decision 1. - The run is offset from the even-hour wipes (for example, at :30 on odd hours) so the two never queue behind each other. - On the first run, `onUmod` is not yet known. The rotation starts with the plugins that have no record, and the 404s (Codefling) fall out of the rotation as they are found. - A 429 ends the run early. The plugins it did not reach stay first in line for the next run.
Sign in to join this conversation.
No description provided.