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-19 08:37:34 -05:00
const crypto = require ( 'crypto' ) ;
2021-03-10 02:19:17 -05:00
const { home , sshAgent , sshAdd } = require ( './paths.js' ) ;
2019-09-14 18:28:16 -04:00
try {
2020-02-06 13:09:44 -05:00
const privateKey = core . getInput ( 'ssh-private-key' ) ;
2022-09-02 02:30:25 -04:00
const dontLogPublicKey = core . getBooleanInput ( 'dont-log-public-key' , { default : false } ) ;
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
const homeSsh = home + '/.ssh' ;
2019-09-15 03:32:43 -04:00
console . log ( ` Adding GitHub.com keys to ${ homeSsh } /known_hosts ` ) ;
2021-03-10 02:19:17 -05:00
2020-03-02 19:41:12 -05:00
fs . mkdirSync ( homeSsh , { recursive : true } ) ;
2021-11-20 06:21:38 -05:00
fs . appendFileSync ( ` ${ homeSsh } /known_hosts ` , '\ngithub.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\n' ) ;
fs . appendFileSync ( ` ${ homeSsh } /known_hosts ` , '\ngithub.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\n' ) ;
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' ) ;
2019-09-14 18:28:16 -04:00
console . log ( "Starting ssh-agent" ) ;
2021-03-10 02:19:17 -05:00
2019-09-14 18:28:16 -04:00
const authSock = core . getInput ( 'ssh-auth-sock' ) ;
2021-03-10 02:19:17 -05:00
const sshAgentArgs = ( authSock && authSock . length > 0 ) ? [ '-a' , authSock ] : [ ] ;
2020-05-18 03:08:29 -04:00
// Extract auth socket path and agent pid and set them as job variables
2021-03-10 02:19:17 -05:00
child _process . execFileSync ( sshAgent , sshAgentArgs ) . toString ( ) . split ( "\n" ) . forEach ( function ( line ) {
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/ . exec ( line ) ;
2020-05-18 03:08:29 -04:00
if ( matches && matches . length > 0 ) {
2021-03-10 02:19:17 -05:00
// This will also set process.env accordingly, so changes take effect for this script
2020-05-18 03:08:29 -04:00
core . exportVariable ( matches [ 1 ] , matches [ 2 ] )
2021-03-10 02:19:17 -05:00
console . log ( ` ${ matches [ 1 ] } = ${ matches [ 2 ] } ` ) ;
2020-05-18 03:08:29 -04:00
}
2021-03-10 02:19:17 -05:00
} ) ;
console . log ( "Adding private key(s) to agent" ) ;
2019-09-14 18:28:16 -04:00
2020-01-14 04:29:16 -05:00
privateKey . split ( /(?=-----BEGIN)/ ) . forEach ( function ( key ) {
2021-03-10 02:19:17 -05:00
child _process . execFileSync ( sshAdd , [ '-' ] , { input : key . trim ( ) + "\n" } ) ;
2020-01-14 04:21:11 -05:00
} ) ;
2020-01-14 04:29:16 -05:00
2021-03-10 02:19:17 -05:00
console . log ( "Key(s) added:" ) ;
child _process . execFileSync ( sshAdd , [ '-l' ] , { stdio : 'inherit' } ) ;
console . log ( 'Configuring deployment key(s)' ) ;
2020-01-14 04:29:16 -05:00
2021-03-10 02:19:17 -05:00
child _process . execFileSync ( sshAdd , [ '-L' ] ) . toString ( ) . split ( /\r?\n/ ) . forEach ( function ( key ) {
2021-03-17 14:27:52 -04:00
const parts = key . match ( /\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/i ) ;
2021-02-19 08:37:34 -05:00
2021-03-10 02:19:17 -05:00
if ( ! parts ) {
2022-09-02 02:30:25 -04:00
if ( ! dontLogPublicKey ) {
2022-07-21 12:27:50 -04:00
console . log ( ` Comment for (public) key ' ${ key } ' does not match GitHub URL pattern. Not treating it as a GitHub deploy key. ` ) ;
}
2021-02-19 08:37:34 -05:00
return ;
}
2021-03-10 02:19:17 -05:00
const sha256 = crypto . createHash ( 'sha256' ) . update ( key ) . digest ( 'hex' ) ;
const ownerAndRepo = parts [ 1 ] . replace ( /\.git$/ , '' ) ;
2021-02-19 08:37:34 -05:00
2021-03-10 02:19:17 -05:00
fs . writeFileSync ( ` ${ homeSsh } /key- ${ sha256 } ` , key + "\n" , { mode : '600' } ) ;
2021-02-19 08:37:34 -05:00
2021-03-10 02:19:17 -05:00
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 } " ` ) ;
2021-02-19 08:37:34 -05:00
2021-03-10 02:19:17 -05:00
const sshConfig = ` \n Host key- ${ sha256 } .github.com \n `
2021-02-19 08:37:34 -05:00
+ ` HostName github.com \n `
2021-03-10 02:19:17 -05:00
+ ` IdentityFile ${ homeSsh } /key- ${ sha256 } \n `
2021-02-19 08:37:34 -05:00
+ ` IdentitiesOnly yes \n ` ;
fs . appendFileSync ( ` ${ homeSsh } /config ` , sshConfig ) ;
2021-03-10 02:19:17 -05:00
console . log ( ` Added deploy-key mapping: Use identity ' ${ homeSsh } /key- ${ sha256 } ' for GitHub repository ${ ownerAndRepo } ` ) ;
2021-02-19 08:37:34 -05:00
} ) ;
2019-09-14 18:28:16 -04:00
} catch ( error ) {
2021-03-05 15:17:14 -05:00
if ( error . code == 'ENOENT' ) {
console . log ( ` The ' ${ error . path } ' executable could not be found. Please make sure it is on your PATH and/or the necessary packages are installed. ` ) ;
console . log ( ` PATH is set to: ${ process . env . PATH } ` ) ;
}
2019-09-14 18:28:16 -04:00
core . setFailed ( error . message ) ;
}