The "Commit version bump and push tag" step had two problems, and the first hid the second. It has never once executed. An empty template expression written literally in one of its comments makes the runner fail to build the step's script, and a step it cannot build is skipped WITHOUT failing the job. That is why sidecar/Cargo.toml still says 0.1.0 after six releases, and why the tag-reuse handling added in #27 was dead on arrival. The tags exist because Gitea's release API creates one when it publishes -- the pipeline has been working by accident. And had it executed, it would have been declined: main is protected, so the push is rejected by the pre-receive hook. The installer's bundle job hit exactly that today. A release must not depend on a write to a protected branch. So the tag is the version, as it already is in servuo-plugins, whose release workflow was written this way on purpose and has never needed a protection exception. The workflow still writes the real version into Cargo.toml before building, so a released binary self-reports correctly; what it no longer does is commit that edit back. Nothing downstream reads the file -- the next version is computed from the newest tag. The comment is reworded so the step can actually run, and warns against writing that token in a comment again. No literal occurrence is left in this file. Co-Authored-By: Claude <noreply@anthropic.com>
uo-link — Rust sidecar
The Rust sidecar half of the Runic Gateway bridge. The ServUO shard dials out to this sidecar over a loopback TCP socket (newline-delimited JSON); the sidecar owns the WebSocket + REST API the website consumes, along with auth, buffering, and fan-out.
ServUO plugin (C#, net48) ──loopback TCP, newline-JSON──► Rust sidecar ──WebSocket/JSON──► website
(RunicGateway/servuo-plugins) >>> THIS REPO <<<
The shard never speaks WebSocket and exposes no port of its own — the sidecar is the only network-facing component, which is what keeps the game unreachable from the internet.
Related repos
| Repo | What |
|---|---|
this — RunicGateway/link |
The Rust sidecar (sidecar/). |
| RunicGateway/servuo-plugins | The C# ServUO plugin — the shard side of the bridge (overlay/, patches/, deploy.ps1, test scaffolding). |
| RunicGateway/docs | All project documentation — design docs, protocol spec, integration guide, research. |
Layout
| Path | What |
|---|---|
sidecar/ |
The Rust sidecar crate — terminates the loopback link to the shard, exposes WS + REST to the website. See sidecar/README.md. |
.gitea/workflows/pr-checks.yml |
Gates every PR into main on cargo fmt --check, cargo clippy -D warnings, and cargo test. |
.gitea/workflows/release.yml |
Builds + releases the sidecar binary (Linux + Windows) on every merge to main. |
Build & run
The sidecar is a standard cargo crate:
cd sidecar
cargo build --release # binary at target/release/uo-link-sidecar
cp sidecar.toml.example sidecar.toml # then edit
cargo run --release
Deploying it rather than developing on it: --config <PATH> names the config file (as does
$UOLINK_CONFIG), and --print-config prints the resolved settings — including the auth token
the website needs — as JSON, provisioning the config file on first run. That is the supported way
to read the token back; it is not meant to be scraped from the log.
uo-link-sidecar --print-config --config /etc/runicgateway/sidecar.toml
.gitea/workflows/release.yml cross-compiles Linux + Windows binaries and cuts a Gitea release on
every merge to main (conventional-commit versioning). See sidecar/README.md
for configuration and the wire protocol.
Before that, .gitea/workflows/pr-checks.yml runs the same gates on every pull request into main —
cargo fmt --check, cargo clippy --all-targets -- -D warnings, then cargo test --locked. Run them
locally before pushing and the PR will be green:
cd sidecar
cargo fmt # or --check to just report
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
Deployment & compatibility
The plugin (RunicGateway/servuo-plugins) and this sidecar are deployed together but built independently:
- The plugin is deployed as source into the ServUO server root and compiled by ServUO at boot — no build artifact, no CI build.
- The sidecar is a standalone Rust binary released from this repo.
The only coupling is the loopback JSON protocol (the shard dials 127.0.0.1). Compatibility is a
protocol concern, not a build-order one — keep the event/command catalog in sync across the two
repos. Canonical spec:
PLAN.md §5/§7 and
INTEGRATION.md.
Because a wedged or absent sidecar cannot stall the shard, either side can be deployed or restarted
independently.
License
Runic Gateway is free software, licensed under the GNU General Public License v3.0 or later — see LICENSE.md.
Copyright (C) 2026 Runic Gateway
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version. It is distributed WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Contributions are welcome — please read CONTRIBUTING.md (note the AI-usage disclosure requirement) and our Code of Conduct. Report vulnerabilities privately per SECURITY.md.