-
Notifications
You must be signed in to change notification settings - Fork 656
Expand file tree
/
Copy pathshow-release-diffs.sh
More file actions
executable file
·158 lines (139 loc) · 5.27 KB
/
show-release-diffs.sh
File metadata and controls
executable file
·158 lines (139 loc) · 5.27 KB
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
#!/usr/bin/env bash
##
## Copyright © contributors to CloudNativePG, established as
## CloudNativePG a Series of LF Projects, LLC.
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
## SPDX-License-Identifier: Apache-2.0
##
## CloudNativePG - Show diffs from main for a release branch
##
## This is a helper script that prints the GitHub pull requests
## that are present in the trunk and not in this branch, and
## viceversa. It should be used to help maintainers spot any
## missed commit to be backported, while waiting for an automate
## procedure that issues PRs on all supported release branches.
## It also enables to compare the current branch with another
## one, by passing an optional parameter.
##
## You need to run this script from the release branch.
## The following example compares 1.16 branch with main:
##
## git checkout release-1.16
## ./hack/show-release-diffs.sh
##
## This example compares the current branch with 1.15:
##
## ./hack/show-release-diffs.sh release-1.15
set -o errexit -o nounset -o pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
cd "${REPO_ROOT}"
if [ "$#" -gt 2 ]; then
echo "Usage: hack/show-release-diffs.sh [branch]"
echo ""
echo "- [branch]: branch to compare with (default main)"
exit 1
fi
MAIN_BRANCH=${1:-main}
# Verify we are working on a clean directory
require_clean_work_tree () {
git rev-parse --verify HEAD >/dev/null || exit 1
git update-index -q --ignore-submodules --refresh
err=0
if ! git diff-files --quiet --ignore-submodules
then
echo >&2 "Cannot $1: You have unstaged changes."
err=1
fi
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
then
if [ $err = 0 ]
then
echo >&2 "Cannot $1: Your index contains uncommitted changes."
else
echo >&2 "Additionally, your index contains uncommitted changes."
fi
err=1
fi
if [ $err = 1 ]
then
# if there is a 2nd argument print it
test -n "${2+1}" && echo >&2 "$2"
exit 1
fi
}
_output_intermediate_csv () {
BRANCH=$1
while read -r r
do
ID=$(echo "$r" | cut -f 2 -d '[' | cut -f 1 -d ']')
MSG=$(echo "$r" | cut -f 2 -d ']')
# Skip lines that don't end with ')'
if [[ $MSG =~ \)$ ]]; then
PR=$(echo "$r" | rev | cut -f 1 -d '(' | rev | cut -f 1 -d ')' | cut -f 2 -d '#')
# Check PR is a number
if ! [[ "$PR" -eq "$PR" ]] 2> /dev/null; then
PR='-'
fi
else
PR='-'
fi
echo "${PR}|${ID}|${MSG## }"
done < <(grep -e "\[${BRANCH}[0-9~^]*\]" "$WORKDIR/show-branch.txt")
}
# Require to be in a release branch
require_clean_work_tree "release"
# Verify that you are in a release branch
if branch=$(git symbolic-ref --short -q HEAD) && [[ "$branch" == release-* ]]
then
echo "# Checking ${branch} vs ${MAIN_BRANCH}"
else
echo >&2 "You must be on a 'release-*' branch ($branch) to run differences with ${MAIN_BRANCH}"
exit 1
fi
WORKDIR=$(mktemp -d -t cnpg-XXXX)
trap 'rm -rf "$WORKDIR"' EXIT
git show-branch --current "${MAIN_BRANCH}" > "$WORKDIR/show-branch.txt"
_output_intermediate_csv "${MAIN_BRANCH}" | sort -nu > "$WORKDIR/${MAIN_BRANCH}.csv"
_output_intermediate_csv "$branch" | sort -nu > "$WORKDIR/$branch.csv"
# Prepare intermediate files
cut -f 1 -d '|' "$WORKDIR/${MAIN_BRANCH}.csv" > "$WORKDIR/${MAIN_BRANCH}-PR.txt"
cut -f 1 -d '|' "$WORKDIR/$branch.csv" > "$WORKDIR/$branch-PR.txt"
grep '^-|' "$WORKDIR/${MAIN_BRANCH}.csv" | cut -f 3 -d '|' | sort -u > "$WORKDIR/${MAIN_BRANCH}-noPR.txt"
grep '^-|' "$WORKDIR/$branch.csv" | cut -f 3 -d '|' | sort -u > "$WORKDIR/$branch-noPR.txt"
diff -B "$WORKDIR/${MAIN_BRANCH}-noPR.txt" "$WORKDIR/$branch-noPR.txt" > "$WORKDIR/manual-verification.txt"
# What's missing in the release
echo -e "\n## PRs that are missing in $branch but are in ${MAIN_BRANCH}\n"
i=0
while read -r pr
do
((i=i+1))
MSG=$(grep "^$pr|" "$WORKDIR/${MAIN_BRANCH}.csv" | cut -f 3 -d '|')
echo "$i. [$MSG](https://github.com/cloudnative-pg/cloudnative-pg/pull/$pr)"
done < <(diff -B "$WORKDIR/${MAIN_BRANCH}-PR.txt" "$WORKDIR/$branch-PR.txt" | grep '^<' | cut -f 2 -d ' ')
# What's in the release and not in ${MAIN_BRANCH}
echo -e "\n## PRs that are in $branch but not in ${MAIN_BRANCH}\n"
i=0
while read -r pr
do
((i=i+1))
MSG=$(grep "^$pr|" "$WORKDIR/$branch.csv" | cut -f 3 -d '|')
echo "$i. [$MSG](https://github.com/cloudnative-pg/cloudnative-pg/pull/$pr)"
done < <(diff -B "$WORKDIR/${MAIN_BRANCH}-PR.txt" "$WORKDIR/$branch-PR.txt" | grep '^>' | cut -f 2 -d ' ')
# Verify commits without a PR
if [ -s "$WORKDIR/manual-verification.txt" ]
then
echo -e "\n## Commits without a PR - please check\n"
cat "$WORKDIR/manual-verification.txt"
fi