From 730a0961864e89ee23806d836e5b984758d3b4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Tue, 12 May 2026 10:35:05 +0200 Subject: [PATCH] add home-path input for GH runners using DynamicUser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a GitHub runner is running in Systemd serivce context that is using DynamicUser=true setting the os.userInfo().homedir call returns /(root). This happens because the Node call uses libuv which calls getpwuid() that uses the NSS(Name Service Switch) which provide home path from /etc/passwd. Because of this the action fails with error like this: Error: ENOENT: no such file or directory, mkdir '//.ssh' Allowing users to override it is the simplest fix, for example like this: home-path: $HOME Signed-off-by: Jakub SokoĊ‚owski --- README.md | 1 + action.yml | 3 +++ dist/cleanup.js | 12 +++++++----- dist/index.js | 12 +++++++----- paths.js | 7 ++++--- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3028201..6c9e23f 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ The following inputs can be used to control the action's behavior: * `ssh-agent-cmd`: Optional. Use this to specify a custom location for the `ssh-agent` binary. * `ssh-add-cmd`: Optional. Use this to specify a custom location for the `ssh-add` binary. * `git-cmd`: Optional. Use this to specify a custom location for the `git` binary. +* `home-path`: Optional. Use this to override user home directory. ## Exported variables diff --git a/action.yml b/action.yml index fa8f454..3ac59d3 100644 --- a/action.yml +++ b/action.yml @@ -19,6 +19,9 @@ inputs: git-cmd: description: 'git command' required: false + home-path: + description: 'User home directory override' + required: false runs: using: 'node24' main: 'dist/index.js' diff --git a/dist/cleanup.js b/dist/cleanup.js index 7e478b7..f60886c 100644 --- a/dist/cleanup.js +++ b/dist/cleanup.js @@ -2824,15 +2824,16 @@ const os = __webpack_require__(87); const core = __webpack_require__(470); const defaults = (process.env['OS'] != 'Windows_NT') ? { - // Use getent() system call, since this is what ssh does; makes a difference in Docker-based - // Action runs, where $HOME is different from the pwent - homePath: os.userInfo().homedir, + // We use os.userInfo() rather than os.homedir(), since it uses the getpwuid() system call to get the user's home directory (see https://nodejs.org/api/os.html#osuserinfooptions). + // This mimics the way openssh derives the home directory for locating config files (see https://github.com/openssh/openssh-portable/blob/826483d51a9fee60703298bbf839d9ce37943474/ssh.c#L710); + // Makes a difference in Docker-based Action runs, when $HOME is different from what getpwuid() returns (which is based on the entry in /etc/passwd) + homePathDefault: os.userInfo().homedir, sshAgentCmdDefault: 'ssh-agent', sshAddCmdDefault: 'ssh-add', gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now - homePath: os.homedir(), + homePathDefault: os.homedir(), sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', gitCmdDefault: 'c://progra~1//git//bin//git.exe' @@ -2841,9 +2842,10 @@ const defaults = (process.env['OS'] != 'Windows_NT') ? { const sshAgentCmdInput = core.getInput('ssh-agent-cmd'); const sshAddCmdInput = core.getInput('ssh-add-cmd'); const gitCmdInput = core.getInput('git-cmd'); +const homePathInput = core.getInput('home-path'); module.exports = { - homePath: defaults.homePath, + homePath: homePathInput !== '' ? homePathInput : defaults.homePathDefault, sshAgentCmd: sshAgentCmdInput !== '' ? sshAgentCmdInput : defaults.sshAgentCmdDefault, sshAddCmd: sshAddCmdInput !== '' ? sshAddCmdInput : defaults.sshAddCmdDefault, gitCmd: gitCmdInput !== '' ? gitCmdInput : defaults.gitCmdDefault, diff --git a/dist/index.js b/dist/index.js index 3f288c7..582d3d9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2898,15 +2898,16 @@ const os = __webpack_require__(87); const core = __webpack_require__(470); const defaults = (process.env['OS'] != 'Windows_NT') ? { - // Use getent() system call, since this is what ssh does; makes a difference in Docker-based - // Action runs, where $HOME is different from the pwent - homePath: os.userInfo().homedir, + // We use os.userInfo() rather than os.homedir(), since it uses the getpwuid() system call to get the user's home directory (see https://nodejs.org/api/os.html#osuserinfooptions). + // This mimics the way openssh derives the home directory for locating config files (see https://github.com/openssh/openssh-portable/blob/826483d51a9fee60703298bbf839d9ce37943474/ssh.c#L710); + // Makes a difference in Docker-based Action runs, when $HOME is different from what getpwuid() returns (which is based on the entry in /etc/passwd) + homePathDefault: os.userInfo().homedir, sshAgentCmdDefault: 'ssh-agent', sshAddCmdDefault: 'ssh-add', gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now - homePath: os.homedir(), + homePathDefault: os.homedir(), sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', gitCmdDefault: 'c://progra~1//git//bin//git.exe' @@ -2915,9 +2916,10 @@ const defaults = (process.env['OS'] != 'Windows_NT') ? { const sshAgentCmdInput = core.getInput('ssh-agent-cmd'); const sshAddCmdInput = core.getInput('ssh-add-cmd'); const gitCmdInput = core.getInput('git-cmd'); +const homePathInput = core.getInput('home-path'); module.exports = { - homePath: defaults.homePath, + homePath: homePathInput !== '' ? homePathInput : defaults.homePathDefault, sshAgentCmd: sshAgentCmdInput !== '' ? sshAgentCmdInput : defaults.sshAgentCmdDefault, sshAddCmd: sshAddCmdInput !== '' ? sshAddCmdInput : defaults.sshAddCmdDefault, gitCmd: gitCmdInput !== '' ? gitCmdInput : defaults.gitCmdDefault, diff --git a/paths.js b/paths.js index f440579..28dabf8 100644 --- a/paths.js +++ b/paths.js @@ -5,13 +5,13 @@ const defaults = (process.env['OS'] != 'Windows_NT') ? { // We use os.userInfo() rather than os.homedir(), since it uses the getpwuid() system call to get the user's home directory (see https://nodejs.org/api/os.html#osuserinfooptions). // This mimics the way openssh derives the home directory for locating config files (see https://github.com/openssh/openssh-portable/blob/826483d51a9fee60703298bbf839d9ce37943474/ssh.c#L710); // Makes a difference in Docker-based Action runs, when $HOME is different from what getpwuid() returns (which is based on the entry in /etc/passwd) - homePath: os.userInfo().homedir, + homePathDefault: os.userInfo().homedir, sshAgentCmdDefault: 'ssh-agent', sshAddCmdDefault: 'ssh-add', gitCmdDefault: 'git' } : { // Assuming GitHub hosted `windows-*` runners for now - homePath: os.homedir(), + homePathDefault: os.homedir(), sshAgentCmdDefault: 'c://progra~1//git//usr//bin//ssh-agent.exe', sshAddCmdDefault: 'c://progra~1//git//usr//bin//ssh-add.exe', gitCmdDefault: 'c://progra~1//git//bin//git.exe' @@ -20,9 +20,10 @@ const defaults = (process.env['OS'] != 'Windows_NT') ? { const sshAgentCmdInput = core.getInput('ssh-agent-cmd'); const sshAddCmdInput = core.getInput('ssh-add-cmd'); const gitCmdInput = core.getInput('git-cmd'); +const homePathInput = core.getInput('home-path'); module.exports = { - homePath: defaults.homePath, + homePath: homePathInput !== '' ? homePathInput : defaults.homePathDefault, sshAgentCmd: sshAgentCmdInput !== '' ? sshAgentCmdInput : defaults.sshAgentCmdDefault, sshAddCmd: sshAddCmdInput !== '' ? sshAddCmdInput : defaults.sshAddCmdDefault, gitCmd: gitCmdInput !== '' ? gitCmdInput : defaults.gitCmdDefault,