diff --git a/.github/scripts/typecheck-example.sh b/.github/scripts/typecheck-example.sh new file mode 100755 index 0000000..d7ed497 --- /dev/null +++ b/.github/scripts/typecheck-example.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Typecheck one example against an SDK tarball packed from this checkout (#143). +# Usage: typecheck-example.sh +# Network: npm install only. Flags mirror sdk-test.yml (--legacy-peer-deps, see its comment). +set -euo pipefail + +dir=$1 +tgz=$(realpath "$2") +npm_flags=(--no-audit --no-fund --legacy-peer-deps) +cd "$dir" + +if [ -f package-lock.json ]; then + npm ci "${npm_flags[@]}" +else + npm install --no-save "${npm_flags[@]}" +fi + +if node -e 'const p=require("./package.json");process.exit({...p.dependencies,...p.devDependencies}.nirium?0:1)'; then + # Replaces whatever the lockfile pinned (an npm release or a file: link to an unbuilt SDK). + npm install --no-save "${npm_flags[@]}" "$tgz" + # Fail unless nirium resolves to the tarball, not the npm release. + tar -xOzf "$tgz" package/dist/index.d.ts | cmp - node_modules/nirium/dist/index.d.ts + echo "nirium resolves to $(basename "$tgz") ($(node -p 'require("nirium/package.json").version'))" +else + echo "$dir does not depend on nirium; typechecking it as is" +fi + +npx --no-install tsc --noEmit -p . diff --git a/.github/workflows/examples-typecheck.yml b/.github/workflows/examples-typecheck.yml new file mode 100644 index 0000000..b65ecd7 --- /dev/null +++ b/.github/workflows/examples-typecheck.yml @@ -0,0 +1,79 @@ +# Issue #143: typecheck every TypeScript example (examples/*/tsconfig.json) +# against the SDK built from this PR, not the npm release, so an SDK change +# that breaks an example fails here. Examples are discovered at run time, so +# new ones are picked up without editing this file. No secrets; no network +# beyond npm. +name: Examples Typecheck +on: + pull_request: + paths: + - packages/sdk/** + - examples/** + - .github/workflows/examples-typecheck.yml + - .github/scripts/typecheck-example.sh + push: + branches: + - main + paths: + - packages/sdk/** + - examples/** + - .github/workflows/examples-typecheck.yml + - .github/scripts/typecheck-example.sh +permissions: + contents: read +env: + # Examples broken on main today, each with its own issue. They still run but + # do not fail the workflow. Space-separated directory names under examples/. + ALLOWED_TO_FAIL: "" +jobs: + build-sdk: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/sdk + outputs: + examples: ${{ steps.discover.outputs.examples }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm install --no-audit --no-fund --legacy-peer-deps + - run: npm run build + - run: mkdir -p "$RUNNER_TEMP/sdk" && npm pack --pack-destination "$RUNNER_TEMP/sdk" + - uses: actions/upload-artifact@v4 + with: + name: nirium-sdk + path: ${{ runner.temp }}/sdk/nirium-*.tgz + if-no-files-found: error + retention-days: 1 + - id: discover + working-directory: examples + run: | + examples=$(for f in */tsconfig.json; do + d=${f%/tsconfig.json} + allow=false + for a in $ALLOWED_TO_FAIL; do [ "$a" = "$d" ] && allow=true; done + printf '{"name":"%s","allow-failure":%s}\n' "$d" "$allow" + done | jq -sc .) + echo "$examples" | jq . + echo "examples=$examples" >> "$GITHUB_OUTPUT" + typecheck: + needs: build-sdk + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.example.allow-failure }} + strategy: + fail-fast: false + matrix: + example: ${{ fromJSON(needs.build-sdk.outputs.examples) }} + name: typecheck (${{ matrix.example.name }}) + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - uses: actions/download-artifact@v4 + with: + name: nirium-sdk + path: ${{ runner.temp }}/sdk + - run: .github/scripts/typecheck-example.sh "examples/${{ matrix.example.name }}" "$RUNNER_TEMP"/sdk/nirium-*.tgz