feat(ci): render the release notes as Markdown with headings and lists
The release page got the newest <release> block as the plain text of its paragraphs, which fit two paragraphs of prose and nothing more. From 3.0.0 the notes group the changes under New, Fixes and Breaking, each in descending order of importance, and AppStream's description markup has lists but no headings to carry that. The metainfo stays the one source of the notes, since the Flatpak installs it and the tag check reads it. A category is written there as a paragraph that introduces a list, <p>New</p><ul>...</ul>, which is how AppStream notes lead into a list anyway, and the CI step renders such a paragraph as a Markdown heading over its items. A paragraph on its own stays a paragraph, so the older entries render as before. The step parses the XML with ElementTree instead of two regexes: entities are decoded, <em> and <code> get their Markdown spelling, and a code span keeps text like lib/<triple>/eh from being read as an HTML tag by the forge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
70ff11d0a1
commit
1d52350b31
1 changed files with 31 additions and 6 deletions
|
|
@ -185,13 +185,38 @@ jobs:
|
||||||
- name: Release notes
|
- name: Release notes
|
||||||
if: github.ref_type == 'tag'
|
if: github.ref_type == 'tag'
|
||||||
run: |
|
run: |
|
||||||
# The newest <release> block's description, as plain text.
|
# The newest <release> block's description as Markdown, for the
|
||||||
|
# release page. AppStream has no headings, so a paragraph that
|
||||||
|
# introduces a list is one: <p>New</p><ul>...</ul> comes out as
|
||||||
|
# "## New" over its items, the shape the notes take since 3.0.0.
|
||||||
|
# A paragraph on its own stays a paragraph, as the older entries
|
||||||
|
# are written. <em> and <code> get their Markdown spelling; a code
|
||||||
|
# span also keeps text such as lib/<triple>/eh from being read as
|
||||||
|
# an HTML tag by the forge.
|
||||||
python3 - > release-notes.md <<'EOF'
|
python3 - > release-notes.md <<'EOF'
|
||||||
import re, html
|
import xml.etree.ElementTree as ET
|
||||||
text = open("packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml").read()
|
|
||||||
block = re.search(r"<release [^>]*>(.*?)</release>", text, re.S).group(1)
|
desc = ET.parse("packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml").getroot().find("releases/release/description")
|
||||||
paras = re.findall(r"<p>(.*?)</p>", block, re.S)
|
|
||||||
print("\n\n".join(html.unescape(" ".join(p.split())) for p in paras))
|
def text(el):
|
||||||
|
parts = [el.text or ""]
|
||||||
|
for child in el:
|
||||||
|
inner = text(child)
|
||||||
|
parts.append({"em": f"*{inner}*", "code": f"`{inner}`"}.get(child.tag, inner))
|
||||||
|
parts.append(child.tail or "")
|
||||||
|
return " ".join("".join(parts).split())
|
||||||
|
|
||||||
|
blocks = list(desc)
|
||||||
|
out = []
|
||||||
|
for i, el in enumerate(blocks):
|
||||||
|
heads_list = i + 1 < len(blocks) and blocks[i + 1].tag in ("ul", "ol")
|
||||||
|
if el.tag == "p":
|
||||||
|
out.append(f"## {text(el)}" if heads_list else text(el))
|
||||||
|
elif el.tag == "ul":
|
||||||
|
out.append("\n".join(f"- {text(li)}" for li in el))
|
||||||
|
elif el.tag == "ol":
|
||||||
|
out.append("\n".join(f"{n}. {text(li)}" for n, li in enumerate(el, 1)))
|
||||||
|
print("\n\n".join(out))
|
||||||
print("\nInstall:\n\n flatpak remote-add --if-not-exists catcrafts https://flatpak.catcrafts.net/catcrafts.flatpakrepo\n flatpak install catcrafts net.catcrafts.CrafterBuild\n")
|
print("\nInstall:\n\n flatpak remote-add --if-not-exists catcrafts https://flatpak.catcrafts.net/catcrafts.flatpakrepo\n flatpak install catcrafts net.catcrafts.CrafterBuild\n")
|
||||||
EOF
|
EOF
|
||||||
- name: Publish release
|
- name: Publish release
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue