Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ff7dcde
State the intent to publish, and get ready for outside contributors
claude Nov 2, 2026
770b41a
Let other packages plug in, and write the guide to building on jupyddl
claude Nov 2, 2026
e1d4f83
Merge the already-merged #163 branch tip so this push fast-forwards
claude Nov 2, 2026
a5ef363
Fix wrong answers in the task model and heuristics
claude Nov 3, 2026
76c970b
Record the already-merged #164 branch tip so this push fast-forwards
claude Nov 3, 2026
0333b0d
Make every planner honour its budget and claim only what it guarantees
claude Nov 3, 2026
5353db4
Record the already-merged #165 branch tip so this push fast-forwards
claude Nov 3, 2026
f7d7334
Make the command line safe to script, and the charts survive a dead end
claude Nov 3, 2026
0f83777
Record the already-merged #166 branch tip so this push fast-forwards
claude Nov 3, 2026
b4981a4
feat: automate semantic releases with release-please
claude Nov 3, 2026
7af289e
chore: record the already-merged #167 branch tip so this push fast-fo…
claude Nov 3, 2026
b7a6a92
fix(learn): honest ranking metrics, seed-sensitive generators, distin…
claude Nov 3, 2026
871f09b
chore: record the already-merged #169 branch tip so this push fast-fo…
claude Nov 3, 2026
3135f36
fix(pddl): correct durative, PDDL 3 and metric semantics; refuse what…
claude Nov 3, 2026
29b54ef
chore: record the already-merged #171 branch tip so this push fast-fo…
claude Nov 3, 2026
edc7e29
feat(release): cut a release on every merge, with no release PR to ap…
claude Nov 3, 2026
d233a30
chore: record the already-merged #172 branch tip so this push fast-fo…
claude Nov 3, 2026
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
89 changes: 48 additions & 41 deletions .docs/RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,53 @@
# Releasing jupyddl

## The normal way: merge the release PR

Releases are **semantic and automatic**. Nobody picks a version number.

1. Every pull request is squash-merged, so its **title** becomes the commit
on `main`. The `pr-title` check requires a
[Conventional Commit](https://www.conventionalcommits.org) title:

| Title | Release it triggers |
|---|---|
| `fix: …`, `fix(lmcut): …`, `perf: …` | patch, 2.4.0 → 2.4.1 |
| `feat: …` | minor, 2.4.0 → 2.5.0 |
| `feat!: …`, or a `BREAKING CHANGE:` footer | major, 2.4.0 → 3.0.0 |
| `docs:`, `chore:`, `ci:`, `test:`, `refactor:`, `build:`, `style:` | none on its own; it rides along with the next one |

2. On every push to `main`, `release-please.yml` keeps **one release PR**
(`chore: release X.Y.Z`) up to date. It bumps `pyproject.toml` and
`jupyddl.__version__`, writes the changelog section from the merged
titles, files the hand-written `## [Unreleased]` notes under it, and
rebuilds `web/dist`, which records the version. The bump is the largest any
merged title asks for.
3. **Merging the release PR is the release.** release-please tags the merge
commit and creates the GitHub Release. It then starts `release.yml` on that
tag, which builds, verifies, publishes to PyPI and attaches the artifacts,
with the same checks as below.

Want a release after every merge? Merge the release PR right after. Want
batches? Let it collect. Either way the version follows from what went in.

**One-time repository settings** (a maintainer has to do these):

- *Settings → Actions → General → Workflow permissions*: tick **Allow GitHub
Actions to create and approve pull requests**. Without it release-please
cannot open its PR.
- *Settings → General → Pull Requests*: allow squash merging and set its
default commit message to **Pull request title**, so the checked title is
what lands on `main`.
- Do **not** make `pr-title` (or `tests`) a required check without an
exception for release-please's PR. A PR opened with the workflow's own
token starts no workflows, so those checks never report on it.
`release.yml` repeats every check that matters before publishing.
## The normal way: merge a pull request

Releases are **semantic and automatic**. Nobody picks a version number, and
nobody approves anything. **Merging a pull request is the release decision.**

On every push to `main`, `release.yml` looks up the pull request that was just
merged and takes the largest bump that its title and its commits ask for
(`tools/release.py`):

| Commit or title | Release |
|---|---|
| `fix: …`, `fix(lmcut): …`, `perf: …` | patch, 2.4.0 → 2.4.1 |
| `feat: …` | minor, 2.4.0 → 2.5.0 |
| `feat!: …`, `fix!: …`, or a `BREAKING CHANGE:` footer | major, 2.4.0 → 3.0.0 |
| `docs:`, `chore:`, `ci:`, `test:`, `refactor:`, `build:`, `style:` | none |

- **Override with a label.** Add `release:major`, `release:minor`,
`release:patch` or `release:none` to the pull request before merging, for
the rare change whose commits say the wrong thing.
- **Nothing is lost.** Commits on `main` since the last `v*` tag count too.
So a merge whose run was dropped, because several merges landed at once,
still releases with the next one.

When a release is due, the workflow:

1. bumps `pyproject.toml`, `jupyddl.__version__` and `CITATION.cff`;
2. turns `## [Unreleased]` in `CHANGELOG.md` into `## [X.Y.Z] - date`, using
the PR title if nobody wrote an entry;
3. rebuilds `web/dist`, which records the version;
4. commits that to `main` as `chore(release): X.Y.Z`, tags `vX.Y.Z`, and
starts `pages`;
5. builds, verifies, publishes to PyPI and cuts the GitHub Release, with every
check described below.

It pushes with the workflow's own token, which is allowed to push commits and
tags. That is all it needs: there is no release pull request, so the *Allow
GitHub Actions to create pull requests* setting is not needed. Those pushes
start no workflows, so nothing loops.

**Requirements:**

- Squash-merge pull requests with the **PR title** as the commit message
(*Settings → General → Pull Requests*). The title is what `pr-title`
checks.
- `main` must accept pushes from GitHub Actions. If you add branch protection,
let `github-actions[bot]` push, as the `format` workflow already needs.
- The `pypi` environment must have no required reviewers, or every release
waits for one.

## By hand

Expand Down
4 changes: 4 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ check enforces this:
- `feat!: drop Python 3.10` → major release
- `docs: …`, `test: …`, `chore: …`, `ci: …`, `refactor: …` → no release on their own

Merging *is* releasing: the largest bump asked for by the title or any commit
in the PR ships as soon as it lands on `main`. A `release:major|minor|patch|none`
label overrides that when the commits say the wrong thing.

Write the user-facing story under `## [Unreleased]` in `CHANGELOG.md` as
well. The title is one line; the changelog entry is where you explain.
[`.docs/RELEASING.md`](../.docs/RELEASING.md) covers the rest.
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/pr-title.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: pr-title

# Pull requests are squash-merged, so the title becomes the commit on main --
# and release-please reads that commit to decide the next version. A title
# that is not a Conventional Commit is a change the release never mentions.
# and release.yml reads it (with the PR's own commits) to decide whether
# merging releases a new version. A title that is not a Conventional Commit
# asks for no release at all.
#
# feat: add the GOOSE feature extractor -> minor release
# fix(lmcut): handle an empty goal -> patch release
Expand All @@ -22,7 +23,7 @@ jobs:
name: conventional title
runs-on: ubuntu-latest
steps:
- name: Check the title release-please will read
- name: Check the title release.yml will read
env:
TITLE: ${{ github.event.pull_request.title }}
run: |
Expand Down
96 changes: 0 additions & 96 deletions .github/workflows/release-please.yml

This file was deleted.

Loading
Loading