Skip to content

Commit 700b64e

Browse files
author
Mukund Lakshman
committed
CI: Verify commits in beta & stable are in upstream branches.
Closes rust-lang#74721
1 parent 2451f42 commit 700b64e

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

.github/workflows/ci.yml

+9
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ jobs:
128128
- name: ensure line endings are correct
129129
run: src/ci/scripts/verify-line-endings.sh
130130
if: success() && !env.SKIP_JOB
131+
- name: ensure backported commits are in upstream branches
132+
run: src/ci/scripts/verify-backported-commits.sh
133+
if: success() && !env.SKIP_JOB
131134
- name: run the build
132135
run: src/ci/scripts/run-build-from-ci.sh
133136
env:
@@ -499,6 +502,9 @@ jobs:
499502
- name: ensure line endings are correct
500503
run: src/ci/scripts/verify-line-endings.sh
501504
if: success() && !env.SKIP_JOB
505+
- name: ensure backported commits are in upstream branches
506+
run: src/ci/scripts/verify-backported-commits.sh
507+
if: success() && !env.SKIP_JOB
502508
- name: run the build
503509
run: src/ci/scripts/run-build-from-ci.sh
504510
env:
@@ -609,6 +615,9 @@ jobs:
609615
- name: ensure line endings are correct
610616
run: src/ci/scripts/verify-line-endings.sh
611617
if: success() && !env.SKIP_JOB
618+
- name: ensure backported commits are in upstream branches
619+
run: src/ci/scripts/verify-backported-commits.sh
620+
if: success() && !env.SKIP_JOB
612621
- name: run the build
613622
run: src/ci/scripts/run-build-from-ci.sh
614623
env:

src/ci/github-actions/ci.yml

+4
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ x--expand-yaml-anchors--remove:
206206
run: src/ci/scripts/verify-line-endings.sh
207207
<<: *step
208208

209+
- name: ensure backported commits are in upstream branches
210+
run: src/ci/scripts/verify-backported-commits.sh
211+
<<: *step
212+
209213
- name: run the build
210214
run: src/ci/scripts/run-build-from-ci.sh
211215
env:
+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/bin/bash
2+
# Ensure commits in beta are in master & commits in stable are in beta + master.
3+
set -euo pipefail
4+
IFS=$'\n\t'
5+
6+
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
7+
8+
# We don't care about commits that predate this automation check, so we pass a
9+
# `<limit>` argument to `git cherry`.
10+
BETA_LIMIT="53fd98ca776cb875bc9e5514f56b52eb74f9e7a9"
11+
STABLE_LIMIT="a178d0322ce20e33eac124758e837cbd80a6f633"
12+
13+
verify_backported_commits_main() {
14+
ci_base_branch=$(ciBaseBranch)
15+
16+
if [[ "$ci_base_branch" != "beta" && "$ci_base_branch" != "stable" ]]; then
17+
echo 'Skipping. This is only run when merging to the beta or stable branches.'
18+
exit 0
19+
fi
20+
21+
echo 'git: unshallowing the repository so we can check commits'
22+
git fetch \
23+
--no-tags \
24+
--no-recurse-submodules \
25+
--progress \
26+
--prune \
27+
--unshallow
28+
29+
if [[ $ci_base_branch == "beta" ]]; then
30+
verify_cherries master "$BETA_LIMIT" \
31+
|| exit 1
32+
33+
elif [[ $ci_base_branch == "stable" ]]; then
34+
(verify_cherries master "$STABLE_LIMIT" \
35+
& verify_cherries beta "$STABLE_LIMIT") \
36+
|| exit 1
37+
38+
fi
39+
}
40+
41+
# Verify all commits in `HEAD` are backports of a commit in <upstream>. See
42+
# https://git-scm.com/docs/git-cherry for an explanation of the arguments.
43+
#
44+
# $1 = <upstream>
45+
# $2 = <limit>
46+
verify_cherries() {
47+
# commits that lack a `backport-of` comment.
48+
local no_backports=()
49+
# commits with an incorrect `backport-of` comment.
50+
local bad_backports=()
51+
52+
commits=$(git cherry "origin/$1" HEAD "$2")
53+
54+
if [[ -z "$commits" ]]; then
55+
echo "All commits in \`HEAD\` are present in \`$1\`"
56+
return 0
57+
fi
58+
59+
commits=$(echo "$commits" | grep '^\+' | cut -c 3-)
60+
61+
while read sha; do
62+
# Check each commit in <current>..<upstream>
63+
backport_sha=$(get_backport "$sha")
64+
65+
if [[ -z "$backport_sha" ]]; then
66+
no_backports+=("$sha")
67+
continue
68+
fi
69+
70+
if ! is_in_master "$backport_sha"; then
71+
bad_backports+=("$sha")
72+
continue
73+
fi
74+
75+
echo "\`$sha\` backports \`$backport_sha\`"
76+
done <<< "$commits"
77+
78+
failure=0
79+
80+
if [ ${#no_backports[@]} -ne 0 ]; then
81+
echo 'Error: Could not find backports for all commits.'
82+
echo
83+
echo 'All commits in \`HEAD\` are required to have a corresponding upstream commit.'
84+
echo 'It looks like the following commits:'
85+
echo
86+
for commit in "${no_backports[@]}"; do
87+
echo " $commit"
88+
done
89+
echo
90+
echo "do not match any commits in \`$1\`. If this was intended, add the text"
91+
echo '\`backport-of: <SHA of a commit already in master>\` somewhere in the'
92+
echo 'message of each of these commits.'
93+
echo
94+
failure=1
95+
fi
96+
97+
if [ ${#bad_backports[@]} -ne 0 ]; then
98+
echo 'Error: Found incorrectly marked commits.'
99+
echo
100+
echo 'The following commits:'
101+
echo
102+
for commit in "${bad_backports[@]}"; do
103+
echo " $commit"
104+
done
105+
echo
106+
echo 'have commit messages marked \`backport-of: <SHA>\`, but the SHA is not in'
107+
echo '\`master\`.'
108+
echo
109+
failure=1
110+
fi
111+
112+
return $failure
113+
}
114+
115+
# Get the backport of a commit, or empty string if it does not exist.
116+
#
117+
# $1 = <sha>
118+
get_backport() {
119+
git show -s --format=%B "$1" \
120+
| sed -n 's/^.*backport-of:\s\?\([a-f0-9]\+\).*/\1/p'
121+
}
122+
123+
# Check if a commit is in master.
124+
#
125+
# $1 = <sha>
126+
is_in_master() {
127+
git merge-base --is-ancestor "$1" origin/master 2> /dev/null
128+
}
129+
130+
verify_backported_commits_main

0 commit comments

Comments
 (0)