Publish JS #9
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
| # NPM publishing workflow for bashkit JavaScript package | |
| # Builds native NAPI-RS bindings for all major platforms and publishes to npm. | |
| # Triggered alongside publish.yml on GitHub Release or manual dispatch. | |
| # Adapted from https://github.com/pydantic/monty CI JS-building pattern. | |
| # | |
| # Prerequisites: | |
| # - NPM_TOKEN secret with publish access (GitHub Settings > Secrets > Actions) | |
| # - id-token: write permission for npm provenance (OIDC attestation) | |
| name: Publish JS | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| MACOSX_DEPLOYMENT_TARGET: "10.13" | |
| CARGO_INCREMENTAL: "1" | |
| DEBUG: "napi:*" | |
| DOPPLER_TOKEN: ${{ secrets.DOPPLER_TOKEN }} | |
| jobs: | |
| # ============================================================================ | |
| # Build native bindings for each platform | |
| # ============================================================================ | |
| build-js: | |
| name: Build JS - ${{ matrix.settings.target }} | |
| runs-on: ${{ matrix.settings.host }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| build: npm run build:napi -- --target x86_64-apple-darwin && npm run build:cjs && npm run build:ts | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| build: npm run build:napi -- --target aarch64-apple-darwin && npm run build:cjs && npm run build:ts | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| build: npm run build:napi -- --target x86_64-unknown-linux-gnu --use-napi-cross && npm run build:cjs && npm run build:ts | |
| - host: ubuntu-24.04-arm | |
| target: aarch64-unknown-linux-gnu | |
| build: npm run build:napi -- --target aarch64-unknown-linux-gnu && npm run build:cjs && npm run build:ts | |
| - host: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| build: npm run build:napi -- --target x86_64-pc-windows-msvc && npm run build:cjs && npm run build:ts | |
| # TODO: WASM disabled — tokio "full" features (from bashkit core) are | |
| # unsupported on wasm32. Needs architectural fix to gate tokio features. | |
| # - host: ubuntu-latest | |
| # target: wasm32-wasip1-threads | |
| # build: npm run build:napi -- --target wasm32-wasip1-threads && npm run build:cjs && npm run build:ts | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: crates/bashkit-js/package-lock.json | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.settings.target }} | |
| - name: Cache cargo | |
| uses: actions/cache@v5 | |
| with: | |
| path: | | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| ~/.napi-rs | |
| .cargo-cache | |
| target/ | |
| key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} | |
| - name: Install dependencies | |
| run: npm install | |
| working-directory: crates/bashkit-js | |
| - name: Build | |
| run: ${{ matrix.settings.build }} | |
| shell: bash | |
| working-directory: crates/bashkit-js | |
| - name: Upload native binding | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: js-bindings-${{ matrix.settings.target }} | |
| path: | | |
| crates/bashkit-js/bashkit.*.node | |
| crates/bashkit-js/bashkit.*.wasm | |
| if-no-files-found: error | |
| # Upload generated JS stubs from one build (they're identical across targets) | |
| - if: ${{ matrix.settings.target == 'x86_64-unknown-linux-gnu' }} | |
| name: Upload JS stubs | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: js-stubs | |
| path: | | |
| crates/bashkit-js/browser.js | |
| crates/bashkit-js/index.cjs | |
| crates/bashkit-js/index.d.ts | |
| crates/bashkit-js/index.d.cts | |
| crates/bashkit-js/wrapper.js | |
| crates/bashkit-js/wrapper.d.ts | |
| crates/bashkit-js/bashkit.wasi.cjs | |
| crates/bashkit-js/bashkit.wasi-browser.js | |
| crates/bashkit-js/wasi-worker.mjs | |
| crates/bashkit-js/wasi-worker-browser.mjs | |
| if-no-files-found: error | |
| # ============================================================================ | |
| # Test bindings on macOS and Windows | |
| # ============================================================================ | |
| test-js-macos-windows: | |
| name: Test JS on ${{ matrix.settings.target }} - node@${{ matrix.node }} | |
| needs: [build-js] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| architecture: x64 | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| architecture: arm64 | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| architecture: x64 | |
| node: ["20", "22", "24"] | |
| runs-on: ${{ matrix.settings.host }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: npm | |
| cache-dependency-path: crates/bashkit-js/package-lock.json | |
| architecture: ${{ matrix.settings.architecture }} | |
| - name: Install dependencies | |
| run: npm install | |
| working-directory: crates/bashkit-js | |
| - name: Download native binding | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: js-bindings-${{ matrix.settings.target }} | |
| path: crates/bashkit-js | |
| - name: Download JS stubs | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: js-stubs | |
| path: crates/bashkit-js | |
| - name: Test bindings | |
| run: npm test | |
| working-directory: crates/bashkit-js | |
| - name: Run examples | |
| shell: bash | |
| run: | | |
| mkdir -p node_modules/@everruns | |
| if [ "$RUNNER_OS" = "Windows" ]; then | |
| cp -r crates/bashkit-js node_modules/@everruns/bashkit | |
| else | |
| ln -s ${{ github.workspace }}/crates/bashkit-js node_modules/@everruns/bashkit | |
| fi | |
| node examples/bash_basics.mjs | |
| node examples/data_pipeline.mjs | |
| node examples/llm_tool.mjs | |
| - name: Install AI SDK dependencies and re-link | |
| shell: bash | |
| run: | | |
| echo '{"type":"module","private":true}' > package.json | |
| npm install --no-save openai ai @ai-sdk/openai @langchain/core @langchain/langgraph @langchain/openai zod | |
| rm -rf node_modules/@everruns/bashkit | |
| mkdir -p node_modules/@everruns | |
| if [ "$RUNNER_OS" = "Windows" ]; then | |
| cp -r crates/bashkit-js node_modules/@everruns/bashkit | |
| else | |
| ln -s ${{ github.workspace }}/crates/bashkit-js node_modules/@everruns/bashkit | |
| fi | |
| - name: Install Doppler CLI | |
| if: env.DOPPLER_TOKEN != '' | |
| uses: dopplerhq/cli-action@v4 | |
| - name: Run AI examples | |
| if: env.DOPPLER_TOKEN != '' | |
| shell: bash | |
| run: | | |
| doppler run -- node examples/openai_tool.mjs | |
| doppler run -- node examples/vercel_ai_tool.mjs | |
| doppler run -- node examples/langchain_agent.mjs | |
| # ============================================================================ | |
| # Test bindings on Linux | |
| # ============================================================================ | |
| test-js-linux: | |
| name: Test JS ${{ matrix.target }} - node@${{ matrix.node }} | |
| needs: [build-js] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - x86_64-unknown-linux-gnu | |
| - aarch64-unknown-linux-gnu | |
| node: ["20", "22", "24"] | |
| runs-on: ${{ contains(matrix.target, 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: npm | |
| cache-dependency-path: crates/bashkit-js/package-lock.json | |
| - name: Output docker params | |
| id: docker | |
| run: | | |
| node -e " | |
| if ('${{ matrix.target }}'.startsWith('aarch64')) { | |
| console.log('PLATFORM=linux/arm64') | |
| } else { | |
| console.log('PLATFORM=linux/amd64') | |
| } | |
| " >> $GITHUB_OUTPUT | |
| node -e " | |
| if ('${{ matrix.target }}'.endsWith('-musl')) { | |
| console.log('IMAGE=node:${{ matrix.node }}-alpine') | |
| } else { | |
| console.log('IMAGE=node:${{ matrix.node }}-slim') | |
| } | |
| " >> $GITHUB_OUTPUT | |
| - name: Install dependencies | |
| run: npm install | |
| working-directory: crates/bashkit-js | |
| - name: Download native binding | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: js-bindings-${{ matrix.target }} | |
| path: crates/bashkit-js | |
| - name: Download JS stubs | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: js-stubs | |
| path: crates/bashkit-js | |
| - name: Test bindings | |
| run: > | |
| docker run --rm -v ${{ github.workspace }}:${{ github.workspace }} | |
| -w ${{ github.workspace }}/crates/bashkit-js | |
| --platform ${{ steps.docker.outputs.PLATFORM }} | |
| ${{ steps.docker.outputs.IMAGE }} | |
| npm test | |
| - name: Link package for examples | |
| run: | | |
| mkdir -p node_modules/@everruns | |
| ln -s ${{ github.workspace }}/crates/bashkit-js node_modules/@everruns/bashkit | |
| - name: Run examples | |
| run: > | |
| docker run --rm -v ${{ github.workspace }}:${{ github.workspace }} | |
| -w ${{ github.workspace }} | |
| --platform ${{ steps.docker.outputs.PLATFORM }} | |
| ${{ steps.docker.outputs.IMAGE }} | |
| sh -c "node examples/bash_basics.mjs && node examples/data_pipeline.mjs && node examples/llm_tool.mjs" | |
| - name: Install AI SDK dependencies and re-link | |
| run: | | |
| echo '{"type":"module","private":true}' > package.json | |
| npm install --no-save openai ai @ai-sdk/openai @langchain/core @langchain/langgraph @langchain/openai zod | |
| rm -rf node_modules/@everruns/bashkit | |
| mkdir -p node_modules/@everruns | |
| ln -s ${{ github.workspace }}/crates/bashkit-js node_modules/@everruns/bashkit | |
| - name: Install Doppler CLI | |
| if: env.DOPPLER_TOKEN != '' | |
| uses: dopplerhq/cli-action@v4 | |
| - name: Run AI examples | |
| if: env.DOPPLER_TOKEN != '' | |
| run: > | |
| docker run --rm -v ${{ github.workspace }}:${{ github.workspace }} | |
| -w ${{ github.workspace }} | |
| -e OPENAI_API_KEY=$(doppler secrets get OPENAI_API_KEY --plain) | |
| --platform ${{ steps.docker.outputs.PLATFORM }} | |
| ${{ steps.docker.outputs.IMAGE }} | |
| sh -c "node examples/openai_tool.mjs && node examples/vercel_ai_tool.mjs && node examples/langchain_agent.mjs" | |
| # ============================================================================ | |
| # Test WASI target — disabled until tokio feature gating is resolved | |
| # TODO: Re-enable when bashkit core gates tokio "full" behind a feature flag | |
| # ============================================================================ | |
| # test-js-wasi: | |
| # name: Test WASI target | |
| # needs: [build-js] | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v6 | |
| # - name: Setup node | |
| # uses: actions/setup-node@v6 | |
| # with: | |
| # node-version: 24 | |
| # cache: npm | |
| # cache-dependency-path: crates/bashkit-js/package-lock.json | |
| # - name: Install dependencies | |
| # run: npm install --cpu wasm32 | |
| # working-directory: crates/bashkit-js | |
| # - name: Download native binding | |
| # uses: actions/download-artifact@v8 | |
| # with: | |
| # name: js-bindings-wasm32-wasip1-threads | |
| # path: crates/bashkit-js | |
| # - name: Download JS stubs | |
| # uses: actions/download-artifact@v8 | |
| # with: | |
| # name: js-stubs | |
| # path: crates/bashkit-js | |
| # - name: Test bindings | |
| # run: npm test | |
| # env: | |
| # NAPI_RS_FORCE_WASI: 1 | |
| # working-directory: crates/bashkit-js | |
| # ============================================================================ | |
| # Publish to npm | |
| # ============================================================================ | |
| release-js: | |
| name: Release to NPM | |
| runs-on: ubuntu-latest | |
| needs: | |
| - test-js-macos-windows | |
| - test-js-linux | |
| if: success() | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: npm | |
| cache-dependency-path: crates/bashkit-js/package-lock.json | |
| registry-url: "https://registry.npmjs.org" | |
| - name: Install dependencies | |
| run: npm install | |
| working-directory: crates/bashkit-js | |
| - name: Download all native bindings | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: js-bindings-* | |
| merge-multiple: true | |
| path: crates/bashkit-js | |
| - name: Download JS stubs | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: js-stubs | |
| path: crates/bashkit-js | |
| - name: List package contents | |
| run: ls -lh bashkit.*.node bashkit.*.wasm 2>/dev/null || true | |
| working-directory: crates/bashkit-js | |
| - name: Publish | |
| run: | | |
| if [[ "$GITHUB_REF" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
| echo "Publishing stable release" | |
| npm publish --provenance --access public | |
| else | |
| echo "Publishing pre-release with 'next' tag" | |
| npm publish --provenance --tag next --access public | |
| fi | |
| working-directory: crates/bashkit-js | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} |