forked from lix-project/lix
releng: automatically add to the summary page
Also delete the obsolescent maintainers/release-notes script that is
unmaintained.
Change-Id: I3f4a75d790e8e00e970358ca8f32e8295c91aac3
This commit is contained in:
parent
f95a47e8c4
commit
79404f7ffc
|
@ -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
|
|
|
@ -15,6 +15,7 @@ from . import version
|
||||||
from . import cli
|
from . import cli
|
||||||
from . import docker
|
from . import docker
|
||||||
from . import docker_assemble
|
from . import docker_assemble
|
||||||
|
from . import release_notes
|
||||||
from . import gitutils
|
from . import gitutils
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,3 +78,4 @@ def reload():
|
||||||
importlib.reload(docker)
|
importlib.reload(docker)
|
||||||
importlib.reload(docker_assemble)
|
importlib.reload(docker_assemble)
|
||||||
importlib.reload(gitutils)
|
importlib.reload(gitutils)
|
||||||
|
importlib.reload(release_notes)
|
||||||
|
|
|
@ -6,12 +6,14 @@ from pathlib import Path
|
||||||
import tempfile
|
import tempfile
|
||||||
import hashlib
|
import hashlib
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from . import environment
|
from . import environment
|
||||||
from .environment import RelengEnvironment
|
from .environment import RelengEnvironment
|
||||||
from . import keys
|
from . import keys
|
||||||
from . import docker
|
from . import docker
|
||||||
from .version import VERSION, RELEASE_NAME, MAJOR
|
from .version import VERSION, RELEASE_NAME, MAJOR
|
||||||
from .gitutils import verify_are_on_tag, git_preconditions
|
from .gitutils import verify_are_on_tag, git_preconditions
|
||||||
|
from . import release_notes
|
||||||
|
|
||||||
$RAISE_SUBPROC_ERROR = True
|
$RAISE_SUBPROC_ERROR = True
|
||||||
$XONSH_SHOW_TRACEBACK = True
|
$XONSH_SHOW_TRACEBACK = True
|
||||||
|
@ -169,51 +171,7 @@ def make_artifacts_dir(eval_result, d: Path):
|
||||||
|
|
||||||
|
|
||||||
def prepare_release_notes():
|
def prepare_release_notes():
|
||||||
print('[+] Preparing release notes')
|
rl_path = release_notes.build_release_notes_to_file()
|
||||||
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)
|
|
||||||
|
|
||||||
commit_msg = textwrap.dedent("""\
|
commit_msg = textwrap.dedent("""\
|
||||||
release: release notes for {VERSION}
|
release: release notes for {VERSION}
|
||||||
|
@ -221,8 +179,8 @@ def prepare_release_notes():
|
||||||
{RELENG_MSG}
|
{RELENG_MSG}
|
||||||
""").format(VERSION=VERSION, RELENG_MSG=RELENG_MSG)
|
""").format(VERSION=VERSION, RELENG_MSG=RELENG_MSG)
|
||||||
|
|
||||||
git add @(rl_path)
|
git add @(rl_path) @(release_notes.SUMMARY)
|
||||||
git rm doc/manual/rl-next/*.md
|
git rm --ignore-unmatch 'doc/manual/rl-next/*.md'
|
||||||
|
|
||||||
git commit -m @(commit_msg)
|
git commit -m @(commit_msg)
|
||||||
|
|
||||||
|
|
81
releng/release_notes.py
Normal file
81
releng/release_notes.py
Normal file
|
@ -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
|
Loading…
Reference in a new issue