This commit is contained in:
2026-06-14 19:09:18 +01:00
parent 14bd1a9271
commit 13fa90a0e9
3958 changed files with 999286 additions and 4 deletions
+271
View File
@@ -0,0 +1,271 @@
#! /usr/bin/env bash
# Copyright 2020, Mark Callow
# SPDX-License-Identifier: Apache-2.0
# Generate release notes from git log.
#
# mkrelnotes [-b] [-c] [-d] [-e] [-l] [-p <preface> [-t] <previous release tag> <release name>
#
# <previous release tag> is the name of the tag identifying the previous
# release. <this release> is the name to be given to the tag for the upcoming
# release. N.B. this tag cannot be created until after ther release notes
# have been generated and checked in. The release notes will include changes
# in the two-dot commit range <previous release tag>..HEAD.
#
# <preface> is inserted between the title and the detailed change list
# that is extracted with git log. It should be used to summarize
# new features and known issues using level 3 (###) headings for those
# sections.
#
# If -b is specified build system changes will be included in the
# release notes.
#
# If -c is specified any previous $RELNOTES_FILE will be appended, with the
# title lines stripped, to the release notes generated here, thus enabling
# cumulative release notes. Otherwise any previous $RELNOTES_FILE file is
# replaced.
#
# If -d is specified details of the changes will be included, otherwise only
# the summary is shown.
#
# If -e is specified changes to `external` packages will be included in the
# release notes.
#
# If -l is specified changes to the load test apps will be included in the
# release notes.
#
# If -i is specified the release notes will be built interactively. That is,
# for each change the user will be asked if it should be included.
#
# If -t is specified changes to the tests will be included in the release notes
# otherwise they are omitted.
# Depth of this script relative to the project root
depth=..
RELNOTES_FILE="RELEASE_NOTES.md"
# The author name in a commit message comes from whatever the user
# has set as user.name in their git config. It usually has no relation
# to their GitHub username so putting an @ before it has no meaning.
#
SUMMARY_FORMAT_W_AUTH="* %s (%h) (%an)"
SUMMARY_FORMAT="* %s (%h)"
function commit_summary() {
local hash=$1
local summary
local prjson
pr=$(git log --oneline -n 1 $hash | grep -o -E "\(#[0-9]+\)" | grep -o -E "[0-9]+")
# Even in PR's the commit has the full name of the user as known to GitHub,
# not their GitHub username. We want to use the GitHub username so there will
# be a link back to the person. We can retrieve this by requesting detailed
# info from GitHub via HTTPS.
summary=$(git log --pretty="$SUMMARY_FORMAT" -n 1 $hash)
if [ -z "$pr" ]; then
cmtjson="$(curl --netrc https://api.github.com/repos/KhronosGroup/KTX-Software/commits/$hash 2>/dev/null)"
author="$(echo $cmtjson | jq -r -e '.author.login')"
else
prjson="$(curl --netrc https://api.github.com/repos/KhronosGroup/KTX-Software/pulls/$pr 2>/dev/null)"
author="$(echo $prjson | jq -r -e '.user.login')"
fi
summary+=" (@$author)"
# \_ avoids confusion with _ for italics.
echo "$summary" | sed -e 's/_/\\_/g'
if [ -n "$includeDetails" ]; then
body="$(git log --pretty="%b" -n 1 $hash | sed -E 's/^(.+)/ \1/')"
if [ -n "$body" ]; then
echo ""
# Remove CR which some multi-line commit bodies contain for unknown
# reasons.
echo "$body" | tr -d \\r | sed -e 's/_/\\_/g'
fi
fi
}
function revisions_in () {
local range=$1; shift
git rev-list $range $*
}
function log() {
local part=$1; shift
local log
for rev in $(revisions_in "$range" $*); do
if [ -n "$interactive" ]; then
git log -1 $rev > /dev/tty
processed=0
while [ $processed -eq 0 ]; do
echo "Include this change? [d,i,s,?] ?" > /dev/tty
read -n 1 opt
echo "" > /dev/tty
case $opt in
d)
git show --pretty=oneline $rev > /dev/tty
;;
[is])
processed=1
;;
?)
echo "d - show diff of this commit" > /dev/tty
echo "i - include this commit." > /dev/tty
echo "s - skip this commit." > /dev/tty
echo "? - display this help message." > /dev/tty
;;
*)
echo "Unknown option: $opt. Try again." > /dev/tty
;;
esac
done
case $opt in
i)
log+="$(commit_summary $rev)"
;;
esac
else
log+="$(commit_summary $rev)"
fi
# For reasons I do not understand I have been completely unable to prevent
# trailing newlines from being removed from the output of commit_summary
# so resorting to ANSI-C quoting to insert some new lines between summaries.
log+=$'\n\n'
done
if [ -n "$log" ]; then
echo "### $part"
echo
echo "$log"
echo
fi
}
function usage() {
cat << EOU
Usage: $0 [-b] [-c] [-d] [-i] [-p <preface>] [-t] <previous release tag> <release name>"
Options:
-b Include build system changes.
-c Make cumulative release notes.
-d Include details of changes. If absent only the summary is shown.
-e Include changes to `external` packages.
-i Interactively select the changes to include.
-l Include changes to load test apps. Ignored if -t specified.
-p <preface>
Include the file <preface> before the list of changes.
-t Include test changes.
EOU
}
while true; do
case $1 in
-b) includeBuildSystem="true"; shift ;;
-c) cumulative="true"; shift;;
-d) includeDetails="true"; shift ;;
-e) includeExternal="true"; shift ;;
-i) interactive="true"; shift;;
-l) includeLoadtests="true"; shift ;;
-p) preface=$2; shift 2 ;;
-t) includeTests="true"; shift ;;
-*) usage; exit 1 ;;
*) break ;;
esac
done
if [ $# -ne 2 ]; then
echo "$0: Need previous release tag and this release name, e.g. 'v4.0.0 v4.0.1'."
exit 1
else
range=$1..
lastrel=$1
thisrel=$2
fi
#if [ $# -ne 1 ]; then
# echo '$0: Need a two-dot revision range, e.g, `v4.0.0..v4.0.1`.'
# exit 1
#else
# range=$1
# if ! [[ $range =~ ([[:alnum:][:punct:]]+)\.\.([[:alnum:]][[:alnum:][:punct:]]*)? ]]; then
# echo "$0: <revision range> is not a two-dot range."
# exit 1
# else
# lastrel=${BASH_REMATCH[1]}
# thisrel=${BASH_REMATCH[2]}
# if [ -z "$lastrel" ]; then
# lastrel=HEAD
# fi
# fi
#fi
# Change to the project root
cd $(dirname $0)/$depth
SAVED_RELNOTES_FILE="${RELNOTES_FILE%.md}-$lastrel.md"
# Save or remove old relnotes.
if [ -f $RELNOTES_FILE ]; then
if [ -z "$cumulative" ]; then
rm $RELNOTES_FILE;
else
mv $RELNOTES_FILE $SAVED_RELNOTES_FILE
fi
fi
# Read preface file before cd.
if [ -n "$preface" ]; then
PREFACE=$(cat $preface)
fi
lib=$(log libktx lib)
tools=$(log Tools tools)
js_binding=$(log "JS Bindings" interface/js_binding)
java_binding=$(log "Java Bindings" interface/java_binding)
python_binding=$(log "Python Bindings" interface/python_binding)
if [ -n "$includeBuildSystem" ]; then
build=$(log "Build Scripts and CMake files" scripts $(find . \( -path ./build -o -path ./.git -o -path ./external -o -path ./other_include \) -prune -false -o -name CMakeLists.txt -o -name '*.cmake'))
fi
if [ -n "$includeExternal" ]; then
external=$(log "External Package Dependencies" external)
fi
if [ -n "$includeTests" ]; then
tests=$(log "Tests" tests)
elif [ -n "$includeLoadtests" ]; then
loadtests=$(log "Load test apps" tests/loadtests)
fi
cat > $RELNOTES_FILE <<- EOF
$(date '+<!-- Copyright %Y, The Khronos Group Inc. -->')
<!-- SPDX-License-Identifier: Apache-2.0 -->
Release Notes
=============
## Version ${thisrel#v}
$PREFACE
### Changes since $lastrel (by part)
$lib
$tools
$js_binding
$java_binding
$python_binding
$external
$tests
$loadtests
$build
EOF
if [ -f $SAVED_RELNOTES_FILE ]; then
awk '! /Release Notes/ && ! /======/ && ! /<!-- Copyright/ && ! /<!-- SPDX/ {print}' $SAVED_RELNOTES_FILE >> $RELNOTES_FILE
rm $SAVED_RELNOTES_FILE
fi