Runner self-updates don't preserve symlinks in externals
Nobody has claimed this yet.
- 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:
- Host a self-hosted runner on a version older than 2.296.1
- Run an action that adds your runner's
externals/node16/bindirectory to the PATH - Run a step that executes
corepack enableornpm - See error
Expected behavior
The loop here should handle when the file being copied is a symlink:
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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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