From a518e402c5dc1f2677e6cb1ef529b8d886b585d5 Mon Sep 17 00:00:00 2001
From: Ben Boeckel <ben.boeckel@kitware.com>
Date: Wed, 1 Nov 2023 20:59:44 -0400
Subject: ci: generate annotation reports

These will render links in the sidebar for each job.

See: https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsannotations
---
 .gitlab/ci/ctest_annotation.cmake | 32 ++++++++++++++++++++++++++++++++
 .gitlab/ci/ctest_build.cmake      |  6 ++++++
 .gitlab/ci/ctest_configure.cmake  | 12 ++++++++++--
 .gitlab/ci/ctest_memcheck.cmake   |  9 +++++++++
 .gitlab/ci/ctest_standalone.cmake | 20 +++++++++++++++++++-
 .gitlab/ci/ctest_test.cmake       |  8 ++++++++
 6 files changed, 84 insertions(+), 3 deletions(-)
 create mode 100644 .gitlab/ci/ctest_annotation.cmake

diff --git a/.gitlab/ci/ctest_annotation.cmake b/.gitlab/ci/ctest_annotation.cmake
new file mode 100644
index 0000000..a219753
--- /dev/null
+++ b/.gitlab/ci/ctest_annotation.cmake
@@ -0,0 +1,32 @@
+function (ctest_annotation_report file)
+  set(label "")
+
+  if (EXISTS "${file}")
+    file(READ "${file}" json)
+  else ()
+    set(json "{\"CDash\": []}")
+  endif ()
+
+  foreach (arg IN LISTS ARGN)
+    if (NOT label)
+      set(label "${arg}")
+      continue ()
+    endif ()
+
+    set(item "{\"external_link\":{\"label\":\"${label}\",\"url\":\"${arg}\"}}")
+    set(label "")
+
+    string(JSON length LENGTH "${json}" "CDash")
+    string(JSON json SET "${json}" "CDash" "${length}" "${item}")
+  endforeach ()
+
+  file(WRITE "${file}" "${json}")
+endfunction ()
+
+if (NOT DEFINED build_id)
+  include("${CTEST_BINARY_DIRECTORY}/cdash-build-id" OPTIONAL)
+endif ()
+function (store_build_id build_id)
+  file(WRITE "${CTEST_BINARY_DIRECTORY}/cdash-build-id"
+    "set(build_id \"${build_id}\")\n")
+endfunction ()
diff --git a/.gitlab/ci/ctest_build.cmake b/.gitlab/ci/ctest_build.cmake
index e874a62..b1b9830 100644
--- a/.gitlab/ci/ctest_build.cmake
+++ b/.gitlab/ci/ctest_build.cmake
@@ -45,11 +45,17 @@ if (iwyu_source_name AND "$ENV{CMAKE_CONFIGURATION}" MATCHES "iwyu")
 endif ()
 
 ctest_build(
+  NUMBER_ERRORS num_errors
   NUMBER_WARNINGS num_warnings
   RETURN_VALUE build_result
   ${ctest_build_args})
 ctest_submit(PARTS Build)
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Errors (${num_errors})"      "https://open.cdash.org/viewBuildError.php?buildid=${build_id}"
+  "Build Warnings (${num_warnings})"  "https://open.cdash.org/viewBuildError.php?type=1&buildid=${build_id}")
+
 if (build_result)
   message(FATAL_ERROR
     "Failed to build")
diff --git a/.gitlab/ci/ctest_configure.cmake b/.gitlab/ci/ctest_configure.cmake
index 2682055..04285fd 100644
--- a/.gitlab/ci/ctest_configure.cmake
+++ b/.gitlab/ci/ctest_configure.cmake
@@ -22,10 +22,18 @@ ctest_configure(
 # Read the files from the build directory.
 ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
 
-# We can now submit because we've configured. This is a cmb-superbuild-ism.
-ctest_submit(PARTS Update)
+# We can now submit because we've configured.
+ctest_submit(PARTS Update
+  BUILD_ID build_id)
 ctest_submit(PARTS Configure)
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Summary" "https://open.cdash.org/build/${build_id}"
+  "Update"        "https://open.cdash.org/build/${build_id}/update"
+  "Configure"     "https://open.cdash.org/build/${build_id}/configure")
+store_build_id("${build_id}")
+
 if (configure_result)
   message(FATAL_ERROR
     "Failed to configure")
diff --git a/.gitlab/ci/ctest_memcheck.cmake b/.gitlab/ci/ctest_memcheck.cmake
index dac907c..c650681 100644
--- a/.gitlab/ci/ctest_memcheck.cmake
+++ b/.gitlab/ci/ctest_memcheck.cmake
@@ -34,6 +34,15 @@ ctest_memcheck(
 ctest_submit(PARTS Test)
 ctest_submit(PARTS Memcheck)
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Summary"     "https://open.cdash.org/build/${build_id}"
+  "All Tests"         "https://open.cdash.org/viewTest.php?buildid=${build_id}"
+  "Dynamic Analysis"  "https://open.cdash.org/viewDynamicAnalysis.php?buildid=${build_id}"
+  "Test Failures"     "https://open.cdash.org/viewTest.php?onlyfailed&buildid=${build_id}"
+  "Tests Not Run"     "https://open.cdash.org/viewTest.php?onlynotrun&buildid=${build_id}"
+  "Test Passes"       "https://open.cdash.org/viewTest.php?onlypassed&buildid=${build_id}")
+
 if (test_result)
   message(FATAL_ERROR
     "Failed to test")
diff --git a/.gitlab/ci/ctest_standalone.cmake b/.gitlab/ci/ctest_standalone.cmake
index 36ba71c..2e67793 100644
--- a/.gitlab/ci/ctest_standalone.cmake
+++ b/.gitlab/ci/ctest_standalone.cmake
@@ -38,9 +38,16 @@ ctest_configure(
 ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
 
 # We can now submit because we've configured. This is a cmb-superbuild-ism.
-ctest_submit(PARTS Update)
+ctest_submit(PARTS Update
+  BUILD_ID build_id)
 ctest_submit(PARTS Configure)
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Summary" "https://open.cdash.org/build/${build_id}"
+  "Update"        "https://open.cdash.org/build/${build_id}/update"
+  "Configure"     "https://open.cdash.org/build/${build_id}/configure")
+
 if (configure_result)
   ctest_submit(PARTS Done)
   message(FATAL_ERROR
@@ -54,10 +61,15 @@ elseif (CTEST_CMAKE_GENERATOR MATCHES "Ninja")
 endif ()
 
 ctest_build(
+  NUMBER_ERRORS num_errors
   NUMBER_WARNINGS num_warnings
   RETURN_VALUE build_result)
 ctest_submit(PARTS Build)
 
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Errors (${num_errors})"      "https://open.cdash.org/viewBuildError.php?buildid=${build_id}"
+  "Build Warnings (${num_warnings})"  "https://open.cdash.org/viewBuildError.php?type=1&buildid=${build_id}")
+
 if (build_result)
   ctest_submit(PARTS Done)
   message(FATAL_ERROR
@@ -86,6 +98,12 @@ ctest_test(
   EXCLUDE "${test_exclusions}")
 ctest_submit(PARTS Test)
 
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "All Tests"     "https://open.cdash.org/viewTest.php?buildid=${build_id}"
+  "Test Failures" "https://open.cdash.org/viewTest.php?onlyfailed&buildid=${build_id}"
+  "Tests Not Run" "https://open.cdash.org/viewTest.php?onlynotrun&buildid=${build_id}"
+  "Test Passes"   "https://open.cdash.org/viewTest.php?onlypassed&buildid=${build_id}")
+
 if (test_result)
   ctest_submit(PARTS Done)
   message(FATAL_ERROR
diff --git a/.gitlab/ci/ctest_test.cmake b/.gitlab/ci/ctest_test.cmake
index b02d032..c155ab3 100644
--- a/.gitlab/ci/ctest_test.cmake
+++ b/.gitlab/ci/ctest_test.cmake
@@ -25,6 +25,14 @@ ctest_test(
   EXCLUDE "${test_exclusions}")
 ctest_submit(PARTS Test)
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Build Summary" "https://open.cdash.org/build/${build_id}"
+  "All Tests"     "https://open.cdash.org/viewTest.php?buildid=${build_id}"
+  "Test Failures" "https://open.cdash.org/viewTest.php?onlyfailed&buildid=${build_id}"
+  "Tests Not Run" "https://open.cdash.org/viewTest.php?onlynotrun&buildid=${build_id}"
+  "Test Passes"   "https://open.cdash.org/viewTest.php?onlypassed&buildid=${build_id}")
+
 if (test_result)
   message(FATAL_ERROR
     "Failed to test")
-- 
cgit v0.12


From 06661b1e4ce2a60e114ca2e67c42d50d20e0092a Mon Sep 17 00:00:00 2001
From: Ben Boeckel <ben.boeckel@kitware.com>
Date: Wed, 1 Nov 2023 21:01:01 -0400
Subject: gitlab-ci: pull annotations for CDash from the jobs

Only move `cdash-build-id` between stages that make sense.
---
 .gitlab-ci.yml        |  2 ++
 .gitlab/artifacts.yml | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3c1c9cc..032a6fc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -105,6 +105,7 @@ l:iwyu-debian12:
         - .debian12_iwyu
         - .cmake_build_linux
         - .linux_x86_64_tags
+        - .cmake_cdash_artifacts
         - .run_automatically
 
 l:tidy-fedora38:
@@ -112,6 +113,7 @@ l:tidy-fedora38:
         - .fedora38_tidy
         - .cmake_build_linux
         - .linux_x86_64_tags
+        - .cmake_cdash_artifacts
         - .run_automatically
 
 l:sphinx-fedora38:
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
index d9943b8..f4d413b 100644
--- a/.gitlab/artifacts.yml
+++ b/.gitlab/artifacts.yml
@@ -62,6 +62,10 @@
             - ${CMAKE_CI_BUILD_DIR}/Testing/
             - ${CMAKE_CI_BUILD_DIR}/DartConfiguation.tcl
             - ${CMAKE_CI_BUILD_DIR}/CTestCustom.cmake
+            - ${CMAKE_CI_BUILD_DIR}/cdash-build-id
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
 
 .cmake_release_artifacts:
     artifacts:
@@ -82,12 +86,26 @@
             - ${CMAKE_CI_BUILD_DIR}/cmake-*.zip
             # Any unsigned packages made.
             - ${CMAKE_CI_BUILD_DIR}/unsigned/cmake-*
+            - ${CMAKE_CI_BUILD_DIR}/cdash-build-id
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
+
+.cmake_cdash_artifacts:
+    artifacts:
+        expire_in: 1d
+        when: always
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
 
 .cmake_junit_artifacts:
     artifacts:
         expire_in: 1d
         when: always
         reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
             junit:
                 - ${CMAKE_CI_BUILD_DIR}/junit.xml
 
@@ -95,6 +113,9 @@
     artifacts:
         expire_in: 1d
         when: always
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
         paths:
             # Take the sphinx logs.
             - ${CMAKE_CI_BUILD_DIR}/build-*.log
@@ -108,6 +129,8 @@
         reports:
             junit:
                 - ${CMAKE_CI_BUILD_DIR}/junit.xml
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
         paths:
             # Take the install tree.
             - ${CMAKE_CI_BUILD_DIR}/install/
@@ -115,6 +138,9 @@
 .cmake_doc_artifacts:
     artifacts:
         expire_in: 1d
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
         paths:
             # Take the install tree.
             - ${CMAKE_CI_BUILD_DIR}/install-doc/
-- 
cgit v0.12