summaryrefslogtreecommitdiffstats
path: root/docs/scripts/release-note.sh
blob: f1a93137ac285f5f59a53accb81ed1033ea38bd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/bin/bash
# This script generates a release note.
# It prints information about breaking-changes first and the rest.
# The content is mostly based on `git log --oneline --since 202X-YY-ZZ`.

# Usage: the script takes one command-line argument that will be used on '-since' option of git command.
# As an example, you can run a script with a following command, and it will print commit titles between today and 2024-07-01.
# ```
# docs/scripts/release-note.sh 2024-07-01
# ```

# This script is supposed to work on all Windows based shell systems including WSL and git-bash.
# If you make any modifications, please test them, because CI doesn't test this script.

verbose=true
$verbose && echo "Reminder: PLEASE make sure your local repo is up-to-date before running the script." >&2

gh=""
for candidate in "$(which gh.exe)" "/mnt/c/Program Files/GitHub CLI/gh.exe" "/c/Program Files/GitHub CLI/gh.exe"
do
	if [ -x "$candidate" ]
	then
		gh="$candidate"
		break
	fi
done
if [ "x$gh" = "x" ] || ! [ -x "$gh" ]
then
	echo "File not found: gh.exe"
	echo "gh.exe can be downloaded from https://cli.github.com"
	exit 1
fi
$verbose && echo "gh.exe is found from: $gh" >&2

if [ "x$1" = "x" ]
then
	echo "This script requires 'since' information for git-log command."
	echo "Usage: $0 2024-07-30"
	exit 1
fi
since="$1"

commits="$(git log --oneline --since $since)"
commitsCount="$(echo "$commits" | wc -l)"

echo "=== Breaking changes ==="
breakingChanges=""
for i in $(seq $commitsCount)
do
	line="$(echo "$commits" | head -$i | tail -1)"

	# Get PR number from the git commit title
	pr="$(echo "$line" | grep '#[1-9][0-9][0-9][0-9][0-9]*' | sed 's|.* (\#\([1-9][0-9][0-9][0-9][0-9]*\))|\1|')"
	[ "x$pr" = "x" ] && break

	# Check if the PR is marked as a breaking change
	if "$gh" issue view $pr --json labels | grep -q 'pr: breaking change'
	then
		breakingChanges+="$line"
	fi
done
if [ "x$breakingChanges" = "x" ]
then
	echo "No breaking changes"
else
	echo "$breakingChanges"
fi
echo ""

echo "=== All changes for this release ==="
for i in $(seq $commitsCount)
do
	line="$(echo "$commits" | head -$i | tail -1)"

	result="$line"
	for dummy in 1
	do
		# Get PR number from the git commit title
		pr="$(echo "$line" | grep '#[1-9][0-9][0-9][0-9][0-9]*' | sed 's|.* (\#\([1-9][0-9][0-9][0-9][0-9]*\))|\1|')"
		[ "x$pr" = "x" ] && break

		# Mark breaking changes with "[BREAKING]"
		if "$gh" issue view $pr --json labels | grep -q 'pr: breaking change'
		then
			result="[BREAKING] $line"
		fi

		# Get the issue number for the PR
		body="$("$gh" issue view $pr --json body)"
		[ "x$body" = "x" ] && break
		issue="$(echo "$body" | grep '#[1-9][0-9][0-9][0-9][0-9]*' | sed 's|.*\#\([1-9][0-9][0-9][0-9][0-9]*\).*|\1|')"
		[ "x$issue" = "x" ] && break

		# Get the labels of the issue
		label="$("$gh" issue view $issue --json labels)"
		[ "x$label" = "x" ] && break

		# Get the goal type from the labels
		goal="$(echo "$label" | grep '"goal:' | sed 's|.*"goal:\([^"]*\)".*|\1|')"
		[ "x$goal" = "x" ] && break

		result+=" (#$issue:$goal)"
	done
	echo "$result"
done