fix(install,smoke): carry cbm-integrations.json wherever the binary goes
pr-smoke failed on all three platforms: the binary's install/uninstall render templates from the integration asset, and every place that stages the binary without the asset made those operations fail closed with "integration assets missing". The asset must travel with the binary in EVERY layout, not just the release archive. Five staging paths were missing it: - scripts/build.sh — stage cbm-integrations.json next to the freshly built binary, so `build/c/codebase-memory-mcp install` works straight out of a build tree (dev, and the base for the smoke fixture). - scripts/smoke-local.sh — include the asset in the fixture tarball and its required-sidecar check. Member set and ORDER now mirror package-release.sh exactly (binary, cbm-integrations.json, LICENSE, install.sh, notices); the fixture was smoking an archive layout we never actually ship. - install.sh / install.ps1 — after installing the binary, copy the asset beside it in the install dir. `install` already publishes a verified copy to ~/.cbm/assets/<version>/, but a later install/uninstall run from the install dir resolves the asset NEXT TO THE BINARY first, so without the adjacent copy that lookup misses and a re-install or uninstall fails on a machine that just installed successfully. Best-effort atomic rename, same shape as the existing install.sh/ps1 sidecar copy. install.ps1 stays pure ASCII. - scripts/smoke-test.sh Phase 14 — this phase hand-stages the binary into a fresh HOME without going through install, so nothing populates ~/.cbm/assets; stage the asset next to each staged copy so the uninstall it drives resolves. Verified: scripts/smoke-local.sh on the standard binary now runs clean through all 16 phases — zero "integration assets missing" / hook_script_uninstall / agent-cleanup-failed lines (was 5). windows-bundle, smoke-fixture, exec-bit and no-embedded-scripts contracts pass; install.ps1 has zero non-ASCII bytes. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
+18
@@ -322,6 +322,24 @@ if (Test-Path -LiteralPath $DownloadedInstaller -PathType Leaf) {
|
||||
}
|
||||
}
|
||||
|
||||
# Place the integration-template asset beside the installed binary, mirroring
|
||||
# install.sh. `install` above published a verified copy to ~/.cbm/assets, but a
|
||||
# later install/uninstall run from $InstallDir resolves the asset next to the
|
||||
# binary first; without this copy that lookup misses and the run fails closed
|
||||
# with "integration assets missing".
|
||||
$DownloadedAsset = Join-Path $TmpDir "cbm-integrations.json"
|
||||
if (Test-Path -LiteralPath $DownloadedAsset -PathType Leaf) {
|
||||
$AssetDest = Join-Path $InstallDir "cbm-integrations.json"
|
||||
$AssetTmp = "$AssetDest.new"
|
||||
try {
|
||||
Copy-Item -LiteralPath $DownloadedAsset -Destination $AssetTmp -Force -ErrorAction Stop
|
||||
Move-Item -LiteralPath $AssetTmp -Destination $AssetDest -Force -ErrorAction Stop
|
||||
} catch {
|
||||
Remove-Item -LiteralPath $AssetTmp -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "note: could not place cbm-integrations.json in $InstallDir (asset resolves from ~/.cbm/assets)"
|
||||
}
|
||||
}
|
||||
|
||||
# Verify
|
||||
try {
|
||||
$ver = & $Dest --version 2>&1
|
||||
|
||||
+19
@@ -294,6 +294,25 @@ if [ -f "$DL_INSTALLER" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Place the integration-template asset beside the installed binary. `install`
|
||||
# above already published a verified copy to ~/.cbm/assets/<version>/, but a
|
||||
# later `install`/`uninstall` run from INSTALL_DIR resolves the asset next to
|
||||
# the binary FIRST — and without this copy that lookup misses, so a re-run or an
|
||||
# uninstall would fail closed with "integration assets missing" even though a
|
||||
# valid install just completed. Atomic rename, best effort, same rationale as
|
||||
# the installer copy above.
|
||||
DL_ASSET="$DLDIR/cbm-integrations.json"
|
||||
if [ -f "$DL_ASSET" ]; then
|
||||
ASSET_TMP="$INSTALL_DIR/.cbm-integrations.json.$$"
|
||||
if cp "$DL_ASSET" "$ASSET_TMP" 2>/dev/null &&
|
||||
mv -f "$ASSET_TMP" "$INSTALL_DIR/cbm-integrations.json" 2>/dev/null; then
|
||||
:
|
||||
else
|
||||
rm -f "$ASSET_TMP" 2>/dev/null || true
|
||||
echo "note: could not place cbm-integrations.json in $INSTALL_DIR (asset resolves from ~/.cbm/assets)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verify
|
||||
VERSION=$("$DEST" --version 2>&1) || {
|
||||
echo "error: installed binary failed to run" >&2
|
||||
|
||||
@@ -156,4 +156,14 @@ else
|
||||
CFLAGS_EXTRA="$CFLAGS_EXTRA" "${EXTRA_MAKE_ARGS[@]+"${EXTRA_MAKE_ARGS[@]}"}"
|
||||
fi
|
||||
|
||||
# Stage the integration-template asset next to the binary so the dev/CI build
|
||||
# mirrors the release archive layout. The binary resolves cbm-integrations.json
|
||||
# next to itself, in $CBM_ASSETS_DIR, or under ~/.cbm/assets/<version>/; a plain
|
||||
# build/c binary has none of those, so install/uninstall (which render the
|
||||
# templates to verify hash and ownership) would fail closed exactly as they do
|
||||
# for a user who deleted the file. Copying it here keeps `install` working
|
||||
# straight out of a build tree — smoke, local dev, and the release packaging all
|
||||
# then see the same adjacency.
|
||||
cp "$ROOT/assets/cbm-integrations.json" "$BUILD_DIR/cbm-integrations.json"
|
||||
|
||||
echo "=== Build complete: ${BUILD_DIR}/codebase-memory-mcp ==="
|
||||
|
||||
@@ -72,7 +72,7 @@ esac
|
||||
ARTIFACT_DIR="${CBM_SMOKE_ARTIFACT_DIR:-}"
|
||||
if [ -n "$ARTIFACT_DIR" ]; then
|
||||
ARTIFACT_DIR="$(cd "$ARTIFACT_DIR" && pwd)"
|
||||
for required in LICENSE install.sh THIRD_PARTY_NOTICES.md; do
|
||||
for required in cbm-integrations.json LICENSE install.sh THIRD_PARTY_NOTICES.md; do
|
||||
[ -s "$ARTIFACT_DIR/$required" ] || {
|
||||
echo "smoke-local: release artifact is missing $required" >&2
|
||||
exit 2
|
||||
@@ -123,16 +123,20 @@ mkdir -p "$FIXTURE_DIR" "$SMOKE_TEMP_DIR" "$SMOKE_HOME" "$SMOKE_XDG_CONFIG" \
|
||||
"$SMOKE_APPDATA" "$SMOKE_LOCALAPPDATA"
|
||||
cp "$BINARY" "$FIXTURE_DIR/codebase-memory-mcp"
|
||||
if [ -n "$ARTIFACT_DIR" ]; then
|
||||
cp "$ARTIFACT_DIR/LICENSE" "$ARTIFACT_DIR/install.sh" \
|
||||
"$ARTIFACT_DIR/THIRD_PARTY_NOTICES.md" "$FIXTURE_DIR/"
|
||||
cp "$ARTIFACT_DIR/cbm-integrations.json" "$ARTIFACT_DIR/LICENSE" \
|
||||
"$ARTIFACT_DIR/install.sh" "$ARTIFACT_DIR/THIRD_PARTY_NOTICES.md" "$FIXTURE_DIR/"
|
||||
else
|
||||
cp "$ROOT/LICENSE" "$ROOT/install.sh" "$FIXTURE_DIR/"
|
||||
cp "$ROOT/assets/cbm-integrations.json" "$ROOT/LICENSE" "$ROOT/install.sh" "$FIXTURE_DIR/"
|
||||
"$ROOT/scripts/gen-third-party-notices.sh" "$FIXTURE_DIR/THIRD_PARTY_NOTICES.md"
|
||||
fi
|
||||
|
||||
# The archive must carry cbm-integrations.json — install verifies it against the
|
||||
# binary's embedded SHA-256 and fails closed without it. Member set and ORDER
|
||||
# mirror scripts/package-release.sh (the Windows single-binary contract locks
|
||||
# that order); a fixture that omits it would smoke a release layout we never ship.
|
||||
EXPECTED_ARTIFACT="codebase-memory-mcp${SUFFIX}-${OS}-${ARCH}.tar.gz"
|
||||
tar -czf "$FIXTURE_DIR/$EXPECTED_ARTIFACT" -C "$FIXTURE_DIR" \
|
||||
codebase-memory-mcp LICENSE install.sh THIRD_PARTY_NOTICES.md
|
||||
codebase-memory-mcp cbm-integrations.json LICENSE install.sh THIRD_PARTY_NOTICES.md
|
||||
if [ -n "$SUFFIX" ]; then
|
||||
cp "$FIXTURE_DIR/$EXPECTED_ARTIFACT" \
|
||||
"$FIXTURE_DIR/codebase-memory-mcp-${OS}-${ARCH}.tar.gz"
|
||||
|
||||
@@ -3068,16 +3068,24 @@ if [ -n "${SMOKE_DOWNLOAD_URL:-}" ]; then
|
||||
fi
|
||||
UPDATE_HOME=$(smoke_mktemp_dir)
|
||||
mkdir -p "$UPDATE_HOME/.claude" "$UPDATE_HOME/.local/bin"
|
||||
# This phase stages the binary by hand into a fresh HOME — it does NOT go
|
||||
# through install.sh or `install`, so nothing populates ~/.cbm/assets. The
|
||||
# integration asset ships next to the binary in every real layout (archive,
|
||||
# build tree, installed dir), so stage it next to each staged copy here too;
|
||||
# otherwise the uninstall this phase drives fails closed rendering templates.
|
||||
BINARY_ASSET="$(dirname "$BINARY")/cbm-integrations.json"
|
||||
if [[ "$BINARY" == *.exe ]]; then
|
||||
cp "$BINARY" "$UPDATE_HOME/.local/bin/codebase-memory-mcp.exe"
|
||||
mkdir -p "$UPDATE_HOME/retired-install"
|
||||
cp "$BINARY" "$UPDATE_HOME/retired-install/codebase-memory-mcp.exe"
|
||||
[ -f "$BINARY_ASSET" ] && cp "$BINARY_ASSET" "$UPDATE_HOME/.local/bin/cbm-integrations.json"
|
||||
else
|
||||
cp "$BINARY" "$UPDATE_HOME/.local/bin/codebase-memory-mcp"
|
||||
chmod 755 "$UPDATE_HOME/.local/bin/codebase-memory-mcp"
|
||||
mkdir -p "$UPDATE_HOME/retired-install"
|
||||
cp "$BINARY" "$UPDATE_HOME/retired-install/codebase-memory-mcp"
|
||||
chmod 755 "$UPDATE_HOME/retired-install/codebase-memory-mcp"
|
||||
[ -f "$BINARY_ASSET" ] && cp "$BINARY_ASSET" "$UPDATE_HOME/.local/bin/cbm-integrations.json"
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
codesign --sign - --force "$UPDATE_HOME/.local/bin/codebase-memory-mcp" 2>/dev/null || true
|
||||
codesign --sign - --force "$UPDATE_HOME/retired-install/codebase-memory-mcp" \
|
||||
|
||||
Reference in New Issue
Block a user