feat(dev-infra): add command for printing release train information (#42644)
Currently the active release trains are printed when a developer runs `ng-dev publish release`. This is not ideal because it requires the developer to provide an OAuth token, to be on the next branch, and to have no uncommitted changes, while the actual release train information is not dependent on these checks. This commit introduces a new command called `ng-dev release info` that can be used to retrieve relase information without the aforementioned requirements. Note that this command provides more detailed information about release branches than the `ng-dev caretaker check` command (which also requires on authentication as a side note). The `release info` command also prints active LTS branches for example. PR Close #42644
This commit is contained in:
parent
b54e8aee37
commit
41823ff277
|
@ -5252,6 +5252,93 @@ const ReleaseBuildCommandModule = {
|
|||
describe: 'Builds the release output for the current branch.',
|
||||
};
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
/**
|
||||
* Prints the active release trains to the console.
|
||||
* @params active Active release trains that should be printed.
|
||||
* @params config Release configuration used for querying NPM on published versions.
|
||||
*/
|
||||
function printActiveReleaseTrains(active, config) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
const { releaseCandidate, next, latest } = active;
|
||||
const isNextPublishedToNpm = yield isVersionPublishedToNpm(next.version, config);
|
||||
const nextTrainType = next.isMajor ? 'major' : 'minor';
|
||||
const ltsBranches = yield fetchLongTermSupportBranchesFromNpm(config);
|
||||
info();
|
||||
info(blue('Current version branches in the project:'));
|
||||
// Print information for release trains in the feature-freeze/release-candidate phase.
|
||||
if (releaseCandidate !== null) {
|
||||
const rcVersion = releaseCandidate.version;
|
||||
const rcTrainType = releaseCandidate.isMajor ? 'major' : 'minor';
|
||||
const rcTrainPhase = rcVersion.prerelease[0] === 'next' ? 'feature-freeze' : 'release-candidate';
|
||||
info(` • ${bold(releaseCandidate.branchName)} contains changes for an upcoming ` +
|
||||
`${rcTrainType} that is currently in ${bold(rcTrainPhase)} phase.`);
|
||||
info(` Most recent pre-release for this branch is "${bold(`v${rcVersion}`)}".`);
|
||||
}
|
||||
// Print information about the release-train in the latest phase. i.e. the patch branch.
|
||||
info(` • ${bold(latest.branchName)} contains changes for the most recent patch.`);
|
||||
info(` Most recent patch version for this branch is "${bold(`v${latest.version}`)}".`);
|
||||
// Print information about the release-train in the next phase.
|
||||
info(` • ${bold(next.branchName)} contains changes for a ${nextTrainType} ` +
|
||||
`currently in active development.`);
|
||||
// Note that there is a special case for versions in the next release-train. The version in
|
||||
// the next branch is not always published to NPM. This can happen when we recently branched
|
||||
// off for a feature-freeze release-train. More details are in the next pre-release action.
|
||||
if (isNextPublishedToNpm) {
|
||||
info(` Most recent pre-release version for this branch is "${bold(`v${next.version}`)}".`);
|
||||
}
|
||||
else {
|
||||
info(` Version is currently set to "${bold(`v${next.version}`)}", but has not been ` +
|
||||
`published yet.`);
|
||||
}
|
||||
// If no release-train in release-candidate or feature-freeze phase is active,
|
||||
// we print a message as last bullet point to make this clear.
|
||||
if (releaseCandidate === null) {
|
||||
info(' • No release-candidate or feature-freeze branch currently active.');
|
||||
}
|
||||
info();
|
||||
info(blue('Current active LTS version branches:'));
|
||||
// Print all active LTS branches (each branch as own bullet point).
|
||||
if (ltsBranches.active.length !== 0) {
|
||||
for (const ltsBranch of ltsBranches.active) {
|
||||
info(` • ${bold(ltsBranch.name)} is currently in active long-term support phase.`);
|
||||
info(` Most recent patch version for this branch is "${bold(`v${ltsBranch.version}`)}".`);
|
||||
}
|
||||
}
|
||||
info();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
/** Yargs command handler for printing release information. */
|
||||
function handler$8() {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
const git = GitClient.get();
|
||||
const gitRepoWithApi = Object.assign({ api: git.github }, git.remoteConfig);
|
||||
const releaseTrains = yield fetchActiveReleaseTrains(gitRepoWithApi);
|
||||
// Print the active release trains.
|
||||
yield printActiveReleaseTrains(releaseTrains, getReleaseConfig());
|
||||
});
|
||||
}
|
||||
/** CLI command module for retrieving release information. */
|
||||
const ReleaseInfoCommandModule = {
|
||||
handler: handler$8,
|
||||
command: 'info',
|
||||
describe: 'Prints active release trains to the console.',
|
||||
};
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
|
@ -5657,7 +5744,7 @@ function builder$8(argv) {
|
|||
});
|
||||
}
|
||||
/** Yargs command handler for generating release notes. */
|
||||
function handler$8({ releaseVersion, from, to, outFile, type }) {
|
||||
function handler$9({ releaseVersion, from, to, outFile, type }) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
// Since `yargs` evaluates defaults even if a value as been provided, if no value is provided to
|
||||
// the handler, the latest semver tag on the branch is used.
|
||||
|
@ -5679,7 +5766,7 @@ function handler$8({ releaseVersion, from, to, outFile, type }) {
|
|||
/** CLI command module for generating release notes. */
|
||||
const ReleaseNotesCommandModule = {
|
||||
builder: builder$8,
|
||||
handler: handler$8,
|
||||
handler: handler$9,
|
||||
command: 'notes',
|
||||
describe: 'Generate release notes',
|
||||
};
|
||||
|
@ -5856,69 +5943,6 @@ function npmLogout(registryUrl) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
/**
|
||||
* Prints the active release trains to the console.
|
||||
* @params active Active release trains that should be printed.
|
||||
* @params config Release configuration used for querying NPM on published versions.
|
||||
*/
|
||||
function printActiveReleaseTrains(active, config) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
const { releaseCandidate, next, latest } = active;
|
||||
const isNextPublishedToNpm = yield isVersionPublishedToNpm(next.version, config);
|
||||
const nextTrainType = next.isMajor ? 'major' : 'minor';
|
||||
const ltsBranches = yield fetchLongTermSupportBranchesFromNpm(config);
|
||||
info();
|
||||
info(blue('Current version branches in the project:'));
|
||||
// Print information for release trains in the feature-freeze/release-candidate phase.
|
||||
if (releaseCandidate !== null) {
|
||||
const rcVersion = releaseCandidate.version;
|
||||
const rcTrainType = releaseCandidate.isMajor ? 'major' : 'minor';
|
||||
const rcTrainPhase = rcVersion.prerelease[0] === 'next' ? 'feature-freeze' : 'release-candidate';
|
||||
info(` • ${bold(releaseCandidate.branchName)} contains changes for an upcoming ` +
|
||||
`${rcTrainType} that is currently in ${bold(rcTrainPhase)} phase.`);
|
||||
info(` Most recent pre-release for this branch is "${bold(`v${rcVersion}`)}".`);
|
||||
}
|
||||
// Print information about the release-train in the latest phase. i.e. the patch branch.
|
||||
info(` • ${bold(latest.branchName)} contains changes for the most recent patch.`);
|
||||
info(` Most recent patch version for this branch is "${bold(`v${latest.version}`)}".`);
|
||||
// Print information about the release-train in the next phase.
|
||||
info(` • ${bold(next.branchName)} contains changes for a ${nextTrainType} ` +
|
||||
`currently in active development.`);
|
||||
// Note that there is a special case for versions in the next release-train. The version in
|
||||
// the next branch is not always published to NPM. This can happen when we recently branched
|
||||
// off for a feature-freeze release-train. More details are in the next pre-release action.
|
||||
if (isNextPublishedToNpm) {
|
||||
info(` Most recent pre-release version for this branch is "${bold(`v${next.version}`)}".`);
|
||||
}
|
||||
else {
|
||||
info(` Version is currently set to "${bold(`v${next.version}`)}", but has not been ` +
|
||||
`published yet.`);
|
||||
}
|
||||
// If no release-train in release-candidate or feature-freeze phase is active,
|
||||
// we print a message as last bullet point to make this clear.
|
||||
if (releaseCandidate === null) {
|
||||
info(' • No release-candidate or feature-freeze branch currently active.');
|
||||
}
|
||||
info();
|
||||
info(blue('Current active LTS version branches:'));
|
||||
// Print all active LTS branches (each branch as own bullet point).
|
||||
if (ltsBranches.active.length !== 0) {
|
||||
for (const ltsBranch of ltsBranches.active) {
|
||||
info(` • ${bold(ltsBranch.name)} is currently in active long-term support phase.`);
|
||||
info(` Most recent patch version for this branch is "${bold(`v${ltsBranch.version}`)}".`);
|
||||
}
|
||||
}
|
||||
info();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
|
@ -7308,7 +7332,7 @@ function builder$9(argv) {
|
|||
return addGithubTokenOption(argv);
|
||||
}
|
||||
/** Yargs command handler for staging a release. */
|
||||
function handler$9() {
|
||||
function handler$a() {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
const git = GitClient.get();
|
||||
const config = getConfig();
|
||||
|
@ -7334,7 +7358,7 @@ function handler$9() {
|
|||
/** CLI command module for publishing a release. */
|
||||
const ReleasePublishCommandModule = {
|
||||
builder: builder$9,
|
||||
handler: handler$9,
|
||||
handler: handler$a,
|
||||
command: 'publish',
|
||||
describe: 'Publish new releases and configure version branches.',
|
||||
};
|
||||
|
@ -7360,7 +7384,7 @@ function builder$a(args) {
|
|||
});
|
||||
}
|
||||
/** Yargs command handler for building a release. */
|
||||
function handler$a(args) {
|
||||
function handler$b(args) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
const { targetVersion: rawVersion, tagName } = args;
|
||||
const { npmPackages, publishRegistry } = getReleaseConfig();
|
||||
|
@ -7393,7 +7417,7 @@ function handler$a(args) {
|
|||
/** CLI command module for setting an NPM dist tag. */
|
||||
const ReleaseSetDistTagCommand = {
|
||||
builder: builder$a,
|
||||
handler: handler$a,
|
||||
handler: handler$b,
|
||||
command: 'set-dist-tag <tag-name> <target-version>',
|
||||
describe: 'Sets a given NPM dist tag for all release packages.',
|
||||
};
|
||||
|
@ -7480,7 +7504,7 @@ function builder$b(args) {
|
|||
choices: ['snapshot', 'release']
|
||||
});
|
||||
}
|
||||
function handler$b({ mode }) {
|
||||
function handler$c({ mode }) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
buildEnvStamp(mode);
|
||||
});
|
||||
|
@ -7488,7 +7512,7 @@ function handler$b({ mode }) {
|
|||
/** CLI command module for building the environment stamp. */
|
||||
const BuildEnvStampCommand = {
|
||||
builder: builder$b,
|
||||
handler: handler$b,
|
||||
handler: handler$c,
|
||||
command: 'build-env-stamp',
|
||||
describe: 'Build the environment stamping information',
|
||||
};
|
||||
|
@ -7500,6 +7524,7 @@ function buildReleaseParser(localYargs) {
|
|||
.demandCommand()
|
||||
.command(ReleasePublishCommandModule)
|
||||
.command(ReleaseBuildCommandModule)
|
||||
.command(ReleaseInfoCommandModule)
|
||||
.command(ReleaseSetDistTagCommand)
|
||||
.command(BuildEnvStampCommand)
|
||||
.command(ReleaseNotesCommandModule);
|
||||
|
@ -7929,7 +7954,7 @@ function builder$c(argv) {
|
|||
});
|
||||
}
|
||||
/** Yargs command handler for the command. */
|
||||
function handler$c({ projectRoot }) {
|
||||
function handler$d({ projectRoot }) {
|
||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
if (!fs.lstatSync(projectRoot).isDirectory()) {
|
||||
|
@ -7957,7 +7982,7 @@ function handler$c({ projectRoot }) {
|
|||
/** CLI command module. */
|
||||
const BuildAndLinkCommandModule = {
|
||||
builder: builder$c,
|
||||
handler: handler$c,
|
||||
handler: handler$d,
|
||||
command: 'build-and-link <projectRoot>',
|
||||
describe: 'Builds the release output, registers the outputs as linked, and links via yarn to the provided project',
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ ts_library(
|
|||
visibility = ["//dev-infra:__subpackages__"],
|
||||
deps = [
|
||||
"//dev-infra/release/build",
|
||||
"//dev-infra/release/info",
|
||||
"//dev-infra/release/notes",
|
||||
"//dev-infra/release/publish",
|
||||
"//dev-infra/release/set-dist-tag",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import * as yargs from 'yargs';
|
||||
|
||||
import {ReleaseBuildCommandModule} from './build/cli';
|
||||
import {ReleaseInfoCommandModule} from './info/cli';
|
||||
import {ReleaseNotesCommandModule} from './notes/cli';
|
||||
import {ReleasePublishCommandModule} from './publish/cli';
|
||||
import {ReleaseSetDistTagCommand} from './set-dist-tag/cli';
|
||||
|
@ -20,6 +21,7 @@ export function buildReleaseParser(localYargs: yargs.Argv) {
|
|||
.demandCommand()
|
||||
.command(ReleasePublishCommandModule)
|
||||
.command(ReleaseBuildCommandModule)
|
||||
.command(ReleaseInfoCommandModule)
|
||||
.command(ReleaseSetDistTagCommand)
|
||||
.command(BuildEnvStampCommand)
|
||||
.command(ReleaseNotesCommandModule);
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "info",
|
||||
srcs = ["cli.ts"],
|
||||
module_name = "@angular/dev-infra-private/release/info",
|
||||
visibility = ["//dev-infra:__subpackages__"],
|
||||
deps = [
|
||||
"//dev-infra/release/config",
|
||||
"//dev-infra/release/versioning",
|
||||
"//dev-infra/utils",
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/yargs",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CommandModule} from 'yargs';
|
||||
|
||||
import {info} from '../../utils/console';
|
||||
import {GitClient} from '../../utils/git/git-client';
|
||||
import {getReleaseConfig} from '../config/index';
|
||||
import {fetchActiveReleaseTrains} from '../versioning/active-release-trains';
|
||||
import {printActiveReleaseTrains} from '../versioning/print-active-trains';
|
||||
|
||||
/** Yargs command handler for printing release information. */
|
||||
async function handler() {
|
||||
const git = GitClient.get();
|
||||
const gitRepoWithApi = {api: git.github, ...git.remoteConfig};
|
||||
const releaseTrains = await fetchActiveReleaseTrains(gitRepoWithApi);
|
||||
|
||||
// Print the active release trains.
|
||||
await printActiveReleaseTrains(releaseTrains, getReleaseConfig());
|
||||
}
|
||||
|
||||
/** CLI command module for retrieving release information. */
|
||||
export const ReleaseInfoCommandModule: CommandModule = {
|
||||
handler,
|
||||
command: 'info',
|
||||
describe: 'Prints active release trains to the console.',
|
||||
};
|
Loading…
Reference in New Issue