forked from docker-library/official-images
-
Notifications
You must be signed in to change notification settings - Fork 1
/
test-pr.sh
executable file
·217 lines (185 loc) · 5.82 KB
/
test-pr.sh
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/bin/bash
set -eo pipefail
# TODO something clever with this pattern to get the exact list of _tags_ which have changed, not just repos:
#format='{{ range .Entries }}{{ join " " (join ":" $.RepoName (.Tags | first)) .GitRepo .GitFetch .GitCommit .Directory }}{{ "\n" }}{{ end }}'
#comm -13 \
# <(bashbrew cat -f "$format" https://github.com/docker-library/official-images/raw/master/library/docker | sort) \
# <(bashbrew cat -f "$format" https://raw.githubusercontent.com/infosiftr/stackbrew/d92ffa4b5f8a558c22c5d0a7e0f33bff8fae990b/library/docker | sort) \
# | cut -d' ' -f1
# make sure we can GTFO
trap 'echo >&2 Ctrl+C captured, exiting; exit 1' SIGINT
# start with an error if Docker isn't working...
docker version > /dev/null
dir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
usage() {
cat <<-EOUSAGE
usage: $0 [PR number] [repo[:tag]]
ie: $0 1024
$0 9001 debian php django
$0 0 hylang # special case that runs against local directory
This script builds and tests the specified pull request to official-images and
provides ouput in markdown for commenting on the pull request.
EOUSAGE
}
pull="$1"
shift || { usage >&2 && exit 1; }
if [ -z "$BASHBREW_SECOND_STAGE" ]; then
dockerRepo='oisupport/bashbrew'
dockerBase="$dockerRepo:base"
dockerImage="$dockerRepo:test-pr"
bashbrewVersion="$(< "$dir/bashbrew-version")"
docker build -t "$dockerBase" --pull "https://github.com/docker-library/bashbrew.git#v$bashbrewVersion" > /dev/null
docker build -t "$dockerImage" "$dir" > /dev/null
args=( --init )
if [ "$pull" = '0' ]; then
args+=( --name "bashbrew-test-local-$RANDOM" )
else
args+=( --name "bashbrew-test-pr-$pull" )
fi
args+=(
-v /var/run/docker.sock:/var/run/docker.sock
--group-add 0
-v /etc/passwd:/etc/passwd:ro
-v /etc/group:/etc/group:ro
)
if getent group docker &> /dev/null; then
args+=( --group-add "$(getent group docker | cut -d: -f3)" )
fi
# if we don't have DOCKER_HOST set, let's bind-mount cache for speed!
if [ -z "$DOCKER_HOST" ]; then
export BASHBREW_CACHE="${BASHBREW_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/bashbrew}" # resolve path to current "host-side" cache directory
mkdir -p "$BASHBREW_CACHE" # ensure it's created by our user, not root
export BASHBREW_CACHE="$(cd "$BASHBREW_CACHE" && pwd -P)" # readlink -f
args+=(
-v "$BASHBREW_CACHE":/bashbrew-cache
-e BASHBREW_CACHE=/bashbrew-cache
# make sure our user in the container can read it
--group-add "$(stat -c '%g' "$BASHBREW_CACHE")"
)
else
dockerGid="$(
docker run -i --rm "${args[@]}" "$dockerImage" sh -e <<-'EOSH'
exec 2>/dev/null
stat -c '%g' /var/run/docker.sock \
|| getent group docker | cut -d: -f3
EOSH
)" || true
if [ "$dockerGid" ]; then
args+=( --group-add "$dockerGid" )
fi
fi
args+=(
--user "$(id -u)":"$(id -g)"
$(id -G | xargs -n1 echo --group-add)
-e BASHBREW_SECOND_STAGE=1
)
for e in "${!BASHBREW_@}"; do
case "$e" in
BASHBREW_SECOND_STAGE|BASHBREW_CACHE|BASHBREW_LIBRARY) ;;
*)
args+=( -e "$e" )
;;
esac
done
cmd=( ./test-pr.sh "$pull" "$@" )
if [ -t 0 ] && [ -t 1 ]; then
# only add "-t" if we have a TTY
args+=( -t )
fi
exec docker run -i --rm "${args[@]}" "$dockerImage" "${cmd[@]}"
fi
if [ -d .git ]; then
echo >&2 'error: something has gone horribly wrong; .git already exists'
echo >&2 ' why do you have BASHBREW_SECOND_STAGE set?'
exit 1
fi
if [ "$pull" = '0' ]; then
commit='FAKE'
else
dir="$(mktemp -d)"
trap "rm -rf '$dir'" EXIT
cd "$dir"
# TODO we only have "git version 2.4.1" which doesn't support "clone -q" :(
git init -q .
git remote add origin https://github.com/docker-library/official-images.git
git fetch -q origin
git reset -q --hard origin/master
git config user.name 'nobody'
git config user.email '[email protected]'
git fetch -q origin "pull/$pull/head:pr-$pull"
git merge -q --no-edit "pr-$pull" > /dev/null
commit="$(git log -1 --format=format:%h "pr-$pull")"
fi
export BASHBREW_LIBRARY="$PWD/library"
if [ "$#" -eq 0 ]; then
IFS=$'\n'
files=( $(git diff --name-only origin/master...HEAD -- library | xargs -n1 basename) )
unset IFS
# TODO narrow this down into groups of the exact tags for each image that changed >:)
else
files=( "$@" )
fi
if [ ${#files[@]} -eq 0 ]; then
echo >&2 'no files in library/ changed in PR #'"$pull"
exit 0
fi
join() {
sep="$1"
arg1="$2"
shift 2
echo -n "$arg1"
[ $# -gt 0 ] && printf "${sep}%s" "$@"
}
IFS=$'\n'
files=( $(bashbrew list --repos --uniq --build-order "${files[@]}") )
unset IFS
echo 'Build test of' '#'"$pull"';' "$commit"';' '`'"${BASHBREW_ARCH:-amd64}"'`' '(`'"$(join '`, `' "${files[@]}")"'`):'
declare -A failedBuild=() failedTests=()
for img in "${files[@]}"; do
IFS=$'\n'
uniqImgs=( $(bashbrew list --uniq --build-order "$img") )
uniqImgs=( $(bashbrew cat --format '{{ if .TagEntry.HasArchitecture arch }}{{ $.RepoName }}:{{ .TagEntry.Tags | first }}{{ end }}' "${uniqImgs[@]}") ) # filter to just the set supported by the current BASHBREW_ARCH
unset IFS
echo
echo '```console'
for uniqImg in "${uniqImgs[@]}"; do
imgRepo="${uniqImg%%:*}"
echo
echo '$ bashbrew build' "$uniqImg"
if bashbrew build --pull=missing "$uniqImg"; then
echo
echo '$ test/run.sh' "$uniqImg"
if ! ./test/run.sh "$uniqImg"; then
failedTests[$imgRepo]+=" $uniqImg"
fi
else
failedBuild[$imgRepo]+=" $uniqImg"
fi
echo
done
echo '```'
done
echo
if [ "${#failedBuild[@]}" -gt 0 ]; then
echo 'The following images failed to build:'
echo
for repo in "${!failedBuild[@]}"; do
echo '- `'"$repo"'`:'
for img in ${failedBuild[$repo]}; do
echo ' - `'"$img"'`'
done
done
echo
fi
if [ "${#failedTests[@]}" -gt 0 ]; then
echo
echo 'The following images failed at least one test:'
echo
for repo in "${!failedTests[@]}"; do
echo '- `'"$repo"'`:'
for img in ${failedTests[$repo]}; do
echo ' - `'"$img"'`'
done
done
echo
fi