add stubs for each ci task

This commit is contained in:
ryan
2019-07-08 16:00:06 -07:00
parent 42e7cd7d65
commit e7d1f1df14
4 changed files with 187 additions and 26 deletions
+1
View File
@@ -28,6 +28,7 @@
"@types/node": "^12.0.4",
"@types/react-dev-utils": "^9.0.1",
"@types/semver": "^6.0.0",
"@types/tmp": "^0.1.0",
"@types/webpack": "4.4.34",
"axios": "0.19.0",
"babel-loader": "8.0.6",
+29 -6
View File
@@ -15,7 +15,7 @@ import { pluginTestTask } from './tasks/plugin.tests';
import { searchTestDataSetupTask } from './tasks/searchTestDataSetup';
import { closeMilestoneTask } from './tasks/closeMilestone';
import { pluginDevTask } from './tasks/plugin.dev';
import { pluginCITask } from './tasks/plugin.ci';
import { ciBuildPluginTask, ciBundlePluginTask, ciTestPluginTask, ciDeployPluginTask } from './tasks/plugin.ci';
export const run = (includeInternalScripts = false) => {
if (includeInternalScripts) {
@@ -154,15 +154,38 @@ export const run = (includeInternalScripts = false) => {
});
program
.command('plugin:ci')
.option('--dryRun', "Dry run (don't post results)")
.description('Run Plugin CI task')
.command('plugin:ci-build')
.option('--platform', 'For backend task, which backend to run')
.description('Build the plugin, leaving artifacts in /dist')
.action(async cmd => {
await execTask(pluginCITask)({
dryRun: cmd.dryRun,
await execTask(ciBuildPluginTask)({
platform: cmd.platform,
});
});
program
.command('plugin:ci-bundle')
.description('Create a zip artifact for the plugin')
.action(async cmd => {
await execTask(ciBundlePluginTask)({});
});
program
.command('plugin:ci-test')
.description('end-to-end test using bundle in /artifacts')
.action(async cmd => {
await execTask(ciTestPluginTask)({
platform: cmd.platform,
});
});
program
.command('plugin:ci-deploy')
.description('Publish plugin CI results')
.action(async cmd => {
await execTask(ciDeployPluginTask)({});
});
program.on('command:*', () => {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
@@ -8,9 +8,10 @@ import { getPluginJson } from '../../config/utils/pluginValidation';
import execa = require('execa');
import path = require('path');
import fs = require('fs');
import tmp = require('tmp');
export interface PluginCIOptions {
dryRun?: boolean;
platform?: string;
}
const calcJavascriptSize = (base: string, files?: string[]): number => {
@@ -33,22 +34,74 @@ const calcJavascriptSize = (base: string, files?: string[]): number => {
return size;
};
const pluginCIRunner: TaskRunner<PluginCIOptions> = async ({ dryRun }) => {
/**
* 1. BUILD
*
* when platform exists it is building backend, otherwise frontend
*
* Everything in /build folder
*
*/
const buildPluginRunner: TaskRunner<PluginCIOptions> = async ({ platform }) => {
const start = Date.now();
const distDir = `${process.cwd()}/dist`;
const artifactsDir = `${process.cwd()}/artifacts`;
await execa('rimraf', [`${process.cwd()}/coverage`]);
await execa('rimraf', [artifactsDir]);
const buildDir = `${process.cwd()}/build`;
const coverageDir = `${process.cwd()}/coverage`;
if (!fs.existsSync(buildDir)) {
fs.mkdirSync(buildDir);
}
if (platform) {
console.log('TODO, backend support?');
const stub = distDir + `/bin_${platform}`;
if (!fs.existsSync(stub)) {
fs.mkdirSync(stub);
}
fs.writeFile(stub + '/README.txt', 'TODO... build it!', err => {
if (err) {
throw new Error('Unable to write: ' + stub);
}
});
} else {
// Do regular build process
await pluginBuildRunner({ coverage: true });
}
// Move dist & coverage into 'build'
fs.renameSync(distDir, path.resolve(buildDir, 'dist'));
fs.renameSync(coverageDir, path.resolve(buildDir, 'coverage'));
// Do regular build process
await pluginBuildRunner({ coverage: true });
const elapsed = Date.now() - start;
const stats = {
job: `${process.env.CIRCLE_JOB}`,
sha1: `${process.env.CIRCLE_SHA1}`,
startTime: start,
buildTime: elapsed,
endTime: Date.now(),
};
console.log('BUILD Info', stats);
};
export const ciBuildPluginTask = new Task<PluginCIOptions>('Build Plugin', buildPluginRunner);
/**
* 2. BUNDLE
*
* Take everything from /build/dist and zip it up
*
*/
const bundlePluginRunner: TaskRunner<PluginCIOptions> = async () => {
const start = Date.now();
const distDir = `${process.cwd()}/build/dist`;
if (!fs.existsSync(distDir)) {
throw new Error('Dist folder does not exist: ' + distDir);
}
const artifactsDir = `${process.cwd()}/build/artifacts`;
if (!fs.existsSync(artifactsDir)) {
fs.mkdirSync(artifactsDir);
}
// TODO? can this typed from @grafana/ui?
const pluginInfo = getPluginJson(`${distDir}/plugin.json`);
const zipName = pluginInfo.id + '-' + pluginInfo.info.version + '.zip';
const zipFile = path.resolve(artifactsDir, zipName);
@@ -56,23 +109,95 @@ const pluginCIRunner: TaskRunner<PluginCIOptions> = async ({ dryRun }) => {
await execa('zip', ['-r', zipFile, '.']);
restoreCwd();
const zipStats = fs.statSync(zipFile);
if (zipStats.size < 100) {
throw new Error('Invalid zip file: ' + zipFile);
}
const stats = {
startTime: start,
buildTime: elapsed,
jsSize: calcJavascriptSize(distDir),
zipSize: fs.statSync(zipFile).size,
endTime: Date.now(),
name: zipName,
size: zipStats.size,
};
fs.writeFile(artifactsDir + '/stats.json', JSON.stringify(stats, null, 2), err => {
fs.writeFile(artifactsDir + '/info.json', JSON.stringify(stats, null, 2), err => {
if (err) {
throw new Error('Unable to write stats');
}
console.log('Stats', stats);
console.log('Created', stats);
});
if (!dryRun) {
console.log('TODO send info to github?');
}
};
export const pluginCITask = new Task<PluginCIOptions>('Plugin CI', pluginCIRunner);
export const ciBundlePluginTask = new Task<PluginCIOptions>('Bundle Plugin', bundlePluginRunner);
/**
* 3. Test (end-to-end)
*
* deploy the zip to a running grafana instance
*
*/
const testPluginRunner: TaskRunner<PluginCIOptions> = async ({ platform }) => {
const start = Date.now();
const artifactsDir = `${process.cwd()}/build/artifacts`;
const infoFile = path.resolve(artifactsDir, 'info.json');
const zipInfo = require(infoFile);
const zipPath = path.resolve(artifactsDir, zipInfo.name);
const tmpobj = tmp.dirSync();
const pluginFolder = tmpobj.name;
console.log('Temp Folder', pluginFolder);
await execa('unzip', [zipPath, '-d', pluginFolder]);
const { stdout } = await execa('ls', ['-Rl', pluginFolder]);
console.log(stdout);
// Manual cleanup
tmpobj.removeCallback();
fs.mkdirSync(pluginFolder, { recursive: true });
const elapsed = Date.now() - start;
const stats = {
job: `${process.env.CIRCLE_JOB}`,
sha1: `${process.env.CIRCLE_SHA1}`,
startTime: start,
buildTime: elapsed,
endTime: Date.now(),
};
console.log('TODO Test', stats);
};
export const ciTestPluginTask = new Task<PluginCIOptions>('Test Plugin (e2e)', testPluginRunner);
/**
* 4. Deploy
*
* deploy the zip to a running grafana instance
*
*/
const deployPluginRunner: TaskRunner<PluginCIOptions> = async () => {
const start = Date.now();
// TASK Time
if (process.env.CIRCLE_INTERNAL_TASK_DATA) {
const timingInfo = fs.readdirSync(`${process.env.CIRCLE_INTERNAL_TASK_DATA}`);
if (timingInfo) {
timingInfo.forEach(file => {
console.log('TIMING INFO: ', file);
});
}
}
const elapsed = Date.now() - start;
const stats = {
job: `${process.env.CIRCLE_JOB}`,
sha1: `${process.env.CIRCLE_SHA1}`,
startTime: start,
buildTime: elapsed,
endTime: Date.now(),
};
console.log('TODO DEPLOY', stats);
};
export const ciDeployPluginTask = new Task<PluginCIOptions>('Deploy plugin', deployPluginRunner);
+12
View File
@@ -2568,6 +2568,11 @@
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
integrity sha512-PeHg/AtdW6aaIO2a+98Xj7rWY4KC1E6yOy7AFknJQ7VXUGNrMlyxDFxJo7HqLtjQms/ZhhQX52mLVW/EX3JGOw==
"@types/tmp@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.1.0.tgz#19cf73a7bcf641965485119726397a096f0049bd"
integrity sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA==
"@types/uglify-js@*":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"
@@ -15752,6 +15757,13 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
tmp@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877"
integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==
dependencies:
rimraf "^2.6.3"
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"