Create an isolated worktree. Returns the worktree path. Throws on failure.
(testName: string)
| 113 | |
| 114 | /** Create an isolated worktree. Returns the worktree path. Throws on failure. */ |
| 115 | create(testName: string): string { |
| 116 | const originalSha = git(['rev-parse', 'HEAD'], this.repoRoot); |
| 117 | |
| 118 | const worktreeBase = path.join(this.repoRoot, '.gstack-worktrees', this.runId); |
| 119 | fs.mkdirSync(worktreeBase, { recursive: true }); |
| 120 | |
| 121 | const worktreePath = path.join(worktreeBase, testName); |
| 122 | |
| 123 | // Create detached worktree at current HEAD |
| 124 | git(['worktree', 'add', '--detach', worktreePath, 'HEAD'], this.repoRoot); |
| 125 | |
| 126 | // Copy gitignored build artifacts that tests need (config-driven) |
| 127 | const { getExternalHosts } = require('../hosts/index'); |
| 128 | for (const hostConfig of getExternalHosts()) { |
| 129 | const hostSrc = path.join(this.repoRoot, hostConfig.hostSubdir); |
| 130 | if (fs.existsSync(hostSrc)) { |
| 131 | copyDirSync(hostSrc, path.join(worktreePath, hostConfig.hostSubdir)); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | const browseDist = path.join(this.repoRoot, 'browse', 'dist'); |
| 136 | if (fs.existsSync(browseDist)) { |
| 137 | copyDirSync(browseDist, path.join(worktreePath, 'browse', 'dist')); |
| 138 | } |
| 139 | |
| 140 | const info: WorktreeInfo = { |
| 141 | path: worktreePath, |
| 142 | testName, |
| 143 | originalSha, |
| 144 | createdAt: Date.now(), |
| 145 | }; |
| 146 | this.active.set(testName, info); |
| 147 | |
| 148 | return worktreePath; |
| 149 | } |
| 150 | |
| 151 | /** Harvest changes from a worktree. Returns null if clean or on error. */ |
| 152 | harvest(testName: string): HarvestResult | null { |
no test coverage detected