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
10 changes: 10 additions & 0 deletions .github/ci-path-filters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ rust_package:
- 'crates/ffi/nemo_relay.h'
- 'crates/ffi/src/**'
- 'justfile'
- 'packages/cli-bin/**'
- 'python/cli-bin/**'
- 'rust-toolchain.toml'
- 'scripts/package-cli-bin.py'

node_package:
- 'Cargo.lock'
Expand All @@ -79,8 +82,11 @@ node_package:
- 'justfile'
- 'package.json'
- 'package-lock.json'
- 'packages/cli-bin/**'
- 'pyproject.toml'
- 'rust-toolchain.toml'
- 'scripts/package-cli-bin.py'
- 'scripts/package-node-bin.py'
- 'uv.lock'

python_package:
Expand All @@ -96,8 +102,10 @@ python_package:
- 'crates/python/src/**'
- 'justfile'
- 'pyproject.toml'
- 'python/cli-bin/**'
- 'python/nemo_relay/**'
- 'rust-toolchain.toml'
- 'scripts/package-cli-bin.py'
- 'uv.lock'

python_integration_langchain:
Expand All @@ -124,7 +132,9 @@ dependencies:
- 'integrations/**/package.json'
- 'package.json'
- 'package-lock.json'
- 'packages/cli-bin/**'
- 'pyproject.toml'
- 'python/cli-bin/**'
- 'scripts/licensing/**'
- 'uv.lock'

Expand Down
127 changes: 108 additions & 19 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ jobs:
exit 1
fi

release-cli-artifacts:
name: Release CLI Artifacts
release-distribution-artifacts:
name: Release Distribution Artifacts
needs: [prepare, ci_required]
if: ${{ needs.prepare.outputs.publish_packages == 'true' && needs.ci_required.result == 'success' }}
runs-on: ubuntu-latest
Expand All @@ -269,36 +269,85 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Download CLI binary artifacts
- name: Download CLI distribution artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: cli-*
merge-multiple: true
path: release-assets/

- name: Generate CLI release checksums
- name: Download Node distribution artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: node-npm-package-*
merge-multiple: true
path: release-assets/

- name: Download Python API wheel artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: wheel-*
merge-multiple: true
path: release-assets/

- name: Generate distribution checksums
run: |
set -euo pipefail

(
cd release-assets
cli_assets=(nemo-relay-cli-*)
sha256sum "${cli_assets[@]}" > SHA256SUMS
expect_count() {
local expected="$1"
local label="$2"
shift 2
local actual="$#"
if [ "$actual" -ne "$expected" ]; then
echo "Error: expected ${expected} ${label} artifacts, found ${actual}" >&2
exit 1
fi
}

cli_binaries=(nemo-relay-cli-*)
cli_wheels=(nemo_relay_cli_bin-*.whl)
python_api_wheels=(nemo_relay-*.whl)
cli_npm=(nemo-relay-bin-npm-*.tgz)
node_npm=(nemo-relay-node-npm-*.tgz)
expect_count 5 "CLI binary" "${cli_binaries[@]}"
expect_count 5 "CLI wheel" "${cli_wheels[@]}"
expect_count 5 "Python API wheel" "${python_api_wheels[@]}"
expect_count 6 "CLI npm" "${cli_npm[@]}"
expect_count 6 "Node npm" "${node_npm[@]}"

mapfile -t distribution_assets < <(
find . -maxdepth 1 -type f \
! -name 'SHA256SUMS' \
! -name '*.sha256' \
-printf '%f\n' |
sort
)
if [ "${#distribution_assets[@]}" -eq 0 ]; then
echo "Error: no distribution artifacts were collected" >&2
exit 1
fi
sha256sum "${distribution_assets[@]}" > SHA256SUMS
sha256sum --check SHA256SUMS

while read -r digest filename; do
printf '%s %s\n' "$digest" "$filename" > "${filename}.sha256"
done < SHA256SUMS
for filename in nemo-relay-cli-*; do
if [[ "$filename" == *.tgz || "$filename" == *.whl || "$filename" == *.sha256 ]]; then
continue
fi
sha256sum "$filename" > "${filename}.sha256"
done

printf 'CLI release assets:\n'
printf 'Distribution release assets:\n'
printf ' release-assets/%s\n' *
)

- name: Upload CLI assets and checksums to draft GitHub Release
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
draft: true
prerelease: ${{ contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') }}
prerelease: ${{ contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') }}
overwrite_files: true
fail_on_unmatched_files: true
files: release-assets/*
Expand Down Expand Up @@ -400,6 +449,13 @@ jobs:
name: plugin-wheel
path: dist/

- name: Download CLI wheel artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: cli-python-wheel-*
merge-multiple: true
path: dist/

- name: Publish to PyPI with trusted publishing
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
with:
Expand Down Expand Up @@ -428,18 +484,26 @@ jobs:
node-version: ${{ steps.ci-config.outputs.node_version }}
registry-url: "https://registry.npmjs.org"

- name: Download consolidated Node package artifact
- name: Download split Node package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: npm-consolidated
path: .
pattern: node-npm-package-*
merge-multiple: true
path: node-packages/

- name: Download OpenClaw plugin artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: openclaw-npm
path: openclaw-package/

- name: Download CLI npm artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: cli-npm-package-*
merge-multiple: true
path: cli-packages/

- name: Select npm dist-tag
run: |
set -e
Expand All @@ -453,14 +517,39 @@ jobs:
run: |
set -euo pipefail
version="${{ github.ref_name }}"
for pkg in node-packages/nemo-relay-node-npm-{linux-x64,linux-arm64,darwin-arm64,win32-x64,win32-arm64}-${version}.tgz; do
name="$(tar xOf "$pkg" package/package.json | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).name')"
if npm view "${name}@${version}" version --registry https://registry.npmjs.org >/dev/null 2>&1; then
Comment thread
willkill07 marked this conversation as resolved.
echo "${name} ${version} already exists on npm; skipping"
continue
fi
npm publish "$pkg" --access public --tag "${NEMO_RELAY_NPM_DIST_TAG}"
done
metapackage="node-packages/nemo-relay-node-npm-${version}.tgz"
if npm view "nemo-relay-node@${version}" version --registry https://registry.npmjs.org >/dev/null 2>&1; then
echo "nemo-relay-node ${version} already exists on npm; skipping"
exit 0
else
npm publish "$metapackage" --access public --tag "${NEMO_RELAY_NPM_DIST_TAG}"
fi

- name: Publish CLI packages to npm
run: |
set -euo pipefail
version="${{ github.ref_name }}"
for pkg in cli-packages/nemo-relay-bin-npm-{linux-x64,linux-arm64,darwin-arm64,win32-x64,win32-arm64}-${version}.tgz; do
name="$(tar xOf "$pkg" package/package.json | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).name')"
if npm view "${name}@${version}" version --registry https://registry.npmjs.org >/dev/null 2>&1; then
echo "${name} ${version} already exists on npm; skipping"
continue
fi
npm publish "$pkg" --access public --tag "${NEMO_RELAY_NPM_DIST_TAG}"
done
launcher="cli-packages/nemo-relay-bin-npm-${version}.tgz"
if npm view "nemo-relay-cli-bin@${version}" version --registry https://registry.npmjs.org >/dev/null 2>&1; then
echo "nemo-relay-cli-bin ${version} already exists on npm; skipping"
else
npm publish "$launcher" --access public --tag "${NEMO_RELAY_NPM_DIST_TAG}"
fi
unzip -q ./consolidated.zip -d combined
echo "Platform binaries included:"
ls -la combined/package/*.node
npm publish ./combined/package --access public --tag "${NEMO_RELAY_NPM_DIST_TAG}"

- name: Publish OpenClaw plugin package to npm
run: |
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/ci_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,10 @@ jobs:
fi
pre-commit run --from-ref "$base_ref" --to-ref HEAD --show-diff-on-failure
fi

- name: Test binary package assembly
working-directory: ${{ env.NEMO_RELAY_CI_WORKSPACE }}
run: >-
uv run --no-project python -m unittest
scripts.tests.test_package_cli_bin
scripts.tests.test_package_node_bin
Loading
Loading