Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created release script that updates all ckeditor5 dependencies to the latest version. #737

Merged
merged 29 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
11fa1c9
Added updatePackageVersions script
przemyslaw-zan Dec 13, 2021
68536f7
Restructure
przemyslaw-zan Dec 14, 2021
7c3f456
Added committing of changes, formatted the output log.
przemyslaw-zan Dec 14, 2021
9344acc
Applied review requests and refractored the script.
przemyslaw-zan Dec 16, 2021
7090e1c
Refractoring
przemyslaw-zan Dec 20, 2021
8b85dfc
Fixed display of a wrong amount of files commited.
przemyslaw-zan Dec 21, 2021
0c5b3ca
Extracted similar loops to a function.
przemyslaw-zan Dec 21, 2021
b0910e9
Displaying diff in the console
przemyslaw-zan Dec 21, 2021
1d07d15
Updated docs, rearanged arguments taken by the function.
przemyslaw-zan Dec 21, 2021
0f71e49
Updated dry run diff display to work gradually based on user input.
przemyslaw-zan Dec 27, 2021
c3a5d12
Fixed logic.
przemyslaw-zan Dec 27, 2021
49cb082
Added tests
przemyslaw-zan Dec 27, 2021
b273e6e
Applied review requests
przemyslaw-zan Dec 27, 2021
e30a9ad
Review requests.
przemyslaw-zan Dec 29, 2021
395e133
Added option to display all changes at once.
przemyslaw-zan Jan 3, 2022
2e83188
Changed order of the conditions to simplify the logic.
przemyslaw-zan Jan 3, 2022
d0e4536
Updated commit message and docs.
przemyslaw-zan Jan 3, 2022
cd941be
Refractoring.
przemyslaw-zan Jan 4, 2022
86aefbf
Changed name to updateCKEditor5Dependencies.
przemyslaw-zan Jan 4, 2022
24a24af
Updated function name in tests.
przemyslaw-zan Jan 4, 2022
c67c7d0
Added more tests.
przemyslaw-zan Jan 4, 2022
176e40b
Added more tests.
przemyslaw-zan Jan 4, 2022
0aabbee
Full code coverage.
przemyslaw-zan Jan 5, 2022
55eae45
Updated tests for `index.js`.
przemyslaw-zan Jan 5, 2022
441bc44
Fixed breaking other test files.
przemyslaw-zan Jan 5, 2022
7efde0a
Merge branch 'master' into ci/1123
przemyslaw-zan Jan 5, 2022
4ae946e
Updated yarn.lock
przemyslaw-zan Jan 5, 2022
1898110
Minor refactoring.
pomek Jan 7, 2022
6aa65a5
Adjusted tests to new API.
pomek Jan 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/ckeditor5-dev-env/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ module.exports = {
return require( './release-tools/tasks/generatechangelogformonorepository' )( ...args );
},

updatePackageVersions( ...args ) {
return require( './release-tools/tasks/update-package-versions' )( ...args );
},

createPotFiles( ...args ) {
return require( './translations/createpotfiles' )( ...args );
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

'use strict';

const chalk = require( 'chalk' );
const { diffChars: diff } = require( 'diff' );
const { execSync } = require( 'child_process' );
const fs = require( 'fs' );
const glob = require( 'glob' );

/**
* Updates `@ckeditor/ckeditor5-*` and `ckeditor5` dependencies in `packages/*` and `release/*`
* directories to the latest version. Changes in `packages/*` will be committed as well.
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
*
* See https://github.com/cksource/ckeditor5-internal/issues/1123
pomek marked this conversation as resolved.
Show resolved Hide resolved
*
* @param {Object} options
* @param {String} options.cwd The root directory of the repository in which
* the script is being used.
* @param {Boolean} options.dryRun Prevents the script from committing, and
* instead shows list of files that was changed in `packages/*` directory.
* @param {Boolean} options.pathsToUpdate Instead of list of files, it displays detailed
* list of changes from each file. Has no effect without options.dryRun.
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
*/
module.exports = function updatePackageVersions( options ) {
const totalResult = { found: 0, updated: 0, toCommit: 0, differences: [] };
const pathsToCommit = [];

options.pathsToUpdate.forEach( ( value, index, array ) => {
array[ index ].path = value.path.split( '\u005C' ).join( '\u002F' );
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
} );

console.log( '\n📍 ' + chalk.blue( 'Updating CKEditor 5 dependencies...\n' ) );

for ( const pathToUpdate of options.pathsToUpdate ) {
console.log( `Looking for package.json files in '${ pathToUpdate.path }'...` );

const result = updateDirectory( pathToUpdate.path, options.cwd, options.dryRun );

totalResult.found += result.found;
totalResult.updated += result.updated;

if ( result.differences ) {
totalResult.differences = [ ...totalResult.differences, ...result.differences ];
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
}

if ( !result.found ) {
console.log( 'No files were found.\n' );
} else if ( result.found && !result.updated ) {
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
console.log( `${ chalk.bold( result.found ) } files were found, but none needed to be updated.\n` );
} else {
console.log( `Out of ${ chalk.bold( result.found ) } files found, ${ chalk.bold( result.updated ) } were updated.\n` );

if ( pathToUpdate.commit ) {
totalResult.toCommit += result.updated;
pathsToCommit.push( pathToUpdate.path );
}
}
}

if ( options.dryRun ) {
console.log( chalk.yellow( 'DRY RUN mode - displaying changes instead of committing.' ) );

// TODO: Changes will be displayed here
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
console.log( totalResult );
} else if ( pathsToCommit.length ) {
console.log( '\n📍 ' + chalk.blue( 'Committing the changes...\n' ) );

for ( const path of pathsToCommit ) {
const execOptions = {
stdio: 'inherit',
cwd: path
};

console.log( `${ chalk.green( '+' ) } ${ path }` );

execSync( `git add ${ path }`, execOptions );
execSync( 'git commit -m "Internal: Updated all CKEditor 5 dependencies ' +
'in `packages/*` to the latest version. [skip ci]"', execOptions );
pomek marked this conversation as resolved.
Show resolved Hide resolved
}

console.log( '\n📍 ' + chalk.green( `Successfully committed ${ totalResult.toCommit } files!\n` ) );
}

if ( totalResult.updated ) {
console.log( '\n📍 ' + chalk.green( `Updated total of ${ totalResult.updated } files!\n` ) );
} else {
console.log( '\n📍 ' + chalk.green( 'No files needed an update.\n' ) );
}
};

/**
* Updates `@ckeditor/ckeditor5-*` and `ckeditor5` dependencies in the specified directory to the latest version.
pomek marked this conversation as resolved.
Show resolved Hide resolved
* Latest version is taken from the `version` property from the root of the `package.json` file, since that value
* should already have been bumped at this point of release process.
*
* @param {String} pathToUpdate directory containing files to update
* @param {String} cwd The root directory of the repository in which
* the script is being used.
* @returns {Object} Object containing numerical values counting files found and updated, as well as array of all changes made.
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
*/
function updateDirectory( pathToUpdate, cwd, dryRun ) {
const globPattern = pathToUpdate + '/*/package.json';
const packageJsonArray = glob.sync( globPattern, { cwd } );
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved

if ( !packageJsonArray.length ) {
return { found: 0, updated: 0 };
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
}

let updatedFiles = 0;
const differences = [];

for ( const file of packageJsonArray ) {
const currentFileData = fs.readFileSync( file, 'utf-8' );
const parsedData = JSON.parse( currentFileData );

updateObjectProperty( parsedData, 'dependencies' );
updateObjectProperty( parsedData, 'devDependencies' );

const newFileData = JSON.stringify( parsedData, null, 2 ) + '\n';

if ( currentFileData !== newFileData ) {
updatedFiles++;
differences.push( diff( currentFileData, newFileData ) );
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved

if ( !dryRun ) {
fs.writeFileSync( file, newFileData, 'utf-8' );
}
}
}

return { found: packageJsonArray.length, updated: updatedFiles, differences };
}

/**
* This function takes an object and a property name, and modifies said property in that object. If any of the properties
* of that property matches the regex, its value will be updated to the value of `version` property from the root of the object.
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
*
* @param {Object} parsedPkgJson Object to update.
* @param {String} propertyName Name of the property to update.
*/
function updateObjectProperty( parsedPkgJson, propertyName ) {
// Update only the CKEditor 5 dependencies, except the *-dev and *-inspector.
const regex = /^@ckeditor\/ckeditor5-(?!dev|inspector)|^ckeditor5$/;
pomek marked this conversation as resolved.
Show resolved Hide resolved
const version = parsedPkgJson.version;

for ( const dependency in parsedPkgJson[ propertyName ] ) {
if ( !regex.test( dependency ) ) {
continue;
}

parsedPkgJson[ propertyName ][ dependency ] = `^${ version }`;
}
}
1 change: 1 addition & 0 deletions packages/ckeditor5-dev-env/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"conventional-commits-filter": "^2.0.6",
"conventional-commits-parser": "^3.1.0",
"del": "^5.1.0",
"diff": "^5.0.0",
"fs-extra": "^9.0.0",
"git-raw-commits": "^2.0.7",
"glob": "^7.1.6",
Expand Down
24 changes: 23 additions & 1 deletion packages/ckeditor5-dev-env/tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ describe( 'dev-env/index', () => {
releaseSubRepositories: sandbox.stub(),
generateChangelogForSinglePackage: sandbox.stub(),
generateChangelogForMonoRepository: sandbox.stub(),
bumpVersions: sandbox.stub()
bumpVersions: sandbox.stub(),
updatePackageVersions: sandbox.stub()
}
};

Expand All @@ -51,6 +52,7 @@ describe( 'dev-env/index', () => {
mockery.registerMock( './release-tools/tasks/generatechangelogforsinglepackage', releaseTools.generateChangelogForSinglePackage );
mockery.registerMock( './release-tools/tasks/releasesubrepositories', releaseTools.releaseSubRepositories );
mockery.registerMock( './release-tools/tasks/generatechangelogformonorepository', releaseTools.generateChangelogForMonoRepository );
mockery.registerMock( './release-tools/tasks/update-package-versions', releaseTools.updatePackageVersions );

tasks = proxyquire( '../lib/index', {
'@ckeditor/ckeditor5-dev-utils': {
Expand Down Expand Up @@ -133,6 +135,26 @@ describe( 'dev-env/index', () => {
} );
} );

describe( 'updatePackageVersions()', () => {
it( 'should update versions in package.json files', () => {
przemyslaw-zan marked this conversation as resolved.
Show resolved Hide resolved
stubs.release.updatePackageVersions.returns( 'OK.' );

const output = tasks.updatePackageVersions( {
cwd: process.cwd(),
dryRun: process.argv.includes( '--dry-run' ),
diff: process.argv.includes( '--diff' )
} );

sinon.assert.calledOnce( stubs.release.updatePackageVersions );
sinon.assert.alwaysCalledWithExactly( stubs.release.updatePackageVersions, {
cwd: process.cwd(),
dryRun: process.argv.includes( '--dry-run' ),
diff: process.argv.includes( '--diff' )
} );
expect( output ).to.equal( 'OK.' );
} );
} );

describe( 'uploadPotFiles()', () => {
it( 'should upload translations', async () => {
stubs.translations.uploadPotFiles.resolves( { status: true } );
Expand Down