feat(release): independent fleet-agent release train#381
Conversation
There was a problem hiding this comment.
ℹ️ No critical issues — one scope question worth confirming.
Reviewed changes — extracts the fleet-agent release infrastructure into its own release-please component and workflow so fleet ships independently of the desktop release train.
- New
fleetrelease-please component —release-please-config.jsonadds afleet/-scoped package (component: fleet-agent,include-component-in-tag: true) taggingfleet-agent-v*, and gives the root.packageexclude-paths: ["fleet"]so desktop releases stop bumping the agent version. Manifest seedsfleetat0.4.17. - Pinned fleet version —
fleet/arcbox-fleet-agent/Cargo.tomlmoves fromversion.workspace = trueto a pinned0.4.17 # x-release-please-version; safe since nothing depends on the crate. - New
release-fleet-agent.yml— signed darwin-arm64 + musl linux amd64/arm64 builds, published as rawarcbox-fleet-agent-<os>-<arch>binaries plus.sha256sidecars withmake_latest: false. - New
xtask release fleet-asset—fleet_asset.rsstages a single binary as a versionless asset +shasum -c-compatible checksum, with a unit test on the layout. - Exec-bit regression fix —
stage_executable(inrelease.rs) copies then chmods0755;package_tarball.rsroutes binaries through it while bundle files stay0644, with a test asserting tar entry modes. Drops theGITHUB_OUTPUTplumbing sorelease.ymlglobs*.tar.gz/*.tar.gz.sha256.
ℹ️ Fleet build matrix omits darwin-amd64
The release workflow builds darwin-arm64, linux-amd64, and linux-arm64, but not darwin-amd64. Since the gateway derives AgentUpdate.binary_url as a pure function of (tag, host_os, host_arch), an Intel-mac fleet host would resolve to arcbox-fleet-agent-darwin-amd64, which no release would carry — a 404 at self-update time.
This is very likely intentional (fleet hosts are arm64 macs + linux), and the root CLAUDE.md P1 "macOS Intel" target is about the desktop app rather than fleet runners. Flagging only to confirm the fleet host matrix deliberately excludes Intel macs.
Technical details
# Fleet build matrix omits darwin-amd64
## Affected sites
- .github/workflows/release-fleet-agent.yml — `build-macos-arm64` is the only darwin job; no `build-macos-amd64`.
- publish loop iterates `darwin-arm64 linux-amd64 linux-arm64` only.
## Required outcome
- Confirm the fleet host matrix intentionally excludes Intel macs. If Intel-mac fleet hosts are ever in scope, add a `darwin-amd64` build + publish entry so the gateway-constructed URL resolves.
## Open questions for the human
- Does the fleet gateway ever emit `(darwin, amd64)` for a host? If it can, this is a latent 404 rather than a non-issue.Claude Opus | 𝕏
Greptile SummaryThis PR splits fleet-agent releases from the desktop release train. The main changes are:
Confidence Score: 4/5One contained release-versioning issue needs to be fixed before relying on the new fleet train. The workflow and xtask changes are coherent, but the fleet release seed currently produces the wrong first independent release version.
What T-Rex did
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Dev as Tag push / workflow_dispatch
participant Version as version job
participant Mac as build-macos matrix
participant Linux as build-linux matrix
participant Publish as publish job
participant Release as GitHub Release
Dev->>Version: "Provide fleet-agent-v* tag"
Version-->>Mac: Resolved tag
Version-->>Linux: Resolved tag
Mac->>Mac: Checkout tag, build, codesign
Linux->>Linux: Checkout tag, build musl binary
Mac-->>Publish: darwin arm64/amd64 artifacts
Linux-->>Publish: linux amd64/arm64 artifacts
Publish->>Publish: Checkout same tag and run xtask fleet-asset
Publish->>Release: Upload raw binaries and .sha256 files
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Dev as Tag push / workflow_dispatch
participant Version as version job
participant Mac as build-macos matrix
participant Linux as build-linux matrix
participant Publish as publish job
participant Release as GitHub Release
Dev->>Version: "Provide fleet-agent-v* tag"
Version-->>Mac: Resolved tag
Version-->>Linux: Resolved tag
Mac->>Mac: Checkout tag, build, codesign
Linux->>Linux: Checkout tag, build musl binary
Mac-->>Publish: darwin arm64/amd64 artifacts
Linux-->>Publish: linux amd64/arm64 artifacts
Publish->>Publish: Checkout same tag and run xtask fleet-asset
Publish->>Release: Upload raw binaries and .sha256 files
Reviews (5): Last reviewed commit: "chore(release): reset fleet-agent versio..." | Re-trigger Greptile |
|
Re pullfrog's scope question ( The "latent 404 at self-update time" mechanism doesn't apply, though: the gateway never fabricates a URL from CodeQL's three permissions findings and greptile's dispatch-ref mismatch are fixed in 9e99c78. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the new commit pins the fleet-agent release workflow's checkouts to the tag being released, so a workflow_dispatch from master builds the tag's tree rather than master.
- Tag-ref checkout discipline — all three checkout steps (
build-macos-arm64,build-linux,publish) now useref: ${{ needs.version.outputs.tag }}, andneeds: versionwas added to the two build jobs so the dependency is real. Theversionjob resolves the tag frominputs.tag(dispatch) or the strippedGITHUB_REF(push tag), which is correct for both triggers. - Least-privilege token — added a top-level
permissions: contents: read; thepublishjob continues to re-declarecontents: writefor asset upload.
The tag-ref fix is correct and the reasoning captured in the workflow comments matches the behavior. The prior informational note about the fleet build matrix omitting darwin-amd64 is unrelated to this commit and remains a scope question for the human.
Claude Opus | 𝕏
upload/download-artifact v4 strips permissions — every CI artifact arrives 0644, and the tar builder records on-disk modes, so shipped desktop tarballs contained non-executable binaries. Stage binaries through a chmod-0755 helper; bundle plist/entitlements files stay 0644. The tarball upload step switches to globs, replacing the GITHUB_OUTPUT plumbing. Regression test packages 0644 inputs and asserts the tar entry modes.
The agent's version is a wire-level contract (the gateway pins one expected agent_version at a time), so inheriting the workspace version meant every desktop release invalidated the entire fleet with zero fleet changes. fleet/ becomes its own release-please component (tags fleet-agent-vX.Y.Z) excluded from the root package; seeded at the current 0.4.17 so the first release PR proposes 0.5.0. release-fleet-agent.yml builds signed darwin-arm64 plus native linux-amd64/arm64 musl binaries and publishes them as raw assets named arcbox-fleet-agent-<os>-<arch> with .sha256 files (make_latest: false keeps the desktop release as the repo's latest). Raw binaries, not tarballs: the artifact is a single file, the checksum covers exactly the bytes the agent self-updater will execute, and the download URL is a pure function of (tag, host_os, host_arch). The crate is publish = false, so the coordinated crates.io publish is unaffected.
A workflow_dispatch run built whatever ref it was dispatched from while attaching assets to the requested tag's release — the binaries could silently mismatch the release. Every checkout now pins the resolved tag (a no-op for tag-push events). Also declares the minimal GITHUB_TOKEN permissions at the workflow level.
9e99c78 to
749f9d1
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the new commit adds Intel macOS to the fleet-agent build matrix, resolving the prior review's open scope question about darwin-amd64 coverage.
- Intel macOS build —
build-macos-arm64becomes abuild-macosmatrix over{arm64: macos-26, amd64: macos-26-intel}, so both Apple Silicon and Intel binaries are produced.macos-26-intelis a GA GitHub-hosted runner label. - Per-arch cache and artifacts — the cargo cache key and
restore-keysnow include${{ matrix.arch }}(avoiding cross-arch cache collisions), and the uploaded artifact is namedfleet-agent-binary-darwin-${{ matrix.arch }}. - Publish wiring —
publishneedsthe renamedbuild-macosjob, and thefleet-assetstaging loop now iteratesdarwin-arm64 darwin-amd64 linux-amd64 linux-arm64, so all four(host_os, host_arch)URLs the gateway can construct now resolve.
The darwin-amd64 platform slug flows through xtask release fleet-asset unchanged — fleet_asset.rs treats --platform as an opaque asset-name component with no allowlist, so no code change was needed there. The prior informational note is now fully addressed.
Claude Opus | 𝕏
The fleet-agent release component was seeded at 0.4.17 to mirror the main arcbox version at split time. That inheritance is a leftover of the pre-split shared version and gives no signal about the fleet-agent binary itself. Reseed the fleet component at 0.0.0 so the first release-please cut lands as fleet-agent-v0.1.0. From that point the fleet train advances purely on fleet-scoped commits, fully decoupled from the main train. Also correct the workflow header comment that called the main release train "desktop" — there is no desktop component in this repo.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the new commit reseeds the fleet-agent release train to 0.0.0, fully decoupling its version from the main arcbox train so the first release lands as fleet-agent-v0.1.0.
- Version reseed to
0.0.0—.release-please-manifest.jsonfleetseed drops from0.4.17to0.0.0, with matching updates tofleet/arcbox-fleet-agent/Cargo.toml(version = "0.0.0" # x-release-please-version) andCargo.lock. The root.package stays at0.4.17, so the main train is untouched. - Workflow doc alignment —
release-fleet-agent.ymlheader comment and theworkflow_dispatchtaginput example were edited to match ("desktop" → "main arcbox" train,fleet-agent-v0.5.0→fleet-agent-v0.1.0).
All three version sites are consistent and the change matches the updated PR body. The author-acknowledged caveat still stands — because no fleet-agent-v* tag exists yet, the first generated fleet changelog may include older fleet history and should be trimmed in the bootstrap release PR before merge.
Claude Opus | 𝕏
Two issues in the fleet-agent release train from #381: 1. release-please defaulted to one combined release PR covering both the main arcbox and fleet-agent components, so their versions had to be bumped and merged together — defeating the independent release cadence. 2. With the fleet manifest seeded at 0.0.0, release-please treats the component as unreleased and hard-codes the first tag to 1.0.0, ignoring bump-minor-pre-major. Enable separate-pull-requests so release-please opens one PR per component, and one-shot release-as: 0.1.0 on the fleet package so its bootstrap tag is fleet-agent-v0.1.0. Once that first release cuts, the release-as override should be removed so subsequent fleet releases advance via normal bump rules (0.1.0 + fix -> 0.1.1, 0.1.0 + feat -> 0.1.1 under bump-patch-for-minor-pre-major).

Extracts the fleet-agent release infrastructure from the RUN-31 stack (#360) so it can land independently of the lifecycle and self-update work still under review.
What changes
fleet/now has its own version and release train, tagged asfleet-agent-vX.Y.Z. It is excluded from the root component, so main arcbox releases no longer bump the fleet agent and fleet-only releases do not trigger the main arcbox version update. The component is reseeded at0.0.0— fully decoupled from the main train's version — so its first release will befleet-agent-v0.1.0..github/workflows/release-fleet-agent.ymlbuilds four platform assets:darwin-arm64on an Apple Silicon runnerdarwin-amd64on an Intel runnerlinux-arm64on a native ARM runnerlinux-amd64on a native x86 runnerarcbox-fleet-agent-<os>-<arch>with a matching.sha256sidecar. The release tag carries the version, while the platform registry can expose only the artifacts registered for a promoted release. Fleet releases usemake_latest: false, preserving the main arcbox release as the repository's latest release.0755; bundle metadata remains non-executable. A regression test checks the modes recorded in the generated archive.Release behavior
The first fleet release provides real, signed artifacts for validating the platform release-registration and promotion flow in arcboxlabs/platform#114. The agent-version handshake and self-update executor remain in #360, so a later fleet release from that work will supersede the bootstrap release for end-to-end self-update testing.
Because there is no existing
fleet-agent-v*tag, the first generated fleet changelog may include older fleet history. If so, the one-time bootstrap release PR should trim that history before merge.