Skip to content

Commit

Permalink
Merge pull request #1064 from ckeditor/cc/7040
Browse files Browse the repository at this point in the history
Other (release-tools): Exported the `getDateIdentifier()` util that converts the current date into `YYYYMMDD` format.

Other (release-tools): Improved the `getLastPreRelease()` util to distinguish pre-release versions starting with the same base name. Previously, `getLastPreRelease( '0.0.0-nightly' )` matched both `0.0.0-nightly` and `0.0.0-nightly-next` versions, but now only the first one is matched.
  • Loading branch information
pomek authored Feb 10, 2025
2 parents be66a0d + b90cd72 commit c3496f0
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 12 deletions.
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 @@ -22,6 +22,7 @@ export {
getNextNightly,
getNextInternal,
getCurrent,
getDateIdentifier,
getLastTagFromGit
} from './utils/versions.js';
export { default as getChangesForVersion } from './utils/getchangesforversion.js';
Expand Down
24 changes: 17 additions & 7 deletions packages/ckeditor5-dev-release-tools/lib/utils/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ export function getLastFromChangelog( cwd = process.cwd() ) {

/**
* Returns the current (latest) pre-release version that matches the provided release identifier.
* It takes into account and distinguishes pre-release tags with different names but starting with the same base name.
* If the package does not have any pre-releases with the provided identifier yet, `null` is returned.
*
* Examples:
* * "0.0.0-nightly" - Matches the last "nightly" version regardless of the publication date.
* It does not match other nightly tags that start with the same "nightly" base name, e.g. "0.0.0-nightly-next-YYYYMMDD.X".
* * "0.0.0-nightly-20230615" - Matches the last "nightly" version from the 2023-06-15 day.
* * "42.0.0-alpha" - Matches the last "alpha" version for the 42.0.0 version.
*
* @param {ReleaseIdentifier} releaseIdentifier
* @param {string} [cwd=process.cwd()]
* @returns {Promise.<string|null>}
Expand All @@ -41,7 +48,13 @@ export function getLastPreRelease( releaseIdentifier, cwd = process.cwd() ) {
return packument( packageName )
.then( result => {
const lastVersion = Object.keys( result.versions )
.filter( version => version.startsWith( releaseIdentifier ) )
.filter( version => {
const optionalDateIdentifier = '(-[0-9]{8})?';
const optionalSequenceNumber = '(\\.[0-9]+)?';
const versionRegExp = new RegExp( `^${ releaseIdentifier }${ optionalDateIdentifier }${ optionalSequenceNumber }$` );

return versionRegExp.test( version );
} )
.sort( ( a, b ) => a.localeCompare( b, undefined, { numeric: true } ) )
.pop();

Expand Down Expand Up @@ -138,9 +151,11 @@ export function getCurrent( cwd = process.cwd() ) {
}

/**
* Returns current date in the "YYYYMMDD" format.
*
* @returns {string}
*/
function getDateIdentifier() {
export function getDateIdentifier() {
const today = new Date();
const year = today.getFullYear().toString();
const month = ( today.getMonth() + 1 ).toString().padStart( 2, '0' );
Expand All @@ -152,9 +167,4 @@ function getDateIdentifier() {
/**
* @typedef {string} ReleaseIdentifier The pre-release identifier without the last dynamic part (the pre-release sequential number).
* It consists of the core base version ("<major>.<minor>.<path>"), a hyphen ("-"), and a pre-release identifier name (e.g. "alpha").
*
* Examples:
* * "0.0.0-nightly" - matches the last nightly version regardless of the publication date.
* * "0.0.0-nightly-20230615" - matches the last nightly version from the 2023-06-15 day.
* * "42.0.0-alpha" - matches the last alpha version for the 42.0.0 version.
*/
8 changes: 8 additions & 0 deletions packages/ckeditor5-dev-release-tools/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
getNextNightly,
getNextInternal,
getCurrent,
getDateIdentifier,
getLastTagFromGit
} from '../lib/utils/versions.js';
import executeInParallel from '../lib/utils/executeinparallel.js';
Expand Down Expand Up @@ -150,6 +151,13 @@ describe( 'dev-release-tools/index', () => {
} );
} );

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

describe( 'getLastPreRelease()', () => {
it( 'should be a function', () => {
expect( getLastPreRelease ).to.be.a( 'function' );
Expand Down
168 changes: 163 additions & 5 deletions packages/ckeditor5-dev-release-tools/tests/utils/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
getNextNightly,
getNextInternal,
getLastTagFromGit,
getCurrent
getCurrent,
getDateIdentifier
} from '../../lib/utils/versions.js';

vi.mock( '@ckeditor/ckeditor5-dev-utils' );
Expand Down Expand Up @@ -145,6 +146,23 @@ describe( 'versions', () => {
} );
} );

it( 'returns null if pre-release version matches the release identifier only partially', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-20230615.1': {},
'0.0.0-nightly-20230615.2': {},
'0.0.0-nightly-next-20230615.3': {}
}
} );

return getLastPreRelease( '0.0.0-nightly-2023' )
.then( result => {
expect( result ).to.equal( null );
} );
} );

it( 'returns last pre-release version matching the release identifier', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
Expand Down Expand Up @@ -245,14 +263,119 @@ describe( 'versions', () => {
expect( result ).to.equal( '0.0.0-nightly-20230615.2' );
} );
} );

it( 'returns last version from exactly the "nightly" tag when multiple nightly tags exist', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-20230615.1': {},
'0.0.0-nightly-20230615.2': {},
'0.0.0-nightly-next-20230615.3': {}
}
} );

return getLastPreRelease( '0.0.0-nightly' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-20230615.2' );
} );
} );

it( 'returns last version from exactly the "nightly-next" tag when multiple nightly tags exist', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-next-20230615.0': {},
'0.0.0-nightly-next-20230615.1': {},
'0.0.0-nightly-next-20230615.2': {},
'0.0.0-nightly-20230615.3': {}
}
} );

return getLastPreRelease( '0.0.0-nightly-next' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-next-20230615.2' );
} );
} );

it( 'returns last version from exactly the "nightly" tag when multiple nightly tags exist from a specific day', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-20230615.1': {},
'0.0.0-nightly-20230615.2': {},
'0.0.0-nightly-next-20230615.3': {}
}
} );

return getLastPreRelease( '0.0.0-nightly-20230615' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-20230615.2' );
} );
} );

it( 'returns last version from exactly the "nightly-next" tag when multiple nightly tags exist from a specific day', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-next-20230615.0': {},
'0.0.0-nightly-next-20230615.1': {},
'0.0.0-nightly-next-20230615.2': {},
'0.0.0-nightly-20230615.3': {}
}
} );

return getLastPreRelease( '0.0.0-nightly-next-20230615' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-next-20230615.2' );
} );
} );

it( 'returns last pre-release version matching the release identifier exactly', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'37.0.0-alpha.1': {},
'37.0.0-alpha.2': {},
'41.0.0': {},
'37.0.0-alpha.10': {},
'37.0.0-alpha.11': {}
}
} );

return getLastPreRelease( '37.0.0-alpha.10' )
.then( result => {
expect( result ).to.equal( '37.0.0-alpha.10' );
} );
} );

it( 'returns last nightly version matching the release identifier exactly', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-20230615.1': {},
'0.0.0-nightly-20230615.2': {},
'0.0.0-nightly-next-20230615.1': {},
'0.0.0-nightly-next-20230615.2': {}
}
} );

return getLastPreRelease( '0.0.0-nightly-20230615.1' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-20230615.1' );
} );
} );
} );

describe( 'getLastNightly()', () => {
beforeEach( async () => {
vi.mocked( getPackageJson ).mockReturnValue( { name: 'ckeditor5' } );
} );

it( 'returns last nightly pre-release version', () => {
it( 'returns last pre-release version from exactly the "nightly" tag', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
Expand All @@ -261,6 +384,7 @@ describe( 'versions', () => {
'0.0.0-nightly-20230614.1': {},
'0.0.0-nightly-20230614.2': {},
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-next-20230616.0': {},
'37.0.0-alpha.0': {},
'42.0.0': {}
}
Expand Down Expand Up @@ -310,11 +434,12 @@ describe( 'versions', () => {
} );
} );

it( 'returns nightly version with incremented id if older nightly version was already published', () => {
it( 'returns version with incremented id from exactly the "nightly" tag if older version was already published', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.5': {},
'0.0.0-nightly-next-20230616.0': {},
'37.0.0-alpha.0': {},
'42.0.0': {}
}
Expand All @@ -325,6 +450,23 @@ describe( 'versions', () => {
expect( result ).to.equal( '0.0.0-nightly-20230615.6' );
} );
} );

it( 'returns version with incremented id from exactly the "nightly-next" tag if older version was already published', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-next-20230615.5': {},
'0.0.0-nightly-20230616.0': {},
'37.0.0-alpha.0': {},
'42.0.0': {}
}
} );

return getNextPreRelease( '0.0.0-nightly-next' )
.then( result => {
expect( result ).to.equal( '0.0.0-nightly-next-20230615.6' );
} );
} );
} );

describe( 'getNextNightly()', () => {
Expand All @@ -339,11 +481,12 @@ describe( 'versions', () => {
vi.useRealTimers();
} );

it( 'asks for a last nightly pre-release version', () => {
it( 'returns next pre-release version from exactly the "nightly" tag', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
'0.0.0-nightly-20230615.0': {},
'0.0.0-nightly-next-20230615.5': {},
'37.0.0-alpha.0': {},
'42.0.0': {}
}
Expand All @@ -368,7 +511,7 @@ describe( 'versions', () => {
vi.useRealTimers();
} );

it( 'asks for a last internal pre-release version', () => {
it( 'returns next internal pre-release version', () => {
vi.mocked( packument ).mockResolvedValue( {
name: 'ckeditor5',
versions: {
Expand All @@ -385,6 +528,21 @@ describe( 'versions', () => {
} );
} );

describe( 'getDateIdentifier()', () => {
beforeEach( () => {
vi.useFakeTimers();
vi.setSystemTime( new Date( '2023-06-15 12:00:00' ) );
} );

afterEach( () => {
vi.useRealTimers();
} );

it( 'returns current date in the YYYYMMDD format', () => {
expect( getDateIdentifier() ).to.equal( '20230615' );
} );
} );

describe( 'getLastTagFromGit()', () => {
it( 'returns last tag if exists', () => {
vi.mocked( tools.shExec ).mockReturnValue( 'v1.0.0' );
Expand Down

0 comments on commit c3496f0

Please sign in to comment.