Skip to content

Commit c229da3

Browse files
authored
ci(publish): add post-publish smoke test job (#85)
Add a smoke-test job that runs after publish-npm and verifies the just-published tarball actually installs and runs from the npm registry in clean linux-x64-gnu (debian-slim) and linux-x64-musl (alpine) containers. The existing build-native + pack-npm steps verify the artefact is built correctly. They do not verify a user can actually 'npm install @hyperlight-dev/hyperagent' and have it work — which is the failure mode we were guessing at after v0.2.3. The new job: - polls registry.npmjs.org for up to 5 min for the new version to propagate (distinguishes real breakage from CDN lag) - fetches the published tarball and verifies its sha1 matches the metadata shasum (catches partial/corrupt CDN responses) - 'npm install -g' in a clean container then asserts --version and --help work (proves the bundled Module._load launcher resolved the correct platform .node at runtime, including musl detection) Windows is not smoke-tested here — the win32-x64-msvc launcher path is exercised pre-publish via just test on the win2025 self-hosted runner. macOS is not shipped. Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent dfa04c5 commit c229da3

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,103 @@ jobs:
219219
env:
220220
NODE_AUTH_TOKEN: ${{ github.event_name == 'workflow_dispatch' && secrets.NPM_TOKEN || '' }}
221221

222+
# Post-publish smoke test: install the *just-published* tarball from the npm
223+
# registry into a clean container and verify the bundled launcher resolves
224+
# the correct platform binary.
225+
#
226+
# This is the missing gate that catches:
227+
# - tarball missing native binaries (the Friday-2026-04-23 false-alarm)
228+
# - launcher musl-vs-glibc detection broken
229+
# - file: deps in `dependencies` actually breaking npm install
230+
# - registry replication / CDN propagation lag
231+
# - shasum mismatch between published metadata and tarball blob
232+
#
233+
# We test linux-x64-gnu (debian-slim) and linux-x64-musl (alpine) — the two
234+
# Linux triples we ship. Windows smoke is left out for now (the launcher's
235+
# win32-x64-msvc path is exercised via `just test` pre-publish).
236+
smoke-test:
237+
name: Smoke test (${{ matrix.label }})
238+
needs: [publish-npm]
239+
runs-on: ubuntu-latest
240+
strategy:
241+
fail-fast: false
242+
matrix:
243+
include:
244+
- label: linux-x64-gnu
245+
image: node:22-bookworm-slim
246+
- label: linux-x64-musl
247+
image: node:22-alpine
248+
steps:
249+
- name: Resolve published version
250+
id: ver
251+
run: |
252+
# Release tags arrive as `v0.2.3`; npm strips the leading `v` at
253+
# publish time. Match that here so `npm view <pkg>@<ver>` resolves.
254+
RAW="${{ github.event.release.tag_name || inputs.version }}"
255+
VERSION="${RAW#v}"
256+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
257+
echo "Smoke-testing @hyperlight-dev/hyperagent@$VERSION"
258+
259+
- name: Wait for registry propagation
260+
env:
261+
VERSION: ${{ steps.ver.outputs.version }}
262+
run: |
263+
# Poll registry.npmjs.org for up to 5 minutes for the version to
264+
# become resolvable. Cloudflare/CouchDB replication is usually fast
265+
# but can lag for minutes after a fresh publish.
266+
for i in $(seq 1 30); do
267+
ACTUAL=$(npm view "@hyperlight-dev/hyperagent@$VERSION" version 2>/dev/null || true)
268+
if [ "$ACTUAL" = "$VERSION" ]; then
269+
echo "✅ visible after $((i * 10))s"
270+
exit 0
271+
fi
272+
sleep 10
273+
done
274+
echo "❌ @hyperlight-dev/hyperagent@$VERSION not visible after 300s"
275+
exit 1
276+
277+
- name: Verify tarball blob fetchable + shasum
278+
env:
279+
VERSION: ${{ steps.ver.outputs.version }}
280+
run: |
281+
TARBALL=$(npm view "@hyperlight-dev/hyperagent@$VERSION" dist.tarball)
282+
EXPECTED=$(npm view "@hyperlight-dev/hyperagent@$VERSION" dist.shasum)
283+
ACTUAL=$(curl -sSL --fail "$TARBALL" | sha1sum | awk '{print $1}')
284+
if [ "$ACTUAL" != "$EXPECTED" ]; then
285+
echo "❌ shasum mismatch — expected $EXPECTED got $ACTUAL"
286+
exit 1
287+
fi
288+
echo "✅ tarball fetchable, shasum matches ($EXPECTED)"
289+
290+
- name: Install + run in ${{ matrix.image }}
291+
env:
292+
VERSION: ${{ steps.ver.outputs.version }}
293+
run: |
294+
docker run --rm \
295+
-e VERSION="$VERSION" \
296+
${{ matrix.image }} \
297+
sh -c '
298+
set -e
299+
echo "=== platform ==="
300+
uname -a
301+
cat /etc/os-release 2>/dev/null | head -3 || true
302+
303+
echo "=== install ==="
304+
npm install -g --no-audit --no-fund "@hyperlight-dev/hyperagent@${VERSION}"
305+
306+
echo "=== version check ==="
307+
ACTUAL=$(hyperagent --version 2>&1)
308+
echo "got: $ACTUAL"
309+
echo "$ACTUAL" | grep -q "${VERSION}" \
310+
|| { echo "❌ --version did not match ${VERSION}"; exit 1; }
311+
312+
echo "=== help check ==="
313+
hyperagent --help 2>&1 | grep -q "Usage:" \
314+
|| { echo "❌ --help did not produce expected output"; exit 1; }
315+
316+
echo "✅ smoke passed on ${VERSION}"
317+
'
318+
222319
# Build and publish Docker image (after tests pass)
223320
publish-docker:
224321
name: Publish to GitHub Container Registry

0 commit comments

Comments
 (0)