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
|
#!/bin/bash
#
# We fail CI if the word "F I X M E" is detedcted, as a whole word,
# in any case. The word is not matched if there are word-characters
# abutted to it.
set -e
set -o pipefail
BASE_BRANCHES='main'
repo=$(
perl -MTOML -we '
use strict;
undef $/;
my $toml = from_toml(<STDIN>);
print $toml->{package}{repository} // die;
' <Cargo.toml
)
repo_host=$(
perl -we '
$ARGV[0] =~ m{^https://[-.0-9a-z]+/}
or die "bad repository url";
print "$&\n";
' "$repo"
)
echo "Cargo.toml package.repository: $repo"
echo "Upstream repository instance: $repo_host"
# Ideally we would somehow find which repo and branch this was going
# to be an MR for. But, in fact, we can't even find out which
# repo this repo it was forked from, in a principled way, with env vars.
# This approach to finding the upstream will have to do for now.
case "$CI_PROJECT_URL" in
"$repo_host"*)
# `package.repository` in `Cargo.toml` is
# on same instance as this CI job.
#
# Use $BASE_BRANCHES on `package.repository` as the baseline.
git remote rm upstream.tmp >/dev/null 2>&1 ||:
git remote rename upstream upstream.tmp >/dev/null 2>&1 ||:
git remote add upstream "$repo"
ORIGIN=upstream
;;
'')
# Not running in CI, use a guess at the baseline:
# $BASE_BRANCHES at whatever `origin` points to.
ORIGIN=origin
;;
*)
# We are apparently running in a different instance to upstream.
# It's not clear what this testing would mean.
# Should it use our repo URL? That would be quite exciting.
echo >&2 "CI_PROJECT_URL $CI_PROJECT_URL not recognised!"
exit 4
;;
esac
echo "Baseline repo remote $ORIGIN, at:"
git remote get-url "$ORIGIN"
tlref () {
echo "refs/remotes/$ORIGIN/$tbranch"
}
x () {
echo "+ $*"
"$@"
}
git_checkout_maybe_clean () {
x=$1; shift
if
$x git checkout -q "$1"
then :
else
echo "Checkout failed, trying with git clean and git reset"
x git clean -xdff
x git reset --hard
x git checkout -q "$1"
fi
}
old_branch=$(git symbolic-ref -q HEAD || test $? = 1)
restore_old_branch () {
case "$old_branch" in
refs/heads/*)
git_checkout_maybe_clean '' "${old_branch#refs/heads/}" ||
echo '*** Failed to return to original branch ***'
;;
*)
echo "*** Was not originally on a branch, HEAD changed! ***"
;;
esac
}
trap 'restore_old_branch' 0
refspecs=()
for tbranch in $BASE_BRANCHES; do
refspecs+=(+"refs/heads/$tbranch:$(tlref)")
done
# If you try to unshallow a repo that's already complete, you get
# an error! Hence this. Not all versions of git-rev-parse
# understand this option; we err on the side of trying the unshallow.
if [ "x$(git rev-parse --is-shallow-repository)" != xfalse ]; then
# TODO really we want something like the converse of
# git fetch --shallow-exclude
# but it doesn't seem to exist.
git fetch --unshallow "$ORIGIN" "${refspecs[@]}"
fi
for tbranch in $BASE_BRANCHES; do
trevlist="$(tlref)..HEAD"
tcount=$(git rev-list --count "$trevlist")
printf "HEAD is %3d commits ahead of %s\n" "$tcount" "$tbranch"
if [ "$count" ] && [ $count -le $tcount ]; then continue; fi
count=$tcount
branch=$tbranch
revlist=$trevlist
done
echo "Testing every commit not already on $branch"
commits=$(git rev-list --reverse "$revlist")
i=0
for commit in $commits; do
banner='##############################'
printf "|\n%s %d/%d %s\n|\n" "$banner" "$i" "$count" "$banner"
git log -n1 "$commit" | sed 's/^/| /'
echo '|'
git_checkout_maybe_clean x "$commit"
if x "$@"; then :; else
rc="$?"
printf "
|
========================= Failed after $i/$count =========================
|
Earliest broken commit is
"
git --no-pager log -n1 --pretty=oneline "$commit"
exit "$rc"
fi
i=$(( $i + 1 ))
done
echo "|
$banner ok $banner
|"
rc=0
|