Package Release: Handle invalid releases (#33798)

This commit is contained in:
Paul Sealock 2022-07-14 14:03:37 +12:00 committed by GitHub
parent e09469c13c
commit 293de77552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 1005 additions and 740 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,9 @@
"dependencies": { "dependencies": {
"@oclif/core": "^1", "@oclif/core": "^1",
"@oclif/plugin-help": "^5", "@oclif/plugin-help": "^5",
"@oclif/plugin-plugins": "^2.0.1" "@oclif/plugin-plugins": "^2.0.1",
"@types/semver": "^7.3.10",
"semver": "^7.3.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^16.9.4", "@types/node": "^16.9.4",

View File

@ -11,6 +11,7 @@ import {
getAllPackges, getAllPackges,
validatePackage, validatePackage,
getFilepathFromPackageName, getFilepathFromPackageName,
isValidUpdate,
} from '../../validate'; } from '../../validate';
import { MONOREPO_ROOT } from '../../const'; import { MONOREPO_ROOT } from '../../const';
@ -79,6 +80,13 @@ export default class PackageRelease extends Command {
stdio: 'inherit', stdio: 'inherit',
} ); } );
// Sometimes the pnpm lock file is out of sync, this shouldn't prevent a release.
execSync( 'git checkout pnpm-lock.yaml', {
cwd: MONOREPO_ROOT,
encoding: 'utf-8',
stdio: 'inherit',
} );
CliUx.ux.action.stop(); CliUx.ux.action.stop();
} }
@ -107,28 +115,32 @@ export default class PackageRelease extends Command {
{ 'dry-run': dryRun, branch }: { 'dry-run': boolean; branch: string } { 'dry-run': dryRun, branch }: { 'dry-run': boolean; branch: string }
) { ) {
packages.forEach( ( name ) => { packages.forEach( ( name ) => {
const verb = dryRun ? 'Performing dry run of' : 'Publishing';
CliUx.ux.action.start( `${ verb } ${ name }` );
try { try {
const cwd = getFilepathFromPackageName( name ); const verb = dryRun ? 'Performing dry run of' : 'Publishing';
return execSync( CliUx.ux.action.start( `${ verb } ${ name }` );
`SKIP_TURBO=true pnpm publish ${ if ( isValidUpdate( name ) ) {
dryRun ? '--dry-run' : '' const cwd = getFilepathFromPackageName( name );
} --publish-branch=${ branch }`, execSync(
{ `SKIP_TURBO=true pnpm publish ${
cwd, dryRun ? '--dry-run' : ''
encoding: 'utf-8', } --publish-branch=${ branch }`,
stdio: 'inherit', {
} cwd,
); encoding: 'utf-8',
stdio: 'inherit',
}
);
CliUx.ux.action.stop( `${ name } successfully published.` );
} else {
CliUx.ux.action.stop(
`${ name } does not have anything to update.`
);
}
} catch ( e ) { } catch ( e ) {
if ( e instanceof Error ) { if ( e instanceof Error ) {
this.error( e.message ); this.error( e.message );
} }
} }
CliUx.ux.action.stop();
} ); } );
} }
} }

View File

@ -3,6 +3,8 @@
*/ */
import { existsSync, readFileSync, readdirSync } from 'fs'; import { existsSync, readFileSync, readdirSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { execSync } from 'child_process';
import { gt as greaterVersionThan } from 'semver';
/** /**
* Internal dependencies * Internal dependencies
@ -19,21 +21,34 @@ export const getFilepathFromPackageName = ( name: string ): string =>
join( MONOREPO_ROOT, 'packages/js', name.replace( '@woocommerce', '' ) ); join( MONOREPO_ROOT, 'packages/js', name.replace( '@woocommerce', '' ) );
/** /**
* Check if package is valid and can be deployed to NPM. * Get a package's package.json file in JSON format.
* *
* @param {string} name package name. * @param {string} name package name.
* @return {boolean} true if the package is private. * @return {Object|false} JSON object or false if it fails.
*/ */
export const isValidPackage = ( name: string ): boolean => { export const getPackageJson = ( name: string ) => {
const filepath = getFilepathFromPackageName( name ); const filepath = getFilepathFromPackageName( name );
const packageJsonFilepath = `${ filepath }/package.json`; const packageJsonFilepath = `${ filepath }/package.json`;
const packageJsonExists = existsSync( packageJsonFilepath ); const packageJsonExists = existsSync( packageJsonFilepath );
if ( ! packageJsonExists ) { if ( ! packageJsonExists ) {
return false; return false;
} }
const packageJson = JSON.parse(
readFileSync( packageJsonFilepath, 'utf8' ) return JSON.parse( readFileSync( packageJsonFilepath, 'utf8' ) );
); };
/**
* Check if package is valid and can be deployed to NPM.
*
* @param {string} name package name.
* @return {boolean} true if the package is private.
*/
export const isValidPackage = ( name: string ): boolean => {
const packageJson = getPackageJson( name );
if ( ! packageJson ) {
return false;
}
if ( name !== packageJson.name ) { if ( name !== packageJson.name ) {
return false; return false;
@ -111,3 +126,29 @@ export const validatePackage = (
); );
} }
}; };
/**
* Determine if an update is valid by comparing version numbers.
*
* @param {string} name package name.
* @return {boolean} If an update is valid.
*/
export const isValidUpdate = ( name: string ): boolean => {
const packageJson = getPackageJson( name );
if ( ! packageJson ) {
return false;
}
const nextVersion = packageJson.version;
if ( ! nextVersion ) {
return false;
}
const npmVersion = execSync( 'pnpm view @woocommerce/number version', {
encoding: 'utf-8',
} );
return greaterVersionThan( nextVersion.trim(), npmVersion.trim() );
};