From 97f64ae552192bc65e23aa1c50f3d6943b9ddafc Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Mon, 28 Sep 2026 18:05:13 +0200 Subject: [PATCH 01/10] ci: drop the redundant prefix and current-branch Co-Authored-By: Claude Opus 5.5 (1M context) --- .ci/manifest.toml | 1 - .github/workflows/ci.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.ci/manifest.toml b/.ci/manifest.toml index 238ea80aa..3c34a89d2 100644 --- a/.ci/manifest.toml +++ b/.ci/manifest.toml @@ -11,7 +11,6 @@ header = """ [package] name = "eckit" -prefix = "eckit" repo = "ecmwf/eckit" visibility = "public" compiler-inputs = ["cxx-compiler"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4506617d6..05a9c0323 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,6 @@ jobs: - id: r uses: ecmwf/ci-infrastructure/actions/resolve-deps@main with: - current-branch: ${{ github.head_ref || github.ref_name }} matrix: build,build-hpc token: ${{ steps.mint.outputs.token }} client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} From 8840bdefc4c6d7eea62ed0fae9b1172df93a570f Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 12:58:53 +0200 Subject: [PATCH 02/10] ci: drop the needs that [[deps]] implies Co-Authored-By: Claude Opus 5.5 (1M context) --- .ci/manifest.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.ci/manifest.toml b/.ci/manifest.toml index 3c34a89d2..7342fc3b4 100644 --- a/.ci/manifest.toml +++ b/.ci/manifest.toml @@ -48,7 +48,6 @@ triggers = ["upstream-change", "rebuild-request"] action = "./.github/actions/build-eckit" forwarded-inputs = ["c-compiler", "cxx-compiler", "build-type"] forwarded-deps-outputs = ["cmake-prefix-path"] -needs = ["ecbuild/build", "stack-deps/build"] ctest = true ctest-args = '-j "$(nproc)"' @@ -72,7 +71,6 @@ container-credentials = true job-script = "./.ci/hpc/build.sh.j2" triggers = ["upstream-change", "rebuild-request"] forwarded-deps-outputs = ["cmake-prefix-path"] -needs = ["ecbuild/build-hpc", "stack-deps/build-hpc"] [[trigger-downstream]] repo = "ecmwf/eccodes" From 85dee5f62e89723645f67ae1758ffb64e089ab3e Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 13:58:07 +0200 Subject: [PATCH 03/10] ci: drop [downstream-gate]; regenerate for level labels Co-Authored-By: Claude Opus 5.5 (1M context) --- .ci/manifest.toml | 2 -- .github/workflows/cross-repo-trigger-hpc.yml | 7 ++++++- .github/workflows/cross-repo-trigger.yml | 7 ++++++- .github/workflows/trigger-downstream-hpc.yml | 15 +++++++++++---- .github/workflows/trigger-downstream.yml | 15 +++++++++++---- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/.ci/manifest.toml b/.ci/manifest.toml index 7342fc3b4..df6ac0a5f 100644 --- a/.ci/manifest.toml +++ b/.ci/manifest.toml @@ -76,5 +76,3 @@ forwarded-deps-outputs = ["cmake-prefix-path"] repo = "ecmwf/eccodes" ref = "develop" -[downstream-gate] -label = "run-downstream-CI" diff --git a/.github/workflows/cross-repo-trigger-hpc.yml b/.github/workflows/cross-repo-trigger-hpc.yml index d36e3bfbf..76ab836d3 100644 --- a/.github/workflows/cross-repo-trigger-hpc.yml +++ b/.github/workflows/cross-repo-trigger-hpc.yml @@ -83,11 +83,15 @@ env: jobs: resolve: if: contains(fromJSON(inputs.from-jobs), 'ecbuild/build-hpc') || contains(fromJSON(inputs.from-jobs), 'stack-deps/build-hpc') || inputs.rebuild-request - runs-on: ubuntu-slim + runs-on: arc-runner-normal + container: + image: eccr.ecmwf.int/public-ci-images/ubuntu24.04-base:latest outputs: ref: ${{ steps.pick.outputs.ref }} matrix-build-hpc: ${{ steps.r.outputs.matrix-build-hpc }} steps: + - name: Announce image + uses: ecmwf/ci-infrastructure/actions/announce-image@main - id: mint uses: actions/create-github-app-token@v3 with: @@ -110,6 +114,7 @@ jobs: uses: ecmwf/ci-infrastructure/actions/resolve-deps@main with: current-branch: ${{ steps.pick.outputs.ref }} + pin: ${{ !inputs.rebuild-request && format('{0}@{1}', inputs.from-repo, inputs.from-sha) || '' }} matrix: build-hpc token: ${{ steps.mint.outputs.token }} client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} diff --git a/.github/workflows/cross-repo-trigger.yml b/.github/workflows/cross-repo-trigger.yml index 1fc89b783..11cb94059 100644 --- a/.github/workflows/cross-repo-trigger.yml +++ b/.github/workflows/cross-repo-trigger.yml @@ -83,11 +83,15 @@ env: jobs: resolve: if: contains(fromJSON(inputs.from-jobs), 'ecbuild/build') || contains(fromJSON(inputs.from-jobs), 'stack-deps/build') || inputs.rebuild-request - runs-on: ubuntu-slim + runs-on: arc-runner-normal + container: + image: eccr.ecmwf.int/public-ci-images/ubuntu24.04-base:latest outputs: ref: ${{ steps.pick.outputs.ref }} matrix-build: ${{ steps.r.outputs.matrix-build }} steps: + - name: Announce image + uses: ecmwf/ci-infrastructure/actions/announce-image@main - id: mint uses: actions/create-github-app-token@v3 with: @@ -110,6 +114,7 @@ jobs: uses: ecmwf/ci-infrastructure/actions/resolve-deps@main with: current-branch: ${{ steps.pick.outputs.ref }} + pin: ${{ !inputs.rebuild-request && format('{0}@{1}', inputs.from-repo, inputs.from-sha) || '' }} matrix: build token: ${{ steps.mint.outputs.token }} client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} diff --git a/.github/workflows/trigger-downstream-hpc.yml b/.github/workflows/trigger-downstream-hpc.yml index 3ec2ef59f..854b1d113 100644 --- a/.github/workflows/trigger-downstream-hpc.yml +++ b/.github/workflows/trigger-downstream-hpc.yml @@ -35,19 +35,23 @@ jobs: pull-requests: read outputs: run: ${{ steps.gate.outputs.run }} + depth: ${{ steps.gate.outputs.depth }} steps: - name: Check the downstream-CI label id: gate uses: ecmwf/ci-infrastructure/actions/check-pr-label@main with: - label: run-downstream-CI sha: ${{ needs.context.outputs.head-sha }} needs: - context validate: if: ${{ (needs.context.outputs.ci-conclusion == 'success') && needs['label-gate'].outputs.run == 'true' }} - runs-on: ubuntu-slim + runs-on: arc-runner-normal + container: + image: eccr.ecmwf.int/public-ci-images/ubuntu24.04-base:latest steps: + - name: Announce image + uses: ecmwf/ci-infrastructure/actions/announce-image@main - id: mint uses: actions/create-github-app-token@v3 with: @@ -117,7 +121,7 @@ jobs: branch: ${{ needs.context.outputs.head-branch }} fallback-ref: develop secrets: inherit - if: ${{ needs['label-gate'].outputs.run == 'true' }} + if: ${{ needs['label-gate'].outputs.run == 'true' && (needs['label-gate'].outputs.depth == 'all' || needs['label-gate'].outputs.depth >= 1) }} report-result: needs: - context @@ -139,9 +143,12 @@ jobs: state=failure fi done + depth="${{ needs['label-gate'].outputs.depth }}" + scope="" + if [ "$depth" != all ]; then scope=" (up to level $depth)"; fi gh api -X POST \ "/repos/${{ github.repository }}/statuses/${{ needs.context.outputs.head-sha }}" \ -f state="$state" \ -f context='downstream/hpc' \ -f target_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - -f description="Downstream HPC tests $state" + -f description="Downstream HPC tests $state$scope" diff --git a/.github/workflows/trigger-downstream.yml b/.github/workflows/trigger-downstream.yml index 2e73d12de..9d7e847ad 100644 --- a/.github/workflows/trigger-downstream.yml +++ b/.github/workflows/trigger-downstream.yml @@ -35,19 +35,23 @@ jobs: pull-requests: read outputs: run: ${{ steps.gate.outputs.run }} + depth: ${{ steps.gate.outputs.depth }} steps: - name: Check the downstream-CI label id: gate uses: ecmwf/ci-infrastructure/actions/check-pr-label@main with: - label: run-downstream-CI sha: ${{ needs.context.outputs.head-sha }} needs: - context validate: if: ${{ (needs.context.outputs.ci-conclusion == 'success') && needs['label-gate'].outputs.run == 'true' }} - runs-on: ubuntu-slim + runs-on: arc-runner-normal + container: + image: eccr.ecmwf.int/public-ci-images/ubuntu24.04-base:latest steps: + - name: Announce image + uses: ecmwf/ci-infrastructure/actions/announce-image@main - id: mint uses: actions/create-github-app-token@v3 with: @@ -117,7 +121,7 @@ jobs: branch: ${{ needs.context.outputs.head-branch }} fallback-ref: develop secrets: inherit - if: ${{ needs['label-gate'].outputs.run == 'true' }} + if: ${{ needs['label-gate'].outputs.run == 'true' && (needs['label-gate'].outputs.depth == 'all' || needs['label-gate'].outputs.depth >= 1) }} report-result: needs: - context @@ -139,9 +143,12 @@ jobs: state=failure fi done + depth="${{ needs['label-gate'].outputs.depth }}" + scope="" + if [ "$depth" != all ]; then scope=" (up to level $depth)"; fi gh api -X POST \ "/repos/${{ github.repository }}/statuses/${{ needs.context.outputs.head-sha }}" \ -f state="$state" \ -f context='downstream/runner' \ -f target_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ - -f description="Downstream runner tests $state" + -f description="Downstream runner tests $state$scope" From 4cfd21dd33e2b25d63b157b46e48ff30ff423874 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 14:22:11 +0200 Subject: [PATCH 04/10] ci: regenerate the downstream-CI workflows by bot Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/regenerate-workflows.yml | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/regenerate-workflows.yml diff --git a/.github/workflows/regenerate-workflows.yml b/.github/workflows/regenerate-workflows.yml new file mode 100644 index 000000000..aa038ac83 --- /dev/null +++ b/.github/workflows/regenerate-workflows.yml @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 1996- European Centre for Medium-Range Weather Forecasts (ECMWF) +# SPDX-License-Identifier: Apache-2.0 + +name: Regenerate downstream-CI workflows + +on: + push: + branches: [develop] + # Drift also comes from sibling manifests and the generator. + schedule: + - cron: '17 3 * * *' + workflow_dispatch: + +concurrency: + group: regenerate-workflows-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + regenerate: + uses: ecmwf/ci-infrastructure/.github/workflows/regenerate-workflows.yml@main + secrets: inherit + with: + # Downstream CI runs the default branch's orchestrator, so it cannot test this PR. + labels: downstream-CI-not-needed From 11d87fb1011cc2b04542f3fb620f8514b72f47c4 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 15:33:13 +0200 Subject: [PATCH 05/10] ci: lowercase downstream-CI labels, from the actions' defaults Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/pr-label-downstream-ci.yml | 2 -- .github/workflows/regenerate-workflows.yml | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/pr-label-downstream-ci.yml b/.github/workflows/pr-label-downstream-ci.yml index c34c30f72..7bae05b63 100644 --- a/.github/workflows/pr-label-downstream-ci.yml +++ b/.github/workflows/pr-label-downstream-ci.yml @@ -22,7 +22,5 @@ jobs: steps: - uses: ecmwf/ci-infrastructure/actions/require-label-decision@main with: - label: run-downstream-CI - opt-out-label: downstream-CI-not-needed context: downstream-ci-label description-decided: Downstream-CI decision recorded diff --git a/.github/workflows/regenerate-workflows.yml b/.github/workflows/regenerate-workflows.yml index aa038ac83..4528a1f58 100644 --- a/.github/workflows/regenerate-workflows.yml +++ b/.github/workflows/regenerate-workflows.yml @@ -24,4 +24,4 @@ jobs: secrets: inherit with: # Downstream CI runs the default branch's orchestrator, so it cannot test this PR. - labels: downstream-CI-not-needed + labels: downstream-ci-not-needed From a452a3fddddf8bb695ba3e70af45ac423abd39d6 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 17:55:32 +0200 Subject: [PATCH 06/10] job-script and ctest-args in the leg defaults Co-Authored-By: Claude Opus 5.5 (1M context) --- .ci/manifest.toml | 6 ++++-- .github/workflows/ci.yml | 2 +- .github/workflows/cross-repo-trigger-hpc.yml | 2 +- .github/workflows/cross-repo-trigger.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.ci/manifest.toml b/.ci/manifest.toml index df6ac0a5f..7458d0439 100644 --- a/.ci/manifest.toml +++ b/.ci/manifest.toml @@ -30,6 +30,7 @@ compiler-inputs = ["cxx-compiler"] [matrix.build.defaults] build-type = "RelWithDebInfo" runs-on = "arc-runner-very-large" +ctest-args = '-j "$(nproc)"' [[matrix.build.include]] cxx-compiler = "clang++-18" @@ -49,7 +50,9 @@ action = "./.github/actions/build-eckit" forwarded-inputs = ["c-compiler", "cxx-compiler", "build-type"] forwarded-deps-outputs = ["cmake-prefix-path"] ctest = true -ctest-args = '-j "$(nproc)"' + +[matrix.build-hpc.defaults] +job-script = "./.ci/hpc/build.sh.j2" [[matrix.build-hpc.include]] cxx-compiler = "g++-8" @@ -68,7 +71,6 @@ time = "00:40:00" [matrix.build-hpc] execution = "hpc" container-credentials = true -job-script = "./.ci/hpc/build.sh.j2" triggers = ["upstream-change", "rebuild-request"] forwarded-deps-outputs = ["cmake-prefix-path"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05a9c0323..508b308b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,7 +161,7 @@ jobs: uses: ecmwf/ci-infrastructure/actions/build-on-hpc@main with: site: ${{ matrix.site }} - job-script: ${{ matrix.job-script || './.ci/hpc/build.sh.j2' }} + job-script: ${{ matrix.job-script }} # The render context for the .j2 recipe: the toolchain this leg declares. matrix-leg: ${{ toJSON(matrix) }} artifact-name: ${{ matrix._resolved.own-artifact-name }} diff --git a/.github/workflows/cross-repo-trigger-hpc.yml b/.github/workflows/cross-repo-trigger-hpc.yml index 76ab836d3..f3a336574 100644 --- a/.github/workflows/cross-repo-trigger-hpc.yml +++ b/.github/workflows/cross-repo-trigger-hpc.yml @@ -197,7 +197,7 @@ jobs: uses: ecmwf/ci-infrastructure/actions/build-on-hpc@main with: site: ${{ matrix.site }} - job-script: ${{ matrix.job-script || './.ci/hpc/build.sh.j2' }} + job-script: ${{ matrix.job-script }} matrix-leg: ${{ toJSON(matrix) }} artifact-name: ${{ steps.m.outputs.own-artifact-name }} cmake-prefix-path: ${{ steps.deps.outputs.cmake-prefix-path }} diff --git a/.github/workflows/cross-repo-trigger.yml b/.github/workflows/cross-repo-trigger.yml index 11cb94059..bd9083fb0 100644 --- a/.github/workflows/cross-repo-trigger.yml +++ b/.github/workflows/cross-repo-trigger.yml @@ -203,7 +203,7 @@ jobs: cxx-compiler: ${{ steps.m.outputs.cxx-compiler }} build-type: ${{ steps.m.outputs.build-type }} - name: Test - run: ctest --test-dir "${{ steps.build.outputs.build-dir }}" --output-on-failure -j "$(nproc)" + run: ctest --test-dir "${{ steps.build.outputs.build-dir }}" --output-on-failure ${{ matrix._resolved['ctest-args'] }} - name: Publish uses: ecmwf/ci-infrastructure/actions/publish-artifact@main with: From b8fbcf095ed925b72ddeadeb67fd19d0a9fb6bf7 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 18:18:53 +0200 Subject: [PATCH 07/10] Lint against the hpc-submit runner group Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/actionlint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 0665d7d5c..7da196935 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -11,5 +11,5 @@ self-hosted-runner: - arc-runner-normal - arc-runner-large - arc-runner-very-large - - arc-hpc-pet-vsphere-prod + - hpc-submit - hpc From 9223d73bae7d521088c96d36f24d88e9f8493fbf Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 18:23:53 +0200 Subject: [PATCH 08/10] Check out with actions/checkout Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 508b308b2..f7a0c4481 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} private-key: ${{ secrets.CI_PERMISSIONS_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - uses: ecmwf/ci-infrastructure/actions/checkout-under-test@main + - uses: actions/checkout@v6 - id: r uses: ecmwf/ci-infrastructure/actions/resolve-deps@main with: @@ -86,7 +86,7 @@ jobs: client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} private-key: ${{ secrets.CI_PERMISSIONS_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - uses: ecmwf/ci-infrastructure/actions/checkout-under-test@main + - uses: actions/checkout@v6 - name: Fetch resolved deps id: deps @@ -144,7 +144,7 @@ jobs: client-id: ${{ secrets.CI_PERMISSIONS_APP_CLIENT_ID }} private-key: ${{ secrets.CI_PERMISSIONS_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} - - uses: ecmwf/ci-infrastructure/actions/checkout-under-test@main + - uses: actions/checkout@v6 - name: Fetch resolved deps id: deps From 81bd87155ead3d089a3389664f785887a7515a24 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 18:31:22 +0200 Subject: [PATCH 09/10] Run the downstream-CI label gate on pull_request Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/pr-label-downstream-ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/pr-label-downstream-ci.yml b/.github/workflows/pr-label-downstream-ci.yml index 7bae05b63..49046b90d 100644 --- a/.github/workflows/pr-label-downstream-ci.yml +++ b/.github/workflows/pr-label-downstream-ci.yml @@ -4,13 +4,9 @@ name: "[PR] Downstream-CI label gate" on: - # pull_request_target runs the BASE branch's copy of this file and gets a token - # that can post a status on a fork's pull request. Safe here because nothing - # from the pull request is ever checked out or executed. - # # `labeled`/`unlabeled` are what make the gate reactive; `synchronize` re-posts # it, since a commit status is per-SHA. - pull_request_target: + pull_request: types: [opened, reopened, synchronize, labeled, unlabeled] permissions: From bbf63866e92113423e1b852b466f4c53cd29cb21 Mon Sep 17 00:00:00 2001 From: Oskar Weser Date: Tue, 29 Sep 2026 18:42:02 +0200 Subject: [PATCH 10/10] ci: regenerate without the fork checkout opt-in Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/trigger-downstream-hpc.yml | 1 - .github/workflows/trigger-downstream.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/trigger-downstream-hpc.yml b/.github/workflows/trigger-downstream-hpc.yml index 854b1d113..22d928aff 100644 --- a/.github/workflows/trigger-downstream-hpc.yml +++ b/.github/workflows/trigger-downstream-hpc.yml @@ -62,7 +62,6 @@ jobs: with: ref: ${{ needs.context.outputs.head-sha }} token: ${{ steps.mint.outputs.token }} - allow-unsafe-pr-checkout: true - uses: ecmwf/ci-infrastructure/actions/validate-generated-workflows@main with: token: ${{ steps.mint.outputs.token }} diff --git a/.github/workflows/trigger-downstream.yml b/.github/workflows/trigger-downstream.yml index 9d7e847ad..0ecd74945 100644 --- a/.github/workflows/trigger-downstream.yml +++ b/.github/workflows/trigger-downstream.yml @@ -62,7 +62,6 @@ jobs: with: ref: ${{ needs.context.outputs.head-sha }} token: ${{ steps.mint.outputs.token }} - allow-unsafe-pr-checkout: true - uses: ecmwf/ci-infrastructure/actions/validate-generated-workflows@main with: token: ${{ steps.mint.outputs.token }}