Skip to content

Commit

Permalink
feat: replace synchronizer with @semrel-extra/topo
Browse files Browse the repository at this point in the history
BREAKING CHANGE: drop support for cycled monorepos
  • Loading branch information
antongolub committed Mar 6, 2022
1 parent 99fffa9 commit ddd1032
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 97 deletions.
4 changes: 2 additions & 2 deletions bin/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ export default async (flags) => {
},
(error) => {
// Log out errors.
console.error(`[multi-semantic-release]:`, error);
console.error(`[multi-semantic-release111]:`, error);
process.exit(1);
}
);
} catch (error) {
// Log out errors.
console.error(`[multi-semantic-release]:`, error);
process.exit(1);
// process.exit(1);
}
};
36 changes: 18 additions & 18 deletions lib/createInlinePluginCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
Object.assign(pkg.loggerRef, context.logger);

pkg._ready = true;
emit(
"_readyForRelease",
todo().find((p) => !p._ready)
);
// emit(
// "_readyForRelease",
// todo().find((p) => !p._ready)
// );

const res = await plugins.verifyConditions(context);

Expand Down Expand Up @@ -106,7 +106,7 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)

// Wait until all todo packages have been analyzed.
pkg._analyzed = true;
await waitForAll("_analyzed");
// await waitForAll("_analyzed");

// Make sure type is "patch" if the package has any deps that have been changed.
pkg._nextType = resolveReleaseType(pkg, flags.deps.bump, flags.deps.release);
Expand All @@ -115,9 +115,9 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
debug(debugPrefix, `release type: ${pkg._nextType}`);

// if the package won't be released consider it as prepared
if (!pkg._nextType) {
emit("_prepared", pkg);
}
// if (!pkg._nextType) {
// emit("_prepared", pkg);
// }

// Return type.
return pkg._nextType;
Expand Down Expand Up @@ -154,7 +154,7 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
pkg._nextRelease = context.nextRelease;

// Wait until all todo packages are ready to generate notes.
await waitForAll("_nextRelease", (p) => p._nextType);
// await waitForAll("_nextRelease", (p) => p._nextType);

// Vars.
const notes = [];
Expand Down Expand Up @@ -188,14 +188,14 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
};

const prepare = async (pluginOptions, context) => {
if (flags.sequentialPrepare) {
debug(debugPrefix, "waiting local dependencies preparation");
await waitLocalDeps("_prepared", pkg);
}
// if (flags.sequentialPrepare) {
// debug(debugPrefix, "waiting local dependencies preparation");
// await waitLocalDeps("_prepared", pkg);
// }

// Wait until the current pkg is ready to be tagged
getLucky("_readyForTagging", pkg);
await waitFor("_readyForTagging", pkg);
// getLucky("_readyForTagging", pkg);
// await waitFor("_readyForTagging", pkg);

updateManifestDeps(pkg);
pkg._depsUpdated = true;
Expand All @@ -208,7 +208,7 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
pkg._prepared = true;

debug(debugPrefix, "prepared");
emit("_prepared", pkg);
// emit("_prepared", pkg);

return res;
};
Expand All @@ -218,8 +218,8 @@ function createInlinePluginCreator(packages, multiContext, synchronizer, flags)
pkg._published = true;
debug(debugPrefix, "published");

next();
await waitForAll("_published", (p) => p._nextType);
// next();
// await waitForAll("_published", (p) => p._nextType);

// istanbul ignore next
return res.length ? res[0] : {};
Expand Down
30 changes: 29 additions & 1 deletion lib/multiSemanticRelease.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { dirname } from "path";
import semanticRelease from "semantic-release";
import { uniq, template } from "lodash-es";
import { topo } from "@semrel-extra/topo";
import { join } from "path";

import { check, ValueError } from "./blork.js";
import getLogger from "./getLogger.js";
import getSynchronizer from "./getSynchronizer.js";
Expand Down Expand Up @@ -67,6 +70,15 @@ async function multiSemanticRelease(
const flags = normalizeFlags(_flags);
const globalOptions = await getConfig(cwd);
const multiContext = { globalOptions, inputOptions, cwd, env, stdout, stderr };
const workspaces = [
...(getManifest(join(cwd, "package.json")).workspaces || []),
...(Array.isArray(flags.ignorePackages) ? flags.ignorePackages.map((p) => `!${p}`) : []),
];
const { queue } = await topo({
cwd,
workspaces,
filter: ({ manifest }) => !manifest.private,
});

// Load packages from paths.
const packages = await Promise.all(paths.map((path) => getPackage(path, multiContext)));
Expand All @@ -92,6 +104,20 @@ async function multiSemanticRelease(

// Release all packages.
const createInlinePlugin = createInlinePluginCreator(packages, multiContext, synchronizer, flags);
const released = await queue.reduce(async (_m, _name) => {
const m = await _m;
const pkg = packages.find(({ name }) => name === _name);
if (pkg) {
const { result } = await releasePackage(pkg, createInlinePlugin, multiContext, flags);
if (result) {
return m + 1;
}
}

return m;
}, Promise.resolve(0));

/*
await Promise.all(
packages.map(async (pkg) => {
// Avoid hypothetical concurrent initialization collisions / throttling issues.
Expand All @@ -105,13 +131,13 @@ async function multiSemanticRelease(
})
);
const released = packages.filter((pkg) => pkg.result).length;
*/

// Return packages list.
logger.complete(`Released ${released} of ${packages.length} packages, semantically!`);
return packages;
}


/**
* Load details about a package.
*
Expand Down Expand Up @@ -207,6 +233,8 @@ async function releasePackage(pkg, createInlinePlugin, multiContext, flags) {
stdout: new RescopedStream(stdout, name),
stderr: new RescopedStream(stderr, name),
});

return pkg;
}

function normalizeFlags(_flags) {
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@
"testTimeout": 50000
},
"dependencies": {
"blork": "^9.3.0",
"@manypkg/get-packages": "^1.1.3",
"@semrel-extra/topo": "^1.3.0",
"blork": "^9.3.0",
"cosmiconfig": "^7.0.1",
"debug": "^4.3.3",
"detect-indent": "^6.1.0",
Expand All @@ -64,8 +65,8 @@
"get-stream": "^6.0.1",
"git-log-parser": "^1.2.0",
"globby": "11.0.4",
"lodash-es": "^4.17.21",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"meow": "^9.0.0",
"promise-events": "^0.2.4",
"semantic-release": "^19.0.2",
Expand Down
25 changes: 19 additions & 6 deletions test/bin/cli.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import execa from "execa";
import {dirname} from "node:path";
import {fileURLToPath} from "node:url";

import { copyDirectory } from "../helpers/file.js";
import {
gitInit,
Expand All @@ -10,8 +13,7 @@ import {
gitTag,
gitGetTags,
} from "../helpers/git.js";
import {dirname} from "node:path";
import {fileURLToPath} from "node:url";


const __dirname = dirname(fileURLToPath(import.meta.url))

Expand All @@ -29,10 +31,21 @@ describe("multi-semantic-release CLI", () => {
const filepath = `${__dirname}/../../bin/cli.js`;

// Run via command line.
const out = (await execa("node", [filepath, "-- --no-sequential-prepare"], { cwd })).stdout;
expect(out).toMatch("Started multirelease! Loading 4 packages...");
expect(out).toMatch("Released 4 of 4 packages, semantically!");
// const out = (await execa("node", [filepath, "-- --no-sequential-prepare"], { cwd })).stdout;
// expect(out).toMatch("Started multirelease! Loading 4 packages...");
// expect(out).toMatch("Released 4 of 4 packages, semantically!");

try {
await execa("node", [filepath, "-- --no-sequential-prepare"], {cwd})
} catch(res) {
const {stdout, stderr, exitCode} = res

expect(stdout).toMatch("Started multirelease! Loading 4 packages...");
expect(stderr).toMatch("Error: Cyclic dependency, node was:\"msr-test-c\"");
expect(exitCode).toBe(1);
}
});

test("Initial commit (changes in 2 packages, 2 filtered out)", async () => {
// Create Git repo with copy of Yarn workspaces fixture.
const cwd = gitInit();
Expand All @@ -45,7 +58,7 @@ describe("multi-semantic-release CLI", () => {
const filepath = `${__dirname}/../../bin/cli.js`;

// Run via command line.
const out = (await execa("node", [filepath, "--ignore-packages=packages/c/**,packages/d/**"], { cwd })).stdout;
const out = (await execa("node", [filepath, "-- --ignore-packages=packages/c/**,packages/d/**"], { cwd })).stdout;
expect(out).toMatch("Started multirelease! Loading 2 packages...");
expect(out).toMatch("Released 2 of 2 packages, semantically!");
});
Expand Down
3 changes: 1 addition & 2 deletions test/fixtures/yarnWorkspaces/packages/c/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "msr-test-c",
"version": "0.0.0",
"devDependencies": {
"msr-test-b": "*",
"msr-test-d": "*"
}
}
}
20 changes: 20 additions & 0 deletions test/fixtures/yarnWorkspacesAcyclic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "msr-test-yarn",
"author": "Dave Houlbrooke <dave@shax.com",
"version": "0.0.0-semantically-released",
"private": true,
"license": "0BSD",
"engines": {
"node": ">=8.3"
},
"workspaces": [
"packages/*"
],
"release": {
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator"
],
"noCi": true
}
}
8 changes: 8 additions & 0 deletions test/fixtures/yarnWorkspacesAcyclic/packages/a/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "msr-test-a",
"version": "0.0.0",
"peerDependencies": {
"msr-test-c": "*",
"left-pad": "latest"
}
}
11 changes: 11 additions & 0 deletions test/fixtures/yarnWorkspacesAcyclic/packages/b/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "msr-test-b",
"version": "0.0.0",
"dependencies": {
"msr-test-a": "*"
},
"devDependencies": {
"msr-test-c": "*",
"left-pad": "latest"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tagFormat": "multi-semantic-release-test-c@v${version}"
}
7 changes: 7 additions & 0 deletions test/fixtures/yarnWorkspacesAcyclic/packages/c/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "msr-test-c",
"version": "0.0.0",
"devDependencies": {
"msr-test-d": "*"
}
}
4 changes: 4 additions & 0 deletions test/fixtures/yarnWorkspacesAcyclic/packages/d/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "msr-test-d",
"version": "0.0.0"
}
Loading

0 comments on commit ddd1032

Please sign in to comment.