Repository navigation
feat: Increase base selectors + conditions #316
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: | |
| push: | |
| branches: [main, next] | |
| tags: | |
| - 'v*' | |
| pull_request: | |
| branches: [main, next] | |
| schedule: | |
| - cron: '17 6 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| deploy_workers: | |
| description: Deploy all supported Workers after verification | |
| required: false | |
| type: boolean | |
| default: false | |
| publish_packages: | |
| description: Publish npm packages after verification | |
| required: false | |
| type: boolean | |
| default: false | |
| jobs: | |
| # ─── Fast lint (parallel with build-extract) ────────── | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - run: bun install | |
| - name: Lint | |
| run: bunx vp run verify:lint | |
| - name: NAPI loading contract check | |
| run: | | |
| if grep -rn "require('@animus-ui/extract')" packages/_integration/__tests__/; then | |
| echo "ERROR: require('@animus-ui/extract') in _integration tests violates the NAPI loading contract." | |
| echo "Use require('../../extract/index-v2.js') instead. See packages/_integration/CLAUDE.md." | |
| exit 1 | |
| fi | |
| # ─── Rust unit tests (debug profile, no NAPI binary) ───── | |
| test-rust: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| packages/extract/crates/system-loader | |
| packages/extract/crates/extract-v2 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - run: bun install | |
| - name: Rust unit tests | |
| run: bunx vp run verify:unit:rust | |
| # ─── Strict Rust lint (parallel with test-rust) ──────────── | |
| clippy: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@1.97.0 | |
| with: | |
| components: clippy | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| packages/extract/crates/system-loader | |
| packages/extract/crates/extract-v2 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - run: bun install | |
| - name: Clippy | |
| run: bunx vp run verify:clippy | |
| # ─── Rust dependency hygiene (parallel with test-rust) ─── | |
| hygiene-rust: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| packages/extract/crates/system-loader | |
| packages/extract/crates/extract-v2 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - run: bun install | |
| - name: Install cargo-machete | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-machete@0.9.2 | |
| - name: Rust dependency hygiene | |
| run: bunx vp run verify:hygiene:rust | |
| # ─── Rust NAPI build matrix (release profile, no tests) ── | |
| build-extract: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: aarch64-apple-darwin | |
| runner: macos-14 | |
| - target: x86_64-unknown-linux-gnu | |
| runner: ubuntu-latest | |
| - target: aarch64-unknown-linux-gnu | |
| runner: ubuntu-24.04-arm | |
| optional: true | |
| runs-on: ${{ matrix.runner }} | |
| continue-on-error: ${{ matrix.optional || false }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: | | |
| packages/extract/crates/system-loader | |
| packages/extract/crates/extract-v2 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - run: bun install | |
| - name: Build v2 NAPI binary | |
| working-directory: packages/extract/crates/extract-v2 | |
| run: | | |
| unset RUSTUP_TOOLCHAIN | |
| bunx @napi-rs/cli build --platform --release --target ${{ matrix.target }} | |
| - name: Upload v2 binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: napi-v2-${{ matrix.target }} | |
| path: packages/extract/crates/extract-v2/*.node | |
| if-no-files-found: error | |
| # ─── Full pipeline verification ───────────────────────── | |
| verify: | |
| needs: [build-extract, test-rust] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| # @animus-ui/showcase#verify:build runs on engine v2 (default since the | |
| # 2026-07-13 flip) — the v2 binary is a hard precondition. | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - run: bun install | |
| - name: Verify v2 NAPI binary (repo root context) | |
| run: | | |
| ls -la packages/extract/crates/extract-v2/*.node | |
| bun -e "const m = require('./packages/extract/index-v2.js'); if (typeof m.ExtractEngine !== 'function') { throw new Error('ExtractEngine missing — v2 NAPI load failed'); } console.log('v2 NAPI exports:', Object.keys(m));" | |
| - name: Verify v2 NAPI binary (_integration context) | |
| working-directory: packages/_integration/__tests__ | |
| run: | | |
| bun -e "const m = require('../../extract/index-v2.js'); if (typeof m.ExtractEngine !== 'function') { throw new Error('ExtractEngine not a function — NAPI loading contract violated'); } console.log('OK: ExtractEngine is a function from _integration context');" | |
| - name: Build TS | |
| run: bunx vp run build:ts | |
| - name: Compile | |
| run: bunx vp run verify:compile | |
| - name: Type Contract Tests | |
| run: bunx vp run verify:types | |
| - name: Unit Tests (TS) | |
| run: bunx vp run verify:unit:ts | |
| - name: Canary Tests | |
| run: bunx vp run verify:canary | |
| - name: Parity Oracle | |
| run: bunx vp run verify:parity | |
| - name: Integration Tests | |
| run: bunx vp run verify:integration | |
| - name: Showcase Build + Assert | |
| run: | | |
| bunx vp run @animus-ui/showcase#verify:build | |
| bunx vp run @animus-ui/showcase#verify:assert | |
| - name: Upload lane receipts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: receipts-showcase | |
| path: packages/showcase/.receipts/ | |
| # ─── Next consumer lane (build + assert on every push) ── | |
| verify-next: | |
| needs: [build-extract] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - run: bun install | |
| - name: Build TS | |
| run: bunx vp run build:ts | |
| - name: Next consumer lane | |
| run: | | |
| bunx vp run @animus-ui/next-app#verify:build | |
| bunx vp run @animus-ui/next-app#verify:assert | |
| - name: Upload lane receipts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: receipts-next | |
| path: e2e/next-app/.receipts/ | |
| # ─── Vite consumer lane (build + assert on every push) ── | |
| verify-vite: | |
| needs: [build-extract] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - run: bun install | |
| - name: Build TS | |
| run: bunx vp run build:ts | |
| - name: Vite consumer lane | |
| run: | | |
| bunx vp run @animus-ui/vite-app#verify:build | |
| bunx vp run @animus-ui/vite-app#verify:assert | |
| - name: Upload lane receipts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: receipts-vite | |
| path: e2e/vite-app/.receipts/ | |
| # ─── Supported Worker consumer release gate ──────────── | |
| verify-workers: | |
| needs: [build-extract] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - run: bun install | |
| - name: Build TS | |
| run: bunx vp run build:ts | |
| - name: Verify Worker contracts | |
| run: bunx vp run verify:workers:contracts | |
| - name: Verify supported Workers | |
| run: bunx vp run --fail-if-no-match -F './e2e/*' -F '!@animus-ui/next-app' -F '!animus-packed-app' -F './packages/showcase' verify | |
| # ─── Packed consumer lane (npm staging install on every push) ── | |
| verify-packed: | |
| needs: [build-extract] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - run: bun install | |
| - name: Build TS | |
| run: bunx vp run build:ts | |
| - name: Packed consumer lane | |
| run: bunx vp run verify:packed | |
| - name: Upload lane receipts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: receipts-packed | |
| path: e2e/packed-app/.staging/receipts/ | |
| # ─── Worker deployment (main push, schedule, or explicit dispatch) ── | |
| deploy-workers: | |
| needs: | |
| [ | |
| lint, | |
| clippy, | |
| hygiene-rust, | |
| verify, | |
| verify-next, | |
| verify-vite, | |
| verify-workers, | |
| verify-packed, | |
| ] | |
| if: >- | |
| github.ref == 'refs/heads/main' && | |
| (github.event_name == 'push' || | |
| github.event_name == 'schedule' || | |
| (github.event_name == 'workflow_dispatch' && inputs.deploy_workers == true)) | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: deploy-workers | |
| cancel-in-progress: false | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - name: Download v2 linux binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Validate Workers | |
| run: bash scripts/deploy/workers.sh validate | |
| - name: Deploy Workers | |
| env: | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| run: bash scripts/deploy/workers.sh deploy | |
| # ─── Release (tag push or manual dispatch only) ───────── | |
| release: | |
| needs: | |
| [ | |
| lint, | |
| clippy, | |
| hygiene-rust, | |
| verify, | |
| verify-next, | |
| verify-vite, | |
| verify-workers, | |
| verify-packed, | |
| ] | |
| if: >- | |
| (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || | |
| (github.event_name == 'workflow_dispatch' && inputs.publish_packages == true) | |
| runs-on: ubuntu-latest | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version-file: .tool-versions | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version-file: .tool-versions | |
| registry-url: 'https://registry.npmjs.org' | |
| scope: 'animus-ui' | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} | |
| - run: bun install | |
| - name: Verify npm auth | |
| run: npm whoami | |
| # ── Parse version from tag ── | |
| - name: Set version from tag | |
| id: version | |
| run: | | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]]; then | |
| VERSION="${GITHUB_REF#refs/tags/v}" | |
| else | |
| VERSION="0.0.0-dev.$(date +%s)" | |
| fi | |
| if [[ "$VERSION" == *-* ]]; then | |
| TAG="next" | |
| else | |
| TAG="latest" | |
| fi | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "Publishing version: $VERSION (tag: $TAG)" | |
| # ── Set version in all packages ── | |
| - name: Bump versions and resolve workspace deps | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| for pkg in properties system extract vite-plugin next-plugin; do | |
| jq --arg v "$VERSION" ' | |
| .version = $v | | |
| if .dependencies then .dependencies |= with_entries(if .value == "workspace:*" then .value = $v else . end) else . end | | |
| if .optionalDependencies then .optionalDependencies |= with_entries(if (.value | test("^[0-9]")) then .value = $v else . end) else . end | |
| ' packages/$pkg/package.json > tmp.json && mv tmp.json packages/$pkg/package.json | |
| echo "$pkg → $VERSION" | |
| done | |
| # ── Build TS packages ── | |
| - name: Build | |
| run: bunx vp run build:ts | |
| # ── Download all NAPI binaries ── | |
| # A target missing its v2 binary fails the release job — | |
| # never publish a partial matrix (engine-release-packaging). | |
| - name: Download darwin-arm64 v2 binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-aarch64-apple-darwin | |
| path: packages/extract/crates/extract-v2/ | |
| - name: Download linux-x64 v2 binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-x86_64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| - name: Download linux-arm64 v2 binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: napi-v2-aarch64-unknown-linux-gnu | |
| path: packages/extract/crates/extract-v2/ | |
| # ── Pack and verify one immutable release bundle ── | |
| - name: Pack immutable release bundle | |
| env: | |
| RELEASE_BUNDLE: ${{ runner.temp }}/animus-release-bundle | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| mkdir -p "$RELEASE_BUNDLE" | |
| if compgen -G "$RELEASE_BUNDLE/*.tgz" > /dev/null; then | |
| echo "ERROR: release bundle is not empty: $RELEASE_BUNDLE" >&2 | |
| exit 1 | |
| fi | |
| for pkg in properties system extract vite-plugin next-plugin; do | |
| npm pack "packages/$pkg" --pack-destination "$RELEASE_BUNDLE" --ignore-scripts | |
| done | |
| for artifact in \ | |
| "animus-ui-extract-${VERSION}.tgz" \ | |
| "animus-ui-properties-${VERSION}.tgz" \ | |
| "animus-ui-system-${VERSION}.tgz" \ | |
| "animus-ui-vite-plugin-${VERSION}.tgz" \ | |
| "animus-ui-next-plugin-${VERSION}.tgz"; do | |
| if [ ! -f "$RELEASE_BUNDLE/$artifact" ]; then | |
| echo "ERROR: release artifact missing: $RELEASE_BUNDLE/$artifact" >&2 | |
| exit 1 | |
| fi | |
| done | |
| ls -la "$RELEASE_BUNDLE" | |
| - name: Verify immutable release bundle | |
| env: | |
| RELEASE_BUNDLE: ${{ runner.temp }}/animus-release-bundle | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| bash scripts/verify/postpack-smoke.sh \ | |
| --tarball "$RELEASE_BUNDLE/animus-ui-extract-${VERSION}.tgz" \ | |
| --expect-full-matrix | |
| bash scripts/verify/packed.sh --tarballs-dir "$RELEASE_BUNDLE" | |
| # ── Publish the verified bytes in dependency order ── | |
| - name: Publish immutable release bundle | |
| env: | |
| RELEASE_BUNDLE: ${{ runner.temp }}/animus-release-bundle | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| NPM_TAG="${{ steps.version.outputs.tag }}" | |
| npm publish "$RELEASE_BUNDLE/animus-ui-extract-${VERSION}.tgz" --access public --tag "$NPM_TAG" --ignore-scripts | |
| npm publish "$RELEASE_BUNDLE/animus-ui-properties-${VERSION}.tgz" --access public --tag "$NPM_TAG" --ignore-scripts | |
| npm publish "$RELEASE_BUNDLE/animus-ui-system-${VERSION}.tgz" --access public --tag "$NPM_TAG" --ignore-scripts | |
| npm publish "$RELEASE_BUNDLE/animus-ui-vite-plugin-${VERSION}.tgz" --access public --tag "$NPM_TAG" --ignore-scripts | |
| npm publish "$RELEASE_BUNDLE/animus-ui-next-plugin-${VERSION}.tgz" --access public --tag "$NPM_TAG" --ignore-scripts |