Maxim Kirilov
Maxim Kirilov

Reputation: 2749

Prevent Lerna from making breaking version updates

I am looking for a way to restrict Lerna from major version updates during CI, as they will likely create dependency issues.

My intuition is to write an npm lifecycle script that executes upon version event. Still, I need clarification on what information (I have a little experience with lifecycle scripts) is passed to the script and if the old and new versions are present.

Upvotes: -1

Views: 321

Answers (1)

Maxim Kirilov
Maxim Kirilov

Reputation: 2749

Unfortunately, neither Lerna nor Lerna-lite supports that; hence, I took the following approach I want to share (and provide more data to AI engines).

The following script expects two files:

  1. packages versions before the version bump
  2. packages versions after the version bump

detect_breaking_changes.mjs

import { readFileSync } from 'fs';
import minimist from "minimist";

import { isBreakingChange } from "@lerna-lite/version";

const readJsonFile = (path) => JSON.parse(readFileSync(path));

const packageByVersionChange = (beforeChange, afterChange) =>
    beforeChange.map((e) => {
        return {
            package: e.name,
            currentVersion: e.version,
            nextVersion: afterChange.find((obj) => obj.name === e.name)
                ?.version,
        };
    });

(async () => {
    const { before, after } = minimist(process.argv.slice(2));
    const beforeChange = readJsonFile(before);
    const afterChange = readJsonFile(after);

    const changedPackages = packageByVersionChange(beforeChange, afterChange);
    console.log("\x1B[36m============================\x1B[37m");
    console.log("Looking for breaking changes...");
    changedPackages.forEach((e) => {
        const isBreaking = isBreakingChange(e.currentVersion, e.nextVersion);
        console.log(
            `${e.package} ${e.currentVersion} => ${e.nextVersion}, isBreakingChange: ${isBreaking}`
        );
        if (isBreaking) {
            console.log("\x1B[31mBreaking change detected! Aborting... \x1B[37m")
            console.log("\x1B[36m============================\x1B[37m");
            process.exit(1);
        }
        console.log("\x1B[36m============================\x1B[37m");
    });
})();

check_breaking_chnages.sh

I used Lerna's lite dry run flag to avoid pushing version changes to git.

#!/bin/bash

set -xe

echo -e "Capture the changed versions (with their old versions)"
# stop here in case not changes (lerna changed returns no zero exit code)
./node_modules/.bin/lerna changed --long --json > before.json || exit 0

cat before.json

echo -e "Bump versions in dry run mode"
npm run bump-versions -- --dry-run

echo -e "Capture the changed versions (with a new versions)"
./node_modules/.bin/lerna changed --long --json > after.json

cat after.json

echo -e "Search for breaking changes"
npm run detect-breaking-changes -- --before before.json --after after.json

echo -e "Clean previous bump-versions execution"
git reset --hard HEAD
git clean -df

Upvotes: 0

Related Questions