diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a60f364279970622d5f2e28efea2489276a9bafa..35fd1ef639d60b53e08fc9337cad03e45c29e744 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,25 +14,25 @@ include: - local: '/templates/shared/all.yml' - local: '/templates/changedfiles/all.yml' -#build_containers: -# stage: build -# # Note: the docker-builder image has to be build and pushed manually once to bootstrap this job. -# image: ${CI_REGISTRY_IMAGE}/docker-builder:master -# rules: -# - !reference [.primary_ref_jobs, rules] -# - !reference [.merge_request_jobs, rules] -# script: -# # Find the directories that contain a file named 'Dockerfile', and (re)build the ones -# # that contain changed files. -# - | -# find . -name Dockerfile -type f | while read FILE; -# do -# # Strip leading './' and trailing '/<filename>' -# DOCKER_DIR=$(echo "${FILE}" | sed -r 's|^\./||' | xargs dirname) -# if grep -q "^${DOCKER_DIR}" changed_files.log; -# then -# echo "Detected a changed file inside ./${DOCKER_DIR}/. (Re)build the container." -# IMAGE_NAME=$(echo "${DOCKER_DIR}" | sed -r 's|^dockerfiles/||') -# buildimage "${DOCKER_DIR}" "${IMAGE_NAME}:${CI_COMMIT_REF_SLUG}" -# fi -# done +build_containers: + stage: build + # Note: the docker-builder image has to be build and pushed manually once to bootstrap this job. + image: ${CI_REGISTRY_IMAGE}/docker-builder:master + rules: + - !reference [.primary_ref_jobs, rules] + - !reference [.merge_request_jobs, rules] + script: + # Find the directories that contain a file named 'Dockerfile', and (re)build the ones + # that contain changed files. + - | + find . -name Dockerfile -type f | while read FILE; + do + # Strip leading './' and trailing '/<filename>' + DOCKER_DIR=$(echo "${FILE}" | sed -r 's|^\./||' | xargs dirname) + if grep -q "^${DOCKER_DIR}" changed_files.log; + then + echo "Detected a changed file inside ./${DOCKER_DIR}/. (Re)build the container." + IMAGE_NAME=$(echo "${DOCKER_DIR}" | sed -r 's|^dockerfiles/||') + buildimage "${DOCKER_DIR}" "${IMAGE_NAME}:${CI_COMMIT_REF_SLUG}" + fi + done diff --git a/README.rst b/README.rst index bde3f7f5022a06eb3aa748d9e68635b6b8282d75..b523dd80d3851713e35a7770ecb2d247c35208e6 100644 --- a/README.rst +++ b/README.rst @@ -307,7 +307,8 @@ a job, respectively. The full list of variables is as follows: `latex_pdf_diff` CI_AWE_SKIP_LATEX_PDF_DIFF CI_AWE_RUN_LATEX_PDF_DIFF `templates/latex.yml` `sonar_branch` CI_AWE_SKIP_SONAR_BRANCH CI_AWE_RUN_SONAR_BRANCH `templates/sonarqube.yml` `sonar_mr` CI_AWE_SKIP_SONAR_MR CI_AWE_RUN_SONAR_MR `templates/sonarqube.yml` -`test_badge` CI_AWE_SKIP_TEST_BADGE CI_AWE_RUN_TEST_BADGE `templates/testbadge.yml` +`report_badge` CI_AWE_SKIP_REPORT_BADGE CI_AWE_RUN_REPORT_BADGE `templates/report/badge.yml` +`report_changes` CI_AWE_SKIP_REPORT_CHANGES CI_AWE_RUN_REPORT_CHANGES `templates/report/changes.yml` In addition, you can use the ``CI_AWE_SKIP_ALL` and ``CI_AWE_RUN_ALL` variables to control whether any or all of these jobs run. diff --git a/dockerfiles/ci-tools/Dockerfile b/dockerfiles/ci-tools/Dockerfile index 36d557aaa35aa0d093bc4b811606bc06532de4be..5a56838242f226f573abe598399071f287650ecc 100644 --- a/dockerfiles/ci-tools/Dockerfile +++ b/dockerfiles/ci-tools/Dockerfile @@ -10,12 +10,16 @@ RUN apt-get update && apt-get -y install \ gettext \ && apt-get clean # Install via pip +# https://github.com/weiwei/junitparser/pull/89 is in junitparser 2.6.0. \ +# https://github.com/weiwei/junitparser/pull/90 is not yet merged :(. RUN pip install \ black==22.3.0 \ autopep8 \ python-gitlab \ python-compare-ast \ - coverage-fixpaths + coverage-fixpaths \ + anybadge \ + "junitparser>=2.6" # Install Gitlab release-cli RUN curl --location --output /usr/local/bin/release-cli "https://gitlab.com/gitlab-org/release-cli/-/releases/permalink/latest/downloads/bin/release-cli-linux-amd64" \ diff --git a/dockerfiles/testbadge/testbadge.py b/dockerfiles/ci-tools/report_badge.py similarity index 100% rename from dockerfiles/testbadge/testbadge.py rename to dockerfiles/ci-tools/report_badge.py diff --git a/dockerfiles/ci-tools/report_compare.py b/dockerfiles/ci-tools/report_compare.py new file mode 100755 index 0000000000000000000000000000000000000000..fea475b2b3bf8c9f8fdc8f6a2c3b89a08c6e15e8 --- /dev/null +++ b/dockerfiles/ci-tools/report_compare.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +import argparse + +from junitparser import JUnitXml, TestSuite + + +def compare_reports(path_before, path_after, path_out): + before = JUnitXml.fromfile(path_before) + after = JUnitXml.fromfile(path_after) + + passed = [] + for suite in before: + for case in suite: + if case.is_passed: + passed.append(case) + + failed = [] + for suite in after: + for case in suite: + if not case.is_passed and not case.is_skipped: + failed.append(case) + + newly_failed = [] + for f in failed: + for p in passed: + if (f.classname, f.name) == (p.classname, p.name): + newly_failed.append(f) + + xml = JUnitXml() + suite = TestSuite('newly_failed_tests') + suite.add_testcases(newly_failed) + xml.add_testsuite(suite) + xml.update_statistics() + xml.write(path_out, to_console=False) + + +def main(): + parser = argparse.ArgumentParser( + description='Create a new report with testcases that passed before but fail or error now.' + ) + parser.add_argument("before", help="Path of the initial XML report to compare.") + parser.add_argument("after", help="Path of the re-run XML report to compare.") + parser.add_argument("output", help='Path to write compare report to.') + args = parser.parse_args() + compare_reports(args.before, args.after, args.output) + + +if __name__ == '__main__': + main() diff --git a/dockerfiles/testbadge/Dockerfile b/dockerfiles/testbadge/Dockerfile deleted file mode 100644 index 9c03df6f5455192e999a9db003c4ef97b45ad9f6..0000000000000000000000000000000000000000 --- a/dockerfiles/testbadge/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM python:3-slim - -# https://github.com/weiwei/junitparser/pull/89 is in junitparser 2.6.0. -# https://github.com/weiwei/junitparser/pull/90 is not yet merged :(. -RUN pip install anybadge "junitparser>=2.6" - -COPY testbadge.py /usr/local/bin/testbadge - -CMD ["/bin/bash"] diff --git a/templates/testbadge.yml b/templates/report/badge.yml similarity index 58% rename from templates/testbadge.yml rename to templates/report/badge.yml index 97eed286bc13ca6836d9b40fb520f0cc5085b1d0..afb1a5c2ba1c6de5d2d0235645aef6a027f2540c 100644 --- a/templates/testbadge.yml +++ b/templates/report/badge.yml @@ -1,17 +1,17 @@ include: - local: '/templates/shared/all.yml' -test_badge: - image: ${CI_AWE_IMAGE_BASE}/testbadge:${CI_AWE_IMAGE_TAG} +report_badge: + image: ${CI_AWE_IMAGE_BASE}/ci-tools:${CI_AWE_IMAGE_TAG} stage: test_post rules: - - if: $CI_AWE_SKIP_TEST_BADGE + - if: $CI_AWE_SKIP_REPORT_BADGE when: never - - if: $CI_AWE_RUN_TEST_BADGE + - if: $CI_AWE_RUN_REPORT_BADGE - !reference [.primary_ref_jobs, rules] - !reference [.merge_request_jobs, rules] script: - - testbadge report.xml report.svg + - report_badge report.xml report.svg artifacts: paths: - report.svg diff --git a/templates/report/changes.yml b/templates/report/changes.yml new file mode 100644 index 0000000000000000000000000000000000000000..f3edf8444b7a71a8c969c408c8ecf9405d05b150 --- /dev/null +++ b/templates/report/changes.yml @@ -0,0 +1,20 @@ +report_changes: + image: ${CI_AWE_IMAGE_BASE}/ci-tools:${CI_AWE_IMAGE_TAG} + variables: + REPORT_CHANGES_JOB: conda_test + REPORT_CHANGES_ARTIFACT_FILE: report.xml + REPORT_CHANGES_ARTIFACT_URL: "$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/$CI_COMMIT_REF_NAME/raw/$REPORT_CHANGES_ARTIFACT_FILE?job=$REPORT_CHANGES_JOB" + stage: test_post + rules: + - if: $CI_AWE_SKIP_REPORT_CHANGES + when: never + - if: $CI_AWE_RUN_REPORT_CHANGES + - !reference [.primary_ref_jobs, rules] + script: + - 'curl --output "$REPORT_CHANGES_FILE.old" --location --header "JOB-TOKEN: $CI_JOB_TOKEN" "$REPORT_CHANGES_ARTIFACT_URL"' + - report_compare "$REPORT_CHANGES_FILE.old" "$REPORT_CHANGES_ARTIFACT_FILE" report_changes.xml + - junitparser verify report_changes.xml + artifacts: + expire_in: 1 day + reports: + junit: report_changes.xml