@ckeditor/ckeditor5-dev-release-tools 51.0.0 → 52.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,103 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import { parseCommitsStream } from 'conventional-commits-parser';
7
- import { filterRevertedCommitsSync } from 'conventional-commits-filter';
8
- import { getRawCommitsStream } from 'git-raw-commits';
9
- import concat from 'concat-stream';
10
- import parserOptions from './parseroptions.js';
11
- import { tools } from '@ckeditor/ckeditor5-dev-utils';
12
- import shellEscape from 'shell-escape';
13
-
14
- /**
15
- * Returns a promise that resolves an array of commits since the last tag specified as `options.from`.
16
- *
17
- * @param {function} transformCommit
18
- * @param {object} options
19
- * @param {string} [options.from] A commit or tag name that will be the first param of the range of commits to collect.
20
- * @param {string} [options.releaseBranch='master'] A name of the branch that should be used for releasing packages.
21
- * @param {string} [options.mainBranch='master'] A name of the main branch in the repository.
22
- * @returns {Promise.<Array.<Commit>>}
23
- */
24
- export default function getCommits( transformCommit, options = {} ) {
25
- const releaseBranch = options.releaseBranch || 'master';
26
- const mainBranch = options.mainBranch || 'master';
27
-
28
- const currentBranch = exec( 'git rev-parse --abbrev-ref HEAD' ).trim();
29
-
30
- // Check whether current branch is the same as the release branch.
31
- if ( currentBranch !== releaseBranch ) {
32
- return Promise.reject( new Error(
33
- `Expected to be checked out on the release branch ("${ releaseBranch }") instead of "${ currentBranch }". Aborting.`
34
- ) );
35
- }
36
-
37
- // If the release branch is the same as the main branch, we can collect all commits directly from the branch.
38
- if ( releaseBranch === mainBranch ) {
39
- return findCommits( { from: options.from } );
40
- } else {
41
- // Otherwise, (release branch is other than the main branch) we need to merge arrays of commits.
42
- // See: https://github.com/ckeditor/ckeditor5/issues/7492.
43
- const baseCommit = exec( `git merge-base ${ shellEscape( [ releaseBranch, mainBranch ] ) }` ).trim();
44
-
45
- const commitPromises = [
46
- // 1. Commits from the last release and to the point where the release branch was created (the merge-base commit).
47
- findCommits( { from: options.from, to: baseCommit } ),
48
- // 2. Commits from the merge-base commit to HEAD.
49
- findCommits( { from: baseCommit, to: 'HEAD' } )
50
- ];
51
-
52
- return Promise.all( commitPromises )
53
- .then( commits => [].concat( ...commits ) );
54
- }
55
-
56
- function findCommits( gitRawCommitsOptions ) {
57
- const gitRawCommitsOpts = Object.assign( {}, gitRawCommitsOptions, {
58
- format: '%B%n-hash-%n%H',
59
- merges: undefined,
60
- firstParent: true
61
- } );
62
-
63
- return new Promise( ( resolve, reject ) => {
64
- const stream = getRawCommitsStream( gitRawCommitsOpts )
65
- .on( 'error', err => {
66
- /* istanbul ignore else */
67
- if ( err.message.match( /'HEAD': unknown/ ) ) {
68
- reject( new Error( 'Given repository is empty.' ) );
69
- } else if ( err.message.match( new RegExp( `'${ options.from }\\.\\.HEAD': unknown` ) ) ) {
70
- reject( new Error(
71
- `Cannot find tag or commit "${ options.from }" in given repository.`
72
- ) );
73
- } else {
74
- reject( err );
75
- }
76
- } );
77
-
78
- stream.pipe( parseCommitsStream( parserOptions ) )
79
- .pipe( concat( data => {
80
- const commits = [ ...filterRevertedCommitsSync( data ) ]
81
- .map( commit => transformCommit( commit ) )
82
- .reduce( ( allCommits, commit ) => {
83
- if ( Array.isArray( commit ) ) {
84
- allCommits.push( ...commit );
85
- } else {
86
- allCommits.push( commit );
87
- }
88
-
89
- return allCommits;
90
- }, [] )
91
- .filter( commit => commit );
92
-
93
- stream.destroy();
94
-
95
- return resolve( commits );
96
- } ) );
97
- } );
98
- }
99
-
100
- function exec( command ) {
101
- return tools.shExec( command, { verbosity: 'error' } );
102
- }
103
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import { format } from 'date-fns';
7
-
8
- /**
9
- * @returns {string}
10
- */
11
- export default function getFormattedDate() {
12
- return format( new Date(), 'yyyy-MM-dd' );
13
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- /**
7
- * Proposes new version based on commits.
8
- *
9
- * @param {Array.<Commit>} commits
10
- * @returns {string|null}
11
- */
12
- export default function getNewVersionType( commits ) {
13
- // No commits = no changes.
14
- if ( !commits.length ) {
15
- return 'skip';
16
- }
17
-
18
- const publicCommits = commits.filter( commit => commit.isPublicCommit );
19
-
20
- // No public commits = internal changes.
21
- if ( !publicCommits.length ) {
22
- return 'internal';
23
- }
24
-
25
- let newFeatures = false;
26
- let minorBreakingChanges = false;
27
-
28
- for ( const commit of publicCommits ) {
29
- for ( const note of commit.notes ) {
30
- if ( note.title === 'MAJOR BREAKING CHANGES' || note.title === 'BREAKING CHANGES' ) {
31
- return 'major';
32
- }
33
-
34
- /* istanbul ignore else */
35
- if ( note.title === 'MINOR BREAKING CHANGES' ) {
36
- minorBreakingChanges = true;
37
- }
38
- }
39
-
40
- if ( commit.rawType === 'Feature' ) {
41
- newFeatures = true;
42
- }
43
- }
44
-
45
- // Repository has new features or minor breaking changes.
46
- if ( minorBreakingChanges || newFeatures ) {
47
- return 'minor';
48
- }
49
-
50
- return 'patch';
51
- }
@@ -1,87 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import path from 'path';
7
- import { minimatch } from 'minimatch';
8
- import { tools, workspaces } from '@ckeditor/ckeditor5-dev-utils';
9
-
10
- /**
11
- * Returns an object with two collections of paths to packages which are located in single repository.
12
- * Those packages must be defined as dependencies in the repository found in `options.cwd`.
13
- *
14
- * - The first one is marked as `matched` and means that packages specified in a path (which is a combination of values specified as
15
- * `options.cwd` and `options.packages`) match to given criteria.
16
- * - The second one is marked as `skipped` and means that packages should not be processed. They were listed as packages to skip
17
- * (`options.skipPackages` or don't mach to `options.scope`).
18
- *
19
- * @param {object} options
20
- * @param {string} options.cwd Current work directory.
21
- * @param {string|null} options.packages Name of directory where to look for packages. If `null`, only repository specified under
22
- * `options.cwd` will be returned.
23
- * @param {string|Array.<string>} options.skipPackages Glob pattern(s) which describes which packages should be skipped.
24
- * @param {string} [options.scope] Package names have to match to specified glob pattern.
25
- * @param {boolean} [options.skipMainRepository=false] If set on true, package found in `options.cwd` will be skipped.
26
- * @returns {PathsCollection}
27
- */
28
- export default function getPackagesPaths( options ) {
29
- const pathsCollection = {
30
- matched: new Set(),
31
- skipped: new Set()
32
- };
33
-
34
- if ( options.skipMainRepository ) {
35
- pathsCollection.skipped.add( options.cwd );
36
- } else {
37
- pathsCollection.matched.add( options.cwd );
38
- }
39
-
40
- if ( !options.packages ) {
41
- return pathsCollection;
42
- }
43
-
44
- const packagesPath = path.join( options.cwd, options.packages );
45
- const skipPackages = Array.isArray( options.skipPackages ) ? options.skipPackages : [ options.skipPackages ];
46
-
47
- for ( const directory of tools.getDirectories( packagesPath ) ) {
48
- const dependencyPath = path.join( packagesPath, directory );
49
-
50
- try {
51
- const { name: dependencyName } = workspaces.getPackageJson( dependencyPath );
52
-
53
- if ( isValidPackage( dependencyName ) ) {
54
- pathsCollection.matched.add( dependencyPath );
55
- } else {
56
- pathsCollection.skipped.add( dependencyPath );
57
- }
58
- } catch {
59
- /* istanbul ignore next */
60
- console.warn( `Missing "package.json file in "${ dependencyPath }". Skipping.` );
61
- }
62
- }
63
-
64
- return pathsCollection;
65
-
66
- function isValidPackage( packageName ) {
67
- for ( const skipPackageGlob of skipPackages ) {
68
- if ( minimatch( packageName, skipPackageGlob ) ) {
69
- return false;
70
- }
71
- }
72
-
73
- if ( options.scope ) {
74
- return minimatch( packageName, options.scope );
75
- }
76
-
77
- return true;
78
- }
79
- }
80
-
81
- /**
82
- * @typedef {object} PathsCollection
83
- *
84
- * @property {Set.<string>} matched Packages that match given criteria.
85
- *
86
- * @property {Set.<string>} skipped Packages that do not match given criteria.
87
- */
@@ -1,42 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import fs from 'fs';
7
- import path from 'path';
8
- import { fileURLToPath } from 'url';
9
- import { getTypeOrder } from './transformcommitutils.js';
10
-
11
- const __filename = fileURLToPath( import.meta.url );
12
- const __dirname = path.dirname( __filename );
13
-
14
- const templatePath = path.join( __dirname, '..', 'templates' );
15
-
16
- /**
17
- * @param {WriterOptionsTransformCallback} transform
18
- * @returns {object}
19
- */
20
- export default function getWriterOptions( transform ) {
21
- return {
22
- transform,
23
- groupBy: 'type',
24
- commitGroupsSort: sortFunction,
25
- commitsSort: [ 'subject' ],
26
- noteGroupsSort: sortFunction,
27
- mainTemplate: fs.readFileSync( path.join( templatePath, 'template.hbs' ), 'utf-8' ),
28
- headerPartial: fs.readFileSync( path.join( templatePath, 'header.hbs' ), 'utf-8' ),
29
- commitPartial: fs.readFileSync( path.join( templatePath, 'commit.hbs' ), 'utf-8' ),
30
- footerPartial: fs.readFileSync( path.join( templatePath, 'footer.hbs' ), 'utf-8' )
31
- };
32
- }
33
-
34
- function sortFunction( a, b ) {
35
- return getTypeOrder( a.title ) - getTypeOrder( b.title );
36
- }
37
-
38
- /**
39
- * @callback WriterOptionsTransformCallback
40
- * @param {Commit}
41
- * @returns {Commit}
42
- */
@@ -1,24 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- export default {
7
- mergePattern: /^Merge .*$/,
8
- headerPattern: /^([^:]+): (.*)$/,
9
- headerCorrespondence: [
10
- 'type',
11
- 'subject'
12
- ],
13
- noteKeywords: [
14
- 'MAJOR BREAKING CHANGES',
15
- 'MAJOR BREAKING CHANGE',
16
- 'MINOR BREAKING CHANGES',
17
- 'MINOR BREAKING CHANGE',
18
- 'BREAKING CHANGES', // It will be treated as "MAJOR BREAKING CHANGES"
19
- 'BREAKING CHANGE' // An alias for "BREAKING CHANGES".
20
- ],
21
- revertPattern: /^Revert:\s([\s\S]*?)\s*This reverts commit (\w*)\./,
22
- revertCorrespondence: [ 'header', 'hash' ],
23
- referenceActions: []
24
- };
@@ -1,67 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import inquirer from 'inquirer';
7
- import semver from 'semver';
8
- import chalk from 'chalk';
9
- import { CLI_INDENT_SIZE } from './constants.js';
10
- import { npm } from '@ckeditor/ckeditor5-dev-utils';
11
-
12
- /**
13
- * Asks a user for providing the new version for a major release.
14
- *
15
- * @param {object} options
16
- * @param {string} options.packageName
17
- * @param {string} options.version
18
- * @param {string} options.bumpType
19
- * @param {number} [options.indentLevel=0] The indent level.
20
- * @returns {Promise.<string>}
21
- */
22
- export default async function provideNewVersionForMonoRepository( options ) {
23
- const {
24
- version,
25
- packageName,
26
- bumpType,
27
- indentLevel = 0
28
- } = options;
29
-
30
- const suggestedVersion = semver.inc( version, bumpType );
31
- const message = 'Type the new version ' +
32
- `(current highest: "${ version }" found in "${ chalk.underline( packageName ) }", suggested: "${ suggestedVersion }"):`;
33
-
34
- const versionQuestion = {
35
- type: 'input',
36
- name: 'version',
37
- default: suggestedVersion,
38
- message,
39
-
40
- filter( input ) {
41
- return input.trim();
42
- },
43
-
44
- async validate( input ) {
45
- if ( !semver.valid( input ) ) {
46
- return 'Please provide a valid version.';
47
- }
48
-
49
- if ( !semver.gt( input, version ) ) {
50
- return `Provided version must be higher than "${ version }".`;
51
- }
52
-
53
- const isAvailable = await npm.checkVersionAvailability( input, packageName );
54
-
55
- if ( !isAvailable ) {
56
- return 'Given version is already taken.';
57
- }
58
-
59
- return true;
60
- },
61
- prefix: ' '.repeat( indentLevel * CLI_INDENT_SIZE ) + chalk.cyan( '?' )
62
- };
63
-
64
- const answers = await inquirer.prompt( [ versionQuestion ] );
65
-
66
- return answers.version;
67
- }
@@ -1,115 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import inquirer from 'inquirer';
7
- import semver from 'semver';
8
- import chalk from 'chalk';
9
- import { CLI_INDENT_SIZE } from './constants.js';
10
- import { npm } from '@ckeditor/ckeditor5-dev-utils';
11
-
12
- /**
13
- * Asks a user for providing the new version.
14
- *
15
- * @param {object} options
16
- * @param {string} options.packageName
17
- * @param {string} options.version
18
- * @param {string|null} options.releaseTypeOrNewVersion
19
- * @param {boolean} [options.disableInternalVersion=false] Whether to "internal" version is enabled.
20
- * @param {boolean} [options.disableSkipVersion=false] Whether to "skip" version is enabled.
21
- * @param {number} [options.indentLevel=0] The indent level.
22
- * @returns {Promise.<string>}
23
- */
24
- export default function provideVersion( options ) {
25
- const {
26
- packageName,
27
- version,
28
- releaseTypeOrNewVersion,
29
- indentLevel = 0
30
- } = options;
31
-
32
- const suggestedVersion = getSuggestedVersion( {
33
- version,
34
- releaseTypeOrNewVersion,
35
- disableInternalVersion: options.disableInternalVersion
36
- } );
37
-
38
- let message = 'Type the new version, "skip" or "internal"';
39
-
40
- if ( options.disableInternalVersion ) {
41
- message = 'Type the new version or "skip"';
42
- }
43
-
44
- message += ` (suggested: "${ suggestedVersion }", current: "${ version }"):`;
45
-
46
- const versionQuestion = {
47
- type: 'input',
48
- name: 'version',
49
- default: suggestedVersion,
50
- message,
51
-
52
- filter( input ) {
53
- return input.trim();
54
- },
55
-
56
- async validate( input ) {
57
- if ( !options.disableSkipVersion && input === 'skip' ) {
58
- return true;
59
- }
60
-
61
- if ( !options.disableInternalVersion && input === 'internal' ) {
62
- return true;
63
- }
64
-
65
- if ( !semver.valid( input ) ) {
66
- return 'Please provide a valid version.';
67
- }
68
-
69
- const isAvailable = await npm.checkVersionAvailability( input, packageName );
70
-
71
- if ( !isAvailable ) {
72
- return 'Given version is already taken.';
73
- }
74
-
75
- return true;
76
- },
77
-
78
- prefix: ' '.repeat( indentLevel * CLI_INDENT_SIZE ) + chalk.cyan( '?' )
79
- };
80
-
81
- return inquirer.prompt( [ versionQuestion ] )
82
- .then( answers => answers.version );
83
- }
84
-
85
- /**
86
- * @param {object} options
87
- * @param {string} options.version
88
- * @param {string|null} options.releaseTypeOrNewVersion
89
- * @param {boolean} options.disableInternalVersion
90
- * @returns {string}
91
- */
92
- function getSuggestedVersion( { version, releaseTypeOrNewVersion, disableInternalVersion } ) {
93
- if ( !releaseTypeOrNewVersion || releaseTypeOrNewVersion === 'skip' ) {
94
- return 'skip';
95
- }
96
-
97
- if ( semver.valid( releaseTypeOrNewVersion ) ) {
98
- return releaseTypeOrNewVersion;
99
- }
100
-
101
- if ( releaseTypeOrNewVersion === 'internal' ) {
102
- return disableInternalVersion ? 'skip' : 'internal';
103
- }
104
-
105
- if ( semver.prerelease( version ) ) {
106
- releaseTypeOrNewVersion = 'prerelease';
107
- }
108
-
109
- // If package's version is below the '1.0.0', bump the 'minor' instead of 'major'
110
- if ( releaseTypeOrNewVersion === 'major' && semver.gt( '1.0.0', version ) ) {
111
- return semver.inc( version, 'minor' );
112
- }
113
-
114
- return semver.inc( version, releaseTypeOrNewVersion );
115
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- import fs from 'fs';
7
- import path from 'path';
8
- import { CHANGELOG_FILE } from './constants.js';
9
-
10
- /**
11
- * @param {string} content
12
- * @param {string} [cwd=process.cwd()] Where to look for the changelog file.
13
- */
14
- export default function saveChangelog( content, cwd = process.cwd() ) {
15
- const changelogFile = path.join( cwd, CHANGELOG_FILE );
16
-
17
- fs.writeFileSync( changelogFile, content, 'utf-8' );
18
- }