@ckeditor/ckeditor5-dev-release-tools 34.0.2 → 34.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.
@@ -10,6 +10,7 @@ const path = require( 'path' );
10
10
  const chalk = require( 'chalk' );
11
11
  const glob = require( 'glob' );
12
12
  const mkdirp = require( 'mkdirp' );
13
+ const semver = require( 'semver' );
13
14
  const Table = require( 'cli-table' );
14
15
  const { tools, logger } = require( '@ckeditor/ckeditor5-dev-utils' );
15
16
  const parseGithubUrl = require( 'parse-github-url' );
@@ -98,6 +99,9 @@ const additionalFiles = [
98
99
  * @param {String|null} options.packages Where to look for other packages (dependencies). If `null`, only repository specified under
99
100
  * `options.cwd` will be used in the task.
100
101
  *
102
+ * @param {String} [options.npmTag='latest'] Defines an npm tag which the package manager will use when installing the package.
103
+ * Read more: https://docs.npmjs.com/cli/v8/commands/npm-publish#tag.
104
+ *
101
105
  * @param {Array.<String>} [options.skipPackages=[]] Name of packages which won't be released.
102
106
  *
103
107
  * @param {Boolean} [options.dryRun=false] If set on true, nothing will be published:
@@ -140,6 +144,7 @@ module.exports = async function releaseSubRepositories( options ) {
140
144
 
141
145
  const dryRun = Boolean( options.dryRun );
142
146
  const releaseBranch = options.releaseBranch || 'master';
147
+ const npmTag = options.npmTag || 'latest';
143
148
  const customReleases = Array.isArray( options.customReleases ) ? options.customReleases : [ options.customReleases ].filter( Boolean );
144
149
 
145
150
  // When preparing packages for release, we check whether there are files in the directory structure of the package, which are
@@ -188,6 +193,7 @@ module.exports = async function releaseSubRepositories( options ) {
188
193
  return configureRelease()
189
194
  .then( _releaseOptions => saveReleaseOptions( _releaseOptions ) )
190
195
  .then( () => authCheck() )
196
+ .then( () => confirmNpmTag() )
191
197
  .then( () => preparePackagesToRelease() )
192
198
  .then( () => filterPackagesToReleaseOnNpm() )
193
199
  .then( () => filterPackagesToReleaseOnGitHub() )
@@ -267,6 +273,33 @@ module.exports = async function releaseSubRepositories( options ) {
267
273
  }
268
274
  }
269
275
 
276
+ // Verifies if the provided by the user npm tag should be used to release new packages to npm.
277
+ //
278
+ // @returns {Promise}
279
+ function confirmNpmTag() {
280
+ if ( !releaseOptions.npm ) {
281
+ return Promise.resolve();
282
+ }
283
+
284
+ const packageJson = getPackageJson( options.cwd );
285
+ logProcess( 'Verifying the npm tag...' );
286
+
287
+ const [ versionTag ] = semver.prerelease( packageJson.version ) || [ 'latest' ];
288
+
289
+ if ( versionTag !== npmTag ) {
290
+ log.warning( '⚠️ The version tag is different from the npm tag.' );
291
+ } else {
292
+ log.info( '✅ Release tags are defined correctly.' );
293
+ }
294
+
295
+ return cli.confirmNpmTag( versionTag, npmTag )
296
+ .then( isConfirmed => {
297
+ if ( !isConfirmed ) {
298
+ throw new Error( BREAK_RELEASE_MESSAGE );
299
+ }
300
+ } );
301
+ }
302
+
270
303
  // Checks whether to a user is logged to npm.
271
304
  //
272
305
  // @returns {Promise}
@@ -415,6 +448,7 @@ module.exports = async function releaseSubRepositories( options ) {
415
448
  // The keys in returned map are file patterns, and their values represent number of matched files. If there is no `#files` key
416
449
  // in `package.json`, then empty map is returned.
417
450
  function getMatchedFilesToPublish( packageJson, repositoryPath ) {
451
+ // TODO: Include the `main` and `types` properties if they are specified.
418
452
  if ( !packageJson.files ) {
419
453
  return new Map();
420
454
  }
@@ -727,10 +761,26 @@ module.exports = async function releaseSubRepositories( options ) {
727
761
  // For this reason we have to temporarily replace the extension in the `main` field while the package is being published to npm.
728
762
  // This change is then reverted.
729
763
  const hasTypeScriptEntryPoint = packageJson.main && packageJson.main.endsWith( '.ts' );
764
+ const hasTypesProperty = !!packageJson.types;
730
765
 
766
+ // TODO: The entire update phase should be done before collecting packages
767
+ // TODO: to publish on npm (the `filterPackagesToReleaseOnNpm()` task).
731
768
  if ( hasTypeScriptEntryPoint ) {
732
769
  tools.updateJSONFile( packageJsonPath, jsonFile => {
733
- jsonFile.main = jsonFile.main.replace( '.ts', '.js' );
770
+ const { main } = jsonFile;
771
+
772
+ jsonFile.main = main.replace( /\.ts$/, '.js' );
773
+
774
+ if ( !hasTypesProperty ) {
775
+ const typesPath = main.replace( /\.ts$/, '.d.ts' );
776
+ const absoluteTypesPath = path.join( repositoryPath, typesPath );
777
+
778
+ if ( fs.existsSync( absoluteTypesPath ) ) {
779
+ jsonFile.types = typesPath;
780
+ } else {
781
+ log.warning( `⚠️ The "${ typesPath }" file does not exist and cannot be a source of typings.` );
782
+ }
783
+ }
734
784
 
735
785
  return jsonFile;
736
786
  } );
@@ -756,7 +806,11 @@ module.exports = async function releaseSubRepositories( options ) {
756
806
  // again to the `index.ts` file.
757
807
  if ( hasTypeScriptEntryPoint ) {
758
808
  tools.updateJSONFile( packageJsonPath, jsonFile => {
759
- jsonFile.main = jsonFile.main.replace( '.js', '.ts' );
809
+ jsonFile.main = jsonFile.main.replace( /\.js$/, '.ts' );
810
+
811
+ if ( !hasTypesProperty ) {
812
+ delete jsonFile.types;
813
+ }
760
814
 
761
815
  return jsonFile;
762
816
  } );
package/lib/utils/cli.js CHANGED
@@ -314,6 +314,31 @@ const cli = {
314
314
  return options;
315
315
  } );
316
316
  } );
317
+ },
318
+
319
+ /**
320
+ * Asks a user for a confirmation for updating and tagging versions of the packages.
321
+ *
322
+ * @param {String} versionTag A version tag based on a package version specified in `package.json`.
323
+ * @param {String} npmTag A tag typed by the user when using the release tools.
324
+ * @returns {Promise.<Boolean>}
325
+ */
326
+ confirmNpmTag( versionTag, npmTag ) {
327
+ const areVersionsEqual = versionTag === npmTag;
328
+ const color = areVersionsEqual ? chalk.magenta : chalk.red;
329
+
330
+ // eslint-disable-next-line max-len
331
+ const message = `The next release bumps the "${ color( versionTag ) }" version. Should it be published to npm as "${ color( npmTag ) }"?`;
332
+
333
+ const confirmQuestion = {
334
+ message,
335
+ type: 'confirm',
336
+ name: 'confirm',
337
+ default: areVersionsEqual
338
+ };
339
+
340
+ return inquirer.prompt( [ confirmQuestion ] )
341
+ .then( answers => answers.confirm );
317
342
  }
318
343
  };
319
344
 
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-dev-release-tools",
3
- "version": "34.0.2",
3
+ "version": "34.1.0",
4
4
  "description": "Tools used for releasing CKEditor 5 and related packages.",
5
5
  "keywords": [],
6
6
  "main": "lib/index.js",
7
7
  "dependencies": {
8
- "@ckeditor/ckeditor5-dev-utils": "^34.0.2",
8
+ "@ckeditor/ckeditor5-dev-utils": "^34.1.0",
9
9
  "@octokit/rest": "^17.9.2",
10
10
  "chalk": "^4.0.0",
11
11
  "cli-table": "^0.3.1",