From f6a8c7282b605d934f7b1498392d5a35bb599cbc Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Sun, 23 Aug 2026 23:05:44 +0900 Subject: [PATCH 1/3] Bring the GitHub Actions up to date, and let Dependabot keep them there MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing here had been bumped since it was written, and two of the actions had aged past working. `julia-actions/cache@v1` speaks a cache-service API GitHub has retired, so every job logged ##[warning]Failed to restore: Cache service responded with 400 Cache not found for input keys: julia-cache;workflow=CI;job=test;... and CI has been running with no dependency cache at all — every job rebuilding and re-precompiling the whole tree from scratch. And the runners were force- migrating `actions/checkout@v4`, `julia-actions/setup-julia@v1` and the cache action's bundled `actions/cache` off Node 20, which is on a deprecation clock. Three of the pins were `@latest`, which is not a moving alias — it is a literal tag, and neither upstream still moves theirs. `julia-actions/setup-julia@latest` is a commit from November 2024 matching no release, and `julia-actions/RegisterAction@latest` one from November 2022, older than that action's own v0.3.2. Both read as if they track upstream and do not. actions/checkout v4, v3 -> v7 actions/upload-artifact v4 -> v7 julia-actions/setup-julia v1, @latest -> v3 julia-actions/cache v1 -> v3 codecov/codecov-action v3 -> v7 julia-actions/RegisterAction @latest -> v0.3.2 `julia-buildpkg`, `julia-runtest`, `julia-processcoverage`, `julia-docdeploy` and `TagBot` are all still on their current major. Two behaviour changes come with this. The `arch: x64` matrix pin is gone. `macOS-latest` is aarch64, and setup-julia v3 refuses `x64` there unless `force-arch` is set, because that build runs under Rosetta — which is not the platform anyone deploys on. Each runner now gets its native architecture, and the job name loses its `- x64` component. Nothing required those names: `main`'s branch protection lists no required status checks. `cache-registries: false`, against the action's default. The registry is the one part of the depot that must not persist between runs. The package server's General snapshot already lags the registry by hours — a run at 08:01 UTC today still reported `AbstractNeuralNetworks ... possible versions are: 0.1.0 - 0.6.4` four hours after 0.7.0 was registered — and caching it on top of that would keep a freshly registered dependency invisible to CI for days. Artifacts, packages, compiled code and scratchspaces are still cached, which is where the time goes. Co-Authored-By: Claude Opus 5 (1M context) --- .github/dependabot.yml | 19 +++++++++++++++++++ .github/workflows/CI.yml | 28 ++++++++++++++-------------- .github/workflows/Documenter.yml | 6 ++++-- .github/workflows/Latex.yml | 6 +++--- .github/workflows/Register.yml | 4 +++- 5 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..eb47f079e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,19 @@ +# Keeps the GitHub Actions in `.github/workflows/` current. +# +# Julia dependencies are not handled here — Dependabot has no Julia ecosystem, and +# `.github/workflows/CompatHelper.yml` already opens the `[compat]` bumps nightly. +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + # One PR per action rather than a combined bump: a major of `setup-julia` or `codecov-action` + # can need a workflow change alongside it, and that is easier to review on its own. + open-pull-requests-limit: 10 + commit-message: + prefix: "CI" + labels: + - dependencies + - github-actions diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6c44a9398..a61e9ce90 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,7 +12,7 @@ concurrency: cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} strategy: @@ -25,45 +25,45 @@ jobs: - ubuntu-latest - macOS-latest - windows-latest - arch: - - x64 experimental: [false] include: - version: "^1.13.0-0" os: ubuntu-latest - arch: x64 experimental: true - version: "^1.13.0-0" os: macOS-latest - arch: x64 experimental: true - version: "^1.13.0-0" os: windows-latest - arch: x64 experimental: true - version: "nightly" os: ubuntu-latest - arch: x64 experimental: true - version: "nightly" os: macOS-latest - arch: x64 experimental: true - version: "nightly" os: windows-latest - arch: x64 experimental: true steps: - - uses: actions/checkout@v4 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v7 + # No `arch:` pin. `macOS-latest` is aarch64, and setup-julia refuses `x64` there + # unless `force-arch` is set — the x64 build would run under Rosetta, which is not + # the platform anyone deploys on. Each runner gets its native architecture. + - uses: julia-actions/setup-julia@v3 with: version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/cache@v1 + # `cache-registries` defaults to true. The registry is the one thing that must not be + # reused between runs: the package server's General snapshot already lags the registry + # by hours, and caching it adds a second layer of staleness, so a freshly registered + # dependency stays invisible to CI for days. Everything else is worth caching. + - uses: julia-actions/cache@v3 + with: + cache-registries: "false" - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v7 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index ce4426e5a..1e09145ad 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -12,14 +12,16 @@ jobs: name: Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 - name: Install packages for generating tikz images run: | sudo apt-get install imagemagick sudo apt-get install poppler-utils sudo apt-get install texlive-xetex sudo apt-get install texlive-science - - uses: julia-actions/setup-julia@latest + # `@latest` is not a moving alias — it is a literal tag, and upstream stopped moving it + # in November 2024. Pin the major instead. + - uses: julia-actions/setup-julia@v3 with: version: '1' - name: Install BrenierTwoFluid package diff --git a/.github/workflows/Latex.yml b/.github/workflows/Latex.yml index 567f10b26..00e951f5b 100644 --- a/.github/workflows/Latex.yml +++ b/.github/workflows/Latex.yml @@ -10,7 +10,7 @@ jobs: LatexDocs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: install imagemagick, poppler-utils and texlive run: | sudo apt-get install imagemagick @@ -20,7 +20,7 @@ jobs: sudo apt-get install latex-cjk-all sudo apt-get install texlive-fonts-recommended sudo apt-get install texlive-fonts-extra - - uses: julia-actions/setup-julia@latest + - uses: julia-actions/setup-julia@v3 with: version: '1' - name: install BrenierTwoFluid @@ -53,7 +53,7 @@ jobs: xelatex -shell-escape GeometricMachineLearning.jl.tex xelatex -shell-escape GeometricMachineLearning.jl.tex - name: Upload PDF file - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: Docs in PDF version path: docs/build/GeometricMachineLearning.jl.pdf diff --git a/.github/workflows/Register.yml b/.github/workflows/Register.yml index 6e71f2f96..3fce4f084 100644 --- a/.github/workflows/Register.yml +++ b/.github/workflows/Register.yml @@ -9,6 +9,8 @@ jobs: register: runs-on: ubuntu-latest steps: - - uses: julia-actions/RegisterAction@latest + # The `latest` tag points at a 2022 commit that matches no release; v0.3.2 (2023-01) is + # the newest one there is. + - uses: julia-actions/RegisterAction@v0.3.2 with: token: ${{ secrets.GITHUB_TOKEN }} From 2e070b651c3615751584d4b1159a3bbac71ac098 Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Sun, 23 Aug 2026 23:17:32 +0900 Subject: [PATCH 2/3] Take General from git in CI, since no package server has a current one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no `JULIA_PKG_SERVER` that works. Every official mirror — us-east, us-west, eu-central, jp, sg, kr, in, au — serves the identical registry tree, in both the conservative and the eager flavour, and so do the third-party storage mirrors (tuna, nju, bfsu). Checked this morning they were all on `4ead4e5d`, which is General as of 18:04 the previous evening: fifteen hours behind, and hours after `AbstractNeuralNetworks` 0.7.0 (04:00), `NeuralNetworkParameters` 0.1.1 (04:12) and `GeometricOptimizers` 0.4.1 (06:10) were registered. The lag is at the single storage server they all pull from, not at the edges, so picking a different one changes nothing. Cloning General over git is the only thing that sees a version the moment it is registered, and it is what #246 needs to resolve at all. The clone costs a fetch of the registry per job; against jobs that currently cannot resolve, that is worth paying. `JULIA_PKG_SERVER` itself is deliberately left alone. Unsetting it would route package tarballs off the CDN as well, which is not wanted — only the registry needs to bypass it. Verified locally: with General added by URL, `Pkg.pkg_server()` is still `https://pkg.julialang.org`, and `Pkg.add(name = "AbstractNeuralNetworks", version = "0.7")` resolves and installs 0.7.0. `julia-buildpkg` calls `Pkg.Registry.add()` on Julia >= 1.8, which installs the default registries only when none are present, so the step lands before it and nothing is duplicated — confirmed against a depot that already had the git clone. Added to `CI.yml`, `Documenter.yml` and `Latex.yml`, the three workflows that resolve. `cache-registries` stays false: a restored registry would only shadow the fresh clone. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/CI.yml | 17 ++++++++++++++--- .github/workflows/Documenter.yml | 5 +++++ .github/workflows/Latex.yml | 5 +++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a61e9ce90..52fdc8d26 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -54,12 +54,23 @@ jobs: with: version: ${{ matrix.version }} # `cache-registries` defaults to true. The registry is the one thing that must not be - # reused between runs: the package server's General snapshot already lags the registry - # by hours, and caching it adds a second layer of staleness, so a freshly registered - # dependency stays invisible to CI for days. Everything else is worth caching. + # reused between runs — the step below clones a current one, and a restored copy would + # only shadow it. Everything else is worth caching. - uses: julia-actions/cache@v3 with: cache-registries: "false" + # Every Julia package server serves the same registry snapshot, and it can sit most of a + # day behind the registry: on 2026-08-23 all eight official mirrors, in both the + # conservative and the eager flavour, were still on General as of 18:04 the previous + # evening — so `AbstractNeuralNetworks` 0.7.0, registered at 04:00, was invisible and + # every job failed to resolve. Cloning General over git is the only way to see a version + # the moment it is registered. `JULIA_PKG_SERVER` is deliberately left alone, so package + # tarballs still come from the CDN; only the registry bypasses it. + # + # `julia-buildpkg` calls `Pkg.Registry.add()` on Julia >= 1.8, which installs the default + # registries only when none are present, so this step wins and nothing is duplicated. + - name: Take General from git rather than the package server + run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 1e09145ad..658e5d122 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -24,6 +24,11 @@ jobs: - uses: julia-actions/setup-julia@v3 with: version: '1' + # The package server's General snapshot can sit most of a day behind the registry, and every + # mirror serves the same one; see the comment in `CI.yml`. `JULIA_PKG_SERVER` is left alone, + # so only the registry bypasses the CDN. + - name: Take General from git rather than the package server + run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - name: Install BrenierTwoFluid package run: | cd docs diff --git a/.github/workflows/Latex.yml b/.github/workflows/Latex.yml index 00e951f5b..ddb638561 100644 --- a/.github/workflows/Latex.yml +++ b/.github/workflows/Latex.yml @@ -23,6 +23,11 @@ jobs: - uses: julia-actions/setup-julia@v3 with: version: '1' + # The package server's General snapshot can sit most of a day behind the registry, and every + # mirror serves the same one; see the comment in `CI.yml`. `JULIA_PKG_SERVER` is left alone, + # so only the registry bypasses the CDN. + - name: Take General from git rather than the package server + run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - name: install BrenierTwoFluid run: | cd docs From b146301129cfe0626654fb7be201647400a330f5 Mon Sep 17 00:00:00 2001 From: Michael Kraus Date: Sun, 23 Aug 2026 23:31:13 +0900 Subject: [PATCH 3/3] Use JULIA_PKG_SERVER="" for the registry, as SymbolicNeuralNetworks does MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same effect as the explicit `Pkg.Registry.add(RegistrySpec(url = ...))` step this replaces — both end up cloning General over git — but it is the idiom the sibling repo already runs, it is one `env:` block rather than a step per workflow, and it needs no reasoning about where it sits relative to `julia-buildpkg`'s own `Pkg.Registry.add()`. The objection to it was that an empty `JULIA_PKG_SERVER` routes package tarballs off the CDN as well, not just the registry. Measured, that costs nothing worth having: the registry clone is 68 s and 275 MB either way (it is the same git clone), and installing `HDF5` with its jll artifacts took 8.8 s without a package server against 10.1 s with one. The CDN is not carrying the weight here. `arch: default` comes back with it, again matching SymbolicNeuralNetworks — the previous commit had dropped the matrix dimension entirely to get off `x64` on aarch64 macOS, which also dropped the arch component from every job name. `default` is the runner's own architecture and keeps the names. `cache-registries: false` stays, which is the one deliberate difference from the sibling repo. `julia-actions/cache` saves the depot at the end of a job and restores it at the start of the next, so a cached registry is whatever the previous run cloned — for a repo whose CI runs a few times a day that is the same staleness this commit is working around, reintroduced through the back door. Everything else in the depot is still cached. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/CI.yml | 52 ++++++++++++++++++++------------ .github/workflows/Documenter.yml | 9 +++--- .github/workflows/Latex.yml | 9 +++--- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 52fdc8d26..ed59798b1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,9 +10,26 @@ concurrency: # Cancel intermediate builds: only if it is a pull request build. group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +# Temporary: go straight to the General registry instead of through a package server. +# +# `AbstractNeuralNetworks` 0.7.0 was registered at 04:00 UTC on 2026-08-23 and the package servers +# were still serving a registry that stopped at 0.6.4 hours later, so jobs died in `Pkg.resolve` +# before running anything. It is not a matter of picking a better server: all eight official +# mirrors, in both the conservative and the eager flavour, and the third-party storage mirrors too, +# were serving the identical tree — the lag is at the storage server they all pull from. An empty +# `JULIA_PKG_SERVER` makes Pkg clone the registry over git and fetch packages from their own +# repositories, which resolves the same environment that resolves locally. Same workaround as +# SymbolicNeuralNetworks.jl. +# +# The cost is speed: no CDN and no registry tarball. Remove this once the package servers have +# caught up (check with `curl -sL https://pkg.julialang.org/registries` against +# `gh api repos/JuliaRegistries/General/commits/master --jq .commit.tree.sha`), and check whether it +# is still needed before assuming it is. +env: + JULIA_PKG_SERVER: "" jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} strategy: @@ -25,52 +42,49 @@ jobs: - ubuntu-latest - macOS-latest - windows-latest + # `default` is the runner's own architecture. Not `x64`: `macOS-latest` is aarch64, + # and setup-julia v3 refuses `x64` there unless `force-arch` is set, because that + # build runs under Rosetta. + arch: + - default experimental: [false] include: - version: "^1.13.0-0" os: ubuntu-latest + arch: default experimental: true - version: "^1.13.0-0" os: macOS-latest + arch: default experimental: true - version: "^1.13.0-0" os: windows-latest + arch: default experimental: true - version: "nightly" os: ubuntu-latest + arch: default experimental: true - version: "nightly" os: macOS-latest + arch: default experimental: true - version: "nightly" os: windows-latest + arch: default experimental: true steps: - uses: actions/checkout@v7 - # No `arch:` pin. `macOS-latest` is aarch64, and setup-julia refuses `x64` there - # unless `force-arch` is set — the x64 build would run under Rosetta, which is not - # the platform anyone deploys on. Each runner gets its native architecture. - uses: julia-actions/setup-julia@v3 with: version: ${{ matrix.version }} - # `cache-registries` defaults to true. The registry is the one thing that must not be - # reused between runs — the step below clones a current one, and a restored copy would - # only shadow it. Everything else is worth caching. + arch: ${{ matrix.arch }} + # `cache-registries` defaults to true; with the git registry above, a restored copy is + # whatever the previous run cloned, which puts the staleness straight back. Artifacts, + # packages and compiled code are still cached, which is where the time goes. - uses: julia-actions/cache@v3 with: cache-registries: "false" - # Every Julia package server serves the same registry snapshot, and it can sit most of a - # day behind the registry: on 2026-08-23 all eight official mirrors, in both the - # conservative and the eager flavour, were still on General as of 18:04 the previous - # evening — so `AbstractNeuralNetworks` 0.7.0, registered at 04:00, was invisible and - # every job failed to resolve. Cloning General over git is the only way to see a version - # the moment it is registered. `JULIA_PKG_SERVER` is deliberately left alone, so package - # tarballs still come from the CDN; only the registry bypasses it. - # - # `julia-buildpkg` calls `Pkg.Registry.add()` on Julia >= 1.8, which installs the default - # registries only when none are present, so this step wins and nothing is duplicated. - - name: Take General from git rather than the package server - run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 658e5d122..ed5e92c95 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -7,6 +7,10 @@ on: tags: '*' pull_request: +# Temporary: go straight to the General registry instead of through a package server; see the +# comment in `CI.yml`. Same workaround as SymbolicNeuralNetworks.jl. +env: + JULIA_PKG_SERVER: "" jobs: build: name: Documentation @@ -24,11 +28,6 @@ jobs: - uses: julia-actions/setup-julia@v3 with: version: '1' - # The package server's General snapshot can sit most of a day behind the registry, and every - # mirror serves the same one; see the comment in `CI.yml`. `JULIA_PKG_SERVER` is left alone, - # so only the registry bypasses the CDN. - - name: Take General from git rather than the package server - run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - name: Install BrenierTwoFluid package run: | cd docs diff --git a/.github/workflows/Latex.yml b/.github/workflows/Latex.yml index ddb638561..1e72c716b 100644 --- a/.github/workflows/Latex.yml +++ b/.github/workflows/Latex.yml @@ -6,6 +6,10 @@ on: - main pull_request: +# Temporary: go straight to the General registry instead of through a package server; see the +# comment in `CI.yml`. Same workaround as SymbolicNeuralNetworks.jl. +env: + JULIA_PKG_SERVER: "" jobs: LatexDocs: runs-on: ubuntu-latest @@ -23,11 +27,6 @@ jobs: - uses: julia-actions/setup-julia@v3 with: version: '1' - # The package server's General snapshot can sit most of a day behind the registry, and every - # mirror serves the same one; see the comment in `CI.yml`. `JULIA_PKG_SERVER` is left alone, - # so only the registry bypasses the CDN. - - name: Take General from git rather than the package server - run: julia -e 'using Pkg; Pkg.Registry.add(Pkg.RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))' - name: install BrenierTwoFluid run: | cd docs