Clone a Repo into the Sandbox
Echoing strings is cute, but nobody hires you to print "hello." We want to look at real code, in isolation, without trusting it. Step one is getting that code into the Sandbox.
Git is already available inside the Sandbox base image. Cloning is just another runCommand. The interesting part isn't the clone itself, it's verifying that the clone actually worked.
Outcome
Run git clone inside the Sandbox against a real GitHub URL, capture the exit code, and confirm the repo landed in the expected directory.
Fast Track
- Pick a public repo URL (we'll use
https://github.com/vercel/examples). - Run
git clone <url> repoinside the Sandbox. - Check the exit code and log a confirmation.
Hands-on exercise
Open src/sandbox-lifecycle.ts and replace the echo with a clone:
import { Sandbox } from '@vercel/sandbox';
const REPO_URL = 'https://github.com/vercel/examples';
async function main() {
const sandbox = await Sandbox.create({ persistent: false, timeout: 10 * 60 * 1000 });
console.log(`Sandbox created: ${sandbox.name}`);
const clone = await sandbox.runCommand('git', ['clone', '--depth', '1', REPO_URL, 'repo']);
console.log(`Clone exit code: ${clone.exitCode}`);
if (clone.exitCode !== 0) {
console.error(`Clone failed: ${await clone.stderr()}`);
} else {
console.log(`Cloned ${REPO_URL} into repo`);
}
await sandbox.stop();
}
main();Notice we're checking exitCode instead of assuming success. runCommand doesn't throw when the underlying command fails. It returns the exit code immediately; output is available through async methods such as await clone.stderr().
The URL is a separate argument instead of part of a shell string. That prevents repository input from being interpreted as shell syntax, even if another caller bypasses the CLI's URL validation later.
Try breaking it on purpose. Change the URL to https://github.com/this-does-not-exist/nope and run it again. You'll see a non-zero exit code and a "Repository not found" message in stderr. That's the shape of failure we'll keep checking for.
Try It
pnpm tsx src/sandbox-lifecycle.tsExpected output (success case):
Sandbox created: repo-review-...
Clone exit code: 0
Cloned https://github.com/vercel/examples into repoAnd the failure case (bad URL):
Sandbox created: sbx_7N2k4A...
Clone exit code: 128
Clone failed: fatal: repository 'https://github.com/this-does-not-exist/nope/' not foundBoth are good. The first proves the happy path works; the second proves we notice when it doesn't.
Commit
git add src/sandbox-lifecycle.ts
git commit -m "feat(sandbox): clone a repo and check the exit code"Done-When
git cloneruns inside the Sandbox- Exit code is captured and printed
- Success case logs a confirmation
- Failure case logs
stderrinstead of silently passing
Solution
import { Sandbox } from '@vercel/sandbox';
const REPO_URL = 'https://github.com/vercel/examples';
async function main() {
const sandbox = await Sandbox.create({ persistent: false, timeout: 10 * 60 * 1000 });
console.log(`Sandbox created: ${sandbox.name}`);
const clone = await sandbox.runCommand('git', ['clone', '--depth', '1', REPO_URL, 'repo']);
console.log(`Clone exit code: ${clone.exitCode}`);
if (clone.exitCode !== 0) {
console.error(`Clone failed: ${await clone.stderr()}`);
} else {
console.log(`Cloned ${REPO_URL} into repo`);
}
await sandbox.stop();
}
main();Was this helpful?