Skip to content

Commit 57eb8e1

Browse files
committed
docs: add GitHub Actions CI/CD use case page
1 parent 2fba168 commit 57eb8e1

2 files changed

Lines changed: 285 additions & 1 deletion

File tree

docs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
{
4646
"group": "Use cases",
4747
"pages": [
48-
"docs/use-cases/computer-use"
48+
"docs/use-cases/computer-use",
49+
"docs/use-cases/ci-cd"
4950
]
5051
},
5152
{

docs/use-cases/ci-cd.mdx

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
---
2+
title: "GitHub Actions CI/CD"
3+
description: "Run AI-powered code review, testing, and validation in secure E2B sandboxes from your GitHub Actions workflows."
4+
icon: "gears"
5+
---
6+
7+
CI/CD pipelines can use AI agents to review pull requests, generate tests, and validate code changes automatically. E2B sandboxes provide the secure, isolated execution environment where these agents can safely clone repositories, run untrusted code, and report results — all triggered by [GitHub Actions](https://docs.github.com/en/actions) on every pull request. Since each run gets a fresh sandbox, malicious or buggy PR code never touches your CI runner.
8+
9+
## How It Works
10+
11+
The AI-powered CI/CD workflow follows this pattern:
12+
13+
1. **A pull request is opened or updated** — GitHub Actions triggers a workflow
14+
2. **The workflow creates an E2B sandbox** — a fresh Linux environment isolated from the CI runner
15+
3. **The repository is cloned into the sandbox** — the PR branch is checked out using E2B's [git integration](/docs/sandbox/git-integration)
16+
4. **An LLM analyzes the changes** — the diff is sent to a language model (e.g., OpenAI GPT-4o, Anthropic Claude) for review or test generation
17+
5. **Tests run inside the sandbox** — the project's test suite executes in isolation, with output streamed back to the workflow
18+
6. **Results are reported** — the workflow posts findings as PR comments via the GitHub API
19+
20+
## Install the E2B SDK
21+
22+
The [E2B SDK](https://github.com/e2b-dev/e2b) provides sandbox creation, command execution, file operations, and git integration for your CI/CD scripts.
23+
24+
<CodeGroup>
25+
```bash JavaScript & TypeScript
26+
npm i e2b
27+
```
28+
```bash Python
29+
pip install e2b
30+
```
31+
</CodeGroup>
32+
33+
## GitHub Actions Workflow
34+
35+
Define a workflow that triggers on pull request events and runs your AI review script. Store your `E2B_API_KEY` and LLM API key as [GitHub Actions secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) — the built-in `GITHUB_TOKEN` is available automatically.
36+
37+
```yaml .github/workflows/ai-review.yml
38+
name: AI Code Review
39+
40+
on:
41+
pull_request:
42+
types: [opened, synchronize]
43+
44+
permissions:
45+
pull-requests: write
46+
47+
jobs:
48+
ai-review:
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
- name: Set up Node.js
54+
uses: actions/setup-node@v4
55+
with:
56+
node-version: "20"
57+
58+
- name: Install dependencies
59+
run: npm install e2b openai
60+
61+
- name: Run AI review
62+
env:
63+
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
64+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
65+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
66+
PR_REPO: ${{ github.event.pull_request.head.repo.full_name }}
67+
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
68+
PR_NUMBER: ${{ github.event.pull_request.number }}
69+
GITHUB_REPOSITORY: ${{ github.repository }}
70+
run: node review.mjs
71+
```
72+
73+
For Python, replace the setup step with `actions/setup-python@v5`, install with `pip install e2b openai`, and run `python review.py` instead.
74+
75+
## Core Implementation
76+
77+
The following snippets show how to build an AI-powered code review script that runs inside the GitHub Actions workflow above.
78+
79+
### Cloning the pull request
80+
81+
Create a sandbox and clone the PR branch. The `GITHUB_TOKEN` provided by GitHub Actions works as the git password when paired with `x-access-token` as the username — this is the standard [GitHub Apps authentication pattern](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation).
82+
83+
<CodeGroup>
84+
```typescript JavaScript & TypeScript
85+
import { Sandbox } from 'e2b'
86+
87+
// Create a sandbox with a 5-minute timeout
88+
const sandbox = await Sandbox.create({ timeoutMs: 300_000 })
89+
90+
const repoUrl = `https://github.com/${process.env.PR_REPO}.git`
91+
92+
// Clone the PR branch into the sandbox
93+
await sandbox.git.clone(repoUrl, {
94+
path: '/home/user/repo',
95+
branch: process.env.PR_BRANCH,
96+
username: 'x-access-token',
97+
password: process.env.GITHUB_TOKEN,
98+
depth: 1,
99+
})
100+
101+
console.log('Repository cloned successfully')
102+
```
103+
```python Python
104+
import os
105+
from e2b import Sandbox
106+
107+
# Create a sandbox with a 5-minute timeout
108+
sandbox = Sandbox.create(timeout=300)
109+
110+
repo_url = f"https://github.com/{os.environ['PR_REPO']}.git"
111+
112+
# Clone the PR branch into the sandbox
113+
sandbox.git.clone(
114+
repo_url,
115+
path="/home/user/repo",
116+
branch=os.environ["PR_BRANCH"],
117+
username="x-access-token",
118+
password=os.environ["GITHUB_TOKEN"],
119+
depth=1,
120+
)
121+
122+
print("Repository cloned successfully")
123+
```
124+
</CodeGroup>
125+
126+
### Running AI code review
127+
128+
Run `git diff` inside the sandbox to collect the changes, then send them to an LLM for analysis. Because the diff is extracted inside the sandbox, even repositories with malicious build hooks cannot affect the CI runner.
129+
130+
<CodeGroup>
131+
```typescript JavaScript & TypeScript
132+
import { Sandbox } from 'e2b'
133+
import OpenAI from 'openai'
134+
135+
const sandbox = await Sandbox.create({ timeoutMs: 300_000 })
136+
137+
// ... clone step from above
138+
139+
// Get the diff against the base branch
140+
const diffResult = await sandbox.commands.run(
141+
'cd /home/user/repo && git diff origin/main...HEAD'
142+
)
143+
const diff = diffResult.stdout
144+
145+
// Send the diff to an LLM for review
146+
const openai = new OpenAI()
147+
const response = await openai.chat.completions.create({
148+
model: 'gpt-4o',
149+
messages: [
150+
{
151+
role: 'system',
152+
content:
153+
'You are a senior code reviewer. Analyze the following git diff and provide a concise review with actionable feedback. Focus on bugs, security issues, and code quality.',
154+
},
155+
{
156+
role: 'user',
157+
content: `Review this diff:\n\n${diff}`,
158+
},
159+
],
160+
})
161+
162+
const review = response.choices[0].message.content
163+
console.log('AI Review:', review)
164+
```
165+
```python Python
166+
import os
167+
from e2b import Sandbox
168+
from openai import OpenAI
169+
170+
sandbox = Sandbox.create(timeout=300)
171+
172+
# ... clone step from above
173+
174+
# Get the diff against the base branch
175+
diff_result = sandbox.commands.run(
176+
"cd /home/user/repo && git diff origin/main...HEAD"
177+
)
178+
diff = diff_result.stdout
179+
180+
# Send the diff to an LLM for review
181+
client = OpenAI()
182+
response = client.chat.completions.create(
183+
model="gpt-4o",
184+
messages=[
185+
{
186+
"role": "system",
187+
"content": "You are a senior code reviewer. Analyze the following git diff and provide a concise review with actionable feedback. Focus on bugs, security issues, and code quality.",
188+
},
189+
{
190+
"role": "user",
191+
"content": f"Review this diff:\n\n{diff}",
192+
},
193+
],
194+
)
195+
196+
review = response.choices[0].message.content
197+
print("AI Review:", review)
198+
```
199+
</CodeGroup>
200+
201+
### Running tests in the sandbox
202+
203+
Use the sandbox to run the project's test suite in isolation, streaming output in real time to the GitHub Actions logs. This ensures that untrusted PR code executes in a sandboxed environment rather than on the CI runner itself.
204+
205+
The `commands.run()` method throws when a command exits with a non-zero code — `CommandExitError` in JavaScript and `CommandExitException` in Python. Catch these to handle test failures gracefully.
206+
207+
<CodeGroup>
208+
```typescript JavaScript & TypeScript
209+
import { Sandbox, CommandExitError } from 'e2b'
210+
211+
const sandbox = await Sandbox.create({ timeoutMs: 300_000 })
212+
213+
// ... clone step from above
214+
215+
// Install dependencies with streaming output
216+
await sandbox.commands.run('cd /home/user/repo && npm install', {
217+
onStdout: (data) => console.log(data),
218+
onStderr: (data) => console.error(data),
219+
})
220+
221+
// Run the test suite
222+
try {
223+
await sandbox.commands.run('cd /home/user/repo && npm test', {
224+
onStdout: (data) => console.log(data),
225+
onStderr: (data) => console.error(data),
226+
})
227+
console.log('All tests passed')
228+
} catch (err) {
229+
if (err instanceof CommandExitError) {
230+
console.error('Tests failed with exit code:', err.exitCode)
231+
process.exit(1)
232+
}
233+
throw err
234+
}
235+
236+
await sandbox.kill()
237+
```
238+
```python Python
239+
import sys
240+
from e2b import Sandbox, CommandExitException
241+
242+
sandbox = Sandbox.create(timeout=300)
243+
244+
# ... clone step from above
245+
246+
# Install dependencies with streaming output
247+
sandbox.commands.run(
248+
"cd /home/user/repo && npm install",
249+
on_stdout=lambda data: print(data),
250+
on_stderr=lambda data: print(data, file=sys.stderr),
251+
)
252+
253+
# Run the test suite
254+
try:
255+
sandbox.commands.run(
256+
"cd /home/user/repo && npm test",
257+
on_stdout=lambda data: print(data),
258+
on_stderr=lambda data: print(data, file=sys.stderr),
259+
)
260+
print("All tests passed")
261+
except CommandExitException as err:
262+
print(f"Tests failed with exit code: {err.exit_code}", file=sys.stderr)
263+
sys.exit(1)
264+
265+
sandbox.kill()
266+
```
267+
</CodeGroup>
268+
269+
To post the AI review as a PR comment, use the GitHub REST API with the `GITHUB_TOKEN`. See [Using the GitHub CLI in workflows](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-github-cli-in-workflows) for more ways to interact with GitHub from your workflow scripts.
270+
271+
## Related Guides
272+
273+
<CardGroup cols={3}>
274+
<Card title="Git Integration" icon="code-branch" href="/docs/sandbox/git-integration">
275+
Clone repos, manage branches, and push changes from sandboxes
276+
</Card>
277+
<Card title="Connect LLMs" icon="brain" href="/docs/quickstart/connect-llms">
278+
Integrate AI models with sandboxes using tool calling
279+
</Card>
280+
<Card title="Custom Templates" icon="cube" href="/docs/template/quickstart">
281+
Build reproducible sandbox environments for your pipelines
282+
</Card>
283+
</CardGroup>

0 commit comments

Comments
 (0)