Skip to content

Commit

Permalink
Extends plugin-helpers to be used for automating version changes
Browse files Browse the repository at this point in the history
Signed-off-by: Miki <[email protected]>
  • Loading branch information
AMoo-Miki committed Sep 21, 2022
1 parent 77af7f9 commit 0302300
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 30 deletions.
59 changes: 37 additions & 22 deletions packages/osd-plugin-helpers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ yarn osd bootstrap

## Usage

This simple CLI has a build task that plugin devs can run from to easily package OpenSearch Dashboards plugins.
This CLI has a `build` command that plugin devs can run to easily package OpenSearch Dashboards plugins. Called with the `version`
command, a plugin's manifest and package files can be updated to match the version of OpenSearch Dashboards or one supplied.

Previously you could also use that tool to start and test your plugin. Currently you can run
your plugin along with OpenSearch Dashboards running `yarn start` in the OpenSearch Dashboards repository root folder. Finally to test
Previously you could also use that tool to start and test your plugin. Currently, you can run
your plugin along with OpenSearch Dashboards running `yarn start` in the OpenSearch Dashboards repository root folder. Finally, to test
your plugin you should now configure and use your own tools.

```sh
Expand All @@ -37,37 +38,44 @@ $ plugin-helpers help
Usage: plugin-helpers [command] [options]

Commands:
build
Copies files from the source into a zip archive that can be distributed for
installation into production OpenSearch Dashboards installs. The archive includes the non-
development npm dependencies and builds itself using raw files in the source
directory so make sure they are clean/up to date. The resulting archive can
be found at:
build
Copies files from the source into a zip archive that can be distributed for
installation into production OpenSearch Dashboards installs. The archive includes the non-
development npm dependencies and builds itself using raw files in the source
directory so make sure they are clean/up to date. The resulting archive can
be found at:

build/{plugin.id}-{opensearchDashboardsVersion}.zip

Options:
--skip-archive Don't create the zip file, just create the build/opensearch-dashboards directory
--opensearch-dashboards-version, -v OpenSearch Dashboards version that the
version
Updates the version to a provided parameter, or syncs it with the version of OpenSearch Dashboards
build/{plugin.id}-{opensearchDashboardsVersion}.zip

Options:
--skip-archive Don't create the zip file, just create the build/opensearch-dashboards directory
--opensearch-dashboards-version, -v OpenSearch Dashboards version that the
Options:
--sync Update the versions to match Dashboards' (default)
--set Update the version to a specific value


Global options:
--verbose, -v Log verbosely
--debug Log debug messages (less than verbose)
--quiet Only log errors
--silent Don't log anything
--help Show this message
--verbose, -v Log verbosely
--debug Log debug messages (less than verbose)
--quiet Only log errors
--silent Don't log anything
--help Show this message
```
## Versions
The plugins helpers in the OpenSearch Dashboards repo are available for OpenSearch Dashboards 1.0 and greater. Just checkout the branch of OpenSearch Dashboards you want to build against and the plugin helpers should be up to date for that version of OpenSearch Dashboards.
The plugins helpers in the OpenSearch Dashboards repo are available for OpenSearch Dashboards 1.0 and greater. Just checkout the branch of OpenSearch Dashboards you want to build against and the plugin helpers should be up-to-date for that version of OpenSearch Dashboards.
## Configuration
`plugin-helpers` accepts a number of settings, which can be specified at runtime, or included in a `.opensearch_dashboards-plugin-helpers.json` file if you'd like to bundle those settings with your project.
`plugin-helpers` accepts a number of settings for the `build` command which can be specified at runtime or included in a `.opensearch_dashboards-plugin-helpers.json` file if you'd like to bundle those settings with your project.

It will also observe a `.opensearch_dashboards-plugin-helpers.dev.json`, much like OpenSearch Dashboards does, which we encourage you to add to your `.gitignore` file and use for local settings that you don't intend to share. These "dev" settings will override any settings in the normal json config.

Expand All @@ -84,6 +92,13 @@ Setting | Description
`skipInstallDependencies` | Don't install dependencies defined in package.json into build output
`opensearchDashboardsVersion` | OpenSearch Dashboards version for the build output (added to package.json)

### Settings for `version`

Setting | Description
------- | -----------
`sync` | As the default behavior, it uses the version of OpenSearch Dashboards to update the plugin's manifest and package files.
`set` | Defines the version to be used in the manifest and package files.
## TypeScript support
Plugin code can be written in [TypeScript](http://www.typescriptlang.org/) if desired. To enable TypeScript support create a `tsconfig.json` file at the root of your plugin that looks something like this:
Expand Down
62 changes: 60 additions & 2 deletions packages/osd-plugin-helpers/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ import { RunWithCommands, createFlagError, createFailError } from '@osd/dev-util
import { findOpenSearchDashboardsJson } from './find_opensearch_dashboards_json';
import { loadOpenSearchDashboardsPlatformPlugin } from './load_opensearch_dashboards_platform_plugin';
import * as Tasks from './tasks';
import { BuildContext } from './build_context';
import { BuildContext, VersionContext } from './contexts';
import { resolveOpenSearchDashboardsVersion } from './resolve_opensearch_dashboards_version';
import { loadConfig } from './config';

const VERSION_PARAM_MATCH_DASHBOARDS = 'sync';
const VERSION_PARAM_MATCH_INPUT = 'set';

export function runCli() {
new RunWithCommands({
description: 'Some helper tasks for plugin-authors',
Expand All @@ -62,7 +65,7 @@ export function runCli() {
k: 'opensearch-dashboards-version',
},
help: `
--skip-archive Don't create the zip file, just create the build/opensearch-dashboards directory
--skip-archive Don't create the zip file, just create the build/opensearch-dashboards directory
--opensearch-dashboards-version, -v OpenSearch version that the
`,
},
Expand Down Expand Up @@ -118,5 +121,60 @@ export function runCli() {
}
},
})
.command({
name: 'version',
description: `
Updates the version to a provided parameter, or syncs it with the version of OpenSearch Dashboards
`,
flags: {
boolean: ['sync'],
string: ['set'],
help: `
--${VERSION_PARAM_MATCH_DASHBOARDS} Update the versions to match Dashboards' (default)
--${VERSION_PARAM_MATCH_INPUT} Update the version to a specific value
`,
},
async run({ log, flags }) {
const pluginDir = await findOpenSearchDashboardsJson(process.cwd());
if (!pluginDir) {
throw createFailError(
`Unable to find OpenSearch Dashboards Platform plugin in [${process.cwd()}] or any of its parent directories. Has it been migrated properly? Does it have a opensearch_dashboards.json file?`
);
}

let versionValue = flags[VERSION_PARAM_MATCH_INPUT];
if (versionValue !== undefined) {
if (typeof versionValue !== 'string')
throw createFlagError(`expected a single --${VERSION_PARAM_MATCH_INPUT} flag`);
if (versionValue && !/^\d+\.\d+\.\d+(-\S+)?$/.test(versionValue))
throw createFlagError(
`expected a valid version following the --${VERSION_PARAM_MATCH_INPUT} flag`
);
}

const doSync = flags[VERSION_PARAM_MATCH_DASHBOARDS];
if (doSync !== undefined && typeof doSync !== 'boolean') {
throw createFlagError(`expected a single --${VERSION_PARAM_MATCH_DASHBOARDS} flag`);
}

if (!versionValue || doSync) {
const dashBoardsPackage = await import(Path.join(process.cwd(), '../../package.json'));
versionValue = dashBoardsPackage?.version;

if (typeof versionValue !== 'string' || !/^\d+\.\d+\.\d+(-\S+)?$/.test(versionValue))
throw createFailError(
`Failed to extract version from Dashboards: ${dashBoardsPackage?.version}`
);
}

const context: VersionContext = {
log,
sourceDir: process.cwd(),
newVersion: versionValue,
};

await Tasks.updateVersions(context);
},
})
.execute();
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,24 @@ export interface BuildContext {
buildDir: string;
opensearchDashboardsVersion: string;
}

export interface VersionContext {
log: ToolingLog;
sourceDir: string;
newVersion: string;
}

interface NestedObject {
[key: string]: NestedObject | string;
}

export interface FileUpdateContext {
log: ToolingLog;
file: string;
updates: NestedObject;
}

export interface ObjectUpdateContext {
original: { [key: string]: any };
updates: NestedObject;
}
2 changes: 1 addition & 1 deletion packages/osd-plugin-helpers/src/tasks/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { promisify } from 'util';

import del from 'del';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const asyncMkdir = promisify(Fs.mkdir);

Expand Down
2 changes: 1 addition & 1 deletion packages/osd-plugin-helpers/src/tasks/create_archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import del from 'del';
import vfs from 'vinyl-fs';
import zip from 'gulp-zip';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const asyncPipeline = promisify(pipeline);

Expand Down
1 change: 1 addition & 0 deletions packages/osd-plugin-helpers/src/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
export * from './clean';
export * from './create_archive';
export * from './optimize';
export * from './update_versions';
export * from './write_public_assets';
export * from './write_server_files';
export * from './yarn_install';
2 changes: 1 addition & 1 deletion packages/osd-plugin-helpers/src/tasks/optimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { promisify } from 'util';
import { REPO_ROOT } from '@osd/utils';
import { OptimizerConfig, runOptimizer, logOptimizerState } from '@osd/optimizer';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const asyncRename = promisify(Fs.rename);

Expand Down
95 changes: 95 additions & 0 deletions packages/osd-plugin-helpers/src/tasks/update_versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

// @ts-ignore
import { readFile, writeFile } from 'fs/promises';
import path from 'path';
import { createFailError } from '@osd/dev-utils';
import { FileUpdateContext, ObjectUpdateContext, VersionContext } from '../contexts';

export async function updateVersions({
log,
sourceDir,
newVersion,
}: VersionContext): Promise<boolean | undefined> {
if (!newVersion) throw createFailError('Missing new version value');
if (!/^\d+\.\d+\.\d+/.test(newVersion))
throw createFailError('The new version is not a valid semantic version');

const cleanVersion = newVersion.replace(/^(\d+\.\d+\.\d+)(-.*)?$/, '$1');

const updateManifestFile = updateFile({
log,
file: path.join(sourceDir, 'opensearch_dashboards.json'),
updates: {
version: `${cleanVersion}.0`,
opensearchDashboardsVersion: cleanVersion,
},
});

const updatePackageJson = updateFile({
log,
file: path.join(sourceDir, 'package.json'),
updates: {
version: `${cleanVersion}.0`,
opensearchDashboards: {
version: cleanVersion,
templateVersion: cleanVersion,
},
},
});

await Promise.all([updateManifestFile, updatePackageJson]);

return true;
}

async function updateFile({ log, file, updates }: FileUpdateContext) {
log.info('Updating', file);

let json;

try {
json = JSON.parse(await readFile(file, 'utf8'));
} catch (ex) {
log.error(ex);
throw createFailError(`Failed to parse ${file}`);
}

const context: ObjectUpdateContext = {
original: json,
updates,
};
updateObject(context);

try {
await writeFile(file, JSON.stringify(json, null, 2), 'utf8');
} catch (ex) {
log.error(ex);
throw createFailError(`Failed to update ${file}`);
}

log.success(`Updated`, file);
}

// Copies values in `updates` onto `obj` only if the keys exist
function updateObject({ original, updates }: ObjectUpdateContext) {
for (const key in updates) {
if (!updates[key]) continue;

// If `key` is not found in `original`, just skip it
if (key in original) {
// If both are objects, merge them
if (updates[key] === 'object' && typeof original[key] === 'object') {
updateObject({
original: original[key],
updates: updates[key],
} as ObjectUpdateContext);
} else {
original[key] = updates[key];
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { promisify } from 'util';

import vfs from 'vinyl-fs';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const asyncPipeline = promisify(pipeline);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { promisify } from 'util';
import vfs from 'vinyl-fs';
import { transformFileWithBabel, transformFileStream } from '@osd/dev-utils';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const asyncPipeline = promisify(pipeline);

Expand Down
2 changes: 1 addition & 1 deletion packages/osd-plugin-helpers/src/tasks/yarn_install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import Path from 'path';

import execa from 'execa';

import { BuildContext } from '../build_context';
import { BuildContext } from '../contexts';

const winVersion = (path: string) => (process.platform === 'win32' ? `${path}.cmd` : path);

Expand Down

0 comments on commit 0302300

Please sign in to comment.