Skip to content

Commit d3450ad

Browse files
Merge pull request #11 from NVIDIA-NeMo/docs/releasing-github
docs: rewrite RELEASING.md for GitHub + current package set
2 parents 082b18b + e678155 commit d3450ad

1 file changed

Lines changed: 55 additions & 81 deletions

File tree

RELEASING.md

Lines changed: 55 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,85 @@
1-
# Releasing nemo-oo-agents
1+
# Releasing
22

3-
Three workspace packages — `nemo-oo-agents`, `nooa-cli`, and
4-
`nemo-oo-agents-benchmarks` — release together from the same git commit.
5-
Version is derived from `git describe` at build time by
6-
[`uv-dynamic-versioning`](https://github.com/ninoseki/uv-dynamic-versioning).
3+
Four workspace packages release together from the same git commit:
4+
5+
- **`nooa`** — the core framework
6+
- **`nooa-cli`** — the `nooa` command and REPL
7+
- **`nooa-memory`** — the long-term memory subsystem
8+
- **`nooa-bench`** — the benchmark agent and Harbor runner
79

8-
There is no `version = "..."` in any pyproject.toml and no manual bump step
9-
between releases. **Tagging the commit is the entire release ceremony.**
10+
The version is derived from the git **tag** at build time by
11+
[`uv-dynamic-versioning`](https://github.com/ninoseki/uv-dynamic-versioning).
12+
There is no `version = "..."` in any `pyproject.toml` and no manual bump step.
13+
**Tagging the commit is the release ceremony.**
1014

11-
## Continuous publishes (every main commit)
15+
## Versioning
1216

13-
Every push to `main` triggers `build-package-*` and `publish-package-*` jobs.
14-
The published version is derived from the last `vX.Y.Z` tag reachable from
15-
the commit, plus the distance to that tag:
17+
The version comes from the last `vX.Y.Z` tag reachable from the commit, plus
18+
the distance to that tag:
1619

17-
| Repo state | Wheel version |
20+
| Repo state | Version |
1821
|---|---|
19-
| Exactly on tag `v0.3.0` | `0.3.0` |
20-
| 5 commits past `v0.3.0` | `0.3.1.dev5` |
21-
| No `vX.Y.Z` tag reachable yet | `0.0.1.dev<commit-count>` (until first tag — see "Bootstrapping") |
22+
| Exactly on tag `v0.0.6` | `0.0.6` |
23+
| 5 commits past `v0.0.6` | `0.0.7.dev5` |
24+
| No `vX.Y.Z` tag reachable yet | `0.0.1.dev<distance>` |
2225

23-
> Note: the `fallback-version = "0.0.6"` in pyproject.toml is the version
24-
> used only when git itself is unavailable (e.g. building from an unpacked
25-
> sdist with no `.git` dir). In CI git is always present, so the version
26-
> is always derived from `git describe` — the fallback never fires.
26+
> `fallback-version = "0.0.6"` in `pyproject.toml` is used **only** when git
27+
> is unavailable (e.g. building from an unpacked sdist with no `.git/`).
28+
> Whenever git is present, the version is derived from `git describe`.
2729
28-
Dev versions sort *above* the latest stable release and *below* the next
29-
stable, so `--pre` consumers always get the freshest dev:
30+
This is a `0.x` **research preview** — the public API is not yet stable and may
31+
change between releases (per [SemVer](https://semver.org/), `0.y.z` signals
32+
initial development).
3033

31-
```bash
32-
# Latest dev wheel from main
33-
uv add nemo-oo-agents --pre
34+
## Cutting a release
3435

35-
# Pin to a specific dev wheel
36-
uv add nemo-oo-agents==0.3.1.dev5
36+
```bash
37+
git checkout main && git pull
38+
git tag -a v0.0.6 -m "NOOA 0.0.6 — research preview"
39+
git push origin v0.0.6
3740
```
3841

39-
`uv add nemo-oo-agents` (no `--pre`) keeps picking the last stable release.
40-
41-
## Bootstrapping (one-time, after this MR merges)
42-
43-
Until a `vX.Y.Z` tag exists in the repo, dev publishes ship as
44-
`0.0.1.dev<commit-count>` — derived from "0 tags reachable" + the `bump = true`
45-
config. To switch dev publishes to a meaningful base, cut the first tag:
42+
Build the four packages from the tagged commit:
4643

4744
```bash
48-
git checkout main
49-
git pull
50-
git tag -a v0.2.0 -m "Initial release with dynamic versioning"
51-
git push origin v0.2.0
45+
rm -rf dist
46+
for p in nooa nooa-cli nooa-memory nooa-bench; do
47+
uv build --package "$p" --out-dir dist
48+
done
5249
```
5350

54-
Subsequent main pushes will then publish as `0.2.1.dev<distance>`. After
55-
that, the rest of this doc is the entire release process.
56-
57-
## Cutting a stable release
51+
**Smoke-test the wheels in a clean environment** before publishing:
5852

5953
```bash
60-
git checkout main
61-
git pull
62-
git tag -a v0.3.0 -m "Release 0.3.0"
63-
git push origin v0.3.0
54+
python3.12 -m venv /tmp/nooa-smoke && . /tmp/nooa-smoke/bin/activate
55+
pip install dist/nooa-*.whl dist/nooa_cli-*.whl dist/nooa_memory-*.whl dist/nooa_bench-*.whl
56+
python -c "import nooa, nooa_cli, nooa_memory, nooa_bench; print(nooa.__version__)"
57+
nooa --version
58+
deactivate
6459
```
6560

66-
That's it. The tag pipeline builds and publishes `0.3.0` of all three
67-
packages to the GitLab Package Registry. No pyproject changes, no follow-up
68-
MRs, no version bumps anywhere.
69-
7061
### Pre-release tags
7162

72-
CI accepts annotated tags matching `^v\d+\.\d+\.\d+([.-][a-zA-Z0-9]+)?$`,
73-
which covers pre-release suffixes:
74-
75-
```bash
76-
git tag -a v0.3.0-rc1 -m "Release candidate"
77-
git push origin v0.3.0-rc1
78-
```
63+
Annotated tags like `v0.0.6-rc1` build as `0.0.6rc1` (PEP 440 normalized).
7964

80-
The wheel ships as `0.3.0-rc1` (PEP 440 normalizes to `0.3.0rc1`).
65+
## Distribution
8166

82-
## Cross-package dependencies
67+
The packages are currently distributed as **source** — install directly from
68+
GitHub at a tag:
8369

84-
`nooa-cli` and `nemo-oo-agents-benchmarks` declare their
85-
dependency on core as a static lower-bound floor in their pyproject.toml:
86-
87-
```toml
88-
"nemo-oo-agents>=0.2.0",
70+
```bash
71+
uv add "nooa @ git+https://github.com/NVIDIA-NeMo/labs-OO-Agents.git@v0.0.6"
8972
```
9073

91-
The floor reflects the actual minimum-compatible core version. **Bump it in
92-
a normal MR when the package starts to require a newer core API** — same as
93-
you would for any third-party dep. CI does not rewrite this declaration.
74+
Optionally attach the built wheels to a **GitHub Release** for the tag.
9475

95-
## Republishing a main commit
76+
> **PyPI publishing is not yet enabled.** When it is, a GitHub Actions workflow
77+
> (PyPI Trusted Publishing) will build and upload all four packages on each
78+
> `vX.Y.Z` tag. The names `nooa`, `nooa-cli`, `nooa-memory`, and `nooa-bench`
79+
> are available on PyPI and can be reserved ahead of the first publish.
9680
97-
`uv publish` is not idempotent against the GitLab Package Registry — a
98-
second attempt with the same version returns HTTP 400. CI does not retry
99-
publish jobs.
100-
101-
If a transient failure leaves a dev publish broken, **push an empty commit**
102-
to advance the dev version:
103-
104-
```bash
105-
git commit --allow-empty -m "ci: re-trigger publish"
106-
git push
107-
```
81+
## Cross-package dependencies
10882

109-
Do NOT use the GitLab "Retry pipeline" button on the build stage — it
110-
rebuilds at the same git HEAD and therefore the same derived version, which
111-
then 400s on publish.
83+
`nooa-cli`, `nooa-memory`, and `nooa-bench` depend on the core `nooa` package.
84+
They are always released together at the same derived version, so their
85+
dependency on `nooa` carries **no version floor** — CI never rewrites it.

0 commit comments

Comments
 (0)