CI: simplify the logic for rebuilding the containers
[platform/upstream/libinput.git] / .gitlab-ci.yml
1 # vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0:
2 #
3 # This is a bit complicated for two reasons:
4 # - we really want to run dnf/apt/... only once, updating on the test runner for
5 #   each job takes forever. So we create a container image for each distribution
6 #   tested, then run the tests on this container image.
7 #
8 #   Creating a container image is time-consuming, so we only do so for pushes to
9 #   libinput directly (not merge requests) and if the current image is 'old'.
10 #
11 # - GitLab only allows one script: set per job but we have a bunch of commands
12 #   we need to re-run for each build (meson && ninja && etc). YAML cannot merge
13 #   arrays templates so we're screwed.
14 #
15 #   So instead we use a default_build template and override everything with
16 #   variables. The only two variables that matter:
17 #     MESON_ARGS=-Denable-something=true
18 #     NINJA_ARGS=dist ... to run 'ninja -C builddir dist'
19 #   Note that you cannot use scripts: in any target if you expect default_build
20 #   to work.
21 #
22 #
23 # All jobs must follow the naming scheme of
24 # <distribution>:<version>@activity:
25 #  e.g. fedora:29@build-default
26
27 include:
28   # Arch container builder template
29   - project: 'wayland/ci-templates'
30     ref: c73dae8b84697ef18e2dbbf4fed7386d9652b0cd # see https://docs.gitlab.com/ee/ci/yaml/#includefile
31     file: '/templates/arch.yml'
32   # Fedora container builder template
33   - project: 'wayland/ci-templates'
34     ref: c73dae8b84697ef18e2dbbf4fed7386d9652b0cd # see https://docs.gitlab.com/ee/ci/yaml/#includefile
35     file: '/templates/fedora.yml'
36   # Ubuntu container builder template
37   - project: 'wayland/ci-templates'
38     ref: c73dae8b84697ef18e2dbbf4fed7386d9652b0cd # see https://docs.gitlab.com/ee/ci/yaml/#includefile
39     file: '/templates/ubuntu.yml'
40
41 stages:
42   - container_prep   # rebuild the container images if there is a change
43   - build            # for actually building things
44   - deploy           # trigger wayland's website generation
45   - container_clean  # clean up unused container images
46
47 variables:
48   ###############################################################################
49   # This is the list of packages required to build libinput with the default    #
50   # configuration.                                                              #
51   #                                                                             #
52   # Run dnf install/apt-get install/.. with the list of packages for your       #
53   # distribution                                                                #
54   #                                                                             #
55   # See the documentation here:                                                 #
56   # https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html  #
57   ###############################################################################
58   FEDORA_RPMS:        'git gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark                          libwacom-devel cairo-devel   gtk3-devel   glib2-devel    mtdev-devel'
59   UBUNTU_CUSTOM_DEBS: 'git gcc g++     pkg-config         meson check       libudev-dev   libevdev-dev   doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme libwacom-dev   libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev'
60   ARCH_PKGS:          'git gcc         pkgconfig          meson check       libsystemd    libevdev       doxygen graphviz  python-sphinx  python-recommonmark                          libwacom                     gtk3                        mtdev      diffutils'
61   FREEBSD_BUILD_PKGS: 'meson'
62   FREEBSD_PKGS:       'libepoll-shim                                        libudev-devd  libevdev                                                                                     libwacom                     gtk3                        libmtdev   '
63   ############################ end of package lists #############################
64
65   # these tags should be updated each time the list of packages is updated
66   # changing these will force rebuilding the associated image
67   # Note: these tags have no meaning and are not tied to a particular
68   # libinput version
69   FEDORA_TAG: '2019-03-15.0'
70   UBUNTU_TAG: '2019-03-15.0'
71   ARCH_TAG: '2019-03-15.0'
72   FREEBSD_TAG: '2019-03-15.0'
73
74   UBUNTU_EXEC: "bash .gitlab-ci/ubuntu_install.sh $UBUNTU_CUSTOM_DEBS"
75
76   UPSTREAM_REPO: libinput/libinput
77   BUILDAH_IMAGE: $CI_REGISTRY/wayland/ci-templates/buildah:latest
78   FEDORA_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FEDORA_VERSION:$FEDORA_TAG
79   UBUNTU_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/ubuntu/$UBUNTU_VERSION:$UBUNTU_TAG
80   ARCH_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/archlinux/rolling:$ARCH_TAG
81   FREEBSD_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/freebsd/11.2:$FREEBSD_TAG
82
83   MESON_BUILDDIR: "build dir"
84   NINJA_ARGS: 'test'
85   MESON_ARGS: ''
86
87   # Until we have a VM with full access, we cannot run the test suite runner
88   SKIP_LIBINPUT_TEST_SUITE_RUNNER: 1
89   # udev isn't available/working properly in the containers
90   UDEV_NOT_AVAILABLE: 1
91   GIT_DEPTH: 1
92
93 .default_artifacts: &default_artifacts
94   artifacts:
95     name: "meson-logs-$CI_JOB_NAME"
96     when: always
97     expire_in: 1 week
98     paths:
99       - $MESON_BUILDDIR/meson-logs
100
101 # The default build instructions
102 .default_build: &default_build
103   script:
104    - rm -rf "$MESON_BUILDDIR"
105    - meson "$MESON_BUILDDIR" $MESON_ARGS
106    - meson configure "$MESON_BUILDDIR"
107    - ninja -C "$MESON_BUILDDIR" $NINJA_ARGS
108
109 #################################################################
110 #                                                               #
111 #                    container prep stage                       #
112 #                                                               #
113 #################################################################
114
115 #
116 # This stage will recreate the container images only if the image
117 # is too old or if it is missing some dependencies.
118 #
119
120 .pull_upstream_or_rebuild: &pull_upstream_or_rebuild
121   before_script:
122     # log in to the registry
123     - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
124
125     # get the full container image name (DISTRIB_VERSION still has indirections)
126     - IMAGE=$(eval echo "$DISTRIB_FLAVOR/$DISTRIB_VERSION:$TAG")
127
128     - |
129       # force rebuild if schedule, reuse otherwise
130       if [[ $CI_PIPELINE_SOURCE != "schedule" ]] ;
131       then
132         # pull the latest upstream image if it exists
133         skopeo copy docker://$CI_REGISTRY/$UPSTREAM_REPO/$IMAGE \
134                     docker://$CI_REGISTRY_IMAGE/$IMAGE && exit 0 || true ;
135
136         # check if our image is already in the current registry
137         skopeo inspect docker://$CI_REGISTRY_IMAGE/$IMAGE > /dev/null && exit 0 || true ;
138       fi
139
140 fedora:28@container-prep:
141   extends: .fedora@container-build
142   stage: container_prep
143   variables:
144     GIT_STRATEGY: none
145     FEDORA_VERSION: 28
146     DISTRIB_FLAVOR: fedora
147     DISTRIB_VERSION: $FEDORA_VERSION
148     TAG: $FEDORA_TAG
149   <<: *pull_upstream_or_rebuild
150
151 fedora:29@container-prep:
152   extends: .fedora@container-build
153   stage: container_prep
154   variables:
155     GIT_STRATEGY: none
156     FEDORA_VERSION: 29
157     DISTRIB_FLAVOR: fedora
158     DISTRIB_VERSION: $FEDORA_VERSION
159     TAG: $FEDORA_TAG
160   <<: *pull_upstream_or_rebuild
161
162
163 ubuntu:18.10@container-prep:
164   extends: .ubuntu@container-build
165   stage: container_prep
166   variables:
167     GIT_STRATEGY: none
168     UBUNTU_VERSION: "18.10"
169     DISTRIB_FLAVOR: ubuntu
170     DISTRIB_VERSION: $UBUNTU_VERSION
171     TAG: $UBUNTU_TAG
172   <<: *pull_upstream_or_rebuild
173
174 ubuntu:18.04@container-prep:
175   extends: .ubuntu@container-build
176   stage: container_prep
177   variables:
178     GIT_STRATEGY: none
179     UBUNTU_VERSION: "18.04"
180     DISTRIB_FLAVOR: ubuntu
181     DISTRIB_VERSION: $UBUNTU_VERSION
182     TAG: $UBUNTU_TAG
183   <<: *pull_upstream_or_rebuild
184
185
186 arch:rolling@container-prep:
187   extends: .arch@container-build
188   stage: container_prep
189   variables:
190     GIT_STRATEGY: none
191     ARCH_VERSION: rolling
192     DISTRIB_FLAVOR: archlinux
193     DISTRIB_VERSION: $ARCH_VERSION
194     TAG: $ARCH_TAG
195   <<: *pull_upstream_or_rebuild
196
197 .freebsd@container-prep:
198   stage: container_prep
199   image: $BUILDAH_IMAGE
200   <<: *pull_upstream_or_rebuild
201   script:
202     - buildcntr=$(buildah from --quiet  myfreeweb/freebsd-cross:latest)
203     - buildah run $buildcntr apk add --no-cache $FREEBSD_BUILD_PKGS
204     - buildah run $buildcntr pkg -r /freebsd update -f
205     - buildah run $buildcntr pkg -r /freebsd install -y $FREEBSD_PKGS
206     - buildah config --workingdir /app $buildcntr
207     # tag the current container
208     - buildah commit --quiet $buildcntr $FREEBSD_CONTAINER_IMAGE
209     # clean up the working container
210     - buildah rm $buildcntr
211
212     # push the container image to the libinput registry
213     - podman push --quiet $FREEBSD_CONTAINER_IMAGE
214     - skopeo copy docker://$FREEBSD_CONTAINER_IMAGE docker://$CI_REGISTRY_IMAGE/freebsd/$FREEBSD_VERSION:$CI_JOB_ID
215
216 freebsd:11.2@container-prep:
217   extends: .freebsd@container-prep
218   variables:
219     GIT_STRATEGY: none
220     FREEBSD_VERSION: "11.2"
221     DISTRIB_FLAVOR: freebsd
222     DISTRIB_VERSION: $FREEBSD_VERSION
223     TAG: $FREEBSD_TAG
224
225
226 #################################################################
227 #                                                               #
228 #                   container clean stage                       #
229 #                 run during the clean stage                    #
230 #                                                               #
231 #################################################################
232
233 #
234 # This stage will look for the container images we currently have in
235 # the registry and will remove any that are not tagged with the provided
236 # $container_image:$tag
237 #
238 .container-clean:
239   stage: container_clean
240   image: $BUILDAH_IMAGE
241   script:
242     # get the full container image name (CURRENT_CONTAINER_IMAGE still has indirections)
243     - CONTAINER_IMAGE=$(eval echo "$CURRENT_CONTAINER_IMAGE")
244     - GITLAB=$(echo $CI_PROJECT_URL | cut -f3 -d/)
245     - REPOSITORY=$(echo $CONTAINER_IMAGE | cut -f2- -d/ | cut -f1 -d:)
246     - IMAGE_PATH=$(echo $CONTAINER_IMAGE | cut -f1 -d:)
247     - LATEST_TAG=$(echo $CONTAINER_IMAGE | cut -f2 -d:)
248
249     # log in to the registry (read only)
250     - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
251
252     # get the r/w token from the settings to access the registry
253     #
254     # each developer needs to register a secret variable that contains
255     # a personal token with api access in the form of:
256     # PERSONAL_TOKEN_$USER (for example PERSONAL_TOKEN_bentiss)
257     - tokenname="PERSONAL_TOKEN_$GITLAB_USER_LOGIN"
258     - token=$(eval echo "\$$tokenname")
259
260     # request a token for the registry API
261     - REGISTRY_TOKEN=$(curl https://$GITLAB/jwt/auth --get
262                              --silent --show-error
263                              -d client_id=docker
264                              -d offline_token=true
265                              -d service=container_registry
266                              -d "scope=repository:$REPOSITORY:pull,*"
267                              --fail
268                              --user $GITLAB_USER_LOGIN:$token
269                              | sed -r 's/(\{"token":"|"\})//g')
270
271     # get the digest of the latest image
272     - LATEST_MANIFEST=$(skopeo inspect docker://$IMAGE_PATH:$LATEST_TAG | jq -r '.Digest')
273
274     # get the list of tags
275     - TAGS=$(skopeo inspect docker://$IMAGE_PATH:$LATEST_TAG | jq -r '.RepoTags[]')
276     # FIXME: is the above command working properly? If not, use below:
277     # - TAGS=$(curl -X GET -H "accept:application/vnd.docker.distribution.manifest.v2+json"
278     #                      -H "authorization:Bearer $REGISTRY_TOKEN"
279     #                      https://$CI_REGISTRY/v2/$REPOSITORY/tags/list | jq -r '.tags[]')
280
281     # iterate over the tags
282     - for tag in $TAGS;
283       do
284         MANIFEST=$(skopeo inspect docker://$IMAGE_PATH:$tag | jq -r '.Digest');
285         if test x"$MANIFEST" != x"$LATEST_MANIFEST";
286           then
287             echo removing $tag as $MANIFEST;
288             curl https://$CI_REGISTRY/v2/$REPOSITORY/manifests/$MANIFEST --silent
289                  -H "accept:application/vnd.docker.distribution.manifest.v2+json"
290                  -H "authorization:Bearer $REGISTRY_TOKEN"
291                  --fail --show-error -X DELETE || true
292           ;fi
293       ;done
294   dependencies: []
295   allow_failure: true
296   only:
297     - schedules
298
299 fedora:28@container-clean:
300   extends: .container-clean
301   variables:
302     GIT_STRATEGY: none
303     FEDORA_VERSION: 28
304     CURRENT_CONTAINER_IMAGE: $FEDORA_CONTAINER_IMAGE
305
306 fedora:29@container-clean:
307   extends: .container-clean
308   variables:
309     GIT_STRATEGY: none
310     FEDORA_VERSION: 29
311     CURRENT_CONTAINER_IMAGE: $FEDORA_CONTAINER_IMAGE
312
313 ubuntu:18.10@container-clean:
314   extends: .container-clean
315   variables:
316     GIT_STRATEGY: none
317     UBUNTU_VERSION: "18.10"
318     CURRENT_CONTAINER_IMAGE: $UBUNTU_CONTAINER_IMAGE
319
320 ubuntu:18.04@container-clean:
321   extends: .container-clean
322   variables:
323     GIT_STRATEGY: none
324     UBUNTU_VERSION: "18.04"
325     CURRENT_CONTAINER_IMAGE: $UBUNTU_CONTAINER_IMAGE
326
327 arch:rolling@container-clean:
328   extends: .container-clean
329   variables:
330     GIT_STRATEGY: none
331     CURRENT_CONTAINER_IMAGE: $ARCH_CONTAINER_IMAGE
332
333 freebsd:11.2@container-clean:
334   extends: .container-clean
335   variables:
336     GIT_STRATEGY: none
337     CURRENT_CONTAINER_IMAGE: $FREEBSD_CONTAINER_IMAGE
338
339 #################################################################
340 #                                                               #
341 #                       build stage                             #
342 #                                                               #
343 #################################################################
344
345 .build@template:
346   stage: build
347   <<: *default_artifacts
348   <<: *default_build
349   dependencies: []
350
351 #
352 # Fedora
353 #
354
355 .fedora-build@template:
356   extends: .build@template
357   image: $FEDORA_CONTAINER_IMAGE
358
359 fedora:28@default-build:
360   extends: .fedora-build@template
361   variables:
362     FEDORA_VERSION: 28
363
364 fedora:29@default-build:
365   extends: .fedora-build@template
366   variables:
367     FEDORA_VERSION: 29
368
369 fedora:29@default-build-release:
370   extends: .fedora-build@template
371   variables:
372     FEDORA_VERSION: 29
373     MESON_ARGS: "-Dbuildtype=release"
374     CFLAGS: "-Werror"
375
376 fedora:29@scan-build:
377   extends: .fedora-build@template
378   variables:
379     FEDORA_VERSION: 29
380     NINJA_ARGS: scan-build
381   before_script:
382     - dnf install -y clang-analyzer findutils
383   after_script:
384     - test ! -d "$MESON_BUILDDIR"/meson-logs/scanbuild && exit 0
385     - test $(find "$MESON_BUILDDIR"/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 && exit 0
386     - echo "Check scan-build results"
387     - /bin/false
388
389 # Below jobs are build option combinations. We only
390 # run them on one image, they shouldn't fail on one distro
391 # when they succeed on another.
392
393 fedora:29@build-no-libwacom:
394   extends: .fedora-build@template
395   variables:
396     FEDORA_VERSION: 29
397     MESON_ARGS: "-Dlibwacom=false"
398
399 fedora:29@build-no-libwacom-nodeps:
400   extends: .fedora-build@template
401   variables:
402     FEDORA_VERSION: 29
403     MESON_ARGS: "-Dlibwacom=false"
404   before_script:
405     - dnf remove -y libwacom libwacom-devel
406
407 fedora:29@build-no-docs:
408   extends: .fedora-build@template
409   variables:
410     FEDORA_VERSION: 29
411     MESON_ARGS: "-Ddocumentation=false"
412
413 fedora:29@build-no-docs-nodeps:
414   extends: .fedora-build@template
415   variables:
416     FEDORA_VERSION: 29
417     MESON_ARGS: "-Ddocumentation=false"
418   before_script:
419     - dnf remove -y doxygen graphviz
420
421 fedora:29@build-no-debuggui:
422   extends: .fedora-build@template
423   variables:
424     FEDORA_VERSION: 29
425     MESON_ARGS: "-Ddebug-gui=false"
426
427 fedora:29@build-no-debuggui-nodeps:
428   extends: .fedora-build@template
429   variables:
430     FEDORA_VERSION: 29
431     MESON_ARGS: "-Ddebug-gui=false"
432   before_script:
433     - dnf remove -y gtk3-devel
434
435 fedora:29@build-no-tests:
436   extends: .fedora-build@template
437   variables:
438     FEDORA_VERSION: 29
439     MESON_ARGS: "-Dtests=false"
440
441 fedora:29@build-no-tests-nodeps:
442   extends: .fedora-build@template
443   variables:
444     FEDORA_VERSION: 29
445     MESON_ARGS: "-Dtests=false"
446   before_script:
447     - dnf remove -y check-devel
448
449 fedora:29@valgrind:
450   extends: .fedora-build@template
451   variables:
452     FEDORA_VERSION: 29
453   before_script:
454     - dnf install -y valgrind
455   # note: we override the default_build here by providing a new script
456   script:
457    - rm -rf "$MESON_BUILDDIR"
458    - meson "$MESON_BUILDDIR" $MESON_ARGS
459    - meson configure "$MESON_BUILDDIR"
460    - meson test -C "$MESON_BUILDDIR" --setup=valgrind
461
462 #
463 # Ubuntu
464 #
465
466 .ubuntu@template:
467   extends: .build@template
468   image: $UBUNTU_CONTAINER_IMAGE
469
470 ubuntu:18.10@default-build:
471   extends: .ubuntu@template
472   variables:
473     UBUNTU_VERSION: "18.10"
474
475 ubuntu:18.04@default-build:
476   extends: .ubuntu@template
477   variables:
478     UBUNTU_VERSION: "18.04"
479
480 #
481 # Arch
482 #
483 .arch@template:
484   extends: .build@template
485   image: $ARCH_CONTAINER_IMAGE
486
487 arch:rolling@default-build:
488   extends: .arch@template
489
490 #
491 # FreeBSD
492 #
493 .freebsd@template:
494   extends: .build@template
495   image: $FREEBSD_CONTAINER_IMAGE
496   variables:
497     MESON_ARGS: '--cross-file freebsd -Ddocumentation=false -Dtests=false -Depoll-dir=/freebsd/usr/local/'
498     # Can't run FreeBSD tests on Linux machine, so NINJA_ARGS shouldn't be "test"
499     NINJA_ARGS: ''
500
501 freebsd:11.2@default-build:
502   extends: .freebsd@template
503
504 #
505 # deploy
506 #
507
508 wayland-web:
509   image: $BUILDAH_IMAGE
510   stage: deploy
511   script:
512     - curl --request POST
513            --form "token=$WAYLAND_WEB_TOKEN"
514            --form ref=master
515            https://gitlab.freedesktop.org/api/v4/projects/wayland${SLASH}wayland${DOT}freedesktop${DOT}org/trigger/pipeline
516   only:
517     refs:
518       - master
519     variables:
520       - $CI_PROJECT_PATH == "libinput/libinput"
521   dependencies: []
522   variables:
523     DOT: "%2E"
524     SLASH: "%2F"