Skip to content

Commit 04537a8

Browse files
authored
Merge branch 'main' into api
2 parents c191ba3 + 822515a commit 04537a8

File tree

87 files changed

+8038
-976
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+8038
-976
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
name: Claude Live Testing
2+
3+
# AI-powered exploratory testing with Playwright MCP
4+
# Trigger: Add 'claude-test' label to PR
5+
# Claude will test the feature with browser automation and provide reports
6+
7+
on:
8+
pull_request_target:
9+
types: [labeled]
10+
branches: [ main, master ]
11+
12+
permissions:
13+
contents: write
14+
pull-requests: write
15+
issues: write
16+
17+
concurrency:
18+
group: claude-test-${{ github.event.pull_request.number }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
# Security check - only proceed if claude-test label was added
23+
check-label:
24+
runs-on: ubuntu-latest
25+
outputs:
26+
should-run: ${{ steps.check.outputs.should-run }}
27+
steps:
28+
- name: Check if claude-test label was added
29+
id: check
30+
run: |
31+
if [ "${{ github.event.label.name }}" = "claude-test" ]; then
32+
echo "should-run=true" >> $GITHUB_OUTPUT
33+
echo "✅ claude-test label added - proceeding with live testing"
34+
else
35+
echo "should-run=false" >> $GITHUB_OUTPUT
36+
echo "⏭️ Label '${{ github.event.label.name }}' is not claude-test - skipping"
37+
fi
38+
39+
claude-live-test:
40+
name: Claude Live Testing
41+
runs-on: ubuntu-latest
42+
needs: check-label
43+
if: needs.check-label.outputs.should-run == 'true'
44+
timeout-minutes: 30
45+
46+
steps:
47+
- name: Checkout PR code
48+
uses: actions/checkout@v6
49+
with:
50+
ref: ${{ github.event.pull_request.head.sha }}
51+
52+
- name: Cleanup Diskspace
53+
uses: kubeflow/pipelines/.github/actions/github-disk-cleanup@master
54+
if: (!cancelled())
55+
56+
- name: Set up Node.js
57+
uses: actions/setup-node@v6
58+
with:
59+
node-version: '20'
60+
61+
- name: Set up Docker Buildx
62+
uses: docker/setup-buildx-action@v3
63+
with:
64+
driver-opts: network=host
65+
66+
- name: Build component images from PR code
67+
run: |
68+
echo "======================================"
69+
echo "Building images from PR code..."
70+
echo "PR #${{ github.event.pull_request.number }}"
71+
echo "SHA: ${{ github.event.pull_request.head.sha }}"
72+
echo "======================================"
73+
74+
# Build all images from PR code
75+
docker build -t quay.io/ambient_code/vteam_frontend:claude-test \
76+
-f components/frontend/Dockerfile components/frontend
77+
78+
docker build -t quay.io/ambient_code/vteam_backend:claude-test \
79+
-f components/backend/Dockerfile components/backend
80+
81+
docker build -t quay.io/ambient_code/vteam_operator:claude-test \
82+
-f components/operator/Dockerfile components/operator
83+
84+
docker build -t quay.io/ambient_code/vteam_claude_runner:claude-test \
85+
-f components/runners/claude-code-runner/Dockerfile components/runners
86+
87+
echo "✅ All images built"
88+
89+
- name: Install kind
90+
run: |
91+
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
92+
chmod +x ./kind
93+
sudo mv ./kind /usr/local/bin/kind
94+
kind version
95+
96+
- name: Setup kind cluster
97+
working-directory: e2e
98+
run: |
99+
chmod +x scripts/*.sh
100+
./scripts/setup-kind.sh
101+
102+
- name: Load images into kind cluster
103+
run: |
104+
echo "Loading images into kind cluster..."
105+
kind load docker-image quay.io/ambient_code/vteam_frontend:claude-test --name ambient-local
106+
kind load docker-image quay.io/ambient_code/vteam_backend:claude-test --name ambient-local
107+
kind load docker-image quay.io/ambient_code/vteam_operator:claude-test --name ambient-local
108+
kind load docker-image quay.io/ambient_code/vteam_claude_runner:claude-test --name ambient-local
109+
echo "✅ All images loaded"
110+
111+
- name: Update kustomization to use claude-test images
112+
run: |
113+
sed -i 's/newTag: latest/newTag: claude-test/g' components/manifests/overlays/e2e/kustomization.yaml
114+
115+
- name: Deploy vTeam
116+
working-directory: e2e
117+
env:
118+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
119+
run: ./scripts/deploy.sh
120+
121+
- name: Verify deployment
122+
run: |
123+
echo "Checking pods..."
124+
kubectl get pods -n ambient-code
125+
echo ""
126+
echo "Checking services..."
127+
kubectl get svc -n ambient-code
128+
129+
- name: Get test token
130+
id: token
131+
run: |
132+
TOKEN=$(kubectl get secret test-user-token -n ambient-code -o jsonpath='{.data.token}' | base64 -d)
133+
echo "token=$TOKEN" >> $GITHUB_OUTPUT
134+
echo "✅ Token retrieved (length: ${#TOKEN})"
135+
136+
- name: Install Playwright
137+
run: |
138+
npm install -g @playwright/mcp
139+
npx playwright install chromium
140+
141+
- name: Create MCP configuration for Playwright
142+
run: |
143+
mkdir -p /tmp/mcp /tmp/test_output
144+
145+
# Create MCP config with video and trace recording
146+
cat > /tmp/mcp/playwright-config.json << 'EOF'
147+
{
148+
"mcpServers": {
149+
"playwright": {
150+
"command": "npx",
151+
"args": [
152+
"@playwright/mcp",
153+
"--headless",
154+
"--caps", "testing,pdf,vision",
155+
"--save-trace",
156+
"--save-video=1280x720",
157+
"--output-dir", "/tmp/test_output"
158+
]
159+
}
160+
}
161+
}
162+
EOF
163+
164+
echo "✅ MCP config created"
165+
cat /tmp/mcp/playwright-config.json
166+
167+
- name: Create test prompt for Claude
168+
id: prompt
169+
env:
170+
PR_NUMBER: ${{ github.event.pull_request.number }}
171+
PR_TITLE: ${{ github.event.pull_request.title }}
172+
PR_BODY: ${{ github.event.pull_request.body }}
173+
PR_ADDITIONS: ${{ github.event.pull_request.additions }}
174+
PR_DELETIONS: ${{ github.event.pull_request.deletions }}
175+
PR_CHANGED_FILES: ${{ github.event.pull_request.changed_files }}
176+
PR_DIFF_URL: ${{ github.event.pull_request.diff_url }}
177+
run: |
178+
# Create prompt with full PR context
179+
cat > /tmp/test-prompt.txt << 'PROMPT_EOF'
180+
You are performing exploratory testing using Playwright MCP browser tools.
181+
182+
## PR Information
183+
**PR #${{ github.event.pull_request.number }}**: ${{ github.event.pull_request.title }}
184+
185+
**Description:**
186+
${{ github.event.pull_request.body }}
187+
188+
**Changes:**
189+
- Files changed: ${{ github.event.pull_request.changed_files }}
190+
- Lines added: +${{ github.event.pull_request.additions }}
191+
- Lines deleted: -${{ github.event.pull_request.deletions }}
192+
- Diff: ${{ github.event.pull_request.diff_url }}
193+
194+
## Test Environment
195+
- App URL: http://localhost
196+
- Test workspace: e2e-claude-test-${{ github.event.pull_request.number }}
197+
198+
## Your Mission
199+
1. Gain na understanding of the PR changes and how you will manually test them using the browser tools. ONLY test the specific features/fixes mentioned in the PR.
200+
1. Navigate to http://localhost
201+
2. Create test workspace: e2e-claude-test-${{ github.event.pull_request.number }}
202+
6. Take screenshots at key moments
203+
7. Write findings to /tmp/test_output/test_report.md
204+
205+
Video/trace recording is automatic. Focus on thorough testing of the PR changes.
206+
PROMPT_EOF
207+
208+
# Save to output
209+
{
210+
echo 'prompt<<GITHUB_OUTPUT_EOF'
211+
cat /tmp/test-prompt.txt
212+
echo 'GITHUB_OUTPUT_EOF'
213+
} >> $GITHUB_OUTPUT
214+
215+
echo "✅ Test prompt created"
216+
217+
- name: Run Claude with Playwright MCP
218+
uses: anthropics/claude-code-action@v1
219+
env:
220+
TEST_TOKEN: ${{ steps.token.outputs.token }}
221+
DEBUG: "*"
222+
with:
223+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
224+
github_token: ${{ secrets.GITHUB_TOKEN }}
225+
prompt: ${{ steps.prompt.outputs.prompt }}
226+
show_full_output: true
227+
claude_args: |
228+
--mcp-config /tmp/mcp/playwright-config.json
229+
--max-turns 50
230+
--model claude-haiku-4-5-20251001
231+
--allowedTools "mcp__playwright__*,Read,Write,List,WebFetch"
232+
--disallowedTools "Bash"
233+
--debug
234+
235+
- name: Upload test report and screenshots
236+
if: always()
237+
uses: actions/upload-artifact@v6
238+
with:
239+
name: claude-test-report-pr-${{ github.event.pull_request.number }}
240+
path: |
241+
/tmp/test_output/test_report.md
242+
/tmp/test_output/*.png
243+
/tmp/test_output/*.pdf
244+
if-no-files-found: ignore
245+
retention-days: 30
246+
247+
- name: Upload Playwright traces (includes video)
248+
if: always()
249+
uses: actions/upload-artifact@v6
250+
with:
251+
name: playwright-traces-pr-${{ github.event.pull_request.number }}
252+
path: /tmp/test_output/traces
253+
if-no-files-found: ignore
254+
retention-days: 30
255+
256+
- name: Debug logs on failure
257+
if: failure()
258+
run: |
259+
echo "=== Frontend logs ==="
260+
kubectl logs -n ambient-code -l app=frontend --tail=100 || true
261+
echo ""
262+
echo "=== Backend logs ==="
263+
kubectl logs -n ambient-code -l app=backend-api --tail=100 || true
264+
echo ""
265+
echo "=== Operator logs ==="
266+
kubectl logs -n ambient-code -l app=agentic-operator --tail=100 || true
267+
268+
- name: Cleanup
269+
if: always()
270+
working-directory: e2e
271+
run: |
272+
CLEANUP_ARTIFACTS=true ./scripts/cleanup.sh || true

.github/workflows/components-build-deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ jobs:
162162
context: ${{ matrix.component.context }}
163163
file: ${{ matrix.component.dockerfile }}
164164
platforms: linux/amd64,linux/arm64
165-
push: false
165+
push: true
166166
tags: ${{ matrix.component.image }}:pr-${{ github.event.pull_request.number }}
167167
cache-from: type=gha
168168
cache-to: type=gha,mode=max

0 commit comments

Comments
 (0)