Fix nightly SSH remote daemon checksum mismatch (#2225)

* Fix nightly SSH remote daemon checksum mismatch

Each nightly build overwrites the shared cmuxd-remote-* assets on the
nightly release, but older nightly DMGs have manifests with checksums
from their build time. When a user's nightly is even one build behind,
the downloaded binary doesn't match their embedded manifest.

Two-layer fix:

1. CI: version nightly remote daemon asset names with the build number
   (e.g. cmuxd-remote-darwin-arm64-2362248028801) so each nightly's
   manifest points to immutable files. Unsuffixed "latest" copies are
   still uploaded for tooling compatibility.

2. Client: on checksum mismatch, fetch the live manifest from the
   release and verify against that. This handles users on older
   nightlies that predate the CI fix.

Fixes https://github.com/manaflow-ai/cmux/issues/1745

* Fix unsuffixed checksums file to use generic filenames

Regenerate cmuxd-remote-checksums.txt from the unsuffixed alias
binaries so `shasum -c` works against the generic asset names.
Also document that unsuffixed manifest intentionally keeps versioned
downloadURLs and that aliases don't carry attestation.

---------

Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
This commit is contained in:
Lawrence Chen 2026-03-26 17:24:37 -07:00 committed by GitHub
parent 1b03d23fee
commit ccd84bd578
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 148 additions and 34 deletions

View file

@ -63,3 +63,46 @@ for entry in manifest["entries"]:
print("PASS: remote daemon release assets include all targets and manifest entries")
PY
# ------------------------------------------------------------------
# Test with --asset-suffix (nightly-style immutable asset names)
# ------------------------------------------------------------------
SUFFIX_DIR="$(mktemp -d "${TMPDIR:-/tmp}/cmux-remote-assets-suffix-test.XXXXXX")"
trap 'rm -rf "$OUTPUT_DIR" "$SUFFIX_DIR"' EXIT
"$ROOT_DIR/scripts/build_remote_daemon_release_assets.sh" \
--version "0.62.0-nightly.123456" \
--release-tag "nightly" \
--repo "manaflow-ai/cmux" \
--output-dir "$SUFFIX_DIR" \
--asset-suffix "123456" >/dev/null
for asset in \
cmuxd-remote-darwin-arm64-123456 \
cmuxd-remote-darwin-amd64-123456 \
cmuxd-remote-linux-arm64-123456 \
cmuxd-remote-linux-amd64-123456 \
cmuxd-remote-checksums-123456.txt \
cmuxd-remote-manifest-123456.json
do
if [[ ! -f "$SUFFIX_DIR/$asset" ]]; then
echo "FAIL: missing suffixed asset $asset" >&2
exit 1
fi
done
python3 - <<'PY' "$SUFFIX_DIR/cmuxd-remote-manifest-123456.json"
import json
import sys
from pathlib import Path
manifest = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
for entry in manifest["entries"]:
if not entry["assetName"].endswith("-123456"):
raise SystemExit(f"FAIL: suffixed asset name missing suffix: {entry['assetName']}")
if not entry["downloadURL"].endswith("/" + entry["assetName"]):
raise SystemExit(f"FAIL: downloadURL mismatch for {entry['assetName']}")
print("PASS: --asset-suffix produces correctly suffixed assets and manifest entries")
PY