From 2d976fc19172a0a5d52cf0c35930ec7c08ce17cf Mon Sep 17 00:00:00 2001 From: Kyle Sunderland Date: Wed, 21 Oct 2026 12:41:03 -0400 Subject: [PATCH 1/2] COMP: Cache the Qt install and harden its download in CI Two of the last four nightly failures were the Install Qt step: aqtinstall downloads 27 Qt archives per job from a geo-selected mirror and, when one times out, tries a single random fallback mirror before aborting. Twice that fallback was ftp1/ftp2.nluug.nl, whose TLS certificate does not match the hostname, so the whole build failed. Move the Qt install into a local composite action shared by the VTK and Plus build workflows, so that both use the same archive list and therefore the same cache key. The action: - caches the Qt directory with install-qt-action's built-in actions/cache support, so that only the first job per architecture downloads Qt at all; - restricts the download to the archives Plus links against (9 instead of 27). qtdeclarative is included because VTK is built with VTK_GROUP_ENABLE_Qt=YES, which includes GUISupportQtQuick, and find_package(VTK) without a component list requires every built module's dependencies; - gives aqtinstall a config with longer timeouts, a curated fallback mirror list and the slow redirect mirror blacklisted for the cache-miss path. Neither workflow checks out PlusLib (the superbuild clones it), so each does a sparse checkout of .github/actions first. Let dependabot see the action's "uses:" lines as well. Co-Authored-By: Claude Fable 5.1 --- .github/actions/install-qt/action.yml | 61 +++++++++++++++++++++++++++ .github/dependabot.yml | 6 ++- .github/workflows/build-plus.yml | 13 ++++-- .github/workflows/build-vtk.yml | 14 ++++-- 4 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 .github/actions/install-qt/action.yml diff --git a/.github/actions/install-qt/action.yml b/.github/actions/install-qt/action.yml new file mode 100644 index 000000000..50c823128 --- /dev/null +++ b/.github/actions/install-qt/action.yml @@ -0,0 +1,61 @@ +name: Install Qt +description: >- + Install the Qt 5 archives that Plus needs with jurplel/install-qt-action, + restored from the actions cache when an entry exists. Shared by the VTK and + Plus build workflows so that both use the same archive list and therefore + the same cache key. + +inputs: + arch: + description: Build architecture, x64 or Win32 + required: true + version: + description: Qt version to install + required: false + default: '5.15.0' + +runs: + using: composite + steps: + # aqtinstall downloads each archive from a geo-selected mirror and, on a + # timeout, tries exactly one random fallback mirror before giving up. Give + # slow mirrors more time, skip the mirrors that have failed nightly builds + # (ftp1/ftp2.nluug.nl serve a certificate for a different hostname), and + # avoid the slow mirror that download.qt.io redirects the runners to. + - name: Configure aqtinstall + shell: bash + run: | + cat > "$RUNNER_TEMP/aqt.ini" <<'EOF' + [requests] + connection_timeout : 10 + response_timeout : 120 + max_retries_on_connection_error : 10 + [mirrors] + blacklist : + https://mirror.ossplanet.net + fallbacks : + https://ftp.fau.de/qtproject/ + https://mirror.netcologne.de/qtproject/ + https://mirrors.dotsrc.org/qtproject/ + https://master.qt.io/ + https://qt.mirror.constant.com/ + https://mirrors.ukfast.co.uk/sites/qt.io/ + EOF + echo "AQT_CONFIG=$RUNNER_TEMP/aqt.ini" >> "$GITHUB_ENV" + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + dir: ${{ github.workspace }}/Qt + version: ${{ inputs.version }} + arch: ${{ inputs.arch == 'x64' && 'win64_msvc2019_64' || 'win32_msvc2019' }} + # Only the archives Plus links against (Core/Gui/Widgets/OpenGL/Sql/ + # Concurrent/Network/Test/Xml come from qtbase; Designer from qttools; + # Quick/Qml from qtdeclarative for VTK's GUISupportQtQuick module, which + # find_package(VTK) requires even though Plus does not use it) plus what + # windeployqt bundles. Cuts the download from 27 archives to 9 and keeps + # the cache entry small. + archives: qtbase qttools qtxmlpatterns qtmultimedia qtdeclarative qttranslations d3dcompiler_47 opengl32sw + # Restore the Qt directory from the actions cache so that only the first + # job per architecture downloads Qt at all. + cache: true diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 79d1174ef..8a67b18eb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,11 @@ version: 2 updates: - package-ecosystem: "github-actions" - directory: "/" + # "/" only covers .github/workflows; local composite actions have to be + # listed separately for their "uses:" lines to be updated too. + directories: + - "/" + - "/.github/actions/*" schedule: # Check for updates to GitHub Actions every week interval: "weekly" diff --git a/.github/workflows/build-plus.yml b/.github/workflows/build-plus.yml index cc3414aec..d7aa277cc 100644 --- a/.github/workflows/build-plus.yml +++ b/.github/workflows/build-plus.yml @@ -133,12 +133,19 @@ jobs: with: cmakeVersion: 4.3.4 + # The job never checks out PlusLib itself (the superbuild clones it), so + # fetch just the local actions used below. + - name: Checkout CI actions + uses: actions/checkout@v7 + with: + sparse-checkout: .github/actions + path: pluslib-ci + - name: Install Qt - uses: jurplel/install-qt-action@v4 + uses: ./pluslib-ci/.github/actions/install-qt with: - dir: ${{ github.workspace }}/Qt + arch: ${{ inputs.arch }} version: ${{ inputs.qt-version }} - arch: ${{ inputs.arch == 'x64' && 'win64_msvc2019_64' || 'win32_msvc2019' }} - name: Install NSIS uses: repolevedavaj/install-nsis@v1.3.0 diff --git a/.github/workflows/build-vtk.yml b/.github/workflows/build-vtk.yml index 42f95fe21..d7682a48b 100644 --- a/.github/workflows/build-vtk.yml +++ b/.github/workflows/build-vtk.yml @@ -59,13 +59,21 @@ jobs: with: cmakeVersion: 4.3.4 + # The job never checks out PlusLib itself (the superbuild clones it), so + # fetch just the local actions used below. + - name: Checkout CI actions + if: steps.cache-vtk.outputs.cache-hit != 'true' + uses: actions/checkout@v7 + with: + sparse-checkout: .github/actions + path: pluslib-ci + - name: Install Qt if: steps.cache-vtk.outputs.cache-hit != 'true' - uses: jurplel/install-qt-action@v4 + uses: ./pluslib-ci/.github/actions/install-qt with: - dir: ${{github.workspace}}/Qt + arch: ${{ inputs.arch }} version: '5.15.0' - arch: ${{ inputs.arch == 'x64' && 'win64_msvc2019_64' || 'win32_msvc2019' }} - name: Clone VTK if: steps.cache-vtk.outputs.cache-hit != 'true' From bdb564f0eadcc0cf28b34566262464a4495feeed Mon Sep 17 00:00:00 2001 From: Kyle Sunderland Date: Wed, 21 Oct 2026 13:16:40 -0400 Subject: [PATCH 2/2] COMP: Do not fail the build when the CDash submission fails The superbuild's ctest invocation ended in -T Submit, so an open.cdash.org outage failed every Plus job whose build and tests had passed. Submit from a separate continue-on-error step instead, as the test results already are. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/build-plus.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-plus.yml b/.github/workflows/build-plus.yml index d7aa277cc..adaba75c7 100644 --- a/.github/workflows/build-plus.yml +++ b/.github/workflows/build-plus.yml @@ -190,11 +190,22 @@ jobs: } # -M/-T is used instead of -D so that the Nightly model does not run an # Update step, which would move the checkout to the nightly start time. - ctest -C Release -M ${{ inputs.dashboard-model }} -T Start -T Configure -T Build -T Test -T Submit -V + ctest -C Release -M ${{ inputs.dashboard-model }} -T Start -T Configure -T Build -T Test -V if ($LASTEXITCODE -ne 0) { throw "CTest failed with exit code $LASTEXITCODE" } + # Separate from the build step so that a CDash outage cannot fail the job. + - name: Submit build results to CDash + continue-on-error: true + shell: pwsh + working-directory: ${{ github.workspace }}/build + run: | + ctest -M ${{ inputs.dashboard-model }} -T Submit + if ($LASTEXITCODE -ne 0) { + throw "CDash submission failed with exit code $LASTEXITCODE" + } + # The runners have no GPU, so VTK cannot create a render window. Tests that # generate report plots (the calibration algorithm tests) crash without a # software OpenGL implementation. This installs Mesa system-wide.