Skip to content

docs(dev): add release process runbook (#573)#574

Merged
utensil merged 15 commits intopygae:masterfrom
utiberious:fix/issue-573-release-runbook
Apr 2, 2026
Merged

docs(dev): add release process runbook (#573)#574
utensil merged 15 commits intopygae:masterfrom
utiberious:fix/issue-573-release-runbook

Conversation

@utiberious
Copy link
Copy Markdown
Contributor

Closes #573.

Changes

doc/dev/release-process.md (new) — end-to-end release runbook covering:

  • Policy: always cut an RC first; squash-merge all PRs
  • Step 1 — Changelog: when to add :release:, why to omit it for RCs (semantic_version rejects PEP 440 RC suffixes), and validating the nbval_sanitize.cfg version regex before tagging
  • Step 2 — RC version bump: why _version.py must exactly match the git tag (references the 0.5.1 incident, Release 0.5.2 #517)
  • Step 3 — Tag and create RC release via gh release create --prerelease
  • Step 4 — Validate RC: PyPI, RTD, CI, install test
  • Step 5 — Final version bump with :release: marker
  • Step 6 — Tag and create final release
  • Step 7 — Post-release checks: PyPI, Zenodo (manual trigger if webhook missed), close milestone, follow-up docs PR

Added to doc/index.rst under "Developer guides" alongside the bumping-python and bumping-sympy guides (those land via #570 and #572; this PR adds the toctree entries for all three so the section renders correctly when they all merge).

utiberious and others added 13 commits March 31, 2026 12:28
* Fix norm to always return nonneg value for even grades

The norm method could return expressions like s instead of Abs(s) for
scalar and even-grade multivectors. Now norm checks whether the result
from square_root_of_expr is guaranteed nonneg, and wraps it in Abs
when it is not.

Fixes #6

* Update test_gsg_undual_etc notebook output for norm/abs/bar changes

The norm/abs/bar fix (issue pygae#522) changes how these operations are
printed in LaTeX. Update saved notebook outputs to match.

* Remove dead code branch, add non-Euclidean norm test
…an metrics (pygae#461) (pygae#558)

* test(lt): add regression tests for lt.matrix() on oblique/non-Euclidean metrics (pygae#461)

Adds two tests to confirm the bugs reported in pygae#461 are fixed:
- test_lt_matrix_oblique: lt.matrix() on oblique g=[[1,1],[1,2]] and
  Minkowski g=diag(1,-1) returns the bare coefficient matrix without
  metric tensor factors
- test_lt_generic_oblique: Ga.lt('f') on oblique metric produces f(e_j)
  with plain symbol coefficients and a matching matrix()

* style(lt): move Symbol import to top-level per review
…e#556)

* fix(interop): reset dual mode to galgebra default in interop.Cl

galgebra.interop.Cl now calls Ga.dual_mode('I+') before building the
algebra, mirroring what kingdon.Cl does for 'Iinv+'. This prevents
silent session contamination when both Cl variants are used in the same
session (pygae#555).

Update kingdon.Cl docstring: the save/restore warning becomes a note
explaining that interop.Cl resets the mode, so sequential calls are safe
without manual save/restore.

Fixes pygae#555 (short-term). Long-term per-instance fix tracked on
feat/issue-555-interop-dual-mode-per-instance.

* test(interop): add regression test for dual mode reset in interop.Cl

Add test_Cl_dual_mode_reset: calls kingdon.Cl (sets Iinv+) then
galgebra.interop.Cl and asserts dual mode is reset to I+. Without the
fix in _cl.py this test fails.

Clarify kingdon.Cl note: explicitly warn that algebras built under Iinv+
will compute duals with I+ once a subsequent galgebra.interop.Cl call is
made.
…) (pygae#557)

* feat(examples): validate galgebra against Goyder cheatsheet (pygae#506)

Adds examples/Terminal/cheatsheet_validation.py covering all 7 sections
of the geometric algebra cheat sheet by Russell Goyder:

1. geometric product decomposition (ab = a.b + a^b)
2. vector-multivector grade raising/lowering
3. bivector identities (a.(b^c), (a^b).(c^d))
4. commutator product (B x v = B.v, Jacobi identity)
5. pseudoscalar (I^2=-1, centrality in 3D, dual)
6. outermorphism (rotor normalization, rotation, det=1)
7. adjoint (a.F_bar(b) = F(a).b, det(FG) = det(F)det(G))

* test(cheatsheet): move validation to test/ so pytest collects it (pygae#506)

Per review: examples/Terminal/ is not collected by CI (setup.cfg only
collects test_*.py). Move to test/test_cheatsheet.py so assertions
actually run in CI.

Also adds a comment in section 5 clarifying that the dual is computed
manually via I^{-1} (Iinv+ convention), which differs from galgebra's
built-in dual() that uses I+ by default.

* chore: remove unused Symbol and Matrix imports

Co-authored-by: utensil <utensilcandel@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…gae#560)

* Allow returning zero from Lt callable constructor

* test(lt): add regression test for callable Lt returning zero (pygae#540)
Co-authored-by: T0mstone <realt0mstone@gmail.com>
* docs: add 0.6.0 changelog entries

Groups new entries by: features, bug fixes, examples/docs, tests/maintenance.

Features: Cl() kingdon interface (pygae#550, closes pygae#524), Mv.__rtruediv__
(pygae#543, closes pygae#512), shirokov_inverse/hitzer_inverse (pygae#530).

Bugs: interop dual mode contamination (pygae#556, closes pygae#555), norm() Abs
wrapping (pygae#554, closes pygae#522), is_versor() improvement (pygae#536, closes pygae#533).

Examples/docs: sundial + cheatsheet tests (pygae#549+pygae#557, closes pygae#506),
coords tutorial (pygae#551), README ops (pygae#548, closes pygae#523).

Tests/maintenance: lt.matrix() regression tests (pygae#558, closes pygae#461),
extra-cdot regression test (pygae#545), er_blade + ReciprocalFrame refactors
(pygae#552+pygae#553), CI fix (pygae#535).

* docs: add missing issue link for pygae#551 entry

* docs: add changelog entry for pygae#560 (Lt callable zero fix)

* docs: move Lt zero fix into bug group, use issue pygae#540 as reference
* chore: bump version to 0.6.0rc1 and add release marker
* fix(test): extend nbval sanitize regex to match rc version suffixes

The GAlgebra version pattern (-dev) didn't cover release candidates
like 0.6.0rc1, causing nbval output mismatch failures in notebooks.
* fix(docs): remove :release: marker from changelog for rc (semver incompatible)

releases extension uses semantic_version which rejects '0.6.0rc1' (PEP 440
format, not semver). The release marker will be added as ':release:`0.6.0`'
for the final release. The _version.py bump to 0.6.0rc1 controls PyPI.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the git+https workaround with plain `pip install galgebra` and remove the "not yet finalized" note.
Copy link
Copy Markdown
Member

@utensil utensil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for writing this up — it's a solid runbook.

Steps 3 and 6 show git tag vX.Y.ZrcN && git push origin vX.Y.ZrcN before gh release create. We just ran gh release create directly — it auto-creates the tag from the latest state of the default branch, so the manual tag push is not needed and can cause confusion if local HEAD differs. Please remove those two lines and add --target master to the gh release create commands to make the intent explicit.

The branch names in Steps 2 and 5 use utensil/X.Y.ZrcN and utensil/X.Y.Z, but the actual 0.6.0 branches were utensil/0.6.0-rc1 and utensil/0.6.0-release. Worth updating to match that convention.

One thing worth adding in Step 3: the tag must start with v — the CI release job checks for that prefix to trigger the PyPI publish, so 0.6.0rc1 without the v would not publish.

@pygae pygae deleted a comment from utiberious Apr 2, 2026
- Add pre-push version verification command in Steps 3 and 6 to guard
  against the _version.py/tag mismatch that caused the 0.5.1 incident
- Clarify that CI publishes to PyPI automatically; gh release create is
  the manual step that creates the GitHub release
- Add specific Zenodo sync URL (zenodo.org/account/settings/github/)
  instead of the vague "settings page" instruction
- gh release create auto-creates the tag; remove manual git tag/push
  steps and add --target master to make the target branch explicit
- Add note that tag must start with v for the CI release job to trigger
- Update branch naming convention to match 0.6.0 practice:
  utensil/X.Y.Z-rc1 and utensil/X.Y.Z-release
Copy link
Copy Markdown
Member

@utensil utensil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

~

@utiberious utiberious force-pushed the fix/issue-573-release-runbook branch from 55da443 to 7676c70 Compare April 2, 2026 00:57
@review-notebook-app
Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@utensil utensil merged commit 2731933 into pygae:master Apr 2, 2026
5 checks passed
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
- Remove Developer guides toctree from doc/index.rst; pygae#574 owns it
  with the full three-entry block to avoid duplicate sidebar sections
- Fix setup.py: python_requires>=3.10, drop 3.8/3.9 classifiers, add 3.12
- Add test_requirements.txt to the files-to-update table in bumping-python.md
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
- Remove Developer guides toctree from doc/index.rst; pygae#574 owns it
  with the full three-entry block to avoid duplicate sidebar sections
- Fix setup.py: python_requires>=3.10, drop 3.8/3.9 classifiers, add 3.12
- Add test_requirements.txt to the files-to-update table in bumping-python.md
utensil pushed a commit that referenced this pull request Apr 2, 2026
… and SymPy (#571) (#572)

* docs: update README Python prereqs; add dev guides for bumping Python and SymPy (#571)

* docs: address review feedback on #572

- Remove Developer guides toctree from doc/index.rst; #574 owns it
  with the full three-entry block to avoid duplicate sidebar sections
- Fix setup.py: python_requires>=3.10, drop 3.8/3.9 classifiers, add 3.12
- Add test_requirements.txt to the files-to-update table in bumping-python.md

* docs: add only bumping-python to Developer guides toctree

* docs(bumping-python): make doc self-contained, no sympy cross-refs

- Remove version policy cross-reference to bumping-sympy.md
- Inline the full tracking issue pattern description instead of
  deferring to bumping-sympy.md
- Use bare flake8/pytest to match CI
utiberious added a commit to utiberious/galgebra that referenced this pull request Apr 2, 2026
Covers: Mlt component-expression constructor (pygae#578/pygae#580),
is_blade null fix (pygae#537), Macdonald PDF update (pygae#577),
dev guides (pygae#572/pygae#574), SymPy 1.13 notebook refresh (pygae#570),
Lt ImmutableDenseMatrix fix (pygae#569), Python 3.10-3.12 CI (pygae#565).
utensil pushed a commit that referenced this pull request Apr 3, 2026
* docs: add 0.6.1 changelog entries

Covers: Mlt component-expression constructor (#578/#580),
is_blade null fix (#537), Macdonald PDF update (#577),
dev guides (#572/#574), SymPy 1.13 notebook refresh (#570),
Lt ImmutableDenseMatrix fix (#569), Python 3.10-3.12 CI (#565).

* docs(changelog): fix is_blade entry reference from issue to PR

The is_blade entry incorrectly referenced issue 537 but should reference
PR 582 to match the convention used in other entries.

---------

Co-authored-by: utiberious <utiberious@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write a release procedure runbook (doc/dev/release-process.md)

2 participants