Skip to content

Commit

Permalink
Merge pull request #285 from MichaelSasser/feature/#284-gen-release-body
Browse files Browse the repository at this point in the history
Generate the release body with a script
  • Loading branch information
MichaelSasser authored Nov 16, 2021
2 parents 8b7bc0c + 8c8904a commit fa0993a
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 29 deletions.
52 changes: 27 additions & 25 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,33 @@ jobs:
- name: Build project
run: poetry build

- name: Zip project
run: zip --junk-paths matrixctl.zip dist/* README.md LICENSE.txt

- name: Generate changelog_latest.rst from CHANGELOG.rst
run: python scripts/get_latest_release.py

- name: Convert from changelog_latest.rst to changelog_latest.md
uses: docker://pandoc/core:2.9
with:
args: >-
--output=chagelog_latest.md
--from rst
--to markdown
chagelog_latest.rst
- name: Create Release
uses: softprops/action-gh-release@v1
with:
prerelease: false
draft: false
name: Release ${{ github.ref }}
body_path: chagelog_latest.md
files: matrixctl.zip

- name: Delete temp files
run: rm -rf matrixctl.zip chagelog_latest.md chagelog_latest.rst

- name: pypi-publish
uses: pypa/[email protected]
with:
Expand All @@ -60,28 +87,3 @@ jobs:
# repository_url: # optional
# The target directory for distribution
# packages_dir: # optional, default is dist

- name: Zip project
run: zip --junk-paths matrixctl.zip dist/* README.md LICENSE.txt

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: true
prerelease: true

- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./matrixctl.zip
asset_name: matrixctl.zip
asset_content_type: application/zip
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/.vim

# Files produced by a script while running the script get_latest_release.py
# The latter file is used for as release message.
/chagelog_latest.rst
/chagelog_latest.md

# Created by https://www.toptal.com/developers/gitignore/api/vim,emacs,python
# Edit at https://www.toptal.com/developers/gitignore?templates=vim,emacs,python

Expand Down
Empty file added news/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions news/284.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generate the release body with a script while running the release action.
3 changes: 0 additions & 3 deletions news/templates/default.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{% if top_line %}
{{ top_line }}
{{ top_underline * ((top_line)|length)}}
{% elif versiondata.name %}
{{ versiondata.name }} {{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.name + versiondata.version + versiondata.date)|length + 4)}}
{% else %}
{{ versiondata.version }} ({{ versiondata.date }})
{{ top_underline * ((versiondata.version + versiondata.date)|length + 3)}}
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ filename = "CHANGELOG.rst"
issue_format = "`#{issue} <https://github.com/MichaelSasser/matrixctl/issues/{issue}>`_"
directory = "news/"
top_line = false
title_format = "{version} ({project_date})" # {name}
# title_format = "{version} ({project_date})" # {name}
all_bullets = true # make all fragments bullet points
wrap = true # Wrap text to 79 characters
template = "news/templates/default.rst"
Expand Down
134 changes: 134 additions & 0 deletions scripts/get_latest_release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env python3
# get_latest_release.py - A support script for the MatrixCtl project
# Copyright (c) 2021 Michael Sasser <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Use this script in GH actions, to get the latest changelog.
The script splits the CHANGELOG.rst by the headline including
the version (example: ``0.11.2 (2021-09-26)``) and date with a
regular expression.
The first list entry at index 0 is everything before the latest entry.
The second list entry at index 1 contains the headline like in the example
above.
The third list entry contains the body of the latest entry including the
underline of the first headline.
Notes
-----
- This script is not part of the source code of MatrixCtl. It is a release
helper script.
- After the script finished run the following command:
``pandoc chagelog_latest.rst --from rst --to markdown -o chagelog_latest.md``
"""


from __future__ import annotations

import logging
import re
import sys
import typing as t

from pathlib import Path


__author__: str = "Michael Sasser"
__email__: str = "[email protected]"
__version__: str = "0.1.0"


logger = logging.getLogger(__name__)

# Modified SemVer version pattern to account for the rest of the headline
# https://regex101.com/r/pOWOBM/1 # With match groups
# https://regex101.com/r/WiHlCF/1 # without
_VERSION_PATTERN: str = (
r"^((?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)"
r"(?:-(?:"
r"(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)"
r"(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?"
r"(?:\+(?:[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"
r"\s*\((?:\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]))\))$"
)

_HEADLINE: t.Pattern[str] = re.compile(_VERSION_PATTERN, re.MULTILINE)


def main(input_path: Path, output_path: Path) -> int:
"""Create a new file which only contains the latest changelog entry.
Attributes
----------
input_path : pathlib.Path
The input file as ``Path()``, which is a news file created by
towncrier.
output_path : pathlib.Path
The output file, which does not need to exist beforehand. The output
will be written to this file.
Returns
-------
return_code : int
The return code of the program.
- **0** - The program has successfully generated the outputfile.
- **1** - An I/O error occurred.
- **2** - The news file does not contain enough news entries.
"""
# Read CHANGELOG.rst
try:
with input_path.open() as fp:
found_headlines = _HEADLINE.split(fp.read())
except (OSError):
logger.fatal(f"Unable to read from the input file! {input_path =}")
return 1

# Check, that there are enough headlines to work with
if len(found_headlines) < 3:
logger.fatal(f"Unable to find enough headlines! {found_headlines =}")
return 2

entry: str = f"{found_headlines[1]}{found_headlines[2].rstrip()}"
logger.info("Latest entry:\n%s", entry)

# Write changelog_latest.rst
try:
with output_path.open("w") as fp:
fp.write(entry)
except (OSError):
logger.fatal(f"Unable to write to the output file! {output_path =}")
return 1

return 0


if __name__ == "__main__":
# setup logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(name)s:%(lineno)d %(levelname)s - %(message)s",
)

# The path to the project root
project_root_path: Path = Path(__file__).resolve().parent.parent

input_path: Path = project_root_path / "CHANGELOG.rst"
output_path: Path = project_root_path / "chagelog_latest.rst"

sys.exit(main(input_path, output_path))

# vim: set ft=python :

0 comments on commit fa0993a

Please sign in to comment.