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
11 changes: 7 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ from data_designer_my_plugin.config import MyPluginColumnConfig

Never release or publish a plugin version as a tag or to PyPI without being asked or having express permission from the user.

Use `make bump` to increment the version, then `make release` to tag. Do not edit `pyproject.toml` version strings by hand.
Use `make bump` to increment the version, then `make release` to tag. Add `PUBLISH=1` only when the user has explicitly authorized publishing the GitHub Release. Do not edit `pyproject.toml` version strings by hand.

```bash
# 1. Bump version (defaults to patch; use PART=minor or PART=major as needed)
Expand All @@ -183,14 +183,17 @@ git commit -m "chore(data-designer-my-plugin): bump version to 0.2.0"

# 3. Tag and release (runs tests, validation, and build)
make release PLUGIN=data-designer-my-plugin
git push origin data-designer-my-plugin/v0.2.0

# Optional: when publishing has been explicitly requested, push the tag and
# publish the GitHub Release in the same target invocation.
make release PLUGIN=data-designer-my-plugin PUBLISH=1
```

Release facts:

- Tags are per-plugin: `data-designer-my-plugin/v0.1.0`.
- Release CI expects the tagged commit to be on `main`.
- The tag pusher must be listed in that plugin's `CODEOWNERS`.
- Release CI expects the tagged commit to be reachable from `main`; `make release` requires a clean worktree and checks the commit against `origin/main`.
- Release validation requires the plugin `CODEOWNERS` file to include at least one GitHub `@user` or `@org/team` owner.
- Pre-release versions (e.g. `0.2.0a1`) are not supported by `ddp bump`; edit `pyproject.toml` manually for those.

# References
Expand Down
37 changes: 30 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

.PHONY: sync lint format test test-devtools test-plugins validate docs docs-server plugin-docs catalog package-index check-plugin-docs check-catalog check-package-index qa-package-index codeowners check-codeowners check-license-headers update-license-headers check all bump release build-plugin validate-release test-plugin
.PHONY: sync lint format test test-devtools test-plugins validate docs docs-server plugin-docs catalog package-index check-plugin-docs check-catalog check-package-index qa-package-index codeowners check-codeowners check-license-headers update-license-headers check all bump release build-plugin validate-release test-plugin check-release-state

# ── Setup ────────────────────────────────────────────────────────────────

Expand Down Expand Up @@ -116,6 +116,7 @@ all: lint test validate check docs

PLUGIN ?=
PART ?= patch
PUBLISH ?= 0
PLUGIN_DIR = plugins/$(PLUGIN)

bump:
Expand All @@ -140,11 +141,33 @@ test-plugin:
build-plugin: validate-release
uv build "$(PLUGIN_DIR)" --out-dir dist/

release: test-plugin build-plugin
check-release-state:
@test -z "$$(git status --porcelain)" || { echo "ERROR: release worktree must be clean"; git status --short; exit 1; }
@git fetch origin main
@git merge-base --is-ancestor HEAD origin/main || { echo "ERROR: release commit must be reachable from origin/main"; exit 1; }

release: check-release-state test-plugin build-plugin
@PLUGIN_VERSION=$$(uv run python -c "import tomllib; print(tomllib.load(open('$(PLUGIN_DIR)/pyproject.toml','rb'))['project']['version'])"); \
echo "Creating tag: $(PLUGIN)/v$$PLUGIN_VERSION"; \
git tag "$(PLUGIN)/v$$PLUGIN_VERSION"; \
RELEASE_TAG="$(PLUGIN)/v$$PLUGIN_VERSION"; \
if git rev-parse -q --verify "refs/tags/$$RELEASE_TAG" >/dev/null; then \
if [ "$$(git rev-list -n 1 "$$RELEASE_TAG")" != "$$(git rev-parse HEAD)" ]; then \
echo "ERROR: tag $$RELEASE_TAG already exists on a different commit"; \
exit 1; \
fi; \
echo "Tag already exists at HEAD: $$RELEASE_TAG"; \
else \
echo "Creating tag: $$RELEASE_TAG"; \
git tag "$$RELEASE_TAG"; \
fi; \
echo ""; \
echo "Tag created. Push it, then publish a GitHub Release to trigger CI publish:"; \
echo " git push origin $(PLUGIN)/v$$PLUGIN_VERSION"; \
echo " gh release create $(PLUGIN)/v$$PLUGIN_VERSION --title \"$(PLUGIN) v$$PLUGIN_VERSION\" --notes \"Release $(PLUGIN) v$$PLUGIN_VERSION\" --latest=false"
if [ "$(PUBLISH)" = "1" ]; then \
echo "Pushing tag and publishing GitHub Release: $$RELEASE_TAG"; \
git push origin "$$RELEASE_TAG"; \
gh release create "$$RELEASE_TAG" --title "$(PLUGIN) v$$PLUGIN_VERSION" --notes "Release $(PLUGIN) v$$PLUGIN_VERSION" --latest=false --verify-tag; \
else \
echo "Tag created. Push it, then publish a GitHub Release to trigger CI publish:"; \
echo " git push origin $$RELEASE_TAG"; \
echo " gh release create $$RELEASE_TAG --title \"$(PLUGIN) v$$PLUGIN_VERSION\" --notes \"Release $(PLUGIN) v$$PLUGIN_VERSION\" --latest=false --verify-tag"; \
echo ""; \
echo "Run with PUBLISH=1 to push the tag and create the GitHub Release automatically."; \
fi
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ The `ddp` command manages the monorepo. Run `uv run ddp --help` to see all subco
make bump PLUGIN=data-designer-my-plugin PART=patch # Bump version (major/minor/patch)
git add plugins/data-designer-my-plugin/pyproject.toml
git commit -m "chore(data-designer-my-plugin): bump version to 0.1.1"
make release PLUGIN=data-designer-my-plugin # Build and tag for GitHub Release publishing
git push origin data-designer-my-plugin/v0.1.1
gh release create data-designer-my-plugin/v0.1.1 # Triggers CI publish
make release PLUGIN=data-designer-my-plugin PUBLISH=1 # Build, tag, push, and publish the GitHub Release
```

See [docs/releasing.md](docs/releasing.md) for the full release guide.
Expand Down
43 changes: 0 additions & 43 deletions devtools/ddp/src/ddp/release_owners.py

This file was deleted.

15 changes: 12 additions & 3 deletions docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ After the version bump is merged to `main`, create the release tag:
make release PLUGIN=data-designer-my-plugin
```

For the lowest-touch path, let the target push the tag and publish the GitHub
Release after local checks pass:

```bash
make release PLUGIN=data-designer-my-plugin PUBLISH=1
```

Release tags are per plugin package and use this format:

```text
Expand All @@ -43,13 +50,14 @@ tag `data-designer-my-plugin/v0.2.0`. The tag format comes from

The release target:

- warns if your git email is not listed in the plugin `CODEOWNERS`;
- verifies that the worktree is clean and the release commit is reachable from
`origin/main`;
- runs that plugin's isolated tests;
- validates release metadata;
- builds the wheel and source distribution;
- creates a tag named `data-designer-my-plugin/v<version>`.

Push the tag printed by the release command:
When run without `PUBLISH=1`, push the tag printed by the release command:

```bash
git push origin data-designer-my-plugin/v0.2.0
Expand All @@ -62,7 +70,8 @@ explicit maintainer action that starts package publication:
gh release create data-designer-my-plugin/v0.2.0 \
--title "data-designer-my-plugin v0.2.0" \
--notes "Release data-designer-my-plugin v0.2.0" \
--latest=false
--latest=false \
--verify-tag
```

## Catalog discoverability
Expand Down
Loading