Windows virtual environment: Use SSH binaries from the Git suite (#63)

* Use SSH binaries from the Git suite

* Try to kill the ssh-agent upon action termination on Windows as well
This commit is contained in:
Matthias Pigulla 2021-03-10 08:19:17 +01:00 committed by GitHub
parent 795485730f
commit 4b6f4eb000
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 182 additions and 146 deletions

View file

@ -1,48 +1,12 @@
on: [push, pull_request] on: [ push, pull_request ]
jobs: jobs:
single_key_demo:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Setup key
uses: ./
with:
ssh-private-key: |
${{ secrets.DEMO_KEY }}
${{ secrets.DEMO_KEY_2 }}
multiple_keys_demo:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Setup key
uses: ./
with:
ssh-private-key: ${{ secrets.DEMO_KEY }}
docker_demo:
runs-on: ubuntu-latest
container:
image: ubuntu:latest
steps:
- uses: actions/checkout@v2
- run: apt update && apt install -y openssh-client
- name: Setup key
uses: ./
with:
ssh-private-key: |
${{ secrets.DEMO_KEY }}
${{ secrets.DEMO_KEY_2 }}
deployment_keys_demo: deployment_keys_demo:
runs-on: ubuntu-latest strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macOS-latest, windows-latest ]
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup key - name: Setup key
@ -58,3 +22,25 @@ jobs:
git clone https://github.com/mpdude/test-2.git test-2-http git clone https://github.com/mpdude/test-2.git test-2-http
git clone git@github.com:mpdude/test-2.git test-2-git git clone git@github.com:mpdude/test-2.git test-2-git
git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh
docker_demo:
runs-on: ubuntu-latest
container:
image: ubuntu:latest
steps:
- uses: actions/checkout@v2
- run: apt update && apt install -y openssh-client git
- name: Setup key
uses: ./
with:
ssh-private-key: |
${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
- run: |
git clone https://github.com/mpdude/test-1.git test-1-http
git clone git@github.com:mpdude/test-1.git test-1-git
git clone ssh://git@github.com/mpdude/test-1.git test-1-git-ssh
git clone https://github.com/mpdude/test-2.git test-2-http
git clone git@github.com:mpdude/test-2.git test-2-git
git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh

View file

@ -1,10 +1,12 @@
const core = require('@actions/core') const core = require('@actions/core');
const { execSync } = require('child_process') const { execSync } = require('child_process');
const { sshAgent } = require('./paths.js');
try { try {
// Kill the started SSH agent // Kill the started SSH agent
console.log('Stopping SSH agent') console.log('Stopping SSH agent');
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' }) execSync(sshAgent, ['-k'], { stdio: 'inherit' });
} catch (error) { } catch (error) {
console.log(error.message); console.log(error.message);
console.log('Error stopping the SSH agent, proceeding anyway'); console.log('Error stopping the SSH agent, proceeding anyway');

35
dist/cleanup.js vendored
View file

@ -122,13 +122,15 @@ module.exports = require("child_process");
/***/ 175: /***/ 175:
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) { /***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {
const core = __webpack_require__(470) const core = __webpack_require__(470);
const { execSync } = __webpack_require__(129) const { execSync } = __webpack_require__(129);
const { sshAgent } = __webpack_require__(972);
try { try {
// Kill the started SSH agent // Kill the started SSH agent
console.log('Stopping SSH agent') console.log('Stopping SSH agent');
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' }) execSync(sshAgent, ['-k'], { stdio: 'inherit' });
} catch (error) { } catch (error) {
console.log(error.message); console.log(error.message);
console.log('Error stopping the SSH agent, proceeding anyway'); console.log('Error stopping the SSH agent, proceeding anyway');
@ -480,6 +482,31 @@ module.exports = require("path");
module.exports = require("fs"); module.exports = require("fs");
/***/ }),
/***/ 972:
/***/ (function(module, __unusedexports, __webpack_require__) {
const os = __webpack_require__(87);
module.exports = (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
home: os.userInfo().homedir,
sshAgent: 'ssh-agent',
sshAdd: 'ssh-add'
} : {
home: os.homedir(),
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
};
/***/ }) /***/ })
/******/ }); /******/ });

104
dist/index.js vendored
View file

@ -118,8 +118,8 @@ exports.issueCommand = issueCommand;
const core = __webpack_require__(470); const core = __webpack_require__(470);
const child_process = __webpack_require__(129); const child_process = __webpack_require__(129);
const fs = __webpack_require__(747); const fs = __webpack_require__(747);
const os = __webpack_require__(87);
const crypto = __webpack_require__(417); const crypto = __webpack_require__(417);
const { home, sshAgent, sshAdd } = __webpack_require__(972);
try { try {
const privateKey = core.getInput('ssh-private-key'); const privateKey = core.getInput('ssh-private-key');
@ -130,77 +130,66 @@ try {
return; return;
} }
var home;
if (process.env['OS'] == 'Windows_NT') {
console.log('Preparing ssh-agent service on Windows');
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
home = os.homedir();
} else {
// 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
var { homedir: home } = os.userInfo();
}
const homeSsh = home + '/.ssh'; const homeSsh = home + '/.ssh';
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`); console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
fs.mkdirSync(homeSsh, { recursive: true }); fs.mkdirSync(homeSsh, { recursive: true });
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n'); fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n'); fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
console.log("Starting ssh-agent"); console.log("Starting ssh-agent");
const authSock = core.getInput('ssh-auth-sock'); const authSock = core.getInput('ssh-auth-sock');
let sshAgentOutput = '' const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
if (authSock && authSock.length > 0) {
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
} else {
sshAgentOutput = child_process.execFileSync('ssh-agent')
}
// Extract auth socket path and agent pid and set them as job variables // Extract auth socket path and agent pid and set them as job variables
const lines = sshAgentOutput.toString().split("\n") child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
for (const lineNumber in lines) { const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(lines[lineNumber])
if (matches && matches.length > 0) {
core.exportVariable(matches[1], matches[2])
}
}
console.log("Adding private key to agent"); if (matches && matches.length > 0) {
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) { // This will also set process.env accordingly, so changes take effect for this script
child_process.execSync('ssh-add -', { input: key.trim() + "\n" }); core.exportVariable(matches[1], matches[2])
console.log(`${matches[1]}=${matches[2]}`);
}
}); });
console.log("Keys added:"); console.log("Adding private key(s) to agent");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) { privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/); child_process.execFileSync(sshAdd, ['-'], { input: key.trim() + "\n" });
});
if (parts == null) { console.log("Key(s) added:");
child_process.execFileSync(sshAdd, ['-l'], { stdio: 'inherit' });
console.log('Configuring deployment key(s)');
child_process.execFileSync(sshAdd, ['-L']).toString().split(/\r?\n/).forEach(function(key) {
const parts = key.match(/\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/);
if (!parts) {
return; return;
} }
let ownerAndRepo = parts[1]; const sha256 = crypto.createHash('sha256').update(key).digest('hex');
let sha256 = crypto.createHash('sha256').update(key).digest('hex'); const ownerAndRepo = parts[1].replace(/\.git$/, '');
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' }); fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`); child_process.execSync(`git config --global --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`); child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`); child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
let sshConfig = `\nHost ${sha256}\n` const sshConfig = `\nHost key-${sha256}.github.com\n`
+ ` HostName github.com\n` + ` HostName github.com\n`
+ ` User git\n` + ` IdentityFile ${homeSsh}/key-${sha256}\n`
+ ` IdentityFile ${homeSsh}/${sha256}\n`
+ ` IdentitiesOnly yes\n`; + ` IdentitiesOnly yes\n`;
fs.appendFileSync(`${homeSsh}/config`, sshConfig); fs.appendFileSync(`${homeSsh}/config`, sshConfig);
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}`); console.log(`Added deploy-key mapping: Use identity '${homeSsh}/key-${sha256}' for GitHub repository ${ownerAndRepo}`);
}); });
} catch (error) { } catch (error) {
@ -573,6 +562,31 @@ module.exports = require("path");
module.exports = require("fs"); module.exports = require("fs");
/***/ }),
/***/ 972:
/***/ (function(module, __unusedexports, __webpack_require__) {
const os = __webpack_require__(87);
module.exports = (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
home: os.userInfo().homedir,
sshAgent: 'ssh-agent',
sshAdd: 'ssh-add'
} : {
home: os.homedir(),
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
};
/***/ }) /***/ })
/******/ }); /******/ });

View file

@ -1,8 +1,8 @@
const core = require('@actions/core'); const core = require('@actions/core');
const child_process = require('child_process'); const child_process = require('child_process');
const fs = require('fs'); const fs = require('fs');
const os = require('os');
const crypto = require('crypto'); const crypto = require('crypto');
const { home, sshAgent, sshAdd } = require('./paths.js');
try { try {
const privateKey = core.getInput('ssh-private-key'); const privateKey = core.getInput('ssh-private-key');
@ -13,77 +13,66 @@ try {
return; return;
} }
var home;
if (process.env['OS'] == 'Windows_NT') {
console.log('Preparing ssh-agent service on Windows');
child_process.execSync('sc config ssh-agent start=demand', { stdio: 'inherit' });
home = os.homedir();
} else {
// 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
var { homedir: home } = os.userInfo();
}
const homeSsh = home + '/.ssh'; const homeSsh = home + '/.ssh';
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`); console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
fs.mkdirSync(homeSsh, { recursive: true }); fs.mkdirSync(homeSsh, { recursive: true });
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n'); fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n'); fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-dss AAAAB3NzaC1kc3MAAACBANGFW2P9xlGU3zWrymJgI/lKo//ZW2WfVtmbsUZJ5uyKArtlQOT2+WRhcg4979aFxgKdcsqAYW3/LS1T2km3jYW/vr4Uzn+dXWODVk5VlUiZ1HFOHf6s6ITcZvjvdbp6ZbpM+DuJT7Bw+h5Fx8Qt8I16oCZYmAPJRtu46o9C2zk1AAAAFQC4gdFGcSbp5Gr0Wd5Ay/jtcldMewAAAIATTgn4sY4Nem/FQE+XJlyUQptPWMem5fwOcWtSXiTKaaN0lkk2p2snz+EJvAGXGq9dTSWHyLJSM2W6ZdQDqWJ1k+cL8CARAqL+UMwF84CR0m3hj+wtVGD/J4G5kW2DBAf4/bqzP4469lT+dF2FRQ2L9JKXrCWcnhMtJUvua8dvnwAAAIB6C4nQfAA7x8oLta6tT+oCk2WQcydNsyugE8vLrHlogoWEicla6cWPk7oXSspbzUcfkjN3Qa6e74PhRkc7JdSdAlFzU3m7LMkXo1MHgkqNX8glxWNVqBSc0YRdbFdTkL0C6gtpklilhvuHQCdbgB3LBAikcRkDp+FCVkUgPC/7Rw==\n');
console.log("Starting ssh-agent"); console.log("Starting ssh-agent");
const authSock = core.getInput('ssh-auth-sock'); const authSock = core.getInput('ssh-auth-sock');
let sshAgentOutput = '' const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
if (authSock && authSock.length > 0) {
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
} else {
sshAgentOutput = child_process.execFileSync('ssh-agent')
}
// Extract auth socket path and agent pid and set them as job variables // Extract auth socket path and agent pid and set them as job variables
const lines = sshAgentOutput.toString().split("\n") child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
for (const lineNumber in lines) { const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(lines[lineNumber])
if (matches && matches.length > 0) {
core.exportVariable(matches[1], matches[2])
}
}
console.log("Adding private key to agent"); if (matches && matches.length > 0) {
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) { // This will also set process.env accordingly, so changes take effect for this script
child_process.execSync('ssh-add -', { input: key.trim() + "\n" }); core.exportVariable(matches[1], matches[2])
console.log(`${matches[1]}=${matches[2]}`);
}
}); });
console.log("Keys added:"); console.log("Adding private key(s) to agent");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) { privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/); child_process.execFileSync(sshAdd, ['-'], { input: key.trim() + "\n" });
});
if (parts == null) { console.log("Key(s) added:");
child_process.execFileSync(sshAdd, ['-l'], { stdio: 'inherit' });
console.log('Configuring deployment key(s)');
child_process.execFileSync(sshAdd, ['-L']).toString().split(/\r?\n/).forEach(function(key) {
const parts = key.match(/\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/);
if (!parts) {
return; return;
} }
let ownerAndRepo = parts[1]; const sha256 = crypto.createHash('sha256').update(key).digest('hex');
let sha256 = crypto.createHash('sha256').update(key).digest('hex'); const ownerAndRepo = parts[1].replace(/\.git$/, '');
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' }); fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`); child_process.execSync(`git config --global --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`); child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`); child_process.execSync(`git config --global --add url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
let sshConfig = `\nHost ${sha256}\n` const sshConfig = `\nHost key-${sha256}.github.com\n`
+ ` HostName github.com\n` + ` HostName github.com\n`
+ ` User git\n` + ` IdentityFile ${homeSsh}/key-${sha256}\n`
+ ` IdentityFile ${homeSsh}/${sha256}\n`
+ ` IdentitiesOnly yes\n`; + ` IdentitiesOnly yes\n`;
fs.appendFileSync(`${homeSsh}/config`, sshConfig); fs.appendFileSync(`${homeSsh}/config`, sshConfig);
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}`); console.log(`Added deploy-key mapping: Use identity '${homeSsh}/key-${sha256}' for GitHub repository ${ownerAndRepo}`);
}); });
} catch (error) { } catch (error) {

18
paths.js Normal file
View file

@ -0,0 +1,18 @@
const os = require('os');
module.exports = (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
home: os.userInfo().homedir,
sshAgent: 'ssh-agent',
sshAdd: 'ssh-add'
} : {
home: os.homedir(),
sshAgent: 'c://progra~1//git//usr//bin//ssh-agent.exe',
sshAdd: 'c://progra~1//git//usr//bin//ssh-add.exe'
};