Skip to content

fix(scripts): nuke-and-rebuild self-bootstraps templates; add E2E test - #2122

Merged
hongmingwang-moleculeai merged 1 commit into
stagingfrom
fix/nuke-and-rebuild-self-bootstraps
Apr 26, 2026
Merged

fix(scripts): nuke-and-rebuild self-bootstraps templates; add E2E test#2122
hongmingwang-moleculeai merged 1 commit into
stagingfrom
fix/nuke-and-rebuild-self-bootstraps

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

What this fixes

Two paper cuts surfaced today during a real `bash scripts/nuke-and-rebuild.sh` flow:

  1. Empty template palette in Canvas after nuke. The script wipes the compose stack but never re-populates `workspace-configs-templates/`, `org-templates/`, or `plugins/` — those dirs are `.gitignored` (curated set lives in `manifest.json` as external repos). Without re-cloning, Canvas's "Deploy your first agent" shows zero templates and provisioning falls back to bare defaults.
  2. Documented why the existing `ws-*` reap lines are load-bearing. They were already in the script (good), but the reason wasn't obvious — `docker compose down -v` doesn't kill dynamically-spawned workspace containers because they're created by the provisioner, not declared in compose.

What's in the PR

  • `scripts/nuke-and-rebuild.sh` — adds one `bash clone-manifest.sh ...` step. `clone-manifest.sh` is idempotent, so a re-nuke on a healthy machine pays only a few stat calls. Header docstring expanded with the "why" for each step.
  • `scripts/test-nuke-and-rebuild.sh` (new, ~150 lines) — E2E test that:
    • plants a fake orphan `ws-deadbeeftest` container, asserts it gets reaped
    • renames `workspace-configs-templates/` etc. to simulate fresh checkout, asserts repopulation
    • waits for `/health` and asserts platform sees same template count on disk vs in `/configs` (catches bind-mount drift)
    • asserts the image-auto-refresh watcher (PR feat(workspace-server): GHCR digest watcher closes runtime CD chain #2114) starts

Pre-flight check

The test exits `0` with a clear SKIP message when ports 5432/6379/8080 are held by a non-target compose project (common when parallel monorepo checkouts coexist on one Docker daemon).

Test plan

  • `shellcheck --severity=warning` passes on both files
  • Test SKIPs cleanly when a parallel stack is up
  • Stop other stacks → `bash scripts/test-nuke-and-rebuild.sh` → all 5 assertions PASS

What this PR does NOT solve (deliberately)

Plain `docker compose down -v` (without invoking the canonical script) still leaves `ws-*` orphans behind. The runtime root cause is in `internal/registry/orphan_sweeper.go` — it only reaps containers whose workspace row has `status='removed'`. A wiped DB has no row at all, so the sweeper ignores them.

Proper fix needs container labels keyed to a per-platform-instance UUID so the sweeper can reap "containers I provisioned that aren't in my DB anymore" without nuking a sibling platform's containers on a shared daemon. Tracked as a follow-up under task #109; deferred from this PR to keep scope tight.

🤖 Generated with Claude Code

Two paper cuts the fix addresses:

1. nuke-and-rebuild.sh wipes the compose stack but never re-populates
   workspace-configs-templates/, org-templates/, or plugins/. Those dirs
   are .gitignored — the curated set lives in manifest.json as external
   repos cloned via clone-manifest.sh (idempotent). Without that step,
   a fresh checkout or a post-deletion run leaves the dirs empty, which
   silently hides the entire template palette in Canvas + falls back to
   bare default workspace provisioning. Symptom: "Deploy your first
   agent" shows zero templates.

2. The existing ws-* container reap was already in the script (good),
   but it only fires when this script runs. Folks running `docker compose
   down -v` directly leave orphan ws-* containers behind. Documented
   that explicitly in the script comment so future readers understand
   why those lines are critical.

The fix is just `bash clone-manifest.sh` added to the script. clone-
manifest.sh is idempotent — populated dirs short-circuit, so a re-nuke
on a healthy machine pays only a few stat calls.

scripts/test-nuke-and-rebuild.sh exercises the canonical workflow end-
to-end:
  - plants a fake orphan ws-* container, then asserts it gets reaped
  - renames the manifest dirs to simulate a fresh checkout, then
    asserts they get repopulated
  - waits for /health and asserts the platform sees the same template
    count on disk as via /configs in the container (catches bind-mount
    drift)
  - asserts the image-auto-refresh watcher (PR #2114) starts, since
    that's load-bearing for the CD chain users now rely on

The test pre-flights port 5432/6379/8080 and exits 0 with a SKIP
message if a non-target compose project is holding them — common when
parallel monorepo checkouts coexist on one Docker daemon.

scripts/ is intentionally outside CI shellcheck per ci.yml comment, but
both files pass `shellcheck --severity=warning` anyway.

Defers but does not solve the runtime root-cause for orphan ws-* after
plain `docker compose down -v`: the orphan-sweeper in the platform only
reaps containers whose workspace row says status='removed', so a wiped
DB → no row → sweeper ignores them. Proper fix needs container labels
keyed to a per-platform-instance UUID so the sweeper can confidently
reap "containers I provisioned that aren't in my DB anymore" without
nuking a sibling platform's containers on a shared daemon. Tracked as
task #109's follow-up; out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@HongmingWang-Rabbit
HongmingWang-Rabbit force-pushed the fix/nuke-and-rebuild-self-bootstraps branch from d118d54 to 44d0444 Compare April 26, 2026 21:37
Merged via the queue into staging with commit 9ee27a5 Apr 26, 2026
14 checks passed
@molecule-ai
molecule-ai Bot deleted the fix/nuke-and-rebuild-self-bootstraps branch May 20, 2026 06:22
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
PR #2122 makes workspace Pause/Resume cascade opt-in via ?cascade=true.
Without this parameter, pausing/resuming a workspace with descendants
returns 409 Conflict, breaking the Canvas ContextMenu and batch-pause
flows that currently depend on implicit cascade behavior.

Add ?cascade=true to all Canvas callers so the existing UX behavior
is preserved when #2122 lands.

Refs: #2122
/sop-ack
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…via ?cascade=true' (#2122) from fix/pause-resume-cascade-opt-in-1991 into main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant