actions / actions/runner

Runner self-updates don't preserve symlinks in externals

Open
#2,094 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug Runner Bug
Dominant language
C#
Stars
6.3k
Forks
1.4k
Avg merge
1d 16h
Merged PRs (30d)
24

Description

Describe the bug
When the self-updater recursively copies files from the update tarball into the root file system, it does so without paying attention to whether a file is a symlink.

In particular, the the npm, npx, and corepack symlinks bundled with Node.js are resolved to actual files. JS actions that aim to be portable across public runners and self-hosted runners (where Node.js isn't provided by the OS) that depend on these binaries being in the PATH stop working.

To Reproduce
Steps to reproduce the behavior:

  1. Host a self-hosted runner on a version older than 2.296.1
  2. Run an action that adds your runner's externals/node16/bin directory to the PATH
  3. Run a step that executes corepack enable or npm
  4. See error

Expected behavior
The loop here should handle when the file being copied is a symlink:

https://github.com/actions/runner/blob/352f201c6257e37b330df1b443ab734856fefb68/src/Runner.Sdk/Util/IOUtil.cs#L368-L380

Runner Version and Platform

Runner 2.296.0 (self-updating to 2.296.1)
Linux x64 (using https://github.com/actions-runner-controller/actions-runner-controller)

What's not working?

I can't execute corepack, but based on my testing, npm/npx seems to be broken too. The updated externals have the full binaries installed rather than symlink causing the following downstream issue: https://github.com/nodejs/node/issues/42791#issuecomment-1104099469

Job Log Output

Here's a snippet of an action that attempts to install corepack symlinks to a temporary directory:

/runner/externals/node16/bin/corepack enable --install-directory /runner/_work/_temp/7ed1e9df-f2bf-4ab2-8ba0-93e93ceddb93
  Internal Error: Cannot find module 'corepack/package.json'
  Require stack:
  - /runner/externals.2.296.1/node16/bin/corepack
  Require stack:
  - /runner/externals.2.296.1/node16/bin/corepack
      at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
      at Function.resolve (node:internal/modules/cjs/helpers:10[8](https://github.com/****/runs/8140449464?check_suite_focus=true#step:4:10):1[9](https://github.com/****/runs/8140449464?check_suite_focus=true#step:4:11))
      at EnableCommand.execute (/runner/externals.2.296.1/node16/bin/corepack:3332:46)
      at EnableCommand.validateAndExecute (/runner/externals.2.296.1/node16/bin/corepack:450:37)
      at Cli.run (/runner/externals.2.296.1/node16/bin/corepack:144:38)
      at main (/runner/externals.2.296.1/node16/bin/corepack:14823:26)
      at runMain (/runner/externals.2.296.1/node16/bin/corepack:14845:5)
      at /runner/externals.2.296.1/node16/bin/corepack:14857:5
      at /runner/externals.2.296.1/node16/bin/corepack:14859:3
      at Object.<anonymous> (/runner/externals.2.296.1/node16/bin/corepack:14864:[12](https://github.com/****/runs/8140449464?check_suite_focus=true#step:4:14))

Runner and Worker's Diagnostic Logs

NA

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/Runner.Sdk/Util/IOUtil.cs around lines 368-380, where the self-updater recursively copies files from the update tarball. Reproduce the update with a symlink in the externals tree and verify that the copied entry remains a symlink rather than becoming a regular file. Done means npm, npx, and corepack continue to work after self-updating.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.