forked from django-cms/django-cms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake-changelog
executable file
·189 lines (140 loc) · 5.41 KB
/
make-changelog
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/bin/bash
# This script will take the last CHANGELOG.rst, pull information from the commit logs since last tagged version
# and update the content to create dedicated sections
SCRIPTS=$(dirname "$(realpath "$0")")
#shellcheck disable=SC1090
source "${SCRIPTS}/functions"
# Scope used in this script
declare -A SCOPES_HEADINGS
declare -a SCOPES
SCOPES=("feat" "security" "fix" "style" "refactor" "tools")
SCOPES_HEADINGS["feat"]="Features:"
SCOPES_HEADINGS["fix"]="Bug Fixes:"
SCOPES_HEADINGS["security"]="Security Updates:"
SCOPES_HEADINGS["style"]="Styles:"
SCOPES_HEADINGS["refactor"]="Refactoring and Cleanups:"
SCOPES_HEADINGS["tools"]="Internal Tools:"
# argument checks
if [ -z "$1" ] ; then
echo "Usage $0 <version> [base_version]"
echo
echo "Update the CHANGELOG.rst to create <version>"
echo "Version can be X.Y.Zsuffix"
echo "suffix can be rc, or anything, X,Y,Z are numbers"
exit 1
fi
FULL_VERSION="$1"
# extracting version from the FULL_VERSION, and sanity checks
check_version_string "${FULL_VERSION}"
VERSION=$(get_main_version "${FULL_VERSION}")
VERSUFFIX=$(get_version_suffix "${FULL_VERSION}")
# extracting the base version from changelog
OLD_FULL_VERSION="$2"
if [ -z "${OLD_FULL_VERSION}" ]; then
OLD_FULL_VERSION=$(grep -vi "unreleased\|unpublished" CHANGELOG.rst | awk '/^[0-9]+\.[0-9]+\.[0-9] \(.+\)$/ { print $1; nextfile }')
else
check_version_string "${OLD_FULL_VERSION}"
fi
# shellcheck disable=SC2001
OLD_VERSION=$(get_main_version "${OLD_FULL_VERSION}")
# shellcheck disable=SC2001
# Sanity checks
if [ -z "$(git tag -l "${OLD_FULL_VERSION}")" ]; then
error "Can not find tag for version ${OLD_FULL_VERSION} aborting ..."
exit 1
fi
if [ "${FULL_VERSION}" = "${OLD_VERSION}" ]; then
error "New version must be different than old version!"
exit 1
fi
# Computing dates
if echo "${VERSUFFIX}" | grep -qi '^rc'; then
DATE="unpublished"
else
DATE=$(date +"%Y-%m-%d")
fi
title="${FULL_VERSION} (${DATE})"
#shellcheck disable=SC2001
line=$(echo "${title}" | sed 's/./=/g')
# Cutting the Changelog into OLD and CURRENT
legacy="$(mktemp)"
current="$(mktemp)"
awk -e "BEGIN {show=0} /^${OLD_FULL_VERSION} \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\$/ {show=1} {if (show==1) print; }" < CHANGELOG.rst > "${legacy}"
awk -e "/^${OLD_FULL_VERSION} \([0-9]{4}-[0-9]{2}-[0-9]{2}\)\$/ {nextfile} {print; }" < CHANGELOG.rst | awk -e '/^Statistics:$/ {nextfile} {print}' > "${current}"
LAST_FULL_VERSION=$(awk -e '/^[0-9]+\.[0-9]+\.[0-9].* \(.+\)$/ { print $1; nextfile }' < CHANGELOG.rst )
LAST_VERSION=$(get_main_version "${LAST_FULL_VERSION}")
# Sanity checks
if [ -z "$(git tag -l "${LAST_FULL_VERSION}")" ]; then
error "Can not find tag for version ${LAST_FULL_VERSION} aborting ..."
exit 1
fi
# making sure the headings are right:
if [ "${VERSION}" = "${LAST_VERSION}" ]; then
# releasing a golden release from RC, so we just change the version RC to the new one
sed -i "${current}" \
-e "/^${LAST_FULL_VERSION} (unpublished)$/a${title}" \
-e "/^${LAST_FULL_VERSION} (unpublished)$/a${line}" \
-e "/^${LAST_FULL_VERSION} (unpublished)$/,+1d" \
-e "s/(unpublished)/(${DATE})/"
else
# This is a first release (RC or equivalent),
# let's add some headings to be sure we got all of them right for next steps
sed -i "${current}" \
-e "/^Unreleased$/a${title}" \
-e "/^Unreleased$/a${line}" \
-e "/^Unreleased$/a
" \
-e "/^Unreleased$/aHighlights:" \
-e "/^Unreleased$/a-----------" \
-e "/^Unreleased$/,+1d" \
-e "s/(unpublished)/(${DATE})/"
fi
# computing / updating each section
for scope in "${SCOPES[@]}"; do
content=$(mktemp)
heading="${SCOPES_HEADINGS[$scope]}"
# only checking on the last version *in the changelog" (ex:rc1 to rc2, the changelog already includes old to rc1)
git log "${LAST_FULL_VERSION}.." --pretty="format:%s (%h) -- %aN" | grep -i "^${scope}:" | sed -e "s/^${scope}:/*/i" > "${content}"
if [ -z "$(cat "${content}")" ]; then
continue
fi
# making sure the heading is there:
if ! grep -q "^${heading}\$" "${current}"; then
# shellcheck disable=SC2129
echo "${heading}" >> "${current}"
# shellcheck disable=SC2001
echo "${heading}" | sed -e 's/./-/g' >> "${current}"
echo "" >> "${current}"
fi
sed -i "${current}" -e "/^${heading}\$/{N
r${content}
}"
rm "${content}"
done
# generating statistics
PR_NUMBER=$(git log --pretty=oneline "${OLD_FULL_VERSION}.." | wc -l)
cat >> "${current}" << EOF
Statistics:
-----------
This release includes ${PR_NUMBER} pull requests, and was created with the help of the following contributors (in alphabetical order):
EOF
while read -r name; do
count=$( git log "${OLD_FULL_VERSION}.." --pretty=format:"%aN" | grep -c "${name}" )
if [ "${count}" -gt 1 ]; then
pl="s"
else
pl=""
fi
echo "* ${name} (${count} pull request${pl})" >> "${current}"
done < <( git log "${OLD_FULL_VERSION}.." --pretty=format:"%aN" | sort -u)
# shellcheck disable=SC2129
cat >> "${current}" << EOF
With the review help of the following contributors:
EOF
git log "${OLD_FULL_VERSION}.." | grep Co-authored-by | sed -e 's/^ *Co-authored-by: /* /;s/ <.*//' | sort -u >> "${current}"
cat >> "${current}" << EOF
Thanks to all contributors for their efforts!
EOF
cat "${current}" "${legacy}" > CHANGELOG.rst
rm "${current}" "${legacy}"
# now computing sections