Skip to content

Runner self-updates don't preserve symlinks in externals #2094

Open
@kherock

Description

@kherock

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:

foreach (FileInfo sourceFile in sourceDir.GetFiles() ?? new FileInfo[0])
{
// Check if the file already exists.
cancellationToken.ThrowIfCancellationRequested();
FileInfo targetFile = new FileInfo(Path.Combine(target, sourceFile.Name));
if (!targetFile.Exists ||
sourceFile.Length != targetFile.Length ||
sourceFile.LastWriteTime != targetFile.LastWriteTime)
{
// Copy the file.
sourceFile.CopyTo(targetFile.FullName, true);
}
}

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: nodejs/node#42791 (comment)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Runner BugBug fix scope to the runnerbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions