refactor(scripts): postlude owns worktree-branch checkout
Strip the inline `git checkout -B` block from the Docker and Sprites default prepare scripts. The kandev-managed postlude (KandevBranchCheckoutPostlude) is appended unconditionally after every user prepare script, so keeping the same logic inline made the default and the postlude two sources of truth that could drift.
This commit is contained in:
@@ -97,21 +97,12 @@ git config --global url."https://github.com/".insteadOf "ssh://git@github.com/"
|
||||
{{github.auth_setup}}
|
||||
|
||||
# ---- Clone repository ----
|
||||
# The kandev-managed feature-branch checkout is appended as an invariant
|
||||
# postlude (see KandevBranchCheckoutPostlude) — keep it out of the default
|
||||
# so old profiles snapshotting this script and the postlude never disagree.
|
||||
git clone --depth=1 --branch {{repository.branch}} {{repository.clone_url}} {{workspace.path}}
|
||||
cd {{workspace.path}}
|
||||
|
||||
# Switch to the kandev-managed feature branch. On resume after a destroyed
|
||||
# container, prefer the remote tip if the agent had previously pushed; fall
|
||||
# back to a fresh branch off the chosen base. -B is idempotent if the local
|
||||
# branch somehow already exists.
|
||||
if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then
|
||||
if git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then
|
||||
git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"
|
||||
else
|
||||
git checkout -b "{{worktree.branch}}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Strip embedded token from remote URL to avoid persisting credentials in .git/config
|
||||
git remote set-url origin "$(git remote get-url origin | sed 's|https://[^@]*@github.com/|https://github.com/|')" 2>/dev/null || true
|
||||
|
||||
@@ -149,22 +140,13 @@ chmod +x /usr/local/bin/pnpm
|
||||
{{git.identity_setup}}
|
||||
|
||||
# ---- Clone repository ----
|
||||
# The kandev-managed feature-branch checkout is appended as an invariant
|
||||
# postlude (see KandevBranchCheckoutPostlude) — keep it out of the default
|
||||
# so old profiles snapshotting this script and the postlude never disagree.
|
||||
echo "Cloning {{repository.clone_url}} (branch: {{repository.branch}})..."
|
||||
git clone --depth=1 --quiet --branch {{repository.branch}} {{repository.clone_url}} {{workspace.path}}
|
||||
cd {{workspace.path}}
|
||||
|
||||
# Switch to the kandev-managed feature branch. On resume after a destroyed
|
||||
# sandbox, prefer the remote tip if the agent had previously pushed; fall
|
||||
# back to a fresh branch off the chosen base. -B is idempotent if the local
|
||||
# branch somehow already exists.
|
||||
if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then
|
||||
if git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then
|
||||
git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"
|
||||
else
|
||||
git checkout -b "{{worktree.branch}}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Strip embedded token from remote URL to avoid persisting credentials in .git/config
|
||||
git remote set-url origin "$(git remote get-url origin | sed 's|https://[^@]*@github.com/|https://github.com/|')" 2>/dev/null || true
|
||||
|
||||
|
||||
@@ -29,53 +29,27 @@ func TestKandevBranchCheckoutPostlude_HasInvariantSteps(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestDefaultPrepareScripts_FeatureBranchCheckout asserts that both clone-based
|
||||
// remote scripts include the kandev feature-branch checkout block, that the
|
||||
// block prefers the remote tip when one exists (resume-after-destroyed-sandbox
|
||||
// recovery), and that it falls back to creating a fresh local branch.
|
||||
func TestDefaultPrepareScripts_FeatureBranchCheckout(t *testing.T) {
|
||||
cases := []struct {
|
||||
executorType string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
executorType: "local_docker",
|
||||
want: []string{
|
||||
`if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then`,
|
||||
`if git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then`,
|
||||
`git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"`,
|
||||
`git checkout -b "{{worktree.branch}}"`,
|
||||
},
|
||||
},
|
||||
{
|
||||
executorType: "remote_docker",
|
||||
want: []string{
|
||||
`if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then`,
|
||||
`if git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then`,
|
||||
`git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"`,
|
||||
`git checkout -b "{{worktree.branch}}"`,
|
||||
},
|
||||
},
|
||||
{
|
||||
executorType: "sprites",
|
||||
want: []string{
|
||||
`if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then`,
|
||||
`if git fetch --depth=1 origin "{{worktree.branch}}" 2>/dev/null; then`,
|
||||
`git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"`,
|
||||
`git checkout -b "{{worktree.branch}}"`,
|
||||
},
|
||||
},
|
||||
// TestDefaultPrepareScripts_NoInlineFeatureBranchCheckout asserts that the
|
||||
// clone-based remote default scripts no longer carry an inline worktree-
|
||||
// branch checkout. The checkout is owned exclusively by the postlude
|
||||
// (KandevBranchCheckoutPostlude) so old stored profiles and the current
|
||||
// default can never disagree about how the feature branch is materialised.
|
||||
func TestDefaultPrepareScripts_NoInlineFeatureBranchCheckout(t *testing.T) {
|
||||
executors := []string{"local_docker", "remote_docker", "sprites"}
|
||||
forbidden := []string{
|
||||
`if [ -n "{{worktree.branch}}" ] && [ "{{worktree.branch}}" != "{{repository.branch}}" ]; then`,
|
||||
`git checkout -B "{{worktree.branch}}" "origin/{{worktree.branch}}"`,
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.executorType, func(t *testing.T) {
|
||||
script := DefaultPrepareScript(tc.executorType)
|
||||
for _, executorType := range executors {
|
||||
t.Run(executorType, func(t *testing.T) {
|
||||
script := DefaultPrepareScript(executorType)
|
||||
if script == "" {
|
||||
t.Fatalf("DefaultPrepareScript(%q) returned empty", tc.executorType)
|
||||
t.Fatalf("DefaultPrepareScript(%q) returned empty", executorType)
|
||||
}
|
||||
for _, want := range tc.want {
|
||||
if !strings.Contains(script, want) {
|
||||
t.Errorf("script for %q missing %q", tc.executorType, want)
|
||||
for _, bad := range forbidden {
|
||||
if strings.Contains(script, bad) {
|
||||
t.Errorf("script for %q must not contain inline checkout %q (postlude owns it)", executorType, bad)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user