mirror of
https://github.com/crazy-max/ghaction-import-gpg.git
synced 2024-12-24 20:22:07 -05:00
Allow to seed the internal cache of gpg-agent with provided passphrase (#5)
Better handling of commands output streams
This commit is contained in:
parent
9a41db05e6
commit
a8f7b5960a
8 changed files with 1612 additions and 76 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -32,3 +32,4 @@ jobs:
|
||||||
uses: ./
|
uses: ./
|
||||||
env:
|
env:
|
||||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY_TEST }}
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY_TEST }}
|
||||||
|
PASSPHRASE: ${{ secrets.PASSPHRASE_TEST }}
|
||||||
|
|
|
@ -12,6 +12,12 @@ If you are interested, [check out](https://git.io/Je09Y) my other :octocat: GitH
|
||||||
|
|
||||||
![Import GPG key](.res/ghaction-import-gpg.png)
|
![Import GPG key](.res/ghaction-import-gpg.png)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Works on Linux, MacOS and Windows [virtual environments](https://help.github.com/en/articles/virtual-environments-for-github-actions#supported-virtual-environments-and-hardware-resources)
|
||||||
|
* Allow to seed the internal cache of `gpg-agent` with provided passphrase
|
||||||
|
* Purge imported GPG key and cache information from runner (security)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -33,6 +39,7 @@ jobs:
|
||||||
uses: crazy-max/ghaction-import-gpg@master
|
uses: crazy-max/ghaction-import-gpg@master
|
||||||
env:
|
env:
|
||||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
PASSPHRASE: ${{ secrets.PASSPHRASE }}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
|
@ -44,6 +51,7 @@ Following environment variables can be used as `step.env` keys
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|----------------|---------------------------------------|
|
|----------------|---------------------------------------|
|
||||||
| `SIGNING_KEY` | GPG private key exported as an ASCII armored version |
|
| `SIGNING_KEY` | GPG private key exported as an ASCII armored version |
|
||||||
|
| `PASSPHRASE` | Passphrase of your GPG key if setted for your `SIGNING_KEY` |
|
||||||
|
|
||||||
## How can I help?
|
## How can I help?
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {deleteKey, getVersion, importKey} from '../src/gpg';
|
import * as gpg from '../src/gpg';
|
||||||
import * as child_process from 'child_process';
|
|
||||||
|
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
name: 'Joe Tester',
|
name: 'Joe Tester',
|
||||||
|
@ -8,6 +7,7 @@ const userInfo = {
|
||||||
keyID: 'D523BD50DD70B0BA',
|
keyID: 'D523BD50DD70B0BA',
|
||||||
userID: 'Joe Tester <joe@foo.bar>',
|
userID: 'Joe Tester <joe@foo.bar>',
|
||||||
fingerprint: '27571A53B86AF0C799B38BA77D851EB72D73BDA0',
|
fingerprint: '27571A53B86AF0C799B38BA77D851EB72D73BDA0',
|
||||||
|
keygrip: 'BA83FC8947213477F28ADC019F6564A956456163',
|
||||||
pgp: `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
pgp: `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
lQdGBF6tzaABEACjFbX7PFEG6vDPN2MPyxYW7/3o/sonORj4HXUFjFxxJxktJ3x3
|
lQdGBF6tzaABEACjFbX7PFEG6vDPN2MPyxYW7/3o/sonORj4HXUFjFxxJxktJ3x3
|
||||||
|
@ -119,7 +119,7 @@ PejgXO0uIRolYQ3sz2tMGhx1MfBqH64=
|
||||||
describe('gpg', () => {
|
describe('gpg', () => {
|
||||||
describe('getVersion', () => {
|
describe('getVersion', () => {
|
||||||
it('returns GnuPG and libgcrypt version', async () => {
|
it('returns GnuPG and libgcrypt version', async () => {
|
||||||
await getVersion().then(version => {
|
await gpg.getVersion().then(version => {
|
||||||
console.log(version);
|
console.log(version);
|
||||||
expect(version.gnupg).not.toEqual('');
|
expect(version.gnupg).not.toEqual('');
|
||||||
expect(version.libgcrypt).not.toEqual('');
|
expect(version.libgcrypt).not.toEqual('');
|
||||||
|
@ -127,25 +127,58 @@ describe('gpg', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getDirs', () => {
|
||||||
|
it('returns GnuPG dirs', async () => {
|
||||||
|
await gpg.getDirs().then(dirs => {
|
||||||
|
console.log(dirs);
|
||||||
|
expect(dirs.libdir).not.toEqual('');
|
||||||
|
expect(dirs.datadir).not.toEqual('');
|
||||||
|
expect(dirs.homedir).not.toEqual('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('importKey', () => {
|
describe('importKey', () => {
|
||||||
it('imports key to GnuPG', async () => {
|
it('imports key to GnuPG', async () => {
|
||||||
await importKey(userInfo.pgp).then(() => {
|
await gpg.importKey(userInfo.pgp).then(output => {
|
||||||
console.log(
|
console.log(output);
|
||||||
child_process.execSync(`gpg --batch --list-keys --keyid-format LONG ${userInfo.email}`, {encoding: 'utf8'})
|
expect(output).not.toEqual('');
|
||||||
);
|
});
|
||||||
console.log(
|
});
|
||||||
child_process.execSync(`gpg --batch --list-secret-keys --keyid-format LONG ${userInfo.email}`, {
|
});
|
||||||
encoding: 'utf8'
|
|
||||||
})
|
describe('getKeygrip', () => {
|
||||||
);
|
it('returns the keygrip', async () => {
|
||||||
|
await gpg.importKey(userInfo.pgp);
|
||||||
|
await gpg.getKeygrip(userInfo.fingerprint).then(keygrip => {
|
||||||
|
console.log(keygrip);
|
||||||
|
expect(keygrip).toEqual(userInfo.keygrip);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('configureAgent', () => {
|
||||||
|
it('configures GnuPG agent', async () => {
|
||||||
|
await gpg.configureAgent(gpg.agentConfig);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('presetPassphrase', () => {
|
||||||
|
it('presets passphrase', async () => {
|
||||||
|
await gpg.importKey(userInfo.pgp);
|
||||||
|
const keygrip = await gpg.getKeygrip(userInfo.fingerprint);
|
||||||
|
await gpg.configureAgent(gpg.agentConfig);
|
||||||
|
await gpg.presetPassphrase(keygrip, userInfo.passphrase).then(output => {
|
||||||
|
console.log(output);
|
||||||
|
expect(output).not.toEqual('');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteKey', () => {
|
describe('deleteKey', () => {
|
||||||
it('removes key from GnuPG', async () => {
|
it('removes key from GnuPG', async () => {
|
||||||
await importKey(userInfo.pgp);
|
await gpg.importKey(userInfo.pgp);
|
||||||
await deleteKey(userInfo.fingerprint);
|
await gpg.deleteKey(userInfo.fingerprint);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {readPrivateKey, generateKeyPair} from '../src/openpgp';
|
import * as openpgp from '../src/openpgp';
|
||||||
|
|
||||||
const userInfo = {
|
const userInfo = {
|
||||||
name: 'Joe Tester',
|
name: 'Joe Tester',
|
||||||
|
@ -118,7 +118,7 @@ PejgXO0uIRolYQ3sz2tMGhx1MfBqH64=
|
||||||
describe('openpgp', () => {
|
describe('openpgp', () => {
|
||||||
describe('readPrivateKey', () => {
|
describe('readPrivateKey', () => {
|
||||||
it('returns a PGP private key', async () => {
|
it('returns a PGP private key', async () => {
|
||||||
await readPrivateKey(userInfo.pgp).then(privateKey => {
|
await openpgp.readPrivateKey(userInfo.pgp).then(privateKey => {
|
||||||
expect(privateKey.keyID).toEqual(userInfo.keyID);
|
expect(privateKey.keyID).toEqual(userInfo.keyID);
|
||||||
expect(privateKey.userID).toEqual(userInfo.userID);
|
expect(privateKey.userID).toEqual(userInfo.userID);
|
||||||
expect(privateKey.fingerprint).toEqual(userInfo.fingerprint);
|
expect(privateKey.fingerprint).toEqual(userInfo.fingerprint);
|
||||||
|
@ -128,7 +128,7 @@ describe('openpgp', () => {
|
||||||
|
|
||||||
describe('generateKeyPair', () => {
|
describe('generateKeyPair', () => {
|
||||||
it('generates a PGP key pair', async () => {
|
it('generates a PGP key pair', async () => {
|
||||||
await generateKeyPair(userInfo.name, userInfo.email, userInfo.passphrase).then(keyPair => {
|
await openpgp.generateKeyPair(userInfo.name, userInfo.email, userInfo.passphrase).then(keyPair => {
|
||||||
expect(keyPair).not.toBeUndefined();
|
expect(keyPair).not.toBeUndefined();
|
||||||
expect(keyPair.publicKey).not.toBeUndefined();
|
expect(keyPair.publicKey).not.toBeUndefined();
|
||||||
expect(keyPair.privateKey).not.toBeUndefined();
|
expect(keyPair.privateKey).not.toBeUndefined();
|
||||||
|
|
1392
dist/index.js
generated
vendored
1392
dist/index.js
generated
vendored
File diff suppressed because it is too large
Load diff
34
src/exec.ts
Normal file
34
src/exec.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import * as actionsExec from '@actions/exec';
|
||||||
|
import {ExecOptions} from '@actions/exec';
|
||||||
|
|
||||||
|
export interface ExecResult {
|
||||||
|
success: boolean;
|
||||||
|
stdout: string;
|
||||||
|
stderr: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const exec = async (command: string, args: string[] = [], silent: boolean): Promise<ExecResult> => {
|
||||||
|
let stdout: string = '';
|
||||||
|
let stderr: string = '';
|
||||||
|
|
||||||
|
const options: ExecOptions = {
|
||||||
|
silent: silent,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
};
|
||||||
|
options.listeners = {
|
||||||
|
stdout: (data: Buffer) => {
|
||||||
|
stdout += data.toString();
|
||||||
|
},
|
||||||
|
stderr: (data: Buffer) => {
|
||||||
|
stderr += data.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const returnCode: number = await actionsExec.exec(command, args, options);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: returnCode === 0,
|
||||||
|
stdout: stdout.trim(),
|
||||||
|
stderr: stderr.trim()
|
||||||
|
};
|
||||||
|
};
|
149
src/gpg.ts
149
src/gpg.ts
|
@ -1,27 +1,33 @@
|
||||||
import * as child_process from 'child_process';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
import * as exec from './exec';
|
||||||
|
|
||||||
|
export const agentConfig = `default-cache-ttl 1
|
||||||
|
max-cache-ttl 31536000
|
||||||
|
allow-preset-passphrase`;
|
||||||
|
|
||||||
export interface Version {
|
export interface Version {
|
||||||
gnupg: string;
|
gnupg: string;
|
||||||
libgcrypt: string;
|
libgcrypt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gpg = async (args: string[] = []): Promise<string> => {
|
export interface Dirs {
|
||||||
return child_process
|
libdir: string;
|
||||||
.execSync(`gpg ${args.join(' ')}`, {
|
datadir: string;
|
||||||
encoding: 'utf8'
|
homedir: string;
|
||||||
})
|
}
|
||||||
.trim();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getVersion = async (): Promise<Version> => {
|
export const getVersion = async (): Promise<Version> => {
|
||||||
let gnupgVersion: string = '';
|
return await exec.exec('gpg', ['--version'], true).then(res => {
|
||||||
let libgcryptVersion: string = '';
|
if (res.stderr != '') {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
|
||||||
await gpg(['--version']).then(stdout => {
|
let gnupgVersion: string = '';
|
||||||
for (let line of stdout.replace(/\r/g, '').trim().split(/\n/g)) {
|
let libgcryptVersion: string = '';
|
||||||
|
|
||||||
|
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
|
||||||
if (line.startsWith('gpg (GnuPG) ')) {
|
if (line.startsWith('gpg (GnuPG) ')) {
|
||||||
gnupgVersion = line.substr('gpg (GnuPG) '.length).trim();
|
gnupgVersion = line.substr('gpg (GnuPG) '.length).trim();
|
||||||
} else if (line.startsWith('gpg (GnuPG/MacGPG2) ')) {
|
} else if (line.startsWith('gpg (GnuPG/MacGPG2) ')) {
|
||||||
|
@ -30,25 +36,124 @@ export const getVersion = async (): Promise<Version> => {
|
||||||
libgcryptVersion = line.substr('libgcrypt '.length).trim();
|
libgcryptVersion = line.substr('libgcrypt '.length).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
gnupg: gnupgVersion,
|
gnupg: gnupgVersion,
|
||||||
libgcrypt: libgcryptVersion
|
libgcrypt: libgcryptVersion
|
||||||
};
|
};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const importKey = async (armoredText: string): Promise<void> => {
|
export const getDirs = async (): Promise<Dirs> => {
|
||||||
|
return await exec.exec('gpgconf', ['--list-dirs'], true).then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
let libdir: string = '';
|
||||||
|
let datadir: string = '';
|
||||||
|
let homedir: string = '';
|
||||||
|
|
||||||
|
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
|
||||||
|
if (line.startsWith('libdir:')) {
|
||||||
|
libdir = line.substr('libdir:'.length).replace('%3a', ':').trim();
|
||||||
|
} else if (line.startsWith('datadir:')) {
|
||||||
|
datadir = line.substr('datadir:'.length).replace('%3a', ':').trim();
|
||||||
|
} else if (line.startsWith('homedir:')) {
|
||||||
|
homedir = line.substr('homedir:'.length).replace('%3a', ':').trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
libdir: path.normalize(libdir),
|
||||||
|
datadir: path.normalize(datadir),
|
||||||
|
homedir: path.normalize(homedir)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const importKey = async (armoredText: string): Promise<string> => {
|
||||||
const keyFolder: string = fs.mkdtempSync(path.join(os.tmpdir(), 'ghaction-import-gpg-'));
|
const keyFolder: string = fs.mkdtempSync(path.join(os.tmpdir(), 'ghaction-import-gpg-'));
|
||||||
const keyPath: string = `${keyFolder}/key.pgp`;
|
const keyPath: string = `${keyFolder}/key.pgp`;
|
||||||
fs.writeFileSync(keyPath, armoredText, {mode: 0o600});
|
fs.writeFileSync(keyPath, armoredText, {mode: 0o600});
|
||||||
|
|
||||||
await gpg(['--import', '--batch', '--yes', keyPath]).finally(() => {
|
return await exec
|
||||||
fs.unlinkSync(keyPath);
|
.exec('gpg', ['--import', '--batch', '--yes', keyPath], true)
|
||||||
|
.then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
if (res.stderr != '') {
|
||||||
|
return res.stderr.trim();
|
||||||
|
}
|
||||||
|
return res.stdout.trim();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
fs.unlinkSync(keyPath);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getKeygrip = async (fingerprint: string): Promise<string> => {
|
||||||
|
return await exec
|
||||||
|
.exec('gpg', ['--batch', '--with-colons', '--with-keygrip', '--list-secret-keys', fingerprint], true)
|
||||||
|
.then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
let keygrip: string = '';
|
||||||
|
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
|
||||||
|
if (line.startsWith('grp')) {
|
||||||
|
keygrip = line.replace(/(grp|:)/g, '').trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keygrip;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const configureAgent = async (config: string): Promise<void> => {
|
||||||
|
const {homedir: homedir} = await getDirs();
|
||||||
|
const gpgAgentConf = path.join(homedir, 'gpg-agent.conf');
|
||||||
|
await fs.writeFile(gpgAgentConf, config, function (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
});
|
||||||
|
await exec.exec(`gpg-connect-agent "RELOADAGENT" /bye`, [], true).then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const presetPassphrase = async (keygrip: string, passphrase: string): Promise<string> => {
|
||||||
|
await exec
|
||||||
|
.exec('gpg-preset-passphrase', ['--verbose', '--preset', '--passphrase', `"${passphrase}"`, keygrip], true)
|
||||||
|
.then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return await exec.exec(`gpg-connect-agent "KEYINFO ${keygrip}" /bye`, [], true).then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
for (let line of res.stdout.replace(/\r/g, '').trim().split(/\n/g)) {
|
||||||
|
if (line.startsWith('ERR')) {
|
||||||
|
throw new Error(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.stdout.trim();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteKey = async (fingerprint: string): Promise<void> => {
|
export const deleteKey = async (fingerprint: string): Promise<void> => {
|
||||||
await gpg(['--batch', '--yes', ' --delete-secret-keys', fingerprint]);
|
await exec.exec('gpg', ['--batch', '--yes', '--delete-secret-keys', fingerprint], true).then(res => {
|
||||||
await gpg(['--batch', '--yes', ' --delete-keys', fingerprint]);
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await exec.exec('gpg', ['--batch', '--yes', '--delete-keys', fingerprint], true).then(res => {
|
||||||
|
if (res.stderr != '' && !res.success) {
|
||||||
|
throw new Error(res.stderr);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
37
src/main.ts
37
src/main.ts
|
@ -12,18 +12,37 @@ async function run(): Promise<void> {
|
||||||
|
|
||||||
core.info('📣 GnuPG info');
|
core.info('📣 GnuPG info');
|
||||||
const version = await gpg.getVersion();
|
const version = await gpg.getVersion();
|
||||||
core.info(`GnuPG version: ${version.gnupg}`);
|
const dirs = await gpg.getDirs();
|
||||||
core.info(`libgcrypt version: ${version.libgcrypt}`);
|
core.info(`Version : ${version.gnupg} (libgcrypt ${version.libgcrypt})`);
|
||||||
|
core.info(`Homedir : ${dirs.homedir}`);
|
||||||
|
core.info(`Datadir : ${dirs.datadir}`);
|
||||||
|
core.info(`Libdir : ${dirs.libdir}`);
|
||||||
|
|
||||||
core.info('🔮 Checking signing key...');
|
core.info('🔮 Checking signing key...');
|
||||||
const privateKey = await openpgp.readPrivateKey(process.env.SIGNING_KEY);
|
const privateKey = await openpgp.readPrivateKey(process.env.SIGNING_KEY);
|
||||||
core.debug(`key.fingerprint=${privateKey.fingerprint}`);
|
core.debug(`Fingerprint : ${privateKey.fingerprint}`);
|
||||||
core.debug(`key.keyID=${privateKey.keyID}`);
|
core.debug(`KeyID : ${privateKey.keyID}`);
|
||||||
core.debug(`key.userID=${privateKey.userID}`);
|
core.debug(`UserID : ${privateKey.userID}`);
|
||||||
core.debug(`key.creationTime=${privateKey.creationTime}`);
|
core.debug(`CreationTime : ${privateKey.creationTime}`);
|
||||||
|
|
||||||
core.info('🔑 Importing secret key...');
|
core.info('🔑 Importing secret key...');
|
||||||
await gpg.importKey(process.env.SIGNING_KEY);
|
await gpg.importKey(process.env.SIGNING_KEY).then(stdout => {
|
||||||
|
core.debug(stdout);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.PASSPHRASE) {
|
||||||
|
core.info('⚙️ Configuring GnuPG agent...');
|
||||||
|
await gpg.configureAgent(gpg.agentConfig);
|
||||||
|
|
||||||
|
core.info('📌 Getting keygrip...');
|
||||||
|
const keygrip = await gpg.getKeygrip(privateKey.fingerprint);
|
||||||
|
core.debug(`${keygrip}`);
|
||||||
|
|
||||||
|
core.info('🔓 Preset passphrase...');
|
||||||
|
await gpg.presetPassphrase(keygrip, process.env.PASSPHRASE).then(stdout => {
|
||||||
|
core.debug(stdout);
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
@ -31,11 +50,11 @@ async function run(): Promise<void> {
|
||||||
|
|
||||||
async function cleanup(): Promise<void> {
|
async function cleanup(): Promise<void> {
|
||||||
if (!process.env.SIGNING_KEY) {
|
if (!process.env.SIGNING_KEY) {
|
||||||
core.debug('Private key is not defined. Skipping cleanup.');
|
core.debug('Signing key is not defined. Skipping cleanup.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
core.info('🚿 Removing keys from GnuPG...');
|
core.info('🚿 Removing keys...');
|
||||||
const privateKey = await openpgp.readPrivateKey(process.env.SIGNING_KEY);
|
const privateKey = await openpgp.readPrivateKey(process.env.SIGNING_KEY);
|
||||||
await gpg.deleteKey(privateKey.fingerprint);
|
await gpg.deleteKey(privateKey.fingerprint);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
Loading…
Reference in a new issue