Skip to content

Commit 8bba78c

Browse files
ci(safe-docx): add npm install retries across CI and release (#4)
Transient npm registry 403 failures on esbuild tarball fetches were causing false-negative pipeline failures in jobs that failed before any project checks ran.\n\nWrapping npm ci with bounded retry/backoff improves resilience to short-lived npm/network policy hiccups while preserving strict failure behavior after three attempts.\n\nRef: #3
1 parent b3dab9b commit 8bba78c

File tree

2 files changed

+202
-73
lines changed

2 files changed

+202
-73
lines changed

.github/workflows/ci.yml

Lines changed: 163 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@ jobs:
1616
with:
1717
node-version: 20
1818
cache: npm
19-
- run: npm ci
19+
- name: Install dependencies (npm ci with retry)
20+
run: |
21+
for attempt in 1 2 3; do
22+
echo "npm ci attempt ${attempt}/3"
23+
if npm ci; then
24+
exit 0
25+
fi
26+
if [ "$attempt" -lt 3 ]; then
27+
sleep $((attempt * 20))
28+
fi
29+
done
30+
echo "npm ci failed after 3 attempts"
31+
exit 1
2032
- name: Build workspaces
2133
run: npm run build
2234
- name: Lint/typecheck workspaces
@@ -30,7 +42,19 @@ jobs:
3042
with:
3143
node-version: 20
3244
cache: npm
33-
- run: npm ci
45+
- name: Install dependencies (npm ci with retry)
46+
run: |
47+
for attempt in 1 2 3; do
48+
echo "npm ci attempt ${attempt}/3"
49+
if npm ci; then
50+
exit 0
51+
fi
52+
if [ "$attempt" -lt 3 ]; then
53+
sleep $((attempt * 20))
54+
fi
55+
done
56+
echo "npm ci failed after 3 attempts"
57+
exit 1
3458
- name: Validate OpenSpec traceability coverage
3559
run: npm run check:spec-coverage
3660

@@ -42,7 +66,19 @@ jobs:
4266
with:
4367
node-version: 20
4468
cache: npm
45-
- run: npm ci
69+
- name: Install dependencies (npm ci with retry)
70+
run: |
71+
for attempt in 1 2 3; do
72+
echo "npm ci attempt ${attempt}/3"
73+
if npm ci; then
74+
exit 0
75+
fi
76+
if [ "$attempt" -lt 3 ]; then
77+
sleep $((attempt * 20))
78+
fi
79+
done
80+
echo "npm ci failed after 3 attempts"
81+
exit 1
4682
- name: Regenerate and verify tool reference docs are committed
4783
run: npm run check:tool-docs
4884

@@ -54,7 +90,19 @@ jobs:
5490
with:
5591
node-version: 20
5692
cache: npm
57-
- run: npm ci
93+
- name: Install dependencies (npm ci with retry)
94+
run: |
95+
for attempt in 1 2 3; do
96+
echo "npm ci attempt ${attempt}/3"
97+
if npm ci; then
98+
exit 0
99+
fi
100+
if [ "$attempt" -lt 3 ]; then
101+
sleep $((attempt * 20))
102+
fi
103+
done
104+
echo "npm ci failed after 3 attempts"
105+
exit 1
58106
- name: Validate MCPB manifest/tool contract
59107
run: npm run check:mcpb-manifest
60108

@@ -66,7 +114,19 @@ jobs:
66114
with:
67115
node-version: 20
68116
cache: npm
69-
- run: npm ci
117+
- name: Install dependencies (npm ci with retry)
118+
run: |
119+
for attempt in 1 2 3; do
120+
echo "npm ci attempt ${attempt}/3"
121+
if npm ci; then
122+
exit 0
123+
fi
124+
if [ "$attempt" -lt 3 ]; then
125+
sleep $((attempt * 20))
126+
fi
127+
done
128+
echo "npm ci failed after 3 attempts"
129+
exit 1
70130
- name: Validate Allure hierarchy labels
71131
run: npm run check:allure-labels
72132
- name: Enforce Allure filename migration policy
@@ -75,48 +135,110 @@ jobs:
75135
workspace-test:
76136
runs-on: ubuntu-latest
77137
needs: workspace-lint
138+
permissions:
139+
contents: read
140+
id-token: write
78141
strategy:
79142
matrix:
80143
node-version: [20, 22]
144+
include:
145+
- node-version: 20
146+
coverage: true
147+
- node-version: 22
148+
coverage: false
81149
steps:
82150
- uses: actions/checkout@v4
83151
- uses: actions/setup-node@v4
84152
with:
85153
node-version: ${{ matrix.node-version }}
86154
cache: npm
87-
- run: npm ci
155+
- name: Install dependencies (npm ci with retry)
156+
run: |
157+
for attempt in 1 2 3; do
158+
echo "npm ci attempt ${attempt}/3"
159+
if npm ci; then
160+
exit 0
161+
fi
162+
if [ "$attempt" -lt 3 ]; then
163+
sleep $((attempt * 20))
164+
fi
165+
done
166+
echo "npm ci failed after 3 attempts"
167+
exit 1
88168
- name: Build workspaces
89169
run: npm run build
90-
- name: Test workspaces
91-
run: npm run test
92-
93-
package-smoke:
94-
runs-on: ubuntu-latest
95-
needs: workspace-test
96-
steps:
97-
- uses: actions/checkout@v4
98-
- uses: actions/setup-node@v4
99-
with:
100-
node-version: 20
101-
cache: npm
102-
- run: npm ci
103-
- name: Package-level smoke tests
170+
- name: Test workspaces (with coverage)
171+
if: matrix.coverage
104172
run: |
105-
npm run test:run -w @usejunior/docx-core
106-
npm run test:run -w @usejunior/docx-mcp
173+
npm run test:coverage -w @usejunior/docx-core
174+
npm run test:coverage -w @usejunior/docx-mcp
107175
npm run test:run -w @usejunior/safe-docx
108176
npm run test:run -w @usejunior/safedocx-mcpb
177+
- name: Test workspaces
178+
if: ${{ !matrix.coverage }}
179+
run: npm run test
180+
- name: Generate package coverage dashboard + enforce ratchet
181+
if: matrix.coverage
182+
run: |
183+
mkdir -p coverage
184+
npm run coverage:packages:check > coverage/package-coverage-table.txt
185+
cat coverage/package-coverage-table.txt
186+
- name: Upload package coverage artifacts
187+
if: ${{ matrix.coverage && always() }}
188+
uses: actions/upload-artifact@v4
189+
with:
190+
name: package-coverage
191+
if-no-files-found: error
192+
path: |
193+
coverage/package-coverage-baseline.json
194+
coverage/package-coverage-summary.json
195+
coverage/package-coverage-table.txt
196+
packages/docx-core/coverage/coverage-summary.json
197+
packages/docx-mcp/coverage/coverage-summary.json
198+
packages/docx-core/coverage/lcov.info
199+
packages/docx-mcp/coverage/lcov.info
200+
- name: Upload coverage to Codecov
201+
if: ${{ matrix.coverage && !cancelled() }}
202+
continue-on-error: true
203+
uses: codecov/codecov-action@v5
204+
with:
205+
files: ./packages/docx-core/coverage/lcov.info,./packages/docx-mcp/coverage/lcov.info
206+
disable_search: true
207+
use_oidc: true
208+
fail_ci_if_error: false
209+
verbose: true
210+
- name: Upload allure results
211+
if: matrix.coverage
212+
uses: actions/upload-artifact@v4
213+
with:
214+
name: allure-results
215+
if-no-files-found: error
216+
path: |
217+
packages/docx-core/allure-results/
218+
packages/docx-mcp/allure-results/
109219
110220
mcpb-bundle:
111221
runs-on: ubuntu-latest
112-
needs: package-smoke
222+
needs: workspace-test
113223
steps:
114224
- uses: actions/checkout@v4
115225
- uses: actions/setup-node@v4
116226
with:
117227
node-version: 20
118228
cache: npm
119-
- run: npm ci
229+
- name: Install dependencies (npm ci with retry)
230+
run: |
231+
for attempt in 1 2 3; do
232+
echo "npm ci attempt ${attempt}/3"
233+
if npm ci; then
234+
exit 0
235+
fi
236+
if [ "$attempt" -lt 3 ]; then
237+
sleep $((attempt * 20))
238+
fi
239+
done
240+
echo "npm ci failed after 3 attempts"
241+
exit 1
120242
- name: Sanitize npm auth for public npx fetches
121243
run: |
122244
unset NODE_AUTH_TOKEN
@@ -150,7 +272,23 @@ jobs:
150272
with:
151273
node-version: 20
152274
cache: npm
153-
- run: npm ci
275+
- name: Install dependencies (npm ci with retry)
276+
run: |
277+
for attempt in 1 2 3; do
278+
echo "npm ci attempt ${attempt}/3"
279+
if npm ci; then
280+
exit 0
281+
fi
282+
if [ "$attempt" -lt 3 ]; then
283+
sleep $((attempt * 20))
284+
fi
285+
done
286+
echo "npm ci failed after 3 attempts"
287+
exit 1
288+
- name: Download allure results
289+
uses: actions/download-artifact@v4
290+
with:
291+
name: allure-results
154292
- name: Generate Allure report
155293
run: npm run allure:generate
156294
- name: Brand Allure report
@@ -162,48 +300,3 @@ jobs:
162300
- name: Deploy to GitHub Pages
163301
id: deployment
164302
uses: actions/deploy-pages@v4
165-
166-
package-coverage:
167-
runs-on: ubuntu-latest
168-
needs: workspace-test
169-
permissions:
170-
contents: read
171-
id-token: write
172-
steps:
173-
- uses: actions/checkout@v4
174-
- uses: actions/setup-node@v4
175-
with:
176-
node-version: 20
177-
cache: npm
178-
- run: npm ci
179-
- name: Run package coverage suites
180-
run: npm run test:coverage:packages
181-
- name: Generate package coverage dashboard + enforce ratchet
182-
run: |
183-
mkdir -p coverage
184-
npm run coverage:packages:check > coverage/package-coverage-table.txt
185-
cat coverage/package-coverage-table.txt
186-
- name: Upload package coverage artifacts
187-
if: ${{ always() }}
188-
uses: actions/upload-artifact@v4
189-
with:
190-
name: package-coverage
191-
if-no-files-found: error
192-
path: |
193-
coverage/package-coverage-baseline.json
194-
coverage/package-coverage-summary.json
195-
coverage/package-coverage-table.txt
196-
packages/docx-core/coverage/coverage-summary.json
197-
packages/docx-mcp/coverage/coverage-summary.json
198-
packages/docx-core/coverage/lcov.info
199-
packages/docx-mcp/coverage/lcov.info
200-
- name: Upload coverage to Codecov
201-
if: ${{ !cancelled() }}
202-
continue-on-error: true
203-
uses: codecov/codecov-action@v5
204-
with:
205-
files: ./packages/docx-core/coverage/lcov.info,./packages/docx-mcp/coverage/lcov.info
206-
disable_search: true
207-
use_oidc: true
208-
fail_ci_if_error: false
209-
verbose: true

.github/workflows/release.yml

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,19 @@ jobs:
6363
exit 1
6464
fi
6565
66-
- run: npm ci
66+
- name: Install dependencies (npm ci with retry)
67+
run: |
68+
for attempt in 1 2 3; do
69+
echo "npm ci attempt ${attempt}/3"
70+
if npm ci; then
71+
exit 0
72+
fi
73+
if [ "$attempt" -lt 3 ]; then
74+
sleep $((attempt * 20))
75+
fi
76+
done
77+
echo "npm ci failed after 3 attempts"
78+
exit 1
6779
6880
- name: Lint/typecheck workspaces
6981
run: npm run lint:workspaces
@@ -155,7 +167,19 @@ jobs:
155167
- name: Use npm 11.5.1+ for OIDC trusted publishing compatibility
156168
run: npm install --global npm@11.5.1
157169

158-
- run: npm ci
170+
- name: Install dependencies (npm ci with retry)
171+
run: |
172+
for attempt in 1 2 3; do
173+
echo "npm ci attempt ${attempt}/3"
174+
if npm ci; then
175+
exit 0
176+
fi
177+
if [ "$attempt" -lt 3 ]; then
178+
sleep $((attempt * 20))
179+
fi
180+
done
181+
echo "npm ci failed after 3 attempts"
182+
exit 1
159183
160184
- name: Publish to npm (trusted publishing)
161185
run: |
@@ -201,7 +225,19 @@ jobs:
201225
- name: Use npm 11.5.1+ for OIDC trusted publishing compatibility
202226
run: npm install --global npm@11.5.1
203227

204-
- run: npm ci
228+
- name: Install dependencies (npm ci with retry)
229+
run: |
230+
for attempt in 1 2 3; do
231+
echo "npm ci attempt ${attempt}/3"
232+
if npm ci; then
233+
exit 0
234+
fi
235+
if [ "$attempt" -lt 3 ]; then
236+
sleep $((attempt * 20))
237+
fi
238+
done
239+
echo "npm ci failed after 3 attempts"
240+
exit 1
205241
206242
- name: Sanitize npm auth for public npx fetches
207243
run: |

0 commit comments

Comments
 (0)