From a5a06c1be8e4fb47fed6a558e10626602acb78a1 Mon Sep 17 00:00:00 2001 From: can1357 Date: Thu, 30 Apr 2026 14:38:43 +0200 Subject: [PATCH] ci: drop x86-64-v3 native variants for win32/darwin-x64 and clean up release flow - Drop the modern (x86-64-v3) native build matrix entries for darwin-x64 and win32-x64. Linux x64 still ships both variants. Loader fallback chain (modern -> baseline -> default) means hosts on those platforms now load baseline; npm install via @oh-my-pi/pi-natives and the embedded standalone binary both keep working unchanged. - Stop downloading .node files in scripts/install.sh and scripts/install.ps1. The standalone omp binary embeds the native at compile time, so the separate downloads were redundant and were going to 404 on platforms with no modern variant. - Stop publishing standalone .node files to GitHub Releases. The npm registry is the only consumer that needs them. - Drop the release-archives build entirely (omp-*.tar.gz). Nothing consumed them. Deleted scripts/ci-release-build-archives.ts and the ci:release:build-archives package script. - Split the monolithic release job into release-github (download omp-* binaries, upload to GitHub Release) and release-npm (download natives, bun publish). Each job's steps now obviously serve its single output. --- .github/workflows/ci.yml | 762 ++++++++++++++------------- package.json | 1 - scripts/ci-release-build-archives.ts | 96 ---- scripts/install.ps1 | 11 - scripts/install.sh | 20 - 5 files changed, 395 insertions(+), 495 deletions(-) delete mode 100644 scripts/ci-release-build-archives.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a69e74e19..6c93510c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,380 +1,408 @@ name: CI on: - push: - branches: [main] - tags: ["v*"] - pull_request: - branches: [main] - workflow_dispatch: - inputs: - skip_npm: - description: "Skip npm publish" - type: boolean - default: false + push: + branches: [main] + tags: ["v*"] + pull_request: + branches: [main] + workflow_dispatch: + inputs: + skip_npm: + description: "Skip npm publish" + type: boolean + default: false concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - # Compute a stable hash of every input that affects the native cdylib output, - # then look for a prior successful main build that already produced artifacts - # with this hash. If found, downstream consumers reuse those artifacts and - # the native job is skipped entirely. - rust-hash: - runs-on: ubuntu-22.04 - outputs: - hash: ${{ steps.compute.outputs.hash }} - run-id: ${{ steps.find.outputs.run-id }} - steps: - - uses: actions/checkout@v4 - - name: Compute rust source hash - id: compute - shell: bash - run: | - 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 "hash=$hash" >> "$GITHUB_OUTPUT" - echo "Rust source hash: $hash" - - name: Find prior main build with matching hash - id: find - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash - run: | - hash="${{ steps.compute.outputs.hash }}" - # Canary artifact: main always builds linux-x64-modern, so its presence - # implies the run has the full multi-platform set we need. - canary="pi-natives-linux-x64-modern-h${hash}" - run_id="" - for candidate in $(gh run list \ - --workflow=ci.yml --branch=main --status=success --event=push \ - --limit=20 --json databaseId --jq='.[].databaseId'); do - if gh api "/repos/${{ github.repository }}/actions/runs/$candidate/artifacts?per_page=100" \ - --jq ".artifacts[] | select(.name == \"$canary\") | select(.expired == false) | .id" \ - | grep -q .; then - run_id="$candidate" - break - fi - done - if [ -n "$run_id" ]; then - echo "Reusing native artifacts from run $run_id" - else - echo "No cached native artifacts for hash $hash; native job will rebuild." - fi - echo "run-id=$run_id" >> "$GITHUB_OUTPUT" + # Compute a stable hash of every input that affects the native cdylib output, + # then look for a prior successful main build that already produced artifacts + # with this hash. If found, downstream consumers reuse those artifacts and + # the native job is skipped entirely. + rust-hash: + runs-on: ubuntu-22.04 + outputs: + hash: ${{ steps.compute.outputs.hash }} + run-id: ${{ steps.find.outputs.run-id }} + steps: + - uses: actions/checkout@v4 + - name: Compute rust source hash + id: compute + shell: bash + run: | + 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 "hash=$hash" >> "$GITHUB_OUTPUT" + echo "Rust source hash: $hash" + - name: Find prior main build with matching hash + id: find + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + run: | + hash="${{ steps.compute.outputs.hash }}" + # Canary artifact: main always builds linux-x64-modern, so its presence + # implies the run has the full multi-platform set we need. + canary="pi-natives-linux-x64-modern-h${hash}" + run_id="" + for candidate in $(gh run list \ + --workflow=ci.yml --branch=main --status=success --event=push \ + --limit=20 --json databaseId --jq='.[].databaseId'); do + if gh api "/repos/${{ github.repository }}/actions/runs/$candidate/artifacts?per_page=100" \ + --jq ".artifacts[] | select(.name == \"$canary\") | select(.expired == false) | .id" \ + | grep -q .; then + run_id="$candidate" + break + fi + done + if [ -n "$run_id" ]; then + echo "Reusing native artifacts from run $run_id" + else + echo "No cached native artifacts for hash $hash; native job will rebuild." + fi + echo "run-id=$run_id" >> "$GITHUB_OUTPUT" - # Fast lint + type check (no Rust, no native build needed) - check: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - name: Cache bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - run: bun install --frozen-lockfile - - name: Type check workspace - run: bun run ci:check:full + # Fast lint + type check (no Rust, no native build needed) + check: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - name: Cache bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - run: bun install --frozen-lockfile + - name: Type check workspace + run: bun run ci:check:full - native: - needs: [rust-hash] - if: ${{ needs.rust-hash.outputs.run-id == '' }} - strategy: - fail-fast: false - matrix: - # Tag and main pushes build the full multi-platform set (so the cache - # has every artifact a future tag could need). PRs only build linux-x64. - include: ${{ (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') && fromJSON('[ - {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"baseline","rust_checks":true}, - {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"modern"}, - {"os":"ubuntu-22.04","platform":"linux","arch":"arm64","target":"aarch64-unknown-linux-gnu"}, - {"os":"macos-15-intel","platform":"darwin","arch":"x64","variant":"baseline"}, - {"os":"macos-15-intel","platform":"darwin","arch":"x64","variant":"modern"}, - {"os":"macos-14","platform":"darwin","arch":"arm64"}, - {"os":"windows-latest","platform":"win32","arch":"x64","variant":"baseline"}, - {"os":"windows-latest","platform":"win32","arch":"x64","variant":"modern"} - ]') || fromJSON('[ - {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"baseline","rust_checks":true}, - {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"modern"} - ]') }} - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: dtolnay/rust-toolchain@nightly - with: - toolchain: nightly-2026-04-29 - components: ${{ matrix.rust_checks && 'clippy, rustfmt' || '' }} - targets: ${{ matrix.target }} - - name: Ensure cross-compilation target is installed - if: matrix.target - run: rustup target add ${{ matrix.target }} - - uses: Swatinem/rust-cache@v2 - with: - shared-key: native-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.variant || 'default' }} - cache-on-failure: true - save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) }} - cache-workspace-crates: true - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - run: bun install --frozen-lockfile - - name: Install cross-compilation toolchain - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu - - name: Rust checks - if: matrix.rust_checks - run: bun run check:rs - - name: Build native addon(s) - env: - CROSS_TARGET: ${{ matrix.target }} - TARGET_PLATFORM: ${{ matrix.platform }} - TARGET_ARCH: ${{ matrix.arch }} - TARGET_VARIANTS: ${{ matrix.variant }} - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc - shell: bash - run: | - bun run ci:build:native - - name: Upload native addon(s) - uses: actions/upload-artifact@v4 - with: - name: pi-natives-${{ matrix.platform }}-${{ matrix.arch }}${{ matrix.variant && format('-{0}', matrix.variant) || '' }}-h${{ needs.rust-hash.outputs.hash }} - path: packages/natives/native/pi_natives.${{ matrix.platform }}-${{ matrix.arch }}*.node - if-no-files-found: error + native: + needs: [rust-hash] + if: ${{ needs.rust-hash.outputs.run-id == '' }} + strategy: + fail-fast: false + matrix: + # Tag and main pushes build the full multi-platform set (so the cache + # has every artifact a future tag could need). PRs only build linux-x64. + include: ${{ (startsWith(github.ref, 'refs/tags/v') || github.ref == + 'refs/heads/main') && fromJSON('[ + {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"baseline","rust_checks":true}, + {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"modern"}, + {"os":"ubuntu-22.04","platform":"linux","arch":"arm64","target":"aarch64-unknown-linux-gnu"}, + {"os":"macos-15-intel","platform":"darwin","arch":"x64","variant":"baseline"}, + {"os":"macos-14","platform":"darwin","arch":"arm64"}, + {"os":"windows-latest","platform":"win32","arch":"x64","variant":"baseline"} + ]') || fromJSON('[ + {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"baseline","rust_checks":true}, + {"os":"ubuntu-22.04","platform":"linux","arch":"x64","variant":"modern"} + ]') }} + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + toolchain: nightly-2026-04-29 + components: ${{ matrix.rust_checks && 'clippy, rustfmt' || '' }} + targets: ${{ matrix.target }} + - name: Ensure cross-compilation target is installed + if: matrix.target + run: rustup target add ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + with: + shared-key: native-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.variant + || 'default' }} + cache-on-failure: true + save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || + startsWith(github.ref, 'refs/tags/v')) }} + cache-workspace-crates: true + - uses: taiki-e/install-action@v2 + if: ${{ !matrix.target }} + with: + tool: nextest + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - run: bun install --frozen-lockfile + - name: Install cross-compilation toolchain + if: matrix.target == 'aarch64-unknown-linux-gnu' + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu + - name: Rust checks + if: matrix.rust_checks + run: bun run check:rs + - name: Test workspace (Rust) + if: ${{ !matrix.target }} + run: bun run test:rs + - name: Build native addon(s) + env: + CROSS_TARGET: ${{ matrix.target }} + TARGET_PLATFORM: ${{ matrix.platform }} + TARGET_ARCH: ${{ matrix.arch }} + TARGET_VARIANTS: ${{ matrix.variant }} + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc + shell: bash + run: | + bun run ci:build:native + - name: Upload native addon(s) + uses: actions/upload-artifact@v4 + with: + name: pi-natives-${{ matrix.platform }}-${{ matrix.arch }}${{ matrix.variant && + format('-{0}', matrix.variant) || '' }}-h${{ + needs.rust-hash.outputs.hash }} + path: packages/natives/native/pi_natives.${{ matrix.platform }}-${{ matrix.arch + }}*.node + if-no-files-found: error - test: - runs-on: ubuntu-22.04 - needs: [native, rust-hash] - if: ${{ !cancelled() && needs.native.result != 'failure' }} - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - uses: dtolnay/rust-toolchain@nightly - with: - toolchain: nightly-2026-04-29 - - uses: Swatinem/rust-cache@v2 - with: - shared-key: test-linux-x64 - cache-on-failure: true - save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) }} - cache-workspace-crates: true - - uses: taiki-e/install-action@v2 - with: - tool: nextest - - name: Cache bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - name: Install system deps - run: | - sudo apt-get update - sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep imagemagick - sudo ln -s $(which fdfind) /usr/local/bin/fd - sudo ln -sf /usr/bin/convert /usr/local/bin/magick - - run: bun install --frozen-lockfile - - name: Resolve native source run - id: source - shell: bash - run: | - if [ "${{ needs.native.result }}" = "success" ]; then - echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" - else - echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" - fi - - name: Download native addons - uses: actions/download-artifact@v4 - with: - pattern: pi-natives-linux-x64-*-h${{ needs.rust-hash.outputs.hash }} - path: packages/natives/native - merge-multiple: true - run-id: ${{ steps.source.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Test workspace (TS) - run: bun run test:ts - - name: Test workspace (Rust) - if: ${{ needs.native.result == 'success' }} - run: bun run test:rs - - name: CLI smoke test - run: bun run ci:test:smoke + test: + runs-on: ubuntu-22.04 + needs: [native, rust-hash] + if: ${{ !cancelled() && needs.native.result != 'failure' }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - name: Cache bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep imagemagick + sudo ln -s $(which fdfind) /usr/local/bin/fd + sudo ln -sf /usr/bin/convert /usr/local/bin/magick + - run: bun install --frozen-lockfile + - name: Resolve native source run + id: source + shell: bash + run: | + if [ "${{ needs.native.result }}" = "success" ]; then + echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" + else + echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" + fi + - name: Download native addons + uses: actions/download-artifact@v4 + with: + pattern: pi-natives-linux-x64-*-h${{ needs.rust-hash.outputs.hash }} + path: packages/natives/native + merge-multiple: true + run-id: ${{ steps.source.outputs.run-id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Test workspace (TS) + run: bun run test:ts + - name: CLI smoke test + run: bun run ci:test:smoke - install_methods: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - uses: dtolnay/rust-toolchain@nightly - with: - toolchain: nightly-2026-04-29 - - uses: Swatinem/rust-cache@v2 - with: - shared-key: install-methods-linux-x64 - cache-on-failure: true - save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) }} - cache-workspace-crates: true - - name: Cache bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - name: Install system deps - run: | - sudo apt-get update - sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep imagemagick - sudo ln -s $(which fdfind) /usr/local/bin/fd - sudo ln -sf /usr/bin/convert /usr/local/bin/magick - - run: bun install --frozen-lockfile - - name: Install method smoke tests - run: bun run ci:test:install-methods + install_methods: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - uses: dtolnay/rust-toolchain@nightly + with: + toolchain: nightly-2026-04-29 + - uses: Swatinem/rust-cache@v2 + with: + shared-key: install-methods-linux-x64 + cache-on-failure: true + save-if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || + startsWith(github.ref, 'refs/tags/v')) }} + cache-workspace-crates: true + - name: Cache bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep imagemagick + sudo ln -s $(which fdfind) /usr/local/bin/fd + sudo ln -sf /usr/bin/convert /usr/local/bin/magick + - run: bun install --frozen-lockfile + - name: Install method smoke tests + run: bun run ci:test:install-methods - release_binary: - if: ${{ startsWith(github.ref, 'refs/tags/v') && !cancelled() && needs.native.result != 'failure' && needs.test.result == 'success' && needs.check.result == 'success' && needs.install_methods.result == 'success' }} - needs: [check, native, test, install_methods, rust-hash] - 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} - - {os: ubuntu-24.04-arm, platform: linux, arch: arm64, target_id: linux-arm64, binary_path: packages/coding-agent/binaries/omp-linux-arm64} - - {os: macos-15-intel, platform: darwin, arch: x64, target_id: darwin-x64, binary_path: packages/coding-agent/binaries/omp-darwin-x64} - - {os: macos-14, platform: darwin, arch: arm64, target_id: darwin-arm64, binary_path: packages/coding-agent/binaries/omp-darwin-arm64} - - {os: windows-latest, platform: win32, arch: x64, target_id: win32-x64, binary_path: packages/coding-agent/binaries/omp-windows-x64.exe} - runs-on: ${{ matrix.os }} - permissions: - contents: read - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - name: Cache bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - run: bun install --frozen-lockfile - - name: Resolve native source run - id: source - shell: bash - run: | - if [ "${{ needs.native.result }}" = "success" ]; then - echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" - else - echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" - fi - - name: Download native addon(s) - uses: actions/download-artifact@v4 - with: - pattern: pi-natives-${{ matrix.platform }}-${{ matrix.arch }}*-h${{ needs.rust-hash.outputs.hash }} - path: packages/natives/native - merge-multiple: true - run-id: ${{ steps.source.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Build release binary - env: - RELEASE_TARGETS: ${{ matrix.target_id }} - run: bun run ci:release:build-binaries - - name: Smoke release binary - if: runner.os != 'Windows' - run: | - runtime_dir="$(mktemp -d)" - HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --version - - name: Smoke release binary (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - $runtimeDir = Join-Path $env:TEMP ("omp-runtime-" + [System.Guid]::NewGuid().ToString("N")) - New-Item -ItemType Directory -Force -Path $runtimeDir | Out-Null - $env:HOME = Join-Path $runtimeDir "home" - $env:XDG_DATA_HOME = Join-Path $runtimeDir "xdg" - & "${{ matrix.binary_path }}" --version - - name: Upload release binary artifact - uses: actions/upload-artifact@v4 - with: - name: omp-binary-${{ matrix.target_id }} - path: ${{ matrix.binary_path }} + release_binary: + if: ${{ startsWith(github.ref, 'refs/tags/v') && !cancelled() && + needs.native.result != 'failure' && needs.test.result == 'success' && + needs.check.result == 'success' && needs.install_methods.result == + 'success' }} + needs: [check, native, test, install_methods, rust-hash] + 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, + } + - { + os: ubuntu-24.04-arm, + platform: linux, + arch: arm64, + target_id: linux-arm64, + binary_path: packages/coding-agent/binaries/omp-linux-arm64, + } + - { + os: macos-15-intel, + platform: darwin, + arch: x64, + target_id: darwin-x64, + binary_path: packages/coding-agent/binaries/omp-darwin-x64, + } + - { + os: macos-14, + platform: darwin, + arch: arm64, + target_id: darwin-arm64, + binary_path: packages/coding-agent/binaries/omp-darwin-arm64, + } + - { + os: windows-latest, + platform: win32, + arch: x64, + target_id: win32-x64, + binary_path: packages/coding-agent/binaries/omp-windows-x64.exe, + } + runs-on: ${{ matrix.os }} + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - name: Cache bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - run: bun install --frozen-lockfile + - name: Resolve native source run + id: source + shell: bash + run: | + if [ "${{ needs.native.result }}" = "success" ]; then + echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" + else + echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" + fi + - name: Download native addon(s) + uses: actions/download-artifact@v4 + with: + pattern: pi-natives-${{ matrix.platform }}-${{ matrix.arch }}*-h${{ + needs.rust-hash.outputs.hash }} + path: packages/natives/native + merge-multiple: true + run-id: ${{ steps.source.outputs.run-id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Build release binary + env: + RELEASE_TARGETS: ${{ matrix.target_id }} + run: bun run ci:release:build-binaries + - name: Smoke release binary + if: runner.os != 'Windows' + run: | + runtime_dir="$(mktemp -d)" + HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --version + - name: Smoke release binary (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + $runtimeDir = Join-Path $env:TEMP ("omp-runtime-" + [System.Guid]::NewGuid().ToString("N")) + New-Item -ItemType Directory -Force -Path $runtimeDir | Out-Null + $env:HOME = Join-Path $runtimeDir "home" + $env:XDG_DATA_HOME = Join-Path $runtimeDir "xdg" + & "${{ matrix.binary_path }}" --version + - name: Upload release binary artifact + uses: actions/upload-artifact@v4 + with: + name: omp-binary-${{ matrix.target_id }} + path: ${{ matrix.binary_path }} - release: - if: ${{ startsWith(github.ref, 'refs/tags/v') && !cancelled() && needs.release_binary.result == 'success' }} - needs: [release_binary, native, rust-hash] - runs-on: ubuntu-22.04 - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: oven-sh/setup-bun@v2 - with: - bun-version: "1.3" - - uses: actions/setup-node@v4 - with: - node-version: "24" - registry-url: "https://registry.npmjs.org" - - name: Cache bun dependencies - uses: actions/cache@v4 - with: - path: ~/.bun/install/cache - key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - - run: bun install --frozen-lockfile - - name: Download release binaries - uses: actions/download-artifact@v4 - with: - pattern: omp-binary-* - path: packages/coding-agent/binaries - merge-multiple: true - - name: Resolve native source run - id: source - shell: bash - run: | - if [ "${{ needs.native.result }}" = "success" ]; then - echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" - else - echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" - fi - - name: Download native addons - uses: actions/download-artifact@v4 - with: - pattern: pi-natives-*-h${{ needs.rust-hash.outputs.hash }} - path: packages/natives/native - merge-multiple: true - run-id: ${{ steps.source.outputs.run-id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Stage native addons for release - run: cp packages/natives/native/*.node packages/coding-agent/binaries/ - - name: Build release archives - run: bun run ci:release:build-archives - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - files: packages/coding-agent/binaries/* - generate_release_notes: true - - name: Publish to npm - if: ${{ !inputs.skip_npm }} - env: - NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bun run ci:release:publish + release-github: + if: ${{ startsWith(github.ref, 'refs/tags/v') && !cancelled() && + needs.release_binary.result == 'success' }} + needs: [release_binary] + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + - name: Download release binaries + uses: actions/download-artifact@v4 + with: + pattern: omp-binary-* + path: packages/coding-agent/binaries + merge-multiple: true + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: | + packages/coding-agent/binaries/omp-* + generate_release_notes: true + + release-npm: + if: ${{ startsWith(github.ref, 'refs/tags/v') && !cancelled() && + needs.release_binary.result == 'success' && !inputs.skip_npm }} + needs: [release_binary, native, rust-hash] + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v2 + with: + bun-version: "1.3" + - uses: actions/setup-node@v4 + with: + node-version: "24" + registry-url: "https://registry.npmjs.org" + - name: Cache bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - run: bun install --frozen-lockfile + - name: Resolve native source run + id: source + shell: bash + run: | + if [ "${{ needs.native.result }}" = "success" ]; then + echo "run-id=${{ github.run_id }}" >> "$GITHUB_OUTPUT" + else + echo "run-id=${{ needs.rust-hash.outputs.run-id }}" >> "$GITHUB_OUTPUT" + fi + - name: Download native addons + uses: actions/download-artifact@v4 + with: + pattern: pi-natives-*-h${{ needs.rust-hash.outputs.hash }} + path: packages/natives/native + merge-multiple: true + run-id: ${{ steps.source.outputs.run-id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Publish to npm + env: + NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} + run: bun run ci:release:publish diff --git a/package.json b/package.json index c7b2c2a69..e9004c61a 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,6 @@ "ci:test:smoke": "bun packages/coding-agent/src/cli.ts --version && bun packages/coding-agent/src/cli.ts --help && bun packages/coding-agent/src/cli.ts stats --help", "ci:test:install-methods": "bash scripts/install-tests/run-ci.sh", "ci:release:build-binaries": "bun scripts/ci-release-build-binaries.ts", - "ci:release:build-archives": "bun scripts/ci-release-build-archives.ts", "ci:release:publish": "bun scripts/ci-release-publish.ts", "bench:gen-fixtures": "bun --cwd=packages/typescript-edit-benchmark run src/generate.ts --typescript-dir /tmp/typescript-source --count-per-type 8", "bench:edit": "bun --cwd=packages/typescript-edit-benchmark run start", diff --git a/scripts/ci-release-build-archives.ts b/scripts/ci-release-build-archives.ts deleted file mode 100644 index b60bdcafd..000000000 --- a/scripts/ci-release-build-archives.ts +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bun - -import { $ } from "bun"; -import * as fs from "node:fs/promises"; -import * as path from "node:path"; - -interface ArchiveTarget { - id: string; - binaryName: string; - archiveName: string; - executableName: string; - nativeAddons: string[]; -} - -const repoRoot = path.join(import.meta.dir, ".."); -const binariesDir = path.join(repoRoot, "packages", "coding-agent", "binaries"); -const archivesDir = path.join(binariesDir, ".archives"); - -const targets: ArchiveTarget[] = [ - { - id: "darwin-arm64", - binaryName: "omp-darwin-arm64", - archiveName: "omp-darwin-arm64.tar.gz", - executableName: "omp", - nativeAddons: ["pi_natives.darwin-arm64.node"], - }, - { - id: "darwin-x64", - binaryName: "omp-darwin-x64", - archiveName: "omp-darwin-x64.tar.gz", - executableName: "omp", - nativeAddons: ["pi_natives.darwin-x64-modern.node", "pi_natives.darwin-x64-baseline.node"], - }, - { - id: "linux-x64", - binaryName: "omp-linux-x64", - archiveName: "omp-linux-x64.tar.gz", - executableName: "omp", - nativeAddons: ["pi_natives.linux-x64-modern.node", "pi_natives.linux-x64-baseline.node"], - }, - { - id: "linux-arm64", - binaryName: "omp-linux-arm64", - archiveName: "omp-linux-arm64.tar.gz", - executableName: "omp", - nativeAddons: ["pi_natives.linux-arm64.node"], - }, - { - id: "win32-x64", - binaryName: "omp-windows-x64.exe", - archiveName: "omp-windows-x64.tar.gz", - executableName: "omp.exe", - nativeAddons: ["pi_natives.win32-x64-modern.node", "pi_natives.win32-x64-baseline.node"], - }, -]; - -async function copyRequiredFile(source: string, destination: string): Promise { - try { - await fs.copyFile(source, destination); - } catch (error) { - throw new Error(`Missing release archive input ${path.relative(repoRoot, source)}: ${String(error)}`); - } -} - -async function createArchive(target: ArchiveTarget): Promise { - const stagingDir = path.join(archivesDir, target.id); - await fs.rm(stagingDir, { recursive: true, force: true }); - await fs.mkdir(stagingDir, { recursive: true }); - - await copyRequiredFile(path.join(binariesDir, target.binaryName), path.join(stagingDir, target.executableName)); - for (const addonName of target.nativeAddons) { - await copyRequiredFile(path.join(binariesDir, addonName), path.join(stagingDir, addonName)); - } - - if (target.executableName === "omp") { - await fs.chmod(path.join(stagingDir, target.executableName), 0o755); - } - - const archivePath = path.join(binariesDir, target.archiveName); - await fs.rm(archivePath, { force: true }); - await $`tar -czf ${archivePath} -C ${stagingDir} .`.quiet(); -} - -async function main(): Promise { - await fs.mkdir(binariesDir, { recursive: true }); - await fs.rm(archivesDir, { recursive: true, force: true }); - await fs.mkdir(archivesDir, { recursive: true }); - - for (const target of targets) { - await createArchive(target); - } - - await fs.rm(archivesDir, { recursive: true, force: true }); -} - -await main(); diff --git a/scripts/install.ps1 b/scripts/install.ps1 index c069e0567..95a9f1408 100755 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -20,7 +20,6 @@ $Repo = "can1357/oh-my-pi" $Package = "@oh-my-pi/pi-coding-agent" $InstallDir = if ($env:PI_INSTALL_DIR) { $env:PI_INSTALL_DIR } else { "$env:LOCALAPPDATA\omp" } $BinaryName = "omp-windows-x64.exe" -$NativeAddonNames = @("pi_natives.win32-x64-modern.node", "pi_natives.win32-x64-baseline.node") $MinimumBunVersion = "1.3.7" function Test-BunInstalled { @@ -263,18 +262,8 @@ function Install-Binary { $OutPath = Join-Path $InstallDir "omp.exe" Invoke-WebRequest -Uri $BinaryUrl -OutFile $OutPath - # Download native addons - $downloadedNative = 0 - foreach ($nativeAddonName in $NativeAddonNames) { - $nativeUrl = "https://github.com/$Repo/releases/download/$Latest/$nativeAddonName" - Write-Host "Downloading $nativeAddonName..." - $nativeOutPath = Join-Path $InstallDir $nativeAddonName - Invoke-WebRequest -Uri $nativeUrl -OutFile $nativeOutPath - $downloadedNative += 1 - } Write-Host "" Write-Host "✓ Installed omp to $OutPath" -ForegroundColor Green - Write-Host "✓ Installed $downloadedNative native addon file(s) to $InstallDir" -ForegroundColor Green # Add to PATH if not already there $UserPath = [Environment]::GetEnvironmentVariable("Path", "User") diff --git a/scripts/install.sh b/scripts/install.sh index b749ea8bd..e4db5af27 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -230,28 +230,8 @@ install_binary() { echo "Downloading ${BINARY}..." curl -fsSL "$BINARY_URL" -o "${INSTALL_DIR}/omp" chmod +x "${INSTALL_DIR}/omp" - downloaded_native=0 - if [ "$ARCH" = "x64" ]; then - for variant in modern baseline; do - NATIVE_ADDON="pi_natives.${PLATFORM}-${ARCH}-${variant}.node" - NATIVE_URL="https://github.com/${REPO}/releases/download/${LATEST}/${NATIVE_ADDON}" - echo "Downloading ${NATIVE_ADDON}..." - curl -fsSL "$NATIVE_URL" -o "${INSTALL_DIR}/${NATIVE_ADDON}" || { - echo "Failed to download ${NATIVE_ADDON}" - exit 1 - } - downloaded_native=$((downloaded_native + 1)) - done - else - NATIVE_ADDON="pi_natives.${PLATFORM}-${ARCH}.node" - NATIVE_URL="https://github.com/${REPO}/releases/download/${LATEST}/${NATIVE_ADDON}" - echo "Downloading ${NATIVE_ADDON}..." - curl -fsSL "$NATIVE_URL" -o "${INSTALL_DIR}/${NATIVE_ADDON}" - downloaded_native=1 - fi echo "" echo "✓ Installed omp to ${INSTALL_DIR}/omp" - echo "✓ Installed ${downloaded_native} native addon file(s) to ${INSTALL_DIR}" # Check if in PATH case ":$PATH:" in