@ckeditor/ckeditor5-dev-release-tools 44.0.0 → 44.1.1
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.
- package/lib/index.js +1 -0
- package/lib/tasks/cleanuppackages.js +2 -6
- package/lib/tasks/commitandtag.js +12 -17
- package/lib/tasks/creategithubrelease.js +2 -14
- package/lib/tasks/generatechangelogformonorepository.js +8 -1
- package/lib/tasks/generatechangelogforsinglepackage.js +6 -3
- package/lib/tasks/publishpackages.js +79 -22
- package/lib/tasks/updatedependencies.js +12 -32
- package/lib/tasks/updateversions.js +16 -90
- package/lib/tasks/verifypackagespublishedcorrectly.js +14 -8
- package/lib/utils/assertnpmtag.js +8 -22
- package/lib/utils/checkversionavailability.js +6 -22
- package/lib/utils/executeinparallel.js +4 -10
- package/lib/utils/findpathstopackages.js +78 -0
- package/lib/utils/getnpmtagfromversion.js +9 -0
- package/lib/utils/isversionpublishablefortag.js +4 -6
- package/lib/utils/providenewversionformonorepository.js +26 -10
- package/lib/utils/provideversion.js +33 -16
- package/lib/utils/publishpackageonnpmcallback.js +7 -17
- package/lib/utils/versions.js +3 -2
- package/package.json +4 -2
package/lib/index.js
CHANGED
|
@@ -33,3 +33,4 @@ export { default as verifyPackagesPublishedCorrectly } from './tasks/verifypacka
|
|
|
33
33
|
export { default as getNpmTagFromVersion } from './utils/getnpmtagfromversion.js';
|
|
34
34
|
export { default as isVersionPublishableForTag } from './utils/isversionpublishablefortag.js';
|
|
35
35
|
export { default as provideToken } from './utils/providetoken.js';
|
|
36
|
+
export { default as findPathsToPackages } from './utils/findpathstopackages.js';
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import upath from 'upath';
|
|
8
8
|
import { glob } from 'glob';
|
|
9
|
+
import findPathsToPackages from '../utils/findpathstopackages.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* The purpose of the script is to clean all packages prepared for the release. The cleaning consists of two stages:
|
|
@@ -29,12 +30,7 @@ import { glob } from 'glob';
|
|
|
29
30
|
*/
|
|
30
31
|
export default async function cleanUpPackages( options ) {
|
|
31
32
|
const { packagesDirectory, packageJsonFieldsToRemove, preservePostInstallHook, cwd } = parseOptions( options );
|
|
32
|
-
|
|
33
|
-
const packageJsonPaths = await glob( '*/package.json', {
|
|
34
|
-
cwd: upath.join( cwd, packagesDirectory ),
|
|
35
|
-
nodir: true,
|
|
36
|
-
absolute: true
|
|
37
|
-
} );
|
|
33
|
+
const packageJsonPaths = await findPathsToPackages( cwd, packagesDirectory, { includePackageJson: true } );
|
|
38
34
|
|
|
39
35
|
for ( const packageJsonPath of packageJsonPaths ) {
|
|
40
36
|
const packagePath = upath.dirname( packageJsonPath );
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import upath from 'upath';
|
|
7
|
-
import { tools } from '@ckeditor/ckeditor5-dev-utils';
|
|
8
7
|
import { glob } from 'glob';
|
|
9
|
-
import
|
|
8
|
+
import { simpleGit } from 'simple-git';
|
|
10
9
|
|
|
11
10
|
const { toUnix } = upath;
|
|
12
11
|
|
|
@@ -27,22 +26,18 @@ export default async function commitAndTag( { version, files, cwd = process.cwd(
|
|
|
27
26
|
return;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
verbosity: 'silent'
|
|
34
|
-
};
|
|
29
|
+
const git = simpleGit( {
|
|
30
|
+
baseDir: normalizedCwd
|
|
31
|
+
} );
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await tools.shExec( `git add ${ shellEscape( [ filePath ] ) }`, shExecOptions );
|
|
39
|
-
}
|
|
33
|
+
const { all: availableTags } = await git.tags();
|
|
34
|
+
const tagForVersion = availableTags.find( tag => tag.endsWith( version ) );
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
36
|
+
// Do not commit and create tags if a tag is already taken. It might happen when a release job is restarted.
|
|
37
|
+
if ( tagForVersion ) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
45
40
|
|
|
46
|
-
await
|
|
47
|
-
await
|
|
41
|
+
await git.commit( `Release: v${ version }.`, filePathsToAdd );
|
|
42
|
+
await git.addTag( `v${ version }` );
|
|
48
43
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Octokit } from '@octokit/rest';
|
|
7
|
-
import semver from 'semver';
|
|
8
7
|
import * as transformCommitUtils from '../utils/transformcommitutils.js';
|
|
8
|
+
import getNpmTagFromVersion from '../utils/getnpmtagfromversion.js';
|
|
9
9
|
|
|
10
10
|
const { getRepositoryUrl } = transformCommitUtils;
|
|
11
11
|
|
|
@@ -41,25 +41,13 @@ export default async function createGithubRelease( options ) {
|
|
|
41
41
|
owner: repositoryOwner,
|
|
42
42
|
repo: repositoryName,
|
|
43
43
|
body: description,
|
|
44
|
-
prerelease:
|
|
44
|
+
prerelease: getNpmTagFromVersion( version ) !== 'latest'
|
|
45
45
|
} );
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return `https://github.com/${ repositoryOwner }/${ repositoryName }/releases/tag/v${ version }`;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
/**
|
|
52
|
-
* Returns an npm tag based on the specified release version.
|
|
53
|
-
*
|
|
54
|
-
* @param {string} version
|
|
55
|
-
* @returns {string}
|
|
56
|
-
*/
|
|
57
|
-
function getVersionTag( version ) {
|
|
58
|
-
const [ versionTag ] = semver.prerelease( version ) || [ 'latest' ];
|
|
59
|
-
|
|
60
|
-
return versionTag;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
51
|
/**
|
|
64
52
|
* Resolves a promise containing a flag if the GitHub contains the release page for given version.
|
|
65
53
|
*
|
|
@@ -301,7 +301,14 @@ export default async function generateChangelogForMonoRepository( options ) {
|
|
|
301
301
|
bumpType = 'patch';
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
|
|
304
|
+
const provideVersionOptions = {
|
|
305
|
+
packageName: packageHighestVersion,
|
|
306
|
+
version: highestVersion,
|
|
307
|
+
bumpType,
|
|
308
|
+
indentLevel: 1
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return provideNewVersionForMonoRepository( provideVersionOptions )
|
|
305
312
|
.then( version => {
|
|
306
313
|
nextVersion = version;
|
|
307
314
|
|
|
@@ -79,11 +79,14 @@ export default async function generateChangelogForSinglePackage( options = {} )
|
|
|
79
79
|
.then( () => {
|
|
80
80
|
logProcess( 'Preparing new version for the package...' );
|
|
81
81
|
|
|
82
|
-
const releaseType = getNewVersionType( allCommits );
|
|
83
|
-
|
|
84
82
|
displayCommits( allCommits, { indentLevel: 1 } );
|
|
85
83
|
|
|
86
|
-
return provideVersion(
|
|
84
|
+
return provideVersion( {
|
|
85
|
+
packageName: pkgJson.name,
|
|
86
|
+
version: pkgJson.version,
|
|
87
|
+
indentLevel: 1,
|
|
88
|
+
releaseTypeOrNewVersion: getNewVersionType( allCommits )
|
|
89
|
+
} );
|
|
87
90
|
} )
|
|
88
91
|
.then( version => {
|
|
89
92
|
if ( version === 'skip' ) {
|
|
@@ -4,44 +4,50 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import upath from 'upath';
|
|
7
|
-
import
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
8
|
import assertNpmAuthorization from '../utils/assertnpmauthorization.js';
|
|
9
9
|
import assertPackages from '../utils/assertpackages.js';
|
|
10
10
|
import assertNpmTag from '../utils/assertnpmtag.js';
|
|
11
11
|
import assertFilesToPublish from '../utils/assertfilestopublish.js';
|
|
12
12
|
import executeInParallel from '../utils/executeinparallel.js';
|
|
13
13
|
import publishPackageOnNpmCallback from '../utils/publishpackageonnpmcallback.js';
|
|
14
|
+
import checkVersionAvailability from '../utils/checkversionavailability.js';
|
|
15
|
+
import findPathsToPackages from '../utils/findpathstopackages.js';
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* The purpose of the script is to validate the packages prepared for the release and then release them on npm.
|
|
17
19
|
*
|
|
18
20
|
* The validation contains the following steps in each package:
|
|
19
21
|
* - User must be logged to npm on the specified account.
|
|
20
|
-
* - The package directory
|
|
22
|
+
* - The package directory must contain `package.json` file.
|
|
21
23
|
* - All other files expected to be released must exist in the package directory.
|
|
22
24
|
* - The npm tag must match the tag calculated from the package version.
|
|
23
25
|
*
|
|
24
26
|
* When the validation for each package passes, packages are published on npm. Optional callback is called for confirmation whether to
|
|
25
27
|
* continue.
|
|
26
28
|
*
|
|
29
|
+
* If a package has already been published, the script does not try to publish it again. Instead, it treats the package as published.
|
|
30
|
+
* Whenever a communication between the script and npm fails, it tries to re-publish a package (up to three attempts).
|
|
31
|
+
*
|
|
27
32
|
* @param {object} options
|
|
28
33
|
* @param {string} options.packagesDirectory Relative path to a location of packages to release.
|
|
29
34
|
* @param {string} options.npmOwner The account name on npm, which should be used to publish the packages.
|
|
30
|
-
* @param {ListrTaskObject} options.listrTask An instance of `ListrTask`.
|
|
35
|
+
* @param {ListrTaskObject} [options.listrTask] An instance of `ListrTask`.
|
|
31
36
|
* @param {AbortSignal|null} [options.signal=null] Signal to abort the asynchronous process.
|
|
32
37
|
* @param {string} [options.npmTag='staging'] The npm distribution tag.
|
|
33
38
|
* @param {Object.<string, Array.<string>>|null} [options.optionalEntries=null] Specifies which entries from the `files` field in the
|
|
34
39
|
* `package.json` are optional. The key is a package name, and its value is an array of optional entries from the `files` field, for which
|
|
35
40
|
* it is allowed not to match any file. The `options.optionalEntries` object may also contain the `default` key, which is used for all
|
|
36
41
|
* packages that do not have own definition.
|
|
37
|
-
* @param {
|
|
38
|
-
* and asynchronous callbacks are supported.
|
|
42
|
+
* @param {function|null} [options.confirmationCallback=null] An callback whose response decides to continue the publishing packages.
|
|
43
|
+
* Synchronous and asynchronous callbacks are supported.
|
|
39
44
|
* @param {boolean} [options.requireEntryPoint=false] Whether to verify if packages to publish define an entry point. In other words,
|
|
40
45
|
* whether their `package.json` define the `main` field.
|
|
41
46
|
* @param {Array.<string>} [options.optionalEntryPointPackages=[]] If the entry point validator is enabled (`requireEntryPoint=true`),
|
|
42
47
|
* this array contains a list of packages that will not be checked. In other words, they do not have to define the entry point.
|
|
43
48
|
* @param {string} [options.cwd=process.cwd()] Current working directory from which all paths will be resolved.
|
|
44
49
|
* @param {number} [options.concurrency=4] Number of CPUs that will execute the task.
|
|
50
|
+
* @param {number} [options.attempts=3] Number of attempts. After reaching 0, it won't be publishing packages again.
|
|
45
51
|
* @returns {Promise}
|
|
46
52
|
*/
|
|
47
53
|
export default async function publishPackages( options ) {
|
|
@@ -56,15 +62,14 @@ export default async function publishPackages( options ) {
|
|
|
56
62
|
requireEntryPoint = false,
|
|
57
63
|
optionalEntryPointPackages = [],
|
|
58
64
|
cwd = process.cwd(),
|
|
59
|
-
concurrency = 4
|
|
65
|
+
concurrency = 4,
|
|
66
|
+
attempts = 3
|
|
60
67
|
} = options;
|
|
61
68
|
|
|
69
|
+
const remainingAttempts = attempts - 1;
|
|
62
70
|
await assertNpmAuthorization( npmOwner );
|
|
63
71
|
|
|
64
|
-
const packagePaths = await
|
|
65
|
-
cwd: upath.join( cwd, packagesDirectory ),
|
|
66
|
-
absolute: true
|
|
67
|
-
} );
|
|
72
|
+
const packagePaths = await findPathsToPackages( cwd, packagesDirectory );
|
|
68
73
|
|
|
69
74
|
await assertPackages( packagePaths, { requireEntryPoint, optionalEntryPointPackages } );
|
|
70
75
|
await assertFilesToPublish( packagePaths, optionalEntries );
|
|
@@ -72,17 +77,69 @@ export default async function publishPackages( options ) {
|
|
|
72
77
|
|
|
73
78
|
const shouldPublishPackages = confirmationCallback ? await confirmationCallback() : true;
|
|
74
79
|
|
|
75
|
-
if ( shouldPublishPackages ) {
|
|
76
|
-
|
|
77
|
-
cwd,
|
|
78
|
-
packagesDirectory,
|
|
79
|
-
listrTask,
|
|
80
|
-
taskToExecute: publishPackageOnNpmCallback,
|
|
81
|
-
taskOptions: {
|
|
82
|
-
npmTag
|
|
83
|
-
},
|
|
84
|
-
signal,
|
|
85
|
-
concurrency
|
|
86
|
-
} );
|
|
80
|
+
if ( !shouldPublishPackages ) {
|
|
81
|
+
return Promise.resolve();
|
|
87
82
|
}
|
|
83
|
+
|
|
84
|
+
await removeAlreadyPublishedPackages( packagePaths );
|
|
85
|
+
|
|
86
|
+
await executeInParallel( {
|
|
87
|
+
cwd,
|
|
88
|
+
packagesDirectory,
|
|
89
|
+
listrTask,
|
|
90
|
+
taskToExecute: publishPackageOnNpmCallback,
|
|
91
|
+
taskOptions: {
|
|
92
|
+
npmTag
|
|
93
|
+
},
|
|
94
|
+
signal,
|
|
95
|
+
concurrency
|
|
96
|
+
} );
|
|
97
|
+
|
|
98
|
+
const packagePathsAfterPublishing = await findPathsToPackages( cwd, packagesDirectory );
|
|
99
|
+
|
|
100
|
+
// All packages have been published. No need for re-executing.
|
|
101
|
+
if ( !packagePathsAfterPublishing.length ) {
|
|
102
|
+
return Promise.resolve();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// No more attempts. Abort.
|
|
106
|
+
if ( remainingAttempts <= 0 ) {
|
|
107
|
+
throw new Error( 'Some packages could not be published.' );
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Let's give an npm a moment for taking a breath...
|
|
111
|
+
await wait( 1000 );
|
|
112
|
+
|
|
113
|
+
// ...and try again.
|
|
114
|
+
return publishPackages( {
|
|
115
|
+
packagesDirectory,
|
|
116
|
+
npmOwner,
|
|
117
|
+
listrTask,
|
|
118
|
+
signal,
|
|
119
|
+
npmTag,
|
|
120
|
+
optionalEntries,
|
|
121
|
+
requireEntryPoint,
|
|
122
|
+
optionalEntryPointPackages,
|
|
123
|
+
cwd,
|
|
124
|
+
concurrency,
|
|
125
|
+
confirmationCallback: null, // Do not ask again if already here.
|
|
126
|
+
attempts: remainingAttempts
|
|
127
|
+
} );
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function removeAlreadyPublishedPackages( packagePaths ) {
|
|
131
|
+
for ( const absolutePackagePath of packagePaths ) {
|
|
132
|
+
const pkgJson = await fs.readJson( upath.join( absolutePackagePath, 'package.json' ) );
|
|
133
|
+
const isAvailable = await checkVersionAvailability( pkgJson.version, pkgJson.name );
|
|
134
|
+
|
|
135
|
+
if ( !isAvailable ) {
|
|
136
|
+
await fs.remove( absolutePackagePath );
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function wait( time ) {
|
|
142
|
+
return new Promise( resolve => {
|
|
143
|
+
setTimeout( resolve, time );
|
|
144
|
+
} );
|
|
88
145
|
}
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
|
-
import { glob } from 'glob';
|
|
8
7
|
import upath from 'upath';
|
|
8
|
+
import findPathsToPackages from '../utils/findpathstopackages.js';
|
|
9
|
+
|
|
10
|
+
const { normalizeTrim } = upath;
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* The purpose of this script is to update all eligible dependencies to a version specified in the `options.version`. The following packages
|
|
@@ -38,15 +40,15 @@ export default async function updateDependencies( options ) {
|
|
|
38
40
|
cwd = process.cwd()
|
|
39
41
|
} = options;
|
|
40
42
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
const pkgJsonPaths = await findPathsToPackages(
|
|
44
|
+
cwd,
|
|
45
|
+
packagesDirectory ? normalizeTrim( packagesDirectory ) : null,
|
|
46
|
+
{
|
|
47
|
+
includePackageJson: true,
|
|
48
|
+
includeCwd: true,
|
|
49
|
+
packagesDirectoryFilter
|
|
50
|
+
}
|
|
51
|
+
);
|
|
50
52
|
|
|
51
53
|
for ( const pkgJsonPath of pkgJsonPaths ) {
|
|
52
54
|
const pkgJson = await fs.readJson( pkgJsonPath );
|
|
@@ -78,28 +80,6 @@ function updateVersion( version, callback, dependencies ) {
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
/**
|
|
82
|
-
* @param {string} cwd
|
|
83
|
-
* @param {Array.<string>} globPatterns
|
|
84
|
-
* @param {UpdateDependenciesPackagesDirectoryFilter|null} packagesDirectoryFilter
|
|
85
|
-
* @returns {Promise.<Array.<string>>}
|
|
86
|
-
*/
|
|
87
|
-
async function getPackageJsonPaths( cwd, globPatterns, packagesDirectoryFilter ) {
|
|
88
|
-
const globOptions = {
|
|
89
|
-
cwd,
|
|
90
|
-
nodir: true,
|
|
91
|
-
absolute: true
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const pkgJsonPaths = await glob( globPatterns, globOptions );
|
|
95
|
-
|
|
96
|
-
if ( !packagesDirectoryFilter ) {
|
|
97
|
-
return pkgJsonPaths;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return pkgJsonPaths.filter( packagesDirectoryFilter );
|
|
101
|
-
}
|
|
102
|
-
|
|
103
83
|
/**
|
|
104
84
|
* @callback UpdateVersionCallback
|
|
105
85
|
*
|
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
import upath from 'upath';
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
|
-
import { glob } from 'glob';
|
|
9
8
|
import semver from 'semver';
|
|
10
|
-
import
|
|
9
|
+
import findPathsToPackages from '../utils/findpathstopackages.js';
|
|
11
10
|
|
|
12
|
-
const { normalizeTrim
|
|
11
|
+
const { normalizeTrim } = upath;
|
|
13
12
|
|
|
14
13
|
/**
|
|
15
14
|
* The purpose of the script is to update the version of a root package found in the current working
|
|
@@ -38,24 +37,18 @@ export default async function updateVersions( options ) {
|
|
|
38
37
|
packagesDirectoryFilter = null,
|
|
39
38
|
cwd = process.cwd()
|
|
40
39
|
} = options;
|
|
41
|
-
const normalizedCwd = toUnix( cwd );
|
|
42
|
-
const normalizedPackagesDir = packagesDirectory ? normalizeTrim( packagesDirectory ) : null;
|
|
43
40
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
const pkgJsonPaths = await findPathsToPackages(
|
|
42
|
+
cwd,
|
|
43
|
+
packagesDirectory ? normalizeTrim( packagesDirectory ) : null,
|
|
44
|
+
{
|
|
45
|
+
includePackageJson: true,
|
|
46
|
+
includeCwd: true,
|
|
47
|
+
packagesDirectoryFilter
|
|
48
|
+
}
|
|
49
|
+
);
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if ( !isVersionAvailable ) {
|
|
57
|
-
throw new Error( `The "${ randomPackageName }@${ version }" already exists in the npm registry.` );
|
|
58
|
-
}
|
|
51
|
+
checkIfVersionIsValid( version );
|
|
59
52
|
|
|
60
53
|
for ( const pkgJsonPath of pkgJsonPaths ) {
|
|
61
54
|
const pkgJson = await fs.readJson( pkgJsonPath );
|
|
@@ -66,78 +59,11 @@ export default async function updateVersions( options ) {
|
|
|
66
59
|
}
|
|
67
60
|
|
|
68
61
|
/**
|
|
69
|
-
* @param {string}
|
|
70
|
-
* @param {Array.<string>} globPatterns
|
|
71
|
-
* @param {UpdateVersionsPackagesDirectoryFilter|null} packagesDirectoryFilter
|
|
72
|
-
* @returns {Promise.<Array.<string>>}
|
|
73
|
-
*/
|
|
74
|
-
async function getPackageJsonPaths( cwd, globPatterns, packagesDirectoryFilter ) {
|
|
75
|
-
const pkgJsonPaths = await glob( globPatterns, {
|
|
76
|
-
cwd,
|
|
77
|
-
absolute: true,
|
|
78
|
-
nodir: true
|
|
79
|
-
} );
|
|
80
|
-
|
|
81
|
-
if ( !packagesDirectoryFilter ) {
|
|
82
|
-
return pkgJsonPaths;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return pkgJsonPaths.filter( packagesDirectoryFilter );
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @param {string} packagesDirectory
|
|
90
|
-
* @returns {Promise.<object>}
|
|
62
|
+
* @param {string} version
|
|
91
63
|
*/
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return fs.readJson( packageJsonPath );
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @param {string|null} packagesDirectory
|
|
100
|
-
* @returns {Array.<string>}
|
|
101
|
-
*/
|
|
102
|
-
function getGlobPatterns( packagesDirectory ) {
|
|
103
|
-
const patterns = [ 'package.json' ];
|
|
104
|
-
|
|
105
|
-
if ( packagesDirectory ) {
|
|
106
|
-
patterns.push( packagesDirectory + '/*/package.json' );
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return patterns;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @param {Array.<string>} pkgJsonPaths
|
|
114
|
-
* @param {string|null} packagesDirectory
|
|
115
|
-
* @returns {object}
|
|
116
|
-
*/
|
|
117
|
-
function getRandomPackagePath( pkgJsonPaths, packagesDirectory ) {
|
|
118
|
-
const randomPkgJsonPaths = packagesDirectory ?
|
|
119
|
-
pkgJsonPaths.filter( packagePath => packagePath.includes( packagesDirectory ) ) :
|
|
120
|
-
pkgJsonPaths;
|
|
121
|
-
const randomPkgJsonPath = randomPkgJsonPaths[ Math.floor( Math.random() * randomPkgJsonPaths.length ) ];
|
|
122
|
-
|
|
123
|
-
return dirname( randomPkgJsonPath );
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Checks if the specified version is greater than the current one.
|
|
128
|
-
*
|
|
129
|
-
* A nightly version is always considered as valid.
|
|
130
|
-
*
|
|
131
|
-
* @param {string} newVersion
|
|
132
|
-
* @param {string} currentVersion
|
|
133
|
-
*/
|
|
134
|
-
function checkIfVersionIsValid( newVersion, currentVersion ) {
|
|
135
|
-
if ( newVersion.startsWith( '0.0.0-nightly' ) ) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if ( !semver.gt( newVersion, currentVersion ) ) {
|
|
140
|
-
throw new Error( `Provided version ${ newVersion } must be greater than ${ currentVersion } or match pattern 0.0.0-nightly.` );
|
|
64
|
+
function checkIfVersionIsValid( version ) {
|
|
65
|
+
if ( !semver.valid( version ) ) {
|
|
66
|
+
throw new Error( `Provided version ${ version } must follow the "Semantic Versioning" standard.` );
|
|
141
67
|
}
|
|
142
68
|
}
|
|
143
69
|
|
|
@@ -19,6 +19,16 @@ import checkVersionAvailability from '../utils/checkversionavailability.js';
|
|
|
19
19
|
* @returns {Promise}
|
|
20
20
|
*/
|
|
21
21
|
export default async function verifyPackagesPublishedCorrectly( options ) {
|
|
22
|
+
process.emitWarning(
|
|
23
|
+
'The `verifyPackagesPublishedCorrectly()` function is deprecated and will be removed in the upcoming release (v45). ' +
|
|
24
|
+
'Its responsibility has been merged with `publishPackages()`.',
|
|
25
|
+
{
|
|
26
|
+
type: 'DeprecationWarning',
|
|
27
|
+
code: 'DEP0001',
|
|
28
|
+
detail: 'https://github.com/ckeditor/ckeditor5-dev/blob/master/DEPRECATIONS.md#dep0001-verifypackagespublishedcorrectly'
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
22
32
|
const { packagesDirectory, version, onSuccess } = options;
|
|
23
33
|
const packagesToVerify = await glob( upath.join( packagesDirectory, '*' ), { absolute: true } );
|
|
24
34
|
const errors = [];
|
|
@@ -32,16 +42,12 @@ export default async function verifyPackagesPublishedCorrectly( options ) {
|
|
|
32
42
|
for ( const packageToVerify of packagesToVerify ) {
|
|
33
43
|
const packageJson = await fs.readJson( upath.join( packageToVerify, 'package.json' ) );
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
const packageWasUploadedCorrectly = !await checkVersionAvailability( version, packageJson.name );
|
|
45
|
+
const isPackageVersionAvailable = await checkVersionAvailability( version, packageJson.name );
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
await fs.remove( packageToVerify );
|
|
40
|
-
} else {
|
|
41
|
-
errors.push( packageJson.name );
|
|
42
|
-
}
|
|
43
|
-
} catch {
|
|
47
|
+
if ( isPackageVersionAvailable ) {
|
|
44
48
|
errors.push( packageJson.name );
|
|
49
|
+
} else {
|
|
50
|
+
await fs.remove( packageToVerify );
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import upath from 'upath';
|
|
8
|
-
import
|
|
8
|
+
import getNpmTagFromVersion from './getnpmtagfromversion.js';
|
|
9
|
+
|
|
10
|
+
const ALLOWED_NPM_LATEST_TAGS = [
|
|
11
|
+
'staging',
|
|
12
|
+
'next'
|
|
13
|
+
];
|
|
9
14
|
|
|
10
15
|
/**
|
|
11
16
|
* Checks if the npm tag matches the tag calculated from the package version. Verification takes place for all packages.
|
|
@@ -20,13 +25,13 @@ export default async function assertNpmTag( packagePaths, npmTag ) {
|
|
|
20
25
|
for ( const packagePath of packagePaths ) {
|
|
21
26
|
const packageJsonPath = upath.join( packagePath, 'package.json' );
|
|
22
27
|
const packageJson = await fs.readJson( packageJsonPath );
|
|
23
|
-
const versionTag =
|
|
28
|
+
const versionTag = getNpmTagFromVersion( packageJson.version );
|
|
24
29
|
|
|
25
30
|
if ( versionTag === npmTag ) {
|
|
26
31
|
continue;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
if ( versionTag === 'latest' && npmTag
|
|
34
|
+
if ( versionTag === 'latest' && ALLOWED_NPM_LATEST_TAGS.includes( npmTag ) ) {
|
|
30
35
|
continue;
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -37,22 +42,3 @@ export default async function assertNpmTag( packagePaths, npmTag ) {
|
|
|
37
42
|
throw new Error( errors.join( '\n' ) );
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Returns the version tag for the package.
|
|
43
|
-
*
|
|
44
|
-
* For the official release, returns the "latest" tag. For a non-official release (pre-release), returns the version tag extracted from
|
|
45
|
-
* the package version.
|
|
46
|
-
*
|
|
47
|
-
* @param {string} version
|
|
48
|
-
* @returns {string}
|
|
49
|
-
*/
|
|
50
|
-
function getVersionTag( version ) {
|
|
51
|
-
const [ versionTag ] = semver.prerelease( version ) || [ 'latest' ];
|
|
52
|
-
|
|
53
|
-
if ( versionTag.startsWith( 'nightly' ) ) {
|
|
54
|
-
return 'nightly';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return versionTag;
|
|
58
|
-
}
|
|
@@ -3,41 +3,25 @@
|
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import shellEscape from 'shell-escape';
|
|
6
|
+
import pacote from 'pacote';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Checks if the provided version for the package exists in the npm registry.
|
|
11
10
|
*
|
|
12
11
|
* Returns a promise that resolves to `true` if the provided version does not exist or resolves the promise to `false` otherwise.
|
|
13
|
-
* If the `npm show` command exits with an error, it is re-thrown.
|
|
14
12
|
*
|
|
15
13
|
* @param {string} version
|
|
16
14
|
* @param {string} packageName
|
|
17
15
|
* @returns {Promise}
|
|
18
16
|
*/
|
|
19
17
|
export default async function checkVersionAvailability( version, packageName ) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
.then( result => {
|
|
24
|
-
// Explicit check for npm < 8.13.0, which does not return anything (an empty result) and it exits with a zero status code when
|
|
25
|
-
// the version for the provided package does not exist in the npm registry.
|
|
26
|
-
if ( !result ) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Provided version exists in the npm registry.
|
|
18
|
+
return pacote.manifest( `${ packageName }@${ version }` )
|
|
19
|
+
.then( () => {
|
|
20
|
+
// If `pacote.manifest` resolves, a package with the given version exists.
|
|
31
21
|
return false;
|
|
32
22
|
} )
|
|
33
|
-
.catch(
|
|
34
|
-
//
|
|
35
|
-
if ( !error.toString().includes( 'code E404' ) ) {
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Npm >= 8.13.0 throws an "E404" error if a version does not exist.
|
|
40
|
-
// Npm < 8.13.0 should never reach this line.
|
|
23
|
+
.catch( () => {
|
|
24
|
+
// When throws, the package does not exist.
|
|
41
25
|
return true;
|
|
42
26
|
} );
|
|
43
27
|
}
|
|
@@ -10,8 +10,8 @@ import upath from 'upath';
|
|
|
10
10
|
import os from 'os';
|
|
11
11
|
import fs from 'fs/promises';
|
|
12
12
|
import { Worker } from 'worker_threads';
|
|
13
|
-
import { glob } from 'glob';
|
|
14
13
|
import { registerAbortController, deregisterAbortController } from './abortcontroller.js';
|
|
14
|
+
import findPathsToPackages from './findpathstopackages.js';
|
|
15
15
|
|
|
16
16
|
const WORKER_SCRIPT = new URL( './parallelworker.js', import.meta.url );
|
|
17
17
|
|
|
@@ -49,15 +49,9 @@ export default async function executeInParallel( options ) {
|
|
|
49
49
|
} = options;
|
|
50
50
|
|
|
51
51
|
const concurrencyAsInteger = Math.floor( concurrency ) || 1;
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
absolute: true
|
|
56
|
-
} ) ).map( upath.normalize );
|
|
57
|
-
|
|
58
|
-
const packagesToProcess = packagesDirectoryFilter ?
|
|
59
|
-
packages.filter( packagesDirectoryFilter ) :
|
|
60
|
-
packages;
|
|
52
|
+
const packagesToProcess = await findPathsToPackages( cwd, packagesDirectory, {
|
|
53
|
+
packagesDirectoryFilter
|
|
54
|
+
} );
|
|
61
55
|
|
|
62
56
|
const packagesInThreads = getPackagesGroupedByThreads( packagesToProcess, concurrencyAsInteger );
|
|
63
57
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import upath from 'upath';
|
|
7
|
+
import { glob } from 'glob';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns an array containing paths to packages found in the `packagesDirectory` directory.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} cwd
|
|
13
|
+
* @param {string|null} packagesDirectory
|
|
14
|
+
* @param {object} [options={}]
|
|
15
|
+
* @param {boolean} [options.includePackageJson=false]
|
|
16
|
+
* @param {boolean} [options.includeCwd=false]
|
|
17
|
+
* @param {PackagesDirectoryFilter|null} [options.packagesDirectoryFilter=null]
|
|
18
|
+
* @returns {Array.<string>}
|
|
19
|
+
*/
|
|
20
|
+
export default async function findPathsToPackages( cwd, packagesDirectory, options = {} ) {
|
|
21
|
+
const {
|
|
22
|
+
includePackageJson = false,
|
|
23
|
+
includeCwd = false,
|
|
24
|
+
packagesDirectoryFilter = null
|
|
25
|
+
} = options;
|
|
26
|
+
|
|
27
|
+
const packagePaths = await getPackages( cwd, packagesDirectory, includePackageJson );
|
|
28
|
+
|
|
29
|
+
if ( includeCwd ) {
|
|
30
|
+
if ( includePackageJson ) {
|
|
31
|
+
packagePaths.push( upath.join( cwd, 'package.json' ) );
|
|
32
|
+
} else {
|
|
33
|
+
packagePaths.push( cwd );
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const normalizedPaths = packagePaths.map( item => upath.normalize( item ) );
|
|
38
|
+
|
|
39
|
+
if ( packagesDirectoryFilter ) {
|
|
40
|
+
return normalizedPaths.filter( item => packagesDirectoryFilter( item ) );
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return normalizedPaths;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} cwd
|
|
48
|
+
* @param {string|null} packagesDirectory
|
|
49
|
+
* @param {boolean} includePackageJson
|
|
50
|
+
* @returns {Promise.<Array.<string>>}
|
|
51
|
+
*/
|
|
52
|
+
function getPackages( cwd, packagesDirectory, includePackageJson ) {
|
|
53
|
+
if ( !packagesDirectory ) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const globOptions = {
|
|
58
|
+
cwd: upath.join( cwd, packagesDirectory ),
|
|
59
|
+
absolute: true
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
let pattern = '*/';
|
|
63
|
+
|
|
64
|
+
if ( includePackageJson ) {
|
|
65
|
+
pattern += 'package.json';
|
|
66
|
+
globOptions.nodir = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return glob( pattern, globOptions );
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @callback PackagesDirectoryFilter
|
|
74
|
+
*
|
|
75
|
+
* @param {string} packageJsonPath An absolute path to a `package.json` file.
|
|
76
|
+
*
|
|
77
|
+
* @returns {boolean} Whether to include (`true`) or skip (`false`) processing the given directory/package.
|
|
78
|
+
*/
|
|
@@ -6,11 +6,20 @@
|
|
|
6
6
|
import semver from 'semver';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
+
* Returns a version tag from specified `version`.
|
|
10
|
+
*
|
|
11
|
+
* For the official release, returns the "latest" tag. For a non-official release (pre-release),
|
|
12
|
+
* returns the version tag extracted from the passed version.
|
|
13
|
+
*
|
|
9
14
|
* @param {string} version
|
|
10
15
|
* @returns {string}
|
|
11
16
|
*/
|
|
12
17
|
export default function getNpmTagFromVersion( version ) {
|
|
13
18
|
const [ versionTag ] = semver.prerelease( version ) || [ 'latest' ];
|
|
14
19
|
|
|
20
|
+
if ( versionTag.startsWith( 'nightly' ) ) {
|
|
21
|
+
return 'nightly';
|
|
22
|
+
}
|
|
23
|
+
|
|
15
24
|
return versionTag;
|
|
16
25
|
}
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { tools } from '@ckeditor/ckeditor5-dev-utils';
|
|
7
6
|
import semver from 'semver';
|
|
8
|
-
import
|
|
7
|
+
import pacote from 'pacote';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* This util aims to verify if the given `packageName` can be published with the given `version` on the `npmTag`.
|
|
@@ -16,10 +15,9 @@ import shellEscape from 'shell-escape';
|
|
|
16
15
|
* @returns {Promise.<boolean>}
|
|
17
16
|
*/
|
|
18
17
|
export default async function isVersionPublishableForTag( packageName, version, npmTag ) {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// An `npmTag` does not exist.
|
|
18
|
+
const npmVersion = await pacote.manifest( `${ packageName }@${ npmTag }` )
|
|
19
|
+
.then( ( { version } ) => version )
|
|
20
|
+
// An `npmTag` does not exist, or it's a first release of a package.
|
|
23
21
|
.catch( () => null );
|
|
24
22
|
|
|
25
23
|
if ( npmVersion && semver.lte( version, npmVersion ) ) {
|
|
@@ -7,23 +7,29 @@ import inquirer from 'inquirer';
|
|
|
7
7
|
import semver from 'semver';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { CLI_INDENT_SIZE } from './constants.js';
|
|
10
|
+
import checkVersionAvailability from './checkversionavailability.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Asks a user for providing the new version for a major release.
|
|
13
14
|
*
|
|
14
|
-
* @param {
|
|
15
|
-
* @param {string}
|
|
16
|
-
* @param {string}
|
|
17
|
-
* @param {
|
|
15
|
+
* @param {object} options
|
|
16
|
+
* @param {string} options.packageName
|
|
17
|
+
* @param {string} options.version
|
|
18
|
+
* @param {string} options.bumpType
|
|
18
19
|
* @param {number} [options.indentLevel=0] The indent level.
|
|
19
20
|
* @returns {Promise.<string>}
|
|
20
21
|
*/
|
|
21
|
-
export default async function provideNewVersionForMonoRepository(
|
|
22
|
-
const
|
|
23
|
-
|
|
22
|
+
export default async function provideNewVersionForMonoRepository( options ) {
|
|
23
|
+
const {
|
|
24
|
+
version,
|
|
25
|
+
packageName,
|
|
26
|
+
bumpType,
|
|
27
|
+
indentLevel = 0
|
|
28
|
+
} = options;
|
|
24
29
|
|
|
30
|
+
const suggestedVersion = semver.inc( version, bumpType );
|
|
25
31
|
const message = 'Type the new version ' +
|
|
26
|
-
`(current highest: "${ version }" found in "${ chalk.underline(
|
|
32
|
+
`(current highest: "${ version }" found in "${ chalk.underline( packageName ) }", suggested: "${ suggestedVersion }"):`;
|
|
27
33
|
|
|
28
34
|
const versionQuestion = {
|
|
29
35
|
type: 'input',
|
|
@@ -35,12 +41,22 @@ export default async function provideNewVersionForMonoRepository( version, found
|
|
|
35
41
|
return input.trim();
|
|
36
42
|
},
|
|
37
43
|
|
|
38
|
-
validate( input ) {
|
|
44
|
+
async validate( input ) {
|
|
39
45
|
if ( !semver.valid( input ) ) {
|
|
40
46
|
return 'Please provide a valid version.';
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
if ( !semver.gt( input, version ) ) {
|
|
50
|
+
return `Provided version must be higher than "${ version }".`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const isAvailable = await checkVersionAvailability( input, packageName );
|
|
54
|
+
|
|
55
|
+
if ( !isAvailable ) {
|
|
56
|
+
return 'Given version is already taken.';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return true;
|
|
44
60
|
},
|
|
45
61
|
prefix: ' '.repeat( indentLevel * CLI_INDENT_SIZE ) + chalk.cyan( '?' )
|
|
46
62
|
};
|
|
@@ -7,22 +7,30 @@ import inquirer from 'inquirer';
|
|
|
7
7
|
import semver from 'semver';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { CLI_INDENT_SIZE } from './constants.js';
|
|
10
|
+
import checkVersionAvailability from './checkversionavailability.js';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Asks a user for providing the new version.
|
|
13
14
|
*
|
|
14
|
-
* @param {
|
|
15
|
-
* @param {string
|
|
16
|
-
* @param {
|
|
15
|
+
* @param {object} options
|
|
16
|
+
* @param {string} options.packageName
|
|
17
|
+
* @param {string} options.version
|
|
18
|
+
* @param {string|null} options.releaseTypeOrNewVersion
|
|
17
19
|
* @param {boolean} [options.disableInternalVersion=false] Whether to "internal" version is enabled.
|
|
18
20
|
* @param {boolean} [options.disableSkipVersion=false] Whether to "skip" version is enabled.
|
|
19
21
|
* @param {number} [options.indentLevel=0] The indent level.
|
|
20
22
|
* @returns {Promise.<string>}
|
|
21
23
|
*/
|
|
22
|
-
export default function provideVersion(
|
|
23
|
-
const
|
|
24
|
+
export default function provideVersion( options ) {
|
|
25
|
+
const {
|
|
26
|
+
packageName,
|
|
27
|
+
version,
|
|
28
|
+
releaseTypeOrNewVersion,
|
|
29
|
+
indentLevel = 0
|
|
30
|
+
} = options;
|
|
31
|
+
|
|
24
32
|
const suggestedVersion = getSuggestedVersion( {
|
|
25
|
-
|
|
33
|
+
version,
|
|
26
34
|
releaseTypeOrNewVersion,
|
|
27
35
|
disableInternalVersion: options.disableInternalVersion
|
|
28
36
|
} );
|
|
@@ -33,7 +41,7 @@ export default function provideVersion( packageVersion, releaseTypeOrNewVersion,
|
|
|
33
41
|
message = 'Type the new version or "skip"';
|
|
34
42
|
}
|
|
35
43
|
|
|
36
|
-
message += ` (suggested: "${ suggestedVersion }", current: "${
|
|
44
|
+
message += ` (suggested: "${ suggestedVersion }", current: "${ version }"):`;
|
|
37
45
|
|
|
38
46
|
const versionQuestion = {
|
|
39
47
|
type: 'input',
|
|
@@ -45,7 +53,7 @@ export default function provideVersion( packageVersion, releaseTypeOrNewVersion,
|
|
|
45
53
|
return input.trim();
|
|
46
54
|
},
|
|
47
55
|
|
|
48
|
-
validate( input ) {
|
|
56
|
+
async validate( input ) {
|
|
49
57
|
if ( !options.disableSkipVersion && input === 'skip' ) {
|
|
50
58
|
return true;
|
|
51
59
|
}
|
|
@@ -54,8 +62,17 @@ export default function provideVersion( packageVersion, releaseTypeOrNewVersion,
|
|
|
54
62
|
return true;
|
|
55
63
|
}
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
if ( !semver.valid( input ) ) {
|
|
66
|
+
return 'Please provide a valid version.';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const isAvailable = await checkVersionAvailability( input, packageName );
|
|
70
|
+
|
|
71
|
+
if ( !isAvailable ) {
|
|
72
|
+
return 'Given version is already taken.';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return true;
|
|
59
76
|
},
|
|
60
77
|
|
|
61
78
|
prefix: ' '.repeat( indentLevel * CLI_INDENT_SIZE ) + chalk.cyan( '?' )
|
|
@@ -67,12 +84,12 @@ export default function provideVersion( packageVersion, releaseTypeOrNewVersion,
|
|
|
67
84
|
|
|
68
85
|
/**
|
|
69
86
|
* @param {object} options
|
|
70
|
-
* @param {string} options.
|
|
87
|
+
* @param {string} options.version
|
|
71
88
|
* @param {string|null} options.releaseTypeOrNewVersion
|
|
72
89
|
* @param {boolean} options.disableInternalVersion
|
|
73
90
|
* @returns {string}
|
|
74
91
|
*/
|
|
75
|
-
function getSuggestedVersion( {
|
|
92
|
+
function getSuggestedVersion( { version, releaseTypeOrNewVersion, disableInternalVersion } ) {
|
|
76
93
|
if ( !releaseTypeOrNewVersion || releaseTypeOrNewVersion === 'skip' ) {
|
|
77
94
|
return 'skip';
|
|
78
95
|
}
|
|
@@ -85,14 +102,14 @@ function getSuggestedVersion( { packageVersion, releaseTypeOrNewVersion, disable
|
|
|
85
102
|
return disableInternalVersion ? 'skip' : 'internal';
|
|
86
103
|
}
|
|
87
104
|
|
|
88
|
-
if ( semver.prerelease(
|
|
105
|
+
if ( semver.prerelease( version ) ) {
|
|
89
106
|
releaseTypeOrNewVersion = 'prerelease';
|
|
90
107
|
}
|
|
91
108
|
|
|
92
109
|
// If package's version is below the '1.0.0', bump the 'minor' instead of 'major'
|
|
93
|
-
if ( releaseTypeOrNewVersion === 'major' && semver.gt( '1.0.0',
|
|
94
|
-
return semver.inc(
|
|
110
|
+
if ( releaseTypeOrNewVersion === 'major' && semver.gt( '1.0.0', version ) ) {
|
|
111
|
+
return semver.inc( version, 'minor' );
|
|
95
112
|
}
|
|
96
113
|
|
|
97
|
-
return semver.inc(
|
|
114
|
+
return semver.inc( version, releaseTypeOrNewVersion );
|
|
98
115
|
}
|
|
@@ -14,26 +14,16 @@
|
|
|
14
14
|
export default async function publishPackageOnNpmCallback( packagePath, taskOptions ) {
|
|
15
15
|
const { tools } = await import( '@ckeditor/ckeditor5-dev-utils' );
|
|
16
16
|
const { default: fs } = await import( 'fs-extra' );
|
|
17
|
-
const { default: path } = await import( 'upath' );
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const result = await tools.shExec( `npm publish --access=public --tag ${ taskOptions.npmTag }`, options )
|
|
26
|
-
.catch( e => {
|
|
27
|
-
const packageName = path.basename( packagePath );
|
|
28
|
-
|
|
29
|
-
if ( e.toString().includes( 'code E409' ) ) {
|
|
30
|
-
return { shouldKeepDirectory: true };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
throw new Error( `Unable to publish "${ packageName }" package.` );
|
|
18
|
+
try {
|
|
19
|
+
await tools.shExec( `npm publish --access=public --tag ${ taskOptions.npmTag }`, {
|
|
20
|
+
cwd: packagePath,
|
|
21
|
+
async: true,
|
|
22
|
+
verbosity: 'error'
|
|
34
23
|
} );
|
|
35
24
|
|
|
36
|
-
if ( !result || !result.shouldKeepDirectory ) {
|
|
37
25
|
await fs.remove( packagePath );
|
|
26
|
+
} catch {
|
|
27
|
+
// Do nothing if an error occurs. A parent task will handle it.
|
|
38
28
|
}
|
|
39
29
|
}
|
package/lib/utils/versions.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { tools } from '@ckeditor/ckeditor5-dev-utils';
|
|
7
|
+
import pacote from 'pacote';
|
|
7
8
|
import getChangelog from './getchangelog.js';
|
|
8
9
|
import getPackageJson from './getpackagejson.js';
|
|
9
10
|
|
|
@@ -37,9 +38,9 @@ export function getLastFromChangelog( cwd = process.cwd() ) {
|
|
|
37
38
|
export function getLastPreRelease( releaseIdentifier, cwd = process.cwd() ) {
|
|
38
39
|
const packageName = getPackageJson( cwd ).name;
|
|
39
40
|
|
|
40
|
-
return
|
|
41
|
+
return pacote.packument( packageName )
|
|
41
42
|
.then( result => {
|
|
42
|
-
const lastVersion =
|
|
43
|
+
const lastVersion = Object.keys( result.versions )
|
|
43
44
|
.filter( version => version.startsWith( releaseIdentifier ) )
|
|
44
45
|
.sort( ( a, b ) => a.localeCompare( b, undefined, { numeric: true } ) )
|
|
45
46
|
.pop();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ckeditor/ckeditor5-dev-release-tools",
|
|
3
|
-
"version": "44.
|
|
3
|
+
"version": "44.1.1",
|
|
4
4
|
"description": "Tools used for releasing CKEditor 5 and related packages.",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "CKSource (http://cksource.com/)",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"lib"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@ckeditor/ckeditor5-dev-utils": "^44.
|
|
25
|
+
"@ckeditor/ckeditor5-dev-utils": "^44.1.1",
|
|
26
26
|
"@octokit/rest": "^21.0.0",
|
|
27
27
|
"chalk": "^5.0.0",
|
|
28
28
|
"cli-columns": "^4.0.0",
|
|
@@ -38,8 +38,10 @@
|
|
|
38
38
|
"inquirer": "^11.0.0",
|
|
39
39
|
"lodash-es": "^4.17.21",
|
|
40
40
|
"minimatch": "^9.0.0",
|
|
41
|
+
"pacote": "^19.0.0",
|
|
41
42
|
"semver": "^7.6.3",
|
|
42
43
|
"shell-escape": "^0.2.0",
|
|
44
|
+
"simple-git": "^3.27.0",
|
|
43
45
|
"upath": "^2.0.1"
|
|
44
46
|
}
|
|
45
47
|
}
|