summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2024-09-02 11:13:59 +0000
committerAdrian Johnson <ajohnson@redneon.com>2024-09-02 11:13:59 +0000
commit39ba22d7e677362e70ba63964e30027c26fb3e69 (patch)
tree916f264b06a8ccf214b76b24c6eb1dbea8735459
parentad53e74fd28023b72e6572a3c954a1202eec6c02 (diff)
parentdd4da92782454a21ed344f5c2b8575f43d0b9343 (diff)
Merge branch 'coverage' into 'master'
Add CI jobs for static analysis and a test coverage report See merge request cairo/cairo!574
-rw-r--r--.gitlab-ci.yml77
-rw-r--r--.gitlab-ci/build-with-coverage.sh17
-rw-r--r--.gitlab-ci/env.sh2
-rw-r--r--.gitlab-ci/gen-coverage.sh14
-rw-r--r--.gitlab-ci/install-grcov.sh8
-rw-r--r--.gitlab-ci/install-rust-tools.sh11
-rw-r--r--.gitlab-ci/install-rust.sh92
7 files changed, 220 insertions, 1 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8465c87ae..96d8c1cb1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,7 +16,7 @@ workflow:
variables:
FDO_UPSTREAM_REPO: 'cairo/cairo'
FDO_DISTRIBUTION_VERSION: '40'
- FDO_DISTRIBUTION_TAG: '2024-06-06.0'
+ FDO_DISTRIBUTION_TAG: '2024-07-26-coverage.0'
# TODO: should probably get its own image at some point instead of reusing the GStreamer one
# See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/.gitlab-image-tags.yml for latest
@@ -26,10 +26,16 @@ variables:
DEFAULT_MESON_ARGS: >
--default-library=both
+ RUST_STABLE: "1.80.0"
+ RUSTUP_VERSION: "1.27.1"
+
stages:
- prep
+ - analysis
- build
- test
+ - analysis
+ - deploy
# Global CI policy: This can be used to configure global behaviour our our jobs
default:
@@ -97,6 +103,20 @@ fedora image:
util-linux
poppler-utils
clang
+ clang-analyzer
+ clang-tools-extra
+ compiler-rt
+ libasan
+ libubsan
+ llvm
+ wget
+ FDO_DISTRIBUTION_EXEC: >-
+ bash .gitlab-ci/install-rust.sh --rustup-version ${RUSTUP_VERSION} \
+ --stable ${RUST_STABLE} \
+ --arch x86_64-unknown-linux-gnu &&
+ bash .gitlab-ci/install-rust-tools.sh &&
+ bash .gitlab-ci/install-grcov.sh &&
+ rm -rf /root/.cargo /root/.cache # cleanup compilation dirs; binaries are installed now
.build fedora:
extends:
@@ -460,3 +480,58 @@ macOS x86 host:
- export CAIRO_TEST_IGNORE_quartz_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-quartz-rgb24.txt)
- export CAIRO_TEST_TARGET=quartz
- (cd build/test && srcdir=../../test ./cairo-test-suite)
+
+# Run static analysis.
+static-scan:
+ stage: 'analysis'
+ extends:
+ - '.fdo.distribution-image@fedora'
+ variables:
+ MESON_ARGS: >
+ --buildtype=debug
+ script:
+ - meson setup ${MESON_ARGS} _scan_build .
+ - ninja -C _scan_build scan-build
+ artifacts:
+ name: "cairo-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+ when: always
+ paths:
+ - "_scan_build/meson-logs/scanbuild"
+
+coverage:
+ stage: 'analysis'
+ extends:
+ - '.fdo.distribution-image@fedora'
+ needs:
+ - job: 'fedora image'
+ artifacts: false
+ script:
+ - source ./.gitlab-ci/env.sh
+ - bash -x ./.gitlab-ci/build-with-coverage.sh
+ - bash -x ./.gitlab-ci/gen-coverage.sh
+ coverage: '/Coverage: \d+\.\d+/'
+ artifacts:
+ name: "cairo-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
+ expire_in: 2 days
+ when: always
+ reports:
+ coverage_report:
+ coverage_format: cobertura
+ path: public/coverage.xml
+ paths:
+ - "_build/meson-logs"
+ - public
+
+pages:
+ stage: 'deploy'
+ needs: [ coverage ]
+ script:
+ # No-op, just to gitlab thinks there's something to do.
+ # The jobs that this job depends on have already populated public/
+ - echo
+ artifacts:
+ paths:
+ - public
+ rules:
+ # Restrict to the main branch so not every branch tries to deploy the web site
+ - if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH)
diff --git a/.gitlab-ci/build-with-coverage.sh b/.gitlab-ci/build-with-coverage.sh
new file mode 100644
index 000000000..ed867986d
--- /dev/null
+++ b/.gitlab-ci/build-with-coverage.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -eux -o pipefail
+
+export CFLAGS="-coverage -ftest-coverage -fprofile-arcs"
+
+export CAIRO_TEST_IGNORE_image_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-image-argb32.txt)
+export CAIRO_TEST_IGNORE_image_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-image-rgb24.txt)
+export CAIRO_TEST_IGNORE_image16_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-image16-rgb24.txt)
+export CAIRO_TEST_TARGET=image,image16
+
+meson setup --buildtype=debug _build .
+meson compile -C _build
+
+export srcdir=../../test
+cd _build/test
+xvfb-run ./cairo-test-suite
diff --git a/.gitlab-ci/env.sh b/.gitlab-ci/env.sh
new file mode 100644
index 000000000..b5761529f
--- /dev/null
+++ b/.gitlab-ci/env.sh
@@ -0,0 +1,2 @@
+export RUSTUP_HOME='/usr/local/rustup'
+export PATH=$PATH:/usr/local/cargo/bin
diff --git a/.gitlab-ci/gen-coverage.sh b/.gitlab-ci/gen-coverage.sh
new file mode 100644
index 000000000..cfc78e240
--- /dev/null
+++ b/.gitlab-ci/gen-coverage.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -eux -o pipefail
+
+mkdir -p public
+grcov _build --source-dir ./ --prefix-dir ../ --output-type cobertura --branch --ignore-not-existing -o public/coverage.xml
+grcov _build --source-dir ./ --prefix-dir ../ --output-type html --branch --ignore-not-existing -o public/coverage
+
+# Print "Coverage: 42.42" so .gitlab-ci.yml will pick it up with a regex
+#
+# We scrape this from the HTML report, not the JSON summary, because coverage.json
+# uses no decimal places, just something like "42%".
+
+grep -Eo 'abbr title.* %' public/coverage/index.html | head -n 1 | grep -Eo '[0-9.]+ %' | grep -Eo '[0-9.]+' | awk '{ print "Coverage:", $1 }'
diff --git a/.gitlab-ci/install-grcov.sh b/.gitlab-ci/install-grcov.sh
new file mode 100644
index 000000000..43edaa73f
--- /dev/null
+++ b/.gitlab-ci/install-grcov.sh
@@ -0,0 +1,8 @@
+source ./.gitlab-ci/env.sh
+
+set -eu
+export CARGO_HOME='/usr/local/cargo'
+
+# Coverage tools
+cargo install grcov
+rustup component add llvm-tools-preview
diff --git a/.gitlab-ci/install-rust-tools.sh b/.gitlab-ci/install-rust-tools.sh
new file mode 100644
index 000000000..23e55f4d9
--- /dev/null
+++ b/.gitlab-ci/install-rust-tools.sh
@@ -0,0 +1,11 @@
+source ./.gitlab-ci/env.sh
+
+set -eu
+export CARGO_HOME='/usr/local/cargo'
+
+rustup component add clippy
+rustup component add rustfmt
+# cargo install --force cargo-c
+cargo install --version ^1.0 gitlab_clippy
+cargo install --force cargo-deny
+# cargo install --force cargo-outdated
diff --git a/.gitlab-ci/install-rust.sh b/.gitlab-ci/install-rust.sh
new file mode 100644
index 000000000..93cdb4abd
--- /dev/null
+++ b/.gitlab-ci/install-rust.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+
+set -o errexit -o pipefail -o noclobber -o nounset
+
+source ./.gitlab-ci/env.sh
+
+export CARGO_HOME='/usr/local/cargo'
+
+PARSED=$(getopt --options '' --longoptions 'rustup-version:,stable:,minimum:,nightly,arch:' --name "$0" -- "$@")
+if [ $? -ne 0 ]; then
+ echo 'Terminating...' >&2
+ exit 1
+fi
+
+eval set -- "$PARSED"
+unset PARSED
+
+RUSTUP_VERSION=
+STABLE=
+MINIMUM=
+NIGHTLY=
+ARCH=
+
+while true; do
+ case "$1" in
+ '--rustup-version')
+ RUSTUP_VERSION=$2
+ shift 2
+ ;;
+
+ '--stable')
+ STABLE=$2
+ shift 2
+ ;;
+
+ '--minimum')
+ MINIMUM=$2
+ shift 2
+ ;;
+
+ '--nightly')
+ NIGHTLY=1
+ shift 1
+ ;;
+
+ '--arch')
+ ARCH=$2
+ shift 2
+ ;;
+
+ '--')
+ shift
+ break
+ ;;
+
+ *)
+ echo "Programming error"
+ exit 3
+ ;;
+ esac
+done
+
+if [ -z "$RUSTUP_VERSION" ]; then
+ echo "missing --rustup-version argument"
+ exit 1
+fi
+
+if [ -z "$STABLE" ]; then
+ echo "missing --stable argument, please pass the stable version of rustc you want"
+ exit 1
+fi
+
+if [ -z "$ARCH" ]; then
+ echo "missing --arch argument, please pass an architecture triple like x86_64-unknown-linux-gnu"
+ exit 1
+fi
+
+RUSTUP_URL=https://static.rust-lang.org/rustup/archive/$RUSTUP_VERSION/$ARCH/rustup-init
+wget $RUSTUP_URL
+
+chmod +x rustup-init
+./rustup-init -y --no-modify-path --profile minimal --default-toolchain $STABLE
+rm rustup-init
+chmod -R a+w $RUSTUP_HOME $CARGO_HOME
+
+if [ -n "$MINIMUM" ]; then
+ rustup toolchain install $MINIMUM
+fi
+
+if [ -n "$NIGHTLY" ]; then
+ rustup toolchain install nightly
+fi