setupPath() currently removes entries containing ruby by exporting a complete
replacement PATH/Path through GITHUB_ENV, then adds the selected Ruby paths
separately through GITHUB_PATH:
|
export function setupPath(newPathEntries) { |
|
const originalPath = process.env[PATH_ENV_VAR].split(path.delimiter) |
|
let cleanPath = originalPath.filter(entry => !/\bruby\b/i.test(entry)) |
|
|
|
core.group(`Modifying ${PATH_ENV_VAR}`, async () => { |
|
// First remove the conflicting path entries |
|
if (cleanPath.length !== originalPath.length) { |
|
console.log(`Entries removed from ${PATH_ENV_VAR} to avoid conflicts with default Ruby:`) |
|
for (const entry of originalPath) { |
|
if (!cleanPath.includes(entry)) { |
|
console.log(` ${entry}`) |
|
} |
|
} |
|
core.exportVariable(PATH_ENV_VAR, cleanPath.join(path.delimiter)) |
|
} |
|
|
|
console.log(`Entries added to ${PATH_ENV_VAR} to use selected Ruby:`) |
|
for (const entry of newPathEntries) { |
|
console.log(` ${entry}`) |
|
} |
|
}) |
|
|
|
core.addPath(newPathEntries.join(path.delimiter)) |
This appears to work at process-launch time, but it creates two independently
managed sources of PATH state in the Actions runner. In particular, downstream
action log headers show the replacement value from GITHUB_ENV without the Ruby
paths managed through GITHUB_PATH.
Example public job:
https://github.com/kjanat/actions-shells/actions/runs/33935875402/job/101223659801
On macOS, setup-ruby reports:
Entries removed from PATH to avoid conflicts with default Ruby:
/opt/homebrew/lib/ruby/gems/3.4.0/bin
/opt/homebrew/opt/ruby@3.4/bin
Entries added to PATH to use selected Ruby:
/Users/runner/hostedtoolcache/Ruby/3.4.10/arm64/bin
The immediately following action's logged environment contains the cleaned
PATH, but not the selected Ruby directory. Every later logged PATH has the
same shape. Nevertheless, the effective process environment is correct:
runtime: ruby
command: /Users/runner/hostedtoolcache/Ruby/3.4.10/arm64/bin/ruby
version: ruby 3.4.10 ...
Windows exhibits the same split representation: the logged Path omits the
new Ruby/MSYS2 entries while later processes resolve Ruby 3.4.10 correctly.
Linux does not export a replacement PATH in this job because there were no
Ruby-named entries to remove, so it does not exhibit the confusing split.
There is no runtime failure demonstrated here. The concern is that exporting a
snapshot of the complete shared PATH from a reusable setup action is fragile:
- it mixes a literal job environment value with the runner's separately tracked
prepend-path state;
- downstream action logs do not show the effective process PATH;
- removal from the exported snapshot does not obviously remove matching entries
already retained by the runner's prepend-path state;
- behavior depends on runner merge/order and Windows environment-key handling.
Could setup-ruby avoid exporting the complete PATH through GITHUB_ENV and
only prepend the selected Ruby through GITHUB_PATH? Since the selected Ruby is
prepended, it should win command lookup without removing unrelated PATH state.
If removal is required for a case that prepending does not handle, it would be
helpful to document why this split mutation is safe and add an integration test
covering the effective PATH across subsequent action and shell steps on macOS
and Windows.
setupPath()currently removes entries containingrubyby exporting a completereplacement
PATH/PaththroughGITHUB_ENV, then adds the selected Ruby pathsseparately through
GITHUB_PATH:setup-ruby/common.js
Lines 371 to 393 in 95ef2b0
This appears to work at process-launch time, but it creates two independently
managed sources of PATH state in the Actions runner. In particular, downstream
action log headers show the replacement value from
GITHUB_ENVwithout the Rubypaths managed through
GITHUB_PATH.Example public job:
https://github.com/kjanat/actions-shells/actions/runs/33935875402/job/101223659801
On macOS, setup-ruby reports:
The immediately following action's logged environment contains the cleaned
PATH, but not the selected Ruby directory. Every later loggedPATHhas thesame shape. Nevertheless, the effective process environment is correct:
Windows exhibits the same split representation: the logged
Pathomits thenew Ruby/MSYS2 entries while later processes resolve Ruby 3.4.10 correctly.
Linux does not export a replacement
PATHin this job because there were noRuby-named entries to remove, so it does not exhibit the confusing split.
There is no runtime failure demonstrated here. The concern is that exporting a
snapshot of the complete shared
PATHfrom a reusable setup action is fragile:prepend-path state;
already retained by the runner's prepend-path state;
Could setup-ruby avoid exporting the complete
PATHthroughGITHUB_ENVandonly prepend the selected Ruby through
GITHUB_PATH? Since the selected Ruby isprepended, it should win command lookup without removing unrelated PATH state.
If removal is required for a case that prepending does not handle, it would be
helpful to document why this split mutation is safe and add an integration test
covering the effective PATH across subsequent action and shell steps on macOS
and Windows.