From c46b3245b8dfb91ab0ba9a29f6f0bd49afe78e02 Mon Sep 17 00:00:00 2001 From: Jakub Date: Mon, 29 May 2023 13:48:19 +0200 Subject: [PATCH] feat(GODT-2660): calculate bridge coverage and refactor CI yaml file. --- .gitlab-ci.yml | 348 ++++++++++++++++++++++------------------------ Makefile | 18 ++- utils/coverage.sh | 52 +++++++ 3 files changed, 231 insertions(+), 187 deletions(-) create mode 100755 utils/coverage.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e1bdde67..21fe70aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,13 +30,6 @@ stages: - test - build -.rules-branch-and-MR-always: - rules: - - if: $CI_COMMIT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event" - when: always - allow_failure: false - - when: never - .rules-branch-and-MR-manual: rules: - if: $CI_COMMIT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event" @@ -44,16 +37,6 @@ stages: allow_failure: true - when: never -.rules-branch-manual-MR-always: - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - when: always - allow_failure: false - - if: $CI_COMMIT_BRANCH - when: manual - allow_failure: true - - when: never - .rules-branch-manual-MR-and-devel-always: rules: - if: $CI_COMMIT_BRANCH == "devel" || $CI_PIPELINE_SOURCE == "merge_request_event" @@ -64,172 +47,8 @@ stages: allow_failure: true - when: never -.after-script-code-coverage: - after_script: - - go get github.com/boumenot/gocover-cobertura - - go run github.com/boumenot/gocover-cobertura < /tmp/coverage.out > coverage.xml - - "go tool cover -func=/tmp/coverage.out | grep total:" - coverage: '/total:.*\(statements\).*\d+\.\d+%/' - artifacts: - reports: - coverage_report: - coverage_format: cobertura - path: coverage.xml - -# Stage: TEST - -lint: - stage: test - extends: - - .rules-branch-and-MR-always - script: - - make lint - tags: - - medium - - -.test-base: - stage: test - script: - - make test - -test-linux: - extends: - - .test-base - - .rules-branch-manual-MR-and-devel-always - - .after-script-code-coverage - tags: - - large - -test-linux-race: - extends: - - test-linux - - .rules-branch-and-MR-manual - script: - - make test-race - -test-integration: - extends: - - test-linux - script: - - make test-integration - tags: - - large - -test-integration-race: - extends: - - test-integration - - .rules-branch-and-MR-manual - script: - - make test-integration-race - - -.windows-base: - before_script: - - export GOROOT=/c/Go1.20 - - export PATH=$GOROOT/bin:$PATH - - export GOARCH=amd64 - - export GOPATH=~/go1.20 - - export GO111MODULE=on - - export PATH=$GOPATH/bin:$PATH - - export MSYSTEM= - tags: - - windows-bridge - -test-windows: - extends: - - .rules-branch-manual-MR-always - - .windows-base - stage: test - script: - - make test - -# Stage: BUILD - -.build-base: - stage: build - needs: ["lint"] - rules: - # GODT-1833: use `=~ /qa/` after mac and windows runners are fixed - - if: $CI_JOB_NAME =~ /build-linux-qa/ && $CI_PIPELINE_SOURCE == "merge_request_event" - when: always - allow_failure: false - - if: $CI_COMMIT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event" - when: manual - allow_failure: true - - when: never - script: - - make build - - git diff && git diff-index --quiet HEAD - - make vault-editor - artifacts: - expire_in: 1 day - when: always - name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" - paths: - - bridge_*.tgz - - vault-editor - - -.linux-build-setup: - image: gitlab.protontech.ch:4567/go/bridge-internal:build-go1.20-qt6.3.2 - variables: - VCPKG_DEFAULT_BINARY_CACHE: ${CI_PROJECT_DIR}/.cache - cache: - key: linux-vcpkg - paths: - - .cache - when: 'always' - before_script: - - mkdir -p .cache/bin - - export PATH=$(pwd)/.cache/bin:$PATH - - export GOPATH="$CI_PROJECT_DIR/.cache" - - export PATH=$PATH:$QT6DIR/bin - - $(git config --global -l | grep -o 'url.*gitlab.protontech.ch.*insteadof' | xargs -L 1 git config --global --unset &> /dev/null) || echo "nothing to remove" - - git config --global url.https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}.insteadOf https://${CI_SERVER_HOST} - tags: - - large - -build-linux: - extends: - - .build-base - - .linux-build-setup - -build-linux-qa: - extends: - - build-linux - variables: - BUILD_TAGS: "build_qa" - - -.darwin-build-setup: - before_script: - - export PATH=/usr/local/bin:$PATH - - export PATH=/usr/local/opt/git/bin:$PATH - - export PATH=/usr/local/opt/make/libexec/gnubin:$PATH - - export PATH=/usr/local/opt/go@1.13/bin:$PATH - - export PATH=/usr/local/opt/gnu-sed/libexec/gnubin:$PATH - - export GOPATH=~/go1.20 - - export PATH=$GOPATH/bin:$PATH - - export CGO_CPPFLAGS='-Wno-error -Wno-nullability-completeness -Wno-expansion-to-defined -Wno-builtin-requires-header' - - $(git config --global -l | grep -o 'url.*gitlab.protontech.ch.*insteadof' | xargs -L 1 git config --global --unset &> /dev/null) || echo "nothing to remove" - - git config --global url.https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}.insteadOf https://${CI_SERVER_HOST} - cache: {} - tags: - - macOS - -build-darwin: - extends: - - .build-base - - .darwin-build-setup - -build-darwin-qa: - extends: - - build-darwin - variables: - BUILD_TAGS: "build_qa" - -.windows-build-setup: +# ENV +.env-windows: before_script: - export GOROOT=/c/Go1.20/ - export PATH=$GOROOT/bin:$PATH @@ -249,10 +68,169 @@ build-darwin-qa: tags: - windows-bridge +.env-darwin: + before_script: + - export PATH=/usr/local/bin:$PATH + - export PATH=/usr/local/opt/git/bin:$PATH + - export PATH=/usr/local/opt/make/libexec/gnubin:$PATH + - export PATH=/usr/local/opt/gnu-sed/libexec/gnubin:$PATH + - export GOROOT=~/local/opt/go@1.20 + - export PATH="${GOROOT}/bin:$PATH" + - export GOPATH=~/go1.20 + - export PATH="${GOPATH}/bin:$PATH" + - export QT6DIR=/opt/Qt/6.3.2/macos + - export PATH="${QT6DIR}/bin:$PATH" + - uname -a + cache: {} + tags: + - macos-m1-bridge + +.env-linux-build: + image: gitlab.protontech.ch:4567/go/bridge-internal:build-go1.20-qt6.3.2 + variables: + VCPKG_DEFAULT_BINARY_CACHE: ${CI_PROJECT_DIR}/.cache + cache: + key: linux-vcpkg + paths: + - .cache + when: 'always' + before_script: + - mkdir -p .cache/bin + - export PATH=$(pwd)/.cache/bin:$PATH + - export GOPATH="$CI_PROJECT_DIR/.cache" + - export PATH=$PATH:$QT6DIR/bin + - $(git config --global -l | grep -o 'url.*gitlab.protontech.ch.*insteadof' | xargs -L 1 git config --global --unset &> /dev/null) || echo "nothing to remove" + - git config --global url.https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}.insteadOf https://${CI_SERVER_HOST} + tags: + - large + +# Stage: TEST + +lint: + stage: test + extends: + - .rules-branch-manual-MR-and-devel-always + script: + - make lint + tags: + - medium + +.script-test: + stage: test + extends: + - .rules-branch-manual-MR-and-devel-always + script: + - make test + artifacts: + paths: + - coverage/** + +test-linux: + extends: + - .script-test + tags: + - large + +test-linux-race: + extends: + - test-linux + - .rules-branch-and-MR-manual + script: + - make test-race + +test-integration: + extends: + - test-linux + script: + - make test-integration + +test-integration-race: + extends: + - test-integration + - .rules-branch-and-MR-manual + script: + - make test-integration-race + +test-windows: + extends: + - .env-windows + - .script-test + +test-darwin: + extends: + - .env-darwin + - .script-test + +test-coverage: + stage: test + extends: + - .rules-branch-manual-MR-and-devel-always + script: + - ./utils/coverage.sh + coverage: '/total:.*\(statements\).*\d+\.\d+%/' + needs: + - test-linux + - test-windows + - test-darwin + - test-integration + tags: + - small + artifacts: + paths: + - coverage* + - coverage/** + when: 'always' + reports: + coverage_report: + coverage_format: cobertura + path: coverage.xml + +# Stage: BUILD + +.script-build: + stage: build + needs: ["lint"] + extends: + - .rules-branch-and-MR-manual + script: + - make build + - git diff && git diff-index --quiet HEAD + - make vault-editor + artifacts: + expire_in: 1 day + when: always + name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" + paths: + - bridge_*.tgz + - vault-editor + +build-linux: + extends: + - .script-build + - .env-linux-build + +build-linux-qa: + extends: + - build-linux + - .rules-branch-manual-MR-and-devel-always + variables: + BUILD_TAGS: "build_qa" + +build-darwin: + extends: + - .script-build + - .env-darwin + +build-darwin-qa: + extends: + - build-darwin + variables: + BUILD_TAGS: "build_qa" + build-windows: extends: - - .build-base - - .windows-build-setup + - .script-build + - .env-windows build-windows-qa: extends: diff --git a/Makefile b/Makefile index b7a285d3..4d395c60 100644 --- a/Makefile +++ b/Makefile @@ -229,14 +229,28 @@ add-license: change-copyright-year: ./utils/missing_license.sh change-year +GOCOVERAGE=-covermode=count -coverpkg=github.com/ProtonMail/proton-bridge/v3/internal/...,github.com/ProtonMail/proton-bridge/v3/pkg/..., +GOCOVERDIR=-args -test.gocoverdir=$$PWD/coverage + test: gofiles - go test -v -timeout=20m -p=1 -count=1 -coverprofile=/tmp/coverage.out -run=${TESTRUN} ./internal/... ./pkg/... + mkdir -p coverage/unit-${GOOS} + go test \ + -v -timeout=20m -p=1 -count=1 \ + ${GOCOVERAGE} \ + -run=${TESTRUN} ./internal/... ./pkg/... \ + ${GOCOVERDIR}/unit-${GOOS} test-race: gofiles go test -v -timeout=40m -p=1 -count=1 -race -failfast -run=${TESTRUN} ./internal/... ./pkg/... test-integration: gofiles - go test -v -timeout=60m -p=1 -count=1 github.com/ProtonMail/proton-bridge/v3/tests + mkdir -p coverage/integration + go test \ + -v -timeout=60m -p=1 -count=1 \ + ${GOCOVERAGE} \ + github.com/ProtonMail/proton-bridge/v3/tests \ + ${GOCOVERDIR}/integration + test-integration-debug: gofiles dlv test github.com/ProtonMail/proton-bridge/v3/tests -- -test.v -test.timeout=10m -test.parallel=1 -test.count=1 diff --git a/utils/coverage.sh b/utils/coverage.sh new file mode 100755 index 00000000..c0512914 --- /dev/null +++ b/utils/coverage.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright (c) 2023 Proton AG +# +# This file is part of Proton Mail Bridge. +# +# Proton Mail Bridge is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Proton Mail Bridge is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Proton Mail Bridge. If not, see . + + +# This script calculates coverage for bridge project +# +# Output: +# stdout : total coverage (to be parsed by Gitlab pipeline) +# coverage.xml : Cobertura format of covered lines for coverage visualization in Gitlab + +# Assuming that test coverages from all jobs were put into `./coverage` folder +# and passed as artifacts. The flags are: +# -covermode=count +# -coverpkg=github.com/ProtonMail/proton-bridge/v3/internal/...,github.com/ProtonMail/proton-bridge/v3/pkg/..., +# -args -test.gocoverdir=$$PWD/coverage/${TOPIC} + + +ALLINPUTS="coverage$(printf ",%s" coverage/*)" + +go tool covdata textfmt \ + -i "$ALLINPUTS" \ + -o coverage_withGen.out + +# Filter out auto-generated code +grep -v '\.pb\.go' coverage_withGen.out > coverage.out + +# Print out coverage +go tool cover -func=./coverage.out | grep total: + +# Convert to Cobertura +# +# NOTE: We are not using the latest `github.com/boumenot/gocover-cobertura` +# because it does not support multiplatform coverage in one profile. See +# https://github.com/boumenot/gocover-cobertura/pull/3#issuecomment-1571586099 +go get github.com/t-yuki/gocover-cobertura +go run github.com/t-yuki/gocover-cobertura < ./coverage.out > coverage.xml