Skip to content
Merged
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
165 changes: 110 additions & 55 deletions .github/workflows/npm-package-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ on:

jobs:
release:
# skip this job if the commit was created by this workflow (prevents infinite loop)
if: ${{ github.ref == 'refs/heads/main' && !startsWith(github.event.head_commit.message, 'NPM Package Release') }}
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
env:
DEPLOYMENT_KEY: ${{ github.ref == 'refs/heads/main' && secrets.PRIVATE_KEY || secrets.PRIVATE_KEY_DEV }}
DEPLOYMENT_KEY: ${{ secrets.PRIVATE_KEY }}
DEPLOY_METABOARD_ADDRESS: ${{ vars.CI_DEPLOY_SEPOLIA_METABOARD_ADDRESS }}
CI_FORK_SEPOLIA_BLOCK_NUMBER: ${{ vars.CI_FORK_SEPOLIA_BLOCK_NUMBER }}
CI_FORK_SEPOLIA_DEPLOYER_ADDRESS: ${{ vars.CI_FORK_SEPOLIA_DEPLOYER_ADDRESS }}
Expand All @@ -25,49 +26,102 @@ jobs:
outputs:
version: ${{ env.NEW_VERSION }}
steps:
# checkout with SSH key to allow pushing version bump commits back to repo
- uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.PUBLISH_PRIVATE_KEY }}

- uses: nixbuild/nix-quick-install-action@v30
# WASM builds require significant disk space; free up space to prevent build failures
- name: Free disk space
uses: jlumbroso/free-disk-space@v1.3.1
with:
nix_conf: |
keep-env-derivations = true
keep-outputs = true
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v6
swap-storage: false

# install nix for building WASM artifacts and running tests
- uses: DeterminateSystems/nix-installer-action@main
with:
# restore and save a cache using this key
primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }}
# if there's no cache hit, restore a cache by this prefix
restore-prefixes-first-match: nix-${{ runner.os }}-
# collect garbage until the Nix store size (in bytes) is at most this number
# before trying to save a new cache
# 1G = 1073741824
gc-max-store-size-linux: 1G

- name: Install NodeJS v22
determinate: true
# cache nix store to speed up subsequent builds
- uses: DeterminateSystems/flakehub-cache-action@main

# setup node with npm registry for OIDC-based publishing (no NPM_TOKEN needed)
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: "npm"
node-version: "24.x"
registry-url: "https://registry.npmjs.org"

# npm 10.9+ required for OIDC provenance support
- name: Upgrade npm for OIDC
run: |
npm install -g npm@latest
npm --version

# ensure GitHub Actions OIDC token is available for npm provenance attestation
- name: Verify OIDC availability
run: |
if [ -n "${ACTIONS_ID_TOKEN_REQUEST_URL}" ] && [ -n "${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" ]; then
echo "OIDC token available"
echo "Endpoint: ${ACTIONS_ID_TOKEN_REQUEST_URL}"
else
echo "OIDC token NOT available"
echo "Check workflow permissions include 'id-token: write'"
exit 1
fi

# npm OIDC publish requires package.json repository URL to match git remote
# mismatch causes 422 error during publish
- name: Verify repository configuration
run: |
echo "Checking repository consistency..."
GIT_REPO=$(git remote get-url origin | sed 's/.*github.com[/:]//; s/.git$//')
OB_PKG_REPO=$(node -e "console.log(require('./packages/orderbook/package.json').repository?.url || '')" | sed 's|https://github.com/||; s|git+||; s|.git$||')
UC_PKG_REPO=$(node -e "console.log(require('./packages/ui-components/package.json').repository?.url || '')" | sed 's|https://github.com/||; s|git+||; s|.git$||')
echo "Git remote: $GIT_REPO"
echo "orderbook package.json: $OB_PKG_REPO"
echo "ui-components package.json: $UC_PKG_REPO"
if [ "$GIT_REPO" != "$OB_PKG_REPO" ]; then
echo "Repository mismatch for orderbook!"
echo "This will cause 422 error during publish"
exit 1
fi
if [ "$GIT_REPO" != "$UC_PKG_REPO" ]; then
echo "Repository mismatch for ui-components!"
echo "This will cause 422 error during publish"
exit 1
fi
echo "Repositories match"

# install dependencies and build the workspace
- run: ./prep-base.sh

# remove debug artifacts to free disk space before WASM build
- name: Remove Unused Artifacts
run: rm -rf ./target/debug

# WASM linker can run out of memory on GitHub runners; add swap to prevent OOM
- name: Add swap space
run: |
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# build and test WASM bindings
- name: Test JS/TS Binding 1/2
run: nix develop -c rainix-wasm-test

# cleanup between test phases to prevent disk space exhaustion
- name: Remove Test Artifacts
run: |
rm -rf ./target/debug
rm -rf ./target/wasm32-unknown-unknown/debug

# run JS/TS integration tests against WASM bindings
- name: Test JS/TS Binding 2/2
run: nix develop -c test-js-bindings

# build and test UI components before publishing
- name: Build UI Components
run: nix develop -c npm run build -w @rainlanguage/ui-components
- name: Test UI Components
Expand All @@ -84,6 +138,7 @@ jobs:
with:
working-directory: packages/ui-components

# configure git identity for version bump commits
- name: Git Config
run: |
git config --global user.email "${{ secrets.CI_GIT_EMAIL }}"
Expand All @@ -92,8 +147,8 @@ jobs:
# get hash of latest published pkgs from npm and concat them
- name: Get Old Hash
run: |
OB_PKG_OLD_HASH=$(npm view @rainlanguage/orderbook@latest dist.shasum)
UC_PKG_OLD_HASH=$(npm view @rainlanguage/ui-components@latest dist.shasum)
OB_PKG_OLD_HASH=$(npm view @rainlanguage/orderbook@latest dist.shasum 2>/dev/null || echo "none")
UC_PKG_OLD_HASH=$(npm view @rainlanguage/ui-components@latest dist.shasum 2>/dev/null || echo "none")
OLD_HASH=$OB_PKG_OLD_HASH-$UC_PKG_OLD_HASH
echo "OLD_HASH=$OLD_HASH" >> $GITHUB_ENV
echo "old hash: $OLD_HASH"
Expand Down Expand Up @@ -121,63 +176,63 @@ jobs:
npx prettier --write ./packages/ui-components/package.json
npm version prerelease --preid alpha --no-git-tag-version -w @rainlanguage/ui-components

# Commit changes and tag
- name: Commit And Tag
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: |
git add "packages/orderbook/package.json"
git add "packages/ui-components/package.json"
git add "package-lock.json"
git commit -m "NPM Package Release v${{ env.NEW_VERSION }}"
git tag npm-v${{ env.NEW_VERSION }}

# Push the commit to remote
- name: Push Changes To Remote
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: |
git push origin
git push -u origin npm-v${{ env.NEW_VERSION }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Create orderbook npm package tarball
- name: Create orderbook NPM Package Tarball
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: echo "NPM_PACKAGE=$(npm pack --silent -w @rainlanguage/orderbook)" >> $GITHUB_ENV
run: echo "OB_NPM_PACKAGE=$(npm pack --silent -w @rainlanguage/orderbook)" >> $GITHUB_ENV

- name: Rename orderbook NPM Package Tarball
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: mv ${{ env.NPM_PACKAGE }} orderbook_npm_package_${{ env.NEW_VERSION }}.tgz
run: mv ${{ env.OB_NPM_PACKAGE }} orderbook_npm_package_${{ env.NEW_VERSION }}.tgz

# publish orderbook pkg to npm
- name: Publish orderbook pkg To NPM
if: ${{ env.OLD_HASH != env.NEW_HASH }}
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
access: public
package: orderbook_npm_package_${{ env.NEW_VERSION }}.tgz
run: |
npm publish orderbook_npm_package_${{ env.NEW_VERSION }}.tgz \
--access public \
--tag latest \
--verbose

# Create npm package tarball for ui-components
- name: Create ui-components NPM Package Tarball
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: echo "NPM_PACKAGE=$(npm pack --silent -w @rainlanguage/ui-components)" >> $GITHUB_ENV
run: echo "UC_NPM_PACKAGE=$(npm pack --silent -w @rainlanguage/ui-components)" >> $GITHUB_ENV

- name: Rename ui-components NPM Package Tarball
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: mv ${{ env.NPM_PACKAGE }} ui_components_npm_package_${{ env.NEW_VERSION }}.tgz
run: mv ${{ env.UC_NPM_PACKAGE }} ui_components_npm_package_${{ env.NEW_VERSION }}.tgz

# publish ui-components to npm
- name: Publish ui-components To NPM
if: ${{ env.OLD_HASH != env.NEW_HASH }}
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
access: public
package: ui_components_npm_package_${{ env.NEW_VERSION }}.tgz
run: |
npm publish ui_components_npm_package_${{ env.NEW_VERSION }}.tgz \
--access public \
--tag latest \
--verbose
Comment on lines 206 to +213

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.

⚠️ Potential issue | 🔴 Critical

Same authentication issue as orderbook publish.

Apply the same fix here: add NODE_AUTH_TOKEN environment variable and --provenance flag.

🐛 Proposed fix
       - name: Publish ui-components To NPM
         if: ${{ env.OLD_HASH != env.NEW_HASH }}
         run: |
           npm publish ui_components_npm_package_${{ env.NEW_VERSION }}.tgz \
             --access public \
             --tag latest \
+            --provenance \
             --verbose
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# publish ui-components to npm
- name: Publish ui-components To NPM
if: ${{ env.OLD_HASH != env.NEW_HASH }}
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
access: public
package: ui_components_npm_package_${{ env.NEW_VERSION }}.tgz
run: |
npm publish ui_components_npm_package_${{ env.NEW_VERSION }}.tgz \
--access public \
--tag latest \
--verbose
# publish ui-components to npm
- name: Publish ui-components To NPM
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: |
npm publish ui_components_npm_package_${{ env.NEW_VERSION }}.tgz \
--access public \
--tag latest \
--provenance \
--verbose
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
🤖 Prompt for AI Agents
In @.github/workflows/npm-package-release.yml around lines 206 - 213, The
publish step named "Publish ui-components To NPM" is missing authentication and
provenance flags; update the npm publish invocation to export/use
NODE_AUTH_TOKEN in the step environment (add NODE_AUTH_TOKEN: ${{
secrets.NPM_TOKEN }} to the job/step env) and append the --provenance flag to
the npm publish command (the line invoking npm publish
ui_components_npm_package_${{ env.NEW_VERSION }}.tgz should include
--provenance), leaving the existing --access, --tag and --verbose flags intact;
ensure the step still runs under the same if condition (if: ${{ env.OLD_HASH !=
env.NEW_HASH }}).


# Commit changes and tag
- name: Commit And Tag
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: |
git add "packages/orderbook/package.json"
git add "packages/ui-components/package.json"
git add "package-lock.json"
git commit -m "NPM Package Release v${{ env.NEW_VERSION }}"
git tag npm-v${{ env.NEW_VERSION }}

# Push the commit to remote
- name: Push Changes To Remote
if: ${{ env.OLD_HASH != env.NEW_HASH }}
run: |
git push origin
git push -u origin npm-v${{ env.NEW_VERSION }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Comment on lines +225 to +232

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.

🧹 Nitpick | 🔵 Trivial

Potentially redundant GITHUB_TOKEN for push.

The checkout step (line 30-32) uses ssh-key for authentication. Git push should automatically use the SSH key configured during checkout, making the GITHUB_TOKEN environment variable unnecessary here.

Additionally, consider being explicit about the branch to push:

♻️ Suggested simplification
       - name: Push Changes To Remote
         if: ${{ env.OLD_HASH != env.NEW_HASH }}
         run: |
-          git push origin
+          git push origin HEAD:main
           git push -u origin npm-v${{ env.NEW_VERSION }}
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
🤖 Prompt for AI Agents
In @.github/workflows/npm-package-release.yml around lines 225 - 232, Remove the
unnecessary GITHUB_TOKEN env from the "Push Changes To Remote" step and rely on
the SSH key configured during checkout; update the git push commands to be
explicit about what to push (e.g., git push origin <branch-name> and git push -u
origin npm-v${{ env.NEW_VERSION }} or push the tag/branch explicitly) so the
step "Push Changes To Remote" uses SSH auth and clearly specifies the target
branch/tag instead of depending on the token.


# Create gitHub release with tarballs
- name: Create GitHub Release with orderbook pkg
- name: Create GitHub Release
if: ${{ env.OLD_HASH != env.NEW_HASH }}
id: gh_release
uses: softprops/action-gh-release@v2
Expand Down