Skip to content

Commit

Permalink
Merge pull request #1022 from ckeditor/i/3828-restartable-release-v2
Browse files Browse the repository at this point in the history
Internal: Restored the `verifyPackagesPublishedCorrectly()` function and marked it deprecated.
  • Loading branch information
pomek authored Oct 14, 2024
2 parents ff7d738 + 9dcd7e5 commit adeffc4
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 0 deletions.
11 changes: 11 additions & 0 deletions DEPRECATIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Deprecated APIs

Modules exported by packages in the repository can be marked as deprecated when an improved alternative appears, our processes require updates, or the proposed API is unsafe.

## List of deprecated API

Below, you can find all deprecation codes used in the `ckeditor5-dev-*` packages.

### DEP0001: `verifyPackagesPublishedCorrectly()`

Since v45, the `verifyPackagesPublishedCorrectly()` function is no longer available as its responsibility has been merged with `publishPackages()`.
1 change: 1 addition & 0 deletions packages/ckeditor5-dev-release-tools/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export { default as saveChangelog } from './utils/savechangelog.js';
export { default as executeInParallel } from './utils/executeinparallel.js';
export { default as validateRepositoryToRelease } from './utils/validaterepositorytorelease.js';
export { default as checkVersionAvailability } from './utils/checkversionavailability.js';
export { default as verifyPackagesPublishedCorrectly } from './tasks/verifypackagespublishedcorrectly.js';
export { default as getNpmTagFromVersion } from './utils/getnpmtagfromversion.js';
export { default as isVersionPublishableForTag } from './utils/isversionpublishablefortag.js';
export { default as provideToken } from './utils/providetoken.js';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/

import upath from 'upath';
import { glob } from 'glob';
import fs from 'fs-extra';
import checkVersionAvailability from '../utils/checkversionavailability.js';

/**
* Npm sometimes throws incorrect error 409 while publishing, while the package uploads correctly.
* The purpose of the script is to validate if packages that threw 409 are uploaded correctly to npm.
*
* @param {object} options
* @param {string} options.packagesDirectory Relative path to a location of packages to release.
* @param {string} options.version Version of the current release.
* @param {function} options.onSuccess Callback fired when function is successful.
* @returns {Promise}
*/
export default async function verifyPackagesPublishedCorrectly( options ) {
process.emitWarning(
'The `verifyPackagesPublishedCorrectly()` function is deprecated and will be removed in the upcoming release (v45). ' +
'Its responsibility has been merged with `publishPackages()`.',
{
type: 'DeprecationWarning',
code: 'DEP0001',
detail: 'https://github.com/ckeditor/ckeditor5-dev/blob/master/DEPRECATIONS.md#dep0001-verifypackagespublishedcorrectly'
}
);

const { packagesDirectory, version, onSuccess } = options;
const packagesToVerify = await glob( upath.join( packagesDirectory, '*' ), { absolute: true } );
const errors = [];

if ( !packagesToVerify.length ) {
onSuccess( 'No packages found to check for upload error 409.' );

return;
}

for ( const packageToVerify of packagesToVerify ) {
const packageJson = await fs.readJson( upath.join( packageToVerify, 'package.json' ) );

const isPackageVersionAvailable = await checkVersionAvailability( version, packageJson.name );

if ( isPackageVersionAvailable ) {
errors.push( packageJson.name );
} else {
await fs.remove( packageToVerify );
}
}

if ( errors.length ) {
throw new Error( 'Packages that were uploaded incorrectly, and need manual verification:\n' + errors.join( '\n' ) );
}

onSuccess( 'All packages that returned 409 were uploaded correctly.' );
}
9 changes: 9 additions & 0 deletions packages/ckeditor5-dev-release-tools/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import executeInParallel from '../lib/utils/executeinparallel.js';
import validateRepositoryToRelease from '../lib/utils/validaterepositorytorelease.js';
import checkVersionAvailability from '../lib/utils/checkversionavailability.js';
import verifyPackagesPublishedCorrectly from '../lib/tasks/verifypackagespublishedcorrectly.js';
import getNpmTagFromVersion from '../lib/utils/getnpmtagfromversion.js';
import isVersionPublishableForTag from '../lib/utils/isversionpublishablefortag.js';
import provideToken from '../lib/utils/providetoken.js';
Expand All @@ -48,6 +49,7 @@ vi.mock( '../lib/tasks/push' );
vi.mock( '../lib/tasks/publishpackages' );
vi.mock( '../lib/tasks/updateversions' );
vi.mock( '../lib/tasks/cleanuppackages' );
vi.mock( '../lib/tasks/verifypackagespublishedcorrectly' );
vi.mock( '../lib/utils/versions' );
vi.mock( '../lib/utils/getnpmtagfromversion' );
vi.mock( '../lib/utils/changelog' );
Expand Down Expand Up @@ -233,6 +235,13 @@ describe( 'dev-release-tools/index', () => {
} );
} );

describe( 'verifyPackagesPublishedCorrectly()', () => {
it( 'should be a function', () => {
expect( verifyPackagesPublishedCorrectly ).to.be.a( 'function' );
expect( index.verifyPackagesPublishedCorrectly ).to.equal( verifyPackagesPublishedCorrectly );
} );
} );

describe( 'isVersionPublishableForTag()', () => {
it( 'should be a function', () => {
expect( isVersionPublishableForTag ).to.be.a( 'function' );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md.
*/

import { beforeEach, describe, expect, it, vi } from 'vitest';
import { glob } from 'glob';
import fs from 'fs-extra';
import verifyPackagesPublishedCorrectly from '../../lib/tasks/verifypackagespublishedcorrectly.js';
import checkVersionAvailability from '../../lib/utils/checkversionavailability.js';

vi.mock( 'fs-extra' );
vi.mock( '../../lib/utils/checkversionavailability' );
vi.mock( 'glob' );

describe( 'verifyPackagesPublishedCorrectly()', () => {
beforeEach( () => {
vi.spyOn( process, 'emitWarning' ).mockImplementation( () => {
} );
vi.mocked( fs ).remove.mockResolvedValue();
vi.mocked( fs ).readJson.mockResolvedValue();
vi.mocked( glob ).mockResolvedValue( [] );
vi.mocked( checkVersionAvailability ).mockResolvedValue();
} );

it( 'should not verify packages if there are no packages in the release directory', async () => {
const packagesDirectory = '/workspace/ckeditor5/release/npm';
const version = 'latest';
const onSuccess = vi.fn();

await verifyPackagesPublishedCorrectly( { packagesDirectory, version, onSuccess } );

expect( onSuccess ).toHaveBeenCalledExactlyOnceWith( 'No packages found to check for upload error 409.' );
expect( vi.mocked( checkVersionAvailability ) ).not.toHaveBeenCalled();
} );

it( 'should verify packages and remove them from the release directory on if their version are already taken', async () => {
vi.mocked( glob ).mockResolvedValue( [ 'package1', 'package2' ] );
vi.mocked( fs ).readJson
.mockResolvedValueOnce( { name: '@namespace/package1' } )
.mockResolvedValueOnce( { name: '@namespace/package2' } );

const packagesDirectory = '/workspace/ckeditor5/release/npm';
const version = 'latest';
const onSuccess = vi.fn();

await verifyPackagesPublishedCorrectly( { packagesDirectory, version, onSuccess } );

expect( vi.mocked( checkVersionAvailability ) ).toHaveBeenCalledWith( 'latest', '@namespace/package1' );
expect( vi.mocked( checkVersionAvailability ) ).toHaveBeenCalledWith( 'latest', '@namespace/package2' );
expect( vi.mocked( fs ).remove ).toHaveBeenCalledWith( 'package1' );
expect( vi.mocked( fs ).remove ).toHaveBeenCalledWith( 'package2' );

expect( onSuccess ).toHaveBeenCalledExactlyOnceWith( 'All packages that returned 409 were uploaded correctly.' );
} );

it( 'should not remove package from release directory when package is not available on npm', async () => {
vi.mocked( glob ).mockResolvedValue( [ 'package1', 'package2' ] );
vi.mocked( fs ).readJson
.mockResolvedValueOnce( { name: '@namespace/package1' } )
.mockResolvedValueOnce( { name: '@namespace/package2' } );
vi.mocked( checkVersionAvailability )
.mockResolvedValueOnce( true )
.mockResolvedValueOnce( false );

const packagesDirectory = '/workspace/ckeditor5/release/npm';
const version = 'latest';
const onSuccess = vi.fn();

await expect( verifyPackagesPublishedCorrectly( { packagesDirectory, version, onSuccess } ) )
.rejects.toThrow( 'Packages that were uploaded incorrectly, and need manual verification:\n@namespace/package1' );

expect( vi.mocked( fs ).remove ).toHaveBeenCalledExactlyOnceWith( 'package2' );
} );

it( 'should print a deprecation warning', async () => {
const packagesDirectory = '/workspace/ckeditor5/release/npm';
const version = 'latest';
const onSuccess = vi.fn();

await verifyPackagesPublishedCorrectly( { packagesDirectory, version, onSuccess } );

expect( vi.mocked( process.emitWarning ) ).toHaveBeenCalledExactlyOnceWith(
expect.any( String ),
expect.objectContaining( {
type: 'DeprecationWarning',
code: 'DEP0001',
detail: expect.stringContaining( 'dep0001' )
} )
);
} );
} );

0 comments on commit adeffc4

Please sign in to comment.