feat(vibenet): add Validity demo for conditional inclusion #247
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| # A queued pull request is tested on a temporary gh-readonly-queue ref, which | |
| # fires neither pull_request nor push. Without this the merge queue waits on | |
| # checks that never start. | |
| merge_group: | |
| push: | |
| branches: | |
| - main | |
| # Cancel superseded runs on the same PR/branch. Merge group runs fall through to | |
| # github.ref, which is unique per queue entry, and are never cancelled — | |
| # cancelling one drops its pull request out of the queue. | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| typecheck: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| - run: npm run typecheck | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| - run: npm run lint | |
| test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| - run: npm test | |
| # End-to-end smoke tests against a production build. Not yet a required | |
| # check — continue-on-error keeps failures visible without blocking merges | |
| # while the suite is still being built out. | |
| e2e: | |
| name: e2e (non-blocking) | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| - run: npx playwright install --with-deps chromium | |
| - run: npm run test:e2e | |
| - name: Upload playwright report | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: playwright-report | |
| path: playwright-report/ | |
| retention-days: 14 | |
| # public/llms.txt, llms-full.txt, and AGENTS.md are generated from the route | |
| # tree and committed. They go stale whenever a route is added, renamed, or | |
| # removed, so this fails if they differ from a fresh generation (it also | |
| # reports sitemap drift). Fix with: npm run llms && npm run agents | |
| docs: | |
| name: docs (generated agent index) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| - run: npm run docs:check | |
| public-build-excludes-internal: | |
| name: public build excludes internal-only surfaces | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 | |
| with: | |
| egress-policy: audit | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| - run: npm ci | |
| # The default (external) build is what ships to Vercel. Deliberately no | |
| # NEXT_PUBLIC_DEPLOY_TARGET here, so this reproduces the public build. | |
| - run: npm run build | |
| # Guards the deployment matrix in deploy.config.mjs: a surface that is not | |
| # shipped to the external target must be unreachable on the public site. | |
| # Without this, dropping the middleware rule — or adding an internal-only | |
| # page and forgetting its SURFACES entry — would silently publish it. | |
| - name: Assert internal-only surfaces are absent | |
| run: | | |
| set -euo pipefail | |
| npx next start -p 3000 & | |
| SERVER_PID=$! | |
| trap 'kill $SERVER_PID 2>/dev/null || true' EXIT | |
| for i in $(seq 1 60); do | |
| if curl -fsS -o /dev/null http://localhost:3000/; then break; fi | |
| if [ "$i" -eq 60 ]; then echo "server never became ready"; exit 1; fi | |
| sleep 1 | |
| done | |
| fail=0 | |
| # Internal-only routes must 404 on the public build. Include the | |
| # legacy /tips prefixes so old URLs stay absent too. | |
| for route in /internal-explorer /internal-explorer/block/0x1 \ | |
| /internal-explorer/bundles/0x1 /api/internal-explorer/blocks \ | |
| /tips /tips/block/0x1 /tips/bundles/0x1 /api/tips/blocks \ | |
| /benchmark /benchmark/run/latest /benchmark/run-comparison/1 \ | |
| /benchmark/load-tests/sepolia; do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}") | |
| if [ "${code}" != "404" ]; then | |
| echo "FAIL: ${route} returned ${code}, expected 404" | |
| fail=1 | |
| fi | |
| done | |
| # Pages that must stay public. | |
| for route in / /snapshots; do | |
| code=$(curl -s -o /dev/null -w '%{http_code}' "http://localhost:3000${route}") | |
| if [ "${code}" != "200" ]; then | |
| echo "FAIL: ${route} returned ${code}, expected 200" | |
| fail=1 | |
| fi | |
| done | |
| # No nav link to, or sitemap entry for, an internal-only section. | |
| for section in /internal-explorer /tips /benchmark; do | |
| if curl -s http://localhost:3000/ | grep -q "href=\"${section}\""; then | |
| echo "FAIL: public homepage links to ${section}" | |
| fail=1 | |
| fi | |
| if curl -s http://localhost:3000/sitemap.xml | grep -q "${section}"; then | |
| echo "FAIL: public sitemap lists ${section}" | |
| fail=1 | |
| fi | |
| done | |
| if [ "${fail}" -ne 0 ]; then exit 1; fi | |
| echo "OK: internal-only surfaces are absent from the public build" |