(
env?: Record<string, string>,
abortSignal?: AbortSignal
)
| 224 | } |
| 225 | |
| 226 | private async setupCredentials( |
| 227 | env?: Record<string, string>, |
| 228 | abortSignal?: AbortSignal |
| 229 | ): Promise<void> { |
| 230 | if (!this.shareCredentials) return; |
| 231 | |
| 232 | if (abortSignal?.aborted) { |
| 233 | throw new RuntimeError("Operation aborted before credential setup", "exec"); |
| 234 | } |
| 235 | |
| 236 | const gitconfigContents = await readHostGitconfig(); |
| 237 | if (gitconfigContents) { |
| 238 | const stream = await this.exec('cat > "$HOME/.gitconfig"', { |
| 239 | cwd: this.getContainerBasePath(), |
| 240 | timeout: 30, |
| 241 | abortSignal, |
| 242 | }); |
| 243 | const writer = stream.stdin.getWriter(); |
| 244 | try { |
| 245 | await writer.write(gitconfigContents); |
| 246 | } finally { |
| 247 | writer.releaseLock(); |
| 248 | } |
| 249 | await stream.stdin.close(); |
| 250 | const exitCode = await stream.exitCode; |
| 251 | if (exitCode !== 0) { |
| 252 | const stderr = await streamToString(stream.stderr); |
| 253 | throw new RuntimeError(`Failed to copy gitconfig: ${stderr}`, "file_io"); |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | const ghToken = resolveGhToken(env); |
| 258 | if (ghToken) { |
| 259 | const stream = await this.exec("command -v gh >/dev/null && gh auth setup-git || true", { |
| 260 | cwd: this.getContainerBasePath(), |
| 261 | timeout: 30, |
| 262 | env: { GH_TOKEN: ghToken }, |
| 263 | abortSignal, |
| 264 | }); |
| 265 | await stream.stdin.close(); |
| 266 | await stream.exitCode; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | private async fetchRemoteHome(abortSignal?: AbortSignal): Promise<void> { |
| 271 | if (!this.currentWorkspacePath) return; |
no test coverage detected