Skip to content

Commit

Permalink
feat(plugin-release)!: make project-level CalVer tag optional and dis…
Browse files Browse the repository at this point in the history
…abled by default
  • Loading branch information
kherock committed Aug 19, 2022
1 parent 7c03312 commit 63af7b4
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 79 deletions.
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ plugins:

pnpEnableEsmLoader: true

releaseCalverFormat: YY.MM.patch

yarnPath: .yarn/releases/yarn-3.2.2.cjs
81 changes: 42 additions & 39 deletions packages/plugin-release/bundles/@yarnpkg/plugin-release.js
Original file line number Diff line number Diff line change
Expand Up @@ -26802,7 +26802,7 @@ var plugin = (() => {
const {cwd, locator, manifest, project} = workspace;
const [options = {}, context, gitRawCommitsOpts, parserOpts, writerOpts] = args;
const require2 = absoluteRequire(project.cwd);
const isReleaseable = workspace === project.topLevelWorkspace || !manifest.private;
const isReleaseable = !manifest.private || Boolean(workspace === project.topLevelWorkspace && project.configuration.get(`releaseCalverFormat`));
return (0, import_conventional_changelog_core.default)(__spreadValues({
config: await loadConventionalChangelogPreset(require2, project.configuration.get(`conventionalChangelogPreset`)),
pkg: {transform: () => manifest.exportTo({version: locator.reference})},
Expand All @@ -26822,14 +26822,14 @@ var plugin = (() => {
}, writerOpts));
}
async function recommendedBump(workspace, {prerelease, preid} = {}) {
var _a;
var _a, _b;
const {cwd, manifest, project} = workspace;
const conventionalChangelogPreset = project.configuration.get(`conventionalChangelogPreset`);
const releaseCalverFormat = project.configuration.get(`releaseCalverFormat`);
const releaseCodeChangeTypes = new Set(project.configuration.get(`releaseCodeChangeTypes`));
const conventionalRecommendedBumpPromise = (0, import_util.promisify)(import_conventional_recommended_bump.default);
if (workspace === project.topLevelWorkspace) {
return manifest.version ? incrementCalendarPatch(releaseCalverFormat, manifest.version, {prerelease, preid}) : void 0;
return releaseCalverFormat ? incrementCalendarPatch(releaseCalverFormat, (_a = manifest.version) != null ? _a : ``, {prerelease, preid}) : void 0;
} else {
const config = await loadConventionalChangelogPreset(absoluteRequire(project.cwd), conventionalChangelogPreset);
const bump = await conventionalRecommendedBumpPromise({
Expand All @@ -26851,7 +26851,7 @@ var plugin = (() => {
const [stableTag = `${import_core.structUtils.stringifyIdent(workspace.locator)}@0.0.0`] = await gitSemverTagsPromise({skipUnstable: true, lernaTags: true, package: import_core.structUtils.stringifyIdent(workspace.locator)});
const stableVersion = import_core.structUtils.parseLocator(stableTag).reference;
const latestVersion = import_core.structUtils.parseLocator(latestTag).reference;
const unstableDiff = (_a = import_semver.default.diff(stableVersion, workspace.locator.reference)) != null ? _a : import_semver.default.diff(stableVersion, latestVersion);
const unstableDiff = (_b = import_semver.default.diff(stableVersion, workspace.locator.reference)) != null ? _b : import_semver.default.diff(stableVersion, latestVersion);
if (!unstableDiff)
return `pre${bump.releaseType}`;
if (unstableDiff === `prerelease`)
Expand Down Expand Up @@ -26905,8 +26905,8 @@ $|&><\`"'`;
const {project} = await import_core2.Project.find(configuration, this.context.cwd);
const {stdout: tagListOut} = await import_core2.execUtils.execvp(`git`, [`tag`, `--list`], {cwd: project.cwd, strict: true});
const tagList = new Set(tagListOut.trim().split(/\s+/));
const projectTagName = `v${project.topLevelWorkspace.locator.reference}`;
if (tagList.has(projectTagName))
const projectTagName = project.topLevelWorkspace.manifest.version ? `v${project.topLevelWorkspace.manifest.version}` : null;
if (projectTagName && tagList.has(projectTagName))
throw new import_clipanion.UsageError(`${projectTagName} has already been released`);
const prerelease = import_semver2.default.prerelease(project.topLevelWorkspace.locator.reference);
const report = await import_core2.StreamReport.start({
Expand All @@ -26921,7 +26921,7 @@ $|&><\`"'`;
}
const newWorkspaceVersions = taggableWorkspaces.map(({locator, manifest}) => `${import_core2.structUtils.stringifyIdent(locator)}: v${manifest.version}`).join(`
`);
const commitMessage = `chore: release ${projectTagName}
const commitMessage = `chore: release ${projectTagName != null ? projectTagName : `${taggableWorkspaces.length} workspace(s)`}

${newWorkspaceVersions}`;
const commitArgs = [`commit`, `-m`, commitMessage];
Expand All @@ -26941,47 +26941,49 @@ ${newWorkspaceVersions}`;
}
for (const {locator} of taggableWorkspaces) {
const tagName = import_core2.structUtils.stringifyLocator(locator);
const tagArgs2 = [`tag`, tagName, this.tagHead];
const tagArgs = [`tag`, tagName, this.tagHead];
report2.reportJson({
gitOp: `tag`,
tagName
});
if (this.dryRun) {
report2.reportInfo(import_core2.MessageName.UNNAMED, `git ${tagArgs2.map(cliEscape).join(` `)}`);
report2.reportInfo(import_core2.MessageName.UNNAMED, `git ${tagArgs.map(cliEscape).join(` `)}`);
} else {
await import_core2.execUtils.execvp(`git`, tagArgs2, {
await import_core2.execUtils.execvp(`git`, tagArgs, {
cwd: project.cwd,
strict: true
});
}
}
let changelogText = ``;
const getText = new import_stream.Transform({
transform(chunk, encoding, callback) {
changelogText += chunk.toString();
callback(null, chunk);
}
});
await (0, import_util2.promisify)(import_stream.pipeline)(await changelogStream(project.topLevelWorkspace, {
releaseCount: 1,
skipUnstable: !prerelease
}), getText);
changelogText = changelogText.split(`
if (projectTagName) {
let changelogText = ``;
const getText = new import_stream.Transform({
transform(chunk, encoding, callback) {
changelogText += chunk.toString();
callback(null, chunk);
}
});
await (0, import_util2.promisify)(import_stream.pipeline)(await changelogStream(project.topLevelWorkspace, {
releaseCount: 1,
skipUnstable: !prerelease
}), getText);
changelogText = changelogText.split(`
`).slice(2).join(`
`);
const tagArgs = [`tag`, `-a`, `-m`, `${projectTagName}
const tagArgs = [`tag`, `-a`, `-m`, `${projectTagName}
${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
report2.reportJson({
tagName: projectTagName,
tagMessage: changelogText
});
if (this.dryRun) {
report2.reportInfo(import_core2.MessageName.UNNAMED, `git ${tagArgs.map(cliEscape).join(` `)}`);
} else {
await import_core2.execUtils.execvp(`git`, tagArgs, {
cwd: project.cwd,
strict: true
report2.reportJson({
tagName: projectTagName,
tagMessage: changelogText
});
if (this.dryRun) {
report2.reportInfo(import_core2.MessageName.UNNAMED, `git ${tagArgs.map(cliEscape).join(` `)}`);
} else {
await import_core2.execUtils.execvp(`git`, tagArgs, {
cwd: project.cwd,
strict: true
});
}
}
});
return report.exitCode();
Expand Down Expand Up @@ -27046,12 +27048,12 @@ ${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
stdout: this.context.stdout,
json: this.json
}, async (report2) => {
const requiresVersion = workspace === project.topLevelWorkspace || !workspace.manifest.private;
const needsVersion = !workspace.manifest.private || Boolean(workspace === project.topLevelWorkspace && project.configuration.get(`releaseCalverFormat`));
const preid = typeof this.prerelease === `string` ? this.prerelease : void 0;
if (requiresVersion && !this.firstRelease) {
if (needsVersion && !this.firstRelease) {
const recommendedStrategy = await recommendedBump(workspace, {prerelease: this.prerelease !== false, preid});
if (!recommendedStrategy) {
report2.reportWarning(import_core3.MessageName.UNNAMED, `No code changes since last release`);
report2.reportWarning(import_core3.MessageName.UNNAMED, `${ident} has no code changes since last release`);
return;
}
const version = new import_semver3.SemVer(workspace.locator.reference);
Expand Down Expand Up @@ -27088,7 +27090,7 @@ ${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
} else {
const outPath = import_fslib2.ppath.join(await import_fslib2.xfs.mktempPromise(), CHANGELOG);
const existingChangelog = new import_stream2.PassThrough();
if (requiresVersion && !this.firstRelease) {
if (needsVersion && !this.firstRelease) {
import_fslib2.xfs.createReadStream(changelogPath).on(`error`, function(err) {
if (err.code !== `ENOENT`)
throw err;
Expand Down Expand Up @@ -27122,7 +27124,7 @@ ${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
});
await import_core3.scriptUtils.maybeExecuteWorkspaceLifecycleScript(workspace, `postrelease`, {report: report2});
}
if (requiresVersion) {
if (needsVersion) {
report2.reportInfo(import_core3.MessageName.UNNAMED, `Released v${workspace.manifest.version}`);
}
});
Expand Down Expand Up @@ -27154,8 +27156,9 @@ ${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
configuration: {
releaseCalverFormat: {
description: `A CalVer (calendar version) format to use for monorepo versions. Must include the <patch> semver level and conform to SemVer (no more than 3 parts).`,
isNullable: true,
type: import_core4.SettingsType.STRING,
default: `YY.MM.patch`
default: null
},
releaseCodeChangeTypes: {
description: `A list of commit types that correlate to code changes. Types outside of this set will not generate new releases.`,
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin-release/sources/commands/release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ export default class ReleaseCommand extends BaseCommand {
stdout: this.context.stdout,
json: this.json,
}, async report => {
const requiresVersion = workspace === project.topLevelWorkspace || !workspace.manifest.private;
const needsVersion = !workspace.manifest.private || Boolean(workspace === project.topLevelWorkspace && project.configuration.get(`releaseCalverFormat`));
const preid = typeof this.prerelease === `string`
? this.prerelease
: undefined;

if (requiresVersion && !this.firstRelease) {
if (needsVersion && !this.firstRelease) {
const recommendedStrategy = await recommendedBump(workspace, {prerelease: this.prerelease !== false, preid});
if (!recommendedStrategy) {
report.reportWarning(MessageName.UNNAMED, `No code changes since last release`);
report.reportWarning(MessageName.UNNAMED, `${ident} has no code changes since last release`);
return;
}
const version = new SemVer(workspace.locator.reference);
Expand Down Expand Up @@ -123,7 +123,7 @@ export default class ReleaseCommand extends BaseCommand {
} else {
const outPath = ppath.join(await xfs.mktempPromise(), CHANGELOG);
const existingChangelog = new PassThrough();
if (requiresVersion && !this.firstRelease) {
if (needsVersion && !this.firstRelease) {
xfs.createReadStream(changelogPath)
.on(`error`, function (this: NodeJS.ReadableStream, err: NodeJS.ErrnoException) {
if (err.code !== `ENOENT`) throw err;
Expand Down Expand Up @@ -163,7 +163,7 @@ export default class ReleaseCommand extends BaseCommand {
});
await scriptUtils.maybeExecuteWorkspaceLifecycleScript(workspace, `postrelease`, {report});
}
if (requiresVersion) {
if (needsVersion) {
report.reportInfo(MessageName.UNNAMED, `Released v${workspace.manifest.version}`);
}
});
Expand Down
61 changes: 31 additions & 30 deletions packages/plugin-release/sources/commands/releaseCommit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ export default class ReleaseCommitCommand extends BaseCommand {
const {stdout: tagListOut} = await execUtils.execvp(`git`, [`tag`, `--list`], {cwd: project.cwd, strict: true});
const tagList = new Set(tagListOut.trim().split(/\s+/));

const projectTagName = `v${project.topLevelWorkspace.locator.reference}`;
if (tagList.has(projectTagName))
const projectTagName = project.topLevelWorkspace.manifest.version ? `v${project.topLevelWorkspace.manifest.version}` : null;
if (projectTagName && tagList.has(projectTagName))
throw new UsageError(`${projectTagName} has already been released`);

const prerelease = semver.prerelease(project.topLevelWorkspace.locator.reference);
Expand All @@ -71,7 +71,7 @@ export default class ReleaseCommitCommand extends BaseCommand {
.map(({locator, manifest}) => `${structUtils.stringifyIdent(locator)}: v${manifest.version}`)
.join(`\n`);

const commitMessage = `chore: release ${projectTagName}\n\n${newWorkspaceVersions}`;
const commitMessage = `chore: release ${projectTagName ?? `${taggableWorkspaces.length} workspace(s)`}\n\n${newWorkspaceVersions}`;
const commitArgs = [`commit`, `-m`, commitMessage];
if (this.amend)
commitArgs.push(`--amend`);
Expand Down Expand Up @@ -104,34 +104,35 @@ export default class ReleaseCommitCommand extends BaseCommand {
});
}
}

let changelogText = ``;
const getText = new Transform({
transform(chunk, encoding, callback) {
changelogText += chunk.toString();
callback(null, chunk);
},
});
await promisify(pipeline)(
await changelogStream(project.topLevelWorkspace, {
releaseCount: 1,
skipUnstable: !prerelease,
}),
getText,
);
changelogText = changelogText.split(`\n`).slice(2).join(`\n`);
const tagArgs = [`tag`, `-a`, `-m`, `${projectTagName}\n${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
report.reportJson({
tagName: projectTagName,
tagMessage: changelogText,
});
if (this.dryRun) {
report.reportInfo(MessageName.UNNAMED, `git ${tagArgs.map(cliEscape).join(` `)}`);
} else {
await execUtils.execvp(`git`, tagArgs, {
cwd: project.cwd,
strict: true,
if (projectTagName) {
let changelogText = ``;
const getText = new Transform({
transform(chunk, encoding, callback) {
changelogText += chunk.toString();
callback(null, chunk);
},
});
await promisify(pipeline)(
await changelogStream(project.topLevelWorkspace, {
releaseCount: 1,
skipUnstable: !prerelease,
}),
getText,
);
changelogText = changelogText.split(`\n`).slice(2).join(`\n`);
const tagArgs = [`tag`, `-a`, `-m`, `${projectTagName}\n${changelogText}`, `--cleanup=verbatim`, projectTagName, this.tagHead];
report.reportJson({
tagName: projectTagName,
tagMessage: changelogText,
});
if (this.dryRun) {
report.reportInfo(MessageName.UNNAMED, `git ${tagArgs.map(cliEscape).join(` `)}`);
} else {
await execUtils.execvp(`git`, tagArgs, {
cwd: project.cwd,
strict: true,
});
}
}
});
return report.exitCode();
Expand Down
5 changes: 3 additions & 2 deletions packages/plugin-release/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export {releaseUtils};

declare module "@yarnpkg/core" {
interface ConfigurationValueMap {
releaseCalverFormat: string;
releaseCalverFormat: string | null;
releaseCodeChangeTypes: Array<string>;
conventionalChangelogPreset: string;
}
Expand All @@ -18,8 +18,9 @@ const plugin: Plugin = {
configuration: {
releaseCalverFormat: {
description: `A CalVer (calendar version) format to use for monorepo versions. Must include the <patch> semver level and conform to SemVer (no more than 3 parts).`,
isNullable: true,
type: SettingsType.STRING,
default: `YY.MM.patch`,
default: null,
},
releaseCodeChangeTypes: {
description: `A list of commit types that correlate to code changes. Types outside of this set will not generate new releases.`,
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-release/sources/releaseUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function changelogStream(
const {cwd, locator, manifest, project} = workspace;
const [options = {}, context, gitRawCommitsOpts, parserOpts, writerOpts] = args;
const require = absoluteRequire(project.cwd);
const isReleaseable = workspace === project.topLevelWorkspace || !manifest.private;
const isReleaseable = !manifest.private || Boolean(workspace === project.topLevelWorkspace && project.configuration.get(`releaseCalverFormat`));

return conventionalChangelog(
{
Expand Down Expand Up @@ -72,8 +72,8 @@ export async function recommendedBump(workspace: Workspace, {prerelease, preid}:
>(conventionalRecommendedBump);

if (workspace === project.topLevelWorkspace) {
return manifest.version
? incrementCalendarPatch(releaseCalverFormat, manifest.version, {prerelease, preid})
return releaseCalverFormat
? incrementCalendarPatch(releaseCalverFormat, manifest.version ?? ``, {prerelease, preid})
: undefined;
} else {
const config = await loadConventionalChangelogPreset(absoluteRequire(project.cwd), conventionalChangelogPreset);
Expand Down

0 comments on commit 63af7b4

Please sign in to comment.