release-ckeditor5.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #!/usr/bin/env node
  2. /**
  3. * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
  4. * For licensing, see LICENSE.md.
  5. */
  6. /* eslint-env node */
  7. 'use strict';
  8. const path = require( 'path' );
  9. const { tools, logger } = require( '@ckeditor/ckeditor5-dev-utils' );
  10. const versionUtils = require( '@ckeditor/ckeditor5-dev-env/lib/release-tools/utils/versions' );
  11. const cli = require( '@ckeditor/ckeditor5-dev-env/lib/release-tools/utils/cli' );
  12. const createGithubRelease = require( '@ckeditor/ckeditor5-dev-env/lib/release-tools/utils/creategithubrelease' );
  13. const validatePackageToRelease = require( '@ckeditor/ckeditor5-dev-env/lib/release-tools/utils/validatepackagetorelease' );
  14. const { getChangesForVersion } = require( '@ckeditor/ckeditor5-dev-env/lib/release-tools/utils/changelog' );
  15. const log = logger();
  16. const cke5Path = path.resolve( __dirname, '..', '..' );
  17. const packageJsonPath = path.resolve( cke5Path, 'package.json' );
  18. const templatePath = path.resolve( cke5Path, 'scripts', 'release', 'template' );
  19. const packageJsonTemplatePath = path.resolve( templatePath, 'package.json' );
  20. const packageJsonTemplateCopy = require( packageJsonTemplatePath );
  21. // That files will be copied from source to template directory and will be released too.
  22. const additionalFiles = [
  23. 'CHANGELOG.md',
  24. 'LICENSE.md',
  25. 'README.md'
  26. ];
  27. cli.provideToken()
  28. .then( token => {
  29. const gitVersion = versionUtils.getLastTagFromGit();
  30. const changelogVersion = versionUtils.getLastFromChangelog();
  31. log.info( 'Checking whether there is anything to release...' );
  32. // If the last tag is equal to version saved in changelog, we don't have new version for release.
  33. if ( gitVersion === changelogVersion ) {
  34. return reject( 'Before starting the release process, you should generate the changelog.' );
  35. }
  36. const releaseDescription = getChangesForVersion( changelogVersion );
  37. log.info( 'Validating the repository for the release...' );
  38. const errors = validatePackageToRelease( {
  39. version: changelogVersion,
  40. changes: releaseDescription
  41. } );
  42. // Abort due to errors during validation.
  43. if ( errors.length ) {
  44. const log = logger();
  45. log.error( 'Unexpected errors occured:' );
  46. errors.map( err => '* ' + err ).forEach( log.error.bind( log ) );
  47. return reject( 'Releasing has been aborted due to errors.' );
  48. }
  49. log.info( 'Bumping the version...' );
  50. // Bump the version.
  51. tools.shExec(
  52. `npm version ${ changelogVersion } --message "Release: v${ changelogVersion }." --allow-same-version`,
  53. { verbosity: 'error' }
  54. );
  55. tools.shExec( `git push origin master v${ changelogVersion }` );
  56. const packageJson = require( packageJsonPath );
  57. log.info( 'Copying the package.json...' );
  58. // Update the template of `package.json`. We will use values from source `package.json`
  59. // but only these ones which are defined in the template.
  60. tools.updateJSONFile( packageJsonTemplatePath, jsonFile => {
  61. for ( const property of Object.keys( jsonFile ) ) {
  62. // If the `property` is set in the template, leave it.
  63. if ( jsonFile[ property ] ) {
  64. continue;
  65. }
  66. if ( property == 'private' ) {
  67. continue;
  68. }
  69. // Copy value from original package.json file.
  70. jsonFile[ property ] = packageJson[ property ];
  71. }
  72. return jsonFile;
  73. } );
  74. // Copy additional files.
  75. for ( const file of additionalFiles ) {
  76. tools.shExec( `cp ${ path.resolve( cke5Path, file ) } ${ path.resolve( templatePath, file ) }` );
  77. }
  78. log.info( 'Publishing on npm...' );
  79. // Publish the package on npm.
  80. tools.shExec( `cd ${ templatePath } && npm publish && cd ${ cke5Path }` );
  81. // Remove files that were copy.
  82. for ( const file of additionalFiles ) {
  83. tools.shExec( `rm ${ path.resolve( templatePath, file ) }` );
  84. }
  85. log.info( 'Creating a release on GitHub...' );
  86. // Create a release on GitHub.
  87. return createGithubRelease( token, {
  88. repositoryOwner: 'ckeditor',
  89. repositoryName: 'ckeditor5',
  90. version: `v${ changelogVersion }`,
  91. description: releaseDescription
  92. } ).then( () => changelogVersion );
  93. } )
  94. .then( version => {
  95. log.info( 'Restoring the package.json template...' );
  96. // Restore the template `package.json` to state before the publishing process.
  97. tools.updateJSONFile( packageJsonTemplatePath, () => packageJsonTemplateCopy );
  98. const url = `https://github.com/ckeditor/ckeditor5/releases/tag/v${ version }`;
  99. log.info( `Created the release: ${ url }` );
  100. } )
  101. .catch( err => {
  102. log.error( err.stack );
  103. } );
  104. function reject( message ) {
  105. return Promise.reject( new Error( message ) );
  106. }