feat(dev-infra): create caretaker handoff assistant to update github team membership (#42859)
Create a handoff assistant, currently only assists in updating github team membership for caretaking team. PR Close #42859
This commit is contained in:
parent
74228215a1
commit
bc1da1fe14
@ -65,6 +65,7 @@ var GithubClient = /** @class */ (function () {
|
|||||||
this.issues = this._octokit.issues;
|
this.issues = this._octokit.issues;
|
||||||
this.git = this._octokit.git;
|
this.git = this._octokit.git;
|
||||||
this.rateLimit = this._octokit.rateLimit;
|
this.rateLimit = this._octokit.rateLimit;
|
||||||
|
this.teams = this._octokit.teams;
|
||||||
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
||||||
// TypeScript requires us to provide an explicit type for these.
|
// TypeScript requires us to provide an explicit type for these.
|
||||||
this.rest = this._octokit.rest;
|
this.rest = this._octokit.rest;
|
||||||
|
@ -10,9 +10,11 @@ ts_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//dev-infra/release/versioning",
|
"//dev-infra/release/versioning",
|
||||||
"//dev-infra/utils",
|
"//dev-infra/utils",
|
||||||
|
"@npm//@types/inquirer",
|
||||||
"@npm//@types/node",
|
"@npm//@types/node",
|
||||||
"@npm//@types/node-fetch",
|
"@npm//@types/node-fetch",
|
||||||
"@npm//@types/yargs",
|
"@npm//@types/yargs",
|
||||||
|
"@npm//inquirer",
|
||||||
"@npm//multimatch",
|
"@npm//multimatch",
|
||||||
"@npm//node-fetch",
|
"@npm//node-fetch",
|
||||||
"@npm//typed-graphqlify",
|
"@npm//typed-graphqlify",
|
||||||
|
@ -8,9 +8,10 @@
|
|||||||
|
|
||||||
import {Argv} from 'yargs';
|
import {Argv} from 'yargs';
|
||||||
import {CheckModule} from './check/cli';
|
import {CheckModule} from './check/cli';
|
||||||
|
import {HandoffModule} from './handoff/cli';
|
||||||
|
|
||||||
|
|
||||||
/** Build the parser for the caretaker commands. */
|
/** Build the parser for the caretaker commands. */
|
||||||
export function buildCaretakerParser(yargs: Argv) {
|
export function buildCaretakerParser(yargs: Argv) {
|
||||||
return yargs.command(CheckModule);
|
return yargs.command(CheckModule).command(HandoffModule);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,13 @@
|
|||||||
import {assertNoErrors, getConfig, NgDevConfig} from '../utils/config';
|
import {assertNoErrors, getConfig, NgDevConfig} from '../utils/config';
|
||||||
|
|
||||||
export interface CaretakerConfig {
|
export interface CaretakerConfig {
|
||||||
|
/** Github queries showing a snapshot of pulls/issues caretakers need to monitor. */
|
||||||
githubQueries?: {name: string; query: string;}[];
|
githubQueries?: {name: string; query: string;}[];
|
||||||
|
/**
|
||||||
|
* The Github group used to track current caretakers. A second group is assumed to exist with the
|
||||||
|
* name "<group-name>-roster" containing a list of all users eligible for the caretaker group.
|
||||||
|
* */
|
||||||
|
caretakerGroup?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Retrieve and validate the config as `CaretakerConfig`. */
|
/** Retrieve and validate the config as `CaretakerConfig`. */
|
||||||
|
36
dev-infra/caretaker/handoff/cli.ts
Normal file
36
dev-infra/caretaker/handoff/cli.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* @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 {Argv, CommandModule} from 'yargs';
|
||||||
|
|
||||||
|
import {addGithubTokenOption} from '../../utils/git/github-yargs';
|
||||||
|
|
||||||
|
import {updateCaretakerTeamViaPrompt} from './update-github-team';
|
||||||
|
|
||||||
|
|
||||||
|
export interface CaretakerHandoffOptions {
|
||||||
|
githubToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Builds the command. */
|
||||||
|
function builder(yargs: Argv) {
|
||||||
|
return addGithubTokenOption(yargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Handles the command. */
|
||||||
|
async function handler() {
|
||||||
|
await updateCaretakerTeamViaPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** yargs command module for assisting in handing off caretaker. */
|
||||||
|
export const HandoffModule: CommandModule<{}, CaretakerHandoffOptions> = {
|
||||||
|
handler,
|
||||||
|
builder,
|
||||||
|
command: 'handoff',
|
||||||
|
describe: 'Run a handoff assistant to aide in moving to the next caretaker',
|
||||||
|
};
|
132
dev-infra/caretaker/handoff/update-github-team.ts
Normal file
132
dev-infra/caretaker/handoff/update-github-team.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* @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 {prompt} from 'inquirer';
|
||||||
|
|
||||||
|
import {debug, green, info, red, yellow} from '../../utils/console';
|
||||||
|
import {AuthenticatedGitClient} from '../../utils/git/authenticated-git-client';
|
||||||
|
import {getCaretakerConfig} from '../config';
|
||||||
|
|
||||||
|
/** Update the Github caretaker group, using a prompt to obtain the new caretaker group members. */
|
||||||
|
export async function updateCaretakerTeamViaPrompt() {
|
||||||
|
/** Caretaker specific configuration. */
|
||||||
|
const caretakerConfig = getCaretakerConfig().caretaker;
|
||||||
|
|
||||||
|
if (caretakerConfig.caretakerGroup === undefined) {
|
||||||
|
throw Error('`caretakerGroup` is not defined in the `caretaker` config');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The list of current members in the group. */
|
||||||
|
const current = await getGroupMembers(caretakerConfig.caretakerGroup);
|
||||||
|
/** The list of members able to be added to the group as defined by a separate roster group. */
|
||||||
|
const roster = await getGroupMembers(`${caretakerConfig.caretakerGroup}-roster`);
|
||||||
|
const {
|
||||||
|
/** The list of users selected to be members of the caretaker group. */
|
||||||
|
selected,
|
||||||
|
/** Whether the user positively confirmed the selected made. */
|
||||||
|
confirm
|
||||||
|
} =
|
||||||
|
await prompt([
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
choices: roster,
|
||||||
|
message: 'Select 2 caretakers for the upcoming rotation:',
|
||||||
|
default: current,
|
||||||
|
name: 'selected',
|
||||||
|
prefix: '',
|
||||||
|
validate: (selected: string[]) => {
|
||||||
|
if (selected.length !== 2) {
|
||||||
|
return 'Please select exactly 2 caretakers for the upcoming rotation.';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'confirm',
|
||||||
|
default: true,
|
||||||
|
prefix: '',
|
||||||
|
message: 'Are you sure?',
|
||||||
|
name: 'confirm',
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (confirm === false) {
|
||||||
|
info(yellow(' ⚠ Skipping caretaker group update.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSON.stringify(selected) === JSON.stringify(current)) {
|
||||||
|
info(green(' √ Caretaker group already up to date.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await setCaretakerGroup(caretakerConfig.caretakerGroup, selected);
|
||||||
|
} catch {
|
||||||
|
info(red(' ✘ Failed to update caretaker group.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info(green(' √ Successfully updated caretaker group'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Retrieve the current list of members for the provided group. */
|
||||||
|
async function getGroupMembers(group: string) {
|
||||||
|
/** The authenticated GitClient instance. */
|
||||||
|
const git = AuthenticatedGitClient.get();
|
||||||
|
|
||||||
|
return (await git.github.teams.listMembersInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
}))
|
||||||
|
.data.filter(_ => !!_)
|
||||||
|
.map(member => member!.login);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setCaretakerGroup(group: string, members: string[]) {
|
||||||
|
/** The authenticated GitClient instance. */
|
||||||
|
const git = AuthenticatedGitClient.get();
|
||||||
|
/** The full name of the group <org>/<group name>. */
|
||||||
|
const fullSlug = `${git.remoteConfig.owner}/${group}`;
|
||||||
|
/** The list of current members of the group. */
|
||||||
|
const current = await getGroupMembers(group);
|
||||||
|
/** The list of users to be removed from the group. */
|
||||||
|
const removed = current.filter(login => !members.includes(login));
|
||||||
|
/** Add a user to the group. */
|
||||||
|
const add = async (username: string) => {
|
||||||
|
debug(`Adding ${username} to ${fullSlug}.`);
|
||||||
|
await git.github.teams.addOrUpdateMembershipForUserInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
username,
|
||||||
|
role: 'maintainer',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/** Remove a user from the group. */
|
||||||
|
const remove = async (username: string) => {
|
||||||
|
debug(`Removing ${username} from ${fullSlug}.`);
|
||||||
|
await git.github.teams.removeMembershipForUserInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
debug.group(`Caretaker Group: ${fullSlug}`);
|
||||||
|
debug(`Current Membership: ${current.join(', ')}`);
|
||||||
|
debug(`New Membership: ${members.join(', ')}`);
|
||||||
|
debug(`Removed: ${removed.join(', ')}`);
|
||||||
|
debug.groupEnd();
|
||||||
|
|
||||||
|
// Add members before removing to prevent the account performing the action from removing their
|
||||||
|
// permissions to change the group membership early.
|
||||||
|
await Promise.all(members.map(add));
|
||||||
|
await Promise.all(removed.map(remove));
|
||||||
|
|
||||||
|
debug(`Successfuly updated ${fullSlug}`);
|
||||||
|
}
|
@ -228,6 +228,7 @@ var GithubClient = /** @class */ (function () {
|
|||||||
this.issues = this._octokit.issues;
|
this.issues = this._octokit.issues;
|
||||||
this.git = this._octokit.git;
|
this.git = this._octokit.git;
|
||||||
this.rateLimit = this._octokit.rateLimit;
|
this.rateLimit = this._octokit.rateLimit;
|
||||||
|
this.teams = this._octokit.teams;
|
||||||
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
||||||
// TypeScript requires us to provide an explicit type for these.
|
// TypeScript requires us to provide an explicit type for these.
|
||||||
this.rest = this._octokit.rest;
|
this.rest = this._octokit.rest;
|
||||||
@ -1578,6 +1579,150 @@ const CheckModule = {
|
|||||||
describe: 'Check the status of information the caretaker manages for the repository',
|
describe: 'Check the status of information the caretaker manages for the repository',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
/** Update the Github caretaker group, using a prompt to obtain the new caretaker group members. */
|
||||||
|
function updateCaretakerTeamViaPrompt() {
|
||||||
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
/** Caretaker specific configuration. */
|
||||||
|
const caretakerConfig = getCaretakerConfig().caretaker;
|
||||||
|
if (caretakerConfig.caretakerGroup === undefined) {
|
||||||
|
throw Error('`caretakerGroup` is not defined in the `caretaker` config');
|
||||||
|
}
|
||||||
|
/** The list of current members in the group. */
|
||||||
|
const current = yield getGroupMembers(caretakerConfig.caretakerGroup);
|
||||||
|
/** The list of members able to be added to the group as defined by a separate roster group. */
|
||||||
|
const roster = yield getGroupMembers(`${caretakerConfig.caretakerGroup}-roster`);
|
||||||
|
const {
|
||||||
|
/** The list of users selected to be members of the caretaker group. */
|
||||||
|
selected,
|
||||||
|
/** Whether the user positively confirmed the selected made. */
|
||||||
|
confirm } = yield inquirer.prompt([
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
choices: roster,
|
||||||
|
message: 'Select 2 caretakers for the upcoming rotation:',
|
||||||
|
default: current,
|
||||||
|
name: 'selected',
|
||||||
|
prefix: '',
|
||||||
|
validate: (selected) => {
|
||||||
|
if (selected.length !== 2) {
|
||||||
|
return 'Please select exactly 2 caretakers for the upcoming rotation.';
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'confirm',
|
||||||
|
default: true,
|
||||||
|
prefix: '',
|
||||||
|
message: 'Are you sure?',
|
||||||
|
name: 'confirm',
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
if (confirm === false) {
|
||||||
|
info(yellow(' ⚠ Skipping caretaker group update.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (JSON.stringify(selected) === JSON.stringify(current)) {
|
||||||
|
info(green(' √ Caretaker group already up to date.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
yield setCaretakerGroup(caretakerConfig.caretakerGroup, selected);
|
||||||
|
}
|
||||||
|
catch (_a) {
|
||||||
|
info(red(' ✘ Failed to update caretaker group.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info(green(' √ Successfully updated caretaker group'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/** Retrieve the current list of members for the provided group. */
|
||||||
|
function getGroupMembers(group) {
|
||||||
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
/** The authenticated GitClient instance. */
|
||||||
|
const git = AuthenticatedGitClient.get();
|
||||||
|
return (yield git.github.teams.listMembersInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
}))
|
||||||
|
.data.filter(_ => !!_)
|
||||||
|
.map(member => member.login);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function setCaretakerGroup(group, members) {
|
||||||
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
/** The authenticated GitClient instance. */
|
||||||
|
const git = AuthenticatedGitClient.get();
|
||||||
|
/** The full name of the group <org>/<group name>. */
|
||||||
|
const fullSlug = `${git.remoteConfig.owner}/${group}`;
|
||||||
|
/** The list of current members of the group. */
|
||||||
|
const current = yield getGroupMembers(group);
|
||||||
|
/** The list of users to be removed from the group. */
|
||||||
|
const removed = current.filter(login => !members.includes(login));
|
||||||
|
/** Add a user to the group. */
|
||||||
|
const add = (username) => tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
debug(`Adding ${username} to ${fullSlug}.`);
|
||||||
|
yield git.github.teams.addOrUpdateMembershipForUserInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
username,
|
||||||
|
role: 'maintainer',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/** Remove a user from the group. */
|
||||||
|
const remove = (username) => tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
debug(`Removing ${username} from ${fullSlug}.`);
|
||||||
|
yield git.github.teams.removeMembershipForUserInOrg({
|
||||||
|
org: git.remoteConfig.owner,
|
||||||
|
team_slug: group,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
debug.group(`Caretaker Group: ${fullSlug}`);
|
||||||
|
debug(`Current Membership: ${current.join(', ')}`);
|
||||||
|
debug(`New Membership: ${members.join(', ')}`);
|
||||||
|
debug(`Removed: ${removed.join(', ')}`);
|
||||||
|
debug.groupEnd();
|
||||||
|
// Add members before removing to prevent the account performing the action from removing their
|
||||||
|
// permissions to change the group membership early.
|
||||||
|
yield Promise.all(members.map(add));
|
||||||
|
yield Promise.all(removed.map(remove));
|
||||||
|
debug(`Successfuly updated ${fullSlug}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
/** Builds the command. */
|
||||||
|
function builder$1(yargs) {
|
||||||
|
return addGithubTokenOption(yargs);
|
||||||
|
}
|
||||||
|
/** Handles the command. */
|
||||||
|
function handler$1() {
|
||||||
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
|
yield updateCaretakerTeamViaPrompt();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/** yargs command module for assisting in handing off caretaker. */
|
||||||
|
const HandoffModule = {
|
||||||
|
handler: handler$1,
|
||||||
|
builder: builder$1,
|
||||||
|
command: 'handoff',
|
||||||
|
describe: 'Run a handoff assistant to aide in moving to the next caretaker',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @license
|
* @license
|
||||||
* Copyright Google LLC All Rights Reserved.
|
* Copyright Google LLC All Rights Reserved.
|
||||||
@ -1587,7 +1732,7 @@ const CheckModule = {
|
|||||||
*/
|
*/
|
||||||
/** Build the parser for the caretaker commands. */
|
/** Build the parser for the caretaker commands. */
|
||||||
function buildCaretakerParser(yargs) {
|
function buildCaretakerParser(yargs) {
|
||||||
return yargs.command(CheckModule);
|
return yargs.command(CheckModule).command(HandoffModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1666,7 +1811,7 @@ function restoreCommitMessage(filePath, source) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the command. */
|
/** Builds the command. */
|
||||||
function builder$1(yargs) {
|
function builder$2(yargs) {
|
||||||
return yargs
|
return yargs
|
||||||
.option('file-env-variable', {
|
.option('file-env-variable', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -1678,7 +1823,7 @@ function builder$1(yargs) {
|
|||||||
.positional('source', { type: 'string' });
|
.positional('source', { type: 'string' });
|
||||||
}
|
}
|
||||||
/** Handles the command. */
|
/** Handles the command. */
|
||||||
function handler$1({ fileEnvVariable, file, source }) {
|
function handler$2({ fileEnvVariable, file, source }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
// File and source are provided as command line parameters
|
// File and source are provided as command line parameters
|
||||||
if (file !== undefined) {
|
if (file !== undefined) {
|
||||||
@ -1700,8 +1845,8 @@ function handler$1({ fileEnvVariable, file, source }) {
|
|||||||
}
|
}
|
||||||
/** yargs command module describing the command. */
|
/** yargs command module describing the command. */
|
||||||
const RestoreCommitMessageModule = {
|
const RestoreCommitMessageModule = {
|
||||||
handler: handler$1,
|
handler: handler$2,
|
||||||
builder: builder$1,
|
builder: builder$2,
|
||||||
command: 'restore-commit-message-draft [file] [source]',
|
command: 'restore-commit-message-draft [file] [source]',
|
||||||
// Description: Restore a commit message draft if one has been saved from a failed commit attempt.
|
// Description: Restore a commit message draft if one has been saved from a failed commit attempt.
|
||||||
// No describe is defiend to hide the command from the --help.
|
// No describe is defiend to hide the command from the --help.
|
||||||
@ -2116,7 +2261,7 @@ function validateFile(filePath, isErrorMode) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the command. */
|
/** Builds the command. */
|
||||||
function builder$2(yargs) {
|
function builder$3(yargs) {
|
||||||
var _a;
|
var _a;
|
||||||
return yargs
|
return yargs
|
||||||
.option('file', {
|
.option('file', {
|
||||||
@ -2146,7 +2291,7 @@ function builder$2(yargs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Handles the command. */
|
/** Handles the command. */
|
||||||
function handler$2({ error, file, fileEnvVariable }) {
|
function handler$3({ error, file, fileEnvVariable }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const filePath = file || fileEnvVariable || '.git/COMMIT_EDITMSG';
|
const filePath = file || fileEnvVariable || '.git/COMMIT_EDITMSG';
|
||||||
validateFile(filePath, error);
|
validateFile(filePath, error);
|
||||||
@ -2154,8 +2299,8 @@ function handler$2({ error, file, fileEnvVariable }) {
|
|||||||
}
|
}
|
||||||
/** yargs command module describing the command. */
|
/** yargs command module describing the command. */
|
||||||
const ValidateFileModule = {
|
const ValidateFileModule = {
|
||||||
handler: handler$2,
|
handler: handler$3,
|
||||||
builder: builder$2,
|
builder: builder$3,
|
||||||
command: 'pre-commit-validate',
|
command: 'pre-commit-validate',
|
||||||
describe: 'Validate the most recent commit message',
|
describe: 'Validate the most recent commit message',
|
||||||
};
|
};
|
||||||
@ -2240,7 +2385,7 @@ function validateCommitRange(from, to) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the command. */
|
/** Builds the command. */
|
||||||
function builder$3(yargs) {
|
function builder$4(yargs) {
|
||||||
return yargs
|
return yargs
|
||||||
.positional('startingRef', {
|
.positional('startingRef', {
|
||||||
description: 'The first ref in the range to select',
|
description: 'The first ref in the range to select',
|
||||||
@ -2254,7 +2399,7 @@ function builder$3(yargs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Handles the command. */
|
/** Handles the command. */
|
||||||
function handler$3({ startingRef, endingRef }) {
|
function handler$4({ startingRef, endingRef }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
// If on CI, and no pull request number is provided, assume the branch
|
// If on CI, and no pull request number is provided, assume the branch
|
||||||
// being run on is an upstream branch.
|
// being run on is an upstream branch.
|
||||||
@ -2270,8 +2415,8 @@ function handler$3({ startingRef, endingRef }) {
|
|||||||
}
|
}
|
||||||
/** yargs command module describing the command. */
|
/** yargs command module describing the command. */
|
||||||
const ValidateRangeModule = {
|
const ValidateRangeModule = {
|
||||||
handler: handler$3,
|
handler: handler$4,
|
||||||
builder: builder$3,
|
builder: builder$4,
|
||||||
command: 'validate-range <starting-ref> [ending-ref]',
|
command: 'validate-range <starting-ref> [ending-ref]',
|
||||||
describe: 'Validate a range of commit messages',
|
describe: 'Validate a range of commit messages',
|
||||||
};
|
};
|
||||||
@ -2982,7 +3127,7 @@ function printTargetBranchesForPr(prNumber) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the command. */
|
/** Builds the command. */
|
||||||
function builder$4(yargs) {
|
function builder$5(yargs) {
|
||||||
return yargs.positional('pr', {
|
return yargs.positional('pr', {
|
||||||
description: 'The pull request number',
|
description: 'The pull request number',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@ -2990,15 +3135,15 @@ function builder$4(yargs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Handles the command. */
|
/** Handles the command. */
|
||||||
function handler$4({ pr }) {
|
function handler$5({ pr }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
yield printTargetBranchesForPr(pr);
|
yield printTargetBranchesForPr(pr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** yargs command module describing the command. */
|
/** yargs command module describing the command. */
|
||||||
const CheckTargetBranchesModule = {
|
const CheckTargetBranchesModule = {
|
||||||
handler: handler$4,
|
handler: handler$5,
|
||||||
builder: builder$4,
|
builder: builder$5,
|
||||||
command: 'check-target-branches <pr>',
|
command: 'check-target-branches <pr>',
|
||||||
describe: 'Check a PR to determine what branches it is currently targeting',
|
describe: 'Check a PR to determine what branches it is currently targeting',
|
||||||
};
|
};
|
||||||
@ -3203,11 +3348,11 @@ function checkOutPullRequestLocally(prNumber, githubToken, opts = {}) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the checkout pull request command. */
|
/** Builds the checkout pull request command. */
|
||||||
function builder$5(yargs) {
|
function builder$6(yargs) {
|
||||||
return addGithubTokenOption(yargs).positional('prNumber', { type: 'number', demandOption: true });
|
return addGithubTokenOption(yargs).positional('prNumber', { type: 'number', demandOption: true });
|
||||||
}
|
}
|
||||||
/** Handles the checkout pull request command. */
|
/** Handles the checkout pull request command. */
|
||||||
function handler$5({ prNumber, githubToken }) {
|
function handler$6({ prNumber, githubToken }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const prCheckoutOptions = { allowIfMaintainerCannotModify: true, branchName: `pr-${prNumber}` };
|
const prCheckoutOptions = { allowIfMaintainerCannotModify: true, branchName: `pr-${prNumber}` };
|
||||||
yield checkOutPullRequestLocally(prNumber, githubToken, prCheckoutOptions);
|
yield checkOutPullRequestLocally(prNumber, githubToken, prCheckoutOptions);
|
||||||
@ -3215,8 +3360,8 @@ function handler$5({ prNumber, githubToken }) {
|
|||||||
}
|
}
|
||||||
/** yargs command module for checking out a PR */
|
/** yargs command module for checking out a PR */
|
||||||
const CheckoutCommandModule = {
|
const CheckoutCommandModule = {
|
||||||
handler: handler$5,
|
handler: handler$6,
|
||||||
builder: builder$5,
|
builder: builder$6,
|
||||||
command: 'checkout <pr-number>',
|
command: 'checkout <pr-number>',
|
||||||
describe: 'Checkout a PR from the upstream repo',
|
describe: 'Checkout a PR from the upstream repo',
|
||||||
};
|
};
|
||||||
@ -4534,7 +4679,7 @@ function createPullRequestMergeTask(flags) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Builds the command. */
|
/** Builds the command. */
|
||||||
function builder$6(yargs) {
|
function builder$7(yargs) {
|
||||||
return addGithubTokenOption(yargs)
|
return addGithubTokenOption(yargs)
|
||||||
.help()
|
.help()
|
||||||
.strict()
|
.strict()
|
||||||
@ -4550,7 +4695,7 @@ function builder$6(yargs) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Handles the command. */
|
/** Handles the command. */
|
||||||
function handler$6(_a) {
|
function handler$7(_a) {
|
||||||
var pr = _a.pr, branchPrompt = _a.branchPrompt;
|
var pr = _a.pr, branchPrompt = _a.branchPrompt;
|
||||||
return tslib.__awaiter(this, void 0, void 0, function () {
|
return tslib.__awaiter(this, void 0, void 0, function () {
|
||||||
return tslib.__generator(this, function (_b) {
|
return tslib.__generator(this, function (_b) {
|
||||||
@ -4565,8 +4710,8 @@ function handler$6(_a) {
|
|||||||
}
|
}
|
||||||
/** yargs command module describing the command. */
|
/** yargs command module describing the command. */
|
||||||
var MergeCommandModule = {
|
var MergeCommandModule = {
|
||||||
handler: handler$6,
|
handler: handler$7,
|
||||||
builder: builder$6,
|
builder: builder$7,
|
||||||
command: 'merge <pr>',
|
command: 'merge <pr>',
|
||||||
describe: 'Merge a PR into its targeted branches.',
|
describe: 'Merge a PR into its targeted branches.',
|
||||||
};
|
};
|
||||||
@ -5217,7 +5362,7 @@ function buildReleaseOutput(stampForRelease = false) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Yargs command builder for configuring the `ng-dev release build` command. */
|
/** Yargs command builder for configuring the `ng-dev release build` command. */
|
||||||
function builder$7(argv) {
|
function builder$8(argv) {
|
||||||
return argv.option('json', {
|
return argv.option('json', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Whether the built packages should be printed to stdout as JSON.',
|
description: 'Whether the built packages should be printed to stdout as JSON.',
|
||||||
@ -5225,7 +5370,7 @@ function builder$7(argv) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Yargs command handler for building a release. */
|
/** Yargs command handler for building a release. */
|
||||||
function handler$7(args) {
|
function handler$8(args) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const { npmPackages } = getReleaseConfig();
|
const { npmPackages } = getReleaseConfig();
|
||||||
let builtPackages = yield buildReleaseOutput(true);
|
let builtPackages = yield buildReleaseOutput(true);
|
||||||
@ -5260,8 +5405,8 @@ function handler$7(args) {
|
|||||||
}
|
}
|
||||||
/** CLI command module for building release output. */
|
/** CLI command module for building release output. */
|
||||||
const ReleaseBuildCommandModule = {
|
const ReleaseBuildCommandModule = {
|
||||||
builder: builder$7,
|
builder: builder$8,
|
||||||
handler: handler$7,
|
handler: handler$8,
|
||||||
command: 'build',
|
command: 'build',
|
||||||
describe: 'Builds the release output for the current branch.',
|
describe: 'Builds the release output for the current branch.',
|
||||||
};
|
};
|
||||||
@ -5337,7 +5482,7 @@ function printActiveReleaseTrains(active, config) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Yargs command handler for printing release information. */
|
/** Yargs command handler for printing release information. */
|
||||||
function handler$8() {
|
function handler$9() {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const git = GitClient.get();
|
const git = GitClient.get();
|
||||||
const gitRepoWithApi = Object.assign({ api: git.github }, git.remoteConfig);
|
const gitRepoWithApi = Object.assign({ api: git.github }, git.remoteConfig);
|
||||||
@ -5348,7 +5493,7 @@ function handler$8() {
|
|||||||
}
|
}
|
||||||
/** CLI command module for retrieving release information. */
|
/** CLI command module for retrieving release information. */
|
||||||
const ReleaseInfoCommandModule = {
|
const ReleaseInfoCommandModule = {
|
||||||
handler: handler$8,
|
handler: handler$9,
|
||||||
command: 'info',
|
command: 'info',
|
||||||
describe: 'Prints active release trains to the console.',
|
describe: 'Prints active release trains to the console.',
|
||||||
};
|
};
|
||||||
@ -5758,7 +5903,7 @@ class ReleaseNotes {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Yargs command builder for configuring the `ng-dev release build` command. */
|
/** Yargs command builder for configuring the `ng-dev release build` command. */
|
||||||
function builder$8(argv) {
|
function builder$9(argv) {
|
||||||
return argv
|
return argv
|
||||||
.option('releaseVersion', { type: 'string', default: '0.0.0', coerce: (version) => new semver.SemVer(version) })
|
.option('releaseVersion', { type: 'string', default: '0.0.0', coerce: (version) => new semver.SemVer(version) })
|
||||||
.option('from', {
|
.option('from', {
|
||||||
@ -5784,7 +5929,7 @@ function builder$8(argv) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Yargs command handler for generating release notes. */
|
/** Yargs command handler for generating release notes. */
|
||||||
function handler$9({ releaseVersion, from, to, outFile, type }) {
|
function handler$a({ releaseVersion, from, to, outFile, type }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
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
|
// 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.
|
// the handler, the latest semver tag on the branch is used.
|
||||||
@ -5805,8 +5950,8 @@ function handler$9({ releaseVersion, from, to, outFile, type }) {
|
|||||||
}
|
}
|
||||||
/** CLI command module for generating release notes. */
|
/** CLI command module for generating release notes. */
|
||||||
const ReleaseNotesCommandModule = {
|
const ReleaseNotesCommandModule = {
|
||||||
builder: builder$8,
|
builder: builder$9,
|
||||||
handler: handler$9,
|
handler: handler$a,
|
||||||
command: 'notes',
|
command: 'notes',
|
||||||
describe: 'Generate release notes',
|
describe: 'Generate release notes',
|
||||||
};
|
};
|
||||||
@ -7367,11 +7512,11 @@ class ReleaseTool {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Yargs command builder for configuring the `ng-dev release publish` command. */
|
/** Yargs command builder for configuring the `ng-dev release publish` command. */
|
||||||
function builder$9(argv) {
|
function builder$a(argv) {
|
||||||
return addGithubTokenOption(argv);
|
return addGithubTokenOption(argv);
|
||||||
}
|
}
|
||||||
/** Yargs command handler for staging a release. */
|
/** Yargs command handler for staging a release. */
|
||||||
function handler$a() {
|
function handler$b() {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const git = GitClient.get();
|
const git = GitClient.get();
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
@ -7396,8 +7541,8 @@ function handler$a() {
|
|||||||
}
|
}
|
||||||
/** CLI command module for publishing a release. */
|
/** CLI command module for publishing a release. */
|
||||||
const ReleasePublishCommandModule = {
|
const ReleasePublishCommandModule = {
|
||||||
builder: builder$9,
|
builder: builder$a,
|
||||||
handler: handler$a,
|
handler: handler$b,
|
||||||
command: 'publish',
|
command: 'publish',
|
||||||
describe: 'Publish new releases and configure version branches.',
|
describe: 'Publish new releases and configure version branches.',
|
||||||
};
|
};
|
||||||
@ -7409,7 +7554,7 @@ const ReleasePublishCommandModule = {
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
function builder$a(args) {
|
function builder$b(args) {
|
||||||
return args
|
return args
|
||||||
.positional('tagName', {
|
.positional('tagName', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -7423,7 +7568,7 @@ function builder$a(args) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Yargs command handler for building a release. */
|
/** Yargs command handler for building a release. */
|
||||||
function handler$b(args) {
|
function handler$c(args) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
const { targetVersion: rawVersion, tagName } = args;
|
const { targetVersion: rawVersion, tagName } = args;
|
||||||
const { npmPackages, publishRegistry } = getReleaseConfig();
|
const { npmPackages, publishRegistry } = getReleaseConfig();
|
||||||
@ -7455,8 +7600,8 @@ function handler$b(args) {
|
|||||||
}
|
}
|
||||||
/** CLI command module for setting an NPM dist tag. */
|
/** CLI command module for setting an NPM dist tag. */
|
||||||
const ReleaseSetDistTagCommand = {
|
const ReleaseSetDistTagCommand = {
|
||||||
builder: builder$a,
|
builder: builder$b,
|
||||||
handler: handler$b,
|
handler: handler$c,
|
||||||
command: 'set-dist-tag <tag-name> <target-version>',
|
command: 'set-dist-tag <tag-name> <target-version>',
|
||||||
describe: 'Sets a given NPM dist tag for all release packages.',
|
describe: 'Sets a given NPM dist tag for all release packages.',
|
||||||
};
|
};
|
||||||
@ -7536,22 +7681,22 @@ function getCurrentGitUser() {
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
function builder$b(args) {
|
function builder$c(args) {
|
||||||
return args.option('mode', {
|
return args.option('mode', {
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
description: 'Whether the env-stamp should be built for a snapshot or release',
|
description: 'Whether the env-stamp should be built for a snapshot or release',
|
||||||
choices: ['snapshot', 'release']
|
choices: ['snapshot', 'release']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function handler$c({ mode }) {
|
function handler$d({ mode }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
buildEnvStamp(mode);
|
buildEnvStamp(mode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** CLI command module for building the environment stamp. */
|
/** CLI command module for building the environment stamp. */
|
||||||
const BuildEnvStampCommand = {
|
const BuildEnvStampCommand = {
|
||||||
builder: builder$b,
|
builder: builder$c,
|
||||||
handler: handler$c,
|
handler: handler$d,
|
||||||
command: 'build-env-stamp',
|
command: 'build-env-stamp',
|
||||||
describe: 'Build the environment stamping information',
|
describe: 'Build the environment stamping information',
|
||||||
};
|
};
|
||||||
@ -7984,7 +8129,7 @@ function convertReferenceChainToString(chain) {
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/** Yargs command builder for the command. */
|
/** Yargs command builder for the command. */
|
||||||
function builder$c(argv) {
|
function builder$d(argv) {
|
||||||
return argv.positional('projectRoot', {
|
return argv.positional('projectRoot', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
normalize: true,
|
normalize: true,
|
||||||
@ -7993,7 +8138,7 @@ function builder$c(argv) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/** Yargs command handler for the command. */
|
/** Yargs command handler for the command. */
|
||||||
function handler$d({ projectRoot }) {
|
function handler$e({ projectRoot }) {
|
||||||
return tslib.__awaiter(this, void 0, void 0, function* () {
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
if (!fs.lstatSync(projectRoot).isDirectory()) {
|
if (!fs.lstatSync(projectRoot).isDirectory()) {
|
||||||
@ -8020,8 +8165,8 @@ function handler$d({ projectRoot }) {
|
|||||||
}
|
}
|
||||||
/** CLI command module. */
|
/** CLI command module. */
|
||||||
const BuildAndLinkCommandModule = {
|
const BuildAndLinkCommandModule = {
|
||||||
builder: builder$c,
|
builder: builder$d,
|
||||||
handler: handler$d,
|
handler: handler$e,
|
||||||
command: 'build-and-link <projectRoot>',
|
command: 'build-and-link <projectRoot>',
|
||||||
describe: 'Builds the release output, registers the outputs as linked, and links via yarn to the provided project',
|
describe: 'Builds the release output, registers the outputs as linked, and links via yarn to the provided project',
|
||||||
};
|
};
|
||||||
|
@ -45,6 +45,7 @@ export class GithubClient {
|
|||||||
readonly issues = this._octokit.issues;
|
readonly issues = this._octokit.issues;
|
||||||
readonly git = this._octokit.git;
|
readonly git = this._octokit.git;
|
||||||
readonly rateLimit = this._octokit.rateLimit;
|
readonly rateLimit = this._octokit.rateLimit;
|
||||||
|
readonly teams = this._octokit.teams;
|
||||||
|
|
||||||
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
// Note: These are properties from `Octokit` that are brought in by optional plugins.
|
||||||
// TypeScript requires us to provide an explicit type for these.
|
// TypeScript requires us to provide an explicit type for these.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user