Skip to content

npm

npm #112

Workflow file for this run

name: npm
permissions: {}
on:
workflow_dispatch:
inputs:
run_id:
type: string
required: false
description: The run id of the release to publish
workflow_run:
types: [completed]
workflows: [release]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
env:
ACTIONS_RUNNER_DEBUG: true
NPM_CONFIG_PROVENANCE: true
NPM_REGISTRY_URL: "https://registry.npmjs.org"
jobs:
publish-arch:
permissions:
contents: read
actions: read
id-token: write
name: ${{ matrix.os }}-${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
max-parallel: 3
fail-fast: false
matrix:
include:
- os: linux
arch: amd64
- os: linux
arch: arm64
- os: darwin
arch: amd64
- os: darwin
arch: arm64
- os: win32
arch: amd64
# Run automatically after a successful 'release' workflow, or manually if a run_id is provided
if: >-
${{
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') ||
(github.event_name == 'workflow_dispatch' && inputs.run_id != '')
}}
outputs:
RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set Isolated Artifact Directory
id: paths
run: |
set -euo pipefail
printf 'artifact_dir=%s\n' "$RUNNER_TEMP/foundry_artifacts" >> "$GITHUB_OUTPUT"
- name: Prepare Isolated Artifact Directory
env:
ARTIFACT_DIR: ${{ steps.paths.outputs.artifact_dir }}
run: |
mkdir -p "$ARTIFACT_DIR"
ls -la "$ARTIFACT_DIR" || true
- name: Download Release Assets
uses: actions/download-artifact@v5
with:
merge-multiple: true
# Download all foundry artifacts from the triggering release run
pattern: "foundry_*"
# Extract artifacts into an isolated temp directory, not the workspace
path: ${{ steps.paths.outputs.artifact_dir }}
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || inputs.run_id }}
- name: Setup Bun
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2
with:
bun-version: latest
- name: Setup Node (for npm publish auth)
uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Install Dependencies
working-directory: ./npm
run: bun install --frozen-lockfile
- name: Transpile TS -> JS
working-directory: ./npm
run: bun run build
- name: Derive RELEASE_VERSION
id: release-version
working-directory: ./npm
env:
PROVENANCE: true
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_REGISTRY_URL: ${{ env.NPM_REGISTRY_URL }}
ARTIFACT_DIR: ${{ steps.paths.outputs.artifact_dir }}
run: |
set -euo pipefail
echo "Artifacts in $ARTIFACT_DIR:"
ls -la "$ARTIFACT_DIR" || true
# Derive RELEASE_VERSION from any foundry artifact we downloaded
# Expected names: foundry_<VERSION>_<platform>_<arch>.{tar.gz,zip}
first_file=$(ls "$ARTIFACT_DIR"/foundry_* 2>/dev/null | head -n1 || true)
if [[ -z "${first_file}" ]]; then
echo "No foundry artifacts found to publish" >&2
exit 1
fi
version_part=$(basename "$first_file")
version_part=${version_part#foundry_}
export RELEASE_VERSION=${version_part%%_*}
echo "Detected RELEASE_VERSION=$RELEASE_VERSION"
printf 'RELEASE_VERSION=%s\n' "$RELEASE_VERSION" >>"$GITHUB_OUTPUT"
- name: Stage Binary Into Package
working-directory: ./npm
env:
RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }}
ARTIFACT_DIR: ${{ steps.paths.outputs.artifact_dir }}
run: |
set -euo pipefail
mkdir -p "$ARTIFACT_DIR/tmp"
FILE_PREFIX="$ARTIFACT_DIR/foundry_${RELEASE_VERSION}_${{ matrix.os }}_${{ matrix.arch }}"
if [[ -f "${FILE_PREFIX}.zip" ]]; then
echo "Extracting ${FILE_PREFIX}.zip"
if ! command -v unzip >/dev/null 2>&1; then
sudo apt-get update -y && sudo apt-get install -y unzip
fi
unzip -o "${FILE_PREFIX}.zip" -d "$ARTIFACT_DIR/tmp"
BIN="$ARTIFACT_DIR/tmp/forge.exe"
else
echo "Extracting ${FILE_PREFIX}.tar.gz"
tar -xzf "${FILE_PREFIX}.tar.gz" -C "$ARTIFACT_DIR/tmp"
BIN="$ARTIFACT_DIR/tmp/forge"
fi
echo "Staging binary $BIN into @foundry-rs/forge-${{ matrix.os }}-${{ matrix.arch }}"
PLATFORM_NAME=${{ matrix.os }} ARCH=${{ matrix.arch }} FORGE_BIN_PATH="$BIN" bun ./scripts/prepublish.ts
- name: Sanity Check Binary
working-directory: ./npm
run: |
set -euo pipefail
PKG_DIR="./@foundry-rs/forge-${{ matrix.os }}-${{ matrix.arch }}"
BIN="$PKG_DIR/bin/forge"
if [[ "${{ matrix.os }}" == "win32" ]]; then
BIN="$PKG_DIR/bin/forge.exe"
fi
echo "Verifying binary at: $BIN"
ls -la "$BIN"
if [[ ! -f "$BIN" ]]; then
echo "ERROR: Binary not found at $BIN" >&2
exit 1
fi
if [[ "${{ matrix.os }}" != "win32" ]]; then
if [[ ! -x "$BIN" ]]; then
echo "ERROR: Binary not marked executable" >&2
exit 1
fi
fi
- name: Publish ${{ matrix.os }}-${{ matrix.arch }} Binary
working-directory: ./npm
env:
PROVENANCE: true
VERSION_NAME: ${{ steps.release-version.outputs.RELEASE_VERSION }}
RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set -euo pipefail
ls -la ./@foundry-rs/forge-${{ matrix.os }}-${{ matrix.arch }}
bun ./scripts/publish.ts ./@foundry-rs/forge-${{ matrix.os }}-${{ matrix.arch }}
echo "Published @foundry-rs/forge-${{ matrix.os }}-${{ matrix.arch }}"
publish-meta:
permissions:
contents: read
actions: read
id-token: write
needs: publish-arch
name: Publish Meta Package
runs-on: ubuntu-latest
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
RELEASE_VERSION: ${{ needs.publish-arch.outputs.RELEASE_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Setup Bun
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2
with:
bun-version: latest
- name: Setup Node (for npm publish auth)
uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Install Dependencies
working-directory: ./npm
run: bun install --frozen-lockfile
- name: Transpile TS -> JS
working-directory: ./npm
run: bun run build
- name: Publish Meta
working-directory: ./npm
run: bun run ./scripts/publish.ts ./@foundry-rs/forge
env:
PROVENANCE: true
VERSION_NAME: ${{ env.RELEASE_VERSION }}
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
NPM_TOKEN: ${{ env.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ env.NODE_AUTH_TOKEN }}
NPM_REGISTRY_URL: ${{ env.NPM_REGISTRY_URL }}