# 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 (`defaultAgentDisplayVersion` in `internal/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.txt` marker (`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` (+ `.sha256` sidecars) — panel - `x-ui-agent-linux-amd64`, `x-ui-agent-linux-arm64` (+ `.sha256`) — agent - `agent-version.txt` — one line, the agent line's version (`A2.3.0`) - `geoip-country.mmdb` lives 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: 1. Download the previous release's agent binaries **and** their `.sha256` sidecars. 2. Verify each binary against its sidecar. 3. 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. 4. `agent-version.txt` still 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.ps1` stays 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.txt` content 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 -d` shows 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, `stat` the 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`'s `RELEASE_BASE` points at the new tag.