2019-09-14 22:28:16 +00:00
const core = require ( '@actions/core' );
const child_process = require ( 'child_process' );
const fs = require ( 'fs' );
2021-02-19 14:37:34 +01:00
const crypto = require ( 'crypto' );
2025-01-08 17:59:51 +01:00
const { homePath , sshAgentCmd , sshAddCmd , gitCmd } = require ( './paths.js' );
2019-09-14 22:28:16 +00:00
try {
2020-02-06 12:09:44 -06:00
const privateKey = core . getInput ( 'ssh-private-key' );
2022-10-19 10:41:11 +00:00
const logPublicKey = core . getBooleanInput ( 'log-public-key' , { default : true });
2020-01-14 09:29:16 +00: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 ;
}
2022-10-19 13:27:50 +02:00
const homeSsh = homePath + '/.ssh' ;
2020-03-02 16:41:12 -08:00
fs . mkdirSync ( homeSsh , { recursive : true });
2019-09-14 22:28:16 +00:00
console . log ( "Starting ssh-agent" );
2021-03-10 08:19:17 +01:00
2019-09-14 22:28:16 +00:00
const authSock = core . getInput ( 'ssh-auth-sock' );
2021-03-10 08:19:17 +01:00
const sshAgentArgs = ( authSock && authSock . length > 0 ) ? [ '-a' , authSock ] : [];
2020-05-18 09:08:29 +02:00
// Extract auth socket path and agent pid and set them as job variables
2022-10-19 13:27:50 +02:00
child_process . execFileSync ( sshAgentCmd , sshAgentArgs ). toString (). split ( "\n" ). forEach ( function ( line ) {
2021-03-10 08:19:17 +01:00
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/ . exec ( line );
2020-05-18 09:08:29 +02:00
if ( matches && matches . length > 0 ) {
2021-03-10 08:19:17 +01:00
// This will also set process.env accordingly, so changes take effect for this script
2020-05-18 09:08:29 +02:00
core . exportVariable ( matches [ 1 ], matches [ 2 ])
2021-03-10 08:19:17 +01:00
console . log ( ` ${ matches [ 1 ] } = ${ matches [ 2 ] } ` );
2020-05-18 09:08:29 +02:00
}
2021-03-10 08:19:17 +01:00
});
console . log ( "Adding private key(s) to agent" );
2019-09-14 22:28:16 +00:00
2020-01-14 09:29:16 +00:00
privateKey . split ( /(?=-----BEGIN)/ ). forEach ( function ( key ) {
2022-10-19 13:27:50 +02:00
child_process . execFileSync ( sshAddCmd , [ '-' ], { input : key . trim () + "\n" });
2020-01-14 10:21:11 +01:00
});
2020-01-14 09:29:16 +00:00
2021-03-10 08:19:17 +01:00
console . log ( "Key(s) added:" );
2022-10-19 13:27:50 +02:00
child_process . execFileSync ( sshAddCmd , [ '-l' ], { stdio : 'inherit' });
2021-03-10 08:19:17 +01:00
console . log ( 'Configuring deployment key(s)' );
2020-01-14 09:29:16 +00:00
2022-10-19 14:54:52 +02:00
child_process . execFileSync ( sshAddCmd , [ '-L' ]). toString (). trim (). split ( /\r?\n/ ). forEach ( function ( key ) {
2021-03-17 18:27:52 +00:00
const parts = key . match ( /\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)/i );
2021-02-19 14:37:34 +01:00
2021-03-10 08:19:17 +01:00
if ( ! parts ) {
2022-10-19 10:41:11 +00:00
if ( logPublicKey ) {
console . log ( `Comment for (public) key ' ${ key } ' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.` );
}
2021-02-19 14:37:34 +01:00
return ;
}
2021-03-10 08:19:17 +01:00
const sha256 = crypto . createHash ( 'sha256' ). update ( key ). digest ( 'hex' );
const ownerAndRepo = parts [ 1 ]. replace ( /\.git$/ , '' );
2021-02-19 14:37:34 +01:00
2021-03-10 08:19:17 +01:00
fs . writeFileSync ( ` ${ homeSsh } /key- ${ sha256 } ` , key + "\n" , { mode : '600' });
2021-02-19 14:37:34 +01:00
2022-10-19 13:27:50 +02:00
child_process . execSync ( ` ${ gitCmd } config --global --replace-all url."git@key- ${ sha256 } .github.com: ${ ownerAndRepo } ".insteadOf "https://github.com/ ${ ownerAndRepo } "` );
child_process . execSync ( ` ${ gitCmd } config --global --add url."git@key- ${ sha256 } .github.com: ${ ownerAndRepo } ".insteadOf "git@github.com: ${ ownerAndRepo } "` );
child_process . execSync ( ` ${ gitCmd } config --global --add url."git@key- ${ sha256 } .github.com: ${ ownerAndRepo } ".insteadOf "ssh://git@github.com/ ${ ownerAndRepo } "` );
2021-02-19 14:37:34 +01:00
2021-03-10 08:19:17 +01:00
const sshConfig = `\nHost key- ${ sha256 } .github.com\n`
2021-02-19 14:37:34 +01:00
+ ` HostName github.com\n`
2021-03-10 08:19:17 +01:00
+ ` IdentityFile ${ homeSsh } /key- ${ sha256 } \n`
2021-02-19 14:37:34 +01:00
+ ` IdentitiesOnly yes\n` ;
fs . appendFileSync ( ` ${ homeSsh } /config` , sshConfig );
2021-03-10 08:19:17 +01:00
console . log ( `Added deploy-key mapping: Use identity ' ${ homeSsh } /key- ${ sha256 } ' for GitHub repository ${ ownerAndRepo } ` );
2021-02-19 14:37:34 +01:00
});
2019-09-14 22:28:16 +00:00
} catch ( error ) {
2021-03-05 20:17:14 +00: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 22:28:16 +00:00
core . setFailed ( error . message );
}