Skip to content

Commit 7307ba1

Browse files
committed
Fix validation script: remove Bearer-only tests, move alias test to phase 3, update workflow
- Remove 3 endpoints that tested API key against Bearer-only endpoints (just confirmed 401) - Move GET /templates/aliases/{alias} test to phase 3, use the test template we create there - Update workflow to generate spec, diff, run validation, and create PR with status indicator
1 parent 352c960 commit 7307ba1

3 files changed

Lines changed: 107 additions & 178 deletions

File tree

.github/workflows/api-reference-validation.yml

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ concurrency:
1313
jobs:
1414
validate:
1515
runs-on: ubuntu-latest
16-
timeout-minutes: 15
16+
timeout-minutes: 20
1717
permissions:
1818
contents: write
1919
pull-requests: write
@@ -30,59 +30,104 @@ jobs:
3030
- name: Install dependencies
3131
run: pip install pyyaml
3232

33+
# Step 1: Generate spec from source
34+
- name: Generate OpenAPI spec
35+
run: python3 scripts/generate_openapi_reference.py --output openapi-generated.yml
36+
37+
# Step 2: Compare with committed spec
38+
- name: Compare specs
39+
id: diff
40+
run: |
41+
if diff -q openapi-public.yml openapi-generated.yml > /dev/null 2>&1; then
42+
echo "Spec is up to date — nothing to do"
43+
echo "changed=false" >> $GITHUB_OUTPUT
44+
else
45+
echo "Spec has drifted from source"
46+
echo "changed=true" >> $GITHUB_OUTPUT
47+
fi
48+
49+
# Step 3: If no difference, exit early
50+
# (all subsequent steps are gated on changed == 'true')
51+
52+
# Step 4: Run validation against the NEW generated spec
3353
- name: Run validation
54+
if: steps.diff.outputs.changed == 'true'
55+
id: validate
56+
continue-on-error: true
3457
env:
3558
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
3659
E2B_ACCESS_TOKEN: ${{ secrets.E2B_ACCESS_TOKEN }}
3760
run: |
61+
# Replace committed spec with generated one before validating
62+
cp openapi-generated.yml openapi-public.yml
63+
64+
# Capture the full output; the script exits 1 on critical findings
3865
python3 scripts/validate_api_reference.py \
3966
--output openapi-validation-report.md \
40-
--verbose
67+
--verbose 2>&1 | tee validation-output.txt
4168
42-
- name: Check for changes
43-
id: changes
44-
run: |
45-
if git diff --quiet openapi-validation-report.md 2>/dev/null; then
46-
echo "changed=false" >> $GITHUB_OUTPUT
47-
else
48-
echo "changed=true" >> $GITHUB_OUTPUT
49-
fi
69+
# Extract the final summary block (everything after the last ===... line)
70+
SUMMARY=$(awk '/^={50,}/{buf=""} {buf=buf"\n"$0} END{print buf}' validation-output.txt)
71+
# Store for PR body (escape newlines for GitHub output)
72+
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
73+
echo "summary<<$EOF" >> $GITHUB_OUTPUT
74+
echo "$SUMMARY" >> $GITHUB_OUTPUT
75+
echo "$EOF" >> $GITHUB_OUTPUT
5076
77+
# Step 5+6: Create PR with status indicator
5178
- name: Create PR
52-
if: steps.changes.outputs.changed == 'true'
79+
if: steps.diff.outputs.changed == 'true'
5380
env:
5481
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
82+
VALIDATION_OUTCOME: ${{ steps.validate.outcome }}
83+
VALIDATION_SUMMARY: ${{ steps.validate.outputs.summary }}
5584
run: |
56-
BRANCH="api-validation-$(date +%Y-%m-%d)"
85+
if [ "$VALIDATION_OUTCOME" = "success" ]; then
86+
STATUS_ICON="🟢"
87+
STATUS_TEXT="Validation passed"
88+
else
89+
STATUS_ICON="🔴"
90+
STATUS_TEXT="Validation failed — critical findings detected"
91+
fi
92+
93+
BRANCH="api-spec-update-$(date +%Y-%m-%d)"
5794
git config user.name "github-actions[bot]"
5895
git config user.email "github-actions[bot]@users.noreply.github.com"
5996
6097
git checkout -b "$BRANCH"
61-
git add openapi-validation-report.md
62-
git commit -m "docs: update API validation report $(date +%Y-%m-%d)"
98+
git add openapi-public.yml
99+
if [ -f openapi-validation-report.md ]; then
100+
git add openapi-validation-report.md
101+
fi
102+
git commit -m "docs: update openapi-public.yml from source specs $(date +%Y-%m-%d)"
63103
git push -u origin "$BRANCH"
64104
65105
gh pr create \
66-
--title "API validation report $(date +%Y-%m-%d)" \
67-
--body "$(cat <<'EOF'
68-
## Automated API Reference Validation
106+
--title "$STATUS_ICON Update API spec $(date +%Y-%m-%d)" \
107+
--body "$(cat <<EOF
108+
## OpenAPI Spec Update
109+
110+
The generated \`openapi-public.yml\` has drifted from the source specs.
111+
This PR updates it to match the latest upstream definitions.
69112
70-
Weekly validation of `openapi-public.yml` against the live E2B API.
113+
### Validation: $STATUS_ICON $STATUS_TEXT
71114
72-
Review the updated `openapi-validation-report.md` for any new findings.
115+
\`\`\`
116+
$VALIDATION_SUMMARY
117+
\`\`\`
73118
EOF
74119
)" \
75120
--base main
76121
77122
- name: Summary
123+
if: always()
124+
env:
125+
CHANGED: ${{ steps.diff.outputs.changed }}
126+
VALIDATION_OUTCOME: ${{ steps.validate.outcome }}
78127
run: |
79-
echo "## API Reference Validation" >> $GITHUB_STEP_SUMMARY
128+
echo "## API Reference Spec Check" >> $GITHUB_STEP_SUMMARY
80129
echo "" >> $GITHUB_STEP_SUMMARY
81-
if [ -f openapi-validation-report.md ]; then
82-
# Extract critical findings count
83-
CRITICAL=$(grep -c "critical" openapi-validation-report.md 2>/dev/null || echo "0")
84-
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
85-
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
86-
echo "| Critical findings | $CRITICAL |" >> $GITHUB_STEP_SUMMARY
87-
echo "| Report | openapi-validation-report.md |" >> $GITHUB_STEP_SUMMARY
88-
fi
130+
echo "| Result | Value |" >> $GITHUB_STEP_SUMMARY
131+
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
132+
echo "| Spec changed | ${CHANGED:-false} |" >> $GITHUB_STEP_SUMMARY
133+
echo "| Validation | ${VALIDATION_OUTCOME:-skipped} |" >> $GITHUB_STEP_SUMMARY

openapi-validation-report.md

Lines changed: 12 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# E2B OpenAPI Spec Validation Report
22

3-
**Date**: 2026-02-26 14:07:08 UTC
3+
**Date**: 2026-02-27 14:24:55 UTC
44
**Spec Version**: 0.1.0
5-
**Endpoints Tested**: 68 / 68
5+
**Endpoints Tested**: 59 / 59
66
**Critical Findings**: 0
7-
**Duration**: 42.7s
7+
**Duration**: 33.8s
88

99
## Executive Summary
1010

@@ -17,7 +17,7 @@ No critical findings. The spec matches the live API behavior.
1717
#### GET /teams
1818
- **Tested**: YES
1919
- **Expected Status**: 200
20-
- **Actual Status**: 200
20+
- **Actual Status**: 401
2121
- **Response Schema**:
2222
- Required fields present: YES
2323
- Extra undocumented fields: none
@@ -68,24 +68,6 @@ No critical findings. The spec matches the live API behavior.
6868
- Extra undocumented fields: none
6969
- Type mismatches: none
7070

71-
#### GET /templates/{templateID}
72-
- **Tested**: YES
73-
- **Expected Status**: 200
74-
- **Actual Status**: 200
75-
- **Response Schema**:
76-
- Required fields present: YES
77-
- Extra undocumented fields: none
78-
- Type mismatches: none
79-
80-
#### GET /templates/{templateID}/tags
81-
- **Tested**: YES
82-
- **Expected Status**: 200
83-
- **Actual Status**: 200
84-
- **Response Schema**:
85-
- Required fields present: YES
86-
- Extra undocumented fields: none
87-
- Type mismatches: none
88-
8971
#### GET /templates/{templateID}
9072
- **Tested**: YES
9173
- **Expected Status**: 404
@@ -95,25 +77,25 @@ No critical findings. The spec matches the live API behavior.
9577
- Extra undocumented fields: none
9678
- Type mismatches: none
9779

98-
#### GET /templates/aliases/{alias}
80+
#### GET /templates/{templateID}/files/{hash}
9981
- **Tested**: YES
100-
- **Expected Status**: 200
101-
- **Actual Status**: 200
82+
- **Expected Status**: 404
83+
- **Actual Status**: 404
10284
- **Response Schema**:
10385
- Required fields present: YES
10486
- Extra undocumented fields: none
10587
- Type mismatches: none
10688

107-
#### GET /templates/{templateID}/builds/{buildID}/status
89+
#### POST /v3/templates
10890
- **Tested**: YES
109-
- **Expected Status**: 200
110-
- **Actual Status**: 200
91+
- **Expected Status**: 202
92+
- **Actual Status**: 202
11193
- **Response Schema**:
11294
- Required fields present: YES
11395
- Extra undocumented fields: none
11496
- Type mismatches: none
11597

116-
#### GET /templates/{templateID}/builds/{buildID}/logs
98+
#### GET /templates/aliases/{alias}
11799
- **Tested**: YES
118100
- **Expected Status**: 200
119101
- **Actual Status**: 200
@@ -122,24 +104,6 @@ No critical findings. The spec matches the live API behavior.
122104
- Extra undocumented fields: none
123105
- Type mismatches: none
124106

125-
#### GET /templates/{templateID}/files/{hash}
126-
- **Tested**: YES
127-
- **Expected Status**: 404
128-
- **Actual Status**: 201
129-
- **Response Schema**:
130-
- Required fields present: YES
131-
- Extra undocumented fields: none
132-
- Type mismatches: none
133-
134-
#### POST /v3/templates
135-
- **Tested**: YES
136-
- **Expected Status**: 202
137-
- **Actual Status**: 202
138-
- **Response Schema**:
139-
- Required fields present: YES
140-
- Extra undocumented fields: none
141-
- Type mismatches: none
142-
143107
#### POST /v3/templates
144108
- **Tested**: YES
145109
- **Expected Status**: 400
@@ -176,15 +140,6 @@ No critical findings. The spec matches the live API behavior.
176140
- Extra undocumented fields: none
177141
- Type mismatches: none
178142

179-
#### POST /templates/{templateID}/builds/{buildID}
180-
- **Tested**: YES
181-
- **Expected Status**: 401
182-
- **Actual Status**: 401
183-
- **Response Schema**:
184-
- Required fields present: YES
185-
- Extra undocumented fields: none
186-
- Type mismatches: none
187-
188143
#### POST /v2/templates
189144
- **Tested**: YES
190145
- **Expected Status**: 202
@@ -203,24 +158,6 @@ No critical findings. The spec matches the live API behavior.
203158
- Extra undocumented fields: none
204159
- Type mismatches: none
205160

206-
#### POST /templates
207-
- **Tested**: YES
208-
- **Expected Status**: 401
209-
- **Actual Status**: 401
210-
- **Response Schema**:
211-
- Required fields present: YES
212-
- Extra undocumented fields: none
213-
- Type mismatches: none
214-
215-
#### POST /templates/{templateID}
216-
- **Tested**: YES
217-
- **Expected Status**: 401
218-
- **Actual Status**: 401
219-
- **Response Schema**:
220-
- Required fields present: YES
221-
- Extra undocumented fields: none
222-
- Type mismatches: none
223-
224161
#### POST /templates/tags
225162
- **Tested**: YES
226163
- **Expected Status**: 400
@@ -230,24 +167,6 @@ No critical findings. The spec matches the live API behavior.
230167
- Extra undocumented fields: none
231168
- Type mismatches: none
232169

233-
#### POST /templates/tags
234-
- **Tested**: YES
235-
- **Expected Status**: 201
236-
- **Actual Status**: 201
237-
- **Response Schema**:
238-
- Required fields present: YES
239-
- Extra undocumented fields: none
240-
- Type mismatches: none
241-
242-
#### DELETE /templates/tags
243-
- **Tested**: YES
244-
- **Expected Status**: 204
245-
- **Actual Status**: 204
246-
- **Response Schema**:
247-
- Required fields present: YES
248-
- Extra undocumented fields: none
249-
- Type mismatches: none
250-
251170
#### DELETE /templates/tags
252171
- **Tested**: YES
253172
- **Expected Status**: 400
@@ -332,7 +251,7 @@ No critical findings. The spec matches the live API behavior.
332251
#### GET /sandboxes/{sandboxID}
333252
- **Tested**: YES
334253
- **Expected Status**: 404
335-
- **Actual Status**: 404
254+
- **Actual Status**: 400
336255
- **Response Schema**:
337256
- Required fields present: YES
338257
- Extra undocumented fields: none

0 commit comments

Comments
 (0)