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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ jobs:
name: plugin-wheel
path: dist/

- name: Download Python source distribution artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: python-sdist
path: dist/

- name: Verify Python API wheel artifacts
run: |
set -euo pipefail
Expand All @@ -410,6 +416,16 @@ jobs:
exit 1
fi

- name: Verify Python source distribution artifact
run: |
set -euo pipefail
shopt -s nullglob
sdists=(dist/nemo_relay-*.tar.gz)
if [ "${#sdists[@]}" -ne 1 ]; then
echo "Error: expected one Python API source distribution artifact, found ${#sdists[@]}" >&2
exit 1
fi

- name: Publish to PyPI with trusted publishing
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
with:
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/ci_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,24 @@ jobs:
path: ${{ env.NEMO_RELAY_CI_WORKSPACE_TMP }}/wheels/*.whl
if-no-files-found: error

- name: Package Python source distribution
if: ${{ matrix.platform == 'linux-amd64' }}
working-directory: ${{ env.NEMO_RELAY_CI_WORKSPACE }}
run: |
set -e
just \
--set output_dir "${{ env.NEMO_RELAY_CI_WORKSPACE_TMP }}" \
--set ref_name "${NEMO_RELAY_PACKAGE_VERSION}" \
package-python-sdist

- name: Upload Python source distribution artifact
if: ${{ matrix.platform == 'linux-amd64' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: python-sdist
path: ${{ env.NEMO_RELAY_CI_WORKSPACE_TMP }}/sdists/nemo_relay-*.tar.gz
if-no-files-found: error

- name: Package Python plugin SDK wheel
if: ${{ matrix.platform == 'linux-amd64' }}
working-directory: ${{ env.NEMO_RELAY_CI_WORKSPACE }}
Expand Down
17 changes: 12 additions & 5 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ collect:github-artifacts:
fi
export GH_TOKEN="${NEMO_RELAY_CI_GITHUB_TOKEN}"

mkdir -p collected/wheels collected/node downloaded
mkdir -p collected/wheels collected/sdists collected/node downloaded

tag="${CI_COMMIT_TAG:-}"
if [ -z "$tag" ]; then
Expand Down Expand Up @@ -133,9 +133,11 @@ collect:github-artifacts:

gh run download "$run_id" --repo "$NEMO_RELAY_CI_GITHUB_REPOSITORY" --pattern 'wheel-*' --dir downloaded/wheels
gh run download "$run_id" --repo "$NEMO_RELAY_CI_GITHUB_REPOSITORY" --name 'plugin-wheel' --dir downloaded/wheels
gh run download "$run_id" --repo "$NEMO_RELAY_CI_GITHUB_REPOSITORY" --name 'python-sdist' --dir downloaded/sdists
gh run download "$run_id" --repo "$NEMO_RELAY_CI_GITHUB_REPOSITORY" --name npm-consolidated --dir downloaded/node

find downloaded/wheels -type f -name '*.whl' -exec cp {} collected/wheels/ \;
find downloaded/sdists -type f -name 'nemo_relay-*.tar.gz' -exec cp {} collected/sdists/ \;
node_zip="$(find downloaded/node -type f -name consolidated.zip -print -quit)"
if [ -z "$node_zip" ]; then
echo "Error: collected GitHub npm-consolidated artifact did not contain consolidated.zip." >&2
Expand All @@ -147,6 +149,10 @@ collect:github-artifacts:
echo "Error: collected GitHub wheel artifacts did not contain any .whl files." >&2
exit 1
fi
if ! ls collected/sdists/nemo_relay-*.tar.gz >/dev/null 2>&1; then
echo "Error: collected GitHub Python source distribution artifact did not contain a nemo-relay sdist." >&2
exit 1
fi
if [ ! -f collected/node/consolidated.zip ]; then
echo "Error: collected GitHub npm-consolidated artifact did not contain consolidated.zip." >&2
exit 1
Expand All @@ -166,6 +172,7 @@ collect:github-artifacts:
expire_in: 7 days
paths:
- collected/wheels/*.whl
- collected/sdists/nemo_relay-*.tar.gz
- collected/node/consolidated.zip
- collected/github-run.json

Expand All @@ -185,18 +192,18 @@ publish:artifactory:wheels:
set -eu

if [ -z "${NEMO_RELAY_CI_ARTIFACTORY_USER:-}" ] || [ -z "${NEMO_RELAY_CI_ARTIFACTORY_KEY:-}" ] || [ -z "${NEMO_RELAY_CI_ARTIFACTORY_PYPI_URL:-}" ]; then
echo "Error: uploading wheels to Artifactory requires NEMO_RELAY_CI_ARTIFACTORY_USER, NEMO_RELAY_CI_ARTIFACTORY_KEY, and NEMO_RELAY_CI_ARTIFACTORY_PYPI_URL." >&2
echo "Error: uploading Python package artifacts to Artifactory requires NEMO_RELAY_CI_ARTIFACTORY_USER, NEMO_RELAY_CI_ARTIFACTORY_KEY, and NEMO_RELAY_CI_ARTIFACTORY_PYPI_URL." >&2
exit 1
fi
if ! ls collected/wheels/*.whl >/dev/null 2>&1; then
echo "Error: no collected wheel artifacts found." >&2
if ! ls collected/wheels/*.whl >/dev/null 2>&1 || ! ls collected/sdists/nemo_relay-*.tar.gz >/dev/null 2>&1; then
echo "Error: no complete set of collected Python package artifacts found." >&2
exit 1
fi

UV_PUBLISH_USERNAME="${NEMO_RELAY_CI_ARTIFACTORY_USER}" \
UV_PUBLISH_PASSWORD="${NEMO_RELAY_CI_ARTIFACTORY_KEY}" \
UV_PUBLISH_URL="${NEMO_RELAY_CI_ARTIFACTORY_PYPI_URL}" \
uv publish --no-progress collected/wheels/*.whl
uv publish --no-progress collected/wheels/*.whl collected/sdists/nemo_relay-*.tar.gz

publish:artifactory:cargo:
stage: publish
Expand Down
15 changes: 9 additions & 6 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The release pipeline publishes these package surfaces from a tag push:
| Ecosystem | Published Surface |
|---|---|
| crates.io | `nemo-relay-types`, `nemo-relay-plugin`, `nemo-relay-worker-proto`, `nemo-relay-worker`, `nemo-relay`, `nemo-relay-adaptive`, `nemo-relay-pii-redaction`, `nemo-relay-switchyard`, `nemo-relay-ffi`, `nemo-relay-cli` |
| PyPI | `nemo-relay`, `nemo-relay-plugin` |
| PyPI | `nemo-relay` wheels and source distribution, `nemo-relay-plugin` wheel |
Comment thread
willkill07 marked this conversation as resolved.
| npm | `nemo-relay-node`, `nemo-relay-openclaw` |
| GitHub Releases | CLI binaries and `SHA256SUMS` |
| Fern | The documentation site |
Expand Down Expand Up @@ -199,6 +199,7 @@ just --set output_dir "$PWD/target/release-artifacts" --set ref_name 0.1.0 packa
just --set output_dir "$PWD/target/release-artifacts" --set ref_name 0.1.0 package-openclaw
just --set output_dir "$PWD/target/release-artifacts" --set ref_name 0.1.0 package-rust
just --set output_dir "$PWD/target/release-artifacts" --set ref_name 0.1.0 package-python
just --set output_dir "$PWD/target/release-artifacts" --set ref_name 0.1.0 package-python-sdist
```

Be aware that the local packaging recipes intentionally rewrite version fields
Expand Down Expand Up @@ -244,6 +245,8 @@ The release pipeline then:
- `package-openclaw` packs the npm OpenClaw plugin package.
- `package-python` builds platform `nemo-relay` wheels, including
`musllinux_1_2_x86_64` and `musllinux_1_2_aarch64` wheels.
- `package-python-sdist` builds one platform-independent `nemo-relay` source
distribution.
- `package-python-plugin` builds the `nemo-relay-plugin` wheel.
- The CLI release-asset job uploads each platform `nemo-relay` binary,
validates the Linux binaries on musllinux, and includes those binaries in
Expand All @@ -257,9 +260,9 @@ The release pipeline then:
`nemo-relay-switchyard`, `nemo-relay-ffi`, and `nemo-relay-cli` through
trusted publishing from
the top-level workflow
- `publish-python` downloads both the `nemo-relay` and `nemo-relay-plugin`
wheel artifacts and uploads them to PyPI with trusted publishing from the
top-level workflow
- `publish-python` downloads the `nemo-relay` wheel and source distribution
artifacts plus the `nemo-relay-plugin` wheel, then uploads them to PyPI
with trusted publishing from the top-level workflow
- `publish-npm` publishes the Node.js and OpenClaw plugin npm packages
through npm trusted publishing from the top-level workflow
- Stable tags publish to the npm `latest` dist-tag
Expand All @@ -286,8 +289,8 @@ NVIDIA Artifactory publication for the same tag:
- GitLab starts the pipeline from a tag push through `CI_COMMIT_TAG`; no GitLab
cron or pipeline schedule is required.
- The collector waits for the mirrored GitHub tag and matching GitHub Actions
run, then downloads the wheel, Cargo, and Node.js package
artifacts produced by GitHub Actions.
run, then downloads the Python wheel and source distribution, Cargo, and
Node.js package artifacts produced by GitHub Actions.
- The Artifactory jobs publish those collected artifacts to the configured
Python, Cargo, and npm Artifactory registries.

Expand Down
28 changes: 28 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -1638,6 +1638,34 @@ package-python:
exit 1
fi

# --set [output_dir=<path>] [ref_name=<name>]
package-python-sdist:
#!/usr/bin/env bash
{{ bash_helpers }}
output_dir="{{ output_dir }}"
export_uv_python_runtime
cd "$NEMO_RELAY_REPO_ROOT"
package_dir="$(prepare_package_dir sdists)"
sync_args=(--no-install-project --no-install-package nemo-relay)
uv sync --inexact "${sync_args[@]}"
activate_project_venv
if [[ -z "{{ ref_name }}" ]]; then
sha="$(head_git_sha)"
version="$(read_workspace_version)"
echo "Non-release build: appending commit hash to version"
set_python_package_version "${version}+${sha}" true
else
echo "Using explicit version {{ ref_name }}"
set_python_package_version "{{ ref_name }}" true
fi
maturin sdist --out "$package_dir"
shopt -s nullglob
sdists=("$package_dir"/nemo_relay-*.tar.gz)
if ((${#sdists[@]} == 0)); then
echo "Error: No nemo-relay source distributions found in $package_dir"
exit 1
fi
Comment thread
willkill07 marked this conversation as resolved.

# --set [output_dir=<path>] [ref_name=<name>]
package-python-plugin:
#!/usr/bin/env bash
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ manifest-path = "crates/python/Cargo.toml"
python-source = "python"
module-name = "nemo_relay._native"
features = ["pyo3/extension-module"]
include = [{ path = "LICENSE", format = ["sdist", "wheel"] }]

[tool.maturin.sbom]
rust = true
Expand Down
Loading