From 2841611d8b59f0b18056ae50281d6f6c5489dcb0 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 13 Feb 2024 09:17:26 +0530 Subject: [PATCH 01/10] POC --- .../workflows/deploy-standalone-plugins.yml | 34 +++++-- bin/plugin/cli.js | 9 ++ bin/plugin/commands/get-plugin-dir.js | 94 +++++++++++++++++++ bin/plugin/commands/test-plugins.js | 42 +++++++-- 4 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 bin/plugin/commands/get-plugin-dir.js diff --git a/.github/workflows/deploy-standalone-plugins.yml b/.github/workflows/deploy-standalone-plugins.yml index 846adacb04..287f35f04d 100644 --- a/.github/workflows/deploy-standalone-plugins.yml +++ b/.github/workflows/deploy-standalone-plugins.yml @@ -1,6 +1,17 @@ name: Deploy standalone plugins to WordPress.org on: + pull_request: + branches: + - trunk + - 'release/**' + - 'feature/**' + paths: + - '.github/workflows/deploy-standalone-plugins.yml' + types: + - opened + - reopened + - synchronize release: types: [published] workflow_dispatch: @@ -28,11 +39,18 @@ jobs: cache: npm - name: Install npm dependencies run: npm ci + - name: Get directory + id: get-plugin-directory + if: ${{ github.event_name == 'workflow_dispatch' }} + run: | + echo "directory=$(node ./bin/plugin/cli.js get-plugin-dir --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT - name: Get plugin version id: get-version - if: ${{ github.event_name == 'workflow_dispatch' }} + if: ${{ github.event_name == 'workflow_dispatch' && steps.get-plugin-directory.outputs.directory == 'build' }} run: | - echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT + if [[ ${{ steps.get-type.outputs.type }} == 'module' ]]; then + echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT + fi - name: Set matrix id: set-matrix run: | @@ -40,7 +58,7 @@ jobs: 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 }}\",\"dry-run\":\"${{ inputs.dry-run }}\"}]}" >> $GITHUB_OUTPUT + echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"version\":\"${{ steps.get-version.outputs.version }}\",,\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"${{ inputs.dry-run }}\"}]}" >> $GITHUB_OUTPUT else echo "The ${{ inputs.slug }} module slug is missing in the file plugins.json." exit 1 @@ -50,7 +68,7 @@ jobs: # for use in the matrix. # The "dry-run" parameter is included here to set the deployment mode. # When running the manual (workflow_dispatch) workflow, this value will be set from manual input type. - echo "matrix="$(jq -c '{include:[.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,"dry-run":false }]}' plugins.json) >> $GITHUB_OUTPUT + echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":false }] + [.plugins[] | {slug:. , directory:"plugins", "dry-run":false}])}' plugins.json)" >> $GITHUB_OUTPUT fi deploy: name: Deploy Plugin @@ -75,9 +93,9 @@ jobs: with: dry-run: ${{ matrix.dry-run }} env: - SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} - SVN_USERNAME: ${{ secrets.SVN_USERNAME }} + #SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} + #SVN_USERNAME: ${{ secrets.SVN_USERNAME }} SLUG: ${{ matrix.slug }} VERSION: ${{ matrix.version }} - BUILD_DIR: ./build/${{ matrix.slug }} - ASSETS_DIR: ./build/${{ matrix.slug }}/.wordpress-org + BUILD_DIR: ./${{ matrix.directory }}/${{ matrix.slug }} + ASSETS_DIR: ./${{ matrix.directory }}/${{ matrix.slug }}/.wordpress-org diff --git a/bin/plugin/cli.js b/bin/plugin/cli.js index 463f16ce2d..04dabfd2c2 100755 --- a/bin/plugin/cli.js +++ b/bin/plugin/cli.js @@ -50,6 +50,10 @@ const { handler: getPluginVersionHandler, options: getPluginVersionOptions, } = require( './commands/get-plugin-version' ); +const { + handler: getPluginDirHandler, + options: getPluginDirOptions, +} = require( './commands/get-plugin-dir' ); const { handler: enabledModulesHandler, options: enabledModulesOptions, @@ -102,6 +106,11 @@ withOptions( .description( 'Get standalone plugin version' ) .action( catchException( getPluginVersionHandler ) ); +withOptions( program.command( 'get-plugin-dir' ), getPluginDirOptions ) + .alias( 'get-plugin-directory' ) + .description( 'Get plugin directory' ) + .action( catchException( getPluginDirHandler ) ); + withOptions( program.command( 'default-enabled-modules' ), enabledModulesOptions diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js new file mode 100644 index 0000000000..cb0e5a0703 --- /dev/null +++ b/bin/plugin/commands/get-plugin-dir.js @@ -0,0 +1,94 @@ +/** + * External dependencies + */ +const fs = require( 'fs' ); +const path = require( 'path' ); + +/** + * Internal dependencies + */ +const { log } = require( '../lib/logger' ); + +exports.options = [ + { + argname: '-s, --slug ', + description: 'Plugin or Standalone module/plugin slug to get directory', + }, +]; + +/** + * Command to get directory for plugin/module based on the slug. + * + * @param {Object} opt Command options. + */ +exports.handler = async ( opt ) => { + doRunGetPluginDir( { + pluginsJsonFile: 'plugins.json', // Path to plugins.json file. + slug: opt.slug, // Plugin slug. + } ); +}; + +/** + * Returns directory for plugin or module based on the slug. + * + * @param {Object} settings Plugin settings. + */ +function doRunGetPluginDir( 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 pluginsConfig = JSON.parse( pluginsFileContent ); + + // Check for valid and not empty object resulting from plugins JSON file parse. + if ( + 'object' !== typeof pluginsConfig || + 0 === Object.keys( pluginsConfig ).length + ) { + throw Error( + `File at "${ pluginsFile }" parsed, but detected empty/non valid JSON object.` + ); + } + + const stPlugins = pluginsConfig.modules; + if ( stPlugins ) { + for ( const moduleDir in stPlugins ) { + const pluginVersion = stPlugins[ moduleDir ]?.version; + const pluginSlug = stPlugins[ moduleDir ]?.slug; + if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { + return log( 'build' ); + } + } + } + + const plugins = pluginsConfig.plugins; + if ( plugins ) { + for ( const plugin in plugins ) { + if ( plugins[ plugin ] && settings.slug === plugins[ plugin ] ) { + return log( 'plugins' ); + } + } + } + + throw Error( + `The "${ settings.slug }" module slug is missing in the file "${ pluginsFile }".` + ); +} diff --git a/bin/plugin/commands/test-plugins.js b/bin/plugin/commands/test-plugins.js index c3d62e3669..a73034361a 100644 --- a/bin/plugin/commands/test-plugins.js +++ b/bin/plugin/commands/test-plugins.js @@ -41,6 +41,7 @@ const { log, formats } = require( '../lib/logger' ); * @property {string} siteType Site type. 'single' or 'multi'. * @property {string} pluginTestAssets Path to 'plugin-tests' folder. * @property {string} builtPluginsDir Path to 'build' directory. + * @property {string} pluginsDir Path to 'plugins' directory. * @property {string} wpEnvFile Path to the plugin tests specific .wp-env.json file. * @property {string} wpEnvDestinationFile Path to the final base .wp-env.json file. * @property {string} performancePluginSlug Slug of the main WPP plugin. @@ -71,6 +72,7 @@ exports.handler = async ( opt ) => { siteType: opt.sitetype || 'single', // Site type. pluginTestAssets: './plugin-tests', // plugin test assets. builtPluginsDir: './build/', // Built plugins directory. + pluginsDir: './plugins/', // Plugins directory. wpEnvFile: './plugin-tests/.wp-env.json', // Base .wp-env.json file for testing plugins. wpEnvDestinationFile: './.wp-env.override.json', // Destination .wp-env.override.json file at root level. wpEnvPluginsRegexPattern: '"plugins": \\[(.*)\\],', // Regex to match plugins string in .wp-env.json. @@ -445,8 +447,8 @@ function doRunStandalonePluginTests( settings ) { process.exit( 1 ); } - const plugins = pluginsConfig.modules; - if ( ! plugins ) { + const stPlugins = pluginsConfig.modules; + if ( ! stPlugins ) { log( formats.error( 'The given module configuration is invalid, the modules are missing, or they are misspelled.' @@ -458,23 +460,51 @@ function doRunStandalonePluginTests( settings ) { } // Create an array of plugins from entries in plugins JSON file. - builtPlugins = Object.keys( plugins ) + builtPlugins = Object.keys( stPlugins ) .filter( ( item ) => { if ( ! fs.pathExistsSync( - `${ settings.builtPluginsDir }${ plugins[ item ].slug }` + `${ settings.builtPluginsDir }${ stPlugins[ item ].slug }` ) ) { log( formats.error( - `Built plugin path "${ settings.builtPluginsDir }${ plugins[ item ].slug }" not found, skipping and removing from plugin list` + `Built plugin path "${ settings.builtPluginsDir }${ stPlugins[ item ].slug }" not found, skipping and removing from plugin list` ) ); return false; } return true; } ) - .map( ( item ) => plugins[ item ].slug ); + .map( ( item ) => stPlugins[ item ].slug ); + + // Append plugins into array. + const plugins = pluginsConfig.plugins; + if ( plugins && Object.keys( plugins ).length > 0 ) { + plugins.forEach( ( plugin ) => { + // Copy plugins to build for testing. + try { + fs.copySync( + `${ settings.pluginsDir }${ plugin }/`, + `${ settings.builtPluginsDir }${ plugin }/`, + { + overwrite: true, + } + ); + log( formats.success( `Copied plugin "${ plugin }".\n` ) ); + builtPlugins = builtPlugins.concat( plugin ); + } catch ( e ) { + log( + formats.error( + `Error copying plugin "${ plugin }". ${ e }` + ) + ); + + // Return with exit code 1 to trigger a failure in the test pipeline. + process.exit( 1 ); + } + } ); + } // For each built plugin, copy the test assets. builtPlugins.forEach( ( plugin ) => { From 2a0c8006073bd5e77c850e7937104589c19b3c2b Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 19 Feb 2024 14:56:54 +0530 Subject: [PATCH 02/10] Update manual workflow --- .../workflows/deploy-standalone-plugins.yml | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-standalone-plugins.yml b/.github/workflows/deploy-standalone-plugins.yml index 287f35f04d..c0cd3ebc24 100644 --- a/.github/workflows/deploy-standalone-plugins.yml +++ b/.github/workflows/deploy-standalone-plugins.yml @@ -1,6 +1,7 @@ name: Deploy standalone plugins to WordPress.org on: + # TODO The pull_request will be removed once the workflow is tested. pull_request: branches: - trunk @@ -48,17 +49,18 @@ jobs: id: get-version if: ${{ github.event_name == 'workflow_dispatch' && steps.get-plugin-directory.outputs.directory == 'build' }} run: | - if [[ ${{ steps.get-type.outputs.type }} == 'module' ]]; then - echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT - fi + 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 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 }}\",,\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"${{ inputs.dry-run }}\"}]}" >> $GITHUB_OUTPUT + if ${{ steps.get-plugin-directory.outputs.directory == 'plugins' }}; then + # Set the manual input values in JSON format for use in the matrix for plugins. + echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"true\"}]}" >> $GITHUB_OUTPUT + elif [[ -n "$result" ]]; then + # Set the manual input values in JSON format for use in the matrix for modules. + echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"version\":\"${{ steps.get-version.outputs.version }}\",\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"true\"}]}" >> $GITHUB_OUTPUT else echo "The ${{ inputs.slug }} module slug is missing in the file plugins.json." exit 1 @@ -68,7 +70,7 @@ jobs: # for use in the matrix. # The "dry-run" parameter is included here to set the deployment mode. # When running the manual (workflow_dispatch) workflow, this value will be set from manual input type. - echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":false }] + [.plugins[] | {slug:. , directory:"plugins", "dry-run":false}])}' plugins.json)" >> $GITHUB_OUTPUT + echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":true }] + [.plugins[] | {slug:. , directory:"plugins", "dry-run":true}])}' plugins.json)" >> $GITHUB_OUTPUT fi deploy: name: Deploy Plugin @@ -93,8 +95,12 @@ jobs: with: dry-run: ${{ matrix.dry-run }} env: + # TODO Once the workflow is tested, we will remove the comment and use the secret SVN access. #SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} #SVN_USERNAME: ${{ secrets.SVN_USERNAME }} + # TODO Once the workflow is tested, we will remove this test credential. + SVN_PASSWORD: SVN_PASSWORD + SVN_USERNAME: SVN_USERNAME SLUG: ${{ matrix.slug }} VERSION: ${{ matrix.version }} BUILD_DIR: ./${{ matrix.directory }}/${{ matrix.slug }} From df66f19b2ae80a1a7b1a4b49f90c73958b429e9c Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 20 Feb 2024 10:51:07 +0530 Subject: [PATCH 03/10] Update plugins config --- .../workflows/deploy-standalone-plugins.yml | 12 ++-- bin/plugin/commands/get-plugin-dir.js | 8 ++- bin/plugin/commands/get-plugin-version.js | 29 +++++---- bin/plugin/commands/test-plugins.js | 62 ++++++++++++------- plugins.json | 7 ++- 5 files changed, 73 insertions(+), 45 deletions(-) diff --git a/.github/workflows/deploy-standalone-plugins.yml b/.github/workflows/deploy-standalone-plugins.yml index c0cd3ebc24..16a5a89d55 100644 --- a/.github/workflows/deploy-standalone-plugins.yml +++ b/.github/workflows/deploy-standalone-plugins.yml @@ -47,7 +47,7 @@ jobs: echo "directory=$(node ./bin/plugin/cli.js get-plugin-dir --slug=${{ inputs.slug }})" >> $GITHUB_OUTPUT - name: Get plugin version id: get-version - if: ${{ github.event_name == 'workflow_dispatch' && steps.get-plugin-directory.outputs.directory == 'build' }} + 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 @@ -55,11 +55,8 @@ jobs: run: | if ${{ github.event_name == 'workflow_dispatch' }}; then result=$(echo "${{ steps.get-version.outputs.version }}" | awk '/^(\*|[0-9]+(\.[0-9]+){0,2}(-[a-zA-Z0-9.]+)?)$/ {print "Matched"}') - if ${{ steps.get-plugin-directory.outputs.directory == 'plugins' }}; then - # Set the manual input values in JSON format for use in the matrix for plugins. - echo "matrix={\"include\":[{\"slug\":\"${{ inputs.slug }}\",\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"true\"}]}" >> $GITHUB_OUTPUT - elif [[ -n "$result" ]]; then - # Set the manual input values in JSON format for use in the matrix for modules. + 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 }}\",\"directory\":\"${{ steps.get-plugin-directory.outputs.directory }}\",\"dry-run\":\"true\"}]}" >> $GITHUB_OUTPUT else echo "The ${{ inputs.slug }} module slug is missing in the file plugins.json." @@ -70,7 +67,7 @@ jobs: # for use in the matrix. # The "dry-run" parameter is included here to set the deployment mode. # When running the manual (workflow_dispatch) workflow, this value will be set from manual input type. - echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":true }] + [.plugins[] | {slug:. , directory:"plugins", "dry-run":true}])}' plugins.json)" >> $GITHUB_OUTPUT + echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":true }] + [.plugins | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"plugins","dry-run":true }])}' plugins.json)" >> $GITHUB_OUTPUT fi deploy: name: Deploy Plugin @@ -89,6 +86,7 @@ jobs: - name: Install npm dependencies run: npm ci - name: Building standalone plugins + if: ${{ matrix.directory != 'plugins' }} run: npm run build-plugins - name: Deploy Standalone Plugin - ${{ matrix.slug }} uses: 10up/action-wordpress-plugin-deploy@stable diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index cb0e5a0703..45c907f067 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -81,14 +81,16 @@ function doRunGetPluginDir( settings ) { const plugins = pluginsConfig.plugins; if ( plugins ) { - for ( const plugin in plugins ) { - if ( plugins[ plugin ] && settings.slug === plugins[ plugin ] ) { + for ( const pluginDir in plugins ) { + const pluginVersion = plugins[ pluginDir ]?.version; + const pluginSlug = plugins[ pluginDir ]?.slug; + if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { return log( 'plugins' ); } } } throw Error( - `The "${ settings.slug }" module slug is missing in the file "${ pluginsFile }".` + `The "${ settings.slug }" module/plugin slug is missing in the file "${ pluginsFile }".` ); } diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index cc3fb8c6d2..f08616f77e 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -68,22 +68,29 @@ function doRunGetPluginVersion( settings ) { ); } - const plugins = pluginsConfig.modules; - if ( ! plugins ) { - throw Error( - `File at "${ pluginsFile }" parsed, but the modules are missing, or they are misspelled.` - ); + const stPlugins = pluginsConfig.modules; + if ( stPlugins ) { + for ( const moduleDir in stPlugins ) { + const pluginVersion = stPlugins[ moduleDir ]?.version; + const pluginSlug = stPlugins[ moduleDir ]?.slug; + if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { + return log( pluginVersion ); + } + } } - for ( const moduleDir in plugins ) { - const pluginVersion = plugins[ moduleDir ]?.version; - const pluginSlug = plugins[ moduleDir ]?.slug; - if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { - return log( pluginVersion ); + const plugins = pluginsConfig.plugins; + if ( plugins ) { + 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 }".` + `The "${ settings.slug }" module/plugin slug is missing in the file "${ pluginsFile }".` ); } diff --git a/bin/plugin/commands/test-plugins.js b/bin/plugin/commands/test-plugins.js index a73034361a..578f1c52e4 100644 --- a/bin/plugin/commands/test-plugins.js +++ b/bin/plugin/commands/test-plugins.js @@ -480,32 +480,48 @@ function doRunStandalonePluginTests( settings ) { // Append plugins into array. const plugins = pluginsConfig.plugins; - if ( plugins && Object.keys( plugins ).length > 0 ) { - plugins.forEach( ( plugin ) => { - // Copy plugins to build for testing. - try { - fs.copySync( - `${ settings.pluginsDir }${ plugin }/`, - `${ settings.builtPluginsDir }${ plugin }/`, - { - overwrite: true, - } - ); - log( formats.success( `Copied plugin "${ plugin }".\n` ) ); - builtPlugins = builtPlugins.concat( plugin ); - } catch ( e ) { - log( - formats.error( - `Error copying plugin "${ plugin }". ${ e }` - ) - ); + if ( ! plugins ) { + log( + formats.error( + 'The given plugin configuration is invalid, the plugins are missing, or they are misspelled.' + ) + ); - // Return with exit code 1 to trigger a failure in the test pipeline. - process.exit( 1 ); - } - } ); + // Return with exit code 1 to trigger a failure in the test pipeline. + process.exit( 1 ); } + // Create an array of plugins from entries in plugins JSON file. + builtPlugins = builtPlugins.concat( + Object.keys( plugins ) + .filter( ( item ) => { + try { + fs.copySync( + `${ settings.pluginsDir }${ plugins[ item ].slug }/`, + `${ settings.builtPluginsDir }${ plugins[ item ].slug }/`, + { + overwrite: true, + } + ); + log( + formats.success( + `Copied plugin "${ plugins[ item ].slug }".\n` + ) + ); + return true; + } catch ( e ) { + // Handle the error appropriately + log( + formats.error( + `Error copying plugin "${ plugins[ item ].slug }": ${ e.message }` + ) + ); + return false; + } + } ) + .map( ( item ) => plugins[ item ].slug ) + ); + // For each built plugin, copy the test assets. builtPlugins.forEach( ( plugin ) => { log( diff --git a/plugins.json b/plugins.json index 3e36d5c794..5fecc227b9 100644 --- a/plugins.json +++ b/plugins.json @@ -9,5 +9,10 @@ "version": "1.0.5" } }, - "plugins": [] + "plugins": { + "auto-sizes": { + "slug": "auto-sizes", + "version": "1.0.1" + } + } } From d6e79c85fb91525a63a93d1f314ea5aaf069eda3 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 21 Feb 2024 10:00:49 +0530 Subject: [PATCH 04/10] Simplify the logic for reading files --- bin/plugin/commands/get-plugin-dir.js | 76 ++++++++++------------- bin/plugin/commands/get-plugin-version.js | 76 ++++++++++------------- 2 files changed, 66 insertions(+), 86 deletions(-) diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index 45c907f067..5d94abbe30 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -1,7 +1,6 @@ /** * External dependencies */ -const fs = require( 'fs' ); const path = require( 'path' ); /** @@ -38,56 +37,47 @@ function doRunGetPluginDir( settings ) { 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 = ''; + // Resolve the absolute path to the plugins.json file. + const pluginsFile = path.join( + __dirname, + '../../../' + settings.pluginsJsonFile + ); 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.` - ); - } + // Read the plugins.json file synchronously. + const { modules, plugins } = require( pluginsFile ); - const pluginsConfig = JSON.parse( pluginsFileContent ); - - // Check for valid and not empty object resulting from plugins JSON file parse. - if ( - 'object' !== typeof pluginsConfig || - 0 === Object.keys( pluginsConfig ).length - ) { - throw Error( - `File at "${ pluginsFile }" parsed, but detected empty/non valid JSON object.` - ); - } - - const stPlugins = pluginsConfig.modules; - if ( stPlugins ) { - for ( const moduleDir in stPlugins ) { - const pluginVersion = stPlugins[ moduleDir ]?.version; - const pluginSlug = stPlugins[ moduleDir ]?.slug; - if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { - return log( 'build' ); + // Validate that the modules object is not empty. + if ( modules || Object.keys( modules ).length !== 0 ) { + for ( const moduleDir in modules ) { + const pluginVersion = modules[ moduleDir ]?.version; + const pluginSlug = modules[ moduleDir ]?.slug; + if ( + pluginVersion && + pluginSlug && + settings.slug === pluginSlug + ) { + return log( 'build' ); + } } } - } - const plugins = pluginsConfig.plugins; - if ( plugins ) { - for ( const pluginDir in plugins ) { - const pluginVersion = plugins[ pluginDir ]?.version; - const pluginSlug = plugins[ pluginDir ]?.slug; - if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { - return log( 'plugins' ); + // Validate that the plugins object is not empty. + if ( plugins || Object.keys( plugins ).length !== 0 ) { + for ( const pluginDir in plugins ) { + const pluginVersion = plugins[ pluginDir ]?.version; + const pluginSlug = plugins[ pluginDir ]?.slug; + if ( + pluginVersion && + pluginSlug && + settings.slug === pluginSlug + ) { + return log( 'plugins' ); + } } } + } catch ( error ) { + throw Error( `Error reading file at "${ pluginsFile }": ${ error }` ); } throw Error( diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index f08616f77e..54f7df30fd 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -1,7 +1,6 @@ /** * External dependencies */ -const fs = require( 'fs' ); const path = require( 'path' ); /** @@ -38,56 +37,47 @@ function doRunGetPluginVersion( settings ) { 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 = ''; + // Resolve the absolute path to the plugins.json file. + const pluginsFile = path.join( + __dirname, + '../../../' + settings.pluginsJsonFile + ); 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.` - ); - } + // Read the plugins.json file synchronously. + const { modules, plugins } = require( pluginsFile ); - const pluginsConfig = JSON.parse( pluginsFileContent ); - - // Check for valid and not empty object resulting from plugins JSON file parse. - if ( - 'object' !== typeof pluginsConfig || - 0 === Object.keys( pluginsConfig ).length - ) { - throw Error( - `File at "${ pluginsFile }" parsed, but detected empty/non valid JSON object.` - ); - } - - const stPlugins = pluginsConfig.modules; - if ( stPlugins ) { - for ( const moduleDir in stPlugins ) { - const pluginVersion = stPlugins[ moduleDir ]?.version; - const pluginSlug = stPlugins[ moduleDir ]?.slug; - if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { - return log( pluginVersion ); + // Validate that the modules object is not empty. + if ( modules || Object.keys( modules ).length !== 0 ) { + for ( const moduleDir in modules ) { + const pluginVersion = modules[ moduleDir ]?.version; + const pluginSlug = modules[ moduleDir ]?.slug; + if ( + pluginVersion && + pluginSlug && + settings.slug === pluginSlug + ) { + return log( pluginVersion ); + } } } - } - const plugins = pluginsConfig.plugins; - if ( plugins ) { - for ( const moduleDir in plugins ) { - const pluginVersion = plugins[ moduleDir ]?.version; - const pluginSlug = plugins[ moduleDir ]?.slug; - if ( pluginVersion && pluginSlug && settings.slug === pluginSlug ) { - return log( pluginVersion ); + // Validate that the plugins object is not empty. + if ( plugins || Object.keys( plugins ).length !== 0 ) { + for ( const pluginDir in plugins ) { + const pluginVersion = plugins[ pluginDir ]?.version; + const pluginSlug = plugins[ pluginDir ]?.slug; + if ( + pluginVersion && + pluginSlug && + settings.slug === pluginSlug + ) { + return log( pluginVersion ); + } } } + } catch ( error ) { + throw Error( `Error reading file at "${ pluginsFile }": ${ error }` ); } throw Error( From 8a3c690ce87654522b610979c7d77deb135e982c Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 22 Feb 2024 10:18:50 +0530 Subject: [PATCH 05/10] Address review feedbacks --- bin/plugin/commands/get-plugin-dir.js | 36 ++++++++--------------- bin/plugin/commands/get-plugin-version.js | 30 +++++++------------ bin/plugin/commands/test-plugins.js | 28 ++++++++---------- 3 files changed, 36 insertions(+), 58 deletions(-) diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index 5d94abbe30..e95ace9f8f 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -11,7 +11,7 @@ const { log } = require( '../lib/logger' ); exports.options = [ { argname: '-s, --slug ', - description: 'Plugin or Standalone module/plugin slug to get directory', + description: 'Slug to search out whether it is a plugin or module.', }, ]; @@ -23,12 +23,12 @@ exports.options = [ exports.handler = async ( opt ) => { doRunGetPluginDir( { pluginsJsonFile: 'plugins.json', // Path to plugins.json file. - slug: opt.slug, // Plugin slug. + slug: opt.slug, // Plugin/module slug. } ); }; /** - * Returns directory for plugin or module based on the slug. + * Prints directory root for plugin or module based on the slug. * * @param {Object} settings Plugin settings. */ @@ -48,31 +48,21 @@ function doRunGetPluginDir( settings ) { const { modules, plugins } = require( pluginsFile ); // Validate that the modules object is not empty. - if ( modules || Object.keys( modules ).length !== 0 ) { - for ( const moduleDir in modules ) { - const pluginVersion = modules[ moduleDir ]?.version; - const pluginSlug = modules[ moduleDir ]?.slug; - if ( - pluginVersion && - pluginSlug && - settings.slug === pluginSlug - ) { - return log( 'build' ); + if ( modules && Object.keys( modules ).length !== 0 ) { + for ( const module of Object.values( modules ) ) { + if ( module.version && settings.slug === module.slug ) { + log( 'build' ); + return; } } } // Validate that the plugins object is not empty. - if ( plugins || Object.keys( plugins ).length !== 0 ) { - for ( const pluginDir in plugins ) { - const pluginVersion = plugins[ pluginDir ]?.version; - const pluginSlug = plugins[ pluginDir ]?.slug; - if ( - pluginVersion && - pluginSlug && - settings.slug === pluginSlug - ) { - return log( 'plugins' ); + if ( plugins && Object.keys( plugins ).length !== 0 ) { + for ( const plugin of Object.values( plugins ) ) { + if ( plugin.version && settings.slug === plugin.slug ) { + log( 'plugins' ); + return; } } } diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index 54f7df30fd..35456be1a5 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -48,31 +48,21 @@ function doRunGetPluginVersion( settings ) { const { modules, plugins } = require( pluginsFile ); // Validate that the modules object is not empty. - if ( modules || Object.keys( modules ).length !== 0 ) { - for ( const moduleDir in modules ) { - const pluginVersion = modules[ moduleDir ]?.version; - const pluginSlug = modules[ moduleDir ]?.slug; - if ( - pluginVersion && - pluginSlug && - settings.slug === pluginSlug - ) { - return log( pluginVersion ); + if ( modules && Object.keys( modules ).length !== 0 ) { + for ( const module of Object.values( modules ) ) { + if ( module.version && settings.slug === module.slug ) { + log( module.version ); + return; } } } // Validate that the plugins object is not empty. - if ( plugins || Object.keys( plugins ).length !== 0 ) { - for ( const pluginDir in plugins ) { - const pluginVersion = plugins[ pluginDir ]?.version; - const pluginSlug = plugins[ pluginDir ]?.slug; - if ( - pluginVersion && - pluginSlug && - settings.slug === pluginSlug - ) { - return log( pluginVersion ); + if ( plugins && Object.keys( plugins ).length !== 0 ) { + for ( const plugin of Object.values( plugins ) ) { + if ( plugin.version && settings.slug === plugin.slug ) { + log( plugin.version ); + return; } } } diff --git a/bin/plugin/commands/test-plugins.js b/bin/plugin/commands/test-plugins.js index 578f1c52e4..a8d1ee0f9b 100644 --- a/bin/plugin/commands/test-plugins.js +++ b/bin/plugin/commands/test-plugins.js @@ -447,8 +447,8 @@ function doRunStandalonePluginTests( settings ) { process.exit( 1 ); } - const stPlugins = pluginsConfig.modules; - if ( ! stPlugins ) { + const standalonePlugins = pluginsConfig.modules; + if ( ! standalonePlugins ) { log( formats.error( 'The given module configuration is invalid, the modules are missing, or they are misspelled.' @@ -460,23 +460,23 @@ function doRunStandalonePluginTests( settings ) { } // Create an array of plugins from entries in plugins JSON file. - builtPlugins = Object.keys( stPlugins ) + builtPlugins = Object.keys( standalonePlugins ) .filter( ( item ) => { if ( ! fs.pathExistsSync( - `${ settings.builtPluginsDir }${ stPlugins[ item ].slug }` + `${ settings.builtPluginsDir }${ standalonePlugins[ item ].slug }` ) ) { log( formats.error( - `Built plugin path "${ settings.builtPluginsDir }${ stPlugins[ item ].slug }" not found, skipping and removing from plugin list` + `Built plugin path "${ settings.builtPluginsDir }${ standalonePlugins[ item ].slug }" not found, skipping and removing from plugin list` ) ); return false; } return true; } ) - .map( ( item ) => stPlugins[ item ].slug ); + .map( ( item ) => standalonePlugins[ item ].slug ); // Append plugins into array. const plugins = pluginsConfig.plugins; @@ -493,33 +493,31 @@ function doRunStandalonePluginTests( settings ) { // Create an array of plugins from entries in plugins JSON file. builtPlugins = builtPlugins.concat( - Object.keys( plugins ) - .filter( ( item ) => { + Object.values( plugins ) + .filter( ( plugin ) => { try { fs.copySync( - `${ settings.pluginsDir }${ plugins[ item ].slug }/`, - `${ settings.builtPluginsDir }${ plugins[ item ].slug }/`, + `${ settings.pluginsDir }${ plugin.slug }/`, + `${ settings.builtPluginsDir }${ plugin.slug }/`, { overwrite: true, } ); log( - formats.success( - `Copied plugin "${ plugins[ item ].slug }".\n` - ) + formats.success( `Copied plugin "${ plugin.slug }".\n` ) ); return true; } catch ( e ) { // Handle the error appropriately log( formats.error( - `Error copying plugin "${ plugins[ item ].slug }": ${ e.message }` + `Error copying plugin "${ plugin.slug }": ${ e.message }` ) ); return false; } } ) - .map( ( item ) => plugins[ item ].slug ) + .map( ( plugin ) => plugin.slug ) ); // For each built plugin, copy the test assets. From 15b1cc0404f04e5e491ec36f0f5c3e7b764f2a86 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Fri, 23 Feb 2024 11:32:34 +0530 Subject: [PATCH 06/10] Apply code suggestions --- bin/plugin/commands/get-plugin-dir.js | 22 ++- bin/plugin/commands/get-plugin-version.js | 21 ++- bin/plugin/commands/test-plugins.js | 157 ++++++++-------------- 3 files changed, 69 insertions(+), 131 deletions(-) diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index e95ace9f8f..a48f9fc9b3 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -47,23 +47,17 @@ function doRunGetPluginDir( settings ) { // Read the plugins.json file synchronously. const { modules, plugins } = require( pluginsFile ); - // Validate that the modules object is not empty. - if ( modules && Object.keys( modules ).length !== 0 ) { - for ( const module of Object.values( modules ) ) { - if ( module.version && settings.slug === module.slug ) { - log( 'build' ); - return; - } + for ( const module of Object.values( modules ) ) { + if ( settings.slug === module.slug ) { + log( 'build' ); + return; } } - // Validate that the plugins object is not empty. - if ( plugins && Object.keys( plugins ).length !== 0 ) { - for ( const plugin of Object.values( plugins ) ) { - if ( plugin.version && settings.slug === plugin.slug ) { - log( 'plugins' ); - return; - } + for ( const plugin of Object.values( plugins ) ) { + if ( settings.slug === plugin.slug ) { + log( 'plugins' ); + return; } } } catch ( error ) { diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index 35456be1a5..c209655172 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -47,23 +47,18 @@ function doRunGetPluginVersion( settings ) { // Read the plugins.json file synchronously. const { modules, plugins } = require( pluginsFile ); - // Validate that the modules object is not empty. - if ( modules && Object.keys( modules ).length !== 0 ) { - for ( const module of Object.values( modules ) ) { - if ( module.version && settings.slug === module.slug ) { - log( module.version ); - return; - } + for ( const module of Object.values( modules ) ) { + if ( settings.slug === module.slug ) { + log( module.version ); + return; } } // Validate that the plugins object is not empty. - if ( plugins && Object.keys( plugins ).length !== 0 ) { - for ( const plugin of Object.values( plugins ) ) { - if ( plugin.version && settings.slug === plugin.slug ) { - log( plugin.version ); - return; - } + for ( const plugin of Object.values( plugins ) ) { + if ( settings.slug === plugin.slug ) { + log( plugin.version ); + return; } } } catch ( error ) { diff --git a/bin/plugin/commands/test-plugins.js b/bin/plugin/commands/test-plugins.js index a8d1ee0f9b..6c7a2f42c7 100644 --- a/bin/plugin/commands/test-plugins.js +++ b/bin/plugin/commands/test-plugins.js @@ -2,6 +2,7 @@ * External dependencies */ const fs = require( 'fs-extra' ); +const path = require( 'path' ); const { execSync, spawnSync } = require( 'child_process' ); /** @@ -405,120 +406,68 @@ function doRunStandalonePluginTests( settings ) { // Buffer built plugins array. let builtPlugins = []; - // Buffer contents of plugins JSON file. - let pluginsJsonFileContent = ''; + // Resolve the absolute path to the plugins.json file. + const pluginsFile = path.join( + __dirname, + '../../../' + settings.pluginsJsonFile + ); try { - pluginsJsonFileContent = fs.readFileSync( - settings.pluginsJsonFile, - 'utf-8' - ); - } catch ( e ) { - log( - formats.error( - `Error reading file at "${ settings.pluginsJsonFile }". ${ e }` - ) - ); - } - - // Validate that the plugins JSON file contains content before proceeding. - if ( '' === pluginsJsonFileContent || ! pluginsJsonFileContent ) { - log( - formats.error( - `Contents of file at "${ settings.pluginsJsonFile }" could not be read, or are empty.` - ) - ); - } - - const pluginsConfig = JSON.parse( pluginsJsonFileContent ); - - // Check for valid and not empty object resulting from plugins JSON file parse. - if ( - 'object' !== typeof pluginsConfig || - 0 === Object.keys( pluginsConfig ).length - ) { - log( - formats.error( - `File at "settings.pluginsJsonFile" parsed, but detected empty/non valid JSON object.` - ) - ); - - // Return with exit code 1 to trigger a failure in the test pipeline. - process.exit( 1 ); - } - - const standalonePlugins = pluginsConfig.modules; - if ( ! standalonePlugins ) { - log( - formats.error( - 'The given module configuration is invalid, the modules are missing, or they are misspelled.' - ) - ); - - // Return with exit code 1 to trigger a failure in the test pipeline. - process.exit( 1 ); - } - - // Create an array of plugins from entries in plugins JSON file. - builtPlugins = Object.keys( standalonePlugins ) - .filter( ( item ) => { - if ( - ! fs.pathExistsSync( - `${ settings.builtPluginsDir }${ standalonePlugins[ item ].slug }` - ) - ) { - log( - formats.error( - `Built plugin path "${ settings.builtPluginsDir }${ standalonePlugins[ item ].slug }" not found, skipping and removing from plugin list` + // Read the plugins.json file synchronously. + const { modules, plugins } = require( pluginsFile ); + + // Create an array of plugins from entries in plugins JSON file. + builtPlugins = Object.keys( modules ) + .filter( ( item ) => { + if ( + ! fs.pathExistsSync( + `${ settings.builtPluginsDir }${ modules[ item ].slug }` ) - ); - return false; - } - return true; - } ) - .map( ( item ) => standalonePlugins[ item ].slug ); - - // Append plugins into array. - const plugins = pluginsConfig.plugins; - if ( ! plugins ) { - log( - formats.error( - 'The given plugin configuration is invalid, the plugins are missing, or they are misspelled.' - ) - ); - - // Return with exit code 1 to trigger a failure in the test pipeline. - process.exit( 1 ); - } - - // Create an array of plugins from entries in plugins JSON file. - builtPlugins = builtPlugins.concat( - Object.values( plugins ) - .filter( ( plugin ) => { - try { - fs.copySync( - `${ settings.pluginsDir }${ plugin.slug }/`, - `${ settings.builtPluginsDir }${ plugin.slug }/`, - { - overwrite: true, - } - ); - log( - formats.success( `Copied plugin "${ plugin.slug }".\n` ) - ); - return true; - } catch ( e ) { - // Handle the error appropriately + ) { log( formats.error( - `Error copying plugin "${ plugin.slug }": ${ e.message }` + `Built plugin path "${ settings.builtPluginsDir }${ modules[ item ].slug }" not found, skipping and removing from plugin list` ) ); return false; } + return true; } ) - .map( ( plugin ) => plugin.slug ) - ); + .map( ( item ) => modules[ item ].slug ); + + // Create an array of plugins from entries in plugins JSON file. + builtPlugins = builtPlugins.concat( + Object.values( plugins ) + .filter( ( plugin ) => { + try { + fs.copySync( + `${ settings.pluginsDir }${ plugin.slug }/`, + `${ settings.builtPluginsDir }${ plugin.slug }/`, + { + overwrite: true, + } + ); + log( + formats.success( + `Copied plugin "${ plugin.slug }".\n` + ) + ); + return true; + } catch ( e ) { + // Handle the error appropriately + log( + formats.error( + `Error copying plugin "${ plugin.slug }": ${ e.message }` + ) + ); + return false; + } + } ) + .map( ( plugin ) => plugin.slug ) + ); + } catch ( error ) { + throw Error( `Error reading file at "${ pluginsFile }": ${ error }` ); + } // For each built plugin, copy the test assets. builtPlugins.forEach( ( plugin ) => { From a4cf3bf058093370ccdf067027edd53049493922 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 27 Feb 2024 12:36:46 +0530 Subject: [PATCH 07/10] Remove version for plugins --- .gitattributes | 2 ++ .../workflows/deploy-standalone-plugins.yml | 11 +++++-- bin/plugin/commands/get-plugin-version.js | 30 ++++++++++++++++--- plugins.json | 7 +---- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.gitattributes b/.gitattributes index 39e21f3e5e..2186c8f749 100644 --- a/.gitattributes +++ b/.gitattributes @@ -36,3 +36,5 @@ /modules/**/readme.txt export-ignore /modules/**/.wordpress-org export-ignore + +/plugins/**/.wordpress-org export-ignore diff --git a/.github/workflows/deploy-standalone-plugins.yml b/.github/workflows/deploy-standalone-plugins.yml index 16a5a89d55..b2830d3365 100644 --- a/.github/workflows/deploy-standalone-plugins.yml +++ b/.github/workflows/deploy-standalone-plugins.yml @@ -65,9 +65,10 @@ jobs: else # Load the JSON file and parse from "{name: {slug, version}, ...}" to "include: [{ name, slug, version }, ...]" # for use in the matrix. + # For plugins, the "version" parameter is not included here; it will dynamically get it in its own job. # The "dry-run" parameter is included here to set the deployment mode. # When running the manual (workflow_dispatch) workflow, this value will be set from manual input type. - echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"build","dry-run":true }] + [.plugins | to_entries[] | {name:.key,slug:.value.slug,version:.value.version,directory:"plugins","dry-run":true }])}' plugins.json)" >> $GITHUB_OUTPUT + echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key, slug: .value.slug, version: .value.version, directory: "build", "dry-run": true}] + ([.plugins[] | {name:. , slug:. , directory: "plugins", "dry-run": true}]))}' plugins.json)" >> $GITHUB_OUTPUT fi deploy: name: Deploy Plugin @@ -88,6 +89,12 @@ jobs: - name: Building standalone plugins if: ${{ matrix.directory != 'plugins' }} run: npm run build-plugins + - name: Set version + id: set_version + run: | + if [ -z "${{ matrix.version }}" ]; then + echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ matrix.slug }})" >> $GITHUB_OUTPUT + fi - name: Deploy Standalone Plugin - ${{ matrix.slug }} uses: 10up/action-wordpress-plugin-deploy@stable with: @@ -100,6 +107,6 @@ jobs: SVN_PASSWORD: SVN_PASSWORD SVN_USERNAME: SVN_USERNAME SLUG: ${{ matrix.slug }} - VERSION: ${{ matrix.version }} + VERSION: ${{ steps.set_version.outputs.version }} BUILD_DIR: ./${{ matrix.directory }}/${{ matrix.slug }} ASSETS_DIR: ./${{ matrix.directory }}/${{ matrix.slug }}/.wordpress-org diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index c209655172..2a51037472 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -1,6 +1,7 @@ /** * External dependencies */ +const fs = require( 'fs' ); const path = require( 'path' ); /** @@ -54,11 +55,32 @@ function doRunGetPluginVersion( settings ) { } } - // Validate that the plugins object is not empty. for ( const plugin of Object.values( plugins ) ) { - if ( settings.slug === plugin.slug ) { - log( plugin.version ); - return; + if ( settings.slug === plugin ) { + const readmeFile = path.join( + __dirname, + '../../../plugins/' + plugin + '/readme.txt' + ); + + let fileContent = ''; + try { + fileContent = fs.readFileSync( readmeFile, 'utf-8' ); + } catch ( err ) { + throw Error( + `Error reading the file "${ readmeFile }": "${ err }"` + ); + } + + if ( fileContent === '' ) { + throw Error( `Error reading the file "${ readmeFile }"` ); + } + + const versionRegex = /(?:Stable tag|v)\s*:\s*(\d+\.\d+\.\d+)/i; + const match = versionRegex.exec( fileContent ); + if ( match ) { + log( match[ 1 ] ); + return; + } } } } catch ( error ) { diff --git a/plugins.json b/plugins.json index 5fecc227b9..a839d995bc 100644 --- a/plugins.json +++ b/plugins.json @@ -9,10 +9,5 @@ "version": "1.0.5" } }, - "plugins": { - "auto-sizes": { - "slug": "auto-sizes", - "version": "1.0.1" - } - } + "plugins": [ "auto-sizes" ] } From 112c080952357d2c2f59f37e54a9b81258b3168d Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 27 Feb 2024 12:38:48 +0530 Subject: [PATCH 08/10] Docblock suggestions --- bin/plugin/commands/get-plugin-dir.js | 4 +++- bin/plugin/commands/get-plugin-version.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index a48f9fc9b3..434449079a 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -30,7 +30,9 @@ exports.handler = async ( opt ) => { /** * Prints directory root for plugin or module based on the slug. * - * @param {Object} settings Plugin settings. + * @param {Object} settings Plugin settings. + * @param {string} settings.pluginsJsonFile Path to plugins JSON file. + * @param {string} settings.slug Slug for the plugin or module. */ function doRunGetPluginDir( settings ) { if ( settings.slug === undefined ) { diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index 2a51037472..b24a9e9c04 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -31,7 +31,9 @@ exports.handler = async ( opt ) => { /** * Returns the match plugin version from plugins.json file. * - * @param {Object} settings Plugin settings. + * @param {Object} settings Plugin settings. + * @param {string} settings.pluginsJsonFile Path to plugins JSON file. + * @param {string} settings.slug Slug for the plugin or module. */ function doRunGetPluginVersion( settings ) { if ( settings.slug === undefined ) { From 32b1c3c1bb31dc07bdce24184241baaab517b5d5 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 27 Feb 2024 12:41:33 +0530 Subject: [PATCH 09/10] Add missing else condition --- .github/workflows/deploy-standalone-plugins.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/deploy-standalone-plugins.yml b/.github/workflows/deploy-standalone-plugins.yml index b2830d3365..bc5b36f840 100644 --- a/.github/workflows/deploy-standalone-plugins.yml +++ b/.github/workflows/deploy-standalone-plugins.yml @@ -66,6 +66,7 @@ jobs: # Load the JSON file and parse from "{name: {slug, version}, ...}" to "include: [{ name, slug, version }, ...]" # for use in the matrix. # For plugins, the "version" parameter is not included here; it will dynamically get it in its own job. + # The "dry-run" parameter is included here to set the deployment mode. # When running the manual (workflow_dispatch) workflow, this value will be set from manual input type. echo "matrix=$(jq -c '{include: ([.modules | to_entries[] | {name:.key, slug: .value.slug, version: .value.version, directory: "build", "dry-run": true}] + ([.plugins[] | {name:. , slug:. , directory: "plugins", "dry-run": true}]))}' plugins.json)" >> $GITHUB_OUTPUT @@ -94,6 +95,8 @@ jobs: run: | if [ -z "${{ matrix.version }}" ]; then echo "version=$(node ./bin/plugin/cli.js get-plugin-version --slug=${{ matrix.slug }})" >> $GITHUB_OUTPUT + else + echo "version=${{ matrix.version }})" >> $GITHUB_OUTPUT fi - name: Deploy Standalone Plugin - ${{ matrix.slug }} uses: 10up/action-wordpress-plugin-deploy@stable From 9c4674d7ad23eafc599c0f754eec45c501d8ac29 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 27 Feb 2024 12:47:07 +0530 Subject: [PATCH 10/10] Docblock suggestions --- bin/plugin/commands/get-plugin-dir.js | 5 +++-- bin/plugin/commands/get-plugin-version.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/bin/plugin/commands/get-plugin-dir.js b/bin/plugin/commands/get-plugin-dir.js index 434449079a..03ca263ac2 100644 --- a/bin/plugin/commands/get-plugin-dir.js +++ b/bin/plugin/commands/get-plugin-dir.js @@ -18,12 +18,13 @@ exports.options = [ /** * Command to get directory for plugin/module based on the slug. * - * @param {Object} opt Command options. + * @param {Object} opt Command options. + * @param {string} opt.slug Plugin/module slug. */ exports.handler = async ( opt ) => { doRunGetPluginDir( { pluginsJsonFile: 'plugins.json', // Path to plugins.json file. - slug: opt.slug, // Plugin/module slug. + slug: opt.slug, } ); }; diff --git a/bin/plugin/commands/get-plugin-version.js b/bin/plugin/commands/get-plugin-version.js index b24a9e9c04..e9a5649284 100644 --- a/bin/plugin/commands/get-plugin-version.js +++ b/bin/plugin/commands/get-plugin-version.js @@ -19,12 +19,13 @@ exports.options = [ /** * Command to get the plugin version based on the slug. * - * @param {Object} opt Command options. + * @param {Object} opt Command options. + * @param {string} opt.slug Plugin/module slug. */ exports.handler = async ( opt ) => { doRunGetPluginVersion( { pluginsJsonFile: 'plugins.json', // Path to plugins.json file. - slug: opt.slug, // Plugin slug. + slug: opt.slug, } ); };