@ckeditor/ckeditor5-dev-release-tools 55.0.0-alpha.5 → 55.1.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.
@@ -14,6 +14,7 @@ import getNpmTagFromVersion from '../utils/getnpmtagfromversion.js';
14
14
  * @param {string} options.token Token used to authenticate with GitHub.
15
15
  * @param {string} options.version Name of tag connected with the release.
16
16
  * @param {string} options.description Description of the release.
17
+ * @param {boolean} [options.isLatest=true] Whether the release should be marked as the latest.
17
18
  * @param {string} [options.cwd=process.cwd()] Current working directory from which all paths will be resolved.
18
19
  * @returns {Promise.<string>}
19
20
  */
@@ -22,6 +23,7 @@ export default async function createGithubRelease( options ) {
22
23
  token,
23
24
  version,
24
25
  description,
26
+ isLatest = true,
25
27
  cwd = process.cwd()
26
28
  } = options;
27
29
 
@@ -39,7 +41,8 @@ export default async function createGithubRelease( options ) {
39
41
  owner: repositoryOwner,
40
42
  repo: repositoryName,
41
43
  body: description,
42
- prerelease: getNpmTagFromVersion( version ) !== 'latest'
44
+ prerelease: getNpmTagFromVersion( version ) !== 'latest',
45
+ make_latest: String( isLatest )
43
46
  } );
44
47
  }
45
48
 
@@ -23,7 +23,7 @@ import { workspaces, npm } from '@ckeditor/ckeditor5-dev-utils';
23
23
  * - A package directory must contain `package.json` file.
24
24
  * - All files defined in the `optionalEntryPointPackages` option must exist in a package directory.
25
25
  * - An npm tag (dist-tag) must match the tag calculated from the package version.
26
- * A stable release can be also published as `next` or `staging.
26
+ * A stable release can be also published as `next`, `staging`, or `latest-v{major}`.
27
27
  *
28
28
  * When the validation for each package passes, packages are published on npm. Optional callback is called for confirmation whether to
29
29
  * continue.
@@ -37,6 +37,7 @@ import { workspaces, npm } from '@ckeditor/ckeditor5-dev-utils';
37
37
  * @param {ListrTaskObject} [options.listrTask] An instance of `ListrTask`.
38
38
  * @param {AbortSignal|null} [options.signal=null] Signal to abort the asynchronous process.
39
39
  * @param {string} [options.npmTag='staging'] The npm distribution tag.
40
+ * @param {boolean} [options.disallowLatestNpmTag=false] Whether to disallow publishing packages using the `latest` npm distribution tag.
40
41
  * @param {Object.<string, Array.<string>>|null} [options.optionalEntries=null] Specifies which entries from the `files` field in the
41
42
  * `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
42
43
  * it is allowed not to match any file. The `options.optionalEntries` object may also contain the `default` key, which is used for all
@@ -59,6 +60,7 @@ export default async function publishPackages( options ) {
59
60
  listrTask,
60
61
  signal = null,
61
62
  npmTag = 'staging',
63
+ disallowLatestNpmTag = false,
62
64
  optionalEntries = null,
63
65
  confirmationCallback = null,
64
66
  requireEntryPoint = false,
@@ -94,7 +96,7 @@ export default async function publishPackages( options ) {
94
96
 
95
97
  await assertPackages( packagesToProcess, { requireEntryPoint, optionalEntryPointPackages } );
96
98
  await assertFilesToPublish( packagesToProcess, optionalEntries );
97
- await assertNpmTag( packagesToProcess, npmTag );
99
+ await assertNpmTag( packagesToProcess, npmTag, { disallowLatestNpmTag } );
98
100
 
99
101
  const shouldPublishPackages = confirmationCallback ? await confirmationCallback() : true;
100
102
 
@@ -15,7 +15,8 @@ import { exec } from 'node:child_process';
15
15
  const execPromise = promisify( exec );
16
16
 
17
17
  /**
18
- * Used to switch the tags from `staging` to `latest` for specified array of packages.
18
+ * Used to assign a dist-tag to a specified version for all packages from the release set.
19
+ * It supports built-in tags (e.g. `latest`, `staging`, `next`) and custom tags (e.g. `latest-v{X}`).
19
20
  * Each operation will be retried up to 3 times in case of failure.
20
21
  *
21
22
  * @param {object} options
@@ -5,6 +5,7 @@
5
5
 
6
6
  import fs from 'node:fs/promises';
7
7
  import upath from 'upath';
8
+ import semver from 'semver';
8
9
  import getNpmTagFromVersion from './getnpmtagfromversion.js';
9
10
 
10
11
  const ALLOWED_NPM_LATEST_TAGS = [
@@ -14,14 +15,22 @@ const ALLOWED_NPM_LATEST_TAGS = [
14
15
 
15
16
  /**
16
17
  * Checks if the npm tag matches the tag calculated from the package version. Verification takes place for all packages.
18
+ * Stable versions can additionally use `latest-v{major}` where `{major}` matches the version major.
17
19
  *
18
20
  * @param {Array.<string>} packagePaths
19
21
  * @param {string} npmTag
22
+ * @param {object} [options={}]
23
+ * @param {boolean} [options.disallowLatestNpmTag=false] Whether to disallow publishing packages using the `latest` npm distribution tag.
20
24
  * @returns {Promise}
21
25
  */
22
- export default async function assertNpmTag( packagePaths, npmTag ) {
26
+ export default async function assertNpmTag( packagePaths, npmTag, options = {} ) {
27
+ const { disallowLatestNpmTag = false } = options;
23
28
  const errors = [];
24
29
 
30
+ if ( disallowLatestNpmTag && npmTag === 'latest' ) {
31
+ throw new Error( 'Publishing with the npm tag "latest" is disallowed.' );
32
+ }
33
+
25
34
  for ( const packagePath of packagePaths ) {
26
35
  const path = upath.join( packagePath, 'package.json' );
27
36
  const file = await fs.readFile( path, 'utf-8' );
@@ -32,8 +41,14 @@ export default async function assertNpmTag( packagePaths, npmTag ) {
32
41
  continue;
33
42
  }
34
43
 
35
- if ( versionTag === 'latest' && ALLOWED_NPM_LATEST_TAGS.includes( npmTag ) ) {
36
- continue;
44
+ if ( versionTag === 'latest' ) {
45
+ if ( ALLOWED_NPM_LATEST_TAGS.includes( npmTag ) ) {
46
+ continue;
47
+ }
48
+
49
+ if ( isValidLatestMajorTag( packageJson.version, npmTag ) ) {
50
+ continue;
51
+ }
37
52
  }
38
53
 
39
54
  errors.push( `The version tag "${ versionTag }" from "${ packageJson.name }" package does not match the npm tag "${ npmTag }".` );
@@ -43,3 +58,13 @@ export default async function assertNpmTag( packagePaths, npmTag ) {
43
58
  throw new Error( errors.join( '\n' ) );
44
59
  }
45
60
  }
61
+
62
+ function isValidLatestMajorTag( version, npmTag ) {
63
+ const match = npmTag.match( /^latest-v(\d+)$/ );
64
+
65
+ if ( !match ) {
66
+ return false;
67
+ }
68
+
69
+ return semver.major( version ) === Number( match[ 1 ] );
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-dev-release-tools",
3
- "version": "55.0.0-alpha.5",
3
+ "version": "55.1.0",
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": "^55.0.0-alpha.5",
25
+ "@ckeditor/ckeditor5-dev-utils": "^55.1.0",
26
26
  "@octokit/rest": "^22.0.0",
27
27
  "cli-columns": "^4.0.0",
28
28
  "glob": "^13.0.0",