From c01257d6ae05fab32b46825711b5cc27df971bb9 Mon Sep 17 00:00:00 2001 From: Aetf Date: Mon, 13 Jun 2022 23:37:42 -0700 Subject: [PATCH] build: automatically extract release note from NEWS upon releasing --- .github/workflows/release.yml | 17 +++---------- tools/extract_release_note.py | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 14 deletions(-) create mode 100755 tools/extract_release_note.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 076dc76..714cf03 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,17 +1,3 @@ -# The way this works is a little weird. But basically, the create-release job -# runs purely to initialize the GitHub release itself. Once done, the upload -# URL of the release is saved as an artifact. -# -# The build-release job runs only once create-release is finished. It gets -# the release upload URL by downloading the corresponding artifact (which was -# uploaded by create-release). It then builds the release executables for each -# supported platform and attaches them as release assets to the previously -# created release. -# -# The key here is that we create the release only once. -# -# Adapted from: https://github.com/BurntSushi/ripgrep/blob/master/.github/workflows/release.yml - name: release on: push: @@ -36,8 +22,11 @@ jobs: - name: Create source distribution # no unit tests yet run: meson dist -C builddir/ --no-tests + - name: Create release note + run: tools/extract_release_note.py NEWS ${{ github.workspace }}-release-note.txt - name: Release uses: softprops/action-gh-release@v1 with: files: builddir/meson-dist/* + body_path: ${{ github.workspace }}-release-note.txt diff --git a/tools/extract_release_note.py b/tools/extract_release_note.py new file mode 100755 index 0000000..3a06eaf --- /dev/null +++ b/tools/extract_release_note.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2022 Aetf +# +# SPDX-License-Identifier: MIT +import re +import inspect + +PTN_RELEASE_NOTE = re.compile(r'^CHANGES WITH.+$([\s\S]+?)^CHANGES WITH.+$', re.MULTILINE) + + +def extract(src: str) -> str: + """Find section between the first and the next 'CHANGES WITH xx:' lines, + and strip common prefix whitespace + """ + m = PTN_RELEASE_NOTE.search(src) + if m is not None: + return inspect.cleandoc(m.group(1)) + '\n' + else: + return '' + + +def main(): + import argparse + import sys + + parser = argparse.ArgumentParser() + parser.add_argument( + 'src', + type=argparse.FileType('r'), + nargs='?', + help='input NEWS', + default=sys.stdin, + ) + parser.add_argument( + 'dest', + type=argparse.FileType('w'), + nargs='?', + help='output', + default=sys.stdout, + ) + args = parser.parse_args() + + args.dest.write(extract(args.src.read())) + + +if __name__ == '__main__': + main()