README: note that patches go as MRs to gitlab now
[platform/upstream/libevdev.git] / .gitlab-ci / gitlab-ci.tmpl
1 {# You're looking at the template here, so you can ignore the below
2    warning. This is the right file to edit #}
3 ########################################
4 #                                      #
5 # THIS FILE IS GENERATED, DO NOT EDIT  #
6 #                                      #
7 ########################################
8
9 .templates_sha: &template_sha 8410d3382c4ba5e83da76a027cb332169f2a95ad # see https://docs.gitlab.com/ee/ci/yaml/#includefile
10
11 include:
12   {% for distribution in distributions|map(attribute='name')|unique()|sort() %}
13   # {{ distribution.capitalize() }} container builder template
14   - project: 'wayland/ci-templates'
15     ref: *template_sha
16     file: '/templates/{{distribution}}.yml'
17   {% endfor %}
18
19 stages:
20   - prep             # rebuild the container images if there is a change
21   - build            # for actually building and testing things in a container
22   - VM               # for running the test suite in a VM
23   - autotools        # distribution builds with autotools
24   - meson            # distribution builds with meson
25   - tarballs         # tarball builds
26   - container_clean  # clean up unused container images
27
28 variables:
29   ###############################################################################
30   # This is the list of packages required to build libevdev with the default    #
31   # configuration.                                                              #
32   #                                                                             #
33   # Run dnf install/apt-get install/.. with the list of packages for your       #
34   # distribution                                                                #
35   ###############################################################################
36   FEDORA_RPMS: 'git gcc gcc-c++ meson automake autoconf libtool make pkgconfig  python3 check-devel valgrind binutils doxygen xz clang-analyzer'
37   CENTOS_RPMS: 'git gcc gcc-c++       automake autoconf libtool make pkgconfig  python3 check-devel valgrind binutils xz'
38   UBUNTU_DEBS: 'git gcc g++     meson automake autoconf libtool make pkg-config python3 check       valgrind binutils doxygen xz-utils'
39   DEBIAN_DEBS: $UBUNTU_DEBS
40   ARCH_PKGS:   'git gcc         meson automake autoconf libtool make pkgconfig  python3 check       valgrind binutils doxygen'
41   ALPINE_PKGS: 'git gcc g++     meson automake autoconf libtool make pkgconfig  python3 check-dev   valgrind binutils doxygen xz linux-headers'
42   ############################ end of package lists #############################
43   # these tags should be updated each time the list of packages is updated
44   # changing these will force rebuilding the associated image
45   # Note: these tags have no meaning and are not tied to a particular
46   # libevdev version
47   FEDORA_TAG: '2020-02-26.4'
48   CENTOS_TAG: '2020-02-26.4'
49   DEBIAN_TAG: '2020-02-26.4'
50   UBUNTU_TAG: '2020-02-26.4'
51   ARCH_TAG:   '2020-02-26.4'
52   ALPINE_TAG: '2020-02-26.4'
53   QEMU_TAG:   'qemu-2020-02-26.4'
54
55   UPSTREAM_REPO: libevdev/libevdev
56   BUILDAH_IMAGE: $CI_REGISTRY/wayland/ci-templates/buildah:latest
57   FEDORA_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/fedora/$FEDORA_VERSION:$FEDORA_TAG
58   CENTOS_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/centos/$CENTOS_VERSION:$CENTOS_TAG
59   UBUNTU_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/ubuntu/$UBUNTU_VERSION:$UBUNTU_TAG
60   DEBIAN_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG
61   ARCH_CONTAINER_IMAGE:   $CI_REGISTRY_IMAGE/arch/rolling:$ARCH_TAG
62   ALPINE_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/alpine/latest:$ALPINE_TAG
63   QEMU_CONTAINER_IMAGE:   $CI_REGISTRY_IMAGE/fedora/$FEDORA_VERSION:$QEMU_TAG
64
65   LIBEVDEV_SKIP_ROOT_TESTS: 1
66   GIT_DEPTH: 1
67   MESON_BUILDDIR: 'build dir'
68
69 .default_artifacts:
70   artifacts:
71     paths:
72       - _build/test/test-suite.log
73       - $MESON_BUILDDIR/meson-logs/
74     expire_in: 1 week
75     when: on_failure
76     reports:
77       junit: $MESON_BUILDDIR/junit-*.xml
78
79 .autotools_build:
80   extends:
81     - .default_artifacts
82   script:
83     - mkdir _build
84     - pushd _build > /dev/null
85     - ../autogen.sh --disable-silent-rules $CONFIGURE_FLAGS
86     - make
87     - make check
88     - if ! [[ -z "$MAKE_ARGS" ]]; then make $MAKE_ARGS; fi
89     - popd > /dev/null
90
91 .meson_build:
92   extends:
93     - .default_artifacts
94   script:
95     - .gitlab-ci/meson-build.sh
96
97 #################################################################
98 #                                                               #
99 #                          prep stage                           #
100 #                                                               #
101 #################################################################
102
103 # Re-generate the CI script and make sure it's the one currently checked in
104 # If this job fails, re-generate the gitlab-ci.yml script, see
105 # $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
106 #
107 check-ci-script:
108   image: golang:alpine
109   stage: prep
110   before_script:
111     - apk add python3 git
112     - pip3 install --user jinja2 PyYAML
113   script:
114     - python3 ./.gitlab-ci/generate-gitlab-ci.py
115     - git diff --exit-code && exit 0 || true
116     - echo "Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify"
117     - exit 1
118
119 check-commit:
120   image: golang:alpine
121   stage: prep
122   before_script:
123     - apk add python3 git
124   script:
125     - pip3 install GitPython
126     - pip3 install pytest
127     - |
128       pytest --junitxml=results.xml \
129              --tb=line \
130              --assert=plain \
131              ./.gitlab-ci/check-commit.py
132   except:
133     - master@libevdev/libevdev
134   variables:
135     GIT_DEPTH: 100
136   artifacts:
137     when: on_failure
138     paths:
139       - results.xml
140     reports:
141       junit: results.xml
142
143 .pull_upstream_or_rebuild:
144   before_script:
145     # log in to the registry
146     - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
147
148     # get the full container image name (DISTRIB_VERSION still has indirections)
149     - IMAGE=$(eval echo "$DISTRIB_NAME/$DISTRIB_VERSION:$TAG")
150
151     - |
152       # force rebuild if schedule, reuse otherwise
153       if [[ $CI_PIPELINE_SOURCE != "schedule" ]] ;
154       then
155         # pull the latest upstream image if it exists
156         skopeo copy docker://$CI_REGISTRY/$UPSTREAM_REPO/$IMAGE \
157                     docker://$CI_REGISTRY_IMAGE/$IMAGE && exit 0 || true ;
158
159         # check if our image is already in the current registry
160         skopeo inspect docker://$CI_REGISTRY_IMAGE/$IMAGE > /dev/null && exit 0 || true ;
161       fi
162
163 fedora:31@qemu-prep:
164   extends:
165     - .fedora@qemu-build
166     - .pull_upstream_or_rebuild
167   stage: prep
168   tags:
169     - kvm
170   variables:
171     GIT_STRATEGY: none
172     FEDORA_VERSION: 31
173     FEDORA_TAG: $QEMU_TAG
174     DISTRIB_NAME: fedora
175     DISTRIB_VERSION: $FEDORA_VERSION
176     TAG: $QEMU_TAG
177   allow_failure: true
178
179 {% for distro in distributions %}
180
181 ### {{ distro.name }} {{ distro.version }}
182 {{ distro.name }}:{{ distro.version }}@container-prep:
183   extends:
184     - .{{ distro.name }}@container-build
185     - .pull_upstream_or_rebuild
186   stage: prep
187   variables:
188     GIT_STRATEGY: none
189     {{ distro.name.upper() }}_VERSION: '{{ distro.version }}'
190     DISTRIB_NAME: {{ distro.name }}
191     DISTRIB_VERSION: ${{ distro.name.upper() }}_VERSION
192     TAG: ${{ distro.name.upper() }}_TAG
193
194 {% endfor %}
195
196 #################################################################
197 #                                                               #
198 #                   container clean stage                       #
199 #                 run during the clean stage                    #
200 #                                                               #
201 #################################################################
202
203 #
204 # This stage will look for the container images we currently have in
205 # the registry and will remove any that are not tagged with the provided
206 # $container_image:$tag
207 #
208 .container-clean:
209   stage: container_clean
210   image: $BUILDAH_IMAGE
211   script:
212     # get the full container image name (CURRENT_CONTAINER_IMAGE still has indirections)
213     - CONTAINER_IMAGE=$(eval echo "$CURRENT_CONTAINER_IMAGE")
214     - GITLAB=$(echo $CI_PROJECT_URL | cut -f3 -d/)
215     - REPOSITORY=$(echo $CONTAINER_IMAGE | cut -f2- -d/ | cut -f1 -d:)
216     - IMAGE_PATH=$(echo $CONTAINER_IMAGE | cut -f1 -d:)
217     - LATEST_TAG=$(echo $CONTAINER_IMAGE | cut -f2 -d:)
218
219     # log in to the registry (read only)
220     - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
221
222     # get the r/w token from the settings to access the registry
223     #
224     # each developer needs to register a secret variable that contains
225     # a personal token with api access. The token
226     # - must be named PERSONAL_TOKEN_$USER (for example PERSONAL_TOKEN_bentiss)
227     # - must be registered in the CI/CD Variables section as type file
228     # - value must be a netrc file as a single-line string:
229     #   default login <user> password <token value>
230     #   e.g. "default login bentiss password 1235abcde"
231     - tokenname="PERSONAL_TOKEN_$GITLAB_USER_LOGIN"
232     - netrcfile=$(eval echo "\$$tokenname")
233     - if [[ ! -f "$netrcfile" ]]; then
234          echo "No netrc file found or token is missing, skipping job" && false;
235       fi
236
237     # request a token for the registry API
238     - REGISTRY_TOKEN=$(curl https://$GITLAB/jwt/auth --get
239                              --silent --show-error
240                              -d client_id=docker
241                              -d offline_token=true
242                              -d service=container_registry
243                              -d "scope=repository:$REPOSITORY:pull,*"
244                              --fail
245                              --netrc-file "$netrcfile"
246                              | sed -r 's/(\{"token":"|"\})//g')
247
248     # get the digest of the latest image
249     - LATEST_MANIFEST=$(skopeo inspect docker://$IMAGE_PATH:$LATEST_TAG | jq -r '.Digest')
250
251     # get the list of tags
252     - TAGS=$(skopeo inspect docker://$IMAGE_PATH:$LATEST_TAG | jq -r '.RepoTags[]')
253     # FIXME: is the above command working properly? If not, use below:
254     # - TAGS=$(curl -X GET -H "accept:application/vnd.docker.distribution.manifest.v2+json"
255     #                      -H "authorization:Bearer $REGISTRY_TOKEN"
256     #                      https://$CI_REGISTRY/v2/$REPOSITORY/tags/list | jq -r '.tags[]')
257
258     # iterate over the tags
259     - for tag in $TAGS;
260       do
261         MANIFEST=$(skopeo inspect docker://$IMAGE_PATH:$tag | jq -r '.Digest');
262         if test x"$MANIFEST" != x"$LATEST_MANIFEST";
263           then
264             echo removing $tag as $MANIFEST;
265             curl https://$CI_REGISTRY/v2/$REPOSITORY/manifests/$MANIFEST --silent
266                  -H "accept:application/vnd.docker.distribution.manifest.v2+json"
267                  -H "authorization:Bearer $REGISTRY_TOKEN"
268                  --fail --show-error -X DELETE || true
269           ;fi
270       ;done
271   dependencies: []
272   allow_failure: true
273   only:
274     - schedules
275   variables:
276     GIT_STRATEGY: none
277
278 {% for distro in distributions %}
279
280 ### {{ distro.name }} {{ distro.version }}
281 {{ distro.name }}:{{ distro.version }}@container-clean:
282   extends: .container-clean
283   variables:
284     {{ distro.name.upper() }}_VERSION: '{{ distro.version }}'
285     CURRENT_CONTAINER_IMAGE: ${{ distro.name.upper() }}_CONTAINER_IMAGE
286
287 {% endfor %}
288
289 #################################################################
290 #                                                               #
291 #                       build stage                             #
292 #                                                               #
293 #################################################################
294
295 .autotools-build@template:
296   extends:
297     - .autotools_build
298   stage: build
299   dependencies: []
300   variables:
301     MAKE_ARGS: "distcheck"
302
303 .meson-build@template:
304   extends:
305     - .meson_build
306   stage: build
307   dependencies: []
308   variables:
309     NINJA_ARGS: "dist"
310
311 {% for distro in distributions %}
312
313 {{ distro.name }}:{{ distro.version }}@autotools-build:
314   extends: .autotools-build@template
315   stage: autotools
316   image: ${{ distro.name.upper() }}_CONTAINER_IMAGE
317   variables:
318     {{ distro.name.upper() }}_VERSION: '{{ distro.version }}'
319     {# Where we have extra_variables defined, add them to the list #}
320     {% if distro.build is defined and distro.build.extra_variables is defined %}
321       {% for key, value in distro.build.extra_variables.items() %}
322     {{ key }}: {{ value }}
323       {% endfor %}
324     {% endif %}
325   needs: ['{{ distro.name }}:{{ distro.version }}@container-prep']
326
327 {% if not distro.build is defined or distro.build.meson|default(True) %}
328 {{ distro.name }}:{{ distro.version }}@meson-build:
329   extends: .meson-build@template
330   stage: meson
331   image: ${{ distro.name.upper() }}_CONTAINER_IMAGE
332   variables:
333     {{ distro.name.upper() }}_VERSION: '{{ distro.version }}'
334     {# Where we have extra_variables defined, add them to the list #}
335     {% if distro.build is defined and distro.build.extra_variables is defined %}
336       {% for key, value in distro.build.extra_variables.items() %}
337     {{ key }}: {{ value }}
338       {% endfor %}
339     {% endif %}
340   needs: ['{{ distro.name }}:{{ distro.version }}@container-prep']
341 {% endif %}
342
343 {% endfor %}
344
345 # Build argument tests
346 #
347 # We only run the build option combinations on one image
348 # because they're supposed to fail equally on all
349 .fedora-custom-build@autotools-template:
350   extends: .autotools-build@template
351   stage: build
352   image: $FEDORA_CONTAINER_IMAGE
353   variables:
354     FEDORA_VERSION: 31
355   needs: ['fedora:31@container-prep']
356
357 no-valgrind:autotools:
358   extends: .fedora-custom-build@autotools-template
359   before_script:
360     - dnf remove -y valgrind
361
362 no-check:autotools:
363   extends: .fedora-custom-build@autotools-template
364   before_script:
365     - dnf remove -y check check-devel
366
367 no-doxygen:autotools:
368   extends: .fedora-custom-build@autotools-template
369   before_script:
370     - dnf remove -y doxygen
371   variables:
372     MAKE_ARGS: ''  # disable distcheck, requires doxygen
373
374 # doxygen is required for distcheck
375 no-doxygen-check-valgrind:autotools:
376   extends: .fedora-custom-build@autotools-template
377   before_script:
378     - dnf remove -y doxygen valgrind check check-devel
379   variables:
380     MAKE_ARGS: ''  # disable distcheck, requires doxygen
381
382 no-nm:autotools:
383   extends: .fedora-custom-build@autotools-template
384   before_script:
385     - mv /usr/bin/nm /usr/bin/nm.moved
386
387 enable-gcov:autotools:
388   extends: .fedora-custom-build@autotools-template
389   variables:
390     CONFIGURE_FLAGS: "--enable-gcov"
391
392 .fedora-custom-build@meson-template:
393   extends: .meson-build@template
394   stage: build
395   image: $FEDORA_CONTAINER_IMAGE
396   variables:
397     FEDORA_VERSION: 31
398   needs: ['fedora:31@container-prep']
399
400 no-valgrind:meson:
401   extends: .fedora-custom-build@meson-template
402   before_script:
403     - dnf remove -y valgrind
404
405 no-check:meson:
406   extends: .fedora-custom-build@meson-template
407   before_script:
408     - dnf remove -y check check-devel
409   variables:
410     MESON_ARGS: -Dtests=disabled
411     SKIP_MESON_TEST: 1
412
413 # doxygen is required for dist
414 no-doxygen:meson:
415   extends: .fedora-custom-build@meson-template
416   before_script:
417     - dnf remove -y doxygen
418   variables:
419     MESON_ARGS: -Ddocumentation=disabled
420     NINJA_ARGS: ''
421
422 # doxygen is required for dist
423 no-doxygen-check-valgrind:meson:
424   extends: .fedora-custom-build@meson-template
425   before_script:
426     - dnf remove -y doxygen valgrind check check-devel
427   variables:
428     MESON_ARGS: -Dtests=disabled -Ddocumentation=disabled
429     NINJA_ARGS: ''
430     SKIP_MESON_TEST: 1
431
432 enable-gcov:meson:
433   extends: .fedora-custom-build@meson-template
434   variables:
435     MESON_ARGS: '-Dcoverity=true'
436
437 scan-build:meson:
438   extends: .fedora-custom-build@meson-template
439   variables:
440     NINJA_ARGS: 'scan-build'
441     SKIP_MESON_TEST: 1
442
443 soname:
444   stage: build
445   image: $FEDORA_CONTAINER_IMAGE
446   script:
447   - ./autogen.sh --prefix=$PWD/prefix-autotools/
448   - make install
449   - ls -l $PWD/prefix-autotools/lib/libevdev.so.2.3.0
450   - meson "$MESON_BUILDDIR" --prefix=$PWD/prefix-meson/
451   - ninja -C "$MESON_BUILDDIR" install
452   - ls -l $PWD/prefix-meson/lib64/libevdev.so.2.3.0
453   variables:
454     FEDORA_VERSION: 31
455   needs: ['fedora:31@container-prep']
456
457 #################################################################
458 #                                                               #
459 #                          VM stage                             #
460 #                                                               #
461 #################################################################
462
463 .check_tainted: &check_tainted |
464   # make sure the kernel is not tainted
465   if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
466   then
467     echo tainted kernel ;
468     exit 1 ;
469   fi
470
471 .qemu@fedora:31:
472   stage: VM
473   image: $QEMU_CONTAINER_IMAGE
474   tags:
475     - kvm
476   variables:
477     FEDORA_VERSION: 31
478     MESON_BUILDDIR: build_dir
479   script:
480     # start our vm, no args required
481     - /app/start_vm.sh
482
483     - *check_tainted
484
485     - "scp -P 5555 -r $PWD localhost:"
486     - echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
487     - echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
488     - echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
489     - echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
490     - echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
491     - "scp -P 5555 sshenv localhost:~/$CI_PROJECT_NAME/.meson_environment"
492     - ssh localhost -p 5555 "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
493     # no matter the results of the tests, we want to fetch the logs
494     - scp -P 5555 -r localhost:$CI_PROJECT_NAME/"$MESON_BUILDDIR" .
495
496     - *check_tainted
497
498     - ssh localhost -p 5555 halt || true
499     - sleep 2
500     - pkill qemu || true
501
502     - if [[ ! -e .success ]] ;
503       then
504         exit 1 ;
505       fi
506   artifacts:
507     name: "qemu-meson-logs-$CI_JOB_NAME"
508     when: always
509     expire_in: 1 week
510     paths:
511       - $MESON_BUILDDIR/meson-logs
512       - console.out
513     reports:
514       junit: $MESON_BUILDDIR/junit-*.xml
515
516   retry:
517     max: 2
518     when: script_failure
519   needs: ['fedora:31@qemu-prep']
520
521 qemu:meson:
522   extends: .qemu@fedora:31
523
524 qemu:meson:valgrind:
525   extends: .qemu@fedora:31
526   variables:
527     MESON_TEST_ARGS: '--setup=valgrind'
528
529 meson-from-tarball:
530   stage: tarballs
531   image: $FEDORA_CONTAINER_IMAGE
532   script:
533     - export INSTALLDIR="$PWD/_inst"
534     - mkdir _build
535     - pushd _build > /dev/null
536     - ../autogen.sh --disable-silent-rules $CONFIGURE_FLAGS
537     - make
538     - make distcheck
539     - popd > /dev/null
540     - mkdir -p _tarball_dir
541     - tar xf _build/libevdev-*.tar.xz -C _tarball_dir
542     - pushd _tarball_dir/libevdev-*/ > /dev/null
543     - meson "$MESON_BUILDDIR" --prefix="$INSTALLDIR"
544     - ninja -C "$MESON_BUILDDIR" test
545     - ninja -C "$MESON_BUILDDIR" install
546     - popd > /dev/null
547     - ls -lR $INSTALLDIR
548   variables:
549     FEDORA_VERSION: 31
550   needs: ['fedora:31@container-prep']
551
552 autotools-from-tarball:
553   stage: tarballs
554   image: $FEDORA_CONTAINER_IMAGE
555   script:
556     - export INSTALLDIR="$PWD/_inst"
557     - meson "$MESON_BUILDDIR"
558     - ninja -C "$MESON_BUILDDIR" dist
559     - mkdir -p _tarball_dir
560     - tar xf "$MESON_BUILDDIR"/meson-dist/libevdev-*.xz -C _tarball_dir
561     - pushd _tarball_dir/libevdev-*/ > /dev/null
562     - mkdir _build
563     - pushd _build > /dev/null
564     - ../autogen.sh --disable-silent-rules --prefix="$INSTALLDIR" $CONFIGURE_FLAGS
565     - make
566     - make install
567     - make distcheck
568     - popd > /dev/null
569     - popd > /dev/null
570     - ls -lR $INSTALLDIR
571   variables:
572     FEDORA_VERSION: 31
573   needs: ['fedora:31@container-prep']