Pass the version argument explicitly to code-analyzer, introduce a new command that determines latest major/minor (#34404)

This also adds a new command `major_minor` that contains some of the old logic of `getPluginData` to determine the latest major/minor version of WooCommerce
This commit is contained in:
Sam Seay 2022-08-22 16:29:59 +12:00 committed by GitHub
parent e651a46fb6
commit 41a276c49b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 161 additions and 68 deletions

View File

@ -13,10 +13,12 @@ jobs:
run: |
npm install -g pnpm@^6.24.2
npm -g i @wordpress/env@5.1.0
pnpm install
pnpm install --filter code-analyzer
- name: Run analyzer
id: run
run: ./tools/code-analyzer/bin/dev analyzer "$GITHUB_HEAD_REF"
run: |
version=$(./tools/code-analyzer/bin/dev major_minor "${{ github.head_ref || github.ref_name }}" "plugins/woocommerce/woocommerce.php")
./tools/code-analyzer/bin/dev analyzer "$GITHUB_HEAD_REF" $version
- name: Print results
id: results
run: echo "::set-output name=results::${{ steps.run.outputs.templates }}${{ steps.run.outputs.wphooks }}${{ steps.run.outputs.schema }}${{ steps.run.outputs.database }}"

View File

@ -0,0 +1,32 @@
# Code Analyzer
## Description
`code-analyzer` is a CLI tool designed to analyze change information about plugins in the WooCommerce monorepo.
## Commands
Currently there are just 2 commands:
1. `analyzer`. Analyzer serves 2 roles currently, as a linter for PRs to check if introduced hook/template/db changes have associated changelog entries and also to provide file output of changes between
WooCommerce versions for the purpose of automating release processes (such as generating release posts.)
Here is an example `analyzer` command:
`./bin/dev analyzer release/6.8 "6.8.0" -b=release/6.7`
In this command we compare the `release/6.7` and `release/6.8` branches to find differences, and we're looking for changes introduced since `6.8.0` (using the `@since` tag).
To find out more about the other arguments to the command you can run `./bin/dev analyzer --help`
2. `major_minor`. This simple CLI tool gives you the latest `.0` major/minor released version of a plugin's mainfile based on Woo release conventions.
Here is an example `major_minor` command:
`./bin/dev major_minor release/6.8 "plugins/woocommerce/woocommerce.php"`
In this command we checkout the branch `release/6.8` and check the version of the woocommerce.php mainfile located at the path passed. Note that at the time of
writing the main file in this particular branch reports `6.8.1` so the output of this command is `6.8.0`.
This command is particularly useful combined with the analyzer, allowing you to determine the last major/minor.0 version of a branch or ref before passing that as the
version argument to `analyzer`.

View File

@ -47,6 +47,12 @@ export default class Analyzer extends Command {
'GitHub branch or commit hash to compare against the base branch/commit.',
required: true,
},
{
name: 'sinceVersion',
description:
'Specify the version used to determine which changes are included (version listed in @since code doc).',
required: true,
},
];
/**
@ -94,6 +100,9 @@ export default class Analyzer extends Command {
async run(): Promise< void > {
const { args, flags } = await this.parse( Analyzer );
const { compare, sinceVersion } = args;
const { base } = flags;
CliUx.ux.action.start(
`Making a temporary clone of '${ flags.source }'`
);
@ -106,14 +115,11 @@ export default class Analyzer extends Command {
const diff = await generateDiff(
tmpRepoPath,
flags.base,
args.compare,
compare,
this.error
);
CliUx.ux.action.stop();
const pluginData = this.getPluginData( tmpRepoPath, flags.plugin );
this.log( `${ pluginData[ 1 ] } Version: ${ pluginData[ 0 ] }` );
// Run schema diffs only in the monorepo.
if ( flags[ 'is-woocommerce' ] ) {
CliUx.ux.action.start( 'Building WooCommerce' );
@ -128,21 +134,21 @@ export default class Analyzer extends Command {
CliUx.ux.action.stop();
CliUx.ux.action.start(
`Comparing WooCommerce DB schemas of '${ flags.base }' and '${ args.compare }'`
`Comparing WooCommerce DB schemas of '${ base }' and '${ compare }'`
);
const schemaDiff = await generateSchemaDiff(
tmpRepoPath,
args.compare,
flags.base,
compare,
base,
( e: string ): void => this.error( e )
);
CliUx.ux.action.stop();
await this.scanChanges( diff, pluginData[ 0 ], flags, schemaDiff );
await this.scanChanges( diff, sinceVersion, flags, schemaDiff );
} else {
await this.scanChanges( diff, pluginData[ 0 ], flags );
await this.scanChanges( diff, sinceVersion, flags );
}
// Clean up the temporary repo.
@ -151,63 +157,6 @@ export default class Analyzer extends Command {
CliUx.ux.action.stop();
}
/**
* Get plugin data
*
* @param {string} plugin Plugin slug.
* @return {string[]} Promise.
*/
private getPluginData( tmpRepoPath: string, plugin: string ): string[] {
/**
* List of plugins from our monorepo.
*/
const plugins = <any>{
core: {
name: 'WooCommerce',
mainFile: join(
tmpRepoPath,
'plugins',
'woocommerce',
'woocommerce.php'
),
},
admin: {
name: 'WooCommerce Admin',
mainFile: join(
tmpRepoPath,
'plugins',
'woocommerce-admin',
'woocommerce-admin.php'
),
},
beta: {
name: 'WooCommerce Beta Tester',
mainFile: join(
tmpRepoPath,
'plugins',
'woocommerce-beta-tester',
'woocommerce-beta-tester.php'
),
},
};
const pluginData = plugins[ plugin ];
CliUx.ux.action.start( `Getting ${ pluginData.name } version` );
const content = readFileSync( pluginData.mainFile ).toString();
const rawVer = content.match( /^\s+\*\s+Version:\s+(.*)/m );
if ( ! rawVer ) {
this.error( 'Failed to find plugin version!' );
}
const version = rawVer[ 1 ].replace( /\-.*/, '' );
CliUx.ux.action.stop();
return [ version, pluginData.name, pluginData.mainFile ];
}
/**
* Scan patches for changes in templates, hooks and database schema
*

View File

@ -0,0 +1,110 @@
/**
* External dependencies
*/
import { CliUx, Command, Flags } from '@oclif/core';
import { join } from 'path';
import { readFileSync, rmSync } from 'fs';
import simpleGit from 'simple-git';
/**
* Internal dependencies
*/
import { cloneRepo } from '../../git';
/**
* MajorMinor command class
*/
export default class MajorMinor extends Command {
/**
* CLI description
*/
static description = 'Determine major/minor version of a plugin';
/**
* CLI arguments
*/
static args = [
{
name: 'branch',
description: 'GitHub branch to use to determine version',
required: true,
},
{
name: 'pathToMainFile',
description: "Path to plugin's main PHP file",
required: true,
},
];
/**
* CLI flags.
*/
static flags = {
source: Flags.string( {
char: 's',
description: 'Git repo url or local path to a git repo.',
default: process.cwd(),
} ),
};
/**
* This method is called to execute the command
*/
async run(): Promise< void > {
const { args, flags } = await this.parse( MajorMinor );
const { source } = flags;
const { branch, pathToMainFile } = args;
CliUx.ux.action.start( `Making a temporary clone of '${ branch }'` );
const tmpRepoPath = await cloneRepo( source );
const version = await this.getPluginData(
tmpRepoPath,
pathToMainFile,
branch
);
// Clean up the temporary repo.
rmSync( tmpRepoPath, { force: true, recursive: true } );
this.log( version );
CliUx.ux.action.stop();
}
/**
* Get plugin data
*
* @param {string} tmpRepoPath - Path to repo.
* @param {string} pathToMainFile - Path to plugin's main PHP file.
* @param {string} hashOrBranch - Hash or branch to checkout.
* @return {Promise<string>} - Promise containing version as string.
*/
private async getPluginData(
tmpRepoPath: string,
pathToMainFile: string,
hashOrBranch: string
): Promise< string > {
const git = simpleGit( { baseDir: tmpRepoPath } );
await git.checkout( [ hashOrBranch ] );
const mainFile = join( tmpRepoPath, pathToMainFile );
CliUx.ux.action.start( `Getting version from ${ pathToMainFile }` );
const content = readFileSync( mainFile ).toString();
const rawVer = content.match( /^\s+\*\s+Version:\s+(.*)/m );
if ( ! rawVer ) {
this.error(
'Failed to find plugin version! Make sure the file contains a version in the format `Version: ...`'
);
}
const version = rawVer[ 1 ].replace( /\-.*/, '' );
CliUx.ux.action.stop();
const [ major, minor ] = version.split( '.' );
return `${ major }.${ minor }.0`;
}
}