@@ -147,3 +147,203 @@ jobs:
147147 run : |
148148 ls -lh bin/
149149 file bin/*
150+
151+ e2e-macos :
152+ name : E2E Tests (macOS)
153+ runs-on : macos-latest
154+ strategy :
155+ matrix :
156+ shell : ['bash', 'zsh']
157+
158+ steps :
159+ - name : Generate GitHub App token
160+ id : generate-token
161+ uses : actions/create-github-app-token@v1
162+ with :
163+ app-id : ${{ secrets.BOT_APP_ID }}
164+ private-key : ${{ secrets.BOT_PRIVATE_KEY }}
165+
166+ - name : Checkout code
167+ uses : actions/checkout@v4
168+ with :
169+ token : ${{ steps.generate-token.outputs.token }}
170+
171+ - name : Set up Go
172+ uses : actions/setup-go@v5
173+ with :
174+ go-version : ' 1.23'
175+
176+ - name : Download dependencies
177+ run : go mod download
178+
179+ - name : Build wt binary
180+ run : |
181+ mkdir -p bin
182+ go build -o bin/wt .
183+
184+ - name : Verify binary
185+ run : |
186+ ./bin/wt --help
187+ file bin/wt
188+
189+ - name : Run e2e tests for ${{ matrix.shell }}
190+ run : |
191+ # Set up isolated test environment
192+ export ISOLATED_TMPDIR=$(mktemp -d)
193+ export HOME=$ISOLATED_TMPDIR
194+
195+ # Run specific e2e tests (not ./... to avoid redundancy)
196+ if [ "${{ matrix.shell }}" = "bash" ]; then
197+ go test -v -run 'TestE2EAutoCdWithNonInteractiveCommand|TestE2EAutoCdWithCreate' .
198+ elif [ "${{ matrix.shell }}" = "zsh" ]; then
199+ go test -v -run TestE2EAutoCdInZsh .
200+ fi
201+
202+ # Cleanup (best effort - ignore errors from Go cache files)
203+ rm -rf "$ISOLATED_TMPDIR" 2>/dev/null || true
204+
205+ - name : Test shellenv output
206+ run : |
207+ # Capture shellenv output for inspection
208+ ./bin/wt shellenv > shellenv-${{ matrix.shell }}.txt
209+
210+ # Verify shellenv produces output
211+ if [ ! -s shellenv-${{ matrix.shell }}.txt ]; then
212+ echo "ERROR: shellenv produced no output"
213+ exit 1
214+ fi
215+
216+ # Check for key components (wt function)
217+ if ! grep -q "wt()" shellenv-${{ matrix.shell }}.txt; then
218+ echo "ERROR: wt function not found in shellenv output"
219+ exit 1
220+ fi
221+
222+ # Verify shell-specific features
223+ if [ "${{ matrix.shell }}" = "bash" ]; then
224+ grep -q "BASH_VERSION" shellenv-${{ matrix.shell }}.txt || (echo "ERROR: bash-specific code not found" && exit 1)
225+ elif [ "${{ matrix.shell }}" = "zsh" ]; then
226+ grep -q "ZSH_VERSION" shellenv-${{ matrix.shell }}.txt || (echo "ERROR: zsh-specific code not found" && exit 1)
227+ fi
228+
229+ echo "shellenv validation passed for ${{ matrix.shell }}"
230+
231+ - name : Test worktree CRUD operations with auto-cd
232+ run : |
233+ # Save absolute paths BEFORE changing directories
234+ WORK_DIR=$(pwd)
235+ WT_BIN="$WORK_DIR/bin/wt"
236+ WT_BIN_DIR="$WORK_DIR/bin"
237+
238+ # Create isolated test environment with separate HOME
239+ ISOLATED_HOME=$(mktemp -d)
240+ WORKTREE_ROOT=$(mktemp -d)/worktrees
241+ TEST_REPO=$(mktemp -d)/test-repo
242+
243+ # Generate shellenv script
244+ $WT_BIN shellenv > /tmp/wt-shellenv-${{ matrix.shell }}.sh
245+
246+ # Create test git repo
247+ mkdir -p $TEST_REPO
248+ cd $TEST_REPO
249+ export HOME=$ISOLATED_HOME
250+ git init
251+ git config user.email "[email protected] " 252+ git config user.name "Test User"
253+ git commit --allow-empty -m "initial commit"
254+ git branch -M main
255+
256+ # Create a test branch
257+ git checkout -b test-branch
258+ git commit --allow-empty -m "test commit"
259+ git checkout main
260+
261+ # Determine shell command
262+ if [ "${{ matrix.shell }}" = "bash" ]; then
263+ SHELL_CMD="bash"
264+ else
265+ SHELL_CMD="zsh"
266+ fi
267+
268+ # Save the current PATH so git is available in the subshell
269+ CURRENT_PATH="$PATH"
270+
271+ # Run test in a subshell with shellenv sourced
272+ $SHELL_CMD -c "
273+ export HOME='$ISOLATED_HOME'
274+ export WORKTREE_ROOT='$WORKTREE_ROOT'
275+ export PATH='$WT_BIN_DIR:$CURRENT_PATH'
276+ cd '$TEST_REPO'
277+
278+ source /tmp/wt-shellenv-${{ matrix.shell }}.sh
279+
280+ echo 'Testing: wt checkout test-branch'
281+ wt checkout test-branch
282+
283+ # Verify we're in the worktree directory
284+ CURRENT_DIR=\$(pwd)
285+ EXPECTED_DIR='$WORKTREE_ROOT/test-repo/test-branch'
286+ if [[ \"\$CURRENT_DIR\" != \"\$EXPECTED_DIR\" ]]; then
287+ echo \"ERROR: Auto-cd failed. Expected: \$EXPECTED_DIR, Got: \$CURRENT_DIR\"
288+ exit 1
289+ fi
290+ echo \"✓ Auto-cd to worktree verified: \$CURRENT_DIR\"
291+
292+ # Verify worktree was created
293+ wt list | grep test-branch || (echo 'ERROR: worktree not in list' && exit 1)
294+ echo '✓ Worktree created and listed'
295+
296+ # Go back to original repo to test create
297+ cd '$TEST_REPO'
298+
299+ # Test create command (from main repo)
300+ echo 'Testing: wt create feature-test'
301+ wt create feature-test
302+ CURRENT_DIR=\$(pwd)
303+ EXPECTED_DIR='$WORKTREE_ROOT/test-repo/feature-test'
304+ if [[ \"\$CURRENT_DIR\" != \"\$EXPECTED_DIR\" ]]; then
305+ echo \"ERROR: Auto-cd failed for create. Expected: \$EXPECTED_DIR, Got: \$CURRENT_DIR\"
306+ exit 1
307+ fi
308+ echo \"✓ Auto-cd to new worktree verified: \$CURRENT_DIR\"
309+
310+ # Go back to original repo to test remove
311+ cd '$TEST_REPO'
312+
313+ # Test remove command
314+ echo 'Testing: wt remove test-branch'
315+ wt remove test-branch
316+
317+ # Verify worktree was removed
318+ if wt list | grep test-branch; then
319+ echo 'ERROR: worktree not removed'
320+ exit 1
321+ fi
322+ echo '✓ Worktree removed successfully'
323+
324+ echo 'CRUD operations with auto-cd test passed!'
325+ "
326+
327+ # Cleanup all temporary directories (best effort)
328+ cd "$WORK_DIR"
329+ rm -rf "$ISOLATED_HOME" "$WORKTREE_ROOT" "$TEST_REPO" /tmp/wt-shellenv-${{ matrix.shell }}.sh 2>/dev/null || true
330+
331+ - name : Upload shellenv output as artifact
332+ if : always()
333+ uses : actions/upload-artifact@v4
334+ with :
335+ name : shellenv-output-${{ matrix.shell }}
336+ path : shellenv-${{ matrix.shell }}.txt
337+ retention-days : 7
338+ if-no-files-found : ignore
339+
340+ - name : Upload test logs
341+ if : failure()
342+ uses : actions/upload-artifact@v4
343+ with :
344+ name : e2e-logs-${{ matrix.shell }}
345+ path : |
346+ /tmp/*.log
347+ /var/tmp/*.log
348+ retention-days : 7
349+ if-no-files-found : ignore
0 commit comments