Skip to content

test(engine): token-shape regression harness for cache/cost invariants #1055

test(engine): token-shape regression harness for cache/cost invariants

test(engine): token-shape regression harness for cache/cost invariants #1055

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Each job runs a single `bun run verify:*` (or underlying) script. Do not
# inline individual check steps here — package.json is the source of truth
# for what "verify" means. If a job needs a new check, add it to the matching
# verify subscript in package.json so local `bun run verify` stays in parity.
jobs:
lint-and-check:
name: Lint & Typecheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Install web dependencies
run: cd web && bun install
- name: Verify (static)
run: bun run verify:static
test-unit:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Install web dependencies
run: cd web && bun install
# Bundle UI deps must be installed so each bundle's co-located tests
# (e.g. the automations markdown sanitizer contract) can resolve their
# own npm dependencies (marked, dompurify, happy-dom). `test:bundles`
# runs `bun test` inside each src/bundles/*/ui package. Mirrors the
# install loop inside build:bundles; CI doesn't build bundles for the
# unit job, so the install must be explicit.
- name: Install bundle UI dependencies
run: bun run install:bundles
- name: Verify (unit + web tests)
run: bun run verify:test-unit
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Integration tests
run: bun run test:integration
smoke:
name: Smoke Tests
# Runs on PRs and on main. Smoke hits the live mpak registry + downloads
# bundles (~15s, network); gating it to main-only previously let a stale
# smoke assertion merge green and turn main red post-merge.
needs: [test-unit, test-integration]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Install mpak
run: npm install -g @nimblebrain/mpak@latest
- name: Smoke tests
run: bun run smoke
# Build + push a SHA-tagged image for every commit that lands on main, so
# `make deploy` can roll out any main commit without a manual local push.
# This is the everyday counterpart to release.yml (which builds on `v*`
# tags): same ECR repos, same `:<short-sha>` tag — a `v*` release just adds
# the version tag and GHCR/`:latest` on top. Gating on every check above
# means an image only exists in ECR if it built green, which closes the
# "deployed a tag that was never pushed" hole.
#
# `if` restricts this to direct pushes to main (post-merge), never PRs — so
# the OIDC/ECR credentials are never exposed to fork PRs, and only verified
# main commits get published.
build-and-push:
name: Build & Push Images
needs: [lint-and-check, test-unit, test-integration, smoke]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: us-east-1
- uses: aws-actions/amazon-ecr-login@v2
id: ecr
- name: Set image tag
id: tag
run: echo "sha=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
- name: Build and push platform image
run: |
docker build --platform linux/amd64 \
--build-arg BUILD_SHA=${{ steps.tag.outputs.sha }} \
-t ${{ steps.ecr.outputs.registry }}/nimblebrain/agent-platform:${{ steps.tag.outputs.sha }} \
-f Dockerfile .
docker push ${{ steps.ecr.outputs.registry }}/nimblebrain/agent-platform:${{ steps.tag.outputs.sha }}
# NOTE: web is built without VITE_TURNSTILE_SITE_KEY (a build-time Vite
# var), matching release.yml. The Makefile `push` target injects a
# per-env key from 1Password; if a build-time Turnstile key is required
# in prod, this image won't carry it. See the deployments Makefile.
- name: Build and push web image
run: |
docker build --platform linux/amd64 \
-t ${{ steps.ecr.outputs.registry }}/nimblebrain/agent-web:${{ steps.tag.outputs.sha }} \
-f web/Dockerfile web/
docker push ${{ steps.ecr.outputs.registry }}/nimblebrain/agent-web:${{ steps.tag.outputs.sha }}