904874cab947ff687e38bf58c8bae3d4f6cfdefd
[platform/upstream/libinput.git] / .gitlab-ci / gitlab-ci.tmpl
1 # vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
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:31@build-default
26
27 .templates_sha: &template_sha 395535ce90eb48e260c0dff12c35d9237e22c539 # see https://docs.gitlab.com/ee/ci/yaml/#includefile
28
29 include:
30   {% for template in templates %}
31   # {{ template.capitalize() }} container builder template
32   - project: 'freedesktop/ci-templates'
33     ref: *template_sha
34     file: '/templates/{{template}}.yml'
35   {% endfor %}
36
37 stages:
38   - prep             # prep work like rebuilding the container images if there is a change
39   - build            # for actually building and testing things in a container
40   - VM               # for running the test suite in a VM
41   - valgrind         # for running the test suite under valgrind in a VM
42   - distro           # distribs test
43   - deploy           # trigger wayland's website generation
44   - container_clean  # clean up unused container images
45
46 variables:
47   ###############################################################################
48   # This is the list of packages required to build libinput with the default    #
49   # configuration.                                                              #
50   #                                                                             #
51   # Run dnf install/apt-get install/.. with the list of packages for your       #
52   # distribution                                                                #
53   #                                                                             #
54   # See the documentation here:                                                 #
55   # https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html  #
56   ###############################################################################
57   FEDORA_PACKAGES:    'git gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel   gtk3-devel   glib2-devel    mtdev-devel diffutils'
58   FEDORA_QEMU_RPMS:   'git gcc gcc-c++ pkgconf-pkg-config meson check-devel libudev-devel libevdev-devel doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx_rtd_theme python3-pytest-xdist libwacom-devel cairo-devel   gtk3-devel   glib2-devel    mtdev-devel diffutils valgrind'
59   UBUNTU_PACKAGES:    'git gcc g++     pkg-config         meson check       libudev-dev   libevdev-dev   doxygen graphviz python3-sphinx python3-recommonmark python3-sphinx-rtd-theme python3-pytest-xdist libwacom-dev   libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev'
60   ARCH_PACKAGES:      'git gcc         pkgconfig          meson check       libsystemd    libevdev       doxygen graphviz python-sphinx  python-recommonmark  python-sphinx_rtd_theme  python-pytest-xdist  libwacom                     gtk3                        mtdev      diffutils'
61   FREEBSD_BUILD_PKGS: 'meson'
62   FREEBSD_PKGS:       'libepoll-shim                                        libudev-devd  libevdev                                                                                     libwacom                     gtk3                        libmtdev   '
63   ALPINE_PACKAGES:    'git gcc build-base pkgconfig       meson check-dev   eudev-dev     libevdev-dev                                                                                 libwacom-dev   cairo-dev     gtk+3.0-dev  mtdev-dev bash'
64   ############################ end of package lists #############################
65
66   # these tags should be updated each time the list of packages is updated
67   # changing these will force rebuilding the associated image
68   # Note: these tags have no meaning and are not tied to a particular
69   # libinput version
70   FEDORA_TAG:  '2020-03-17.0'
71   UBUNTU_TAG:  '2020-03-17.0'
72   ARCH_TAG:    '2020-03-17.0'
73   ALPINE_TAG:  '2020-03-17.0'
74   FREEBSD_TAG: '2020-03-17.0'
75   QEMU_TAG:    'qemu-vm-2020-03-17.0'
76
77   UBUNTU_EXEC: "bash .gitlab-ci/ubuntu_install.sh $UBUNTU_CUSTOM_DEBS"
78
79   FREEBSD_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/freebsd/11.2:$FREEBSD_TAG
80   FDO_UPSTREAM_REPO: libinput/libinput
81
82   MESON_BUILDDIR: "build dir"
83   NINJA_ARGS: ''
84   MESON_ARGS: ''
85   MESON_TEST_ARGS: '--no-suite=hardware'
86
87   # udev isn't available/working properly in the containers
88   UDEV_NOT_AVAILABLE: 1
89   GIT_DEPTH: 1
90
91 .policy:
92   retry:
93     max: 2
94     when:
95       - runner_system_failure
96       - stuck_or_timeout_failure
97   # cancel run when a newer version is pushed to the branch
98   interruptible: true
99
100 .default_artifacts:
101   artifacts:
102     name: "meson-logs-$CI_JOB_NAME"
103     when: always
104     expire_in: 1 week
105     paths:
106       - $MESON_BUILDDIR/meson-logs
107     reports:
108       junit: $MESON_BUILDDIR/junit-*.xml
109
110 #################################################################
111 #                                                               #
112 #                          prep stage                           #
113 #                                                               #
114 #################################################################
115
116 # Re-generate the CI script and make sure it's the one currently checked in
117 # If this job fails, re-generate the gitlab-ci.yml script, see
118 # $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
119 #
120 check-ci-script:
121   image: golang:alpine
122   stage: prep
123   before_script:
124     - apk add python3 git
125     - pip3 install --user jinja2
126   script:
127     - python3 ./.gitlab-ci/generate-gitlab-ci.py
128     - git diff --exit-code && exit 0 || true
129     - echo "Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify"
130     - exit 1
131
132 #
133 # Verify that commit messages are as expected, signed-off, etc.
134 #
135
136 check-commit:
137   image: golang:alpine
138   stage: prep
139   before_script:
140     - apk add python3 git
141   script:
142     - pip3 install GitPython
143     - pip3 install pytest
144     - |
145       pytest --junitxml=results.xml \
146              --tb=line \
147              --assert=plain \
148              ./.gitlab-ci/check-commit.py
149   except:
150     - master@libinput/libinput
151   variables:
152     GIT_DEPTH: 100
153   artifacts:
154     reports:
155       junit: results.xml
156
157 #
158 # This stage will recreate the container images only if the image
159 # is too old or if it is missing some dependencies.
160 #
161
162 .rebuild_for_schedule:
163   before_script:
164     # force rebuild if schedule, reuse otherwise
165     - if [[ $CI_PIPELINE_SOURCE == "schedule" ]] ; then export FDO_FORCE_REBUILD=1; fi
166
167 fedora:30@qemu-prep:
168   extends:
169     - .fdo.qemu-build@fedora
170     - .policy
171     - .rebuild_for_schedule
172   stage: prep
173   tags:
174     - kvm
175   variables:
176     GIT_STRATEGY: none
177     FDO_DISTRIBUTION_VERSION: 30
178     FDO_DISTRIBUTION_TAG: $QEMU_TAG
179     FDO_DISTRIBUTION_PACKAGES: $FEDORA_QEMU_RPMS
180   allow_failure: true
181
182 {% for distro in distributions %}
183 {{distro.name}}:{{distro.version}}@container-prep:
184   extends:
185     - .fdo.container-build@{{distro.name}}
186     - .policy
187     - .rebuild_for_schedule
188   stage: prep
189   variables:
190     GIT_STRATEGY: none
191     FDO_DISTRIBUTION_VERSION: '{{distro.version}}'
192     FDO_DISTRIBUTION_PACKAGES: ${{distro.name.upper()}}_PACKAGES
193     FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
194  {% if version == 'ubuntu'%}
195     FDO_DISTRIBUTION_EXEC: $UBUNTU_EXEC
196  {% endif %}
197
198 {% endfor %}
199
200
201 # Note that we want to use the latest buildah image, and for that
202 # we use one of the .fdo.container-build@distribution by replacing the
203 # `script`.
204 .freebsd@container-prep:
205   extends:
206     - .policy
207     - .fdo.container-build@fedora
208   stage: prep
209   script:
210     # log in to the registry
211     - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
212
213     # get the full container image name
214     - export IMAGE=freebsd/$FREEBSD_VERSION:$FREEBSD_TAG
215
216     # force rebuild if schedule, reuse otherwise
217     - if [[ $CI_PIPELINE_SOURCE == "schedule" ]] ; then touch .scheduled; fi
218
219     # pull the latest upstream image if it exists
220     - test -e .scheduled || skopeo copy --dest-creds $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD
221                                  docker://$CI_REGISTRY/$FDO_UPSTREAM_REPO/$IMAGE
222                                  docker://$CI_REGISTRY_IMAGE/$IMAGE && exit 0 || true ;
223
224     # check if our image is already in the current registry
225     - test -e .scheduled || skopeo inspect docker://$CI_REGISTRY_IMAGE/$IMAGE > /dev/null && exit 0 || true ;
226
227     - export BUILDAH_RUN="buildah run --isolation chroot"
228     - export BUILDAH_COMMIT="buildah commit --format docker"
229     - buildcntr=$(buildah from --quiet  myfreeweb/freebsd-cross:latest)
230     - $BUILDAH_RUN $buildcntr apk add --no-cache $FREEBSD_BUILD_PKGS
231     - $BUILDAH_RUN $buildcntr pkg -r /freebsd update -f
232     - $BUILDAH_RUN $buildcntr pkg -r /freebsd install -y $FREEBSD_PKGS
233     - buildah config --workingdir /app $buildcntr
234     # tag the current container
235     - $BUILDAH_COMMIT $buildcntr $FREEBSD_CONTAINER_IMAGE
236     # clean up the working container
237     - buildah rm $buildcntr
238
239     # push the container image to the libinput registry
240     - podman push --quiet $FREEBSD_CONTAINER_IMAGE
241     - skopeo copy --dest-creds $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD
242         docker://$FREEBSD_CONTAINER_IMAGE
243         docker://$CI_REGISTRY_IMAGE/freebsd/$FREEBSD_VERSION:$CI_JOB_ID
244
245 freebsd:11.2@container-prep:
246   extends:
247     - .freebsd@container-prep
248   variables:
249     GIT_STRATEGY: none
250     FREEBSD_VERSION: "11.2"
251
252
253 #################################################################
254 #                                                               #
255 #                   container clean stage                       #
256 #                 run during the clean stage                    #
257 #                                                               #
258 #################################################################
259
260 #
261 # This stage will look for the container images we currently have in
262 # the registry and will remove any that are not tagged with the provided
263 # $container_image:$tag
264 #
265 .container-clean:
266   stage: container_clean
267   extends:
268     - .policy
269   image: golang:alpine
270   before_script:
271     - apk add python3 git
272     - pip3 install git+http://gitlab.freedesktop.org/freedesktop/ci-templates
273   script:
274     # Go to your Profile, Settings, Access Tokens
275     # Create a personal token with 'api' scope, copy the value.
276     # Go to CI/CD, Schedules, schedule a new monthly job (or edit the existing one)
277     # Define a variable of type File named AUTHFILE. Content is that token
278     # value.
279     - ci-fairy -v --authfile $AUTHFILE delete-image
280             --repository $FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION
281             --exclude-tag $FDO_DISTRIBUTION_TAG
282   dependencies: []
283   allow_failure: true
284   only:
285     - schedules
286
287 {% for distro in distributions %}
288 {{distro.name}}:{{distro.version}}@container-clean:
289   extends:
290     - .container-clean
291   variables:
292     GIT_STRATEGY: none
293     {{distro.name.upper()}}_VERSION: '{{distro.version}}'
294     CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/{{distro.name}}/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
295     FDO_DISTRIBUTION_VERSION: '{{distro.version}}'
296     FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
297
298 {% endfor %}
299
300 freebsd:11.2@container-clean:
301   extends:
302     - .container-clean
303   variables:
304     GIT_STRATEGY: none
305     CURRENT_CONTAINER_IMAGE: $FREEBSD_CONTAINER_IMAGE
306
307 #################################################################
308 #                                                               #
309 #                       build stage                             #
310 #                                                               #
311 #################################################################
312
313 .build@template:
314   extends:
315     - .policy
316     - .default_artifacts
317   stage: build
318   script:
319     - .gitlab-ci/meson-build.sh
320   dependencies: []
321
322 #
323 # Fedora
324 #
325
326 .check_tainted: &check_tainted |
327   # make sure the kernel is not tainted
328   if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
329   then
330     echo tainted kernel ;
331     exit 1 ;
332   fi
333
334 # Run in a test suite. Special variables:
335 # - SUITES: the meson test suites to run, or
336 # - SUITE_NAMES: all elements will be expanded to libinput-test-suite-$value
337 # Set one or the other, not both.
338 .test-suite-vm:
339   extends:
340     - .policy
341     - .fdo.distribution-image@fedora
342   stage: VM
343   tags:
344     - kvm
345   variables:
346     MESON_BUILDDIR: build_dir
347     # remove the global --no-suite=hardware
348     MESON_TEST_ARGS: ''
349   before_script:
350     - if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
351     - echo "Testing $SUITES"
352   script:
353     # start our vm, no args required
354     - /app/start_vm.sh || (echo "Error - Failed to start the VM." && exit 1)
355
356     - *check_tainted
357
358     - "scp -P 5555 -r $PWD localhost:"
359     - echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
360     - echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
361     - echo "MESON_ARGS=\"$MESON_ARGS\"" >> sshenv
362     - echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
363     - echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS $SUITES\"" >> sshenv
364     - echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
365     - "scp -P 5555 sshenv localhost:~/$CI_PROJECT_NAME/.meson_environment"
366     - ssh localhost -p 5555 "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
367     # no matter the results of the tests, we want to fetch the logs
368     - scp -P 5555 -r localhost:$CI_PROJECT_NAME/$MESON_BUILDDIR .
369
370     - *check_tainted
371
372     - ssh localhost -p 5555 halt || true
373     - sleep 2
374     - pkill qemu || true
375
376     - if [[ ! -e .success ]] ;
377       then
378         exit 1 ;
379       fi
380   artifacts:
381     name: "qemu-meson-logs-$CI_JOB_NAME"
382     when: always
383     expire_in: 1 week
384     paths:
385       - $MESON_BUILDDIR/meson-logs
386       - console.out
387     reports:
388       junit: $MESON_BUILDDIR/junit-*.xml
389
390   allow_failure: true
391   retry:
392     max: 2
393     when: script_failure
394
395
396 .fedora:30@test-suite-vm:
397   extends:
398     - .test-suite-vm
399   variables:
400     FDO_DISTRIBUTION_VERSION: 30
401     FDO_DISTRIBUTION_TAG: $QEMU_TAG
402   needs: ['fedora:30@qemu-prep']
403
404
405 {% for suite in test_suites %}
406 vm-{{suite.name}}:
407   extends:
408     - .fedora:30@test-suite-vm
409   variables:
410     SUITE_NAMES: '{{suite.suites}}'
411
412 vm-{{suite.name}}-no-libwacom:
413   extends:
414     - vm-{{suite.name}}
415   variables:
416     MESON_ARGS: '-Dlibwacom=false'
417
418 {% endfor %}
419
420 {% for suite in test_suites %}
421 vm-valgrind-{{suite.name}}:
422   stage: valgrind
423   extends:
424     - vm-{{suite.name}}
425   variables:
426     MESON_TEST_ARGS: '--setup=valgrind'
427
428 {% endfor %}
429
430
431 .fedora-build@template:
432   extends:
433     - .fdo.distribution-image@fedora
434     - .build@template
435   variables:
436     FDO_DISTRIBUTION_VERSION: '30'
437     FDO_DISTRIBUTION_TAG: $FEDORA_TAG
438   needs: ['fedora:30@container-prep']
439
440 default-build-release@fedora:30:
441   stage: distro
442   extends:
443     - .fedora-build@template
444   variables:
445     MESON_ARGS: "-Dbuildtype=release"
446     CFLAGS: "-Werror"
447
448 scan-build@fedora:30:
449   extends:
450     - .fedora-build@template
451   variables:
452     NINJA_ARGS: scan-build
453     MESON_TEST_ARGS: ''
454   before_script:
455     - dnf install -y clang-analyzer findutils
456   after_script:
457     - test ! -d "$MESON_BUILDDIR"/meson-logs/scanbuild && exit 0
458     - test $(find "$MESON_BUILDDIR"/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 && exit 0
459     - echo "Check scan-build results"
460     - /bin/false
461
462 # Below jobs are build option combinations. We only
463 # run them on one image, they shouldn't fail on one distro
464 # when they succeed on another.
465
466 build-no-libwacom@fedora:30:
467   extends:
468     - .fedora-build@template
469   variables:
470     MESON_ARGS: "-Dlibwacom=false"
471
472 build-no-libwacom-nodeps@fedora:30:
473   extends:
474     - .fedora-build@template
475   variables:
476     MESON_ARGS: "-Dlibwacom=false"
477   before_script:
478     - dnf remove -y libwacom libwacom-devel
479
480 build-no-docs@fedora:30:
481   extends:
482     - .fedora-build@template
483   variables:
484     MESON_ARGS: "-Ddocumentation=false"
485
486 build-no-docs-nodeps@fedora:30:
487   extends:
488     - .fedora-build@template
489   variables:
490     MESON_ARGS: "-Ddocumentation=false"
491   before_script:
492     - dnf remove -y doxygen graphviz
493
494 build-no-debuggui@fedora:30:
495   extends:
496     - .fedora-build@template
497   variables:
498     MESON_ARGS: "-Ddebug-gui=false"
499
500 build-no-debuggui-nodeps@fedora:30:
501   extends:
502     - .fedora-build@template
503   variables:
504     MESON_ARGS: "-Ddebug-gui=false"
505   before_script:
506     - dnf remove -y gtk3-devel
507
508 build-no-tests@fedora:30:
509   extends:
510     - .fedora-build@template
511   variables:
512     MESON_ARGS: "-Dtests=false"
513
514 build-no-tests-nodeps@fedora:30:
515   extends:
516     - .fedora-build@template
517   variables:
518     MESON_ARGS: "-Dtests=false"
519   before_script:
520     - dnf remove -y check-devel
521
522 valgrind@fedora:30:
523   extends:
524     - .fedora-build@template
525   variables:
526     MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
527   before_script:
528     - dnf install -y valgrind
529
530 # Python checks, only run on Fedora
531
532 usr-bin-env-python@fedora:30:
533   extends:
534     - .fedora-build@template
535   script:
536     - |
537       if git grep -l '^#!/usr/bin/python'; then
538         echo "Use '/usr/bin/env python3' in the above files";
539         /bin/false
540       fi
541
542 flake8@fedora:30:
543   extends:
544     - .fedora-build@template
545   before_script:
546     - dnf install -y python3-flake8
547   script:
548     - flake8-3 --ignore=W501,E501,W504 $(git grep -l '^#!/usr/bin/env python3')
549
550 #################################################################
551 #                                                               #
552 #                        distro stage                           #
553 #                                                               #
554 #################################################################
555
556 {% for distro in distributions %}
557 {{distro.name}}:{{distro.version}}@default-build:
558   stage: distro
559   extends:
560     - .build@template
561     - .fdo.distribution-image@{{distro.name}}
562   variables:
563     FDO_DISTRIBUTION_VERSION: '{{distro.version}}'
564     FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
565     {# Where we have extra_variables defined, add them to the list #}
566     {% if distro.build is defined and distro.build.extra_variables is defined %}
567     {% for var in distro.build.extra_variables %}
568     {{var}}
569     {% endfor %}
570     {% endif %}
571   needs: ['{{distro.name}}:{{distro.version}}@container-prep']
572
573
574 {% endfor %}
575
576 #
577 # FreeBSD
578 #
579 .freebsd@template:
580   stage: distro
581   extends:
582     - .build@template
583   image: $FREEBSD_CONTAINER_IMAGE
584   variables:
585     MESON_ARGS: '--cross-file freebsd -Ddocumentation=false -Dtests=false -Depoll-dir=/freebsd/usr/local/'
586     # Can't run FreeBSD tests on Linux machine, so MESON_TEST_ARGS shouldn't be "test"
587     MESON_TEST_ARGS: ''
588
589 freebsd:11.2@default-build:
590   extends:
591     - .freebsd@template
592   needs: ['freebsd:11.2@container-prep']
593
594 #
595 # deploy
596 #
597
598 wayland-web:
599   image: alpine:latest
600   stage: deploy
601   script:
602     - apk add curl
603     # Requirements:
604     # - variable WAYLAND_WEB_TOKEN defined as type File in libinput's CI/CD settings
605     # - content of that file is the token value, as generated by the Pipeline Triggers
606     #   of the wayland.freedesktop.org project.
607     - curl --request POST
608            --form "token=<$WAYLAND_WEB_TOKEN"
609            --form ref=master
610            https://gitlab.freedesktop.org/api/v4/projects/wayland${SLASH}wayland${DOT}freedesktop${DOT}org/trigger/pipeline
611   except:
612     refs:
613       - schedules
614   only:
615     refs:
616       - master
617     variables:
618       - $CI_PROJECT_PATH == "libinput/libinput"
619   dependencies: []
620   variables:
621     DOT: "%2E"
622     SLASH: "%2F"
623