.gitlab-ci.yml 8.7 KB
Newer Older
Varac's avatar
Varac committed
1 2
---
stages:
3
  - static
Varac's avatar
Varac committed
4
  - test
5
  - debian:build
6
  - debian:qa
Varac's avatar
Varac committed
7 8
  - docker

9 10
cache:
  paths:
11
    - vendor
12

13
# Jobs that start with a period are disabled
14
# This is just a template, to be used further below in the individual job definitions
15 16 17 18 19 20 21 22
.install_build_depends: &install_build_depends |
  # Get all required build dependencies.
  export APT_BUILD_DEPENDS=`perl -ne 'next if /^#/; $p=(s/^Build-Depends:\s*/ / or (/^ / and $p)); s/,|\n|\([^)]+\)//mg; print if $p' < debian/control`
  # Install the required build dependencies.
  apt-get install -qq -y $APT_BUILD_DEPENDS
  # Check if we're good to go regarding the build dependencies.
  dpkg-checkbuilddeps

23
.setup_apt: &setup_apt
24 25
  before_script:
    # Export APT env vars to cache packages archives and lists based on the current working directory
26
    - export APT_DIR=$CI_PROJECT_DIR/vendor/apt && export APT_ARCHIVES_DIR=$APT_DIR/archives && export APT_LISTS_DIR=$APT_DIR/lists
27 28 29 30
    # Configure APT: Only install necessary packages, set cache location
    - printf
      "apt::install-recommends 0;\n
      apt::install-suggests 0;\n
31 32
      dir::cache::archives ${APT_ARCHIVES_DIR};\n
      dir::state::lists ${APT_LISTS_DIR};\n"
33
      >> /etc/apt/apt.conf.d/99custom
34 35
    # Ensure the custom APT directory does exist
    - mkdir -p {${APT_ARCHIVES_DIR},${APT_LISTS_DIR}}/partial
georg's avatar
georg committed
36
    - apt-get update -qq
37 38 39
    # To keep things DRY, use an env var to handle packages to be installed via APT
    - apt-get install -qq -y $APT_INSTALL_PACKAGES

40 41 42 43 44 45 46 47
.setup_entropy: &setup_entropy
  before_script:
    # Link /dev/random to /dev/urandom do deal with limited entropy, which otherwise blocks the test suite.
    - rm /dev/random && ln -s /dev/urandom /dev/random

.setup_prerequisites: &setup_prerequisites
  <<: [*setup_apt,*setup_entropy]

48 49 50
.test_ruby: &test_ruby
  variables:
    APT_INSTALL_PACKAGES: gnupg2 libgpgme11-dev libsqlite3-dev eatmydata
51 52
    # Use quotes so the following does get recognized as a string, not as a bool
    CHECK_CODE_COVERAGE: "true"
53
  <<: *setup_prerequisites
54
  script:
55 56
    - eatmydata gem install bundler --no-ri --no-rdoc
    - eatmydata bundle install --jobs $(nproc) --path vendor
georg's avatar
georg committed
57
    - SCHLEUDER_ENV=test SCHLEUDER_CONFIG=spec/schleuder.yml eatmydata bundle exec rake db:init
58
    - eatmydata bundle exec rspec
Varac's avatar
Varac committed
59

60 61 62
changelog:
  image: debian:unstable
  variables:
63
    APT_INSTALL_PACKAGES: ca-certificates git
64
  <<: *setup_prerequisites
65
  script:
66 67
    # Ensure we work with the latest master
    - git fetch origin master:master
68 69 70 71 72 73 74 75
    # Compare the master and current branch using their common ancestors
    # to check if the changelog was edited
    - if git diff --exit-code --quiet master...HEAD -- CHANGELOG.md; then
        echo "No CHANGELOG edit found, please verify manually";
        exit 1;
      fi
  stage: static
  allow_failure: true
76 77 78
  except:
    refs:
      - master
79
      - tags
80

81 82 83 84
codespell:
  image: debian:unstable
  variables:
    APT_INSTALL_PACKAGES: codespell
85
  <<: *setup_prerequisites
86 87 88 89 90 91 92
  script:
    # Run codespell to check for spelling errors, using a config with ignored words, skipping files 
    # (German translations, v2 list configs and code of installed dependencies) leading to false positives,
    # ignoring warnings about binary files and, finally, checking file names as well.
    - codespell -I utils/ci/codespell/ignored_words.txt -S de.yml,list.conf,vendor -q 2 -f
  stage: static

93 94
ruby:2.1:
  image: ruby:2.1
95
  <<: *test_ruby
96 97
ruby:2.2:
  image: ruby:2.2
98
  <<: *test_ruby
99 100
ruby:2.3:
  image: ruby:2.3
101
  <<: *test_ruby
102 103
ruby:2.4:
  image: ruby:2.4
104
  <<: *test_ruby
105 106
ruby:2.5:
  image: ruby:2.5
107
  <<: *test_ruby
108

Nina's avatar
Nina committed
109
bundler:audit:
110
  image: ruby:2.5
111 112
  only:
    - schedules
Nina's avatar
Nina committed
113
  script:
114
    - gem install bundler-audit --no-ri --no-rdoc
115
    - bundle install --jobs $(nproc) --path vendor
Nina's avatar
Nina committed
116 117
    - bundle-audit update
    - bundle-audit check
Varac's avatar
Varac committed
118 119 120

build_docker_image:
  stage: docker
121 122 123 124 125
  # Only build packages for https://0xacab.org/schleuder/schleuder, not
  # for forks
  only:
    - master@schleuder/schleuder
    - tags@schleuder/schleuder
Varac's avatar
Varac committed
126 127 128 129 130 131 132 133 134
  tags:
    - docker-in-docker
  image: docker:latest
  services:
    - docker:dind
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
  script:
    - docker build -t $IMAGE_TAG .
135 136 137
    # Disable bash history to prevent the $CI_JOB_TOKEN to be recorded and saved
    - unset HISTFILE
    - echo $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY
Varac's avatar
Varac committed
138
    - docker push $IMAGE_TAG
139 140 141 142 143 144 145 146 147 148 149 150 151

debian:build:
  stage: debian:build
  variables:
    APT_INSTALL_PACKAGES: build-essential ca-certificates dpkg-dev fakeroot git git-buildpackage
  <<: *setup_prerequisites
  script:
    # Ensure we work with the latest state pushed to the git repository.
    - git fetch --all --quiet
    # Setting the git user email is needed, otherwise, merging fails.
    - git config user.email team@schleuder.org
    # We're keeping the current Debian packaging state in a separate branch. Therefore, we need to pull in this.
    - git merge --allow-unrelated-histories --no-edit --quiet origin/debian/unstable
152
    - *install_build_depends
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
    # Get the latest upstream version from the Debian changelog. This is needed to ensure the tarball we'll create
    # is found by gbp, the tool we're using to build the Debian package.
    - export UPSTREAM_VERSION=`dpkg-parsechangelog --show-field Version | cut -d- -f1`
    # We're relying on .gitattribute to exclude files and directories if creating the upstream release tarball
    # via git archive.
    # While this makes sense normally, doing so here leads to dpkg-source (which is called from gbp) being unhappy,
    # due to "local changes detected, the modified files are ..." as there are some files, which don't exist in the
    # tarball, but which do exist in our current working directory. Therefore, create the tarball manually (which
    # ignores the existing .gitattributes file), to ensure it contains all (without the .git/ directory) content of
    # the current working directory.
    # Besides this, we're caching APT packages within vendor/. Currently, GitLab CI is only able to cache stuff within
    # the working directory. However, again in this case, this leads to the same error as described above. Therefore,
    # move the vendor/ directory temporarily out of the way. We'll move it back after the build was done, further below.
    - mv vendor/ /tmp
    - tar --exclude='./.git' -czf /tmp/schleuder_$UPSTREAM_VERSION.orig.tar.gz .
    # Normally, we're checking the signature of the upstream release, to ensure the code we're pulling into Debian
    # wasn't tampered with along the way. However, as we're creating the tarball on our own, there is no signature.
    # During the check for packaging errors later on via lintian this would lead to a warning. Therefore, create a
    # "dummy" signature file.
    - touch /tmp/schleuder_$UPSTREAM_VERSION.orig.tar.gz.asc
    # TODO: Use sbuild to be closer to the common Debian package build environment. This needs chroot creation upfront,
    # though. Creating the chroot needs a mounted /proc filesystem. This works if running a privileged container,
    # however, in our case it fails due to "mount(2) system call failed: Too many levels of symbolic links".
    # I'm not sure why is that, currently, or how to solve it.
    - gbp buildpackage --git-ignore-branch --git-ignore-new --git-tarball-dir=/tmp --git-upstream-branch="$CI_COMMIT_REF_NAME" --git-upstream-tree=BRANCH -us -uc --lintian-opts --no-lintian
    # Move the vendor/ directory back into the current working directory to ensure it gets cached.
    - mv /tmp/vendor .
    # Store and upload the artifacts to make them available for the subsequent jobs.
    - mkdir results
    - cp ../{*.buildinfo,*.changes,*.deb,*.dsc,*.xz} /tmp/schleuder_* results/
  allow_failure: true
  artifacts:
    expire_in: 1 day
    paths:
      - results/
188

189 190 191 192 193 194 195 196 197 198 199 200 201
debian:autopkgtest:
  stage: debian:qa
  variables:
    APT_INSTALL_PACKAGES: autopkgtest eatmydata
  <<: *setup_prerequisites
  script:
    # Run autopkgtest to test full system integration: It runs the upstream test suite (and some additional tests)
    # against the installed package.
    # TODO: Set up LXC. This would allow to reboot the container in between tests, for example to test the sysvinit
    # script as well.
    - eatmydata autopkgtest results/*.dsc -- null
  allow_failure: true

202 203 204 205 206 207
debian:lintian:
  stage: debian:qa
  variables:
    APT_INSTALL_PACKAGES: lintian
  <<: *setup_prerequisites
  script:
208
    # Run lintian, a tool used within Debian to check the package for errors and compliance with the Debian policy.
209 210
    - lintian --allow-root --display-experimental --display-info --info --pedantic results/*.changes
  allow_failure: true
211 212 213

# TODO: Introduce job to check package for reproducibility. Currently, the toolchain is still experimental: Using
# reprotest, even with all variations disabled, makes the build fail.