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
30 changes: 7 additions & 23 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ CC=gcc uv pip install --python-version=3.14 -e '.[full]' --group check --group d
uv run pre-commit install
```

## Working with agents

We encourage contributors to use AI agents when contributing to TorchJD, but there are a few rules:
- The initiative should come from a human. We do not want PRs from fully automated bots.
- The changes should be reviewed by a human before a non-draft PR is open.
Comment thread
ValerianRey marked this conversation as resolved.
- To avoid vendor lock-in, we do not provide any file that is specific to an agent vendor. To use a specific agent that does not follow open file naming conventions, you have to adapt a few things yourself (e.g. symlink files). For example, to work with claude, you have to symlink `CLAUDE.md` to `AGENTS.md`, and `.claude/skill/` to `skills/`.

## Checks

### Running tests
Expand Down Expand Up @@ -275,26 +282,3 @@ The three plot scripts produce PDFs saved to `tests/trajectories/results/<object
> [!NOTE]
> The plot scripts require a LaTeX installation for rendering:
> `sudo apt-get install texlive-latex-extra texlive-fonts-recommended dvipng cm-super`


## Release

*This section is addressed to maintainers.*

To release a new `torchjd` version, you have to:
- If the release introduces changes to the interface, make sure that `README.md` reflects those
changes.
- Make sure that all tests, including those on cuda, pass (for this, you need access to a machine
that has a cuda-enabled GPU).
- Make sure that all important changes since the last release have been reported in the
`[Unreleased]` section at the top of the changelog.
- Add a `[X.Y.Z] - yyyy-mm-dd` header in the changelog just below the `[Unreleased]` header.
- Change the version in `pyproject.toml`.
- Make a pull request with those changes and merge it.
- Make a draft of the release on GitHub (click on `Releases`, then `Draft a new release`, then fill
the details).
- Publish the release (click on `Publish release`). This should trigger the deployment of the new
version on PyPI and the building and deployment of the documentation on github-pages.
- Check that the new version is correctly deployed to PyPI, that it is installable and that it
works.
- Check that the documentation has been correctly deployed.
103 changes: 103 additions & 0 deletions skills/check-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
name: check-release
description: Verifies that a TorchJD release was published correctly by checking the docs site, installing from PyPI, and smoke-testing newly added classes. Use after a release has been merged and published.
---

# Check TorchJD Release

This skill verifies that a release is live and correct after it has been published.

**For agents:** invoke as `/check-release X.Y.Z` (e.g. `/check-release 0.16.0`).
If no version is provided, read the current version from `pyproject.toml`.

---

## Instructions

### Step 1: Determine the version

Read `pyproject.toml` to find the `version` field under `[project]`. Use the version provided as
an argument, or the one from `pyproject.toml` if none is given.

### Step 2: Identify newly added classes

Read `CHANGELOG.md` and find the `## [X.Y.Z]` section. Extract the names of any newly added
public classes, functions, or methods listed under `### Added`. You will use these in later steps.

### Step 3: Check the docs site

Fetch `https://torchjd.org`.

- Verify that the versions dropdown (or switcher) includes `vX.Y.Z` as an entry.
- Verify that the `stable` entry is present.

If the version entry is missing, report it and stop — the rest of the checks depend on the docs
being live.

### Step 4: Verify the new-version docs contain the newly added classes

For each newly added class or function identified in Step 2, fetch its expected docs page under
`https://torchjd.org/vX.Y.Z/`. Use the URL patterns from similar existing classes found in
`README.md` or by browsing the stable docs (`https://torchjd.org/stable/`) to infer the correct
path (e.g. `https://torchjd.org/vX.Y.Z/docs/aggregation`,
`https://torchjd.org/vX.Y.Z/docs/scalarization`, etc.).

Confirm that each new class/function name appears on the fetched page.

### Step 5: Verify the stable docs also reflect the new version

Fetch the same doc pages under `https://torchjd.org/stable/` and confirm the newly added
classes/functions appear there too (i.e. `stable` points to the new release).

### Step 6: Install torchjd from PyPI in a temp environment

Run the following commands to create an isolated install:

```bash
cd /tmp && mkdir -p test_torchjd_install && cd test_torchjd_install
uv venv && uv pip install torchjd
```

Verify the installed version matches X.Y.Z:

```bash
cd /tmp/test_torchjd_install && uv pip show torchjd
```

If the version is wrong, report it and stop.

### Step 7: Smoke-test the newly added classes

Write a minimal Python script `/tmp/test_torchjd_install/smoke_test.py` that:

- Imports each newly added class or function by its fully-qualified name from `torchjd`.
- Instantiates or calls each one with a minimal valid input (e.g. a small `torch.Tensor`, a dummy
preference vector, or no arguments if the class takes none).
- Does NOT assert correctness of values — only that the code runs without raising an exception.

Use the existing test suite under `tests/` or the docs pages fetched in Step 4 as a reference for
correct import paths and minimal usage patterns.

Run the script:

```bash
cd /tmp/test_torchjd_install && uv run python smoke_test.py
```

Report the result. If it crashes, show the traceback.

### Step 8: Clean up

```bash
rm -rf /tmp/test_torchjd_install
```

### Step 9: Report

Summarize what was verified:
- Docs site: version dropdown ✓/✗, new-version page ✓/✗, stable page ✓/✗
- PyPI install: version matches ✓/✗
- Smoke test: each newly added class ✓/✗ (list them)

If everything passes, the release is confirmed good. If anything failed, describe what needs
attention.
97 changes: 97 additions & 0 deletions skills/prepare-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
name: prepare-release
description: Prepares a torchjd package release by verifying the changelog, README, bumping the version in pyproject.toml, and opening a release PR. Use when a maintainer asks to prepare a release or to release.
---

# Prepare TorchJD Release

This skill covers the pre-merge steps of the release process.

**For agents:** invoke as `/prepare-release X.Y.Z` (e.g. `/prepare-release 0.16.0`).
If no version is provided, read the current version from `pyproject.toml` and ask the user
what the new version should be before proceeding.

**For humans:** follow the numbered steps below in your terminal.
Replace `X.Y.Z` with the version you are releasing and `yyyy-mm-dd` with today's date.

---

## Instructions

### Step 1: Determine the version

Read `pyproject.toml` to find the current `version` field under `[project]`. The new release
version is either provided as an argument or must be confirmed with the user before continuing.

Verify it follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Step 2: Verify CHANGELOG

Read `CHANGELOG.md` and compare it against the commits done since the last version release. Verify that no user-facing change was forgotten, and that all were correctly added under the [Unreleased] section.

### Step 3: Check README for interface changes

Read `CHANGELOG.md` and identify any entries in the `[Unreleased]` section that affect the public
interface (new or removed classes, functions, or arguments; changed signatures or behavior).

If such entries exist, read `README.md` and verify it accurately describes the current interface.

If a table listing methods exists in `README.md`, add to it any newly added method of the corresponding type.

If anything else seems missing, report that to the user.

### Step 4: Run the unit tests

CRITICAL: Do not skip this step, even partially.

Run the unit tests and confirm they all pass both on CPU and GPU (you need a CUDA-enabled GPU for this):

```bash
uv run pytest tests/unit
PYTEST_TORCH_DEVICE=cuda:0 uv run pytest tests/unit
```

If any tests fail, stop and report the failures. Do not proceed to the next steps.

### Step 5: Add the version header to the changelog

In `CHANGELOG.md`, insert a new `## [X.Y.Z] - yyyy-mm-dd` heading immediately after the blank
line that follows `## [Unreleased]`, before the existing subsections:

```diff
## [Unreleased]

+## [X.Y.Z] - yyyy-mm-dd
+
### Added
```

The `[Unreleased]` section stays in place and will accumulate entries for the next release.
The newly-inserted heading claims the existing content as its own.

### Step 6: Bump the version in `pyproject.toml`

In `pyproject.toml`, update the `version` field under `[project]`:

```diff
-version = "A.B.C"
+version = "X.Y.Z"
```

### Step 7: Open the release PR

Stage changes, then open a pull request targeting `main`.
Return the PR URL when done.

Comment thread
ValerianRey marked this conversation as resolved.
### Step 8: Create a draft release on GitHub

CRITICAL: The release you'll create should ALWAYS be a draft. Never even suggest to make the real release. A maintainer will manually release the draft if it seems ready.

The command should be:
```
gh release create vX.Y.Z --draft --title vX.Y.Z --notes "<insert notes here>"
```

To write the actual release notes, look at what is done in recent releases and suggest the new notes. Make it short. Also, prompt the user for a good-looking emoji (propose a list) to use in the main section of the release notes.

---
Loading