Agent display version now comes from the agent line's own source (config.agentDisplayVersion injection + defaultAgentDisplayVersion constant, currently A2.3.0) instead of being derived from the panel's displayVersion. Masters resolve the agent line's latest from each release's agent-version.txt marker (selfupdate.ResolveLatestAgentTarget, legacy tag derivation as fallback for pre-marker releases): update intents target the marker under the panel tag, panel-only releases produce no intent, and the nodes page badges agent rows against their own line via PanelUpdateInfo.displayLatestAgentVersion. Windows agent frozen at A2.2.1: release discipline in docs/release.md + scripts/release-build.sh (agent assets reused verbatim when the agent code is unchanged, marker always emitted, no Windows exe), install-agent.ps1 pinned at V2.4.0, and the A2.2.1 protocol shapes locked by TestAgentLegacyWindows221Contract. Agent update tests now derive their targets from the live agent line instead of a hardcoded A2.0.x the line has passed.
4.3 KiB
Release process (L-UI fork)
Releases are published on the self-hosted Gitea (rogue/3x-ui-agent).
Build with scripts/release-build.sh; this document is the rules that
script encodes. Read it before cutting a release — several rules exist
because violating them already caused a production incident once.
Two independent version lines
The panel and the agent are maintained as separate lines (policy set 2026-10-24). They never borrow each other's numbers.
| line | form | source of truth | injection |
|---|---|---|---|
| panel (master) | V2.4.0 |
release tag | -X .../internal/config.displayVersion |
| agent | A2.3.0 |
the release's agent-version.txt marker |
-X .../internal/config.agentDisplayVersion (agents only) |
- The agent line moves only when agent code changes (anything
under
cmd/xui-agent*,internal/agent/, or code reachable from the agent binaries). A panel-only change ships a new panel release whose agent assets are the previous ones, untouched. - An agent built without injection reports the source default
(
defaultAgentDisplayVersionininternal/config), which must always equal the current agent line. When the agent line bumps, bump that constant in the same commit. - Masters resolve "latest agent version" from the newest release's
agent-version.txtmarker (selfupdate.ResolveLatestAgentTarget), never by rewriting the panel tag. Releases older than the marker convention (≤ V2.4.0) transparently fall back to the legacy tag-derived value, which is exact for them (their agent assets were still stamped from the tag).
Asset set
Every release ships exactly:
x-ui-linux-amd64,x-ui-linux-arm64(+.sha256sidecars) — panelx-ui-agent-linux-amd64,x-ui-agent-linux-arm64(+.sha256) — agentagent-version.txt— one line, the agent line's version (A2.3.0)geoip-country.mmdblives in its own standing release, not here.
No Windows executable. See the freeze below.
The agent reuse rule
When agent code is unchanged since the previous release:
- Download the previous release's agent binaries and their
.sha256sidecars. - Verify each binary against its sidecar.
- Upload them to the new release byte-for-byte — do not rebuild, do not re-stamp. Rebuilding the same source with a new injection would mint a binary that claims a version its code does not earn and would churn every node's update state for nothing.
agent-version.txtstill names the same agent version.
When agent code changed: build fresh agents, bump only the agent
line (and defaultAgentDisplayVersion), generate fresh sidecars.
scripts/release-build.sh implements both paths (AGENT_CHANGED=0/1).
Windows freeze
The Windows agent is frozen at A2.2.1; V2.4.0 was the last
release containing x-ui-agent-windows-amd64.exe. One machine
(TYYUN, probe-only) runs it and it will not be updated.
Consequences that are part of the release contract:
install-agent.ps1stays pinned to the V2.4.0 release base. Do not bump it: newer releases contain no exe for it to download.- The frozen agent cannot adapt to master changes, so the master side
of its protocol is contract-locked by
TestAgentLegacyWindows221Contract(register / heartbeat / probe-report request shapes; config payload keys; response envelopes). If that test goes red, the change breaks a node that can never be upgraded — stop and reconsider.
Pre-publish checks
agent-version.txtcontent equals the agent assets' reported version (for reused assets: the version they already report).- Sizes and sha256 of every asset read back through the API after upload match the local files.
- Binaries are static (
readelf -dshows no NEEDED) and carry no CGO stub strings. - Panel self-reports the new V version; agent self-reports the intended A version (unchanged line ⇒ unchanged report).
- Pilot: update ONE node first; after it converges,
statthe on-disk agent binary and compare size + sha256 with the release asset. (V2.3.0 lesson: the version display can look right while the fleet still runs the previous asset generation — the update asset an agent fetches is decided by the agent's own build.) install-agent.sh'sRELEASE_BASEpoints at the new tag.