From 88e872b0e4cb49b8c471ce2c251cee9f83b6029f Mon Sep 17 00:00:00 2001 From: Chris Taylor Date: Fri, 25 Sep 2026 10:26:19 +0100 Subject: [PATCH] fix(actions): stop a killed npm upgrade wedging an agent for good `npm i -g npm` renames the live npm directory aside to `.npm-` before unpacking the new one. The suffix is derived from the path, not random, so an install killed part-way leaves that directory behind and every later install on the same agent fails the rename with ENOTEMPTY. The agent stays broken until someone deletes it by hand -- prosvr8-3 sat like that from 2026-09-24 and failed this step on every job it picked up. Skip the install when npm is already the pinned version, which on a self-hosted agent is every run after the first, and sweep any leftover staging directory before installing for the agents already holding one. Co-Authored-By: Claude Opus 5 (1M context) --- .github/actions/npm/action.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/actions/npm/action.yml b/.github/actions/npm/action.yml index 611aaaf..1cc19b0 100644 --- a/.github/actions/npm/action.yml +++ b/.github/actions/npm/action.yml @@ -28,12 +28,31 @@ runs: uses: prosopo/github_actions/.github/actions/restore_npm_cache@main if: ${{ inputs.restore_npm_cache }} + # `npm i -g npm` upgrades npm by renaming the live npm directory out of the + # way to `.npm-` and unpacking the new one in its place. The suffix + # is stable for a given path, not random, so an install killed part-way -- + # a cancelled run, an agent restart -- leaves that directory behind, and + # every later install on the same agent fails the rename with ENOTEMPTY. + # The agent is then wedged for good: prosvr8-3 was left like that on + # 2026-09-24 and failed this step on every job it picked up for a day. + # + # Doing nothing when npm is already the version we want avoids the rename + # altogether, which on a self-hosted agent is every run after the first. + # Sweeping the leftovers covers the agents already holding one. - name: install npm shell: bash + # 11.6.3 cannot install a tree that uses `overrides`: npm/cli#8757. + # Read from package.json `engines.npm` again once that is released fixed. + env: + NPM_VERSION: "11.6.2" run: | - npm i -g "npm@11.6.2" -# Commented until npm fixes itself https://github.com/npm/cli/issues/8757 -# npm i -g "npm@$(jq -r '.engines.npm // "latest"' < package.json)" + set -euo pipefail + if [ "$(npm -v)" = "$NPM_VERSION" ]; then + echo "npm $NPM_VERSION is already installed" + exit 0 + fi + rm -rf "$(npm prefix -g)/lib/node_modules"/.npm-* + npm i -g "npm@$NPM_VERSION" # Skip `npm ci` when node_modules was restored from an exact-lockfile cache hit: the tree # already matches the lockfile, and `npm ci` would only delete it and reinstall the identical