mirror of
https://github.com/beetbox/beets.git
synced 2026-02-17 12:56:05 +01:00
Improve GitHub release rendering (#6356)
This PR hardens the release/changelog generation pipeline so ReST -> Markdown conversion produces stable, correctly formatted links and inline code. - Fix broken rendering of generated references by ensuring RST `~`-shortened forms like ``` `:class:`~beetsplug._utils...``` are converted into real Markdown links. - Updates `extra/release.py` to generate clearer link text for CLI command refs (e.g., `list-cmd` becomes 'list command') while keeping the same documentation targets. - Simplifies the Markdown post-processing step by removing the redundant `MD_REPLACEMENTS` layer, reducing ad-hoc formatting logic in the release script. - Standardizes changelog section header structure in `docs/changelog.rst` (and the release template) to align with Sphinx/ReST conventions and avoid ambiguous colon-based headers. - Strengthens CI by extending `lint-docs` in `pyproject.toml` to fail on single-backtick inline literals in `.rst`, enforcing double-backtick literals so `pandoc` does not emit meaningless `<span class="title-ref">...` output that breaks Markdown rendering. Net effect: more predictable release notes output, fewer conversion edge cases, and earlier detection of docs formatting that would render incorrectly downstream.
This commit is contained in:
commit
bc52682428
7 changed files with 380 additions and 204 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -99,7 +99,7 @@ started.
|
|||
write: no # Don't modify tags
|
||||
4. **Add customization via plugins (optional):**
|
||||
Beets comes with many plugins that extend its functionality. You can
|
||||
enable plugins by adding a `plugins` section to your config file.
|
||||
enable plugins by adding a ``plugins`` section to your config file.
|
||||
|
||||
We recommend adding at least one :ref:`Autotagger Plugin
|
||||
<autotagger_extensions>` to help with fetching metadata during import.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
MusicBrainz Pseudo-Release Plugin
|
||||
=================================
|
||||
|
||||
The `mbpseudo` plugin can be used *instead of* the `musicbrainz` plugin to
|
||||
The ``mbpseudo`` plugin can be used *instead of* the ``musicbrainz`` plugin to
|
||||
search for MusicBrainz pseudo-releases_ during the import process, which are
|
||||
added to the normal candidates from the MusicBrainz search.
|
||||
|
||||
|
|
@ -20,12 +20,12 @@ Configuration
|
|||
-------------
|
||||
|
||||
Since this plugin first searches for official releases from MusicBrainz, all
|
||||
options from the `musicbrainz` plugin's :ref:`musicbrainz-config` are supported,
|
||||
but they must be specified under `mbpseudo` in the configuration file.
|
||||
Additionally, the configuration expects an array of scripts that are desired for
|
||||
the pseudo-releases. For ``artist`` in particular, keep in mind that even
|
||||
pseudo-releases might specify it with the original script, so you should also
|
||||
configure import :ref:`languages` to give artist aliases more priority.
|
||||
options from the ``musicbrainz`` plugin's :ref:`musicbrainz-config` are
|
||||
supported, but they must be specified under ``mbpseudo`` in the configuration
|
||||
file. Additionally, the configuration expects an array of scripts that are
|
||||
desired for the pseudo-releases. For ``artist`` in particular, keep in mind that
|
||||
even pseudo-releases might specify it with the original script, so you should
|
||||
also configure import :ref:`languages` to give artist aliases more priority.
|
||||
Therefore, the minimum configuration for this plugin looks like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
|
@ -39,10 +39,10 @@ Therefore, the minimum configuration for this plugin looks like this:
|
|||
scripts:
|
||||
- Latn
|
||||
|
||||
Note that the `search_limit` configuration applies to the initial search for
|
||||
official releases, and that the `data_source` in the database will be
|
||||
"MusicBrainz". Nevertheless, `data_source_mismatch_penalty` must also be
|
||||
specified under `mbpseudo` if desired (see also
|
||||
Note that the ``search_limit`` configuration applies to the initial search for
|
||||
official releases, and that the ``data_source`` in the database will be
|
||||
"MusicBrainz". Nevertheless, ``data_source_mismatch_penalty`` must also be
|
||||
specified under ``mbpseudo`` if desired (see also
|
||||
:ref:`metadata-source-plugin-configuration`). An example with multiple data
|
||||
sources may look like this:
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ Default
|
|||
:default: yes
|
||||
|
||||
If a field name contains ``artist``, then any lowercase ``the`` will be
|
||||
capitalized. Useful for bands with `The` as part of the proper name,
|
||||
capitalized. Useful for bands with ``The`` as part of the proper name,
|
||||
like ``Amyl and The Sniffers``.
|
||||
|
||||
.. conf:: all_caps
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ def create_rst_replacements() -> list[Replacement]:
|
|||
refs = get_refs()
|
||||
|
||||
def make_ref_link(ref_id: str, name: str | None = None) -> str:
|
||||
if ref_id.endswith("-cmd"):
|
||||
name = f"{ref_id.removesuffix('-cmd')} command"
|
||||
ref = refs[ref_id]
|
||||
return rf"`{name or ref.name} <{ref.url}>`_"
|
||||
|
||||
|
|
@ -118,13 +120,14 @@ def create_rst_replacements() -> list[Replacement]:
|
|||
lambda m: explicit_replacements.get(m[0], m[0]),
|
||||
),
|
||||
# Replace Sphinx directives by documentation URLs, e.g.,
|
||||
# :ref:`/plugins/autobpm` -> [AutoBPM Plugin](DOCS/plugins/autobpm.html)
|
||||
# :ref:`/plugins/autobpm` -> [AutoBPM Plugin](DOCS/plugins/autobpm.html) # noqa: E501
|
||||
# :ref:`list-cmd` -> [list command](DOCS/reference/cli.html#list-cmd)
|
||||
(
|
||||
r":(?:ref|doc|class|conf):`+(?:([^`<]+)<)?/?([\w.:/_-]+)>?`+",
|
||||
r":(?:ref|doc|class|conf):`+~?(?:([^`<]+)<)?/?([\w.:/_-]+)>?`+",
|
||||
lambda m: make_ref_link(m[2], m[1]),
|
||||
),
|
||||
# Convert command references to documentation URLs
|
||||
# `beet move` or `move` command -> [import](DOCS/reference/cli.html#import)
|
||||
# `beet move` or `move` command -> [move command](DOCS/reference/cli.html#move-cmd) # noqa: E501
|
||||
(
|
||||
rf"`+beet ({commands})`+|`+({commands})`+(?= command)",
|
||||
lambda m: make_ref_link(f"{m[1] or m[2]}-cmd"),
|
||||
|
|
@ -139,14 +142,9 @@ def create_rst_replacements() -> list[Replacement]:
|
|||
]
|
||||
|
||||
|
||||
MD_REPLACEMENTS: list[Replacement] = [
|
||||
(r"^(\w[^\n]{,80}):(?=\n\n[^ ])", r"### \1"), # format section headers
|
||||
(r"^(\w[^\n]{81,}):(?=\n\n[^ ])", r"**\1**"), # and bolden too long ones
|
||||
(r"### [^\n]+\n+(?=### )", ""), # remove empty sections
|
||||
]
|
||||
order_bullet_points = partial(
|
||||
re.compile(r"(\n- .*?(?=\n(?! *(-|\d\.) )|$))", flags=re.DOTALL).sub,
|
||||
lambda m: "\n- ".join(sorted(m.group().split("\n- "))),
|
||||
lambda m: "\n- ".join(sorted(m.group().split("\n- "), key=str.lower)),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -165,13 +163,21 @@ def update_changelog(text: str, new: Version) -> str:
|
|||
Unreleased
|
||||
----------
|
||||
|
||||
New features:
|
||||
..
|
||||
New features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Bug fixes:
|
||||
..
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
For packagers:
|
||||
..
|
||||
For plugin developers
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Other changes:
|
||||
..
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
{new_header}
|
||||
{"-" * len(new_header)}
|
||||
|
|
@ -247,9 +253,6 @@ def changelog_as_markdown(rst: str) -> str:
|
|||
|
||||
md = rst2md(rst)
|
||||
|
||||
for pattern, repl in MD_REPLACEMENTS:
|
||||
md = re.sub(pattern, repl, md, flags=re.M | re.DOTALL)
|
||||
|
||||
# order bullet points in each of the lists alphabetically to
|
||||
# improve readability
|
||||
return order_bullet_points(md)
|
||||
|
|
|
|||
|
|
@ -238,7 +238,17 @@ cmd = "ruff check --config=pyproject.toml"
|
|||
|
||||
[tool.poe.tasks.lint-docs]
|
||||
help = "Lint the documentation"
|
||||
shell = "sphinx-lint --enable all --disable default-role $(git ls-files '*.rst')"
|
||||
interpreter = "bash"
|
||||
shell = """
|
||||
set -o pipefail
|
||||
files=$(git ls-files '*.rst')
|
||||
|
||||
grep -Eno ' `[^`][^`]+`[^_]' $files |
|
||||
sed 's/ .*/ Use double backticks for inline literal (double-backticks-required)/' && failed=1
|
||||
sphinx-lint --enable all --disable default-role $files || failed=1
|
||||
|
||||
exit ${failed:-0}
|
||||
"""
|
||||
|
||||
[tool.poe.tasks.update-dependencies]
|
||||
help = "Update dependencies to their latest versions."
|
||||
|
|
|
|||
|
|
@ -20,12 +20,19 @@ pytestmark = pytest.mark.skipif(
|
|||
|
||||
@pytest.fixture
|
||||
def rst_changelog():
|
||||
return """New features:
|
||||
return """
|
||||
Unreleased
|
||||
----------
|
||||
|
||||
New features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
- :doc:`/plugins/substitute`: Some substitute
|
||||
multi-line change.
|
||||
:bug:`5467`
|
||||
- :ref:`list-cmd` Update.
|
||||
- |BeetsPlugin| Some plugin change.
|
||||
- See :class:`~beetsplug._utils.musicbrainz.MusicBrainzAPI` for documentation.
|
||||
|
||||
You can do something with this command:
|
||||
|
||||
|
|
@ -33,7 +40,8 @@ You can do something with this command:
|
|||
|
||||
$ do-something
|
||||
|
||||
Bug fixes:
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
- Some fix that refers to an issue.
|
||||
:bug:`5467`
|
||||
|
|
@ -53,12 +61,14 @@ Bug fixes:
|
|||
2. Second
|
||||
and some details
|
||||
|
||||
Section naaaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmeeeeeeeeeeeeeee with over 80
|
||||
characters:
|
||||
Long parapgraph naaaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmeeeeeeeeeeeeeee ending
|
||||
with a colon:
|
||||
|
||||
Empty section:
|
||||
.. For plugin developers
|
||||
.. ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Other changes:
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
- Changed ``bitesize`` label to ``good first issue``. Our `contribute`_ page is now
|
||||
automatically populated with these issues. :bug:`4855`
|
||||
|
|
@ -68,23 +78,28 @@ Other changes:
|
|||
2.1.0 (November 22, 2024)
|
||||
-------------------------
|
||||
|
||||
Bug fixes:
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
||||
- Fixed something."""
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def md_changelog():
|
||||
return r"""### New features
|
||||
return r"""# Unreleased
|
||||
|
||||
## New features
|
||||
|
||||
- [beets.plugins.BeetsPlugin](https://beets.readthedocs.io/en/stable/api/generated/beets.plugins.BeetsPlugin.html#beets.plugins.BeetsPlugin) Some plugin change.
|
||||
- [list command](https://beets.readthedocs.io/en/stable/reference/cli.html#list-cmd) Update.
|
||||
- [Substitute Plugin](https://beets.readthedocs.io/en/stable/plugins/substitute.html): Some substitute multi-line change. :bug: (#5467)
|
||||
- [list](https://beets.readthedocs.io/en/stable/reference/cli.html#list-cmd) Update.
|
||||
- See [beetsplug.\_utils.musicbrainz.MusicBrainzAPI](https://beets.readthedocs.io/en/stable/api/generated/beetsplug._utils.musicbrainz.MusicBrainzAPI.html#beetsplug._utils.musicbrainz.MusicBrainzAPI) for documentation.
|
||||
|
||||
You can do something with this command:
|
||||
|
||||
$ do-something
|
||||
|
||||
### Bug fixes
|
||||
## Bug fixes
|
||||
|
||||
- Another fix with an enumerated list
|
||||
1. First and some details
|
||||
|
|
@ -96,15 +111,15 @@ You can do something with this command:
|
|||
- First nested bullet point with some text that wraps to the next line
|
||||
- Second nested bullet point
|
||||
|
||||
**Section naaaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmeeeeeeeeeeeeeee with over 80 characters**
|
||||
Long parapgraph naaaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmeeeeeeeeeeeeeee ending with a colon:
|
||||
|
||||
### Other changes
|
||||
## Other changes
|
||||
|
||||
- Changed `bitesize` label to `good first issue`. Our [contribute](https://github.com/beetbox/beets/contribute) page is now automatically populated with these issues. :bug: (#4855)
|
||||
|
||||
# 2.1.0 (November 22, 2024)
|
||||
|
||||
### Bug fixes
|
||||
## Bug fixes
|
||||
|
||||
- Fixed something.""" # noqa: E501
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue