diff --git a/RELEASE.md b/RELEASE.md index 8a58948..1aed672 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,145 +1,24 @@ # Releasing cat_tools -cat_tools builds on pgxntool (https://github.com/Postgres-Extensions/pgxntool); -the release machinery (`make tag`, `make dist`) lives in `pgxntool/base.mk`. These -steps cut a new release. - -## 1. Safety check: verify committed version files haven't drifted - -Before anything else, confirm every committed versioned install script still matches -what that version actually shipped. - -- [ ] For each committed versioned install script — `sql/cat_tools--.sql.in` - (0.2.0 onward) or `sql/cat_tools--.sql` (the historical pre-0.2.0 files - `0.1.0`/`0.1.3`/`0.1.4`/`0.1.5`, which have no `.sql.in` source and are tracked - directly; see CLAUDE.md "SQL file conventions") — find its last-touching commit: - `git log -1 --format='%H %ad' -- sql/cat_tools--.sql.in` (or `.sql`). -- [ ] Confirm that commit is no later than when that version was actually tagged. - cat_tools tags every release, unprefixed (e.g. `0.2.2`, `0.2.3` — see step 6's - `make tag`), so compare directly: `git log -1 --format='%H %ad' `. (No - tags exist before `0.2.2` — `0.1.x`, `0.2.0`, and `0.2.1` predate cat_tools' - tagging convention — so this direct comparison is only available from `0.2.2` - onward.) -- [ ] A version file touched by a commit LATER than its own release's tag is a red - flag — it likely means `default_version` in `cat_tools.control` was left pointing - at that real (non-`stable`) version after release, and a later source edit to - `sql/cat_tools.sql.in` silently regenerated — and corrupted — the committed file - via `sql.mk`'s current-version rule (`$(EXTENSION__CURRENT_VERSION__FILES:.sql=.sql.in): - sql/cat_tools.sql.in cat_tools.control`, which `cp`s the base source over it). - Investigate before proceeding. -- [ ] **Known exception, not necessarily a corruption:** a version file whose - last-touching commit is much later than its version's real release can also mean - the file was legitimately backfilled or reformatted after the fact (e.g. once new - build tooling started requiring something that wasn't tracked before). A late - touch-date alone isn't suspicious — only worry about a file whose *content* - actually differs from what shipped. - -## 2. Pre-release checks -- [ ] Open issues/PRs for this release reviewed, merged or deferred. -- [ ] CI green on all supported PostgreSQL versions (the `all-checks-passed` job on master). -- [ ] Locally: `make verify-results` passes. It depends on `$(TEST_DEPS)` directly, not - on `test` itself (deliberately — see `base.mk`'s own comment on why: `test`'s early - exit on a regression would otherwise abort the chain before verify-results got to - inspect and report the diff), so it still runs the suite first, then gates on the - results with a stricter pgtap-aware check. `make test` itself also returns - non-zero on a regression as of pgxntool 2.3.0, but `verify-results` remains the - stricter, documented gate. - -## 3. Decide the version and what to track -- [ ] Pick the new version (semantic versioning). -- [ ] **Minor change? Consider NOT committing the generated versioned install script.** - If this release makes only fairly minor changes (unlikely to cross a PostgreSQL - supported-version boundary), decide whether to omit the generated - `sql/cat_tools--.sql.in` — it has little update-test-coverage value and - omitting it keeps the repo smaller (it is regenerated from `sql/cat_tools.sql.in` - at build time). The update script (`sql/cat_tools----.sql.in`) is - ALWAYS committed. See CLAUDE.md "SQL file conventions". - -## 4. Update version + changelog - -> **⚠️ CRITICAL — you are temporarily leaving the `stable` pseudo-version.** Master's -> `default_version` normally sits at the `stable` pseudo-version so that source edits -> regenerate `cat_tools--stable.sql` and never a frozen released file. Stamping a real -> version here points the generated current-version file at `cat_tools--`. The -> moment this release is merged you **MUST** flip `default_version` back to `stable` on -> master (step 7). If you forget, the next source edit on master will regenerate — and -> corrupt — the just-released version's install file. -> -> `sql/cat_tools--.sql.in` must ALWAYS be tracked — that's the entire point, -> keeping a real history of the extension across releases. `stable` is the ONE exception -> (its `.sql.in` is gitignored, not tracked) for the ONE reason that `stable` itself is -> never actually released, so there's no history to keep. - -- [ ] Bump `default_version` in `cat_tools.control` (bumped by hand). -- [ ] Bump the version in `META.in.json` — the source of truth is - `provides.cat_tools.version` (also update the top-level `version`); `META.json`, - `control.mk`, and `meta.mk` (which feeds `PGXNVERSION`) regenerate via `make`. -- [ ] Advance `release_status` in `META.in.json` as appropriate (unstable → testing → - stable). -- [ ] Add/finish the update script `sql/cat_tools----.sql.in`; confirm - `ALTER EXTENSION cat_tools UPDATE` from the previous version reaches the new one, - on multiple PG majors. -- [ ] Stamp `HISTORY.asc`: the top `STABLE` section accumulates user-facing changes as - PRs land; at release, rename that header to the new version number. - -## 5. Verify -- [ ] `make verify-results` green (it runs `test` first, then gates on the results). -- [ ] From a clean checkout (or `git archive` of the tag): `make && make install` - regenerates and installs cleanly and `CREATE EXTENSION cat_tools;` reports the new - version — confirms a PGXN consumer can build from the tracked sources alone. (This - mirrors what `make dist` ships, since it archives the tag: committed files only, so - any omitted generated install script is regenerated on the consumer's side.) - -## 6. Tag and distribute - -> **⚠️ Pass `PGXN_REMOTE=` to every target below if your clone's `origin` -> is a personal fork** (as it typically is for a maintainer working from a fork, -> with the canonical repo configured under some other remote name — check -> `git remote -v` rather than assuming it's called `upstream`). Without it, -> `tag`/`rmtag`/`forcetag`/`dist` push to `origin` by default — silently -> tagging the fork instead of `Postgres-Extensions/cat_tools`. This is exactly -> what happened when the 0.2.3 release tag was first cut and had to be -> re-pointed by hand; pgxntool 2.2.0 added `PGXN_REMOTE` specifically to fix -> this (https://github.com/Postgres-Extensions/pgxntool/issues/53). - -- [ ] Commit the release changes; working tree must be clean — `make tag` aborts with - "Untracked changes!" on a dirty tree. -- [ ] `make tag` — creates a git tag named exactly the version, UNPREFIXED (e.g. `0.2.3`, - matching the existing `0.2.2` tag; no `v` prefix), taken from `PGXNVERSION`, and - pushes it to `$(PGXN_REMOTE)` (default `origin`). It is idempotent when the tag - already points at HEAD, and errors if the tag exists on a different commit. To - move an existing tag use `make forcetag` (= `make rmtag` then `make tag`); - `make rmtag` deletes the tag locally and on `$(PGXN_REMOTE)`. -- [ ] `make dist` — depends on `tag` (and builds the HTML docs), then - `git archive`s the tag into `../cat_tools-.zip` (parent directory). - Because it archives the tag, only committed files are included. If a `.gitattributes` - exists it must be committed, or `dist` aborts (git archive only honors - `export-ignore` for committed files). `make forcedist` = `forcetag` + `dist`. -- [ ] Upload the `../cat_tools-.zip` to PGXN (manual). - -## 7. Return master to `stable` (CRITICAL — do not skip) -- [ ] As soon as the release is merged, flip `default_version` back to the `stable` - pseudo-version on master (`cat_tools.control` + `META.in.json`), open a new top - `STABLE` section in `HISTORY.asc`, and re-seed a fresh - `sql/cat_tools----stable.sql.in` update script for the next cycle. - Leaving master stamped at the real version means the next source edit regenerates - and corrupts the released version's install file. The just-released - `sql/cat_tools--.sql.in` stays tracked, permanently — nothing to clean up - or remove there; see step 4's note above. - -> The persistent `stable` pseudo-version (a permanent version literally named `stable`, -> with a live `sql/cat_tools----stable.sql.in` update script that every -> source fix targets) decouples fixes from version bumps. The machinery is built into -> `sql.mk`; it lands immediately after the 0.2.3 release, so 0.2.3 itself is the last -> release cut before the scheme exists — steps 4/7 above describe the flow from the -> next release onward. - -## Notes and caveats - -- **0.2.3 catalog-view repair / `pg_upgrade` caveat.** Databases updated from - 0.2.0/0.2.1 hold broken catalog views that fail binary `pg_upgrade` to PostgreSQL - 12+ until the extension is updated to 0.2.3 (the update rebuilds them, dropping and - recreating the public `pg_class_v`/`column`/`pg_class()` objects without `CASCADE`). - Surface this in the release notes when people may cross the PG 11 → 12+ boundary. See - README.asc "Updating the extension" and - https://github.com/Postgres-Extensions/cat_tools/pull/42. +See [`../ai/RELEASE.md`](../ai/RELEASE.md) for the actual release process. +What follows is repo-specific context that doesn't belong in that shared +doc. + +## Pre-0.2.2 releases predate tagging + +cat_tools' first git tag is `0.2.2`; `0.1.0`/`0.1.3`/`0.1.4`/`0.1.5`, `0.2.0`, +and `0.2.1` were never tagged. The shared doc's step 1 (verify committed +version files haven't drifted) calls for comparing a version file's +last-touching commit against that version's tag — there's no tag to compare +against for any of those versions. See CLAUDE.md "SQL file conventions" for +how those pre-0.2.0 versions are tracked (plain `.sql`, no `.sql.in`). + +## 0.2.3 catalog-view repair / `pg_upgrade` caveat + +Databases updated from 0.2.0/0.2.1 hold broken catalog views that fail +binary `pg_upgrade` to PostgreSQL 12+ until the extension is updated to +0.2.3 (the update rebuilds them, dropping and recreating the public +`pg_class_v`/`column`/`pg_class()` objects without `CASCADE`). Surface this +in the release notes when people may cross the PG 11 → 12+ boundary. See +README.asc "Updating the extension" and +https://github.com/Postgres-Extensions/cat_tools/pull/42.