9860ad65bf42c1c828fba5bec695ac03bc5d7ec2
[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 docker image for each distribution
6 #   tested, then run the tests on this docker image.
7 #
8 #   Creating a docker 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_PARAMS=-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:28@build-default
26
27 stages:
28   - docker_check  # check if the current docker images are up to date
29   - docker_prep   # rebuild the docker images if previous step failed
30   - build         # for actually building things
31
32 variables:
33   ###############################################################################
34   # This is the list of packages required to build libinput with the default    #
35   # configuration.                                                              #
36   #                                                                             #
37   # Run dnf install/apt-get install/.. with the list of packages for your       #
38   # distribution                                                                #
39   #                                                                             #
40   # See the documentation here:                                                 #
41   # https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html  #
42   ###############################################################################
43   FEDORA_RPMS: 'git gcc gcc-c++ meson check-devel libudev-devel libevdev-devel doxygen graphviz valgrind binutils libwacom-devel cairo-devel   gtk3-devel   glib2-devel    mtdev-devel'
44   UBUNTU_DEBS: 'git gcc g++     meson check       libudev-dev   libevdev-dev   doxygen graphviz valgrind binutils libwacom-dev   libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev'
45   ############################ end of package lists #############################
46   MESON_BUILDDIR: builddir
47   NINJA_ARGS: ''
48   MESON_PARAMS: ''
49   FEDORA_DOCKER_IMAGE: $CI_REGISTRY/libinput/$CI_PROJECT_NAME/fedora/$FEDORA_VERSION:latest
50   UBUNTU_DOCKER_IMAGE: $CI_REGISTRY/libinput/$CI_PROJECT_NAME/ubuntu/$UBUNTU_VERSION:latest
51   # When using docker-in-docker (dind), it's wise to use the overlayfs driver
52   # for improved performance.
53   DOCKER_DRIVER: overlay2
54   GIT_DEPTH: 1
55
56 .default_artifacts: &default_artifacts
57   artifacts:
58     name: "meson-logs-$CI_JOB_NAME"
59     when: always
60     expire_in: 1 week
61     paths:
62       - $MESON_BUILDDIR/meson-logs
63
64 # The default build instructions
65 .default_build: &default_build
66   script:
67    - rm -rf $MESON_BUILDDIR
68    - meson $MESON_BUILDDIR $MESON_PARAMS
69    - meson configure $MESON_BUILDDIR
70    - ninja -C $MESON_BUILDDIR $NINJA_ARGS
71
72 # special rule to not expose the docker creation runners to other users
73 # than those who have set up the CI to push on the registry.
74 # Users who have write access to libinput/libinput will have write
75 # access to the registry, so the libinput/libinput is a catch-all for
76 # our core developers.
77 #
78 # we can add as many users as we want by adding a new line like:
79 #   - $GITLAB_USER_LOGIN == "someone"
80 .restrict_docker_creation: &restrict_docker_creation
81   only:
82     variables:
83       # Note: this is a set of logical OR, not AND
84       - $CI_PROJECT_PATH == "libinput/libinput"
85
86 #################################################################
87 #                                                               #
88 #                     docker check stage                        #
89 #                                                               #
90 #################################################################
91
92 # we need a minimalist image capable of curl, jq, date and test.
93 # instead of using a full fedora and install the dependencies, we
94 # can reuse the one from https://github.com/endeveit/docker-jq with
95 # the following Dockerfile:
96 #   FROM alpine
97 #   MAINTAINER Nikita Vershinin <endeveit@gmail.com>
98 #
99 #   RUN apk add --update --no-cache curl jq
100 #
101 #   CMD ["sh"]
102
103 .docker-check: &docker_check
104   stage: docker_check
105   image: registry.freedesktop.org/libinput/libinput/jq:latest
106   script:
107     # get the full docker image name (CURRENT_DOCKER_IMAGE still has indirections)
108     - DOCKER_IMAGE=$(eval echo "$CURRENT_DOCKER_IMAGE")
109     - REPOSITORY=$(echo $DOCKER_IMAGE | cut -f2- -d/ | cut -f1 -d:)
110     - TAG=$(echo $DOCKER_IMAGE | cut -f2 -d:)
111
112     # request a token for the registry API
113     - REGISTRY_TOKEN=$(curl https://gitlab.freedesktop.org/jwt/auth --get
114                              --silent --show-error
115                              -d client_id=docker
116                              -d offline_token=true
117                              -d service=container_registry
118                              -d "scope=repository:$REPOSITORY:pull,*"
119                              --fail
120                              --user $CI_REGISTRY_USER:$CI_JOB_TOKEN
121                              | sed -r 's/(\{"token":"|"\})//g')
122
123     # get the date of the current image
124     - IMG_DATE=$(curl https://$CI_REGISTRY/v2/$REPOSITORY/manifests/$TAG --silent
125                       -H "accept:application/vnd.docker.distribution.manifest.v1+json"
126                       -H "authorization:Bearer $REGISTRY_TOKEN"
127                       | jq -r '[.history[]]|map(.v1Compatibility|fromjson|.created)|sort|reverse|.[0]'
128                       | cut -dT -f1)
129
130     - TODAY_SECS=$(date -u +%s)
131     - IMG_SECS=$(date -u --date="$IMG_DATE" +%s)
132     - echo "today $TODAY_SECS, image $IMG_SECS"
133
134     # check if image is less than a week old
135     - test $(($IMG_SECS + 604800)) -gt $TODAY_SECS
136
137     # export an artefact telling the next stage that the image is valid
138     - touch .img_ready
139   artifacts:
140     name: image $CURRENT_DOCKER_IMAGE check
141     expire_in: 20 min
142     paths:
143       - .img_ready
144   allow_failure: true
145   <<: *restrict_docker_creation
146
147
148 # TODO: check that the RPMS/DEBS are all in the current images
149
150 fedora:28@docker-check:
151   variables:
152     GIT_STRATEGY: none
153     FEDORA_VERSION: 28
154     CURRENT_DOCKER_IMAGE: $FEDORA_DOCKER_IMAGE
155   <<: *docker_check
156
157 fedora:27@docker-check:
158   variables:
159     GIT_STRATEGY: none
160     FEDORA_VERSION: 27
161     CURRENT_DOCKER_IMAGE: $FEDORA_DOCKER_IMAGE
162   <<: *docker_check
163
164 ubuntu:17.10@docker-check:
165   variables:
166     GIT_STRATEGY: none
167     UBUNTU_VERSION: "17.10"
168     CURRENT_DOCKER_IMAGE: $UBUNTU_DOCKER_IMAGE
169   <<: *docker_check
170
171 ubuntu:18.04@docker-check:
172   variables:
173     GIT_STRATEGY: none
174     UBUNTU_VERSION: "18.04"
175     CURRENT_DOCKER_IMAGE: $UBUNTU_DOCKER_IMAGE
176   <<: *docker_check
177
178
179 #################################################################
180 #                                                               #
181 #                     docker prep stage                         #
182 #                                                               #
183 #################################################################
184
185 #
186 # This stage will recreate the docker images only if the previous
187 # stage had a build failure, i.e. the image is too old or if it is
188 # missing some dependencies.
189 #
190 .fedora@docker-prep: &fedora_docker_prep
191   stage: docker_prep
192   services:
193     - docker:dind
194   script:
195     # if the check was successful, we just skip recreating the docker image
196     - test -e .img_ready && exit 0
197
198     - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
199
200     # create a Dockerfile with our dependencies
201     - echo "FROM fedora:$FEDORA_VERSION" > Dockerfile
202     - echo "WORKDIR /app" >> Dockerfile
203     - echo "RUN dnf upgrade -y ; dnf clean all" >> Dockerfile
204     - echo "RUN dnf install -y $FEDORA_RPMS ; dnf clean all" >> Dockerfile
205
206     # create the docker image
207     - docker build --tag $FEDORA_DOCKER_IMAGE .
208
209     # push the docker image to the libinput registry
210     - docker push $FEDORA_DOCKER_IMAGE
211   <<: *restrict_docker_creation
212
213 fedora:28@docker-prep:
214   variables:
215     GIT_STRATEGY: none
216     FEDORA_VERSION: 28
217   <<: *fedora_docker_prep
218   dependencies:
219     # Note: we can not use $FEDORA_VERSION here
220     - fedora:28@docker-check
221
222 fedora:27@docker-prep:
223   variables:
224     GIT_STRATEGY: none
225     FEDORA_VERSION: 27
226   <<: *fedora_docker_prep
227   dependencies:
228     # Note: we can not use $FEDORA_VERSION here
229     - fedora:27@docker-check
230
231 # FIXME: we should clean up the apt cache between each run
232 .ubuntu@docker-prep: &ubuntu_docker_prep
233   stage: docker_prep
234   services:
235     - docker:dind
236   script:
237     # if the check was successful, we just skip recreating the docker image
238     - test -e .img_ready && exit 0
239
240     - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
241
242     # create a Dockerfile with our dependencies
243     - echo "FROM ubuntu:$UBUNTU_VERSION" > Dockerfile
244     - echo "WORKDIR /app" >> Dockerfile
245     - echo "RUN apt-get update" >> Dockerfile
246     - echo "RUN apt-get install -y software-properties-common" >> Dockerfile
247     - echo "RUN add-apt-repository universe" >> Dockerfile
248     - echo "RUN apt-get update" >> Dockerfile
249     - echo "RUN apt-get install -y $UBUNTU_DEBS" >> Dockerfile
250
251     # create the docker image
252     - docker build --tag $UBUNTU_DOCKER_IMAGE .
253
254     # push the docker image to the libinput registry
255     - docker push $UBUNTU_DOCKER_IMAGE
256   <<: *restrict_docker_creation
257
258 ubuntu:17.10@docker-prep:
259   variables:
260     GIT_STRATEGY: none
261     UBUNTU_VERSION: "17.10"
262   <<: *ubuntu_docker_prep
263   dependencies:
264     # Note: we can not use $UBUNTU_VERSION here
265     - ubuntu:17.10@docker-check
266
267 ubuntu:18.04@docker-prep:
268   variables:
269     GIT_STRATEGY: none
270     UBUNTU_VERSION: "18.04"
271   <<: *ubuntu_docker_prep
272   dependencies:
273     # Note: we can not use $UBUNTU_VERSION here
274     - ubuntu:18.04@docker-check
275
276 # Add some manual runners to be able to recreate the cache on a day
277 # the list of the rpms changed
278
279 fedora:28@force-docker-prep:
280   variables:
281     GIT_STRATEGY: none
282     FEDORA_VERSION: 28
283   <<: *fedora_docker_prep
284   when: manual
285   dependencies: []
286
287 fedora:27@force-docker-prep:
288   variables:
289     GIT_STRATEGY: none
290     FEDORA_VERSION: 27
291   <<: *fedora_docker_prep
292   when: manual
293   dependencies: []
294
295 ubuntu:17.10@force-docker-prep:
296   variables:
297     GIT_STRATEGY: none
298     UBUNTU_VERSION: "17.10"
299   <<: *ubuntu_docker_prep
300   when: manual
301   dependencies: []
302
303 ubuntu:18.04@force-docker-prep:
304   variables:
305     GIT_STRATEGY: none
306     UBUNTU_VERSION: "18.04"
307   <<: *ubuntu_docker_prep
308   when: manual
309   dependencies: []
310
311 #################################################################
312 #                                                               #
313 #                       build stage                             #
314 #                                                               #
315 #################################################################
316
317 #
318 # Fedora
319 #
320
321 .fedora@template: &fedora_template
322   stage: build
323   image: $FEDORA_DOCKER_IMAGE
324   <<: *default_artifacts
325   dependencies: []
326
327 fedora:27@default-build:
328   variables:
329     FEDORA_VERSION: 27
330   <<: *fedora_template
331   <<: *default_build
332
333 .fedora:28@template: &fedora_28_template
334   variables:
335     FEDORA_VERSION: 28
336   <<: *fedora_template
337
338 fedora:28@default-build:
339   <<: *fedora_28_template
340   <<: *default_build
341
342 # Below jobs are build option combinations. We only
343 # run them on one image, they shouldn't fail on one distro
344 # when they succeed on another.
345
346 fedora:28@build-no-libwacom:
347   <<: *fedora_28_template
348   <<: *default_build
349   variables:
350     FEDORA_VERSION: 28
351     MESON_PARAMS: "-Dlibwacom=false"
352
353 fedora:28@build-no-libwacom-nodeps:
354   <<: *fedora_28_template
355   <<: *default_build
356   variables:
357     FEDORA_VERSION: 28
358     MESON_PARAMS: "-Dlibwacom=false"
359   before_script:
360     - dnf remove -y libwacom libwacom-devel
361
362 fedora:28@build-no-docs:
363   <<: *fedora_28_template
364   <<: *default_build
365   variables:
366     FEDORA_VERSION: 28
367     MESON_PARAMS: "-Ddocumentation=false"
368
369 fedora:28@build-no-docs-nodeps:
370   <<: *fedora_28_template
371   <<: *default_build
372   variables:
373     FEDORA_VERSION: 28
374     MESON_PARAMS: "-Ddocumentation=false"
375   before_script:
376     - dnf remove -y doxygen graphviz
377
378 fedora:28@build-no-debuggui:
379   <<: *fedora_28_template
380   <<: *default_build
381   variables:
382     FEDORA_VERSION: 28
383     MESON_PARAMS: "-Ddebug-gui=false"
384
385 fedora:28@build-no-debuggui-nodeps:
386   <<: *fedora_28_template
387   <<: *default_build
388   variables:
389     FEDORA_VERSION: 28
390     MESON_PARAMS: "-Ddebug-gui=false"
391   before_script:
392     - dnf remove -y gtk3-devel
393
394 fedora:28@build-no-tests:
395   <<: *fedora_28_template
396   <<: *default_build
397   variables:
398     FEDORA_VERSION: 28
399     MESON_PARAMS: "-Dtests=false"
400
401 fedora:28@build-no-tests-nodeps:
402   <<: *fedora_28_template
403   <<: *default_build
404   variables:
405     FEDORA_VERSION: 28
406     MESON_PARAMS: "-Dtests=false"
407   before_script:
408     - dnf remove -y check-devel
409
410 fedora:28@scan-build:
411   <<: *fedora_28_template
412   <<: *default_build
413   variables:
414     FEDORA_VERSION: 28
415     NINJA_ARGS: scan-build
416   before_script:
417     - dnf install -y clang-analyzer findutils
418   after_script:
419     - test ! -d $MESON_BUILDDIR/meson-logs/scanbuild && exit 0
420     - test $(find $MESON_BUILDDIR/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 && exit 0
421     - echo "Check scan-build results"
422     - /bin/false
423
424 #
425 # Ubuntu
426 #
427
428 .ubuntu@template: &ubuntu_template
429   stage: build
430   image: $UBUNTU_DOCKER_IMAGE
431   <<: *default_artifacts
432   dependencies: []
433
434 ubuntu:17.10@default-build:
435   variables:
436     UBUNTU_VERSION: "17.10"
437   <<: *ubuntu_template
438   <<: *default_build
439
440 ubuntu:18.04@default-build:
441   variables:
442     UBUNTU_VERSION: "17.10"
443   <<: *ubuntu_template
444   <<: *default_build