Commit b34a5b56 by Ryan McKinley Committed by GitHub

Toolkit: use grabpl for manifest (#24319)

parent 376749ee
......@@ -5,7 +5,6 @@ import chalk from 'chalk';
import { startTask } from './tasks/core.start';
import { changelogTask } from './tasks/changelog';
import { cherryPickTask } from './tasks/cherrypick';
import { manifestTask } from './tasks/manifest';
import { precommitTask } from './tasks/precommit';
import { templateTask } from './tasks/template';
import { pluginBuildTask } from './tasks/plugin.build';
......@@ -236,14 +235,6 @@ export const run = (includeInternalScripts = false) => {
await execTask(pluginUpdateTask)({});
});
// Test the manifest creation
program
.command('manifest')
.description('create a manifest file in the cwd')
.action(async cmd => {
await execTask(manifestTask)({ folder: process.cwd() });
});
program.on('command:*', () => {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
......
import { getFilesForManifest, convertSha1SumsToManifest } from './manifest';
describe('Manifest', () => {
it('should collect file paths', () => {
const info = getFilesForManifest(__dirname);
expect(info).toMatchInlineSnapshot(`
Array [
"changelog.ts",
"cherrypick.ts",
"closeMilestone.ts",
"component.create.ts",
"core.start.ts",
"manifest.test.ts",
"manifest.ts",
"nodeVersionChecker.ts",
"package.build.ts",
"plugin/bundle.managed.ts",
"plugin/bundle.ts",
"plugin/create.ts",
"plugin/tests.ts",
"plugin.build.ts",
"plugin.ci.ts",
"plugin.create.ts",
"plugin.dev.ts",
"plugin.tests.ts",
"plugin.update.ts",
"plugin.utils.ts",
"precommit.ts",
"searchTestDataSetup.ts",
"task.ts",
"template.ts",
"toolkit.build.ts",
]
`);
});
it('should convert a sha1 sum to manifest structure', () => {
const sha1output = `7df059597099bb7dcf25d2a9aedfaf4465f72d8d LICENSE
4ebed28a02dc029719296aa847bffcea8eb5b9ff README.md
4493f107eb175b085f020c1afea04614232dc0fd gfx_sheets_darwin_amd64
d8b05884e3829d1389a9c0e4b79b0aba8c19ca4a gfx_sheets_linux_amd64
88f33db20182e17c72c2823fe3bed87d8c45b0fd gfx_sheets_windows_amd64.exe
e6d8f6704dbe85d5f032d4e8ba44ebc5d4a68c43 img/config-page.png
63d79d0e0f9db21ea168324bd4e180d6892b9d2b img/dashboard.png
7ea6295954b24be55b27320af2074852fb088fa1 img/graph.png
262f2bfddb004c7ce567042e8096f9e033c9b1bd img/query-editor.png
f134ab85caff88b59ea903c5491c6a08c221622f img/sheets.svg
40b8c38cea260caed3cdc01d6e3c1eca483ab5c1 module.js
3c04068eb581f73a262a2081f4adca2edbb14edf module.js.map
bfcae42976f0feca58eed3636655bce51702d3ed plugin.json`;
const manifest = convertSha1SumsToManifest(sha1output);
expect(manifest).toMatchInlineSnapshot(`
Object {
"files": Object {
"LICENSE": "7df059597099bb7dcf25d2a9aedfaf4465f72d8d",
"README.md": "4ebed28a02dc029719296aa847bffcea8eb5b9ff",
"gfx_sheets_darwin_amd64": "4493f107eb175b085f020c1afea04614232dc0fd",
"gfx_sheets_linux_amd64": "d8b05884e3829d1389a9c0e4b79b0aba8c19ca4a",
"gfx_sheets_windows_amd64.exe": "88f33db20182e17c72c2823fe3bed87d8c45b0fd",
"img/config-page.png": "e6d8f6704dbe85d5f032d4e8ba44ebc5d4a68c43",
"img/dashboard.png": "63d79d0e0f9db21ea168324bd4e180d6892b9d2b",
"img/graph.png": "7ea6295954b24be55b27320af2074852fb088fa1",
"img/query-editor.png": "262f2bfddb004c7ce567042e8096f9e033c9b1bd",
"img/sheets.svg": "f134ab85caff88b59ea903c5491c6a08c221622f",
"module.js": "40b8c38cea260caed3cdc01d6e3c1eca483ab5c1",
"module.js.map": "3c04068eb581f73a262a2081f4adca2edbb14edf",
"plugin.json": "bfcae42976f0feca58eed3636655bce51702d3ed",
},
"plugin": "<?>",
"version": "<?>",
}
`);
});
});
import { Task, TaskRunner } from './task';
import fs from 'fs';
import path from 'path';
import execa from 'execa';
import { ManifestInfo } from '../../plugins/types';
interface ManifestOptions {
folder: string;
}
export function getFilesForManifest(root: string, work?: string, acc?: string[]): string[] {
if (!acc) {
acc = [];
}
let abs = work ?? root;
const files = fs.readdirSync(abs);
files.forEach(file => {
const f = path.join(abs, file);
const stat = fs.statSync(f);
if (stat.isDirectory()) {
acc = getFilesForManifest(root, f, acc);
} else {
const idx = f.lastIndexOf('.');
if (idx > 0) {
// Don't hash images
const suffix = f.substring(idx + 1).toLowerCase();
if (suffix === 'png' || suffix == 'gif' || suffix === 'svg') {
return;
}
}
acc!.push(f.substring(root.length + 1).replace('\\', '/'));
}
});
return acc;
}
export function convertSha1SumsToManifest(sums: string): ManifestInfo {
const files: Record<string, string> = {};
for (const line of sums.split(/\r?\n/)) {
const idx = line.indexOf(' ');
if (idx > 0) {
const hash = line.substring(0, idx).trim();
const path = line.substring(idx + 1).trim();
files[path] = hash;
}
}
return {
plugin: '<?>',
version: '<?>',
files,
};
}
const manifestRunner: TaskRunner<ManifestOptions> = async ({ folder }) => {
const GRAFANA_API_KEY = process.env.GRAFANA_API_KEY;
if (!GRAFANA_API_KEY) {
console.log('Plugin signing requires a grafana API key');
}
const filename = 'MANIFEST.txt';
const files = getFilesForManifest(folder).filter(f => f !== filename);
// Run sha1sum
const originalDir = __dirname;
process.chdir(folder);
const { stdout } = await execa('sha1sum', files);
process.chdir(originalDir);
// Send the manifest to grafana API
const manifest = convertSha1SumsToManifest(stdout);
const outputPath = path.join(folder, filename);
const pluginPath = path.join(folder, 'plugin.json');
const plugin = require(pluginPath);
const url = `https://grafana.com/api/plugins/${plugin.id}/ci/sign`;
manifest.plugin = plugin.id;
manifest.version = plugin.info.version;
console.log('Request Signature:', url, manifest);
const axios = require('axios');
try {
const info = await axios.post(url, manifest, {
headers: { Authorization: 'Bearer ' + GRAFANA_API_KEY },
responseType: 'arraybuffer',
});
if (info.status === 200) {
console.log('OK: ', info.data);
const buffer = new Buffer(info.data, 'binary');
fs.writeFileSync(outputPath, buffer);
} else {
console.warn('Error: ', info);
console.log('Saving the unsigned manifest');
fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2));
}
} catch (err) {
console.log('ERROR Fetching response', err);
}
};
export const manifestTask = new Task<ManifestOptions>('Build Manifest', manifestRunner);
......@@ -19,8 +19,6 @@ import {
} from '../../plugins/env';
import { agregateWorkflowInfo, agregateCoverageInfo, agregateTestInfo } from '../../plugins/workflow';
import { PluginPackageDetails, PluginBuildReport } from '../../plugins/types';
import { manifestTask } from './manifest';
import { execTask } from '../utils/execTask';
import rimrafCallback from 'rimraf';
import { promisify } from 'util';
const rimraf = promisify(rimrafCallback);
......@@ -165,7 +163,7 @@ const packagePluginRunner: TaskRunner<PluginCIOptions> = async () => {
// Write a manifest.txt file in the dist folder
try {
await execTask(manifestTask)({ folder: distContentDir });
await execa('grabpl', ['build-plugin-manifest', distContentDir]);
} catch (err) {
console.warn(`Error signing manifest: ${distContentDir}`, err);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment