Skip to content

Commit 93364f4

Browse files
committed
ci: move audit-api-spec to separate workflow
Ticket: DX-2592
1 parent ab2af84 commit 93364f4

File tree

2 files changed

+201
-70
lines changed

2 files changed

+201
-70
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
name: Audit API Spec
2+
3+
on:
4+
pull_request:
5+
6+
env:
7+
STATIC_ANALYSIS_BOT_APP_ID: 1819979
8+
jobs:
9+
generate-head-api-spec:
10+
name: Generate head API spec
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout PR
14+
uses: actions/checkout@v6
15+
with:
16+
ref: ${{ github.event.pull_request.head.sha }}
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v6
20+
with:
21+
node-version: 22
22+
23+
- name: Cache npm dependencies
24+
id: node-modules-cache
25+
uses: actions/cache@v5
26+
with:
27+
path: "**/node_modules"
28+
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
29+
30+
- name: Install Dependencies
31+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
32+
run: npm ci
33+
34+
- name: Generate API spec
35+
run: |
36+
./node_modules/.bin/openapi-generator \
37+
src/masterBitgoExpress/routers/index.ts \
38+
> generated.json
39+
40+
- name: Remove unknown tags from generated spec
41+
run: |
42+
jq '(.paths[] | .[]? | select(. != null)) |= del(."x-unknown-tags")' generated.json > openapi.json
43+
44+
- name: Convert merged spec to YAML
45+
run: yq -P < openapi.json > openapi-head.yaml
46+
47+
- name: Upload API spec to artifact
48+
uses: actions/upload-artifact@v6
49+
with:
50+
name: openapi-head.yaml
51+
path: openapi-head.yaml
52+
53+
generate-merge-base-api-spec:
54+
name: Generate merge base API spec
55+
runs-on: ubuntu-latest
56+
steps:
57+
- name: Checkout PR
58+
uses: actions/checkout@v6
59+
with:
60+
fetch-depth: 0
61+
62+
- name: Find and checkout merge base
63+
run: |
64+
git fetch origin ${{ github.event.pull_request.base.ref }}
65+
MERGE_BASE=$(git merge-base HEAD origin/${{ github.event.pull_request.base.ref }})
66+
echo "Merge base commit: $MERGE_BASE"
67+
git checkout $MERGE_BASE
68+
69+
- name: Setup Node.js
70+
uses: actions/setup-node@v6
71+
with:
72+
node-version: 22
73+
74+
- name: Cache npm dependencies
75+
id: node-modules-cache
76+
uses: actions/cache@v5
77+
with:
78+
path: "**/node_modules"
79+
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
80+
81+
- name: Install Dependencies
82+
if: steps.node-modules-cache.outputs.cache-hit != 'true'
83+
run: npm ci
84+
85+
- name: Generate API spec
86+
run: |
87+
./node_modules/.bin/openapi-generator \
88+
src/masterBitgoExpress/routers/index.ts \
89+
> generated.json
90+
91+
- name: Remove unknown tags from generated spec
92+
run: |
93+
jq '(.paths[] | .[]? | select(. != null)) |= del(."x-unknown-tags")' generated.json > openapi.json
94+
95+
- name: Convert merged spec to YAML
96+
run: yq -P < openapi.json > openapi-merge-base.yaml
97+
98+
- name: Upload API spec to artifact
99+
uses: actions/upload-artifact@v6
100+
with:
101+
name: openapi-merge-base.yaml
102+
path: openapi-merge-base.yaml
103+
104+
generate-vacuum-reports:
105+
name: Generate vacuum reports for API spec
106+
runs-on: ubuntu-latest
107+
needs: [generate-head-api-spec]
108+
steps:
109+
- name: Checkout PR head for ruleset
110+
uses: actions/checkout@v6
111+
with:
112+
ref: ${{ github.event.pull_request.head.sha }}
113+
114+
- name: Download head API spec artifact
115+
uses: actions/download-artifact@v7
116+
with:
117+
name: openapi-head.yaml
118+
119+
- name: Download and install vacuum v0.18.1
120+
run: |
121+
curl -L \
122+
--output vacuum.tar.gz \
123+
--silent \
124+
--show-error \
125+
--fail \
126+
https://github.com/daveshanley/vacuum/releases/download/v0.18.1/vacuum_0.18.1_linux_x86_64.tar.gz
127+
tar -xzf vacuum.tar.gz
128+
chmod u+x vacuum
129+
sudo mv vacuum /usr/local/bin/
130+
vacuum version
131+
132+
- name: Audit head API spec with Vacuum
133+
run: |
134+
vacuum report \
135+
--no-style \
136+
--stdout \
137+
openapi-head.yaml > vacuum-report.json
138+
139+
jq '.resultSet.results // []' vacuum-report.json > vacuum-results.json
140+
141+
ERROR_COUNT=$(jq '[.[] | select(.ruleSeverity == "error")] | length' vacuum-results.json)
142+
WARNING_COUNT=$(jq '[.[] | select(.ruleSeverity == "warn")] | length' vacuum-results.json)
143+
144+
echo "Found $ERROR_COUNT error(s) and $WARNING_COUNT warning(s)"
145+
146+
if [ "$ERROR_COUNT" -gt 0 ]; then
147+
echo "API specification audit failed with $ERROR_COUNT error(s)"
148+
echo ""
149+
echo "Errors:"
150+
jq -r '.[] | select(.ruleSeverity == "error") | " - [\(.ruleId)] \(.message) at \(.path)"' vacuum-results.json
151+
exit 1
152+
else
153+
echo "API specification audit passed!"
154+
fi
155+
156+
check-breaking-changes:
157+
name: Check breaking changes
158+
needs: [generate-head-api-spec, generate-merge-base-api-spec]
159+
runs-on: ubuntu-latest
160+
steps:
161+
- name: Download head API spec artifact
162+
uses: actions/download-artifact@v7
163+
with:
164+
name: openapi-head.yaml
165+
166+
- name: Download merge base API spec artifact
167+
uses: actions/download-artifact@v7
168+
with:
169+
name: openapi-merge-base.yaml
170+
171+
- name: Create static-analysis config file
172+
run: |
173+
cat <<EOF > .static-analysis.yaml
174+
---
175+
api_version: static-analysis.bitgo/v1alpha1
176+
177+
rules:
178+
- path: rules/openapi/breaking-changes
179+
severity: error
180+
options:
181+
before_spec_path: openapi-merge-base.yaml
182+
after_spec_path: openapi-head.yaml
183+
EOF
184+
- name: Generate GitHub App Token
185+
id: generate-github-app-token
186+
uses: actions/create-github-app-token@v2
187+
with:
188+
app-id: ${{ env.STATIC_ANALYSIS_BOT_APP_ID }}
189+
private-key: ${{ secrets.STATIC_ANALYSIS_BOT_PRIVATE_KEY }}
190+
owner: bitgo
191+
repositories: |
192+
static-analysis
193+
194+
- name: Install BitGo/static-analysis/static-analysis@v1
195+
uses: BitGo/install-github-release-binary@v2
196+
with:
197+
targets: BitGo/static-analysis/static-analysis@v1
198+
token: ${{ steps.generate-github-app-token.outputs.token }}
199+
- name: Check breaking changes
200+
run: |
201+
static-analysis

.github/workflows/pull_request.yaml

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -41,73 +41,3 @@ jobs:
4141
VCS_REF=${{ github.sha }}
4242
cache-from: type=gha
4343
cache-to: type=gha,mode=max
44-
45-
audit-api-spec:
46-
name: Audit API Spec
47-
runs-on: ubuntu-latest
48-
49-
steps:
50-
- name: Checkout PR
51-
uses: actions/checkout@v4
52-
with:
53-
ref: ${{ github.event.pull_request.head.sha }}
54-
55-
- name: Setup Node.js
56-
uses: actions/setup-node@v4
57-
with:
58-
node-version: 22
59-
- name: Cache npm dependencies
60-
id: node-modules-cache
61-
uses: actions/cache@v4
62-
with:
63-
path: '**/node_modules'
64-
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
65-
restore-keys: |
66-
${{ runner.os }}-modules-
67-
- name: Install Dependencies
68-
if: steps.node-modules-cache.outputs.cache-hit != 'true'
69-
run: npm ci
70-
71-
- name: Download and install vacuum v0.18.1
72-
run: |
73-
curl -L \
74-
--output vacuum.tar.gz \
75-
--silent \
76-
--show-error \
77-
--fail \
78-
https://github.com/daveshanley/vacuum/releases/download/v0.18.1/vacuum_0.18.1_linux_x86_64.tar.gz
79-
tar -xzf vacuum.tar.gz
80-
chmod u+x vacuum
81-
sudo mv vacuum /usr/local/bin/
82-
vacuum version
83-
84-
- name: Generate API spec
85-
run: |
86-
./node_modules/.bin/openapi-generator \
87-
src/masterBitgoExpress/routers/index.ts \
88-
> api-generated.json
89-
90-
- name: Audit with Vacuum
91-
run: |
92-
vacuum report \
93-
--no-style \
94-
--stdout \
95-
--ruleset ruleset.yaml \
96-
api-generated.json > vacuum-report.json
97-
98-
jq '.resultSet.results // []' vacuum-report.json > vacuum-results.json
99-
100-
ERROR_COUNT=$(jq '[.[] | select(.ruleSeverity == "error")] | length' vacuum-results.json)
101-
WARNING_COUNT=$(jq '[.[] | select(.ruleSeverity == "warn")] | length' vacuum-results.json)
102-
103-
echo "Found $ERROR_COUNT error(s) and $WARNING_COUNT warning(s)"
104-
105-
if [ "$ERROR_COUNT" -gt 0 ]; then
106-
echo "API specification audit failed with $ERROR_COUNT error(s)"
107-
echo ""
108-
echo "Errors:"
109-
jq -r '.[] | select(.ruleSeverity == "error") | " - [\(.ruleId)] \(.message) at \(.path)"' vacuum-results.json
110-
exit 1
111-
else
112-
echo "API specification audit passed!"
113-
fi

0 commit comments

Comments
 (0)