-
Notifications
You must be signed in to change notification settings - Fork 14
/
ci-library.sh
247 lines (220 loc) · 7.58 KB
/
ci-library.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
#!/bin/bash
# Continuous Integration Library for RI2
# Author: Renato Silva <[email protected]>
# Author: Qian Hong <[email protected]>
# Enable colors
normal=$(tput sgr0)
red=$(tput setaf 1)
green=$(tput setaf 2)
cyan=$(tput setaf 6)
# Basic status function
_status() {
local type="${1}"
local status="${package:+${package}: }${2}"
local items=("${@:3}")
case "${type}" in
failure) local -n nameref_color='red'; title='[RI2 CI] FAILURE:' ;;
success) local -n nameref_color='green'; title='[RI2 CI] SUCCESS:' ;;
message) local -n nameref_color='cyan'; title='[RI2 CI]'
esac
printf "\n${nameref_color}${title}${normal} ${status}\n\n"
printf "${items:+\t%s\n}" "${items:+${items[@]}}"
}
# Convert lines to array
_as_list() {
local -n nameref_list="${1}"
local filter="${2}"
local strip="${3}"
local lines="${4}"
local result=1
nameref_list=()
while IFS= read -r line; do
test -z "${line}" && continue
result=0
[[ "${line}" = ${filter} ]] && nameref_list+=("${line/${strip}/}")
done <<< "${lines}"
return "${result}"
}
# Changes since master or from head
_list_changes() {
local list_name="${1}"
local filter="${2}"
local strip="${3}"
local git_options=("${@:4}")
_as_list "${list_name}" "${filter}" "${strip}" "$(git log "${git_options[@]}" upstream/master.. | sort -u)" ||
_as_list "${list_name}" "${filter}" "${strip}" "$(git log "${git_options[@]}" HEAD^.. | sort -u)"
}
# Get package information
_package_info() {
local package="${1}"
local properties=("${@:2}")
for property in "${properties[@]}"; do
local -n nameref_property="${property}"
nameref_property=($(
MINGW_PACKAGE_PREFIX='mingw-w64' source "${package}/PKGBUILD"
declare -n nameref_property="${property}"
echo "${nameref_property[@]}"))
done
}
# Package provides another
_package_provides() {
local package="${1}"
local another="${2}"
local pkgname provides
_package_info "${package}" pkgname provides
for pkg_name in "${pkgname[@]}"; do [[ "${pkg_name}" = "${another}" ]] && return 0; done
for provided in "${provides[@]}"; do [[ "${provided}" = "${another}" ]] && return 0; done
return 1
}
# Add package to build after required dependencies
_build_add() {
local package="${1}"
local depends makedepends
for sorted_package in "${sorted_packages[@]}"; do
[[ "${sorted_package}" = "${package}" ]] && return 0
done
_package_info "${package}" depends makedepends
for dependency in "${depends[@]}" "${makedepends[@]}"; do
for unsorted_package in "${packages[@]}"; do
[[ "${package}" = "${unsorted_package}" ]] && continue
_package_provides "${unsorted_package}" "${dependency}" && _build_add "${unsorted_package}"
done
done
sorted_packages+=("${package}")
}
# Download previous artifact
_download_previous() {
local filenames=("${@}")
for filename in "${filenames[@]}"; do
if ! wget --no-verbose "https://github.com/oneclick/rubyinstaller2-packages/releases/download/ci.ri2/${filename}"; then
rm -f "${filenames[@]}"
return 1
fi
done
return 0
}
# Git configuration
git_config() {
local name="${1}"
local value="${2}"
test -n "$(git config ${name})" && return 0
git config --global "${name}" "${value}" && return 0
failure 'Could not configure Git for makepkg'
}
# Run command with status
execute(){
local status="${1}"
local command="${2}"
local arguments=("${@:3}")
cd "${package:-.}"
message "${status}"
if [[ "${command}" != *:* ]]
then ${command} ${arguments[@]}
else ${command%%:*} | ${command#*:} ${arguments[@]}
fi || failure "${status} failed"
cd - > /dev/null
}
# Sort packages by dependency
define_build_order() {
local sorted_packages=()
for unsorted_package in "${packages[@]}"; do
_build_add "${unsorted_package}"
done
packages=("${sorted_packages[@]}")
}
# Associate artifacts with this build
create_build_references() {
local repository_name="${1}"
local references="${repository_name}.builds"
_download_previous "${references}" || failure "Download ${references} failed"
for file in *; do
sed -i "/^${file}.*/d" "${references}"
printf '%-80s%s\n' "${file}" "${BUILD_URL}" >> "${references}"
done
sort "${references}" | tee "${references}.sorted" | sed -r 's/(\S+)\s.*\/([^/]+)/\2\t\1/'
mv "${references}.sorted" "${references}"
}
# Add packages to repository
create_pacman_repository() {
local name="${1}"
local max_retry=20
local counter=0
until _download_previous "${name}".{db,files}{,.tar.zst}{,.sig}
do
sleep 10
[[ counter -eq $max_retry ]] && echo "Download failed!" && exit 1
echo "Trying again. Try #$counter"
((counter++))
done
# Add files to repository if any
files=(*.pkg.tar.zst)
if [ -e "${files[0]}" ]; then
repo-add --sign --verify "${name}.db.tar.zst" *.pkg.tar.zst
fi
}
_drop_bintray_files() {
local filenames=("${@}")
[[ "${DEPLOY_PROVIDER}" = bintray ]] || return 1
for filename in "${filenames[@]}"; do
echo -n "bintray delete ${filename} "
curl -X DELETE "-u${BINTRAY_ACCOUNT}:${BINTRAY_API_KEY}" "https://api.bintray.com/content/${BINTRAY_ACCOUNT}/${BINTRAY_REPOSITORY}/${filename}"
echo
done
}
drop_old_bintray_versions() {
local package="${1}"
local sdate=$(date +%Y-%m-%d)
for i in {1..30}; do
local rdate=$(date +%Y%m%d -d "${sdate} - $i day")
if [[ "${package}" = "mingw-w64-ruby-head" ]]; then
# mingw-w64-i686-ruby-head-r20170628-1-any.pkg.tar.xz
_drop_bintray_files mingw-w64-{i686,x86_64}-ruby-head-r${rdate}-1-any.pkg.tar.{xz,zst}{,.sig}
# mingw-w64-ruby-head-r20170712-1.src.tar.gz
_drop_bintray_files mingw-w64-ruby-head-r${rdate}-1.src.tar.gz{,.sig}
fi
done
}
# Deployment is enabled
deploy_enabled() {
[[ -n "${GPGPASSWD}" ]]
}
# Added commits
list_commits() {
_list_changes commits '*' '#*::' --pretty=format:'%ai::[%h] %s'
}
# Changed recipes
list_packages() {
local _packages
_list_changes _packages '*/PKGBUILD' '%/PKGBUILD' --pretty=format: --name-only || return 1
for _package in "${_packages[@]}"; do
local find_case_sensitive="$(find -name "${_package}" -type d -print -quit)"
test -n "${find_case_sensitive}" && packages+=("${_package}")
done
return 0
}
# Recipe quality
check_recipe_quality() {
# TODO: remove this option when not anymore needed
if test -n "${DISABLE_QUALITY_CHECK}"; then
echo 'This feature is disabled.'
return 0
fi
saneman --format='\t%l:%c %p:%c %m' --verbose --no-terminal "${packages[@]}"
}
# Add ci.ri2 repository to /etc/pacman.conf
add_ci_ri2_repo() {
# install repman
pacman --noconfirm --sync --needed pactoys
# Trust public signature key
pacman-key --init
gpg --export BE8BF1C5 | pacman-key --add -
pacman-key --lsign-key BE8BF1C5
repman add ci.ri2 'https://github.com/oneclick/rubyinstaller2-packages/releases/download/ci.ri2'
# Download [ci.ri2] package list
pacman --noconfirm --sync --refresh
return 0
}
# Status functions
failure() { local status="${1}"; local items=("${@:2}"); _status failure "${status}." "${items[@]}"; exit 1; }
success() { local status="${1}"; local items=("${@:2}"); _status success "${status}." "${items[@]}"; exit 0; }
message() { local status="${1}"; local items=("${@:2}"); _status message "${status}" "${items[@]}"; }