Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Mar 10, 2021
Merged
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
82 changes: 34 additions & 48 deletions .github/workflows/demo.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,46 @@
on: [push, pull_request]
on: [ push, pull_request ]

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:
deployment_keys_demo:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest]
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 }}
- uses: actions/checkout@v2
- 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

docker_demo:
runs-on: ubuntu-latest
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 }}
- 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

deployment_keys_demo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- 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
10 changes: 6 additions & 4 deletions cleanup.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
const core = require('@actions/core')
const { execSync } = require('child_process')
const core = require('@actions/core');
const { execSync } = require('child_process');
const { sshAgent } = require('./paths.js');

try {
// Kill the started SSH agent
console.log('Stopping SSH agent')
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
console.log('Stopping SSH agent');
execSync(sshAgent, ['-k'], { stdio: 'inherit' });

} catch (error) {
console.log(error.message);
console.log('Error stopping the SSH agent, proceeding anyway');
Expand Down
35 changes: 31 additions & 4 deletions dist/cleanup.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,15 @@ module.exports = require("child_process");
/***/ 175:
/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) {

const core = __webpack_require__(470)
const { execSync } = __webpack_require__(129)
const core = __webpack_require__(470);
const { execSync } = __webpack_require__(129);
const { sshAgent } = __webpack_require__(972);

try {
// Kill the started SSH agent
console.log('Stopping SSH agent')
execSync('kill ${SSH_AGENT_PID}', { stdio: 'inherit' })
console.log('Stopping SSH agent');
execSync(sshAgent, ['-k'], { stdio: 'inherit' });

} catch (error) {
console.log(error.message);
console.log('Error stopping the SSH agent, proceeding anyway');
Expand Down Expand Up @@ -480,6 +482,31 @@ module.exports = require("path");

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'

};



/***/ })

/******/ });
96 changes: 55 additions & 41 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ exports.issueCommand = issueCommand;
const core = __webpack_require__(470);
const child_process = __webpack_require__(129);
const fs = __webpack_require__(747);
const os = __webpack_require__(87);
const crypto = __webpack_require__(417);
const { home, sshAgent, sshAdd } = __webpack_require__(972);

try {
const privateKey = core.getInput('ssh-private-key');
Expand All @@ -130,77 +130,66 @@ try {
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';

console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);

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-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");

const authSock = core.getInput('ssh-auth-sock');
let sshAgentOutput = ''
if (authSock && authSock.length > 0) {
sshAgentOutput = child_process.execFileSync('ssh-agent', ['-a', authSock]);
} else {
sshAgentOutput = child_process.execFileSync('ssh-agent')
}
const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];

// Extract auth socket path and agent pid and set them as job variables
const lines = sshAgentOutput.toString().split("\n")
for (const lineNumber in lines) {
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(lines[lineNumber])
child_process.execFileSync(sshAgent, sshAgentArgs).toString().split("\n").forEach(function(line) {
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);

if (matches && matches.length > 0) {
// This will also set process.env accordingly, so changes take effect for this script
core.exportVariable(matches[1], matches[2])
console.log(`${matches[1]}=${matches[2]}`);
}
}
});

console.log("Adding private key(s) to agent");

console.log("Adding private key to agent");
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
child_process.execFileSync(sshAdd, ['-'], { input: key.trim() + "\n" });
});

console.log("Keys added:");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
console.log("Key(s) added:");

child_process.execFileSync(sshAdd, ['-l'], { stdio: 'inherit' });

console.log('Configuring deployment key(s)');

child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
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 == null) {
if (!parts) {
return;
}

let ownerAndRepo = parts[1];
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
const 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 --add url."git@${sha256}:${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 --replace-all url."git@key-${sha256}.github.com:${ownerAndRepo}".insteadOf "https://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@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`
+ ` User git\n`
+ ` IdentityFile ${homeSsh}/${sha256}\n`
+ ` IdentityFile ${homeSsh}/key-${sha256}\n`
+ ` IdentitiesOnly yes\n`;

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) {
Expand Down Expand Up @@ -567,6 +556,31 @@ module.exports = require("path");

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'

};



/***/ })

/******/ });
Loading