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
18 changes: 16 additions & 2 deletions .github/workflows/publish_rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
run: |
set -euo pipefail

just set-version "$RELEASE_TAG"
just set-cargo-version "$RELEASE_TAG"
version="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -n 1)"
packages=(
nemo-fabric-core
Expand All @@ -76,5 +76,19 @@ jobs:
continue
fi

cargo publish --package "$package" --no-verify --allow-dirty
cargo publish --package "$package" --no-verify --locked --allow-dirty

if [[ "$package" == "nemo-fabric-core" ]]; then
for attempt in {1..12}; do
if cargo info "${package}@${version}" --registry crates-io >/dev/null 2>&1; then
break
fi
if [[ "$attempt" == 12 ]]; then
echo "${package} ${version} did not become visible on crates.io" >&2
exit 1
fi
echo "Waiting for ${package} ${version} to become visible on crates.io"
sleep 10
done
fi
done
3 changes: 0 additions & 3 deletions .github/workflows/publish_typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ jobs:
esac

python3 scripts/ci/set_typescript_project_version.py "$version"
git diff --exit-code -- \
adapter-contract/typescript/package.json \
adapter-contract/typescript/package-lock.json
{
echo "version=$version"
echo "dist_tag=$dist_tag"
Expand Down
27 changes: 19 additions & 8 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,19 +131,26 @@ Before you create a release tag, confirm the following:

1. The intended release commit is already on the release branch you intend to
tag. For frozen release lines, tag the matching `release/*` branch.
2. The release commit contains the final version bump, docs updates, and any
public API changes that belong in the release.
2. The release commit contains the final stable base version, docs updates, and
any public API changes that belong in the release. Prerelease versions are
derived from beta or RC tags in disposable workflow checkouts.
3. The working tree you use for local validation is clean or disposable.

## Prepare The Release Commit

Update the versioned source files in the release PR or release-prep commit.
Prefer the repository helper:
Update the versioned source files in the release PR or release-prep commit to
the stable base version for the release line. Prefer the repository helper:

```bash
just set-version <release-version>
just set-version <stable-base-version>
# For example: just set-version 0.1.0
```

For beta and RC tags, keep the committed source metadata at the corresponding
stable base version. The tag workflows normalize the prerelease tag and stamp
ecosystem-specific package metadata in their disposable checkouts. Do not
Comment thread
AnuradhaKaruppiah marked this conversation as resolved.
commit RC-specific versions or internal dependency pins to the release branch.

The helper updates:

1. The root [`Cargo.toml`](Cargo.toml) workspace version.
Expand Down Expand Up @@ -258,7 +265,8 @@ older release line.
## Cut An RC Tag

After the release commit is merged and validated, create and push a signed,
annotated tag. Set the complete release-candidate version:
annotated tag. Set the complete release-candidate version; the release branch
continues to carry its matching stable base version:

```bash
export RELEASE_VERSION=0.1.0-rc.1
Expand All @@ -275,6 +283,9 @@ RELEASE_SHA="$(git rev-parse HEAD)"
REMOTE_RELEASE_SHA="$(git rev-parse "upstream/${RELEASE_BRANCH}^{commit}")"
test "${RELEASE_SHA}" = "${REMOTE_RELEASE_SHA}"
test "$(just normalize-release-tag "${RELEASE_TAG}")" = "${RELEASE_VERSION}"
BASE_RELEASE_VERSION="${RELEASE_VERSION%%-*}"
CURRENT_VERSION="$(sed -n 's/^version = "\(.*\)"$/\1/p' Cargo.toml | head -n 1)"
test "${CURRENT_VERSION}" = "${BASE_RELEASE_VERSION}"

if git ls-remote --exit-code --tags upstream "refs/tags/${RELEASE_TAG}" >/dev/null; then
echo "Error: remote tag ${RELEASE_TAG} already exists" >&2
Expand Down Expand Up @@ -393,8 +404,8 @@ Pushing a valid tag triggers :

The release pipeline then:

1. Validates the tag format with `just set-version` or
`normalize_release_tag.py`.
1. Normalizes and validates the tag format, then stamps ecosystem-specific
package metadata in each disposable workflow checkout.
2. Builds platform `nemo-fabric-runtime` wheels and pure-Python
`nemo-fabric` and adapter wheels with the exact tag version, then uploads
them as GitHub Actions artifacts.
Expand Down
23 changes: 20 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -384,15 +384,32 @@ lock-python:

# Normalize a release tag to the version used by package metadata.
normalize-release-tag tag:
@uv run --no-project --no-cache python scripts/ci/normalize_release_tag.py "{{ tag }}"
@uv run --no-project --no-cache python scripts/ci/normalize_release_tag.py {{ quote(tag) }}

# Apply a release version only to Cargo workspace metadata and Cargo.lock.
# Tag publication uses this narrow recipe in a disposable checkout.
set-cargo-version version="":
#!/usr/bin/env bash
{{ bash_helpers }}
version={{ quote(version) }}
if [[ -z "$version" ]]; then
version={{ quote(ref_name) }}
fi
if [[ -z "$version" ]]; then
echo "Error: version is required for set-cargo-version" >&2
exit 1
fi
version="$(just normalize-release-tag "$version")"
cd "$REPO_ROOT"
set_cargo_workspace_version "$version"

# [version-or-tag] or --set ref_name=<version-or-tag>
set-version version="":
#!/usr/bin/env bash
{{ bash_helpers }}
version="{{ version }}"
version={{ quote(version) }}
if [[ -z "$version" ]]; then
version="{{ ref_name }}"
version={{ quote(ref_name) }}
fi
if [[ -z "$version" ]]; then
echo "Error: version is required for set-version" >&2
Expand Down
51 changes: 51 additions & 0 deletions tests/scripts/test_justfile_release_tag_quoting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

from __future__ import annotations

import os
import subprocess
from pathlib import Path

import pytest


REPO_ROOT = Path(__file__).resolve().parents[2]


@pytest.mark.parametrize(
"arguments",
[
("normalize-release-tag",),
("set-cargo-version",),
("set-version",),
("--set", "ref_name={payload}", "set-cargo-version"),
("--set", "ref_name={payload}", "set-version"),
],
Comment thread
AnuradhaKaruppiah marked this conversation as resolved.
)
def test_release_tag_interpolation_does_not_execute_command_substitution(
tmp_path: Path,
arguments: tuple[str, ...],
):
marker = tmp_path / "interpolation-executed"
payload = f"$(touch {marker})"
command = [
"just",
*(argument.format(payload=payload) for argument in arguments),
]
if not any("{payload}" in argument for argument in arguments):
command.append(payload)

environment = os.environ.copy()
environment["UV_CACHE_DIR"] = str(tmp_path / "uv-cache")
result = subprocess.run(
command,
cwd=REPO_ROOT,
env=environment,
capture_output=True,
text=True,
check=False,
)

assert result.returncode != 0
assert not marker.exists()
Comment thread
AnuradhaKaruppiah marked this conversation as resolved.
Loading