#!/bin/sh set -eu # Print the Keep-a-Changelog section for a release tag, so CI can use it as the # body of the Gitea release page without re-implementing CHANGELOG parsing. # # Run as `scripts/release-notes.sh `. A leading `v` is tolerated so both # `v1.2.3` and `1.2.3` match the `## [1.2.3]` heading. Prints to stdout and # exits non-zero when the tag has no section, so a release can never publish # with an empty body. # # Why: development/publishing.md ยง Release notes are extracted from the changelog. TAG="${1:-}" CHANGELOG="${CHANGELOG:-CHANGELOG.md}" if [ -z "${TAG}" ]; then echo "Error: usage: $0 " >&2 exit 1 fi if [ ! -f "${CHANGELOG}" ]; then echo "Error: ${CHANGELOG} not found." >&2 exit 1 fi # `v1.2.3` and `1.2.3` are the same release; the heading only ever uses the # bare version. VERSION="${TAG#v}" awk -v version="${VERSION}" ' # A new section ends the one we are printing (or is the one we want). /^## \[/ { if (found) exit heading = $0 sub(/^## \[/, "", heading) sub(/\].*$/, "", heading) if (heading == version) found = 1 next } # Link-reference definitions live at the bottom of the file and are never # part of the section body. Stopping here keeps the last release notes # from picking them up (there is no following heading to stop at). /^\[[^]]+\]:/ { exit } found { if ($0 ~ /^[[:space:]]*$/) { # Buffer blank lines so trailing ones at the end of the section # are dropped instead of leaking into the release body. if (started) pending = pending $0 "\n" } else { printf "%s%s\n", pending, $0 pending = "" started = 1 } } END { if (!found) { printf "Error: no CHANGELOG section for [%s].\n", version > "/dev/stderr" exit 1 } } ' "${CHANGELOG}"