aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-06-15 17:35:05 -0700
committerJade Lovelace <lix@jade.fyi>2024-06-15 18:46:18 -0700
commit79404f7ffc99a331e89a719af009dc62d6283783 (patch)
tree8f268ef534cb2fc4dc5810496a9e04040c78b524
parentf95a47e8c48a8b6eccc349d64aa5191a3618d7f4 (diff)
releng: automatically add to the summary page
Also delete the obsolescent maintainers/release-notes script that is unmaintained. Change-Id: I3f4a75d790e8e00e970358ca8f32e8295c91aac3
-rwxr-xr-xmaintainers/release-notes179
-rw-r--r--releng/__init__.py2
-rw-r--r--releng/create_release.xsh52
-rw-r--r--releng/release_notes.py81
4 files changed, 88 insertions, 226 deletions
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 = '<!-- RELENG-AUTO-INSERTION-MARKER'
+
+ new_lines = []
+ for line in SUMMARY.read_text().splitlines():
+ new_lines.append(line)
+ if MARKER in line:
+ indent, _, _ = line.partition(MARKER)
+ new_lines.append(f'{indent}- [Lix {MAJOR} ({date})](release-notes/rl-{MAJOR}.md)')
+
+ # make pre-commit happy about one newline
+ text = '\n'.join(new_lines).rstrip()
+ text += '\n'
+ SUMMARY.write_text(text)
+
+def build_release_notes_to_file():
+ date = datetime.datetime.now().strftime('%Y-%m-%d')
+ add_to_summary(date)
+
+ 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', RELEASE_NOTES_PATH]).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(RELEASE_NOTES_BASE / f'rl-{MAJOR}.md')
+
+ existing_rl = ''
+ try:
+ with open(rl_path, 'r') as fh:
+ existing_rl = fh.read()
+ except FileNotFoundError:
+ pass
+
+ 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)
+
+ return rl_path