docs: correct the csp --agent list in CLAUDE.md (#79)
#46
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
| on: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| name: release-please | |
| jobs: | |
| release-please: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_created: ${{ steps.release.outputs.release_created }} | |
| tag_name: ${{ steps.release.outputs.tag_name }} | |
| steps: | |
| - uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 | |
| id: app-token | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.PRIVATE_KEY }} | |
| - uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1 | |
| id: release | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| config-file: release-please-config.json | |
| manifest-file: .release-please-manifest.json | |
| # release-please bumps package.json but does not know about bun.lock. | |
| # A version-only bump usually leaves bun.lock unchanged, but a release PR | |
| # can also carry dependency updates — re-resolve and commit the lockfile | |
| # into the release PR so the tagged commit always installs cleanly with | |
| # `bun install --frozen-lockfile`. Only commits when bun.lock changes. | |
| - name: Checkout release PR branch | |
| if: ${{ steps.release.outputs.pr }} | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| token: ${{ steps.app-token.outputs.token }} | |
| ref: ${{ fromJson(steps.release.outputs.pr).headBranchName }} | |
| - name: Setup Bun | |
| if: ${{ steps.release.outputs.pr }} | |
| uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 | |
| with: | |
| bun-version: 1.3.14 | |
| - name: Sync bun.lock | |
| if: ${{ steps.release.outputs.pr }} | |
| run: | | |
| bun install --lockfile-only | |
| if git diff --quiet bun.lock; then | |
| echo "bun.lock already in sync" | |
| else | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add bun.lock | |
| git commit -m "chore: sync bun.lock" | |
| git push origin HEAD:${{ fromJson(steps.release.outputs.pr).headBranchName }} | |
| fi | |
| # release-please bumps the workspace version in Cargo.toml (via the | |
| # x-release-please-version annotation) but does not touch Cargo.lock, so | |
| # every workspace member stays at the previous version and the release | |
| # build's `cargo build --locked` fails. `--workspace` re-locks only the | |
| # local members by their real package names (code-search-please / | |
| # csp-node) — it does not bump external deps. Don't name packages | |
| # explicitly: `-p csp` broke once the lib crate was renamed to | |
| # code-search-please and csp-node was added. Commit it into the release | |
| # PR. Mirrors the bun.lock sync. | |
| - name: Sync Cargo.lock | |
| if: ${{ steps.release.outputs.pr }} | |
| run: | | |
| cargo update --workspace | |
| if git diff --quiet Cargo.lock; then | |
| echo "Cargo.lock already in sync" | |
| else | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add Cargo.lock | |
| git commit -m "chore: sync Cargo.lock" | |
| git push origin HEAD:${{ fromJson(steps.release.outputs.pr).headBranchName }} | |
| fi | |
| # 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 }} | |
| permissions: | |
| contents: write | |
| uses: ./.github/workflows/release-rust.yml | |
| with: | |
| tag: ${{ needs.release-please.outputs.tag_name }} | |
| # Build + publish the napi-rs SDK (@pleaseai/csp-sdk) — the separate in-process | |
| # native-addon channel. Reuses release-sdk.yml so its cross-compile matrix | |
| # lives in one place. id-token: write is granted here (the caller) so the | |
| # reusable workflow's publish job can use npm Trusted Publishing (OIDC). | |
| build-and-publish-sdk: | |
| needs: release-please | |
| if: ${{ needs.release-please.outputs.release_created }} | |
| permissions: | |
| contents: read | |
| id-token: write | |
| uses: ./.github/workflows/release-sdk.yml | |
| with: | |
| publish: true | |
| # 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] | |
| # always(): publish whatever targets reached the release even if one build | |
| # leg failed. The generator is partial-matrix-tolerant (only present targets | |
| # are pinned in optionalDependencies) and fails loudly if nothing built. | |
| if: ${{ always() && 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 | |
| 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. The global prefix | |
| # (/usr/local) is root-owned, so installing a new global npm needs sudo — | |
| # without it npm fails with EACCES on /usr/local/share/man. | |
| - name: Upgrade npm for Trusted Publishing | |
| run: sudo npm install -g npm@latest | |
| - name: Download released binaries | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| RELEASE_TAG: ${{ needs.release-please.outputs.tag_name }} | |
| run: | | |
| mkdir -p assets | |
| gh release download "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" \ | |
| --pattern 'csp-*' --dir assets | |
| ls -lh assets | |
| - name: Generate platform packages | |
| env: | |
| 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: | | |
| 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, build-and-upload] | |
| # always(): the formula only needs the 4 darwin/linux-gnu assets, so a musl | |
| # build failure shouldn't block it. Fails on its own if a core asset is missing. | |
| if: ${{ always() && needs.release-please.outputs.release_created }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 | |
| id: app-token | |
| with: | |
| app-id: ${{ secrets.APP_ID }} | |
| private-key: ${{ secrets.PRIVATE_KEY }} | |
| repositories: | | |
| code-search | |
| homebrew-tap | |
| - name: Checkout homebrew-tap repository | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| repository: pleaseai/homebrew-tap | |
| token: ${{ steps.app-token.outputs.token }} | |
| path: homebrew-tap | |
| - name: Configure git | |
| run: | | |
| cd homebrew-tap | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Update Formula | |
| run: | | |
| VERSION=${{ needs.release-please.outputs.tag_name }} | |
| VERSION_NO_V=${VERSION#v} | |
| # Download checksums. -f makes curl fail (non-zero) on a 404 instead of | |
| # writing an HTML error page into the .sha256 file — so when a core | |
| # target is missing under always(), this job hard-fails rather than | |
| # baking a corrupt checksum into the formula. | |
| curl -fLsS -o darwin-x64.sha256 \ | |
| "https://github.com/${{ github.repository }}/releases/download/${VERSION}/csp-darwin-x64.sha256" | |
| curl -fLsS -o darwin-arm64.sha256 \ | |
| "https://github.com/${{ github.repository }}/releases/download/${VERSION}/csp-darwin-arm64.sha256" | |
| curl -fLsS -o linux-x64.sha256 \ | |
| "https://github.com/${{ github.repository }}/releases/download/${VERSION}/csp-linux-x64.sha256" | |
| curl -fLsS -o linux-arm64.sha256 \ | |
| "https://github.com/${{ github.repository }}/releases/download/${VERSION}/csp-linux-arm64.sha256" | |
| # Extract checksums | |
| DARWIN_X64_SHA256=$(cat darwin-x64.sha256 | awk '{print $1}') | |
| DARWIN_ARM64_SHA256=$(cat darwin-arm64.sha256 | awk '{print $1}') | |
| LINUX_X64_SHA256=$(cat linux-x64.sha256 | awk '{print $1}') | |
| LINUX_ARM64_SHA256=$(cat linux-arm64.sha256 | awk '{print $1}') | |
| # Create or update Formula | |
| cd homebrew-tap | |
| cat > csp.rb << 'FORMULA_EOF' | |
| class Csp < Formula | |
| desc "Fast and accurate hybrid code search for agents" | |
| homepage "https://github.com/pleaseai/code-search" | |
| version "VERSION_PLACEHOLDER" | |
| license "MIT" | |
| on_macos do | |
| if Hardware::CPU.arm? | |
| url "https://github.com/pleaseai/code-search/releases/download/vVERSION_PLACEHOLDER/csp-darwin-arm64" | |
| sha256 "SHA256_DARWIN_ARM64_PLACEHOLDER" | |
| else | |
| url "https://github.com/pleaseai/code-search/releases/download/vVERSION_PLACEHOLDER/csp-darwin-x64" | |
| sha256 "SHA256_DARWIN_X64_PLACEHOLDER" | |
| end | |
| end | |
| on_linux do | |
| if Hardware::CPU.arm? | |
| url "https://github.com/pleaseai/code-search/releases/download/vVERSION_PLACEHOLDER/csp-linux-arm64" | |
| sha256 "SHA256_LINUX_ARM64_PLACEHOLDER" | |
| else | |
| url "https://github.com/pleaseai/code-search/releases/download/vVERSION_PLACEHOLDER/csp-linux-x64" | |
| sha256 "SHA256_LINUX_X64_PLACEHOLDER" | |
| end | |
| end | |
| def install | |
| if OS.mac? | |
| if Hardware::CPU.arm? | |
| bin.install "csp-darwin-arm64" => "csp" | |
| else | |
| bin.install "csp-darwin-x64" => "csp" | |
| end | |
| else | |
| if Hardware::CPU.arm? | |
| bin.install "csp-linux-arm64" => "csp" | |
| else | |
| bin.install "csp-linux-x64" => "csp" | |
| end | |
| end | |
| end | |
| test do | |
| assert_match version.to_s, shell_output("#{bin}/csp --version") | |
| end | |
| end | |
| FORMULA_EOF | |
| # Replace placeholders | |
| sed -i "s/VERSION_PLACEHOLDER/${VERSION_NO_V}/g" csp.rb | |
| sed -i "s/SHA256_DARWIN_X64_PLACEHOLDER/${DARWIN_X64_SHA256}/" csp.rb | |
| sed -i "s/SHA256_DARWIN_ARM64_PLACEHOLDER/${DARWIN_ARM64_SHA256}/" csp.rb | |
| sed -i "s/SHA256_LINUX_X64_PLACEHOLDER/${LINUX_X64_SHA256}/" csp.rb | |
| sed -i "s/SHA256_LINUX_ARM64_PLACEHOLDER/${LINUX_ARM64_SHA256}/" csp.rb | |
| # Stage first, then check the *staged* diff. `git diff --quiet csp.rb` | |
| # compares the working tree against the index and ignores untracked | |
| # files, so on the very first run (csp.rb absent from the tap) it | |
| # reported "no changes" and skipped the commit — which is why the | |
| # formula was never published. `git diff --cached` sees the newly | |
| # added file and still no-ops on an unchanged re-run. | |
| git add csp.rb | |
| if git diff --cached --quiet; then | |
| echo "No changes to Formula" | |
| exit 0 | |
| fi | |
| # Commit and push | |
| git commit -m "chore: update csp to ${VERSION}" | |
| git push origin main | |
| env: | |
| GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} | |
| # Publish the `code-search-please` library crate to crates.io via Trusted | |
| # Publishing (OIDC) — no CARGO_REGISTRY_TOKEN. Gated on the CRATES_IO_PUBLISH | |
| # repo variable so it stays dormant until the one-time bootstrap is done: | |
| # (1) claim the name with a manual `cargo publish` (crates.io TP can't be | |
| # configured on a crate that doesn't exist yet), (2) add a GitHub Actions | |
| # trusted publisher on crates.io (repo pleaseai/code-search, workflow | |
| # release-please.yml), (3) set the repo variable CRATES_IO_PUBLISH=true. | |
| # The CLI ships inside this same crate as the `csp` binary (default-on `cli` | |
| # feature — the ripgrep model), so `cargo publish -p code-search-please` and | |
| # `cargo install code-search-please` both cover the library and the CLI; there | |
| # is no separate CLI crate to version-manage. | |
| publish-crate: | |
| needs: [release-please] | |
| if: ${{ needs.release-please.outputs.release_created && vars.CRATES_IO_PUBLISH == 'true' }} | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - name: Checkout the released tag | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| ref: ${{ needs.release-please.outputs.tag_name }} | |
| persist-credentials: false | |
| - name: Authenticate to crates.io (Trusted Publishing) | |
| uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 | |
| id: auth | |
| - name: Publish code-search-please | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} | |
| run: cargo publish -p code-search-please --locked |