diff --git a/scripts/open-user-pr.mjs b/scripts/open-user-pr.mjs deleted file mode 100644 index ef2509a075c44..0000000000000 --- a/scripts/open-user-pr.mjs +++ /dev/null @@ -1,69 +0,0 @@ -import { - Octokit, -} from "@octokit/rest"; - -import { - runSequence, -} from "./run-sequence.mjs"; - -const userName = process.env.GH_USERNAME || "typescript-bot"; -const reviewers = process.env.REQUESTING_USER ? [process.env.REQUESTING_USER] : ["weswigham", "sandersn", "RyanCavanaugh"]; -const masterBranchname = `user-baseline-updates`; -const targetBranch = process.env.TARGET_BRANCH || "main"; -const branchName = process.env.TARGET_FORK?.toLowerCase() === "microsoft" && (targetBranch === "main" || targetBranch === "refs/heads/main") - ? masterBranchname - : `user-update-${process.env.TARGET_FORK}-${process.env.TARGET_BRANCH ? "-" + process.env.TARGET_BRANCH : ""}`; -const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`; -const baseRef = branchName === masterBranchname ? "main" : masterBranchname; -runSequence([ - ["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork - ["git", ["checkout", "."]], // reset any changes - ["git", ["fetch", baseRef === "main" ? "origin" : "fork", baseRef]], // fetch target ref in case it's not present locally - ["git", ["checkout", baseRef]], // move head to target - ["node", ["./node_modules/hereby/dist/cli.js", "baseline-accept"]], // accept baselines - ["git", ["checkout", "-b", branchName]], // create a branch - ["git", ["add", "."]], // Add all changes - ["git", ["commit", "-m", `"Update user baselines${+(process.env.SOURCE_ISSUE ?? 0) === 33716 ? " +cc @sandersn" : ""}"`]], // Commit all changes (ping nathan if we would post to CI thread) - ["git", ["push", "--set-upstream", "fork", branchName, "-f"]], // push the branch -]); - -const gh = new Octokit({ - auth: process.argv[2], -}); -const prOwner = branchName === masterBranchname ? "microsoft" : userName; -gh.pulls.create({ - owner: prOwner, - repo: "TypeScript", - maintainer_can_modify: true, - title: `🤖 User test baselines have changed` + (process.env.TARGET_BRANCH ? ` for ${process.env.TARGET_BRANCH}` : ""), - head: `${userName}:${branchName}`, - base: branchName === masterBranchname ? "main" : masterBranchname, - body: `${process.env.SOURCE_ISSUE ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.SOURCE_ISSUE} ` + "\n" : ""}Please review the diff and merge if no changes are unexpected. -You can view the build log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary). - -cc ${reviewers.map(r => "@" + r).join(" ")}`, -}).then(async r => { - const num = r.data.number; - console.log(`Pull request ${num} created.`); - if (!process.env.SOURCE_ISSUE) { - await gh.pulls.requestReviewers({ - owner: prOwner, - repo: "TypeScript", - pull_number: num, - reviewers, - }); - } - else { - await gh.issues.createComment({ - issue_number: +process.env.SOURCE_ISSUE, - owner: "microsoft", - repo: "TypeScript", - body: `The user suite test run you requested has finished and _failed_. I've opened a [PR with the baseline diff from master](${r.data.html_url}).`, - }); - } -}).then(() => { - console.log(`Reviewers requested, done.`); -}).catch(e => { - console.error(e); - process.exit(1); -}); diff --git a/scripts/request-pr-review.mjs b/scripts/request-pr-review.mjs deleted file mode 100644 index ef5a69808deed..0000000000000 --- a/scripts/request-pr-review.mjs +++ /dev/null @@ -1,75 +0,0 @@ -import { - Octokit, -} from "@octokit/rest"; -import minimist from "minimist"; - -const options = minimist(process.argv.slice(2), { - boolean: ["help"], - string: ["token", "pull", "reviewer", "owner", "repo"], - alias: { - pr: "pull", - h: "help", - ["?"]: "help", - }, - default: { - token: process.env.GH_TOKEN, - pull: process.env.GH_PULL_NUMBER, - reviewer: process.env.REQUESTED_REVIEWER, - owner: "microsoft", - repo: "TypeScript", - }, -}); - -if (options.help) { - printHelpAndExit(0); -} - -if (!options.token || !options.pull || !options.reviewer || !options.owner || !options.repo) { - console.error("Invalid arguments"); - printHelpAndExit(-1); -} - -const pull_number = +options.pull; -if (!isFinite(pull_number)) { - console.error("Invalid arguments"); - printHelpAndExit(-2); -} - -const reviewers = Array.isArray(options.reviewer) ? options.reviewer : [options.reviewer]; - -main().catch(console.error); - -async function main() { - const gh = new Octokit({ auth: options.token }); - const response = await gh.pulls.requestReviewers({ - owner: options.owner, - repo: options.repo, - pull_number, - reviewers, - }); - if (response.status === 201) { - console.log(`Added ${reviewers.join(", ")} to ${response.data.url}`); - } - else { - console.log(`Failed to add ${reviewers.join(", ")} to the pull request.`); - } -} - -/** - * @param {number} exitCode - */ -function printHelpAndExit(exitCode) { - console.log(` -usage: request-pr-review.js [options] - -options: - --token Your GitHub auth token. Uses %GH_TOKEN% if present. - --owner The GH user or organization for the repo (default: 'microsoft'). - --repo The GH repo for the pull request (default: 'TypeScript'). - --pull The pull request number. Uses %GH_PULL_NUMBER% if present. - --reviewer The GH username of reviewer to add. May be specified multiple times. - Uses %REQUESTED_REVIEWER% if present. - -h --help Prints this help message. -`); - return process.exit(exitCode); -} diff --git a/scripts/update-experimental-branches.mjs b/scripts/update-experimental-branches.mjs deleted file mode 100644 index 3f3493296c36f..0000000000000 --- a/scripts/update-experimental-branches.mjs +++ /dev/null @@ -1,105 +0,0 @@ -import { - Octokit, -} from "@octokit/rest"; - -import { - runSequence, -} from "./run-sequence.mjs"; - -// The first is used by bot-based kickoffs, the second by automatic triggers -const triggeredPR = process.env.SOURCE_ISSUE || process.env.SYSTEM_PULLREQUEST_PULLREQUESTNUMBER; - -/** - * This program should be invoked as `node ./scripts/update-experimental-branches ` - * TODO: the following is racey - if two experiment-enlisted PRs trigger simultaneously and witness one another in an unupdated state, they'll both produce - * a new experimental branch, but each will be missing a change from the other. There's no _great_ way to fix this beyond setting the maximum concurrency - * of this task to 1 (so only one job is allowed to update experiments at a time). - */ -async function main() { - const gh = new Octokit({ - auth: process.argv[2], - }); - const prnums = (await gh.issues.listForRepo({ - labels: "typescript@experimental", - sort: "created", - state: "open", - owner: "Microsoft", - repo: "TypeScript", - })).data.filter(i => !!i.pull_request).map(i => i.number); - if (triggeredPR && !prnums.some(n => n === +triggeredPR)) { - return; // Only have work to do for enlisted PRs - } - console.log(`Performing experimental branch updating and merging for pull requests ${prnums.join(", ")}`); - - const userName = process.env.GH_USERNAME; - const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`; - - // Forcibly cleanup workspace - runSequence([ - ["git", ["checkout", "."]], - ["git", ["fetch", "-fu", "origin", "main:main"]], - ["git", ["checkout", "main"]], - ["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork - ]); - - for (const numRaw of prnums) { - const num = +numRaw; - if (num) { - // PR number rather than branch name - lookup info - const inputPR = await gh.pulls.get({ owner: "Microsoft", repo: "TypeScript", pull_number: num }); - // GH calculates the rebaseable-ness of a PR into its target, so we can just use that here - if (!inputPR.data.rebaseable) { - if (+(triggeredPR ?? 0) === num) { - await gh.issues.createComment({ - owner: "Microsoft", - repo: "TypeScript", - issue_number: num, - body: `This PR is configured as an experiment, and currently has rebase conflicts with main - please rebase onto main and fix the conflicts.`, - }); - } - throw new Error(`Rebase conflict detected in PR ${num} with main`); // A PR is currently in conflict, give up - } - runSequence([ - ["git", ["fetch", "origin", `pull/${num}/head:${num}`]], - ["git", ["checkout", `${num}`]], - ["git", ["rebase", "main"]], - ["git", ["push", "-f", "-u", "fork", `${num}`]], // Keep a rebased copy of this branch in our fork - ]); - } - else { - throw new Error(`Invalid PR number: ${numRaw}`); - } - } - - // Return to `master` and make a new `experimental` branch - runSequence([ - ["git", ["checkout", "main"]], - ["git", ["checkout", "-b", "experimental"]], - ]); - - // Merge each branch into `experimental` (which, if there is a conflict, we now know is from inter-experiment conflict) - for (const branchnum of prnums) { - const branch = "" + branchnum; - // Find the merge base - const mergeBase = runSequence([ - ["git", ["merge-base", branch, "experimental"]], - ]); - // Simulate the merge and abort if there are conflicts - const mergeTree = runSequence([ - ["git", ["merge-tree", mergeBase.trim(), branch, "experimental"]], - ]); - if (mergeTree.includes(`===${"="}===`)) { // 7 equals is the center of the merge conflict marker - throw new Error(`Merge conflict detected involving PR ${branch} with other experiment`); - } - // Merge (always producing a merge commit) - runSequence([ - ["git", ["merge", branch, "--no-ff"]], - ]); - } - // Every branch merged OK, force push the replacement `experimental` branch - runSequence([ - ["git", ["push", "-f", "-u", "fork", "experimental"]], - ]); -} - -main().catch(e => (console.error(e), process.exitCode = 2));