From 79404f7ffc99a331e89a719af009dc62d6283783 Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Sat, 15 Jun 2024 17:35:05 -0700 Subject: [PATCH] releng: automatically add to the summary page Also delete the obsolescent maintainers/release-notes script that is unmaintained. Change-Id: I3f4a75d790e8e00e970358ca8f32e8295c91aac3 --- maintainers/release-notes | 179 -------------------------------------- releng/__init__.py | 2 + releng/create_release.xsh | 52 ++--------- releng/release_notes.py | 81 +++++++++++++++++ 4 files changed, 88 insertions(+), 226 deletions(-) delete mode 100755 maintainers/release-notes create mode 100644 releng/release_notes.py diff --git a/maintainers/release-notes b/maintainers/release-notes deleted file mode 100755 index 51864cbc2..000000000 --- a/maintainers/release-notes +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i bash ../shell.nix -I nixpkgs=channel:nixos-unstable-small -# ^^^^^^^ -# Only used for bash. shell.nix goes to the flake. - -# --- CONFIGURATION --- - -# This does double duty for -# - including rl-next -# - marking where to insert new links (right after) -SUMMARY_MARKER_LINE='release-notes/rl-next.md' - -# --- LIB --- - -log() { - echo 1>&2 "release-notes:" "$@" -} -logcmd() { - local cmd="$1" - shift - logcmd2 "$cmd" "${*@Q}" "$cmd" "$@" -} -logcmd2() { - local fakecmd="$1" - local fakeargs="$2" - shift - shift - printf 1>&2 "release-notes: \033[34;1m$fakecmd\033[0m " - echo "$fakeargs" 1>&2 - "$@" -} -die() { - # ANSI red - printf 1>&2 "release-notes: \033[31;1merror:\033[0m" - echo 1>&2 "" "$@" - exit 1 -} -confirm() { - local answer - echo 1>&2 "$@" "[y/n]" - read -r answer - case "$answer" in - y|Y|yes|Yes|YES) - return 0 - ;; - n|N|no|No|NO) - return 1 - ;; - *) - echo 1>&2 "please answer y or n" - confirm "$@" - ;; - esac -} -report_done() { - logcmd2 "git" "show" git -c pager.show=false show - printf 1>&2 "release-notes: \033[32;1mdone\033[0m\n" -} - -# --- PARSE ARGS --- - -if [[ $# -gt 0 ]]; then - die "Release notes takes no arguments, but make sure to set VERSION." -fi - -# --- CHECKS --- - -if [[ ! -e flake.nix ]] || [[ ! -e .git ]]; then - die "must run in repo root" - exit 1 -fi - -# repo must be clean -if ! git diff --quiet; then - die "repo is dirty, please commit or stash changes" -fi - -if ! git diff --quiet --cached; then - die "repo has staged changes, please commit or stash them" -fi - -if ! grep -F "$SUMMARY_MARKER_LINE" doc/manual/src/SUMMARY.md >/dev/null; then - # would have been nice to catch this early, but won't be worth the extra infra - die "SUMMARY.md is missing the marker line '$SUMMARY_MARKER_LINE', which would be used for inserting a new release notes page. Please fix the script." -fi - -if [[ ! -n "${VERSION:-}" ]]; then - die "please set the VERSION environment variable before invoking this script" - exit 1 -fi - -# version_major_minor: MAJOR.MINOR -# version_full: MAJOR.MINOR.PATCH -# IS_PATCH: true if this is a patch release; append instead of create -if grep -E '^[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then - log 'is minor' - IS_PATCH=false - version_full="$VERSION.0" - version_major_minor="$VERSION" -elif grep -E '^[0-9]+\.[0-9]+\.0$' <<< "$VERSION" >/dev/null; then - log 'is minor (.0)' - IS_PATCH=false - version_full="$VERSION" - version_major_minor="$(echo "$VERSION" | sed -e 's/\.0$//')" -elif grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' <<< "$VERSION" >/dev/null; then - log 'is patch' - IS_PATCH=true - version_full="$VERSION" - version_major_minor="$(echo "$VERSION" | sed -e 's/\.[0-9]*$//')" -else - die "VERSION must be MAJOR.MINOR[.PATCH], where each is a number, e.g. 2.20 or 2.20.1 (VERSION was set to $VERSION)" -fi - -unset VERSION - -log "version_major_minor=$version_major_minor" -log "version_full=$version_full" -log "IS_PATCH=$IS_PATCH" - -basename=rl-${version_major_minor}.md -file=doc/manual/src/release-notes/$basename - -if ! $IS_PATCH; then - if [[ -e $file ]]; then - die "release notes file $file already exists. If you'd like to make a minor release, pass a patch version, e.g. 2.20.1" - fi -fi - -# --- DEFAULTS --- - -if [[ ! -n "${DATE:-}" ]]; then - DATE="$(date +%Y-%m-%d)" - log "DATE not set, using $DATE" -fi - -case "$DATE" in - [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) - ;; - *) - die "DATE must be YYYY-MM-DD, e.g. 2021-12-31 (DATE was set to $DATE)" - ;; -esac - -# --- DO THE WORK --- - -# menu -title="Release $version_major_minor ($DATE)" -# section on page -section_title="Release $version_full ($DATE)" - -( - # TODO add minor number, and append? - echo "# $section_title" - echo - build-release-notes --change-authors doc/manual/change-authors.yml doc/manual/rl-next -) | tee -a $file - -log "Wrote $file" - -if ! $IS_PATCH; then - NEW_SUMMARY_LINE=" - [$title](release-notes/$basename)" - - # find the marker line, insert new link after it - escaped_marker="$(echo "$SUMMARY_MARKER_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')" - escaped_line="$(echo "$NEW_SUMMARY_LINE" | sed -e 's/\//\\\//g' -e 's/ /\\ /g')" - logcmd sed -i -e "/$escaped_marker/a $escaped_line" doc/manual/src/SUMMARY.md -fi - -for f in doc/manual/rl-next/*.md; do - if [[ config != "$(basename $f)" ]]; then - logcmd git rm $f - fi -done - -logcmd git add $file doc/manual/src/SUMMARY.md -logcmd git status -logcmd git commit -m "release notes: $version_full" - -report_done diff --git a/releng/__init__.py b/releng/__init__.py index 179ea3e2b..65f8476af 100644 --- a/releng/__init__.py +++ b/releng/__init__.py @@ -15,6 +15,7 @@ from . import version from . import cli from . import docker from . import docker_assemble +from . import release_notes from . import gitutils @@ -77,3 +78,4 @@ def reload(): importlib.reload(docker) importlib.reload(docker_assemble) importlib.reload(gitutils) + importlib.reload(release_notes) diff --git a/releng/create_release.xsh b/releng/create_release.xsh index 242286f6c..874f71a77 100644 --- a/releng/create_release.xsh +++ b/releng/create_release.xsh @@ -6,12 +6,14 @@ from pathlib import Path import tempfile import hashlib import datetime + from . import environment from .environment import RelengEnvironment from . import keys from . import docker from .version import VERSION, RELEASE_NAME, MAJOR from .gitutils import verify_are_on_tag, git_preconditions +from . import release_notes $RAISE_SUBPROC_ERROR = True $XONSH_SHOW_TRACEBACK = True @@ -169,51 +171,7 @@ def make_artifacts_dir(eval_result, d: Path): def prepare_release_notes(): - print('[+] Preparing release notes') - RELEASE_NOTES_PATH = Path('doc/manual/rl-next') - - if RELEASE_NOTES_PATH.is_dir(): - notes_body = subprocess.check_output(['build-release-notes', '--change-authors', 'doc/manual/change-authors.yml', 'doc/manual/rl-next']).decode() - else: - # I guess nobody put release notes on their changes? - print('[-] Warning: seemingly missing any release notes, not worrying about it') - notes_body = '' - - rl_path = Path(f'doc/manual/src/release-notes/rl-{MAJOR}.md') - - existing_rl = '' - try: - with open(rl_path, 'r') as fh: - existing_rl = fh.read() - except FileNotFoundError: - pass - - date = datetime.datetime.now().strftime('%Y-%m-%d') - - minor_header = f'# Lix {VERSION} ({date})' - - header = f'# Lix {MAJOR} "{RELEASE_NAME}"' - if existing_rl.startswith(header): - # strip the header off for minor releases - lines = existing_rl.splitlines() - header = lines[0] - existing_rl = '\n'.join(lines[1:]) - else: - header += f' ({date})\n\n' - - header += '\n' + minor_header + '\n' - - notes = header - notes += notes_body - notes += "\n\n" - notes += existing_rl - - # make pre-commit happy about one newline - notes = notes.rstrip() - notes += "\n" - - with open(rl_path, 'w') as fh: - fh.write(notes) + rl_path = release_notes.build_release_notes_to_file() commit_msg = textwrap.dedent("""\ release: release notes for {VERSION} @@ -221,8 +179,8 @@ def prepare_release_notes(): {RELENG_MSG} """).format(VERSION=VERSION, RELENG_MSG=RELENG_MSG) - git add @(rl_path) - git rm doc/manual/rl-next/*.md + git add @(rl_path) @(release_notes.SUMMARY) + git rm --ignore-unmatch 'doc/manual/rl-next/*.md' git commit -m @(commit_msg) diff --git a/releng/release_notes.py b/releng/release_notes.py new file mode 100644 index 000000000..0861e8d4e --- /dev/null +++ b/releng/release_notes.py @@ -0,0 +1,81 @@ +from pathlib import Path +import subprocess +import datetime + +from .version import MAJOR, VERSION, RELEASE_NAME + +MANUAL = Path('doc/manual') +RELEASE_NOTES_BASE = MANUAL / 'src/release-notes' +VERSION_RL = RELEASE_NOTES_BASE / f'rl-{MAJOR}.md' +SUMMARY = MANUAL / 'src/SUMMARY.md' + +def add_to_summary(date: str): + # N.B: This kind of duplicates gitutils.is_maintenance_branch, but it's a more clear + # check that allows potentially releasing a -rc without release notes being + # moved, then in .0 actually move the release notes in place. + if VERSION_RL.exists(): + return + + MARKER = '