2019-09-14 18:28:16 -04:00
const core = require ( '@actions/core' ) ;
const child _process = require ( 'child_process' ) ;
const fs = require ( 'fs' ) ;
2021-02-13 15:02:34 -05:00
const os = require ( 'os' ) ;
2021-02-27 15:47:41 -05:00
const token = require ( 'crypto' ) . randomBytes ( 64 ) . toString ( 'hex' ) ;
2019-09-14 18:28:16 -04:00
try {
2020-02-06 13:09:44 -05:00
const privateKey = core . getInput ( 'ssh-private-key' ) ;
2020-01-14 04:29:16 -05:00
if ( ! privateKey ) {
core . setFailed ( "The ssh-private-key argument is empty. Maybe the secret has not been configured, or you are using a wrong secret name in your workflow file." ) ;
return ;
}
2021-02-13 15:02:34 -05:00
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' ;
2019-09-15 03:32:43 -04:00
console . log ( ` Adding GitHub.com keys to ${ homeSsh } /known_hosts ` ) ;
2020-03-02 19:41:12 -05:00
fs . mkdirSync ( homeSsh , { recursive : true } ) ;
2019-09-15 03:32:43 -04:00
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' ) ;
2019-09-14 18:28:16 -04:00
console . log ( "Starting ssh-agent" ) ;
const authSock = core . getInput ( 'ssh-auth-sock' ) ;
2020-05-18 03:08:29 -04:00
let sshAgentOutput = ''
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
const lines = sshAgentOutput . toString ( ) . split ( "\n" )
for ( const lineNumber in lines ) {
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/ . exec ( lines [ lineNumber ] )
if ( matches && matches . length > 0 ) {
core . exportVariable ( matches [ 1 ] , matches [ 2 ] )
}
}
2019-09-14 18:28:16 -04:00
2021-02-27 15:47:41 -05:00
console . log ( "Adding private keys to agent" ) ;
var keyNumber = 0 ;
2020-01-14 04:29:16 -05:00
2021-02-27 15:47:41 -05:00
privateKey . split ( /(?=-----BEGIN)/ ) . forEach ( function ( key ) {
++ keyNumber ;
let keyFile = ` ${ homeSsh } /key_ ${ keyNumber } ` ;
// Write private key (unencrypted!) to file
console . log ( ` Write file ${ keyFile } ` ) ;
fs . writeFileSync ( keyFile , key . replace ( "\r\n" , "\n" ) . trim ( ) + "\n" , { mode : '600' } ) ;
2021-02-28 10:52:09 -05:00
fs . writeFileSync ( ` ${ homeSsh } /askpass ` , ` echo ${ token } ` , { mode : '700' } ) ;
2021-02-27 15:47:41 -05:00
// Set private key passphrase
let output = '' ;
try {
console . log ( ` Set passphrase on ${ keyFile } ` ) ;
output = child _process . execFileSync ( 'ssh-keygen' , [ '-p' , '-f' , keyFile , '-N' , token ] , { stdio : 'inherit' } ) ;
} catch ( exception ) {
fs . unlinkSync ( keyFile ) ;
throw exception ;
}
2020-01-14 04:29:16 -05:00
2021-02-27 15:47:41 -05:00
// Load key into agent
console . log ( 'Load key' ) ;
//let sshAdd = child_process.execSync(`echo "${token}" | ssh-add "${keyFile}"`, { stdio: 'inherit' });
2021-02-28 10:58:23 -05:00
try {
2021-02-28 10:55:23 -05:00
let sshAdd = child _process . execSync ( ` ssh-add ${ keyFile } ` , { stdio : 'inherit' , env : { 'SSH_ASKPASS' : ` ${ homeSsh } /askpass ` } } ) ;
2021-02-28 10:58:23 -05:00
} catch ( exception ) {
console . log ( sshAdd ) ;
console . log ( exception ) ;
throw exception ;
}
console . log ( sshAdd ) ;
2021-02-27 15:47:41 -05:00
// input: token + "\n", stdio: ['pipe', 'inherit', 'inherit'] });
//sshAdd.stdin.write(token + "\n");
//sshAdd.stdin.end();
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
output . toString ( ) . split ( /\r?\n/ ) . forEach ( function ( key ) {
let parts = key . match ( /^Key has comment '.*\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+?)(?=\.git|\s|\')/ ) ;
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
if ( parts == null ) {
return ;
}
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
let ownerAndRepo = parts [ 1 ] ;
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
child _process . execSync ( ` git config --global --replace-all url."git@key- ${ keyNumber } : ${ ownerAndRepo } ".insteadOf "https://github.com/ ${ ownerAndRepo } " ` ) ;
child _process . execSync ( ` git config --global --add url."git@key- ${ keyNumber } : ${ ownerAndRepo } ".insteadOf "git@github.com: ${ ownerAndRepo } " ` ) ;
child _process . execSync ( ` git config --global --add url."git@key- ${ keyNumber } : ${ ownerAndRepo } ".insteadOf "ssh://git@github.com/ ${ ownerAndRepo } " ` ) ;
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
// Use IdentitiesOnly=no due to https://github.com/PowerShell/Win32-OpenSSH/issues/1550
let sshConfig = ` \n Host key- ${ keyNumber } \n `
+ ` HostName github.com \n `
+ ` User git \n `
+ ` IdentitiesOnly yes \n `
+ ` IdentityFile ${ keyFile } \n ` ;
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
fs . appendFileSync ( ` ${ homeSsh } /config ` , sshConfig ) ;
2021-02-19 08:37:34 -05:00
2021-02-27 15:47:41 -05:00
console . log ( ` Added deploy-key mapping: Use key # ${ keyNumber } for GitHub repository ${ ownerAndRepo } ` ) ;
} ) ;
2021-02-19 08:37:34 -05:00
} ) ;
2021-02-27 15:47:41 -05:00
console . log ( "Keys added:" ) ;
child _process . execSync ( 'ssh-add -l' , { stdio : 'inherit' } ) ;
2019-09-14 18:28:16 -04:00
} catch ( error ) {
core . setFailed ( error . message ) ;
}