From d6aa016cbc4ebfca29b63828003ff7563ace9748 Mon Sep 17 00:00:00 2001 From: BitterPanda Date: Wed, 25 Mar 2026 09:54:03 -0700 Subject: [PATCH 1/8] disable build-and-release and move to circleci config.yml --- .circleci/config.yml | 491 ++++++++++++++++++++++++ .github/workflows/build-and-release.yml | 5 +- 2 files changed, 493 insertions(+), 3 deletions(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..331d042 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,491 @@ +version: 2.1 +# env: +# GITHUB_TOKEN — GitHub token with repo write access (used by gh CLI) +# NPM_PUBLISH_TOKEN — npm access token with publish rights + +orbs: + windows: circleci/windows@5.0 + +executors: + linux-node20: + docker: + - image: cimg/node:20.18 + resource_class: medium + + linux-arm64-node20: + docker: + - image: cimg/node:20.18 + resource_class: arm.medium + + linux-machine: + machine: + image: ubuntu-2404:current + resource_class: medium + + # Intel Mac — used for node20-macos-x64 target + macos-x64: + macos: + xcode: "16.0.0" + resource_class: macos.x86.medium.gen2 + + macos-arm64: + macos: + xcode: "16.0.0" + resource_class: macos.m2.medium.gen1 + +commands: + setup-node-20-macos: + steps: + - run: + name: Install Node.js 20 + command: | + echo 'export NVM_DIR="$HOME/.nvm"' >> "$BASH_ENV" + echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> "$BASH_ENV" + source "$BASH_ENV" + nvm install 20 + nvm alias default 20 + node --version + npm --version + + setup-node-20-windows: + steps: + - run: + name: Install Node.js 20 + command: | + nvm install 20.18.0 + nvm use 20.18.0 + node --version + npm --version + + install-safe-chain: + steps: + - run: + name: Setup safe-chain + command: curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci + + set-package-version: + steps: + - run: + name: Set version in safe-chain package + command: | + source version.env + if [ -n "${VERSION}" ]; then + npm --no-git-tag-version version "${VERSION}" --workspace=packages/safe-chain --ignore-scripts + fi + +# --------------------------------------------------------------------------- +# Jobs +# --------------------------------------------------------------------------- + +jobs: + set-version: + executor: linux-machine + steps: + - checkout + - run: + name: Extract version and check pre-release status + command: | + VERSION="${CIRCLE_TAG}" + echo "VERSION=${VERSION}" > version.env + IS_PRERELEASE=$(gh release view "${VERSION}" \ + --json isPrerelease --jq '.isPrerelease' \ + --repo AikidoSec/safe-chain) + echo "IS_PRERELEASE=${IS_PRERELEASE}" >> version.env + cat version.env + - persist_to_workspace: + root: . + paths: + - version.env + + build-macos-x64: + executor: macos-x64 + steps: + - checkout + - attach_workspace: + at: . + - setup-node-20-macos + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-macos-x64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-macos-x64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-macos-x64 + + build-macos-arm64: + executor: macos-arm64 + steps: + - checkout + - attach_workspace: + at: . + - setup-node-20-macos + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-macos-arm64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-macos-arm64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-macos-arm64 + + build-linux-x64: + executor: linux-node20 + steps: + - checkout + - attach_workspace: + at: . + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-linux-x64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-linux-x64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-linux-x64 + + build-linux-arm64: + executor: linux-arm64-node20 + steps: + - checkout + - attach_workspace: + at: . + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-linux-arm64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-linux-arm64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-linux-arm64 + + build-linuxstatic-x64: + executor: linux-node20 + steps: + - checkout + - attach_workspace: + at: . + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-linuxstatic-x64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-linuxstatic-x64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-linuxstatic-x64 + + build-linuxstatic-arm64: + executor: linux-arm64-node20 + steps: + - checkout + - attach_workspace: + at: . + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create binary + command: node build.js node20-linuxstatic-arm64 + - run: + name: Stage artifact + command: | + mkdir -p artifacts + cp dist/safe-chain artifacts/safe-chain-linuxstatic-arm64 + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-linuxstatic-arm64 + + build-win: + # CircleCI has no Windows ARM64 runner, so both Windows targets are built + # here on the x64 runner. pkg cross-compiles win-arm64 on win-x64 natively. + executor: + name: win/server-2022 + shell: bash.exe + resource_class: windows.medium + steps: + - checkout + - attach_workspace: + at: . + - setup-node-20-windows + - install-safe-chain + - run: + name: Install dependencies + command: npm ci --ignore-scripts + - set-package-version + - run: + name: Create win-x64 binary + command: node build.js node20-win-x64 + - run: + name: Stage win-x64 artifact + command: | + mkdir -p artifacts + cp dist/safe-chain.exe artifacts/safe-chain-win-x64.exe + - run: + name: Create win-arm64 binary + command: node build.js node20-win-arm64 + - run: + name: Stage win-arm64 artifact + command: cp dist/safe-chain.exe artifacts/safe-chain-win-arm64.exe + - persist_to_workspace: + root: . + paths: + - artifacts/safe-chain-win-x64.exe + - artifacts/safe-chain-win-arm64.exe + + publish-binaries: + # circleci_ip_ranges routes outbound traffic through static IPs. + # Requires a CircleCI Performance or Scale plan. + machine: + image: ubuntu-2404:current + resource_class: medium + circleci_ip_ranges: true + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Prepare release artifacts + command: | + source version.env + mkdir -p release-artifacts + cp artifacts/safe-chain-macos-x64 release-artifacts/safe-chain-macos-x64 + cp artifacts/safe-chain-macos-arm64 release-artifacts/safe-chain-macos-arm64 + cp artifacts/safe-chain-linux-x64 release-artifacts/safe-chain-linux-x64 + cp artifacts/safe-chain-linux-arm64 release-artifacts/safe-chain-linux-arm64 + cp artifacts/safe-chain-linuxstatic-x64 release-artifacts/safe-chain-linuxstatic-x64 + cp artifacts/safe-chain-linuxstatic-arm64 release-artifacts/safe-chain-linuxstatic-arm64 + cp artifacts/safe-chain-win-x64.exe release-artifacts/safe-chain-win-x64.exe + cp artifacts/safe-chain-win-arm64.exe release-artifacts/safe-chain-win-arm64.exe + sed "s/\$(fetch_latest_version)/${VERSION}/" \ + install-scripts/install-safe-chain.sh > release-artifacts/install-safe-chain.sh + sed "s/\$Version = Get-LatestVersion/\$Version = \"${VERSION}\"/" \ + install-scripts/install-safe-chain.ps1 > release-artifacts/install-safe-chain.ps1 + cp install-scripts/uninstall-safe-chain.sh release-artifacts/uninstall-safe-chain.sh + cp install-scripts/uninstall-safe-chain.ps1 release-artifacts/uninstall-safe-chain.ps1 + cp install-scripts/install-endpoint-mac.sh release-artifacts/install-endpoint-mac.sh + cp install-scripts/install-endpoint-windows.ps1 release-artifacts/install-endpoint-windows.ps1 + cp install-scripts/uninstall-endpoint-mac.sh release-artifacts/uninstall-endpoint-mac.sh + cp install-scripts/uninstall-endpoint-windows.ps1 release-artifacts/uninstall-endpoint-windows.ps1 + - run: + name: Upload binaries to GitHub Release + command: | + source version.env + gh release upload "${VERSION}" \ + release-artifacts/safe-chain-macos-x64 \ + release-artifacts/safe-chain-macos-arm64 \ + release-artifacts/safe-chain-linux-x64 \ + release-artifacts/safe-chain-linux-arm64 \ + release-artifacts/safe-chain-linuxstatic-x64 \ + release-artifacts/safe-chain-linuxstatic-arm64 \ + release-artifacts/safe-chain-win-x64.exe \ + release-artifacts/safe-chain-win-arm64.exe \ + release-artifacts/install-safe-chain.sh \ + release-artifacts/install-safe-chain.ps1 \ + release-artifacts/uninstall-safe-chain.sh \ + release-artifacts/uninstall-safe-chain.ps1 \ + release-artifacts/install-endpoint-mac.sh \ + release-artifacts/install-endpoint-windows.ps1 \ + release-artifacts/uninstall-endpoint-mac.sh \ + release-artifacts/uninstall-endpoint-windows.ps1 \ + --repo AikidoSec/safe-chain + + publish-npm: + executor: linux-node20 + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Skip if pre-release + command: | + source version.env + if [ "${IS_PRERELEASE}" = "true" ]; then + echo "Pre-release tag detected — skipping npm publish" + circleci-agent step halt + fi + - install-safe-chain + - run: + name: Set the version in safe-chain package + command: | + source version.env + npm --no-git-tag-version version "${VERSION}" --workspace=packages/safe-chain + - run: + name: Install dependencies + command: npm ci + - run: + name: Run tests + command: npm run test + - run: + name: Copy documentation files to package + command: | + cp README.md packages/safe-chain/ + cp LICENSE packages/safe-chain/ + cp -r docs packages/safe-chain/ + - run: + name: Configure npm authentication + command: echo "//registry.npmjs.org/:_authToken=${NPM_PUBLISH_TOKEN}" >> ~/.npmrc + - run: + name: Publish to npm + command: | + source version.env + echo "Publishing version ${VERSION} to NPM" + npm publish --workspace=packages/safe-chain --access public --provenance + +# --------------------------------------------------------------------------- +# Workflow — triggered on every tag push (mirrors GitHub's on.push.tags: ["*"]) +# --------------------------------------------------------------------------- +# IMPORTANT: In CircleCI, tag filters must be repeated on every job in the +# workflow, otherwise those jobs are skipped for tag-triggered pipelines. + +workflows: + release: + jobs: + - set-version: + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-macos-x64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-macos-arm64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-linux-x64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-linux-arm64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-linuxstatic-x64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-linuxstatic-arm64: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - build-win: + requires: + - set-version + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + # publish-binaries and publish-npm both fan in from all build jobs and + # run in parallel, matching the original GitHub Actions structure. + - publish-binaries: + requires: + - build-macos-x64 + - build-macos-arm64 + - build-linux-x64 + - build-linux-arm64 + - build-linuxstatic-x64 + - build-linuxstatic-arm64 + - build-win + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ + + - publish-npm: + requires: + - build-macos-x64 + - build-macos-arm64 + - build-linux-x64 + - build-linux-arm64 + - build-linuxstatic-x64 + - build-linuxstatic-arm64 + - build-win + filters: + branches: + ignore: /.*/ + tags: + only: /.*/ diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index d6c810a..6552e17 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -1,9 +1,8 @@ name: Create Release +# Workflow disabled — release pipeline moved to CircleCI (.circleci/config.yml) on: - push: - tags: - - "*" + workflow_dispatch: permissions: id-token: write From 7b764609af63b01b86e7228ba0187405c216b9ae Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:07:00 -0700 Subject: [PATCH 2/8] Apply suggestions from code review Co-authored-by: bitterpanda --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 331d042..f065d9e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -244,8 +244,7 @@ jobs: - artifacts/safe-chain-linuxstatic-arm64 build-win: - # CircleCI has no Windows ARM64 runner, so both Windows targets are built - # here on the x64 runner. pkg cross-compiles win-arm64 on win-x64 natively. + # CircleCI has no Windows ARM64 runner, so both Windows targets are built on x64 executor: name: win/server-2022 shell: bash.exe From 8a902d68d7d3c1f28fefaeda7b8fbc7cda6a9ed3 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:07:40 -0700 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: bitterpanda --- .circleci/config.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f065d9e..7f0bafc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -280,8 +280,6 @@ jobs: - artifacts/safe-chain-win-arm64.exe publish-binaries: - # circleci_ip_ranges routes outbound traffic through static IPs. - # Requires a CircleCI Performance or Scale plan. machine: image: ubuntu-2404:current resource_class: medium From 757ddc4f15917747b4a79dc3535ea99bfed69a9f Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:14:28 -0700 Subject: [PATCH 4/8] fix 'win' orb -> windows --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7f0bafc..388dc67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -246,7 +246,7 @@ jobs: build-win: # CircleCI has no Windows ARM64 runner, so both Windows targets are built on x64 executor: - name: win/server-2022 + name: windows/server-2022 shell: bash.exe resource_class: windows.medium steps: From ea242458dd806d484bb15dee196a6fc451f3b57d Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:16:34 -0700 Subject: [PATCH 5/8] Fix Duplicated resource_class in job build-win and under machine in the same job (may be coming from an executor) --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 388dc67..5645539 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -248,7 +248,7 @@ jobs: executor: name: windows/server-2022 shell: bash.exe - resource_class: windows.medium + resource_class: windows.medium steps: - checkout - attach_workspace: From 0231cd92828e01f88b01f6b342519bb0e1519ebd Mon Sep 17 00:00:00 2001 From: BitterPanda Date: Wed, 25 Mar 2026 10:18:36 -0700 Subject: [PATCH 6/8] Revert "Fix Duplicated resource_class in job build-win and under machine in the same job (may be coming from an executor)" This reverts commit ea242458dd806d484bb15dee196a6fc451f3b57d. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5645539..388dc67 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -248,7 +248,7 @@ jobs: executor: name: windows/server-2022 shell: bash.exe - resource_class: windows.medium + resource_class: windows.medium steps: - checkout - attach_workspace: From 3b73add44f88f51b369dd6f52d5ec7192f143c08 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:19:40 -0700 Subject: [PATCH 7/8] remove windows reaource class --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 388dc67..b566989 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -248,7 +248,6 @@ jobs: executor: name: windows/server-2022 shell: bash.exe - resource_class: windows.medium steps: - checkout - attach_workspace: From 933a334d5b48398678acf1c6d85c0699301e89f9 Mon Sep 17 00:00:00 2001 From: bitterpanda Date: Wed, 25 Mar 2026 10:21:06 -0700 Subject: [PATCH 8/8] Install gh cli tool on circleci --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index b566989..dd15949 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -82,6 +82,12 @@ jobs: executor: linux-machine steps: - checkout + - run: + name: Install GitHub CLI + command: | + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list + sudo apt-get update && sudo apt-get install -y gh - run: name: Extract version and check pre-release status command: |