Skip to content

Release python 1.0.2: sentinel-based update() so callers can clear nu… #56

Release python 1.0.2: sentinel-based update() so callers can clear nu…

Release python 1.0.2: sentinel-based update() so callers can clear nu… #56

Workflow file for this run

name: CI
# Runs the full test + lint matrix for the Worker and every SDK. Kept
# separate from sdk-e2e.yml so the unit + typecheck jobs stay fast and
# the heavier cross-SDK e2e suite lives on its own.
#
# Each job here is independent, so branch protection can require any
# subset as a blocking check for PRs into main.
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
worker:
name: Worker (yarn test)
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Typecheck
run: yarn tsc --noEmit
- name: Run vitest suite
run: yarn test --run
sdk-typescript:
name: SDK — TypeScript
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
working-directory: sdk/typescript
run: yarn install --frozen-lockfile
- name: Test
working-directory: sdk/typescript
run: yarn test
- name: Build
working-directory: sdk/typescript
run: yarn build
sdk-python:
name: SDK — Python
runs-on: ubuntu-latest
timeout-minutes: 5
strategy:
matrix:
python-version: ['3.10', '3.12']
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dev dependencies
working-directory: sdk/python
run: |
python -m pip install --upgrade pip
pip install -e '.[dev]'
- name: Lint (ruff)
working-directory: sdk/python
run: |
ruff check .
ruff format --check .
- name: Typecheck (mypy --strict)
working-directory: sdk/python
run: mypy --strict src/shrtnr
- name: Test (pytest)
working-directory: sdk/python
run: pytest
sdk-dart:
name: SDK — Dart
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: dart-lang/setup-dart@v1
- name: Install dependencies
working-directory: sdk/dart
run: dart pub get
- name: Analyze
working-directory: sdk/dart
run: dart analyze --fatal-infos
- name: Test
working-directory: sdk/dart
# Unit tier only. E2e tests have `@Tags(['e2e'])` and run separately
# via scripts/test-sdks-e2e.sh against a live wrangler dev.
run: dart test --exclude-tags e2e
browser-extension:
name: Browser extension
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
working-directory: browser-extensions
run: yarn install --frozen-lockfile
- name: Test
working-directory: browser-extensions
run: yarn test
- name: Build
working-directory: browser-extensions
run: yarn build
- name: Verify build artifacts
working-directory: browser-extensions
run: node scripts/verify-build.mjs
- name: Lint Firefox build (web-ext)
working-directory: browser-extensions
# web-ext lint emits warnings (notably for Preact's runtime use of
# innerHTML) without failing. We only fail on errors=0; warnings are
# surfaced in the log for review.
run: yarn lint:firefox
sdk-spec-drift:
name: SDK spec hash parity
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- name: Install root dependencies
run: yarn install --frozen-lockfile
- name: Compute current spec hash
id: current
run: |
hash=$(./scripts/spec-hash.sh)
echo "hash=$hash" >> "$GITHUB_OUTPUT"
echo "Current spec hash: $hash"
- name: Check TypeScript SDK manifest hash
env:
CURRENT: ${{ steps.current.outputs.hash }}
run: |
recorded=$(jq -r '."x-spec-hash"' sdk/typescript/package.json | sed 's/^sha256://')
if [ "$recorded" != "$CURRENT" ]; then
echo "::error file=sdk/typescript/package.json::TypeScript SDK x-spec-hash is stale"
echo " recorded: sha256:$recorded"
echo " current: sha256:$CURRENT"
echo "Resolve by regenerating the SDK against the current spec and bumping the hash, or by updating the hash if the spec change does not affect the SDK surface (see CLAUDE.md)."
exit 1
fi
- name: Check Python SDK manifest hash
env:
CURRENT: ${{ steps.current.outputs.hash }}
run: |
# Parse spec_hash from [tool.shrtnr] only. Bare grep would match any table; awk
# tracks the current section header so it stops at the correct key.
recorded=$(awk '
/^\[/ { current_table = $0 }
current_table == "[tool.shrtnr]" && /^spec_hash *=/ {
gsub(/.*= *"/, ""); gsub(/".*/, "");
print
exit
}
' sdk/python/pyproject.toml | sed 's/^sha256://')
if [ "$recorded" != "$CURRENT" ]; then
echo "::error file=sdk/python/pyproject.toml::Python SDK [tool.shrtnr] spec_hash is stale"
echo " recorded: sha256:$recorded"
echo " current: sha256:$CURRENT"
echo "Resolve by regenerating the SDK against the current spec and bumping the hash, or by updating the hash if the spec change does not affect the SDK surface (see CLAUDE.md)."
exit 1
fi
- name: Check Dart SDK manifest hash
env:
CURRENT: ${{ steps.current.outputs.hash }}
run: |
# Hash is stored as a leading comment to avoid a pana score deduction for unknown top-level keys.
recorded=$(grep '^# x-spec-hash:' sdk/dart/pubspec.yaml | awk '{print $3}' | sed 's/^sha256://')
if [ "$recorded" != "$CURRENT" ]; then
echo "::error file=sdk/dart/pubspec.yaml::Dart SDK x-spec-hash is stale"
echo " recorded: sha256:$recorded"
echo " current: sha256:$CURRENT"
echo "Resolve by regenerating the SDK against the current spec and bumping the hash, or by updating the hash if the spec change does not affect the SDK surface (see CLAUDE.md)."
exit 1
fi