@ckeditor/ckeditor5-dev-release-tools 37.0.1 → 38.0.0-alpha.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.
@@ -1,257 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */
5
-
6
- /* eslint-env node */
7
-
8
- 'use strict';
9
-
10
- const path = require( 'path' );
11
- const fs = require( 'fs-extra' );
12
- const chalk = require( 'chalk' );
13
- const glob = require( 'glob' );
14
- const { tools } = require( '@ckeditor/ckeditor5-dev-utils' );
15
- const { getLastFromChangelog } = require( '../utils/versions' );
16
- const executeOnPackages = require( '../utils/executeonpackages' );
17
-
18
- /**
19
- * Fields that will not be removed from `package.json` while preparing a package.
20
- */
21
- const PACKAGE_JSON_FIELDS = [
22
- 'author',
23
- 'dependencies',
24
- 'description',
25
- 'engine',
26
- 'homepage',
27
- 'license',
28
- 'keywords',
29
- 'name',
30
- 'version',
31
- 'files',
32
- 'main',
33
- 'types',
34
- 'scripts'
35
- ];
36
-
37
- /**
38
- * Prepares packages to be released:
39
- *
40
- * * removes TypeScript sources (but keeps typings),
41
- * * secures the code of packages,
42
- * * replaces the main package entry point (use JS file instead of TS),
43
- * * prepares builds for all packages if a command is specified as npm script.
44
- *
45
- * The dry-run mode is not supported as the script creates a directory that should not be tracked by Git.
46
- *
47
- * @param {Object} options
48
- * @param {String} options.cwd Current working directory (packages) from which all paths will be resolved.
49
- * @param {String} options.packages Where to look for sources of packages (dependencies).
50
- * @param {String} options.releaseDirectory Where to copy the packages (dependencies).
51
- * @param {String} options.changelogDirectory An absolute path to the directory where the `CHANGELOG.md` file is saved.
52
- * @param {String} options.buildScript A name of npm script that builds the package. It is executed per package.
53
- * @param {String} options.secureScript A name of npm script that secures the code in the entire repository.
54
- * @param {Array.<String>} [options.npmScriptsToRemove=[]] An array of npm scripts that should be removed when processing a package.
55
- * @returns {Promise}
56
- */
57
- module.exports = async function preparePackages( options ) {
58
- const cwd = process.cwd();
59
- const packagesDirectory = path.join( options.cwd, options.packages );
60
- const releaseDirectory = path.join( options.cwd, options.releaseDirectory );
61
- const ckeditor5Version = getLastFromChangelog( options.changelogDirectory );
62
- const npmScriptsToRemove = options.npmScriptsToRemove || [];
63
-
64
- // Clean the release directory before doing anything.
65
- logProcess( 'Removing the release directory...' );
66
- await fs.remove( releaseDirectory );
67
-
68
- // Copy packages to the temporary, release directory.
69
- logProcess( 'Copying packages to release...' );
70
- await fs.copy( packagesDirectory, releaseDirectory );
71
-
72
- // Find all short package names in the release directory.
73
- // Then, map the names to absolute paths and their `package.json`.
74
- const directoryNames = ( await fs.readdir( releaseDirectory, { withFileTypes: true } ) )
75
- .filter( dirent => dirent.isDirectory() )
76
- .map( dirent => dirent.name )
77
- .map( name => {
78
- const packagePath = path.join( releaseDirectory, name );
79
- const packageJson = require( path.join( packagePath, 'package.json' ) );
80
-
81
- return [ packagePath, packageJson ];
82
- } );
83
-
84
- const packages = new Map( directoryNames );
85
-
86
- // Filter out packages without changes. They won't be released.
87
- logProcess( 'Verifying packages...' );
88
- await filterOutPackagesWithoutChanges( packages, ckeditor5Version );
89
-
90
- if ( !packages.size ) {
91
- logProcess( 'Nothing to release. Aborting.' );
92
- return;
93
- }
94
-
95
- logProcess( 'Preparing packages...' );
96
- await preparePackagesToBeReleased( packages, npmScriptsToRemove );
97
-
98
- // Secure the entire release directory.
99
- logProcess( 'Securing the code...' );
100
- exec( options.secureScript );
101
-
102
- logProcess( 'Preparing builds...' );
103
- await prepareBuilds( packages, options.buildScript );
104
-
105
- process.chdir( cwd );
106
-
107
- logProcess( 'Done.' );
108
- logInfo( chalk.grey( `Review the "${ options.releaseDirectory }/" directory before publishing the packages on npm.\n` ) );
109
- };
110
-
111
- /**
112
- * Check if packages should be released. It compares the packages' version against the latest version in CKEditor 5 changelog.
113
- *
114
- * If they are different, it means that a package should not be released and it is removed from the release directory.
115
- *
116
- * @param {Map.<String, PackageJson>} packages
117
- * @param {String} ckeditor5Version
118
- * @returns {Promise}
119
- */
120
- function filterOutPackagesWithoutChanges( packages, ckeditor5Version ) {
121
- return executeOnPackages( packages.keys(), async packagePath => {
122
- const { name: packageName, version: packageVersion } = packages.get( packagePath );
123
-
124
- logInfo( `* Checking "${ chalk.underline( packageName ) }"...`, { indent: 1, startWithNewLine: true } );
125
-
126
- if ( packageVersion !== ckeditor5Version ) {
127
- logInfo( chalk.grey( 'Nothing to release. Skipping.' ), { indent: 1 } );
128
-
129
- await fs.remove( packagePath );
130
- packages.delete( packagePath );
131
- }
132
- } );
133
- }
134
-
135
- /**
136
- * Prepare packages to be released. It means, for each package we do the following actions:
137
- *
138
- * * Remove TypeScript sources, but keep typing files (`.d.ts`).
139
- * * Redefine the main script of a package. Replace the TypeScript extension with JavaScript.
140
- * * Remove all tests of the package as they should not be released.
141
- * * Remove the `build/` directory. The build script will re-create it from the JavaScript code.
142
- *
143
- * @param {Map.<String, PackageJson>} packages
144
- * @param {Array.<String>} npmScriptsToRemove An array of npm scripts that should be removed when processing a package.
145
- * @returns {Promise}
146
- */
147
- function preparePackagesToBeReleased( packages, npmScriptsToRemove ) {
148
- return executeOnPackages( packages.keys(), async packagePath => {
149
- const { name: packageName } = packages.get( packagePath );
150
-
151
- logInfo( `* Processing "${ chalk.underline( packageName ) }"...`, { indent: 1, startWithNewLine: true } );
152
- logInfo( chalk.grey( 'Cleaning-up the package directory...' ), { indent: 2 } );
153
-
154
- // The build will be refreshed. To avoid weird caches or building from TypeScript, let's clean the directory.
155
- await fs.remove( path.join( packagePath, 'build' ) );
156
-
157
- // Tests will not be published anyway. To increase readability, let's clean it too.
158
- await fs.remove( path.join( packagePath, 'tests' ) );
159
-
160
- // Update the entry point in the `package.json` file to point to a JavaScript file.
161
- logInfo( chalk.grey( 'Replacing the package entry point (TS => JS)...' ), { indent: 2 } );
162
-
163
- tools.updateJSONFile( path.join( packagePath, 'package.json' ), packageJson => {
164
- const { main } = packageJson;
165
-
166
- // Remove properties from package.json that are not related to the production package.
167
- for ( const property of Object.keys( packageJson ) ) {
168
- if ( !PACKAGE_JSON_FIELDS.includes( property ) ) {
169
- delete packageJson[ property ];
170
- }
171
- }
172
-
173
- if ( 'scripts' in packageJson ) {
174
- for ( const npmScript of npmScriptsToRemove ) {
175
- delete packageJson.scripts[ npmScript ];
176
- }
177
- }
178
-
179
- if ( !main ) {
180
- return packageJson;
181
- }
182
-
183
- packageJson.main = main.replace( /.ts$/, '.js' );
184
- packageJson.types = main.replace( /.ts$/, '.d.ts' );
185
-
186
- return packageJson;
187
- } );
188
-
189
- // Find all TypeScript sources...
190
- const typescriptFiles = await new Promise( ( resolve, reject ) => {
191
- glob( '**/*.ts', { cwd: packagePath }, ( err, files ) => {
192
- return err ? reject( err ) : resolve( files );
193
- } );
194
- } );
195
-
196
- logInfo( chalk.grey( 'Removing TypeScript sources...' ), { indent: 2 } );
197
-
198
- // ...and remove all non-typing files.
199
- for ( const tsFile of typescriptFiles ) {
200
- if ( !tsFile.endsWith( '.d.ts' ) ) {
201
- await fs.remove( path.join( packagePath, tsFile ) );
202
- }
203
- }
204
- } );
205
- }
206
-
207
- /**
208
- * Executed a build task for all packages.
209
- *
210
- * @param {Map.<String, PackageJson>} packages
211
- * @param {String} buildScript
212
- * @returns {Promise}
213
- */
214
- function prepareBuilds( packages, buildScript ) {
215
- return executeOnPackages( packages.keys(), async packagePath => {
216
- const { name: packageName, scripts = {} } = packages.get( packagePath );
217
-
218
- if ( buildScript in scripts ) {
219
- logInfo( `* Processing "${ chalk.underline( packageName ) }"...`, { indent: 1, startWithNewLine: true } );
220
-
221
- process.chdir( packagePath );
222
-
223
- exec( `yarn run ${ buildScript }` );
224
- }
225
- } );
226
- }
227
-
228
- /**
229
- * @param {String} message
230
- */
231
- function logProcess( message ) {
232
- console.log( '\nšŸ“ ' + chalk.cyan( message ) );
233
- }
234
-
235
- /**
236
- * @param {String} message
237
- * @param {Object} options
238
- * @param {Number} [options.indent=0]
239
- * @param {Boolean} [options.startWithNewLine=false]
240
- */
241
- function logInfo( message, { indent = 0, startWithNewLine = false } = {} ) {
242
- console.log( ( startWithNewLine ? '\n' : '' ) + ' '.repeat( indent * 3 ) + message );
243
- }
244
-
245
- /**
246
- * @param {String} command
247
- * @returns {String}
248
- */
249
- function exec( command ) {
250
- return tools.shExec( command );
251
- }
252
-
253
- /**
254
- * @typedef {Object} PackageJson
255
- * @property {String} version
256
- * @property {String} name
257
- */