Hardcoded tool versions in a GitHub Actions step drift from mise.lock under Renovate
Renovate bumps mise.lock but a version pinned inside a workflow run step stays stale, and MISE_LOCKED=1 then aborts. Install tools by name and let the lockfile decide.
A run: step in a GitHub Actions workflow pinned a tool inline:
# .github/workflows/quality.yml
- name: Install locked toolchain
run: |
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
MISE_CONFIG_DIR="$tmpdir" MISE_LOCKED=1 mise install node actionlint "github:zizmorcore/zizmor@v1.25.2"
Renovate’s mise manager bumped the same tool in mise.toml and mise.lock to 1.26.1 in its weekly PR. The two pins disagreed. MISE_LOCKED=1 enforces the lockfile, so it refused to resolve the inline @v1.25.2 against a lockfile that now said 1.26.1:
mise ERROR Failed to install github:zizmorcore/zizmor@v1.25.2: No lockfile URL found for github:zizmorcore/zizmor@1.25.2 on platform linux-x64 (--locked mode)
hint: Run `mise lock` to generate lockfile URLs, or disable locked mode
Same drift class as Corepack packageManager vs mise.toml: two sources of truth for one version, updated in different places.
Fix
Drop the version suffix and install by tool name. The lockfile is the only source of truth.
# .github/workflows/quality.yml
MISE_CONFIG_DIR="$tmpdir" MISE_LOCKED=1 mise install node actionlint "github:zizmorcore/zizmor"
Verified locally, and on the rebased PR with the lockfile at zizmor 1.26.1: the command resolves from mise.lock without error.
Notes
MISE_CONFIG_DIR="$tmpdir" points mise at an empty config directory so the install is driven by the repo’s mise.toml/mise.lock, with no global config layered on top. The lockfile pins the tool under [[tools."github:zizmorcore/zizmor"]]; the command keeps that full name and drops the version so the lockfile decides it.
If a version genuinely must live in the workflow (a toolchain: input to an action), teach Renovate to bump it in lockstep with a customManagers regex instead of leaving it manual. One source of truth is still preferred.
References
- Renovate
misemanager. Bumpsmise.toml/mise.lock, not inline workflow pins - mise locked mode.
MISE_LOCKED=1enforces the lockfile and fails on version drift - Corepack
packageManagerdrifts from mise.toml under Renovate. The same drift class for a different duplicate - Reducing Renovate’s blast radius. The
customManagersregex approach for pins that must stay in the workflow
This post was written with AI assistance.