From c9e1656d3b5a5574ede4f2edaf30e50208013ce9 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 12 Nov 2026 11:42:12 +0000 Subject: [PATCH 1/4] ci(test): key the mise tool cache on mise.lock and restore the newest one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mise-action keys its cache on a hash of every mise config file and has no restore-keys. An edit to a task in mise.toml missed the cache and every tool downloaded again. On #545's merge-group runs www.lua.org reset the connection, mise gave up after 3 retries and the unit-tests job failed before it ran a test. Cache the mise data dir with actions/cache, keyed on mise.lock, with the mise version as a restore-keys prefix, and turn mise-action's cache off. Raise mise's HTTP retries from 3 to 6. _Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: --- .github/workflows/test.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 96850793e..f96484150 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,15 +31,34 @@ jobs: fetch-depth: 0 persist-credentials: false + # mise-action's own cache is keyed on a hash of every mise config file, so an edit to a task in mise.toml + # misses it and every tool downloads again (www.lua.org failed the next step that way), and it has no + # restore-keys. This cache is keyed on mise.lock, which pins the tool set. When the lock changes, the + # newest cache of the same mise version restores and only the changed tools download. The key prefix is + # the one mise-action used, so its caches restore too. + - name: Cache mise tools + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: ~/.local/share/mise + key: mise-v1-linux-x64-2026.11.5-${{ hashFiles('mise.lock') }} + restore-keys: | + mise-v1-linux-x64-2026.11.5- + - name: Set up mise uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 + env: + # mise retries a failed download 3 times, with 3 to 5 s of backoff in total. 6 retries give 25 to 50 s. + MISE_HTTP_RETRIES: "6" with: # --locked installs only tools listed in mise.lock, fails when an entry is missing, and never rewrites it. # Without it, `mise install` fills in missing lock data and downloads tools again to do it, so a slow # www.lua.org failed this step. install_args: --locked + # The cache above replaces mise-action's own. + cache: false # mise is pinned because `--locked` rules change between releases (2026.11.0 started to require a - # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. + # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. The cache keys above + # name this version too. version: 2026.11.5 sha256: 7a5b051d6f17d335c502f8047a5175cf3103f347d91942771c60da4e302ebcb0 From d0b854e7fc7fadb843c88a724a41553d4503451a Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 12 Nov 2026 12:31:46 +0000 Subject: [PATCH 2/4] fix(ci): key mise-action's own cache on mise.lock and drop the restore-keys step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex found four problems in the separate actions/cache step: - Its path "~/.local/share/mise" gives another cache version than the absolute path that mise-action uses, so it could not restore the caches that mise-action saved. A cache version hashes the path as written. - Its restore-keys prefix restored installed tools across lock changes. mise does not check an installed tool against mise.lock, so a tool whose checksum changed at the same version stayed as it was. - That fallback also kept every old tool version in the next cache. - Its post step saved the cache after the PR's scripts had run. Use the cache_key input of mise-action instead. The key hashes only mise.lock, so an edit to a task in mise.toml keeps it. mise-action saves right after the install, from an exact key, as before. Keep the 6 HTTP retries. _Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh_ --- .github/workflows/test.yml | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f96484150..d454d9418 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,19 +31,6 @@ jobs: fetch-depth: 0 persist-credentials: false - # mise-action's own cache is keyed on a hash of every mise config file, so an edit to a task in mise.toml - # misses it and every tool downloads again (www.lua.org failed the next step that way), and it has no - # restore-keys. This cache is keyed on mise.lock, which pins the tool set. When the lock changes, the - # newest cache of the same mise version restores and only the changed tools download. The key prefix is - # the one mise-action used, so its caches restore too. - - name: Cache mise tools - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 - with: - path: ~/.local/share/mise - key: mise-v1-linux-x64-2026.11.5-${{ hashFiles('mise.lock') }} - restore-keys: | - mise-v1-linux-x64-2026.11.5- - - name: Set up mise uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 env: @@ -54,11 +41,13 @@ jobs: # Without it, `mise install` fills in missing lock data and downloads tools again to do it, so a slow # www.lua.org failed this step. install_args: --locked - # The cache above replaces mise-action's own. - cache: false + # The default cache key hashes every mise config file, so an edit to a task in mise.toml missed the cache and + # every tool downloaded again. mise.lock pins the tool set, so this key hashes only it. There are no + # restore-keys on purpose: mise does not check an installed tool against mise.lock, so a cache restored from + # another lock could keep a tool that the new lock changed. + cache_key: mise-v1-{{platform}}-{{version}}-${{ hashFiles('mise.lock') }} # mise is pinned because `--locked` rules change between releases (2026.11.0 started to require a - # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. The cache keys above - # name this version too. + # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. version: 2026.11.5 sha256: 7a5b051d6f17d335c502f8047a5175cf3103f347d91942771c60da4e302ebcb0 From d08f39530a3d095fb3834d794545b040f1caa9b5 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 12 Nov 2026 13:12:48 +0000 Subject: [PATCH 3/4] docs(ci): correct the retry backoff in the mise comment and say when to bump the cache key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mise's schedule is about 200 ms, 1 s and 4 s for 3 retries, each cut by a random factor of 0.5 to 1, so the total is 2.6 to 5.2 s. A failed run waited 2.7 s. Also say that a change which alters an install without changing mise.lock keeps the key. _Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh_ --- .github/workflows/test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d454d9418..9037b46d7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,7 +34,7 @@ jobs: - name: Set up mise uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1 env: - # mise retries a failed download 3 times, with 3 to 5 s of backoff in total. 6 retries give 25 to 50 s. + # mise retries a failed download 3 times, with 2.6 to 5.2 s of backoff in total. 6 retries give 25 to 50 s. MISE_HTTP_RETRIES: "6" with: # --locked installs only tools listed in mise.lock, fails when an entry is missing, and never rewrites it. @@ -44,7 +44,8 @@ jobs: # The default cache key hashes every mise config file, so an edit to a task in mise.toml missed the cache and # every tool downloaded again. mise.lock pins the tool set, so this key hashes only it. There are no # restore-keys on purpose: mise does not check an installed tool against mise.lock, so a cache restored from - # another lock could keep a tool that the new lock changed. + # another lock could keep a tool that the new lock changed. A change that alters an install without changing + # mise.lock (a tool option in mise.toml) keeps this key: bump v1 then. cache_key: mise-v1-{{platform}}-{{version}}-${{ hashFiles('mise.lock') }} # mise is pinned because `--locked` rules change between releases (2026.11.0 started to require a # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. From 61d7ea13b2802f2f4c6470e59e8ecc3552a70fba Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Thu, 12 Nov 2026 13:25:35 +0000 Subject: [PATCH 4/4] fix(ci): save the mise cache only on pushes to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mise runs the postinstall hooks of the PR's own mise.toml during mise install, and mise-action saves after that. The key ignores mise.toml, so a PR could keep a tampered tool in its own cache after it removed the hook, and its later runs would restore it. Set cache_save to true only for the push event, which the workflow runs on main only. Pull requests, the merge queue and manual runs restore the cache and never write it. _Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh_ --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9037b46d7..30fae85cc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,6 +47,9 @@ jobs: # another lock could keep a tool that the new lock changed. A change that alters an install without changing # mise.lock (a tool option in mise.toml) keeps this key: bump v1 then. cache_key: mise-v1-{{platform}}-{{version}}-${{ hashFiles('mise.lock') }} + # Only a push to main saves the cache. A pull request only restores it: mise runs the postinstall hooks of the + # PR's own mise.toml before the save, and the key above ignores mise.toml. + cache_save: ${{ github.event_name == 'push' }} # mise is pinned because `--locked` rules change between releases (2026.11.0 started to require a # checksum). sha256 is the linux-x64 mise binary from the v2026.11.5 release. version: 2026.11.5