Release notes that are not forty lines of base64

Found by documenting it. `_notes_for` stripped `-----BEGIN PGP SIGNATURE-----`
from an annotated tag's contents and nothing else, and which header appears
depends on `gpg.format`: `openpgp` writes that one, `ssh` writes
`-----BEGIN SSH SIGNATURE-----`. This repository signs with an SSH key, so the
first signed release tag would have rendered its whole signature block as the
release notes on the update page.

`%(contents:subject)` and `%(contents:body)` would have avoided the question,
and would also have thrown away every blank line in a body written as a list --
which is what release notes are.

The suite caught the other half of the same change: `tag.gpgSign` makes a bare
`git tag <name>` behave as `-s`, so the lightweight tags a test was making now
wait for an editor it does not have.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-06 21:29:42 +02:00
parent 6cc262ea5a
commit 8219bd9635
3 changed files with 53 additions and 5 deletions
+13 -3
View File
@@ -261,19 +261,29 @@ def release_tags(root: Path) -> list[str]:
return [line.strip() for line in output.splitlines() if RELEASE_TAG.match(line.strip())]
# Where a signature block starts in `%(contents)`. **Both**, because which one
# appears depends on `gpg.format` -- `openpgp` writes the first and `ssh` the
# second, and a release tag signed either way would otherwise render forty lines
# of base64 as its release notes. `%(contents:subject)` and `%(contents:body)`
# would avoid this, but they also throw away every blank line in a body written
# as a list, which is what release notes are.
_SIGNATURE_HEADERS = ("-----BEGIN PGP SIGNATURE-----", "-----BEGIN SSH SIGNATURE-----")
def _notes_for(root: Path, tag: str) -> str:
"""An annotated tag's message: the release notes, travelling inside git.
Empty for a lightweight tag, which is the honest answer -- there is nothing
attached to one. `%(contents)` includes the signature block for a signed tag,
so it is cut at the PGP header rather than shown.
attached to one.
"""
code, output = _git(
["for-each-ref", "--format=%(contents)", f"refs/tags/{tag}"], cwd=root
)
if code != 0:
return ""
return output.split("-----BEGIN PGP SIGNATURE-----")[0].strip()
for header in _SIGNATURE_HEADERS:
output = output.split(header)[0]
return output.strip()
def resolve_target(root: Path, channel: str, branch: str) -> Target | None: