release.py: Add changelog.rst conversion to markdown

This commit is contained in:
Šarūnas Nejus 2024-06-04 16:20:48 +01:00
parent 3e5e1eca87
commit d2a94c1cdd
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
2 changed files with 85 additions and 22 deletions

View file

@ -12,8 +12,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install pandoc
run: sudo apt update && sudo apt install pandoc -y
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
@ -25,7 +23,7 @@ jobs:
- uses: EndBug/add-and-commit@v9 - uses: EndBug/add-and-commit@v9
name: Commit the changes name: Commit the changes
with: with:
message: 'Increment version numbers to ${{ inputs.version }}' message: "Increment version numbers to ${{ inputs.version }}"
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -55,6 +53,14 @@ jobs:
needs: build needs: build
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install pandoc
run: sudo apt update && sudo apt install pandoc -y
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
- name: Obtain the changelog
run: echo CHANGELOG="$(python ./extra/release.py changelog)" >> $GITHUB_ENV
- name: Bump version and push tag - name: Bump version and push tag
id: tag_version id: tag_version
uses: mathieudutour/github-tag-action@v6.1 uses: mathieudutour/github-tag-action@v6.1
@ -71,7 +77,7 @@ jobs:
with: with:
tag: ${{ steps.tag_version.outputs.new_tag }} tag: ${{ steps.tag_version.outputs.new_tag }}
name: Release ${{ steps.tag_version.outputs.new_tag }} name: Release ${{ steps.tag_version.outputs.new_tag }}
body: "Check [here](https://beets.readthedocs.io/en/stable/changelog.html) for the latest changes." body: ${{ env.CHANGELOG }}
artifacts: dist/* artifacts: dist/*
publish_to_pypi: publish_to_pypi:
@ -90,5 +96,3 @@ jobs:
path: dist/ path: dist/
- name: Publish distribution 📦 to PyPI - name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1 uses: pypa/gh-action-pypi-publish@release/v1

View file

@ -5,6 +5,7 @@
from __future__ import annotations from __future__ import annotations
import re import re
import subprocess
from datetime import datetime, timezone from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
from typing import Callable from typing import Callable
@ -14,6 +15,13 @@ from packaging.version import Version, parse
BASE = Path(__file__).parent.parent.absolute() BASE = Path(__file__).parent.parent.absolute()
BEETS_INIT = BASE / "beets" / "__init__.py" BEETS_INIT = BASE / "beets" / "__init__.py"
CHANGELOG = BASE / "docs" / "changelog.rst"
MD_CHANGELOG_SECTION_LIST = re.compile(r"- .+?(?=\n\n###|$)", re.DOTALL)
version_header = r"\d+\.\d+\.\d+ \([^)]+\)"
RST_LATEST_CHANGES = re.compile(
rf"{version_header}\n--+\s+(.+?)\n\n+{version_header}", re.DOTALL
)
def update_docs_config(text: str, new: Version) -> str: def update_docs_config(text: str, new: Version) -> str:
@ -48,13 +56,10 @@ FILENAME_AND_UPDATE_TEXT: list[tuple[Path, UpdateVersionCallable]] = [
r"(?<=__version__ = )[^\n]+", f'"{new}"', text r"(?<=__version__ = )[^\n]+", f'"{new}"', text
), ),
), ),
(BASE / "docs" / "changelog.rst", update_changelog), (CHANGELOG, update_changelog),
(BASE / "docs" / "conf.py", update_docs_config), (BASE / "docs" / "conf.py", update_docs_config),
] ]
GITHUB_USER = "beetbox"
GITHUB_REPO = "beets"
def validate_new_version( def validate_new_version(
ctx: click.Context, param: click.Argument, value: Version ctx: click.Context, param: click.Argument, value: Version
@ -84,6 +89,54 @@ def bump_version(new: Version) -> None:
f.truncate() f.truncate()
def rst2md(text: str) -> str:
"""Use Pandoc to convert text from ReST to Markdown."""
# Other backslashes with verbatim ranges.
rst = re.sub(r"(?<=[\s(])`([^`]+)`(?=[^_])", r"``\1``", text)
# Bug numbers.
rst = re.sub(r":bug:`(\d+)`", r":bug: (#\1)", rst)
# Users.
rst = re.sub(r":user:`(\w+)`", r"@\1", rst)
return (
subprocess.check_output(
["/usr/bin/pandoc", "--from=rst", "--to=gfm", "--wrap=none"],
input=rst.encode(),
)
.decode()
.strip()
)
def changelog_as_markdown() -> str:
"""Get the latest changelog entry as hacked up Markdown."""
with CHANGELOG.open() as f:
contents = f.read()
m = RST_LATEST_CHANGES.search(contents)
rst = m.group(1) if m else ""
# Convert with Pandoc.
md = rst2md(rst)
# Make sections stand out
md = re.sub(r"^(\w.+?):$", r"### \1", md, flags=re.M)
# Highlight plugin names
md = re.sub(
r"^- `/?plugins/(\w+)`:?", r"- Plugin **`\1`**:", md, flags=re.M
)
# Highlights command names.
md = re.sub(r"^- `(\w+)-cmd`:?", r"- Command **`\1`**:", md, flags=re.M)
# sort list items alphabetically for each of the sections
return MD_CHANGELOG_SECTION_LIST.sub(
lambda m: "\n".join(sorted(m.group().splitlines())), md
)
@click.group() @click.group()
def cli(): def cli():
pass pass
@ -96,5 +149,11 @@ def bump(version: Version) -> None:
bump_version(version) bump_version(version)
@cli.command()
def changelog():
"""Get the most recent version's changelog as Markdown."""
print(changelog_as_markdown())
if __name__ == "__main__": if __name__ == "__main__":
cli() cli()