From 0067885ea08df93c458083efea5819e2b20537aa Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Sat, 20 Jun 2026 20:00:13 +0900 Subject: [PATCH 1/3] ci: cut over release-please to Rust binary + npm trusted publishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-point the release pipeline from the deprecated TypeScript line to the actually-published artifact (`npm/csp` distributing the Rust binary), and fix the first release version. - release-please-config.json: pin first release via `initial-version: 0.1.0` (manifest is 0.0.0, so release-please ignored the pre-major bump flags and defaulted to 1.0.0); track the real sources via extra-files — npm/csp package.json (json) and Cargo.toml (generic), dropping the dead src/version.ts. - Cargo.toml: annotate the workspace version line so release-please bumps it; both crates use version.workspace=true, so one line covers them. - package.json (root): mark private to prevent accidental publish of the unpublished TS package that shares the @pleaseai/csp name. - release-rust.yml: add workflow_call so it can be reused by the release pipeline. - release-please.yml: replace the TS `bun build` job with a reusable Rust build (6 targets) + a publish-npm job that generates the per-platform packages and publishes them via npm Trusted Publishing (OIDC, no NPM_TOKEN; provenance automatic). Homebrew job now depends on the Rust build+upload. --- .github/workflows/release-please.yml | 118 ++++++++++++--------------- .github/workflows/release-rust.yml | 19 +++-- Cargo.toml | 2 +- package.json | 1 + release-please-config.json | 8 +- 5 files changed, 72 insertions(+), 76 deletions(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index edc6504..346aaa8 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -61,90 +61,72 @@ jobs: git push origin HEAD:${{ fromJson(steps.release.outputs.pr).headBranchName }} fi - build-binaries: + # Build the Rust binaries (6 targets) and upload them to the release that + # release-please just created. Reuses release-rust.yml so the cross-compile + # matrix lives in one place (ADR-0003 cut-over — this replaces the former + # TypeScript `bun build src/cli.ts` job). + build-and-upload: needs: release-please if: ${{ needs.release-please.outputs.release_created }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - # csp embeds platform-specific native addons (onnxruntime-node, - # @kreuzberg/tree-sitter-language-pack). `bun build --compile` bundles - # the *host* platform's .node files, so each target MUST build on a - # native runner — cross-compiling with `--target` produces a binary - # with the wrong-arch addons ("bad CPU type in executable"). - include: - - os: macos-13 # Intel - target: darwin-x64 - - os: macos-14 # Apple Silicon - target: darwin-arm64 - - os: ubuntu-latest # x64 - target: linux-x64 - - os: ubuntu-24.04-arm # arm64 - target: linux-arm64 - - steps: - - name: Checkout code - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - - name: Setup Bun - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 - with: - bun-version: 1.3.14 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Build binary (native target) - run: | - bun build src/cli.ts --compile --outfile csp-${{ matrix.target }} - - - name: Smoke test binary - run: | - ./csp-${{ matrix.target }} --version - - - name: Generate checksum - run: | - shasum -a 256 csp-${{ matrix.target }} > csp-${{ matrix.target }}.sha256 - - - name: Upload artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: csp-${{ matrix.target }} - path: | - csp-${{ matrix.target }} - csp-${{ matrix.target }}.sha256 - - upload-release-assets: - needs: [release-please, build-binaries] + permissions: + contents: write + uses: ./.github/workflows/release-rust.yml + with: + tag: ${{ needs.release-please.outputs.tag_name }} + secrets: inherit + + # Generate the per-platform npm packages from the released binaries and + # publish the wrapper + platform packages via npm Trusted Publishing (OIDC). + # No NPM_TOKEN needed — auth is the OIDC id-token, and provenance is generated + # automatically. Each package must have a trusted publisher configured on + # npmjs.com pointing at this repo + workflow (release-please.yml). + publish-npm: + needs: [release-please, build-and-upload] if: ${{ needs.release-please.outputs.release_created }} runs-on: ubuntu-latest + permissions: + contents: read + id-token: write steps: - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - name: Download all artifacts - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 - with: - path: artifacts + # Trusted Publishing requires npm >= 11.5.1; ubuntu-latest ships npm 10.x + # with Node 22, so upgrade the CLI before publishing. + - name: Upgrade npm for Trusted Publishing + run: npm install -g npm@latest - - name: Prepare release assets + - name: Download released binaries + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }} run: | - mkdir -p release - find artifacts -type f -exec cp {} release/ \; - ls -lh release/ + mkdir -p assets + gh release download "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \ + --pattern 'csp-*' --dir assets + ls -lh assets - - name: Upload release artifacts + - name: Generate platform packages env: - GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }} + run: node npm/scripts/generate-platform-packages.mjs "${RELEASE_TAG#v}" assets + + # Trusted Publishing supplies auth via OIDC and generates provenance + # automatically, so no token or --provenance flag is needed. + - name: Publish to npm run: | - gh release upload ${{ needs.release-please.outputs.tag_name }} \ - release/* \ - --clobber + set -e + # Platform packages first, then the wrapper last (its + # optionalDependencies pin the platform packages by version). + for dir in npm/dist/@pleaseai__*; do + echo "publishing $dir" + npm publish "$dir" --access public + done + npm publish npm/dist/csp --access public update-homebrew-formula: - needs: [release-please, upload-release-assets] + needs: [release-please, build-and-upload] if: ${{ needs.release-please.outputs.release_created }} runs-on: ubuntu-latest diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index f1c182e..0e8fdf2 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -1,12 +1,11 @@ # Rust release pipeline (ADR-0003 / track rust-rewrite-20260618, T022). # # This builds the cross-compiled `csp` binaries from the Rust workspace -# (crates/csp-cli). It is **manually triggered** (workflow_dispatch) and does NOT -# fire on release, so it coexists with the live TypeScript release pipeline in -# release-please.yml without overriding it. Flipping the published product from -# the Bun-compiled binary to the Rust binary is a deliberate, separate cut-over -# (T023/T024) gated on full runtime parity — not something this workflow does on -# its own. +# (crates/csp-cli). It runs in two ways: **manually** (workflow_dispatch) for +# ad-hoc rebuilds, and **as a reusable workflow** (workflow_call) invoked by +# release-please.yml on release_created — the latter is the live cut-over +# (T023/T024) that makes Rust the published product (GitHub release assets + +# npm-distributed binary), replacing the former Bun-compiled TypeScript binary. # # Unlike the TS pipeline (which must build on native runners because # `bun build --compile` bundles host-platform native addons), the Rust binary is @@ -24,6 +23,14 @@ on: description: 'Release tag to upload assets to (e.g. v0.1.0). Leave blank to only build + upload artifacts.' required: false type: string + # Reused by release-please.yml on release_created to build the Rust binaries + # and upload them to the freshly-created GitHub release (ADR-0003 cut-over). + workflow_call: + inputs: + tag: + description: 'Release tag to upload assets to (e.g. v0.1.0).' + required: false + type: string permissions: contents: read diff --git a/Cargo.toml b/Cargo.toml index 2518703..191d9ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ resolver = "2" members = ["crates/csp", "crates/csp-cli"] [workspace.package] -version = "0.0.0" +version = "0.0.0" # x-release-please-version edition = "2021" license = "MIT" repository = "https://github.com/pleaseai/code-search" diff --git a/package.json b/package.json index 3bc0e28..5663abc 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "@pleaseai/csp", "type": "module", "version": "0.0.0", + "private": true, "packageManager": "bun@1.3.14", "description": "Fast and Accurate Code Search for Agents — TypeScript port of MinishLab/semble", "author": "Minsu Lee ", diff --git a/release-please-config.json b/release-please-config.json index 2c7b695..7a56135 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -6,6 +6,7 @@ "package-name": "@pleaseai/csp", "include-component-in-tag": false, "include-v-in-tag": true, + "initial-version": "0.1.0", "bump-minor-pre-major": true, "bump-patch-for-minor-pre-major": true, "changelog-sections": [ @@ -22,9 +23,14 @@ { "type": "ci", "section": "Continuous Integration", "hidden": true } ], "extra-files": [ + { + "type": "json", + "path": "npm/csp/package.json", + "jsonpath": "$.version" + }, { "type": "generic", - "path": "src/version.ts" + "path": "Cargo.toml" } ] } From 444078050d9c49ae7bd5702d97378f9d0284ed9b Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Sat, 20 Jun 2026 20:03:20 +0900 Subject: [PATCH 2/3] ci: use plain-style scalar for workflow_call input description eslint yaml/plain-scalar flagged the quoted description on the reused workflow_call input. --- .github/workflows/release-rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-rust.yml b/.github/workflows/release-rust.yml index 0e8fdf2..48e6a65 100644 --- a/.github/workflows/release-rust.yml +++ b/.github/workflows/release-rust.yml @@ -28,7 +28,7 @@ on: workflow_call: inputs: tag: - description: 'Release tag to upload assets to (e.g. v0.1.0).' + description: Release tag to upload assets to (e.g. v0.1.0). required: false type: string From 92f504fa400c980ce365ebcbef5e318471ee57ec Mon Sep 17 00:00:00 2001 From: Minsu Lee Date: Sat, 20 Jun 2026 21:23:07 +0900 Subject: [PATCH 3/3] chore: apply AI code review suggestions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - re-add src/version.ts to extra-files (still imported by src/cli.ts + src/index.ts; would otherwise freeze at 0.0.0) — gemini, cubic - drop secrets: inherit from the reusable workflow call (github.token is available without it; least-privilege) — coderabbit - set persist-credentials: false on the publish-npm checkout (read+publish only, never pushes) — coderabbit --- .github/workflows/release-please.yml | 5 ++++- release-please-config.json | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 346aaa8..47ac957 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -73,7 +73,6 @@ jobs: uses: ./.github/workflows/release-rust.yml with: tag: ${{ needs.release-please.outputs.tag_name }} - secrets: inherit # Generate the per-platform npm packages from the released binaries and # publish the wrapper + platform packages via npm Trusted Publishing (OIDC). @@ -91,6 +90,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + # This job only reads + publishes to npm; it never pushes to git, so + # don't leave the checkout token persisted in .git/config. + persist-credentials: false # Trusted Publishing requires npm >= 11.5.1; ubuntu-latest ships npm 10.x # with Node 22, so upgrade the CLI before publishing. diff --git a/release-please-config.json b/release-please-config.json index 7a56135..7a3d138 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -31,6 +31,10 @@ { "type": "generic", "path": "Cargo.toml" + }, + { + "type": "generic", + "path": "src/version.ts" } ] }