Files
Rust-Link/egg/build.sh
wtclaude b3b66b1cc2
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 3m53s
feat(sidecar): a Windows service, the egg and its launcher, and the first release workflow (phase 18)
Module-rust phase 18, step 4 of docs/modules/rust/PLAN.md §34.2.7.

The Windows service (D149, §34.2.5): src/windows.rs, ported from link's fix
for error 1053. The same exe tries the SCM handshake and falls through to a
console run on 1063; it reports Running only once the listener and store are
up, and logs to a daily file beside its config. One binary serves every
RunicGatewayRust-<id> instance, because the SCM ignores the dispatcher's name
for an own-process service.

An empty environment variable now counts as unset. A Pterodactyl egg exports
every variable it declares, so a blank RUSTLINK_WEB_TOKEN arrived as "" and
overrode the saved token, and a new one was generated and persisted on every
boot. That breaks D152, which this change makes true.

The egg (R20, R22, D151, D152, §34.2.6), in egg/:
- install.sh is egg 18's script with two changes. A wipe guard moves
  rust-link/ to /tmp around `rm -rf ${REMOVE_FILES}`. The bridge block then
  fetches a schema-2 Rust bundle (pinnable by RUNICGATEWAY_BUNDLE), checks
  every asset's sha256 and the plugin's protocol before placing anything, and
  places the plugin by FRAMEWORK. Vanilla installs nothing and does not fail.
- with-sidecar.sh is the launcher. It unsets blank variables, builds the web
  bind from RUSTLINK_WEB_PORT, and runs --print-config so that a newly
  generated token is printed once. It prints the URL and server id for the
  admin page, then execs the game. It no longer uses `set -e`: nothing the
  bridge gets wrong may keep the game from booting.
- The startup's launcher prefix is conditional, so a server with no bridge
  boots exactly as egg 18 does.
- build.sh assembles egg-rust-runicgateway.json. PR Checks runs it.

The release (D145, §34.2.1) reuses servuo-plugins' engine. It publishes the
static musl Linux binary, the Windows exe, the launcher, the egg and
SHA256SUMS, and dispatches the installer's bundle.yml. PR Checks gains a
clippy run for the Windows target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-25 23:14:57 -05:00

32 lines
1.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Assemble the importable egg: egg.json with install.sh inserted as its install script.
#
# egg/build.sh [OUT] default OUT: dist/egg-rust-runicgateway.json
#
# The install script is kept as a real file so it can be read, diffed and shellchecked; an install
# script edited inside a JSON string is one nobody reviews. PR Checks runs this, so a broken egg
# fails a pull request, and release.yml runs it to produce the asset a panel admin imports.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
OUT="${1:-dist/egg-rust-runicgateway.json}"
mkdir -p "$(dirname "$OUT")"
bash -n "$HERE/install.sh"
sh -n "$HERE/with-sidecar.sh"
jq --rawfile script "$HERE/install.sh" \
'.scripts.installation.script = $script' "$HERE/egg.json" > "$OUT"
# The shape Pterodactyl's importer requires, and the variables this egg exists to add.
jq -e '
.meta.version == "PTDL_v2"
and (.scripts.installation.script | startswith("#!/bin/bash"))
and (.startup | startswith("$( [ -x ./rust-link/with-sidecar.sh ]"))
and ([.variables[].env_variable] as $v
| ["RUSTLINK_SERVER_ID","RUSTLINK_WEB_PORT","RUSTLINK_WEB_TOKEN","RUNICGATEWAY_BUNDLE",
"RUSTLINK_RETAIN_DAYS","FRAMEWORK","REGEN_SERVER","REMOVE_FILES"]
| all(. as $k | $v | index($k)))
' "$OUT" >/dev/null || { echo "egg/build.sh: $OUT is missing something the egg must have" >&2; exit 1; }
echo "egg: $OUT"