Skip to content
26 changes: 20 additions & 6 deletions .github/workflows/deploy-standalone-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ on:
slug:
type: string
description: 'The slug of the plugin to deploy'
version:
type: string
description: 'The version of the plugin to deploy'

jobs:
release:
name: Prepare Deployment
Expand All @@ -21,12 +17,30 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js (.nvmrc)
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: npm
- name: Install npm dependencies
run: npm ci
- name: Get plugin version
id: get-version
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT
- name: Set matrix
id: set-matrix
run: |
if ${{ github.event_name == 'workflow_dispatch' }}; then
# Set the manual input values in JSON format for use in the matrix.
echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"version\":\"${{ inputs.version }}\"}]}" >> $GITHUB_OUTPUT
result=$(echo "${{ steps.get-version.outputs.version }}" | awk '/^(\*|[0-9]+(\.[0-9]+){0,2}(-[a-zA-Z0-9.]+)?)$/ {print "Matched"}')
if [[ -n "$result" ]]; then
# Set the manual input values in JSON format for use in the matrix.
echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"version\":\"${{ steps.get-version.outputs.version }}\"}]}" >> $GITHUB_OUTPUT
else
echo "The ${{ inputs.slug }} module slug is missing in the file plugins.json."
exit 1
fi
else
# Load the JSON file and parse from "{name: {slug, version}, ...}" to "include: [{ name, slug, version }, ...]"
# for use in the matrix.
Expand Down
11 changes: 11 additions & 0 deletions bin/plugin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ const {
handler: testPluginsHandler,
options: testPluginsOptions,
} = require( './commands/test-plugins' );
const {
handler: getPluginVersionHandler,
options: getPluginVersionOptions,
} = require( './commands/get-plugin-version' );
const {
handler: enabledModulesHandler,
options: enabledModulesOptions,
Expand Down Expand Up @@ -92,6 +96,13 @@ withOptions( program.command( 'test-standalone-plugins' ), testPluginsOptions )
)
.action( catchException( testPluginsHandler ) );

withOptions( program.command( 'get-standalone-plugin-version' ), getPluginVersionOptions )
.alias( 'get-plugin-version' )
.description(
'Get standalone plugin version'
)
.action( catchException( getPluginVersionHandler ) );

withOptions(
program.command( 'default-enabled-modules' ),
enabledModulesOptions
Expand Down
76 changes: 76 additions & 0 deletions bin/plugin/commands/get-plugin-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );

/**
* Internal dependencies
*/
const { log } = require( '../lib/logger' );

exports.options = [
{
argname: '-s, --slug <slug>',
description: 'Standalone plugin slug to get version from plugins.json',
},
];

/**
* Command to get the plugin version based on the slug.
*
* @param {Object} opt Command options.
*/
exports.handler = async ( opt ) => {
doRunGetPluginVersion( {
pluginsJsonFile: 'plugins.json', // Path to plugins.json file.
slug: opt.slug, // Plugin slug.
} );
};

/**
* Returns the match plugin version from plugins.json file.
*
* @param {Object} settings Plugin settings.
*/
function doRunGetPluginVersion( settings ) {
if ( settings.slug === undefined ) {
throw Error( 'A slug must be provided via the --slug (-s) argument.' );
}

const pluginsFile = path.join( '.', settings.pluginsJsonFile );

// Buffer contents of plugins JSON file.
let pluginsFileContent = '';

try {
pluginsFileContent = fs.readFileSync( pluginsFile, 'utf-8' );
} catch ( e ) {
throw Error( `Error reading file at "${ pluginsFile }": ${ e }` );
}

// Validate that the plugins JSON file contains content before proceeding.
if ( ! pluginsFileContent ) {
throw Error( `Contents of file at "${ pluginsFile }" could not be read, or are empty.` );
}

const plugins = JSON.parse( pluginsFileContent );

// Check for valid and not empty object resulting from plugins JSON file parse.
if (
'object' !== typeof plugins ||
0 === Object.keys( plugins ).length
) {
throw Error( `File at "${ pluginsFile }" parsed, but detected empty/non valid JSON object.` );
}

for ( const moduleDir in plugins ) {
const pluginVersion = plugins[ moduleDir ]?.version;
const pluginSlug = plugins[ moduleDir ]?.slug;
if ( pluginVersion && pluginSlug && ( settings.slug === pluginSlug ) ) {
return log( pluginVersion );
}
}

throw Error( `The "${ settings.slug }" module slug is missing in the file "${ pluginsFile }".` );
}