forked from framasoft/mobilizon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
.gitlab-ci.yml
462 lines (438 loc) · 13.1 KB
/
.gitlab-ci.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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
image: tcitworld/mobilizon-ci
stages:
- install
- check
- build-js
- sentry
- test
- build
- upload
- deploy
variables:
MIX_ENV: "test"
# DB Variables for Postgres / Postgis
POSTGRES_DB: mobilizon_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_HOST: postgres
# DB Variables for Mobilizon
MOBILIZON_DATABASE_USERNAME: $POSTGRES_USER
MOBILIZON_DATABASE_PASSWORD: $POSTGRES_PASSWORD
MOBILIZON_DATABASE_DBNAME: $POSTGRES_DB
MOBILIZON_DATABASE_HOST: $POSTGRES_HOST
GEOLITE_CITIES_PATH: "/usr/share/GeoIP/GeoLite2-City.mmdb"
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
# Release elements
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}"
ARCH: "amd64"
EXPORT_FORMATS: "csv,ods,pdf"
APP_VERSION: "${CI_COMMIT_REF_NAME}"
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
cache:
key: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}"
paths:
- deps/
- _build/
- node_modules
- .npm
# Installed dependencies are cached across the pipeline
# So there is no need to reinstall them all the time
# It saves minutes during a pipeline build time
install:
stage: install
script:
- npm ci
- mix deps.get
- mix compile
lint-elixir:
stage: check
before_script:
- mix deps.get
script:
- export EXITVALUE=0
- git fetch origin ${CI_DEFAULT_BRANCH}
- TARGET_SHA1=$(git show-ref -s ${CI_DEFAULT_BRANCH})
- echo "$TARGET_SHA1"
- mix format --check-formatted --dry-run || export EXITVALUE=1
- mix credo diff --from-git-merge-base $TARGET_SHA1 --strict -a || export EXITVALUE=1
- mix sobelow --config || export EXITVALUE=1
- exit $EXITVALUE
artifacts:
reports:
codequality: codeclimate.json
lint-front:
image: node:20
stage: check
before_script:
- export EXITVALUE=0
- npm ci
script:
- npm run lint || export EXITVALUE=1
- npx prettier -c . || export EXITVALUE=1
- exit $EXITVALUE
build-frontend:
stage: build-js
image: node:20
before_script:
- apt update
- apt install -y --no-install-recommends python3 build-essential webp imagemagick gifsicle jpegoptim optipng pngquant
script:
- npm install --frozen-lockfile
- npm run build
artifacts:
expire_in: 5 days
paths:
- priv/static
needs:
- lint-front
sentry-commit:
stage: sentry
image: getsentry/sentry-cli
script:
- echo "Create a new release $CI_COMMIT_TAG"
- sentry-cli releases new $CI_COMMIT_TAG
- sentry-cli releases set-commits $CI_COMMIT_TAG --auto
- sentry-cli releases files $CI_COMMIT_TAG upload-sourcemaps priv/static/assets/
- sentry-cli releases finalize $CI_COMMIT_TAG
- echo "Finalized release for $CI_COMMIT_TAG"
needs:
- build-frontend
only:
- tags@framasoft/mobilizon
deps:
stage: check
before_script:
- mix deps.get
script:
- export EXITVALUE=0
- mix hex.outdated || export EXITVALUE=1
- npm outdated || export EXITVALUE=1
- exit $EXITVALUE
allow_failure: true
needs:
- install
exunit:
stage: test
services:
- name: postgis/postgis:16-3.4
alias: postgres
variables:
MIX_ENV: test
before_script:
- mix deps.get
- mix compile
- mix tz_world.update
- mix ecto.create
- mix ecto.migrate
script:
- mix coveralls
artifacts:
when: always
reports:
junit:
- test-junit-report.xml
expire_in: 30 days
vitest:
stage: test
needs:
- lint-front
before_script:
- npm install --frozen-lockfile
script:
- npm run coverage --reporter=default --reporter=junit --outputFile.junit=./junit.xml
artifacts:
when: always
paths:
- coverage
reports:
junit:
- junit.xml
expire_in: 30 days
e2e:
stage: test
services:
- name: postgis/postgis:16-3.4
alias: postgres
variables:
MIX_ENV: "e2e"
before_script:
- mix deps.get
- mix ecto.create
- mix ecto.migrate
- mix run priv/repo/e2e.seed.exs
- npm install && npm run build && npx playwright install
- mix phx.digest
script:
- mix phx.server &
- npx wait-on http://localhost:4000
- npx playwright test --project $BROWSER
parallel:
matrix:
- BROWSER: ["firefox", "chromium"]
artifacts:
expire_in: 2 days
paths:
- playwright-report/
- test-results/
pages:
stage: deploy
script:
- mv public public-mbz
- mkdir public
- mix deps.get
- mix docs
- mv doc public/backend
# #- npm run styleguide:build
# #- mv styleguide public/frontend
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
artifacts:
expire_in: 1 hour
paths:
- public
.docker: &docker
stage: build
image: docker:24
variables:
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
DOCKER_DRIVER: overlay2
DOCKER_CLI_EXPERIMENTAL: enabled
services:
- docker:24-dind
cache: {}
before_script:
# Install buildx
- wget https://github.com/docker/buildx/releases/download/v0.11.2/buildx-v0.11.2.linux-amd64
- mkdir -p ~/.docker/cli-plugins/
- mv buildx-v0.11.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx
- chmod a+x ~/.docker/cli-plugins/docker-buildx
# Create env
- docker context create tls-environment
- docker buildx create --use tls-environment
# Install qemu/binfmt
- docker pull tonistiigi/binfmt:latest
- docker run --rm --privileged tonistiigi/binfmt:latest --install all
# Install jq
- apk --no-cache add jq
# Login to DockerHub
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > ~/.docker/config.json
tags:
- "privileged"
build-docker-main:
<<: *docker
rules:
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_TRIGGERED == "true"'
script:
- docker buildx build --platform linux/amd64 -t framasoft/mobilizon:main -f docker/production/Dockerfile .
build-docker-tag:
<<: *docker
rules: &release-tag-rules
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
- if: $CI_COMMIT_TAG != null
when: on_success
timeout: 3 hours
script:
- >
docker buildx build
--push
--platform linux/${ARCH}
--provenance=false
--build-arg="${ERL_FLAGS}"
-t framasoft/mobilizon:${CI_COMMIT_TAG}-${ARCH}
-f docker/production/Dockerfile .
parallel:
matrix:
- ARCH: ["amd64"]
ERL_FLAGS: ["ERL_FLAGS="]
- ARCH: ["arm64"]
ERL_FLAGS: ["ERL_FLAGS=+JMsingle true"]
# Create manifest and push
docker-manifest-push:
<<: *docker
needs: ["build-docker-tag"]
rules: &release-tag-rules
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
- if: $CI_COMMIT_TAG != null
when: on_success
script:
- >
docker manifest create framasoft/mobilizon:${CI_COMMIT_TAG}
--amend framasoft/mobilizon:${CI_COMMIT_TAG}-amd64
--amend framasoft/mobilizon:${CI_COMMIT_TAG}-arm64
- docker manifest push --purge framasoft/mobilizon:${CI_COMMIT_TAG}
###
# Simply creating an alias to the tag doesn't work:
# « xxx is a manifest list »
# https://joonas.fi/2021/02/docker-multi-arch-image-tooling-buildx/
###
docker-latest:
<<: *docker
needs: ["docker-manifest-push"]
rules: &release-tag-rules
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
- if: $CI_COMMIT_TAG != null && $CI_COMMIT_TAG !~ /alpha|beta|rc/
when: on_success
script:
- echo docker manifest create framasoft/mobilizon:latest $(docker manifest inspect framasoft/mobilizon:$CI_COMMIT_TAG | jq '.manifests[] | .digest' | xargs -I {} echo framasoft/mobilizon@{})
- docker manifest create framasoft/mobilizon:latest $(docker manifest inspect framasoft/mobilizon:$CI_COMMIT_TAG | jq -r '.manifests[] | .digest' | xargs -I {} echo framasoft/mobilizon@{})
- docker manifest push --purge framasoft/mobilizon:latest
# Packaging app for amd64
package-app:
image: mobilizon/buildpack:1.16.1-erlang-26.2.2-${SYSTEM}
stage: build
variables: &release-variables
MIX_ENV: "prod"
DEBIAN_FRONTEND: noninteractive
TZ: Etc/UTC
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
script: &release-script
- mix local.hex --force
- mix local.rebar --force
- mix deps.get --only-prod
- mix compile
- mix phx.digest.clean --all && mix phx.digest
- mix release --path release/mobilizon
- cd release/mobilizon && ln -s lib/mobilizon-*/priv priv && cd ../../
- du -sh release/
- 'echo "Artifact: ${APP_ASSET}"'
- tar czf ${APP_ASSET} -C release mobilizon
- du -sh ${APP_ASSET}
only:
- tags@framasoft/mobilizon
artifacts:
expire_in: 2 days
paths:
- ${APP_ASSET}
parallel:
matrix:
- SYSTEM:
[
"debian-bookworm",
"debian-bullseye",
"debian-buster",
"ubuntu-jammy",
"ubuntu-focal",
"fedora-38",
"fedora-39",
]
package-app-dev:
stage: build
variables: *release-variables
script: *release-script
except:
- tags@framasoft/mobilizon
artifacts:
expire_in: 2 days
paths:
- ${APP_ASSET}
# Packaging app for multi-arch
package-multi-arch-release:
stage: build
image: docker:24
variables:
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
DOCKER_DRIVER: overlay2
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
OS: debian-buster
services:
- docker:24-dind
cache: {}
before_script:
# Install buildx
- wget https://github.com/docker/buildx/releases/download/v0.11.2/buildx-v0.11.2.linux-amd64
- mkdir -p ~/.docker/cli-plugins/
- mv buildx-v0.11.2.linux-amd64 ~/.docker/cli-plugins/docker-buildx
- chmod a+x ~/.docker/cli-plugins/docker-buildx
# Create env
- docker context create tls-environment
- docker buildx create --use tls-environment
# Install qemu/binfmt
- docker pull tonistiigi/binfmt:latest
- docker run --rm --privileged tonistiigi/binfmt:latest --install all
script:
- docker buildx build --platform linux/${ARCH} --output type=local,dest=releases --build-arg="ERL_FLAGS=+JMsingle true" --build-arg APP_ASSET=${APP_ASSET} -f docker/multiarch/Dockerfile .
- ls -alh releases/mobilizon/
- du -sh releases/mobilizon/${APP_ASSET}
- mv releases/mobilizon/${APP_ASSET} .
tags:
- "privileged"
artifacts:
expire_in: 2 days
paths:
- ${APP_ASSET}
- erl_crash.dump # if there's a memory issue
parallel:
matrix:
- ARCH: ["arm64"]
## Currently not used as the hexpm base images do not have support for other architectures than amd64
# SYSTEM:
# [
# "debian-bookworm",
# "debian-bullseye",
# "ubuntu-jammy",
# "ubuntu-focal",
# "ubuntu-bionic",
# "alpine-3.17.5",
# "alpine-3.18.4",
# "fedora-38",
# "fedora-39",
# ]
rules:
- if: '$CI_COMMIT_TAG != null || $CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_TRIGGERED == "true"'
timeout: 3h
allow_failure: true
# Release
release-upload:
stage: upload
image: framasoft/upload-packages:latest
variables:
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
rules:
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
script:
- eval `ssh-agent -s`
- ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i)
- echo "put -r ${APP_ASSET}" | sftp -o "VerifyHostKeyDNS yes" ${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
artifacts:
expire_in: 1 day
when: on_success
paths:
- mobilizon_*.tar.gz
parallel:
matrix:
- ARCH: ["amd64", "arm", "arm64"]
allow_failure: true
release-create:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
when: never
variables:
APP_ASSET_AMD64: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_amd64.tar.gz"
APP_ASSET_ARM: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_arm.tar.gz"
APP_ASSET_ARM64: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_arm64.tar.gz"
before_script:
- apk --no-cache add gawk sed grep
script: |
CHANGELOG=$(awk -v version="$APP_VERSION" '/^## / { printit = $2 == version }; printit' CHANGELOG.md | grep -v "## $APP_VERSION" | sed '1{/^$/d}')
ENDPOINT="https://packages.joinmobilizon.org"
release-cli create --name "$CI_COMMIT_TAG" \
--description "$CHANGELOG" \
--tag-name "$CI_COMMIT_TAG" \
--assets-link "{\"name\":\"${APP_ASSET_AMD64}\",\"url\":\"${ENDPOINT}/${CI_COMMIT_REF_NAME}/${APP_ASSET_AMD64}\"}" \
--assets-link "{\"name\":\"${APP_ASSET_ARM}\",\"url\":\"${ENDPOINT}/${CI_COMMIT_REF_NAME}/${APP_ASSET_ARM}\"}" \
--assets-link "{\"name\":\"${APP_ASSET_ARM64}\",\"url\":\"${ENDPOINT}/${CI_COMMIT_REF_NAME}/${APP_ASSET_ARM64}\"}"