Publish to npm #76
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: Publish to npm | |
| on: | |
| workflow_call: | |
| inputs: | |
| release-tag: | |
| description: 'Release tag to fetch binaries from (e.g. v1.0.0)' | |
| required: true | |
| type: string | |
| dry-run: | |
| required: false | |
| type: boolean | |
| default: false | |
| workflow_dispatch: | |
| inputs: | |
| release-tag: | |
| description: 'Release tag to fetch binaries from (e.g. v1.0.0)' | |
| required: true | |
| type: string | |
| dry-run: | |
| description: 'Dry run (build packages but skip publish)' | |
| required: false | |
| type: boolean | |
| default: true | |
| concurrency: ${{ github.workflow }}-${{ github.ref }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write # Required for npm trusted publishing (OIDC) | |
| jobs: | |
| # Generate ACP TypeScript schema first - this is needed before building npm packages | |
| generate-schema: | |
| name: Generate ACP Schema | |
| runs-on: ubuntu-latest | |
| outputs: | |
| cache-key: ${{ steps.cache-key.outputs.key }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Generate cache key | |
| id: cache-key | |
| run: | | |
| # Create a cache key based on ACP crate files | |
| HASH=$(find crates/goose-acp -type f -name "*.rs" -o -name "Cargo.toml" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1) | |
| echo "key=acp-schema-$HASH" >> "$GITHUB_OUTPUT" | |
| echo "Generated cache key: acp-schema-$HASH" | |
| - name: Check cache | |
| id: cache | |
| uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4 | |
| with: | |
| path: | | |
| crates/goose-acp/acp-schema.json | |
| crates/goose-acp/acp-meta.json | |
| key: ${{ steps.cache-key.outputs.key }} | |
| - name: Setup Rust | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable | |
| - name: Setup Rust cache | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: Swatinem/rust-cache@42dc69e1aa15d09112580998cf2ef0119e2e91ae # v2 | |
| - name: Build and run generate-acp-schema | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| cargo build --release --bin generate-acp-schema | |
| cargo run --release --bin generate-acp-schema | |
| working-directory: crates/goose-acp | |
| - name: Upload schema artifacts | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: acp-schema | |
| path: | | |
| crates/goose-acp/acp-schema.json | |
| crates/goose-acp/acp-meta.json | |
| if-no-files-found: error | |
| retention-days: 7 | |
| # Build npm packages (no environment needed) | |
| build: | |
| name: Build npm packages | |
| runs-on: ubuntu-latest | |
| needs: [generate-schema] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '24.10.0' | |
| registry-url: 'https://registry.npmjs.org' | |
| always-auth: true | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4 | |
| with: | |
| version: 10.30.3 | |
| - name: Download ACP schema | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: acp-schema | |
| path: crates/goose-acp | |
| - name: Download goose binaries from release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="${{ inputs.release-tag }}" | |
| echo "Downloading goose CLI binaries from release ${TAG}" | |
| # Map: npm platform name -> release artifact name (target triple) | |
| declare -A PLATFORM_MAP=( | |
| [darwin-arm64]=aarch64-apple-darwin | |
| [darwin-x64]=x86_64-apple-darwin | |
| [linux-arm64]=aarch64-unknown-linux-gnu | |
| [linux-x64]=x86_64-unknown-linux-gnu | |
| [win32-x64]=x86_64-pc-windows-msvc | |
| ) | |
| for platform in "${!PLATFORM_MAP[@]}"; do | |
| target="${PLATFORM_MAP[$platform]}" | |
| pkg_dir="ui/goose-binary/goose-binary-${platform}/bin" | |
| mkdir -p "${pkg_dir}" | |
| if [[ "${platform}" == "win32-x64" ]]; then | |
| artifact="goose-${target}.zip" | |
| gh release download "${TAG}" --pattern "${artifact}" --dir /tmp | |
| unzip -o "/tmp/${artifact}" -d /tmp/goose-extract | |
| cp /tmp/goose-extract/goose-package/goose.exe "${pkg_dir}/goose.exe" | |
| rm -rf /tmp/goose-extract "/tmp/${artifact}" | |
| else | |
| artifact="goose-${target}.tar.bz2" | |
| gh release download "${TAG}" --pattern "${artifact}" --dir /tmp | |
| mkdir -p /tmp/goose-extract | |
| tar -xjf "/tmp/${artifact}" -C /tmp/goose-extract | |
| cp /tmp/goose-extract/goose "${pkg_dir}/goose" | |
| chmod +x "${pkg_dir}/goose" | |
| rm -rf /tmp/goose-extract "/tmp/${artifact}" | |
| fi | |
| echo " ✅ ${platform} (${target})" | |
| done | |
| - name: List downloaded artifacts (debug) | |
| run: | | |
| echo "Downloaded ACP schema:" | |
| ls -lh crates/goose-acp/acp-*.json | |
| echo "" | |
| echo "Downloaded goose CLI binaries:" | |
| find ui/goose-binary -name 'goose*' -type f | sort | |
| - name: Install dependencies | |
| run: | | |
| cd ui | |
| pnpm install --frozen-lockfile | |
| - name: Generate TypeScript types from schema | |
| run: | | |
| cd ui/acp | |
| # The schema JSON files are already downloaded, just generate TS types | |
| # This only runs the TypeScript generation part, no Rust compilation | |
| npx tsx generate-schema.ts | |
| - name: Build packages | |
| run: | | |
| cd ui/acp | |
| # Build only TypeScript, schema is already generated | |
| pnpm run build:ts | |
| cd ../text | |
| pnpm run build | |
| - name: Upload built packages | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: npm-packages | |
| path: ui/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| - name: Build summary | |
| run: | | |
| { | |
| echo "## 📦 Build Summary" | |
| echo "" | |
| echo "### Release" | |
| echo "Tag: \`${{ inputs.release-tag }}\`" | |
| echo "" | |
| echo "### ACP Schema" | |
| echo "✅ Generated and cached" | |
| echo "" | |
| echo "### Goose CLI Binaries" | |
| echo "✅ Downloaded from release for all platforms:" | |
| for dir in ui/goose-binary/goose-binary-*/; do | |
| platform=$(basename "$dir" | sed 's/goose-binary-//') | |
| echo " - $platform" | |
| done | |
| echo "" | |
| echo "### npm Packages" | |
| cd ui | |
| for pkg in acp text goose-binary/*/; do | |
| if [ -f "$pkg/package.json" ]; then | |
| name=$(jq -r '.name' "$pkg/package.json") | |
| version=$(jq -r '.version' "$pkg/package.json") | |
| echo "- $name@$version" | |
| fi | |
| done | |
| echo "" | |
| if [ "${{ inputs.dry-run }}" = "true" ]; then | |
| echo "### ⚠️ Dry run — packages were built but will NOT be published" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| # Publish to npm (requires environment approval for OIDC token) | |
| publish: | |
| name: Publish to npm | |
| if: inputs.dry-run != true | |
| runs-on: ubuntu-latest | |
| needs: [build] | |
| environment: npm-production-publishing | |
| steps: | |
| - name: Download built packages | |
| uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 | |
| with: | |
| name: npm-packages | |
| path: ui/ | |
| - name: Setup Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | |
| with: | |
| node-version: '24.10.0' | |
| registry-url: 'https://registry.npmjs.org' | |
| always-auth: true | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4 | |
| with: | |
| version: 10.30.3 | |
| - name: Publish to npm | |
| run: | | |
| cd ui | |
| # Authentication is handled via OIDC trusted publishing (no token needed) | |
| pnpm publish -r --access public --no-git-checks --provenance | |
| - name: Publish summary | |
| run: | | |
| cd ui | |
| { | |
| echo "## 🚀 Published Packages" | |
| echo "" | |
| for pkg in acp text goose-binary/*/; do | |
| if [ -f "$pkg/package.json" ]; then | |
| name=$(jq -r '.name' "$pkg/package.json") | |
| version=$(jq -r '.version' "$pkg/package.json") | |
| echo "- $name@$version" | |
| fi | |
| done | |
| } >> "$GITHUB_STEP_SUMMARY" |