feat(task): opt-in minimal-task system prompt preset for subagents #12551
Workflow file for this run
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] | |
| paths: | |
| - "packages/**" | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - "packages/**" | |
| workflow_dispatch: | |
| inputs: | |
| skip_npm: | |
| description: "Skip npm publish" | |
| type: boolean | |
| default: false | |
| # Release runs publish a `v*` tag pushed atomically with main HEAD; sharing | |
| # the cheap branch-wide `CI-refs/heads/main` group meant a later main push | |
| # silently cancelled the in-flight release and left the tag without a GitHub | |
| # Release or npm publish (#2564). Detect release runs at workflow-scheduling | |
| # time via the release-script commit subject (`chore: bump version to vX.Y.Z`), | |
| # via `v*` tag-ref dispatches, and via manual dispatches whose tag-on-HEAD | |
| # status is only known after checkout; scope them to a per-sha group with no | |
| # cancellation. Every other event keeps branch-wide cancellation for PR/main churn. | |
| concurrency: | |
| group: "${{ github.workflow }}-${{ (startsWith(github.event.head_commit.message, 'chore: bump version to ') || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') && format('release-{0}', github.sha) || github.ref }}" | |
| cancel-in-progress: "${{ !(startsWith(github.event.head_commit.message, 'chore: bump version to ') || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') }}" | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| # glibc floor for shipped linux native addons. The omp-kata runner image is | |
| # Ubuntu 24.04 (glibc 2.39); a plain native build links 2.39 symbol versions | |
| # and fails to dlopen on older distros. Building the linux-gnu addons through | |
| # cargo-zigbuild against this floor keeps them portable. Bump to raise the | |
| # minimum supported glibc. | |
| GLIBC_FLOOR: "2.17" | |
| # audiopus_sys bundles an opus tree whose CMakeLists declares a | |
| # cmake_minimum_required below 3.5; CMake 4.x refuses to configure it | |
| # without this override (macOS runner images ship CMake 4). | |
| CMAKE_POLICY_VERSION_MINIMUM: "3.5" | |
| permissions: | |
| contents: read | |
| actions: read | |
| jobs: | |
| # scripts/release.ts pushes the version-bump commit and its `v*` tag | |
| # atomically (`git push --atomic origin refs/heads/main:refs/heads/main | |
| # <sha>:refs/tags/v<version>`), so a release now arrives as a single `push` to | |
| # `refs/heads/main` — we no longer trigger on the tag ref at all (see | |
| # `on.push`). This one branch-push run is therefore authoritative: it runs the | |
| # full build AND, when HEAD carries a release tag, the release/publish jobs. | |
| # `release_metadata` resolves that tag once so downstream jobs switch on | |
| # `is-release` and address the tag by name — `github.ref` is | |
| # `refs/heads/main` here, not the tag. A `workflow_dispatch` from a `v*` tag | |
| # ref (or from a tagged main HEAD) is also treated as a release. | |
| release_metadata: | |
| name: Resolve release metadata | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| outputs: | |
| is-release: ${{ steps.detect.outputs.is-release }} | |
| release-tag: ${{ steps.detect.outputs.release-tag }} | |
| steps: | |
| # Only a main-branch run needs tags fetched, so `git tag --points-at | |
| # HEAD` can see the freshly-pushed `v*`. A tag-ref dispatch reads the | |
| # tag straight from `github.ref_name`, and fetching `--tags` while | |
| # checkout uses an explicit tag refspec makes git refuse — so scope | |
| # fetch-tags to main refs. | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-tags: ${{ github.ref == 'refs/heads/main' }} | |
| - name: Detect release tag at HEAD | |
| id: detect | |
| shell: bash | |
| run: | | |
| is_release=false | |
| release_tag="" | |
| case "${{ github.ref }}" in | |
| refs/tags/v[0-9]*) | |
| release_tag="${{ github.ref_name }}" | |
| ;; | |
| refs/heads/main) | |
| if [ "${{ github.event_name }}" != "pull_request" ]; then | |
| release_tag=$(git tag --points-at HEAD | grep -E '^v[0-9]' | head -n1 || true) | |
| fi | |
| ;; | |
| esac | |
| if [ -n "$release_tag" ]; then | |
| echo "HEAD carries release tag $release_tag; this run builds and publishes the release." | |
| is_release=true | |
| fi | |
| { | |
| echo "is-release=$is_release" | |
| echo "release-tag=$release_tag" | |
| } >> "$GITHUB_OUTPUT" | |
| # Compute a stable hash of every input that affects the native cdylib output, | |
| # then look for any prior successful main run that already uploaded the | |
| # native artifacts for this hash. Two independent outputs: | |
| # * `linux-x64-run-id` — set when the linux x64 canary | |
| # (`pi-natives-linux-x64-modern-h<hash>`) is present on a prior main run, | |
| # so native-dependent TS test jobs and `native_linux_x64` can reuse it. | |
| # * `cross-platform-run-id` — set when ALL cross-platform native artifacts | |
| # also have non-expired artifacts on that same prior run, so | |
| # `native_cross_platform` can skip the cold rebuild on main pushes after | |
| # dep changes have already warmed sccache there. | |
| # Non-release native jobs are skipped when their canary hits; the canary | |
| # retention window (see build-native action) is the effective TTL. | |
| native_artifact_lookup: | |
| name: Look up cached native artifacts | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| outputs: | |
| source-hash: ${{ steps.compute.outputs.source-hash }} | |
| linux-x64-run-id: ${{ steps.find.outputs.linux-x64-run-id }} | |
| cross-platform-run-id: ${{ steps.find.outputs.cross-platform-run-id }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Compute native source hash | |
| id: compute | |
| shell: bash | |
| run: | | |
| source_hash=$(find crates Cargo.toml Cargo.lock rust-toolchain.toml \ | |
| packages/natives/scripts packages/natives/package.json \ | |
| scripts/ci-build-native.ts scripts/host-detect.ts \ | |
| -type f -print0 \ | |
| | sort -z \ | |
| | xargs -0 sha256sum \ | |
| | sha256sum \ | |
| | cut -c1-16) | |
| echo "source-hash=$source_hash" >> "$GITHUB_OUTPUT" | |
| echo "Native source hash: $source_hash" | |
| - name: Find prior main build with matching native artifacts | |
| id: find | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| hash="${{ steps.compute.outputs.source-hash }}" | |
| # Canary for native_linux_x64: presence of the modern artifact | |
| # implies the baseline sibling is also there (they upload from the | |
| # same job). | |
| linux_canary="pi-natives-linux-x64-modern-h${hash}" | |
| # Required set for cross-platform reuse — names must match the | |
| # `actions/upload-artifact` `name:` template in build-native action. | |
| cross_platform_required=( | |
| "pi-natives-linux-arm64-h${hash}" | |
| "pi-natives-linux-musl-x64-baseline-h${hash}" | |
| "pi-natives-linux-musl-arm64-h${hash}" | |
| "pi-natives-darwin-x64-baseline-h${hash}" | |
| "pi-natives-darwin-arm64-h${hash}" | |
| "pi-natives-win32-x64-baseline-h${hash}" | |
| ) | |
| linux_x64_run_id="" | |
| cross_platform_run_id="" | |
| for candidate in $(gh run list \ | |
| --workflow=ci.yml --branch=main --status=success --event=push \ | |
| --limit=20 --json databaseId --jq='.[].databaseId'); do | |
| names=$(gh api "/repos/${{ github.repository }}/actions/runs/$candidate/artifacts?per_page=100" \ | |
| --jq '.artifacts[] | select(.expired == false) | .name') | |
| if [ -z "$linux_x64_run_id" ] && echo "$names" | grep -qFx "$linux_canary"; then | |
| linux_x64_run_id="$candidate" | |
| fi | |
| if [ -z "$cross_platform_run_id" ]; then | |
| all_found=true | |
| # Cross-platform reuse requires the linux canary AND every | |
| # cross-platform artifact, since release_binary downloads them | |
| # from the same run. | |
| if ! echo "$names" | grep -qFx "$linux_canary"; then | |
| all_found=false | |
| else | |
| for req in "${cross_platform_required[@]}"; do | |
| if ! echo "$names" | grep -qFx "$req"; then | |
| all_found=false | |
| break | |
| fi | |
| done | |
| fi | |
| if $all_found; then | |
| cross_platform_run_id="$candidate" | |
| fi | |
| fi | |
| if [ -n "$linux_x64_run_id" ] && [ -n "$cross_platform_run_id" ]; then | |
| break | |
| fi | |
| done | |
| if [ -n "$linux_x64_run_id" ]; then | |
| echo "Reusing Linux x64 native artifacts from run $linux_x64_run_id" | |
| else | |
| echo "No cached Linux x64 native artifacts for hash $hash; native_linux_x64 will rebuild." | |
| fi | |
| if [ -n "$cross_platform_run_id" ]; then | |
| echo "Reusing cross-platform native artifacts from run $cross_platform_run_id" | |
| else | |
| echo "No cached cross-platform native artifacts for hash $hash; native_cross_platform will rebuild on main." | |
| fi | |
| { | |
| echo "linux-x64-run-id=$linux_x64_run_id" | |
| echo "cross-platform-run-id=$cross_platform_run_id" | |
| } >> "$GITHUB_OUTPUT" | |
| # Fast lint, type check, and browser bundle build (no Rust, no native build needed) | |
| check: | |
| name: Lint, type check & web build | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/bun-install | |
| - name: Type check workspace | |
| run: bun run ci:check:full | |
| - name: Build collab web | |
| run: bun run collab:web:build | |
| # Linux x64 baseline + modern: required by `test`, so it runs on every PR | |
| # unless native_artifact_lookup found a cached run. Release runs always | |
| # rebuild for fresh artifacts but skip clippy + Rust tests (skip_validation): | |
| # the bump commit only changes version strings over content that already | |
| # passed validation on its main-push run. | |
| native_linux_x64: | |
| name: "Native: Linux x64 (${{ matrix.variant }})" | |
| needs: [release_metadata, native_artifact_lookup] | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' || needs.native_artifact_lookup.outputs.linux-x64-run-id == '' }} | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { variant: baseline, rust_checks: true } | |
| - { variant: modern } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/build-native | |
| with: | |
| hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| platform: linux | |
| arch: x64 | |
| variant: ${{ matrix.variant }} | |
| glibc: ${{ env.GLIBC_FLOOR }} | |
| rust_checks: ${{ matrix.rust_checks && 'true' || 'false' }} | |
| skip_validation: ${{ needs.release_metadata.outputs.is-release }} | |
| save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| # Pre-warm the cross-platform native build cache on `main`, in addition to | |
| # building the artifacts that ship in releases. Skipped on main when | |
| # native_artifact_lookup already found a recent run with all artifacts intact. | |
| native_cross_platform_kata: | |
| name: "Native: ${{ matrix.platform }} ${{ matrix.libc || '' }} ${{ matrix.arch }}" | |
| needs: [release_metadata, native_artifact_lookup] | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '') }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: omp-kata, platform: linux, arch: arm64, target: aarch64-unknown-linux-gnu } | |
| - { os: omp-kata, platform: linux, libc: musl, arch: x64, target: x86_64-unknown-linux-musl, variant: baseline } | |
| - { os: omp-kata, platform: linux, libc: musl, arch: arm64, target: aarch64-unknown-linux-musl } | |
| - { os: omp-kata, platform: win32, arch: x64, target: x86_64-pc-windows-msvc, variant: baseline } | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/build-native | |
| with: | |
| hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| platform: ${{ matrix.platform }} | |
| arch: ${{ matrix.arch }} | |
| libc: ${{ matrix.libc }} | |
| variant: ${{ matrix.variant }} | |
| target: ${{ matrix.target }} | |
| glibc: ${{ matrix.platform == 'linux' && matrix.libc != 'musl' && env.GLIBC_FLOOR || '' }} | |
| save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| native_cross_platform_macos: | |
| name: "Native: ${{ matrix.platform }} ${{ matrix.arch }}" | |
| needs: [release_metadata, native_artifact_lookup] | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.native_artifact_lookup.outputs.cross-platform-run-id == '') }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: macos-15-intel, platform: darwin, arch: x64, variant: baseline } | |
| - { os: macos-14, platform: darwin, arch: arm64 } | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/build-native | |
| with: | |
| hash: ${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| platform: ${{ matrix.platform }} | |
| arch: ${{ matrix.arch }} | |
| variant: ${{ matrix.variant }} | |
| target: ${{ matrix.target }} | |
| save_cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| test_workspace: | |
| name: Test TS workspace fast | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test workspace packages and repo scripts (TS) | |
| run: bun run ci:test:ts:workspace | |
| test_coding_agent_singleton: | |
| name: Test coding-agent singleton/global-state (TS) | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test coding-agent singleton/global-state bucket | |
| # Keep global Settings/env/fake-timer tests serial; native addon | |
| # artifacts are still available like every other coding-agent bucket. | |
| run: bun run ci:test:coding-agent:singleton | |
| test_ts_native: | |
| name: Test TS native/integration packages | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test native/TUI/browser-ish packages (TS) | |
| run: bun run ci:test:ts:native | |
| test_coding_agent_ui: | |
| name: Test coding-agent UI/TUI (TS) | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test coding-agent UI/TUI bucket | |
| run: bun run ci:test:coding-agent:ui | |
| test_coding_agent_runtime: | |
| name: Test coding-agent runtime/session (TS) | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test coding-agent runtime bucket | |
| # Runtime/session tests import native-backed barrels too; keep this | |
| # separate for concurrency, not as a native-free guardrail. | |
| run: bun run ci:test:coding-agent:runtime | |
| test_coding_agent_native: | |
| name: Test coding-agent native/unit (TS) | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 25 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Test coding-agent native/unit bucket | |
| run: bun run ci:test:coding-agent:native | |
| test_smoke: | |
| name: Test CLI smoke (TS) | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| needs: [native_linux_x64, native_artifact_lookup] | |
| if: ${{ !cancelled() && needs.native_linux_x64.result != 'failure' }} | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Resolve Linux x64 native artifact run | |
| id: source | |
| shell: bash | |
| run: | | |
| if [ "${{ needs.native_linux_x64.result }}" = "success" ]; then | |
| echo "artifact-run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "artifact-run-id=${{ needs.native_artifact_lookup.outputs.linux-x64-run-id }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Download native addons | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| run-id: ${{ steps.source.outputs.artifact-run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: CLI smoke test | |
| run: bun run ci:test:smoke | |
| install_methods: | |
| name: Install method smoke tests | |
| runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: ./.github/actions/ensure-rust-toolchain | |
| with: | |
| toolchain: nightly-2026-04-29 | |
| - uses: ./.github/actions/ensure-cmake | |
| - name: Detect runner environment | |
| id: detect | |
| shell: bash | |
| run: | | |
| # $SCCACHE_BUCKET is injected only on self-hosted omp-kata pods; its | |
| # presence selects baked sccache + shared S3. GitHub-hosted runners | |
| # (PRs) need sccache-action to export the GHA cache URL/token into the | |
| # step env — a bare binary install leaves SCCACHE_GHA_ENABLED set with | |
| # no cache URL, so sccache server startup fails ("cache url for ghac | |
| # not found"). Mirrors the build-native action's sccache wiring. | |
| if [ -n "${SCCACHE_BUCKET:-}" ]; then | |
| echo "on_infra=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "on_infra=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Ensure baked sccache (omp-kata) | |
| if: steps.detect.outputs.on_infra == 'true' | |
| uses: ./.github/actions/ensure-sccache | |
| with: | |
| version: "0.15.0" | |
| - name: Setup sccache (GitHub-hosted) | |
| if: steps.detect.outputs.on_infra == 'false' | |
| uses: mozilla-actions/sccache-action@v0.0.10 | |
| - name: Enable sccache for cargo | |
| # Conditional backend: self-hosted omp-kata injects a shared S3 | |
| # (RustFS) sccache via pod env; GitHub-hosted runners keep the GHA | |
| # cache. CARGO_INCREMENTAL=0 keeps sccache from silently no-oping. | |
| shell: bash | |
| run: | | |
| { | |
| echo "RUSTC_WRAPPER=sccache" | |
| echo "CARGO_INCREMENTAL=0" | |
| } >> "$GITHUB_ENV" | |
| if [ -n "${SCCACHE_BUCKET:-}" ]; then | |
| echo "sccache backend: shared S3 ($SCCACHE_BUCKET @ $SCCACHE_ENDPOINT)" | |
| else | |
| echo "SCCACHE_GHA_ENABLED=true" >> "$GITHUB_ENV" | |
| echo "sccache backend: GitHub Actions cache" | |
| fi | |
| - uses: ./.github/actions/setup-system-deps | |
| - uses: ./.github/actions/bun-install | |
| - name: Install method smoke tests | |
| run: bun run ci:test:install-methods | |
| release_binary: | |
| name: "Release binary: ${{ matrix.target_id }}" | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && | |
| needs.native_linux_x64.result == 'success' && needs.native_cross_platform_kata.result == | |
| 'success' && needs.native_cross_platform_macos.result == 'success' && | |
| needs.test_workspace.result == 'success' && | |
| needs.test_coding_agent_singleton.result == 'success' && | |
| needs.test_ts_native.result == 'success' && | |
| needs.test_coding_agent_ui.result == 'success' && | |
| needs.test_coding_agent_runtime.result == 'success' && | |
| needs.test_coding_agent_native.result == 'success' && | |
| needs.test_smoke.result == 'success' && needs.check.result == 'success' && | |
| needs.install_methods.result == 'success' }} | |
| needs: [release_metadata, check, native_linux_x64, native_cross_platform_kata, native_cross_platform_macos, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods, native_artifact_lookup] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { | |
| os: ubuntu-22.04, | |
| platform: linux, | |
| arch: x64, | |
| target_id: linux-x64, | |
| binary_path: packages/coding-agent/binaries/omp-linux-x64, | |
| native_artifact_pattern: pi-natives-linux-x64-*, | |
| } | |
| - { | |
| os: ubuntu-22.04, | |
| platform: linux, | |
| libc: musl, | |
| arch: x64, | |
| target_id: linux-musl-x64, | |
| binary_path: packages/coding-agent/binaries/omp-linux-musl-x64, | |
| native_artifact_pattern: pi-natives-linux-musl-x64-*, | |
| } | |
| - { | |
| os: ubuntu-24.04-arm, | |
| platform: linux, | |
| arch: arm64, | |
| target_id: linux-arm64, | |
| binary_path: packages/coding-agent/binaries/omp-linux-arm64, | |
| native_artifact_pattern: pi-natives-linux-arm64*, | |
| } | |
| - { | |
| os: ubuntu-24.04-arm, | |
| platform: linux, | |
| libc: musl, | |
| arch: arm64, | |
| target_id: linux-musl-arm64, | |
| binary_path: packages/coding-agent/binaries/omp-linux-musl-arm64, | |
| native_artifact_pattern: pi-natives-linux-musl-arm64*, | |
| } | |
| - { | |
| os: macos-15-intel, | |
| platform: darwin, | |
| arch: x64, | |
| target_id: darwin-x64, | |
| binary_path: packages/coding-agent/binaries/omp-darwin-x64, | |
| native_artifact_pattern: pi-natives-darwin-x64*, | |
| } | |
| - { | |
| os: macos-14, | |
| platform: darwin, | |
| arch: arm64, | |
| target_id: darwin-arm64, | |
| binary_path: packages/coding-agent/binaries/omp-darwin-arm64, | |
| native_artifact_pattern: pi-natives-darwin-arm64*, | |
| } | |
| - { | |
| os: ubuntu-22.04, | |
| platform: win32, | |
| arch: x64, | |
| target_id: win32-x64, | |
| binary_path: packages/coding-agent/binaries/omp-windows-x64.exe, | |
| native_artifact_pattern: pi-natives-win32-x64*, | |
| } | |
| runs-on: ${{ matrix.os }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| env: | |
| MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }} | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: "1.3" | |
| env: | |
| SCCACHE_BUCKET: "" | |
| AWS_ACCESS_KEY_ID: "" | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: "24" | |
| registry-url: "https://registry.npmjs.org" | |
| # npm runs under Bun when invoked by the release script; npm 12 | |
| # requires a newer emulated Node version than Bun 1.3 provides. | |
| - name: Ensure npm supports trusted publishing | |
| if: ${{ !inputs.skip_npm }} | |
| run: npm install -g npm@11.17.0 | |
| - name: Cache bun dependencies | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} | |
| - run: bun install --frozen-lockfile | |
| - name: Download native addon(s) | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: ${{ matrix.native_artifact_pattern }}-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| - name: Build release binary | |
| env: | |
| RELEASE_TARGETS: ${{ matrix.target_id }} | |
| run: bun run ci:release:build-binaries | |
| - name: Sign and notarize macOS binary (Developer ID) | |
| # Replaces the ad-hoc signature with a Developer ID + hardened-runtime | |
| # one (+JIT/library-validation entitlements; omp dlopens its | |
| # runtime-extracted native addon, which has a different Team ID) and | |
| # notarizes. Auto-skips until the APPLE_* secrets are configured. | |
| if: matrix.platform == 'darwin' && env.MACOS_SIGNING == 'true' | |
| env: | |
| APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| run: bash scripts/ci-macos-sign.sh "${{ matrix.binary_path }}" | |
| # Windows binary is cross-built on Linux, so we have no Windows runner | |
| # to smoke it on. Cross-build correctness is verified via the napi | |
| # entry-point exports (see build-native action) and the bun | |
| # `--compile --target=bun-windows-x64-*` cross-compile. Musl binaries | |
| # need the musl loader, which glibc runners lack — they are smoked in | |
| # the Alpine container step below instead. | |
| - name: Smoke release binary | |
| if: matrix.platform != 'win32' && matrix.libc != 'musl' | |
| run: | | |
| runtime_dir="$(mktemp -d)" | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --version | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --smoke-test | |
| - name: Smoke musl release binary on Alpine | |
| if: matrix.libc == 'musl' | |
| run: | | |
| binary="$(realpath "${{ matrix.binary_path }}")" | |
| # Bun's musl-target binaries link libstdc++/libgcc dynamically; | |
| # Alpine users install them alongside the binary (same as bun itself). | |
| docker run --rm -v "$binary:/usr/local/bin/omp:ro" alpine:3.22 sh -ec ' | |
| apk add --no-cache libstdc++ libgcc >/dev/null | |
| runtime_dir="$(mktemp -d)" | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" omp --version | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" omp --smoke-test | |
| ' | |
| - name: Publish native addon package | |
| if: ${{ !inputs.skip_npm && matrix.libc != 'musl' }} | |
| env: | |
| # Fallback auth: setup-node wrote an .npmrc referencing | |
| # NODE_AUTH_TOKEN; npm uses it only when OIDC has no trusted | |
| # publisher for the package (or on a first publish). | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: bun run ci:release:publish-native-leaf ${{ matrix.target_id }} | |
| - name: Upload release binary artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: omp-binary-${{ matrix.target_id }} | |
| path: ${{ matrix.binary_path }} | |
| release_github: | |
| name: Publish GitHub release | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && | |
| needs.release_binary.result == 'success' }} | |
| needs: [release_metadata, release_binary] | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: "1.3" | |
| - name: Generate release notes from CHANGELOGs | |
| env: | |
| # `gh release list` (used to find the latest published GitHub | |
| # Release tag below the target so silent-tag changelog sections | |
| # roll forward — #2596) requires GH_TOKEN in Actions. Without | |
| # it gh exits non-zero and the script would degrade to legacy | |
| # single-version notes, defeating the recovery. | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun scripts/ci-release-notes.ts ${{ needs.release_metadata.outputs.release-tag }} | |
| - name: Download release binaries | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: omp-binary-* | |
| path: packages/coding-agent/binaries | |
| merge-multiple: true | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2 | |
| with: | |
| tag_name: ${{ needs.release_metadata.outputs.release-tag }} | |
| files: | | |
| packages/coding-agent/binaries/omp-* | |
| body_path: release-notes.md | |
| generate_release_notes: true | |
| release_github_verify: | |
| name: Verify published release (macOS) | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && | |
| needs.release_github.result == 'success' }} | |
| needs: [release_metadata, release_github] | |
| runs-on: macos-14 | |
| permissions: | |
| contents: read | |
| env: | |
| MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }} | |
| steps: | |
| - name: Download published macOS arm64 binary | |
| run: | | |
| curl -fsSL -o omp-darwin-arm64 "https://github.com/${{ github.repository }}/releases/download/${{ needs.release_metadata.outputs.release-tag }}/omp-darwin-arm64" | |
| chmod +x omp-darwin-arm64 | |
| - name: Verify published macOS arm64 binary | |
| run: | | |
| codesign -dvvv ./omp-darwin-arm64 | |
| codesign --verify --strict --verbose=4 ./omp-darwin-arm64 | |
| runtime_dir="$(mktemp -d)" | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" ./omp-darwin-arm64 --version | |
| HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" ./omp-darwin-arm64 --smoke-test | |
| - name: Assert signed release is not ad-hoc | |
| if: env.MACOS_SIGNING == 'true' | |
| run: | | |
| if codesign -dvvv ./omp-darwin-arm64 2>&1 | grep -qE "flags=.*adhoc|Signature=adhoc"; then | |
| echo "published binary is still ad-hoc signed (Developer ID signing did not run)" >&2 | |
| exit 1 | |
| fi | |
| # Gatekeeper assessment: a notarized Developer ID binary is accepted. | |
| # Informational — a bare (unstapled) Mach-O relies on the online ticket | |
| # lookup, so surface the result without gating the release on it. | |
| spctl -a -t exec -vv ./omp-darwin-arm64 || echo "spctl non-zero (expected for unstapled bare binary; ticket served online)" | |
| release_npm: | |
| name: Publish to npm | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && | |
| needs.release_binary.result == 'success' && | |
| needs.release_github_verify.result == 'success' && | |
| !inputs.skip_npm }} | |
| needs: [release_metadata, release_binary, release_github_verify, native_artifact_lookup] | |
| runs-on: ubuntu-22.04 | |
| # `id-token: write` lets npm mint the GitHub OIDC token it exchanges for a | |
| # short-lived publish token (trusted publishing + provenance). When a | |
| # package has no matching trusted publisher configured, npm silently falls | |
| # back to NODE_AUTH_TOKEN below — which also covers first-ever publishes. | |
| permissions: | |
| id-token: write | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: "1.3" | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: "24" | |
| registry-url: "https://registry.npmjs.org" | |
| # npm runs under Bun when invoked by the release script; npm 12 | |
| # requires a newer emulated Node version than Bun 1.3 provides. | |
| - name: Ensure npm supports trusted publishing | |
| run: npm install -g npm@11.17.0 | |
| - name: Cache bun dependencies | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} | |
| - run: bun install --frozen-lockfile | |
| # The pi-coding-agent prepack executes workspace code (bundle-dist | |
| # imports the pi-utils barrel, which loads the pi-natives addon), so | |
| # this job needs the linux x64 native addons just like `test` does. | |
| # Release runs always rebuild natives in this same run, so the | |
| # default run-id resolves the artifacts. | |
| - name: Download native addons | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: pi-natives-linux-x64-*-h${{ needs.native_artifact_lookup.outputs.source-hash }} | |
| path: packages/natives/native | |
| merge-multiple: true | |
| - name: Publish to npm | |
| env: | |
| # Fallback auth: setup-node wrote an .npmrc referencing | |
| # NODE_AUTH_TOKEN; npm uses it only when OIDC has no trusted | |
| # publisher for the package (or on a first publish). | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: bun run ci:release:publish | |
| # Regenerate the Homebrew tap formula (can1357/homebrew-tap) from the freshly | |
| # published release assets and push it. Gated on release_github_verify so the | |
| # tap only cuts over to a release whose published binary was verified (matches | |
| # how release_npm is gated). No-ops when HOMEBREW_TAP_DEPLOY_KEY is unset, so a | |
| # release never blocks on tap access. | |
| release_brew: | |
| name: Update Homebrew tap | |
| if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && | |
| needs.release_github_verify.result == 'success' }} | |
| needs: [release_metadata, release_github_verify] | |
| runs-on: ubuntu-22.04 | |
| env: | |
| HAS_TAP_KEY: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY != '' }} | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| if: env.HAS_TAP_KEY == 'true' | |
| - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| if: env.HAS_TAP_KEY == 'true' | |
| with: | |
| bun-version: "1.3" | |
| - name: Check out the Homebrew tap | |
| if: env.HAS_TAP_KEY == 'true' | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| repository: can1357/homebrew-tap | |
| ssh-key: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }} | |
| path: homebrew-tap | |
| - name: Regenerate and push the formula | |
| if: env.HAS_TAP_KEY == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| bun scripts/ci-update-brew-formula.ts "${{ needs.release_metadata.outputs.release-tag }}" --out homebrew-tap/Formula/omp.rb | |
| cd homebrew-tap | |
| if git diff --quiet -- Formula/omp.rb; then | |
| echo "formula already up to date for ${{ needs.release_metadata.outputs.release-tag }}" | |
| exit 0 | |
| fi | |
| git -c user.name="github-actions[bot]" \ | |
| -c user.email="41898282+github-actions[bot]@users.noreply.github.com" \ | |
| commit -m "omp ${{ needs.release_metadata.outputs.release-tag }}" -- Formula/omp.rb | |
| git push origin HEAD:main |