From 44fc4fb379393db6e120b1966f08cfed96b90b51 Mon Sep 17 00:00:00 2001 From: "Thing-han, Lim" <15379156+potsrevennil@users.noreply.github.com> Date: Tue, 20 Oct 2026 15:25:40 +0800 Subject: [PATCH] fix(ci): pin plugins to lazy-lock.json on a fresh restore A bare `Lazy! restore` on a cache miss lets lazy.nvim's first-run install rewrite the lockfile before LazyVim's imported specs are known, leaving those plugins at their upstream target. Install first, copy the committed lock back, restore, and cmp the result -- the same sequence lazy-update.yml uses. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a23f16e..4a7e67f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,8 +121,23 @@ jobs: with: path: ~/.local/share/nvim/lazy key: lazy-${{ matrix.runs-on }}-${{ hashFiles('lazy-lock.json') }} + # The wrapped nvim loads its config from the read-only store, so + # lazy.nvim reads and writes the lockfile through a stdpath("state") + # copy (see lua/config/lazy.lua), hence the copy in below. + # + # A bare `Lazy! restore` on a fresh runner (cache miss above) doesn't + # reproduce the lock: the first-run install handles LazyVim before the + # plugins its specs import are known, rewrites the lockfile without + # their entries, and then installs them at their upstream target. So + # install first, put the committed lock back, restore, and check it + # took. On a cache hit every plugin is already on disk, so the first + # `+qa` installs nothing. - name: Restore plugins - run: nvim --headless "+Lazy! restore" +qa + run: | + nvim --headless +qa + cp lazy-lock.json ~/.local/state/nvim/lazy-lock.json + nvim --headless "+Lazy! restore" +qa + cmp lazy-lock.json ~/.local/state/nvim/lazy-lock.json - name: Run smoke test run: nvim --headless -S .github/scripts/smoke-test.lua # Appended here rather than a separate workflow: this job already paid