feat(local-dev): deploy from a sibling git worktree via up --worktree/--branch#6031
feat(local-dev): deploy from a sibling git worktree via up --worktree/--branch#6031Yicong-Huang wants to merge 2 commits into
Conversation
…/--branch Split the orchestration tree (SELF_ROOT — where local-dev.sh lives, always main's copy of the tooling: the script, tui.py, docker overlay) from the application source tree (SOURCE_ROOT). `up`/`auto` now take --worktree=PATH or --branch=NAME to build/run a sibling worktree without disturbing the main checkout; a plain `up` returns to this checkout. The choice persists to $STATE_DIR/deploy-source so status/down/logs/<svc>/auto all follow it, and status --json gains "worktree"/"source" fields. Build stamps are namespaced per source so switching worktrees can't skip a needed build. The TUI mirrors all of this: u/a accept the selectors and re-point the banner live. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Automated Reviewer SuggestionsBased on the
|
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The deploy source's branch + short-sha was computed inline in four spots (status JSON, status banner, the up Deploy-target line, the TUI dashboard banner). Fold the three pre-existing copies plus the one this feature added into a single `_git_head` helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@mengw15 could you please help on review? thanks |
mengw15
left a comment
There was a problem hiding this comment.
LGTM, left one forward-looking note
| # Infra orchestration is part of the tooling, not the deployed app — pin it to | ||
| # the self tree so a deployed worktree always comes up against main's known-good | ||
| # docker compose (the app schema/DDL it applies still comes from the source tree | ||
| # via $REPO_ROOT). | ||
| DOCKER_COMPOSE_FILE="$SELF_ROOT/bin/single-node/docker-compose.yml" | ||
| DOCKER_OVERLAY_FILE="$SELF_ROOT/bin/local-dev/docker-compose.override.yml" | ||
| DOCKER_ENV_FILE="$SELF_ROOT/bin/single-node/.env" |
There was a problem hiding this comment.
The intentional split (SOURCE_ROOT for app, SELF_ROOT for infra) is the right call for the common case — 95% of PRs only touch app code and this is a huge quality-of-life win. But it silently deposits a real footgun for the other 5%:
- PR adds a new docker service (Redis, ClickHouse, etc.) in its compose file → deployed stack silently misses it (self's compose wins)
- PR adds a required env var → app starts, hits NPE at runtime (self's
.envhas no such var) - PR adds a new backend service to the
SERVICES=(...)array inmain.sh→ self'smain.shnever launches it - PR is itself a tooling change (like this PR) → self's tooling doesn't have the change under test
Worth surfacing this boundary to the user. Two lightweight options:
- Add a note in
--help(and the TUI?help): "--worktree/--branchassumes the target only differs in app code — if it modifiesbin/local-dev/**,bin/single-node/**,docker-compose*, or.env, checkout that branch and run its ownlocal-dev.shinstead." - At startup of
up --worktree=...,diff -q $SELF_ROOT/bin/local-dev/ $SOURCE_ROOT/bin/local-dev/(same forbin/single-node/) and print a one-line warn if there's drift. Non-fatal, just informational.
Not blocking — the design is sound and the failure modes are recoverable. Just want future users to have a chance to notice the boundary before they burn 30 minutes debugging.
What changes were proposed in this PR?
bin/local-dev.shcan now build and run the stack from a sibling git worktree while the orchestration tooling itself always runs from the canonical checkout.The key split is SELF_ROOT (where
local-dev.sh,tui.py, and the docker overlay live — the tooling) vs SOURCE_ROOT (the application tree that gets built/run, whichREPO_ROOTnow points at).up/autoaccept--worktree=PATHor--branch=NAME(resolved to the worktree that has the branch checked out). A plainupreturns to this checkout.$STATE_DIR/deploy-source, sostatus/down/logs/ single-service rebuild /autoall act on the active deployment.upre-marks the deploy target (branch / sha / worktree) at startup, andstatus --jsongains"worktree"and"source"fields..env/ overlay stay pinned to the canonical checkout (orchestration), while the app schema/DDL still comes from the deployed source.u/aaccept the same selectors, and the banner + SRC-dirty column re-point to the active tree live (the shell exportsTEXERA_DEPLOY_SOURCE; the TUI re-reads the persisted pointer after a switch).--branch/--worktreefail fast with a clear, actionable message before anything is built or started.Any related issues, documentation, discussions?
Closes #6030. The
--helptext and the in-TUI help (h) document the new selectors.How was this PR tested?
Extended both existing local-dev test suites (all green):
bin/local-dev/tests/test_local_dev_sh.sh— 25 checks (6 new):--helpdocuments the selectors;status --jsoncarriesworktree/source; a stale pointer is dropped and falls back to self; a valid pointer to a throwaway worktree (created and cleaned up in-test) is honored and reports its branch; invalid--branchand--worktreefail fast with rc=1.bin/local-dev/tests/test_local_dev_tui.py— 43 checks (5 new):_stamp_dir_formatches the shell'ssha1(path)[:12]namespacing;_resolve_deploy_sourcereturns self when the pointer is missing/stale/points at a non-checkout, and the worktree when valid.Run:
Also verified manually that
status --jsonagainst a persisted worktree pointer reports that worktree's branch/sha/source, and thatbash -n/py_compilepass.Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 4.8 (Claude Code)