Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ testdata/fixtures/**/* eol=lf

dprint.json linguist-language=JSON-with-Comments
.devcontainer/devcontainer.json linguist-language=JSON-with-Comments

.env.example linguist-language=Dotenv
51 changes: 28 additions & 23 deletions .github/workflows/npm.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish NPM
name: npm

on:
workflow_dispatch:
Expand All @@ -22,6 +22,7 @@ defaults:
env:
ACTIONS_RUNNER_DEBUG: true
NPM_CONFIG_PROVENANCE: true
NPM_REGISTRY_URL: "https://registry.npmjs.org"

jobs:
publish-arch:
Expand Down Expand Up @@ -54,31 +55,38 @@ jobs:
}}
outputs:
RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }}
env:
NPM_REGISTRY_URL: "https://registry.npmjs.org"
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set Isolated Artifact Directory
id: set-artifact-dir
# Use RUNNER_TEMP env var to persist ARTIFACT_DIR across steps
run: echo "ARTIFACT_DIR=$RUNNER_TEMP/foundry_artifacts" >> "$GITHUB_ENV"

- name: Prepare Isolated Artifact Directory
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_*"
path: foundry_artifacts
# Extract artifacts into an isolated temp directory, not the workspace
path: ${{ runner.temp }}/foundry_artifacts
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id || inputs.run_id }}

- name: Setup Bun
uses: oven-sh/setup-bun@main
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2
with:
bun-version: latest
registries: |
https://registry.npmjs.org

- name: Setup Node (for npm publish auth)
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
Expand All @@ -102,12 +110,12 @@ jobs:
run: |
set -euo pipefail

echo "Artifacts in foundry_artifacts:"
ls -la ../foundry_artifacts || true
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 ../foundry_artifacts/foundry_* 2>/dev/null | head -n1 || true)
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
Expand All @@ -125,20 +133,20 @@ jobs:
RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }}
run: |
set -euo pipefail
mkdir -p tmp
mkdir -p "$ARTIFACT_DIR/tmp"

FILE_PREFIX="../foundry_artifacts/foundry_${RELEASE_VERSION}_${{ matrix.os }}_${{ matrix.arch }}"
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 ./tmp
BIN=./tmp/forge.exe
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 ./tmp
BIN=./tmp/forge
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 }}"
Expand Down Expand Up @@ -193,23 +201,20 @@ jobs:
name: Publish Meta Package
runs-on: ubuntu-latest
env:
RELEASE_VERSION: ${{ needs.publish-arch.outputs.RELEASE_VERSION }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_REGISTRY_URL: "https://registry.npmjs.org"
RELEASE_VERSION: ${{ needs.publish-arch.outputs.RELEASE_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Bun
uses: oven-sh/setup-bun@main
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # v2.0.2
with:
bun-version: latest
registries: |
https://registry.npmjs.org

- name: Setup Node (for npm publish auth)
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
Expand Down
4 changes: 2 additions & 2 deletions dprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
"plugins": [
"https://plugins.dprint.dev/toml-0.7.0.wasm",
"https://plugins.dprint.dev/json-0.20.0.wasm",
"https://plugins.dprint.dev/markdown-0.18.0.wasm",
"https://plugins.dprint.dev/markdown-0.19.0.wasm",
"https://plugins.dprint.dev/dockerfile-0.3.3.wasm",
"https://plugins.dprint.dev/typescript-0.95.7.wasm",
"https://plugins.dprint.dev/typescript-0.95.11.wasm",
"https://plugins.dprint.dev/g-plane/pretty_yaml-v0.5.1.wasm"
],
"markdown": {
Expand Down
12 changes: 9 additions & 3 deletions npm/.env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
NODE_ENV="development"

NPM_TOKEN=""
NPM_REGISTRY_URL=""
NPM_USERNAME="foundry-rs"

PLATFORM_NAME=""
ARCH=""
ARCH=""

# for testing purposes
NPM_EMAIL=""
NPM_PASSWORD=""
NPM_REGISTRY_URL=""
NPM_USER="foundry-rs"
ALLOW_NO_INTEGRITY=false
ALLOW_INSECURE_REGISTRY=false
2 changes: 1 addition & 1 deletion npm/@foundry-rs/forge-darwin-amd64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foundry-rs/forge-darwin-amd64",
"version": "1.3.2",
"version": "0.0.0",
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework (macOS amd64)",
Expand Down
2 changes: 1 addition & 1 deletion npm/@foundry-rs/forge-darwin-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foundry-rs/forge-darwin-arm64",
"version": "1.3.2",
"version": "0.0.0",
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework (macOS arm64)",
Expand Down
2 changes: 1 addition & 1 deletion npm/@foundry-rs/forge-linux-amd64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foundry-rs/forge-linux-amd64",
"version": "1.3.2",
"version": "0.0.0",
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework (Linux amd64)",
Expand Down
2 changes: 1 addition & 1 deletion npm/@foundry-rs/forge-linux-arm64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foundry-rs/forge-linux-arm64",
"version": "1.3.2",
"version": "0.0.0",
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework (Linux arm64)",
Expand Down
2 changes: 1 addition & 1 deletion npm/@foundry-rs/forge-win32-amd64/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foundry-rs/forge-win32-amd64",
"version": "1.3.2",
"version": "0.0.0",
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework (Windows amd64)",
Expand Down
6 changes: 3 additions & 3 deletions npm/@foundry-rs/forge/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# forge
# Forge

A CLI tool for testing, building, and deploying your smart contracts.
See <https://getfoundry.sh/forge/overview> for details.
Forge is a command-line tool that ships with Foundry. Forge tests, builds, and deploys your smart contracts.
Forge is part of the Foundry suite and is installed alongside `cast`, `chisel`, and `anvil`.
4 changes: 0 additions & 4 deletions npm/@foundry-rs/forge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
"type": "module",
"homepage": "https://getfoundry.sh/forge",
"description": "Fast and flexible Ethereum testing framework",
"main": "./dist/index.mjs",
"engines": {
"node": ">=20"
},
"bin": {
"forge": "./bin/forge.mjs"
},
Expand Down
73 changes: 2 additions & 71 deletions npm/README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,5 @@
# @foundry-rs npm Packages

This folder contains the npm packages for the Foundry CLI.
The npm folder contains the meta packages for `forge` (`@foundry-rs/forge`) and per-arch packages (e.g. `@foundry-rs/forge-darwin-arm64`).

- `@foundry-rs/forge`,
- `@foundry-rs/anvil` (soon),

## Local publish & Test

The npm folder contains the meta package `@foundry-rs/forge` and per-arch packages (e.g. `@foundry-rs/forge-darwin-arm64`). This guide shows how to publish them to a local registry and test via npx/bunx.

### Prerequisites

- Node.js LTS, npm, and Bun installed (`bun -v`).
- Docker (recommended) or a local [Verdaccio](https://verdaccio.org) install.
- Optional: Rust toolchain if you want to build a fresh `forge` binary (`cargo build --release -p forge`).

Start a local npm registry (Verdaccio) with Docker:

- Docker: `docker run -it --rm --name verdaccio -p 4873:4873 verdaccio/verdaccio`
- Verify: open `http://localhost:4873` in a browser
- Note: you might need to bump `max_body_size` in [Verdaccio `config.yaml`](https://verdaccio.org/docs/configuration#max-body-size):

```yaml
max_body_size: 300mb # default is 10mb
```

I enter the docker image then `echo 'max_body_size: 300mb' >> /verdaccio/conf/config.yaml`

Authenticate npm to Verdaccio

- Create a user/token: `npm adduser --registry http://localhost:4873 --scope=@foundry-rs`
- Ensure your auth token is present (either in `~/.npmrc` or a project `.npmrc`):
- `registry=http://localhost:4873`
- `//localhost:4873/:_authToken=YOUR_TOKEN`

#### Quick publish (macOS arm64)

- From `npm/` in this repo:
- `export NPM_REGISTRY_URL=http://localhost:4873`
- `export NPM_TOKEN=localtesttoken` # required by scripts; any non-empty value works
- `bun install`
- `./scripts/setup-local.sh`
- This publishes `@foundry-rs/forge-darwin-arm64` and then `@foundry-rs/forge` to your local registry.

### Manual publish (any platform)

- Build wrappers: `cd npm && bun install && npm run build`
- If you have a local `forge` binary, stage it for your platform:
- Example (macOS arm64):
- `cargo build --release -p forge`
- `cd npm`
- `ARCH=arm64 PLATFORM_NAME=darwin FORGE_BIN_PATH=../target/release/forge bun ./scripts/prepublish.ts`
- Publish the platform package, then the meta package (versions auto-synced from Cargo.toml unless overridden by `VERSION_NAME`):
- `export NPM_REGISTRY_URL=http://localhost:4873`
- `export NPM_TOKEN=localtesttoken`
- `bun run ./scripts/publish.ts ./@foundry-rs/forge-<platform>-<arch>`
- `bun run ./scripts/publish.ts ./@foundry-rs/forge`

#### Run from a test workspace

- Use the provided workspace: `cd npm/test/workspace`
- Registry config is already set (`.npmrc` and `bunfig.toml` point to `http://localhost:4873`).
- With npm: `npx @foundry-rs/forge --version`
- With Bun: `bunx @foundry-rs/forge --version`
- Alternatively from anywhere, force the local registry:
- `npm_config_registry=http://localhost:4873 npx @foundry-rs/forge --version`
- `REGISTRY_URL=http://localhost:4873 bunx @foundry-rs/forge --version`

#### Notes

- The meta package’s `postinstall` either installs the platform-specific optionalDependency or downloads its tarball from the configured registry.
- Publish arch packages first, then the meta package; the publish script auto-updates `optionalDependencies` to the same version.
- If `npm publish` returns 401, ensure you ran `npm adduser` against `http://localhost:4873` and that your token is present in `.npmrc` or provided via `NODE_AUTH_TOKEN`.
A guide on how to publish to a local registry and test via `npx`/`bunx` is available in [./test/README.md](./test/README.md).
Loading
Loading