Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
73 changes: 73 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: "Build"
description: "Sets up environment and builds the WASM package"

inputs:
github-app-token:
description: "GitHub App token for private git deps"
required: false
default: ""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not need this if all outputs are public.

configure-git-user:
description: "Configure git user for commits"
required: false
default: "false"
node-version:
description: "Node.js version to install"
required: false
default: "24"
setup-npm-registry:
description: "Setup NPM registry URL"
required: false
default: "false"

runs:
using: "composite"
steps:
- name: Configure git for GitHub App auth (private deps and push)
if: ${{ inputs.github-app-token != '' }}
shell: bash
env:
BULLET_APP_TOKEN: ${{ inputs.github-app-token }}
run: |
git config --global --add url."https://x-access-token:${BULLET_APP_TOKEN}@github.com/".insteadOf "ssh://git@github.com/"
git config --global --add url."https://x-access-token:${BULLET_APP_TOKEN}@github.com/".insteadOf "git@github.com:"
git config --global --add url."https://x-access-token:${BULLET_APP_TOKEN}@github.com/".insteadOf "https://github.com/"
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which dependencies are needing these?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None, good point, this was copied from the old js sdk

- name: Configure Git user
if: ${{ inputs.configure-git-user == 'true' }}
shell: bash
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
registry-url: ${{ inputs.setup-npm-registry == 'true' && 'https://registry.npmjs.org' || '' }}

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown

- name: Rust cache
uses: Swatinem/rust-cache@v2

- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@main
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unpinned third-party action in release publish pipeline

Medium Severity

cargo-bins/cargo-binstall@main references a mutable branch rather than a commit SHA, unlike the other actions in this pipeline (e.g., actions/checkout and actions/setup-node are SHA-pinned). Since this composite action is used in the npm-publish.yml workflow that has id-token: write permission and publishes to npm with provenance, a compromised main branch in the cargo-binstall repo could inject malicious code into the published package. At minimum, the version input available on this action could be set to pin the installed binary version.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 059ac8f. Configure here.


- name: Install wasm-pack
shell: bash
run: cargo binstall wasm-pack -y

- name: Install just
uses: extractions/setup-just@v2

- name: Install npm dependencies
shell: bash
working-directory: ./wasm
run: npm install

- name: Build WASM
shell: bash
run: just build-wasm
Comment thread
cursor[bot] marked this conversation as resolved.
99 changes: 99 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Publishes @bulletxyz/sdk-wasm to npm. Triggered by the `v<version>` git tag
# that release-plz creates after a release PR is merged (see release-plz.yml).
# The version is already baked into wasm/Cargo.toml and wasm/package.json at this
# point, so this workflow only builds and publishes — no version bump, no commits.
#
# Authentication uses npm OIDC Trusted Publishers; configure at:
# https://www.npmjs.com/package/@bulletxyz/sdk-wasm/access
# See: https://docs.npmjs.com/generating-provenance-statements#publishing-packages-with-provenance-via-github-actions

name: NPM Publish

on:
push:
tags:
- "v*"
Comment thread
cursor[bot] marked this conversation as resolved.
workflow_dispatch:
inputs:
tag:
description: "Existing git tag to publish (e.g. v0.0.14)"
required: true
type: string

env:
CARGO_TERM_COLOR: always
CARGO_NET_GIT_FETCH_WITH_CLI: true
CI: 1

concurrency:
group: npm-publish
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Resolve ref
id: ref
env:
INPUT_TAG: ${{ inputs.tag }}
PUSH_REF: ${{ github.ref }}
run: |
if [ -n "${INPUT_TAG:-}" ]; then
echo "ref=${INPUT_TAG}" >> "$GITHUB_OUTPUT"
else
echo "ref=${PUSH_REF}" >> "$GITHUB_OUTPUT"
fi

- name: Checkout tag
uses: actions/checkout@v4
with:
ref: ${{ steps.ref.outputs.ref }}
persist-credentials: false
fetch-depth: 1

- name: Create GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.BULLET_DEPLOY_APP_ID }}
private-key: ${{ secrets.BULLET_DEPLOY_KEY }}
owner: ${{ github.repository_owner }}

- name: Verify tag matches Cargo + package.json versions
id: version
env:
REF: ${{ steps.ref.outputs.ref }}
run: |
set -euo pipefail
TAG="${REF#refs/tags/}"
V="${TAG#v}"
if ! echo "$V" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
echo "::error::Tag '$TAG' is not a valid semver tag" >&2
exit 1
fi
CARGO_V=$(grep -m1 '^version' wasm/Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
PKG_V=$(node -p "require('./wasm/package.json').version")
if [ "$V" != "$CARGO_V" ] || [ "$V" != "$PKG_V" ]; then
echo "::error::Version mismatch — tag=$V wasm/Cargo.toml=$CARGO_V wasm/package.json=$PKG_V" >&2
exit 1
fi
echo "version=$V" >> "$GITHUB_OUTPUT"

- name: Build
uses: ./.github/actions/build
with:
github-app-token: ${{ steps.app-token.outputs.token }}
setup-npm-registry: "true"

- name: Publish to npm
working-directory: wasm
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
TAG=$(echo "$VERSION" | grep -q '-' && echo "rc" || echo "latest")
npm publish --tag "$TAG" --access public
47 changes: 45 additions & 2 deletions .github/workflows/release-plz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,58 @@ jobs:
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
persist-credentials: false
persist-credentials: true

- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable

- name: Authenticate with crates.io
id: cargo-auth
uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe # v1.0.4

- uses: release-plz/action@1528104d2ca23787631a1c1f022abb64b34c1e11 # v0.5.128
- name: Run release-plz
id: release-plz
uses: release-plz/action@1528104d2ca23787631a1c1f022abb64b34c1e11 # v0.5.128
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
CARGO_REGISTRY_TOKEN: ${{ steps.cargo-auth.outputs.token }}

# release-plz bumps Rust crate versions in Cargo.toml, but doesn't know about
# wasm/package.json. Mirror the new wasm/Cargo.toml version onto the same
# release PR so the Rust crate and the @bulletxyz/sdk-wasm npm package stay
# in lockstep. The actual `npm publish` is handled by npm-publish.yml,
# which is triggered by the v<version> tag release-plz creates after merge.
- name: Sync wasm/package.json to release PR
if: ${{ steps.release-plz.outputs.pr != '' }}
env:
PR_JSON: ${{ steps.release-plz.outputs.pr }}
run: |
set -euo pipefail

BRANCH=$(echo "$PR_JSON" | jq -r '.head_branch')
if [ -z "$BRANCH" ] || [ "$BRANCH" = "null" ]; then
echo "No head_branch in release PR output; skipping package.json sync"
exit 0
fi

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

git fetch origin "$BRANCH"
git checkout "$BRANCH"

# cargo pkgid outputs "path+file:///…/wasm#bullet-rust-sdk-wasm@0.0.14" on
# modern Cargo, or "…#0.0.14" on older versions. Take whatever follows the
# final '#' or '@'.
V=$(cargo pkgid -p bullet-rust-sdk-wasm | sed -E 's/^.*[#@]([^#@]+)$/\1/')
echo "Syncing wasm/package.json to version $V"

(cd wasm && npm version "$V" --no-git-tag-version --allow-same-version)

if git diff --quiet -- wasm/package.json; then
echo "wasm/package.json already at $V; nothing to commit"
exit 0
fi

git add wasm/package.json
git commit -m "chore: sync wasm/package.json to $V"
git push origin "$BRANCH"
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
members = ["rust", "wasm"]
resolver = "2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can upgrade this to 3 now with latest rust versions (we just moved to rust 1.94)


[workspace.package]
version = "0.0.9"
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
edition = "2024"
license = "MIT"
repository = "https://github.com/bulletxyz/bullet-rust-sdk"

[workspace.dependencies]
bon = "3.9.0"
bullet-exchange-interface = { version = "0.2", features = ["schema"] }
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
packages = [
rust
pkgs.cargo-nextest
pkgs.cargo-edit
pkgs.just
(makeWasmPack pkgs)
pkgs.pkg-config
Expand Down
8 changes: 4 additions & 4 deletions release-plz.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ commit_parsers = [
{ message = "^build", skip = true },
]

# wasm crate ships to npm as @bulletxyz/sdk-wasm via a separate workflow_dispatch
# flow; release-plz only manages the Rust crate.
# `publish = false` mirrors wasm/Cargo.toml so release-plz's consistency check passes.
# wasm crate ships to npm as @bulletxyz/sdk-wasm (not crates.io). release-plz still
# bumps its version and tags it alongside the Rust crate; the npm-publish workflow
# triggers on the tag push and reuses that version for `npm publish`.
# `publish = false` mirrors wasm/Cargo.toml so release-plz skips the crates.io upload.
[[package]]
name = "bullet-rust-sdk-wasm"
release = false
publish = false
6 changes: 3 additions & 3 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[package]
name = "bullet-rust-sdk"
version = "0.0.13"
edition = "2024"
license = "MIT"
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "Rust SDK for the Bullet trading platform"
homepage = "https://www.bullet.xyz"
repository = "https://github.com/bulletxyz/bullet-rust-sdk"
readme = "../README.md"
keywords = ["bullet", "trading", "exchange", "sdk"]
categories = ["api-bindings", "cryptography::cryptocurrencies"]
Expand Down
6 changes: 3 additions & 3 deletions wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[package]
name = "bullet-rust-sdk-wasm"
version = "0.0.13"
edition = "2024"
license = "MIT"
edition.workspace = true
license.workspace = true
repository.workspace = true
description = "WebAssembly bindings for the Bullet trading SDK"
repository = "https://github.com/bulletxyz/bullet-rust-sdk"
publish = false # ships to npm as @bulletxyz/sdk-wasm, not crates.io

[lib]
Expand Down
4 changes: 3 additions & 1 deletion wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
],
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
Comment thread
Firaenix marked this conversation as resolved.
"build": "cd .. && just build-wasm",
"prepublishOnly": "[ -n \"$CI\" ] || npm run build"
},
"devDependencies": {
"@jest/globals": "30.3.0",
Expand Down
Loading