@ckeditor/ckeditor5-dev-release-tools 45.0.5 → 45.0.6

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.
@@ -15,19 +15,22 @@ import checkVersionAvailability from '../utils/checkversionavailability.js';
15
15
  import findPathsToPackages from '../utils/findpathstopackages.js';
16
16
 
17
17
  /**
18
- * The purpose of the script is to validate the packages prepared for the release and then release them on npm.
18
+ * The purpose of the script is to publish the prepared packages. However, before, it executes a few checks that
19
+ * prevent from publishing an incomplete package.
19
20
  *
20
- * The validation contains the following steps in each package:
21
- * - User must be logged to npm on the specified account.
22
- * - The package directory must contain `package.json` file.
23
- * - All other files expected to be released must exist in the package directory.
24
- * - The npm tag must match the tag calculated from the package version.
21
+ * The validation contains the following steps:
22
+ *
23
+ * - A user (a CLI session) must be logged to npm on the specified account (`npmOwner`).
24
+ * - A package directory must contain `package.json` file.
25
+ * - All files defined in the `optionalEntryPointPackages` option must exist in a package directory.
26
+ * - An npm tag (dist-tag) must match the tag calculated from the package version.
27
+ * A stable release can be also published as `next` or `staging.
25
28
  *
26
29
  * When the validation for each package passes, packages are published on npm. Optional callback is called for confirmation whether to
27
30
  * continue.
28
31
  *
29
32
  * 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).
33
+ * Whenever a communication between the script and npm fails, it tries to re-publish a package (up to five attempts).
31
34
  *
32
35
  * @param {object} options
33
36
  * @param {string} options.packagesDirectory Relative path to a location of packages to release.
@@ -63,17 +66,36 @@ export default async function publishPackages( options ) {
63
66
  optionalEntryPointPackages = [],
64
67
  cwd = process.cwd(),
65
68
  concurrency = 2,
66
- attempts = 3
69
+ attempts = 5
67
70
  } = options;
68
71
 
69
- const remainingAttempts = attempts - 1;
70
72
  await assertNpmAuthorization( npmOwner );
71
73
 
74
+ // Find packages that would be published...
72
75
  const packagePaths = await findPathsToPackages( cwd, packagesDirectory );
73
76
 
74
- await assertPackages( packagePaths, { requireEntryPoint, optionalEntryPointPackages } );
75
- await assertFilesToPublish( packagePaths, optionalEntries );
76
- await assertNpmTag( packagePaths, npmTag );
77
+ // ...and filter out those that have already been processed.
78
+ // In other words, check whether a version per package (it's read from a `package.json` file)
79
+ // is not available. Otherwise, a package is ignored.
80
+ await removeAlreadyPublishedPackages( packagePaths );
81
+
82
+ // Once again, find packages to publish after the filtering operation.
83
+ const packagesToProcess = await findPathsToPackages( cwd, packagesDirectory );
84
+
85
+ if ( !packagesToProcess.length ) {
86
+ listrTask.output = 'All packages have been published.';
87
+
88
+ return Promise.resolve();
89
+ }
90
+
91
+ // No more attempts. Abort.
92
+ if ( attempts <= 0 ) {
93
+ throw new Error( 'Some packages could not be published.' );
94
+ }
95
+
96
+ await assertPackages( packagesToProcess, { requireEntryPoint, optionalEntryPointPackages } );
97
+ await assertFilesToPublish( packagesToProcess, optionalEntries );
98
+ await assertNpmTag( packagesToProcess, npmTag );
77
99
 
78
100
  const shouldPublishPackages = confirmationCallback ? await confirmationCallback() : true;
79
101
 
@@ -81,8 +103,6 @@ export default async function publishPackages( options ) {
81
103
  return Promise.resolve();
82
104
  }
83
105
 
84
- await removeAlreadyPublishedPackages( packagePaths );
85
-
86
106
  await executeInParallel( {
87
107
  cwd,
88
108
  packagesDirectory,
@@ -95,39 +115,17 @@ export default async function publishPackages( options ) {
95
115
  concurrency
96
116
  } );
97
117
 
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
118
  listrTask.output = 'Let\'s give an npm a moment for taking a breath (~10 sec)...';
111
119
 
112
- // Let's give an npm a moment for taking a breath...
113
120
  await wait( 1000 * 10 );
114
121
 
115
- listrTask.output = 'Done. Let\'s continue.';
122
+ listrTask.output = 'Done. Let\'s continue. Re-executing.';
116
123
 
117
124
  // ...and try again.
118
125
  return publishPackages( {
119
- packagesDirectory,
120
- npmOwner,
121
- listrTask,
122
- signal,
123
- npmTag,
124
- optionalEntries,
125
- requireEntryPoint,
126
- optionalEntryPointPackages,
127
- cwd,
128
- concurrency,
126
+ ...options,
129
127
  confirmationCallback: null, // Do not ask again if already here.
130
- attempts: remainingAttempts
128
+ attempts: attempts - 1
131
129
  } );
132
130
  }
133
131
 
@@ -3,7 +3,7 @@
3
3
  * For licensing, see LICENSE.md.
4
4
  */
5
5
 
6
- import pacote from 'pacote';
6
+ import { manifest } from './pacotecacheless.js';
7
7
 
8
8
  /**
9
9
  * Checks if the provided version for the package exists in the npm registry.
@@ -15,9 +15,9 @@ import pacote from 'pacote';
15
15
  * @returns {Promise}
16
16
  */
17
17
  export default async function checkVersionAvailability( version, packageName ) {
18
- return pacote.manifest( `${ packageName }@${ version }`, { cache: null, preferOnline: true } )
18
+ return manifest( `${ packageName }@${ version }` )
19
19
  .then( () => {
20
- // If `pacote.manifest` resolves, a package with the given version exists.
20
+ // If `manifest` resolves, a package with the given version exists.
21
21
  return false;
22
22
  } )
23
23
  .catch( () => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import semver from 'semver';
7
- import pacote from 'pacote';
7
+ import { manifest } from './pacotecacheless.js';
8
8
 
9
9
  /**
10
10
  * This util aims to verify if the given `packageName` can be published with the given `version` on the `npmTag`.
@@ -15,7 +15,7 @@ import pacote from 'pacote';
15
15
  * @returns {Promise.<boolean>}
16
16
  */
17
17
  export default async function isVersionPublishableForTag( packageName, version, npmTag ) {
18
- const npmVersion = await pacote.manifest( `${ packageName }@${ npmTag }`, { cache: null, preferOnline: true } )
18
+ const npmVersion = await manifest( `${ packageName }@${ npmTag }` )
19
19
  .then( ( { version } ) => version )
20
20
  // An `npmTag` does not exist, or it's a first release of a package.
21
21
  .catch( () => null );
@@ -0,0 +1,33 @@
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 os from 'os';
7
+ import { randomUUID } from 'crypto';
8
+ import upath from 'upath';
9
+ import fs from 'fs-extra';
10
+ import pacote from 'pacote';
11
+
12
+ export const manifest = cacheLessPacoteFactory( pacote.manifest );
13
+ export const packument = cacheLessPacoteFactory( pacote.packument );
14
+
15
+ function cacheLessPacoteFactory( callback ) {
16
+ return async ( description, options = {} ) => {
17
+ const uuid = randomUUID();
18
+ const cacheDir = upath.join( os.tmpdir(), `pacote--${ uuid }` );
19
+
20
+ await fs.ensureDir( cacheDir );
21
+
22
+ try {
23
+ return await callback( description, {
24
+ ...options,
25
+ cache: cacheDir,
26
+ memoize: false,
27
+ preferOnline: true
28
+ } );
29
+ } finally {
30
+ await fs.remove( cacheDir );
31
+ }
32
+ };
33
+ }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { tools } from '@ckeditor/ckeditor5-dev-utils';
7
- import pacote from 'pacote';
7
+ import { packument } from './pacotecacheless.js';
8
8
  import getChangelog from './getchangelog.js';
9
9
  import getPackageJson from './getpackagejson.js';
10
10
 
@@ -38,7 +38,7 @@ export function getLastFromChangelog( cwd = process.cwd() ) {
38
38
  export function getLastPreRelease( releaseIdentifier, cwd = process.cwd() ) {
39
39
  const packageName = getPackageJson( cwd ).name;
40
40
 
41
- return pacote.packument( packageName, { cache: null, preferOnline: true } )
41
+ return packument( packageName )
42
42
  .then( result => {
43
43
  const lastVersion = Object.keys( result.versions )
44
44
  .filter( version => version.startsWith( releaseIdentifier ) )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-dev-release-tools",
3
- "version": "45.0.5",
3
+ "version": "45.0.6",
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": "^45.0.5",
25
+ "@ckeditor/ckeditor5-dev-utils": "^45.0.6",
26
26
  "@octokit/rest": "^21.0.0",
27
27
  "chalk": "^5.0.0",
28
28
  "cli-columns": "^4.0.0",