-
Notifications
You must be signed in to change notification settings - Fork 26
/
update_gitlab-ci.sh
executable file
·274 lines (233 loc) · 7.58 KB
/
update_gitlab-ci.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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#!/bin/bash
# -*- mode: Shell-script; sh-basic-offset: 4; -*-
set -e
set -o pipefail
base_dir=$(pwd)
br_path=${base_dir}/buildroot
frag_dir=${base_dir}/frags
git_current_branch=$(git symbolic-ref -q --short HEAD)
debug=0
opt_arch="*"
opt_libc="*"
opt_variant="*"
opt_target="no_push"
opt_brtree=""
opt_version=""
function clean_up {
echo "Catching signal, cleaning up"
cd ${base_dir}
rm -rf ${frag_dir}
echo "Checkouting to original branch: ${git_current_branch}"
git checkout $git_current_branch
echo "Exiting with code 1"
exit 1
}
trap clean_up SIGHUP SIGINT SIGTERM
function show_help {
cat - <<EOF
Usage: $0 -n version [-a arch] [-l libc] [-v variant] [-t target] [-dh]
-h show this help and exit
-d debug output
-t target defines what to do:
no_push: just prepare the config files and the commit in
the build branch, but don't push (do not trigger the
Gitlab CI). Useful for debugging.
ci_debug: just launch the ci jobs, but does not really
compiles the toolchains. Useful for CI debugging.
<folder_name>: launch the ci jobs and compiles the toolchains, then
send them in the <folder_name>.
The webpage searches for toolchains in 'releases'.
This option defaults to no_push in order not to trigger builds
by accident or misuse.
-b tree-ish checkout Buildroot to that tree-ish object
-n version version string appended to tarball name
-a arch specify architecture to build (see \`ls configs/arch/*\`)
-l libc specify libc to use (see \`ls configs/libc/*\`)
-v variant specify variant to build (see \`ls configs/version/*\`)
EOF
}
function check_config {
local config_file=$1
local release_name=$2
cp ${config_file} ${br_path}/.config
make -C ${br_path} olddefconfig 1>/dev/null 2>&1
local libc_name=$(grep "^BR2_TOOLCHAIN_BUILDROOT_LIBC=\".*\"" ${br_path}/.config |
sed 's/BR2_TOOLCHAIN_BUILDROOT_LIBC="\(.*\)"/\1/')
sort ${br_path}/.config > /tmp/sorted.config
sort ${config_file} > /tmp/sortedfragmentfile
local rejects_file=$(mktemp)
comm -23 /tmp/sortedfragmentfile /tmp/sorted.config > ${rejects_file}
# If the reject file is empty, the configuration is valid
if [ $(cat ${rejects_file} | wc -l) -eq 0 ]; then
rm ${rejects_file}
return 0
fi
# Check if the reject matches an exception file. If so, the
# configuration is considered valid.
for exception in $(ls -1 configs/exceptions/); do
local exception_m=${exception%.config}
if [[ $name = $exception_m ]]; then
if cmp -s configs/exceptions/${exception} ${rejects_file}; then
rm ${rejects_file}
return 0
fi
fi
done
if [ $debug -eq 1 ]; then
echo ""
cat ${rejects_file}
fi
rm ${rejects_file}
return 1
}
function gen_fragment {
local arch_name=$1
local libc_name=$2
local variant_name=$3
local name="${arch_name}-${libc_name}-${variant_name}"
local release_name="${arch_name}--${libc_name}--${variant_name}"
local extras=""
local optionals=""
local disables=""
local config_file=$(mktemp)
cat configs/arch/${arch}.config \
configs/libc/${libc}.config \
configs/version/${variant}.config \
configs/common.config > ${config_file}
for extra in $(ls -1 ${base_dir}/configs/extra/); do
local extra_m=${extra%.config}
if [[ $name = $extra_m ]]; then
extras="${extras} ${extra}"
cat "${base_dir}/configs/extra/$extra" >> ${config_file}
fi
done
if check_config ${config_file} ${release_name}; then
for optional in $(ls -1 ${base_dir}/configs/optionals/); do
local optional_m=${optional%.config}
if [[ $name = $optional_m ]]; then
optionals="${optionals} ${optional}"
cat "${base_dir}/configs/optionals/$optional" >> ${config_file}
fi
done
for disable in $(ls -1 ${base_dir}/configs/disables/); do
local disable_m=${disable%.config}
if [[ $name = $disable_m ]]; then
disables="${disables} ${disable}"
cat "${base_dir}/configs/disables/$disable" >> ${config_file}
fi
done
mv ${config_file} ${frag_dir}/${release_name}.config
printf "\e[0;32m - %s-%s-%s: OK\e[m\n" ${arch_name} ${libc_name} ${variant_name}
printf " extras: ${extras}\n"
printf " optionals: ${optionals}\n"
printf " disables: ${disables}\n"
else
printf "\e[0;31m - %s-%s-%s: NOK\e[m\n" ${arch_name} ${libc_name} ${variant_name}
printf " extras: ${extras}\n"
rm ${config_file}
fi
}
function prepare_git_branch {
local branch="$1"
git branch -q -D ${branch} || true
git checkout -b ${branch}
mkdir -p ${frag_dir}
}
function submit_git_branch {
local branch="$1"
cat .gitlab-ci.yml - > .gitlab-ci.yml.tmp <<EOF
variables:
TOOLCHAIN_BUILDER_TARGET: "${opt_target}"
TOOLCHAIN_BUILDER_BRTREE: "${opt_brtree}"
TOOLCHAIN_BUILDER_VERSION: "${opt_version}"
EOF
mv .gitlab-ci.yml.tmp .gitlab-ci.yml
git add frags/
git add -f .gitlab-ci.yml
git commit -m "Build bot: trigger new builds"
if [ "$opt_target" != "no_push" ]; then
git push -u -f [email protected]:buildroot.org/toolchains-builder.git ${branch}
fi
git checkout $git_current_branch
}
function delete_git_branch {
local branch="$1"
git checkout $git_current_branch
git branch -D ${branch}
}
function handle_special {
local git_build_branch="builds-$(date +%Y-%m-%d--%H-%M-%S)"
prepare_git_branch ${git_build_branch}
for special in $(ls ./configs/special/*.config); do
special_name=$(basename ${special} .config)
cp ${special} ${frag_dir}/
done
submit_git_branch ${git_build_branch}
}
function handle_normal {
local git_build_branch="builds-$(date +%Y-%m-%d--%H-%M-%S)"
prepare_git_branch ${git_build_branch}
for arch_config in $(ls ./configs/arch/${opt_arch}.config); do
local arch=$(basename ${arch_config} .config)
for libc_config in $(ls ./configs/libc/${opt_libc}.config); do
local libc=$(basename ${libc_config} .config)
for variant_config in $(ls ./configs/version/${opt_variant}.config); do
local variant=$(basename ${variant_config} .config)
gen_fragment ${arch} ${libc} ${variant}
done
done
done
nfrags=$(ls -1 ${frag_dir} | wc -l)
if test ${nfrags} -eq 0; then
delete_git_branch ${git_build_branch}
else
submit_git_branch ${git_build_branch}
fi
}
function main {
# Get buildroot if it's not done to check the configurations
if [ ! -d ${br_path} ] ; then
git clone https://github.com/bootlin/buildroot-toolchains.git ${br_path}
fi
# Grab the specified version of Buildroot
pushd ${br_path}
git fetch origin
git reset --hard ${opt_brtree}
popd
if test "${opt_variant}" = "special" ; then
handle_special
else
handle_normal
fi
}
while getopts "a:l:v:t:b:n:dh" opt; do
case "$opt" in
d) debug=1
;;
a) opt_arch=$OPTARG
;;
l) opt_libc=$OPTARG
;;
v) opt_variant=$OPTARG
;;
b) opt_brtree=$OPTARG
;;
t) opt_target=$OPTARG
;;
n) opt_version=$OPTARG
;;
*|h|\?)
show_help
exit 0
;;
esac
done
if [ -z $opt_version ] ; then
echo "ERROR: -n option is mandatory"
exit 1
fi
if [ -z $opt_brtree ] ; then
echo "ERROR: -b option is mandatory"
exit 1
fi
main