Support loading GPG private key from file path.

This commit is contained in:
Warren Seine 2020-08-05 23:02:41 +02:00
parent 3019d15cad
commit b9a18e1677
8 changed files with 86 additions and 35 deletions

View file

@ -170,6 +170,8 @@ If `gpg-private-key` input is provided, the private key will be written to a fil
See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file.
Alternatively, you can use `gpg-private-key-path` to point to a key file.
## Publishing using Gradle ## Publishing using Gradle
```yaml ```yaml
jobs: jobs:

View file

@ -1,4 +1,5 @@
import path = require('path'); import path = require('path');
import fs = require('fs');
import io = require('@actions/io'); import io = require('@actions/io');
import exec = require('@actions/exec'); import exec = require('@actions/exec');
@ -41,6 +42,23 @@ describe('gpg tests', () => {
}); });
}); });
describe('importKeyFromPath', () => {
it('attempts to import private key from path and returns null key id on failure', async () => {
const privateKey = 'KEY CONTENTS';
const privateKeyPath = path.join(tempDir, 'test.asc');
fs.writeFileSync(privateKeyPath, privateKey);
const keyId = await gpg.importKeyFromPath(privateKeyPath);
expect(keyId).toBeNull();
expect(exec.exec).toHaveBeenCalledWith(
'gpg',
expect.anything(),
expect.anything()
);
});
});
describe('deleteKey', () => { describe('deleteKey', () => {
it('deletes private key', async () => { it('deletes private key', async () => {
const keyId = 'asdfhjkl'; const keyId = 'asdfhjkl';

View file

@ -42,6 +42,9 @@ inputs:
gpg-private-key: gpg-private-key:
description: 'GPG private key to import. Default is empty string.' description: 'GPG private key to import. Default is empty string.'
required: false required: false
gpg-private-key-path:
description: 'Path to the GPG private key to import. Default is empty string. Overriden by gpg-private-key'
required: false
gpg-passphrase: gpg-passphrase:
description: 'Environment variable name for the GPG private key passphrase. Default is description: 'Environment variable name for the GPG private key passphrase. Default is
$GPG_PASSPHRASE.' $GPG_PASSPHRASE.'

22
dist/cleanup/index.js vendored
View file

@ -963,8 +963,10 @@ exports.INPUT_SERVER_ID = 'server-id';
exports.INPUT_SERVER_USERNAME = 'server-username'; exports.INPUT_SERVER_USERNAME = 'server-username';
exports.INPUT_SERVER_PASSWORD = 'server-password'; exports.INPUT_SERVER_PASSWORD = 'server-password';
exports.INPUT_SETTINGS_PATH = 'settings-path'; exports.INPUT_SETTINGS_PATH = 'settings-path';
exports.INPUT_GPG_PRIVATE_KEY_PATH = 'gpg-private-key-path';
exports.INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; exports.INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
exports.INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; exports.INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
exports.INPUT_DEFAULT_GPG_PRIVATE_KEY_PATH = undefined;
exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint'; exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint';
@ -1627,6 +1629,15 @@ function importKey(privateKey) {
encoding: 'utf-8', encoding: 'utf-8',
flag: 'w' flag: 'w'
}); });
const keyFingerprint = yield importKeyFromPath(exports.PRIVATE_KEY_FILE);
yield io.rmRF(exports.PRIVATE_KEY_FILE);
return keyFingerprint;
});
}
exports.importKey = importKey;
function importKeyFromPath(privateKeyPath) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`from path: ${privateKeyPath}`);
let output = ''; let output = '';
const options = { const options = {
silent: true, silent: true,
@ -1636,19 +1647,12 @@ function importKey(privateKey) {
} }
} }
}; };
yield exec.exec('gpg', [ yield exec.exec('gpg', ['--batch', '--import-options', 'import-show', '--import', privateKeyPath], options);
'--batch',
'--import-options',
'import-show',
'--import',
exports.PRIVATE_KEY_FILE
], options);
yield io.rmRF(exports.PRIVATE_KEY_FILE);
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
return match && match[0]; return match && match[0];
}); });
} }
exports.importKey = importKey; exports.importKeyFromPath = importKeyFromPath;
function deleteKey(keyFingerprint) { function deleteKey(keyFingerprint) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true }); yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true });

38
dist/setup/index.js vendored
View file

@ -25663,8 +25663,10 @@ exports.INPUT_SERVER_ID = 'server-id';
exports.INPUT_SERVER_USERNAME = 'server-username'; exports.INPUT_SERVER_USERNAME = 'server-username';
exports.INPUT_SERVER_PASSWORD = 'server-password'; exports.INPUT_SERVER_PASSWORD = 'server-password';
exports.INPUT_SETTINGS_PATH = 'settings-path'; exports.INPUT_SETTINGS_PATH = 'settings-path';
exports.INPUT_GPG_PRIVATE_KEY_PATH = 'gpg-private-key-path';
exports.INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; exports.INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
exports.INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; exports.INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
exports.INPUT_DEFAULT_GPG_PRIVATE_KEY_PATH = undefined;
exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';
exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint'; exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint';
@ -28699,18 +28701,26 @@ function run() {
const password = core.getInput(constants.INPUT_SERVER_PASSWORD, { const password = core.getInput(constants.INPUT_SERVER_PASSWORD, {
required: false required: false
}); });
const gpgPrivateKeyPath = core.getInput(constants.INPUT_GPG_PRIVATE_KEY_PATH, { required: false }) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY_PATH;
const gpgPrivateKey = core.getInput(constants.INPUT_GPG_PRIVATE_KEY, { required: false }) || const gpgPrivateKey = core.getInput(constants.INPUT_GPG_PRIVATE_KEY, { required: false }) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY; constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase = core.getInput(constants.INPUT_GPG_PASSPHRASE, { required: false }) || const gpgPassphrase = core.getInput(constants.INPUT_GPG_PASSPHRASE, { required: false }) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined); (gpgPrivateKey || gpgPrivateKeyPath
? constants.INPUT_DEFAULT_GPG_PASSPHRASE
: undefined);
if (gpgPrivateKey) { if (gpgPrivateKey) {
core.setSecret(gpgPrivateKey); core.setSecret(gpgPrivateKey);
} }
yield auth.configAuthentication(id, username, password, gpgPassphrase); yield auth.configAuthentication(id, username, password, gpgPassphrase);
if (gpgPrivateKey) { if (gpgPrivateKey || gpgPrivateKeyPath) {
core.info('importing private key'); core.info('importing private key');
const keyFingerprint = (yield gpg.importKey(gpgPrivateKey)) || ''; const keyFingerprint = gpgPrivateKey
core.saveState(constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, keyFingerprint); ? yield gpg.importKey(gpgPrivateKey)
: gpgPrivateKeyPath
? yield gpg.importKeyFromPath(gpgPrivateKeyPath)
: null;
core.saveState(constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, keyFingerprint || '');
} }
} }
catch (error) { catch (error) {
@ -32612,6 +32622,15 @@ function importKey(privateKey) {
encoding: 'utf-8', encoding: 'utf-8',
flag: 'w' flag: 'w'
}); });
const keyFingerprint = yield importKeyFromPath(exports.PRIVATE_KEY_FILE);
yield io.rmRF(exports.PRIVATE_KEY_FILE);
return keyFingerprint;
});
}
exports.importKey = importKey;
function importKeyFromPath(privateKeyPath) {
return __awaiter(this, void 0, void 0, function* () {
console.log(`from path: ${privateKeyPath}`);
let output = ''; let output = '';
const options = { const options = {
silent: true, silent: true,
@ -32621,19 +32640,12 @@ function importKey(privateKey) {
} }
} }
}; };
yield exec.exec('gpg', [ yield exec.exec('gpg', ['--batch', '--import-options', 'import-show', '--import', privateKeyPath], options);
'--batch',
'--import-options',
'import-show',
'--import',
exports.PRIVATE_KEY_FILE
], options);
yield io.rmRF(exports.PRIVATE_KEY_FILE);
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
return match && match[0]; return match && match[0];
}); });
} }
exports.importKey = importKey; exports.importKeyFromPath = importKeyFromPath;
function deleteKey(keyFingerprint) { function deleteKey(keyFingerprint) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true }); yield exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', keyFingerprint], { silent: true });

View file

@ -7,9 +7,11 @@ export const INPUT_SERVER_ID = 'server-id';
export const INPUT_SERVER_USERNAME = 'server-username'; export const INPUT_SERVER_USERNAME = 'server-username';
export const INPUT_SERVER_PASSWORD = 'server-password'; export const INPUT_SERVER_PASSWORD = 'server-password';
export const INPUT_SETTINGS_PATH = 'settings-path'; export const INPUT_SETTINGS_PATH = 'settings-path';
export const INPUT_GPG_PRIVATE_KEY_PATH = 'gpg-private-key-path';
export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key';
export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase';
export const INPUT_DEFAULT_GPG_PRIVATE_KEY_PATH = undefined;
export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined;
export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE';

View file

@ -15,6 +15,15 @@ export async function importKey(privateKey: string) {
flag: 'w' flag: 'w'
}); });
const keyFingerprint = await importKeyFromPath(PRIVATE_KEY_FILE);
await io.rmRF(PRIVATE_KEY_FILE);
return keyFingerprint;
}
export async function importKeyFromPath(privateKeyPath: string) {
console.log(`from path: ${privateKeyPath}`);
let output = ''; let output = '';
const options: ExecOptions = { const options: ExecOptions = {
@ -28,18 +37,10 @@ export async function importKey(privateKey: string) {
await exec.exec( await exec.exec(
'gpg', 'gpg',
[ ['--batch', '--import-options', 'import-show', '--import', privateKeyPath],
'--batch',
'--import-options',
'import-show',
'--import',
PRIVATE_KEY_FILE
],
options options
); );
await io.rmRF(PRIVATE_KEY_FILE);
const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX); const match = output.match(PRIVATE_KEY_FINGERPRINT_REGEX);
return match && match[0]; return match && match[0];
} }

View file

@ -29,12 +29,17 @@ async function run() {
const password = core.getInput(constants.INPUT_SERVER_PASSWORD, { const password = core.getInput(constants.INPUT_SERVER_PASSWORD, {
required: false required: false
}); });
const gpgPrivateKeyPath =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY_PATH, {required: false}) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY_PATH;
const gpgPrivateKey = const gpgPrivateKey =
core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) || core.getInput(constants.INPUT_GPG_PRIVATE_KEY, {required: false}) ||
constants.INPUT_DEFAULT_GPG_PRIVATE_KEY; constants.INPUT_DEFAULT_GPG_PRIVATE_KEY;
const gpgPassphrase = const gpgPassphrase =
core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) || core.getInput(constants.INPUT_GPG_PASSPHRASE, {required: false}) ||
(gpgPrivateKey ? constants.INPUT_DEFAULT_GPG_PASSPHRASE : undefined); (gpgPrivateKey || gpgPrivateKeyPath
? constants.INPUT_DEFAULT_GPG_PASSPHRASE
: undefined);
if (gpgPrivateKey) { if (gpgPrivateKey) {
core.setSecret(gpgPrivateKey); core.setSecret(gpgPrivateKey);
@ -42,12 +47,16 @@ async function run() {
await auth.configAuthentication(id, username, password, gpgPassphrase); await auth.configAuthentication(id, username, password, gpgPassphrase);
if (gpgPrivateKey) { if (gpgPrivateKey || gpgPrivateKeyPath) {
core.info('importing private key'); core.info('importing private key');
const keyFingerprint = (await gpg.importKey(gpgPrivateKey)) || ''; const keyFingerprint = gpgPrivateKey
? await gpg.importKey(gpgPrivateKey)
: gpgPrivateKeyPath
? await gpg.importKeyFromPath(gpgPrivateKeyPath)
: null;
core.saveState( core.saveState(
constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT, constants.STATE_GPG_PRIVATE_KEY_FINGERPRINT,
keyFingerprint keyFingerprint || ''
); );
} }
} catch (error) { } catch (error) {