]> git.ipfire.org Git - people/ms/nightly-builds.git/blame - build.sh
Do not leave build directory before all builds are done
[people/ms/nightly-builds.git] / build.sh
CommitLineData
fd9f9810
MT
1#!/bin/bash -l
2
3BASEDIR="/build/nightly"
d2b7a495 4LOCKFILE="/tmp/.nightly-builds.lock"
fd9f9810
MT
5
6UPLOAD_DIR="${BASEDIR}/upload"
7899475b 7UPLOAD_TO="pakfire@fs01.haj.ipfire.org:/pub/nightly"
00e27fa7 8RSYNC_ARGS=( "-avH" "--progress" "--delay-updates" )
fd9f9810 9
fd9f9810
MT
10extract_installer_from_iso() {
11 local dir="${1}"
12
13 local tmpdir="$(mktemp -d)"
14 mkdir -p "${dir}/images"
15
16 local file
17 for file in ${dir}/*.iso; do
18 if mount -o loop,ro "${file}" "${tmpdir}"; then
19 local f
20 for f in vmlinuz instroot; do
21 cp -f "${tmpdir}/boot/isolinux/${f}" "${dir}/images"
22 done
23 umount "${tmpdir}"
81a5283c
MT
24
25 local ext
26 for ext in "" ".md5"; do
27 ln -s --relative "${file}${ext}" \
28 "${dir}/images/installer.iso${ext}"
29 done
fd9f9810
MT
30 break
31 fi
32 done 2>/dev/null
33
34 rm -rf "${tmpdir}"
35}
36
e5c0113d
MT
37uriencode() {
38 local path="${1}"
39
40 local IFS="/"
41
42 local s
43 local segments=()
44 for s in ${path}; do
45 s="${s//'%'/%25}"
46 s="${s//' '/%20}"
47 s="${s//'"'/%22}"
48 s="${s//'#'/%23}"
49 s="${s//'$'/%24}"
50 s="${s//'&'/%26}"
51 s="${s//'+'/%2B}"
52 s="${s//','/%2C}"
53 s="${s//'/'/%2F}"
54 s="${s//':'/%3A}"
55 s="${s//';'/%3B}"
56 s="${s//'='/%3D}"
57 s="${s//'?'/%3F}"
58 s="${s//'@'/%40}"
59 s="${s//'['/%5B}"
60 s="${s//']'/%5D}"
61
62 segments+=( "${s}" )
63 done
64
65 echo "${segments[*]}"
66}
67
68send_email() {
69 local status="${1}"
70 local target="${2}"
71 local branch="${3}"
72 local commit="${4}"
73 local build="${5}"
74
75 sendmail -ti <<END
76From: IPFire Nightly Builder <nightly-builds@ipfire.org>
77To: Nightly Builds List <nightly-builds@lists.ipfire.org>
78Subject: [${status^^}] Nightly Build of ${branch} (${commit:0:7}) for ${target} on ${HOSTNAME}
79Date: $(date --rfc-2822)
80MIME-Version: 1.0
bb7411bd
MT
81Content-Type: text/plain; charset="utf-8"
82Content-Transfer-Encoding: 8bit
e5c0113d
MT
83
84https://nightly.ipfire.org$(uriencode "${build:${#UPLOAD_DIR}}")
85
86$(git log -1 "${commit}")
87
88https://git.ipfire.org/?p=ipfire-2.x.git;a=shortlog;h=${commit}
89
90$(<"${build}/build.log")
91END
92}
93
fd9f9810
MT
94build() {
95 local dir="${1}"
96 shift
97
fb8a369c
MT
98 # Check if this actually source of IPFire 2
99 [ -x "${dir}/make.sh" ] || return 1
100
fd9f9810
MT
101 pushd "${dir}"
102
103 local branch="$(git config build.branch)"
104 [ -z "${branch}" ] && branch="master"
105
106 local commit_old="$(git rev-parse HEAD)"
107 git fetch
108
ecab61ba
MT
109 # Search for the latest core branch
110 if [ "${branch}" = "core" ]; then
2272fea9 111 branch="$(git branch -r | awk -F/ '{ print $NF }' | grep ^core | sort --version-sort | tail -n1)"
ecab61ba
MT
112 fi
113
fd9f9810 114 local commit_new="$(git rev-parse origin/${branch})"
d1e3c705
MT
115
116 # If the branch was not updated, we won't build
117 if [ ! -e "${dir}/.force-build" ] && [ "${commit_old}" = "${commit_new}" ]; then
118 return 2
119 fi
fd9f9810 120
dc1916d9
MT
121 local current_branch="$(git rev-parse --abbrev-ref HEAD)"
122 if [ "${current_branch}" != "${branch}" ]; then
123 git checkout -b "${branch}" "${commit_new}"
124 fi
125
fd9f9810
MT
126 # Checkout the latest commit
127 git reset --hard "${commit_new}"
128
e685e88f 129 local now="$(git log --format="%ci" -1 "${commit_new}")"
fd9f9810 130
7e10f4db
MT
131 local target
132 for target in $(git config build.targets); do
133 local build_path="${UPLOAD_DIR}/${branch}/${now}-${commit_new:0:8}"
134 local build="${build_path}/${target}"
135 local status="failed"
136
137 # Remove marker
138 unlink "${dir}/.force-build"
139
140 # Ready for build: Download toolchain and sources
141 local action
142 for action in clean gettoolchain downloadsrc; do
143 if ! ./make.sh --target="${target}" "${action}"; then
144 touch "${dir}/.force-build"
145 continue
146 fi
147 done
148
149 # Execute the build
150 mkdir -p "${build}"
151 ./make.sh --target="${target}" build | tee "${build}/build.log"
152 local ret=${PIPESTATUS[0]}
153
154 # Save the changelog
155 git log -50 > "${build}/changelog.txt"
156
157 # Save the result
158 if [ "${ret}" = "0" ]; then
159 status="success"
160 touch "${build}/.success"
161
162 # Copy images
163 mv -v *.iso *.img.gz *.img.xz *.tar.bz2 *.md5 packages/ "${build}"
164 extract_installer_from_iso "${build}"
2272fea9 165 fi
7e10f4db 166 mv -v log/ "${build}"
2272fea9 167
7e10f4db
MT
168 # Cleanup the build environment
169 ./make.sh --target="${target}" clean
2272fea9 170
7e10f4db
MT
171 # Send an email notification
172 send_email "${status}" "${target}" "${branch}" "${commit_new}" "${build}"
2272fea9 173
7e10f4db
MT
174 # Upload the result
175 sync
7e10f4db 176 done
4821902d
MT
177
178 popd
fd9f9810
MT
179}
180
181sync() {
8e3d51d0
MT
182 # Do not attempt to upload anything if nothing exists
183 [ ! -d "${UPLOAD_DIR}" ] && return 0
fd9f9810 184
7899475b 185 # Acquire a Kerberos ticket for authentication
a55d5bff 186 kinit -k -t /etc/krb5.keytab "host/${HOSTNAME}"
7899475b 187
00e27fa7
MT
188 if rsync "${RSYNC_ARGS[@]}" "${UPLOAD_DIR}/" "${UPLOAD_TO}"; then
189 rm -rf "${UPLOAD_DIR}"
190 fi
fd9f9810
MT
191}
192
d2b7a495
MT
193is_locked() {
194 [ -e "${LOCKFILE}" ]
195}
196
197lock() {
198 touch "${LOCKFILE}"
199}
200
201unlock() {
202 rm -f "${LOCKFILE}"
203}
204
d2b7a495 205# Don't start again if the script is already running
b9def775
MT
206# or if an other build script is running
207if is_locked || pgrep make.sh >/dev/null; then
d2b7a495
MT
208 exit 0
209fi
210
211# Lock
212trap unlock EXIT
213lock
214
51ab69f5
MT
215for repo in ${BASEDIR}/*; do
216 [ -d "${repo}/.git" ] || continue
fd9f9810 217
a70eabe7 218 build "${repo}"
fd9f9810 219done
d2b7a495 220
555260fa
MT
221# Try to sync even nothing was built for retrying failed uploads
222sync
223
d2b7a495 224exit 0