Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
# Optional.
private-key: ${{ secrets.PRIVATE_KEY }}

# Passphrase for the private key, if it is encrypted.
# Optional.
private-key-passphrase: ${{ secrets.PRIVATE_KEY_PASSPHRASE }}

# Content of `~/.ssh/known_hosts` file. The public SSH keys for a
# host may be obtained using the utility `ssh-keyscan`.
# For example: `ssh-keyscan deployer.org`.
Expand Down
5 changes: 5 additions & 0 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ inputs:
default: ''
description: The private key for connecting to remote hosts.

private-key-passphrase:
required: false
default: ''
description: Passphrase for the private key.

known-hosts:
required: false
default: ''
Expand Down
32 changes: 31 additions & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36650,10 +36650,36 @@ async function ssh() {
let privateKey = getInput("private-key");
if (privateKey !== "") {
privateKey = privateKey.replace(/\r/g, "").trim() + "\n";
const privateKeyPassphrase = getInput("private-key-passphrase");
const askPassPath = privateKeyPassphrase !== "" ? `${sshHomeDir}/askpass.sh` : "";
if (askPassPath !== "") {
fs.writeFileSync(askPassPath, "#!/bin/sh\nprintf \"%s\\n\" \"$SSH_KEY_PASSPHRASE\"\n");
fs.chmodSync(askPassPath, "700");
}
const previousAskPass = process.env["SSH_ASKPASS"];
const previousAskPassRequire = process.env["SSH_ASKPASS_REQUIRE"];
const previousDisplay = process.env["DISPLAY"];
const previousKeyPassphrase = process.env["SSH_KEY_PASSPHRASE"];
if (askPassPath !== "") {
process.env["SSH_ASKPASS"] = askPassPath;
process.env["SSH_ASKPASS_REQUIRE"] = "force";
process.env["DISPLAY"] = process.env["DISPLAY"] || ":0";
process.env["SSH_KEY_PASSPHRASE"] = privateKeyPassphrase;
}
const p = $`ssh-add -`;
p.stdin.write(privateKey);
p.stdin.end();
await p;
try {
await p;
} finally {
if (askPassPath !== "") {
restoreEnv("SSH_ASKPASS", previousAskPass);
restoreEnv("SSH_ASKPASS_REQUIRE", previousAskPassRequire);
restoreEnv("DISPLAY", previousDisplay);
restoreEnv("SSH_KEY_PASSPHRASE", previousKeyPassphrase);
fs.rmSync(askPassPath, { force: true });
}
}
}
const knownHosts = getInput("known-hosts");
if (knownHosts !== "") {
Expand All @@ -36669,6 +36695,10 @@ async function ssh() {
fs.chmodSync(`${sshHomeDir}/config`, "600");
}
}
function restoreEnv(key, value) {
if (value === void 0) delete process.env[key];
else process.env[key] = value;
}
async function dep() {
let bin = getInput("deployer-binary");
const subDirectory = getInput("sub-directory").trim();
Expand Down
44 changes: 43 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,44 @@ async function ssh(): Promise<void> {
let privateKey = core.getInput('private-key')
if (privateKey !== '') {
privateKey = privateKey.replace(/\r/g, '').trim() + '\n'
const privateKeyPassphrase = core.getInput('private-key-passphrase')
const askPassPath =
privateKeyPassphrase !== '' ? `${sshHomeDir}/askpass.sh` : ''

if (askPassPath !== '') {
fs.writeFileSync(
askPassPath,
'#!/bin/sh\nprintf "%s\\n" "$SSH_KEY_PASSPHRASE"\n',
)
fs.chmodSync(askPassPath, '700')
}

const previousAskPass = process.env['SSH_ASKPASS']
const previousAskPassRequire = process.env['SSH_ASKPASS_REQUIRE']
const previousDisplay = process.env['DISPLAY']
const previousKeyPassphrase = process.env['SSH_KEY_PASSPHRASE']

if (askPassPath !== '') {
process.env['SSH_ASKPASS'] = askPassPath
process.env['SSH_ASKPASS_REQUIRE'] = 'force'
process.env['DISPLAY'] = process.env['DISPLAY'] || ':0'
process.env['SSH_KEY_PASSPHRASE'] = privateKeyPassphrase
}

const p = $`ssh-add -`
p.stdin.write(privateKey)
p.stdin.end()
await p
try {
await p
} finally {
if (askPassPath !== '') {
restoreEnv('SSH_ASKPASS', previousAskPass)
restoreEnv('SSH_ASKPASS_REQUIRE', previousAskPassRequire)
restoreEnv('DISPLAY', previousDisplay)
restoreEnv('SSH_KEY_PASSPHRASE', previousKeyPassphrase)
fs.rmSync(askPassPath, { force: true })
}
}
}

const knownHosts = core.getInput('known-hosts')
Expand All @@ -62,6 +96,14 @@ async function ssh(): Promise<void> {
}
}

function restoreEnv(key: string, value: string | undefined): void {
if (value === undefined) {
delete process.env[key]
} else {
process.env[key] = value
}
}

async function dep(): Promise<void> {
let bin = core.getInput('deployer-binary')
const subDirectory = core.getInput('sub-directory').trim()
Expand Down