From 6df68fbd00cfaac6411a95e38fec4ffb35378581 Mon Sep 17 00:00:00 2001 From: mattd-tg <132939725+mattd-tg@users.noreply.github.com> Date: Fri, 12 Jul 2024 12:01:10 -0400 Subject: [PATCH 1/2] feat: add `skipSingleStacks` optionp Adds an option to skip posting the PR stack in the description if the PR is not actually part of a stack, but just a single PR to trunk/perennial --- .editorconfig-checker | 2 +- action.yml | 3 +++ dist/index.js | 48 ++++++++++++++++++++++++++++++------------- src/index.ts | 1 + src/inputs.ts | 8 ++++++++ src/main.ts | 22 +++++++++++++++++++- src/types.ts | 1 + 7 files changed, 69 insertions(+), 16 deletions(-) diff --git a/.editorconfig-checker b/.editorconfig-checker index 4367774..98ee990 100644 --- a/.editorconfig-checker +++ b/.editorconfig-checker @@ -1,5 +1,5 @@ { - "Version": "v3.0.1", + "Version": "v3.0.3", "Verbose": false, "Format": "", "Debug": false, diff --git a/action.yml b/action.yml index a2ca590..ad66c71 100644 --- a/action.yml +++ b/action.yml @@ -18,6 +18,9 @@ inputs: perennial-regex: required: false default: '' + skip-single-stacks: + required: false + default: false runs: using: 'node20' diff --git a/dist/index.js b/dist/index.js index ffa19db..311f3bf 100644 --- a/dist/index.js +++ b/dist/index.js @@ -18741,7 +18741,7 @@ var require_core = __commonJS({ return inputs2.map((input) => input.trim()); } exports2.getMultilineInput = getMultilineInput2; - function getBooleanInput(name, options) { + function getBooleanInput2(name, options) { const trueValue = ["true", "True", "TRUE"]; const falseValue = ["false", "False", "FALSE"]; const val = getInput2(name, options); @@ -18752,7 +18752,7 @@ var require_core = __commonJS({ throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name} Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); } - exports2.getBooleanInput = getBooleanInput; + exports2.getBooleanInput = getBooleanInput2; function setOutput(name, value) { const filePath = process.env["GITHUB_OUTPUT"] || ""; if (filePath) { @@ -42837,7 +42837,8 @@ async function main({ mainBranch, perennialBranches, currentPullRequest, - pullRequests + pullRequests, + skipSingleStacks }) { const repoGraph = new import_graphology.MultiDirectedGraph(); repoGraph.addNode(mainBranch, { @@ -42860,13 +42861,13 @@ async function main({ repoGraph.addDirectedEdge(pullRequest.baseRefName, pullRequest.headRefName); }); const getStackGraph = (pullRequest) => { - const stackGraph = repoGraph.copy(); - stackGraph.setNodeAttribute(pullRequest.headRefName, "isCurrent", true); + const stackGraph2 = repoGraph.copy(); + stackGraph2.setNodeAttribute(pullRequest.headRefName, "isCurrent", true); (0, import_graphology_traversal.bfsFromNode)( - stackGraph, + stackGraph2, pullRequest.headRefName, (ref, attributes) => { - stackGraph.setNodeAttribute(ref, "shouldPrint", true); + stackGraph2.setNodeAttribute(ref, "shouldPrint", true); return attributes.type === "perennial"; }, { @@ -42874,14 +42875,14 @@ async function main({ } ); (0, import_graphology_traversal.dfsFromNode)( - stackGraph, + stackGraph2, pullRequest.headRefName, (ref) => { - stackGraph.setNodeAttribute(ref, "shouldPrint", true); + stackGraph2.setNodeAttribute(ref, "shouldPrint", true); }, { mode: "outbound" } ); - return stackGraph; + return stackGraph2; }; const getOutput = (graph) => { const lines = []; @@ -42910,14 +42911,25 @@ async function main({ return lines.join("\n"); }; const jobs = []; - getStackGraph(currentPullRequest).forEachNode((_, stackNode) => { + const stackGraph = getStackGraph(currentPullRequest); + const shouldSkip = () => { + const neighbors = stackGraph.neighbors(currentPullRequest.headRefName); + const allPerennialBranches = stackGraph.filterNodes( + (_, nodeAttributes) => nodeAttributes.type === "perennial" + ); + return skipSingleStacks && neighbors.length === 1 && allPerennialBranches.includes(neighbors.at(0) || ""); + }; + if (shouldSkip()) { + return; + } + stackGraph.forEachNode((_, stackNode) => { if (stackNode.type !== "pull-request" || !stackNode.shouldPrint) { return; } jobs.push(async () => { core.info(`Updating stack details for PR #${stackNode.number}`); - const stackGraph = getStackGraph(stackNode); - const output = getOutput(stackGraph); + const stackGraph2 = getStackGraph(stackNode); + const output = getOutput(stackGraph2); let description = stackNode.body ?? ""; description = updateDescription({ description, @@ -46824,6 +46836,13 @@ var inputs = { getToken() { return core2.getInput("github-token", { required: true, trimWhitespace: true }); }, + getSkipSingleStacks() { + core2.startGroup("Inputs: Skip single stacks"); + const input = core2.getBooleanInput("skip-single-stacks", { required: false }); + core2.info(input.toString()); + core2.endGroup(); + return input; + }, async getMainBranch(octokit, config2, context3) { const { data: { default_branch: defaultBranch } @@ -46975,7 +46994,8 @@ async function run() { currentPullRequest: inputs.getCurrentPullRequest(github2.context), pullRequests, mainBranch, - perennialBranches + perennialBranches, + skipSingleStacks: inputs.getSkipSingleStacks() }; void main(context3); } catch (error) { diff --git a/src/index.ts b/src/index.ts index 5e72289..d9d62aa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,6 +31,7 @@ async function run() { pullRequests, mainBranch, perennialBranches, + skipSingleStacks: inputs.getSkipSingleStacks(), } void main(context) diff --git a/src/inputs.ts b/src/inputs.ts index 5fb6f77..4720d44 100644 --- a/src/inputs.ts +++ b/src/inputs.ts @@ -9,6 +9,14 @@ export const inputs = { return core.getInput('github-token', { required: true, trimWhitespace: true }) }, + getSkipSingleStacks() { + core.startGroup('Inputs: Skip single stacks') + const input = core.getBooleanInput('skip-single-stacks', { required: false }) + core.info(input.toString()) + core.endGroup() + return input + }, + async getMainBranch( octokit: Octokit, config: Config | undefined, diff --git a/src/main.ts b/src/main.ts index 391dd00..c6ed500 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ export async function main({ perennialBranches, currentPullRequest, pullRequests, + skipSingleStacks, }: Context) { const repoGraph = new MultiDirectedGraph() @@ -101,7 +102,26 @@ export async function main({ const jobs: Array<() => Promise> = [] - getStackGraph(currentPullRequest).forEachNode((_, stackNode) => { + const stackGraph = getStackGraph(currentPullRequest) + + const shouldSkip = () => { + const neighbors = stackGraph.neighbors(currentPullRequest.headRefName) + const allPerennialBranches = stackGraph.filterNodes( + (_, nodeAttributes) => nodeAttributes.type === 'perennial' + ) + + return ( + skipSingleStacks && + neighbors.length === 1 && + allPerennialBranches.includes(neighbors.at(0) || '') + ) + } + + if (shouldSkip()) { + return + } + + stackGraph.forEachNode((_, stackNode) => { if (stackNode.type !== 'pull-request' || !stackNode.shouldPrint) { return } diff --git a/src/types.ts b/src/types.ts index 6678b37..59385d3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,6 +18,7 @@ export type Context = { currentPullRequest: PullRequest pullRequests: PullRequest[] perennialBranches: string[] + skipSingleStacks: boolean } export type StackNode = From c519e1d75a0b2baae216d734dc57230ac61c4e39 Mon Sep 17 00:00:00 2001 From: mattd-tg Date: Sun, 18 Aug 2024 12:05:52 -0400 Subject: [PATCH 2/2] stack1 --- .github/workflows/git-town.yml | 2 ++ stack1 | 0 2 files changed, 2 insertions(+) create mode 100644 stack1 diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 85105ad..bee28e1 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -22,3 +22,5 @@ jobs: - uses: actions/checkout@v4 - name: Git Town uses: ./ + with: + skip-single-stacks: true diff --git a/stack1 b/stack1 new file mode 100644 index 0000000..e69de29