-
Notifications
You must be signed in to change notification settings - Fork 0
/
gitlab-stages.yml
340 lines (327 loc) · 9.66 KB
/
gitlab-stages.yml
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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
stages:
- build
- manage
- run
- post-process
variables:
# https://docs.gitlab.com/runner/configuration/feature-flags.html#enable-feature-flag-in-pipeline-configuration
FF_USE_FASTZIP: 1 # enable fast zip gitlab runner feature
# https://docs.gitlab.com/ee/ci/runners/configure_runners.html#artifact-and-cache-settings
TRANSFER_METER_FREQUENCY: "1s" # shows a progress meter for artifact and cache uploads and downloads
ARTIFACT_COMPRESSION_LEVEL: "fast"
CACHE_COMPRESSION_LEVEL: "fast"
# https://docs.gitlab.com/ee/ci/large_repositories/#shallow-cloning
GIT_DEPTH: 10
# Academy variables
ACADEMY_DEFAULT_DOCKER_IMAGE: "internetguru/academy:latest"
ACADEMY_DOCKER_IMAGE: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
ACADEMY_CACHE: "../.academy-cache"
ACADEMY_EDITABLE: "**/*"
ACADEMY_FORCE_MERGE: ""
cache:
- key: academy-cache
paths:
- $ACADEMY_CACHE
- key: artifacts
paths:
- .results/
.before_script_global: &global_init |
# fix TERM
export TERM=xterm
if [[ -d .git ]]; then
# checkout to current branch
git checkout -B "${CI_COMMIT_REF_NAME}" "${CI_COMMIT_SHA}"
# set git user
git config --global user.email "${GITLAB_USER_EMAIL}"
git config --global user.name "Runner = ${CI_RUNNER_DESCRIPTION}"
fi
mkdir -p ${ACADEMY_CACHE}
export ACADEMY_DIR="${ACADEMY_CACHE}/academy"
mkdir -p "${ACADEMY_DIR}"
if grep -s 'ACADEMY_INCLUDE' '.gitlab-ci.yml'; then
revision=$(grep -oP -m1 "[^/]+(?=/gitlab-stages)" <<< "$ACADEMY_INCLUDE")
else
revision=$(grep -oP -m1 "[^/]+(?=/gitlab-stages)" .gitlab-ci.yml)
fi
if [[ -d "${ACADEMY_DIR}/.git" ]]; then
git -C "${ACADEMY_DIR}" reset --hard
git -C "${ACADEMY_DIR}" clean -fd
git -C "${ACADEMY_DIR}" config --replace-all remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git -C "${ACADEMY_DIR}" fetch origin ${revision}
git -C "${ACADEMY_DIR}" checkout origin/${revision}
else
git clone --single-branch --branch ${revision} https://github.com/InternetGuru/academy ${ACADEMY_DIR}
fi
# e.g. /umiami/george/csc220
declare -r namespace="${CI_PROJECT_NAMESPACE}"
declare -r project_name="$(basename "${PWD}")"
declare -r user_namespace="${namespace}/${CI_COMMIT_REF_NAME}/${project_name}"
# simplify project remote url
if [[ -d .git ]]; then
git remote set-url --push origin "${namespace}/${project_name}.git"
fi
# set permissions
declare ACADEMY=${ACADEMY_DIR}/academy
chmod +x ${ACADEMY_DIR}/*
declare DASHBOARD_PROJECT_NAME="${project_name}"
.before_script_token: &validate_token |
# prepare acccess token for the distribution script
if [[ -z "${ACADEMY_GITLAB_ACCESS_TOKEN}" ]]; then
echo "Undefined variable {ACADEMY_GITLAB_ACCESS_TOKEN}"
echo "Refer to README and make sure the current branch is protected."
exit 1
fi
.get_users: &get_users |
get_users() {
# do not distribute ACADEMY_ASSIGN file
if [[ -f "ACADEMY_ASSIGN" ]]; then
mv "ACADEMY_ASSIGN" ..
# commit move to keep git status empty (do not push)
git commit --quiet -m "move users file" -- "ACADEMY_ASSIGN"
fi
# do not distribute ACADEMY_ALLOW file
if [[ -f "ACADEMY_ALLOW" ]]; then
mv "ACADEMY_ALLOW" ..
# commit move to keep git status empty (do not push)
git commit --quiet -m "move allow file" -- "ACADEMY_ALLOW"
fi
declare users
if [[ -n "${ACADEMY_ASSIGN}" ]]; then
users="${ACADEMY_ASSIGN}"
elif [[ -f '../ACADEMY_ASSIGN' ]]; then
users="$(<../ACADEMY_ASSIGN)"
else
users="${GITLAB_USER_NAME}"
fi
tr ',' ' ' <<< "${users}"
}
distribute:
image: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
stage: manage
tags:
- docker
cache: []
before_script:
- *validate_token
- *global_init
script:
# set token file (will be deprecated)
- echo "${ACADEMY_GITLAB_ACCESS_TOKEN}" > ${HOME}/.ACADEMY_GITLAB_ACCESS_TOKEN
- *get_users
# distribute current project among all users
- |
declare users
users="$(get_users)"
declare merge=''
if [[ -n "${ACADEMY_FORCE_MERGE}" ]]; then
merge='--force-merge'
fi
${ACADEMY} distribute ${merge} --update-links --namespace "${user_namespace}" \
--process-issues "${ACADEMY_ISSUES:-${CI_COMMIT_REF_NAME}}" \
<<< "${users}"
rules:
- if: $ACADEMY_FORCE_JOB == "distribute"
when: always
- when: manual
allow_failure: true
collect:
image: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
stage: manage
tags:
- docker
cache: []
before_script:
- *validate_token
- *global_init
script:
# set token file (will be deprecated)
- echo "${ACADEMY_GITLAB_ACCESS_TOKEN}" > ${HOME}/.ACADEMY_GITLAB_ACCESS_TOKEN
- *get_users
- |
if [[ -z "${ACADEMY_GROUP}" ]]; then
echo "Missing ACADEMY_GROUP variable (groups to collect)."
exit 1;
fi
declare users
git fetch --all
while read group; do
# get users from $group
git checkout ${group}
users="$(get_users)"
# checkout to starting branch
git checkout ${CI_COMMIT_REF_NAME}
echo "Collecting for ${group}"
${ACADEMY} distribute --collect --update-links --namespace "${user_namespace}" \
--default-branch-namespace "${namespace}/${group}/${project_name}" --member-role 0 --assign 'never' \
<<< "${users}"
done <<< "${ACADEMY_GROUP}"
# TODO remove other existing repositories rules:
rules:
- if: $ACADEMY_FORCE_JOB == "collect"
when: always
- when: manual
allow_failure: true
clear-cache:
image: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
stage: manage
tags:
- docker
before_script:
- *global_init
script:
- |
for file in "${ACADEMY_CACHE}/"*; do
rm -rf "${file}"
done
for file in ".results/"*; do
rm -rf "${file}"
done
rules:
- when: manual
artifacts:
paths:
- .results/
expire_in: 1 year
allow_failure: true
execute:
image: ${ACADEMY_DOCKER_IMAGE}
stage: run
tags:
- docker
before_script:
- *global_init
script:
- echo '%% job start execute %%'
- ${ACADEMY} execute
- echo '%% job end execute %%'
artifacts:
paths:
- .results/
expire_in: 1 year
rules:
- if: $ACADEMY_FORCE_JOB == "execute"
when: always
- when: manual
allow_failure: true
test:
image: ${ACADEMY_DOCKER_IMAGE}
stage: run
tags:
- docker
before_script:
- *global_init
script:
- echo '%% job start test %%'
- ${ACADEMY} test
- echo '%% job end test %%'
artifacts:
paths:
- .results/
expire_in: 1 year
rules:
- if: $ACADEMY_FORCE_JOB == "test"
when: always
- when: manual
allow_failure: true
evaluate:
image: ${ACADEMY_DOCKER_IMAGE}
stage: run
tags:
- docker
before_script:
- *global_init
script:
- echo '%% job start evaluate %%'
- ${ACADEMY} evaluate
- echo '%% job end evaluate %%'
artifacts:
paths:
- .results/
expire_in: 1 year
rules:
- if: $ACADEMY_FORCE_JOB == "evaluate"
when: always
- if: $CI_COMMIT_BRANCH == "submit"
when: always
- if: $CI_COMMIT_BRANCH == "main"
when: always
- when: manual
allow_failure: true
meta:
# variables:
# GIT_STRATEGY: none
image: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
stage: post-process
tags:
- docker
before_script:
- *global_init
script:
- |
# clear dashboards cache
if [[ -z "${ACADEMY_DASHBOARD}" ]]; then
echo "Missing or empty ACADEMY_DASHBOARD variable."
exit 1
fi
while read dashboard; do
echo "${dashboard}/${namespace}/${DASHBOARD_PROJECT_NAME}?group=${CI_COMMIT_REF_NAME}"
curl "${dashboard}/${namespace}/${DASHBOARD_PROJECT_NAME}?group=${CI_COMMIT_REF_NAME}" \
-I -H "Cache-Control: no-cache" -H "Accept: application/json"
done <<< "${ACADEMY_DASHBOARD}"
# create age badge
mkdir -p .results
source "${ACADEMY_DIR}/commons"
source "${ACADEMY_DIR}/badges"
WORKING_DIR='.'
title='View activity'
link="${CI_PROJECT_URL}/activity"
generate_badge 'Age' "$(date +"%Y-%m-%dT%H:%M:%S%z")" 'blue' '10-badge-age' "${link}" "${title}"
title='View all merge requests'
link="${CI_PROJECT_URL}/-/merge_requests"
generate_badge 'Updates' 'unknown' '' '20-badge-updates' "${link}" "${title}"
generate_badge 'Status' 'unknown' '' '30-badge-status'
- |
# output badges
for badge in $(ls -1v .results/*.svg); do
[[ "${badge}" =~ ".results/"(.*).svg ]]
badge_name="${BASH_REMATCH[1]}"
badge_link="$(grep -Po '(?<=href=")([^"]+)' "${badge}" || true)"
if [[ -z "${badge_link}" ]]; then
printf -- '![%s](%s/builds/artifacts/%s/raw/%s?job=meta)\n' \
"${badge_name}" "${CI_PROJECT_URL}" "${CI_COMMIT_REF_NAME}" "${badge}"
else
printf -- '[![%s](%s/builds/artifacts/%s/raw/%s?job=meta)](%s)\n' \
"${badge_name}" "${CI_PROJECT_URL}" "${CI_COMMIT_REF_NAME}" "${badge}" "${badge_link}"
fi
done
rules:
- if: $CI_COMMIT_BRANCH == "source"
when: manual
- if: $CI_COMMIT_BRANCH == "draft"
when: manual
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- when: always
artifacts:
paths:
- .results/
expire_in: 1 year
submit:
image: ${ACADEMY_DEFAULT_DOCKER_IMAGE}
stage: post-process
cache:
- key: academy-cache
paths:
- $ACADEMY_CACHE
tags:
- docker
before_script:
- *global_init
script:
- "${ACADEMY_DIR}/submit"
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: always
- if: $CI_COMMIT_BRANCH == "source"
when: always
- when: never