fix(claude): stop stale .mcp.json residue outranking a project switch, and gate stale builds #106
@@ -890,8 +890,14 @@ ships a binary missing whatever landed on main meanwhile, and `rpm -U --force`
|
||||
overwrites the good one with it. That happened on 2026-08-10: a build from a
|
||||
stale checkout replaced `/usr/bin/mcpctl` with one that had no `statusline`
|
||||
command, months after the status line landed. `scripts/check-main-sync.sh`
|
||||
(sourced by `build-rpm.sh` and `build-deb.sh`) fetches `main`, compares, and
|
||||
fails before any work happens, listing the commits you are missing.
|
||||
fetches `main`, compares, and fails before any work happens, listing the commits
|
||||
you are missing. It gates every path that produces something others consume:
|
||||
`build-rpm.sh`, `build-deb.sh`, `build-mcpd.sh` (each is also run standalone, so
|
||||
none can rely on another having checked) and `deploy-k8s.sh` — where a stale
|
||||
branch would pin its sha in Pulumi and make it the cluster's source of truth.
|
||||
`deploy-k8s.sh --dry-run` skips the check: it builds and cuts over nothing, and
|
||||
blocking a read-only inspection only teaches people to export the escape hatch
|
||||
permanently, disabling the gate for real deploys too.
|
||||
|
||||
```bash
|
||||
git merge main # the fix
|
||||
|
||||
@@ -16,6 +16,11 @@ if [ -f .env ]; then
|
||||
set -a; source .env; set +a
|
||||
fi
|
||||
|
||||
# This pushes an image to the registry, so the same staleness gate as the package
|
||||
# builds applies. Run standalone as well as from deploy-k8s.sh, hence its own copy.
|
||||
source "$SCRIPT_DIR/check-main-sync.sh"
|
||||
check_main_sync
|
||||
|
||||
# Push directly to internal address (external proxy has body size limit)
|
||||
REGISTRY="10.0.0.194:3012"
|
||||
IMAGE="mcpd"
|
||||
|
||||
@@ -84,8 +84,10 @@ check_main_sync() {
|
||||
echo "" >&2
|
||||
echo "ERROR: '$branch' is $behind commit(s) behind $base — refusing to build." >&2
|
||||
echo "" >&2
|
||||
echo " Building now would package a binary without these, and installing it" >&2
|
||||
echo " would overwrite a good one with a version missing them:" >&2
|
||||
# Deliberately artifact-agnostic: the same helper gates RPM/DEB packages, the
|
||||
# mcpd image, and the k8s deploy.
|
||||
echo " Building now would produce an artifact without these, and shipping it" >&2
|
||||
echo " would replace a good one with a version missing them:" >&2
|
||||
echo "" >&2
|
||||
git log --oneline --no-decorate "HEAD..$ref" | head -15 | sed 's/^/ /' >&2
|
||||
if [ "$behind" -gt 15 ]; then
|
||||
|
||||
@@ -80,6 +80,20 @@ cat <<EOF
|
||||
EOF
|
||||
[ -f "$PULUMI_YAML" ] || die "Pulumi config not found: $PULUMI_YAML"
|
||||
|
||||
# ── 0. Staleness gate ──
|
||||
# Same hazard as the RPM build, with the cluster on the receiving end: a branch
|
||||
# behind main deploys images missing whatever landed there, and the sha pinned in
|
||||
# Pulumi makes that the new source of truth. Skipped for --dry-run, which builds
|
||||
# and cuts over nothing — blocking a read-only inspection only teaches people to
|
||||
# export MCPCTL_ALLOW_BEHIND_MAIN=1 permanently, which would disable the gate for
|
||||
# the real deploys too.
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
warn "dry-run: skip the main-sync check"
|
||||
else
|
||||
source "$SCRIPT_DIR/check-main-sync.sh"
|
||||
check_main_sync || die "branch is behind main — merge it before deploying"
|
||||
fi
|
||||
|
||||
# ── 1. Test gate ──
|
||||
if [ "$SKIP_TESTS" = true ]; then warn "skipping unit tests (--skip-tests)"; else
|
||||
say "1/7 Unit tests (pnpm test:run)"
|
||||
|
||||
Reference in New Issue
Block a user