Toolkit: implement plugin signing in grafana-toolkit (#27907)
* implement plugin signing in grafana-toolkit
This commit is contained in:
@@ -18,6 +18,7 @@ import { pluginUpdateTask } from './tasks/plugin.update';
|
||||
import { ciBuildPluginDocsTask, ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci';
|
||||
import { buildPackageTask } from './tasks/package.build';
|
||||
import { pluginCreateTask } from './tasks/plugin.create';
|
||||
import { pluginSignTask } from './tasks/plugin.sign';
|
||||
import { bundleManagedTask } from './tasks/plugin/bundle.managed';
|
||||
import { componentCreateTask } from './tasks/component.create';
|
||||
|
||||
@@ -179,6 +180,19 @@ export const run = (includeInternalScripts = false) => {
|
||||
});
|
||||
});
|
||||
|
||||
program
|
||||
.command('plugin:sign')
|
||||
.option('--signatureType <type>', 'Signature Type')
|
||||
.option('--rootUrls <urls...>', 'Root URLs')
|
||||
.description('Create a plugin signature')
|
||||
.action(async cmd => {
|
||||
await execTask(pluginSignTask)({
|
||||
signatureType: cmd.signatureType,
|
||||
rootUrls: cmd.rootUrls,
|
||||
silent: true,
|
||||
});
|
||||
});
|
||||
|
||||
program
|
||||
.command('plugin:ci-build')
|
||||
.option('--finish', 'move all results to the jobs folder', false)
|
||||
@@ -200,11 +214,14 @@ export const run = (includeInternalScripts = false) => {
|
||||
|
||||
program
|
||||
.command('plugin:ci-package')
|
||||
.option('--signing-admin', 'Use the admin API endpoint for signing the manifest.', false)
|
||||
.option('--signatureType <type>', 'Signature Type')
|
||||
.option('--rootUrls <urls...>', 'Root URLs')
|
||||
.option('--signing-admin', 'Use the admin API endpoint for signing the manifest. (deprecated)', false)
|
||||
.description('Create a zip packages for the plugin')
|
||||
.action(async cmd => {
|
||||
await execTask(ciPackagePluginTask)({
|
||||
signingAdmin: cmd.signingAdmin,
|
||||
signatureType: cmd.signatureType,
|
||||
rootUrls: cmd.rootUrls,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import execa = require('execa');
|
||||
import path = require('path');
|
||||
import fs from 'fs-extra';
|
||||
import { getPackageDetails, getGrafanaVersions, readGitLog } from '../../plugins/utils';
|
||||
import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest';
|
||||
import {
|
||||
getJobFolder,
|
||||
writeJobStats,
|
||||
@@ -25,7 +26,8 @@ const rimraf = promisify(rimrafCallback);
|
||||
export interface PluginCIOptions {
|
||||
finish?: boolean;
|
||||
upload?: boolean;
|
||||
signingAdmin?: boolean;
|
||||
signatureType?: string;
|
||||
rootUrls?: string[];
|
||||
maxJestWorkers?: string;
|
||||
}
|
||||
|
||||
@@ -107,7 +109,7 @@ export const ciBuildPluginDocsTask = new Task<PluginCIOptions>('Build Plugin Doc
|
||||
* 2. zip it into packages in `~/ci/packages`
|
||||
* 3. prepare grafana environment in: `~/ci/grafana-test-env`
|
||||
*/
|
||||
const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signingAdmin }) => {
|
||||
const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signatureType, rootUrls }) => {
|
||||
const start = Date.now();
|
||||
const ciDir = getCiFolder();
|
||||
const packagesDir = path.resolve(ciDir, 'packages');
|
||||
@@ -163,11 +165,16 @@ const packagePluginRunner: TaskRunner<PluginCIOptions> = async ({ signingAdmin }
|
||||
});
|
||||
|
||||
// Write a MANIFEST.txt file in the dist folder
|
||||
// By using the --signing-admin flag the plugin doesn't need to be in the plugins database to be signed,
|
||||
// however it requires an Admin API key.
|
||||
try {
|
||||
const grabplCommandFlags = signingAdmin ? ['build-plugin-manifest', '--signing-admin'] : ['build-plugin-manifest'];
|
||||
await execa('grabpl', [...grabplCommandFlags, distContentDir]);
|
||||
const manifest = await buildManifest(distContentDir);
|
||||
if (signatureType) {
|
||||
manifest.signatureType = signatureType;
|
||||
}
|
||||
if (rootUrls) {
|
||||
manifest.rootUrls = rootUrls;
|
||||
}
|
||||
const signedManifest = await signManifest(manifest);
|
||||
await saveManifest(distContentDir, signedManifest);
|
||||
} catch (err) {
|
||||
console.warn(`Error signing manifest: ${distContentDir}`, err);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import path from 'path';
|
||||
import { buildManifest, signManifest, saveManifest } from '../../plugins/manifest';
|
||||
import { Task, TaskRunner } from './task';
|
||||
|
||||
interface PluginSignOptions {
|
||||
signatureType?: string;
|
||||
rootUrls?: string[];
|
||||
}
|
||||
|
||||
const pluginSignRunner: TaskRunner<PluginSignOptions> = async ({ signatureType, rootUrls }) => {
|
||||
const distContentDir = path.resolve('dist');
|
||||
|
||||
try {
|
||||
console.log('Building manifest...');
|
||||
const manifest = await buildManifest(distContentDir);
|
||||
// console.log(manifest);
|
||||
|
||||
console.log('Signing manifest...');
|
||||
if (signatureType) {
|
||||
manifest.signatureType = signatureType;
|
||||
}
|
||||
if (rootUrls) {
|
||||
manifest.rootUrls = rootUrls;
|
||||
}
|
||||
|
||||
const signedManifest = await signManifest(manifest);
|
||||
// console.log(signedManifest);
|
||||
|
||||
console.log('Saving signed manifest...');
|
||||
await saveManifest(distContentDir, signedManifest);
|
||||
|
||||
console.log('Signed successfully');
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
};
|
||||
|
||||
export const pluginSignTask = new Task<PluginSignOptions>('plugin:sign task', pluginSignRunner);
|
||||
Reference in New Issue
Block a user