Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/shared/package.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"name": "@azure-tools/specs-shared",
"private": "true",
Expand All @@ -14,6 +14,7 @@
"./path": "./src/path.js",
"./readme": "./src/readme.js",
"./sdk-types": "./src/sdk-types.js",
"./set": "./src/set.js",
"./sleep": "./src/sleep.js",
"./sort": "./src/sort.js",
"./spec-model-error": "./src/spec-model-error.js",
Expand Down
13 changes: 13 additions & 0 deletions .github/shared/src/set.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @ts-check

/**
* @template T
* @param {Set<T>} a
* @param {Set<T>} b
* @returns {Set<T>}
*/
export function intersect(a, b) {
// Since set lookup is O(1), iterate over the smaller set for better perf: O(small) vs O(large)
const [small, large] = a.size < b.size ? [a, b] : [b, a];
return new Set([...small].filter((value) => large.has(value)));
}
42 changes: 42 additions & 0 deletions .github/shared/test/set.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// @ts-check

import { describe, expect, it } from "vitest";
import { intersect } from "../src/set";

describe("set", () => {
it.each([
[[], [], []],
[[1, 2, 3], [], []],
[
[1, 2, 3],
[2, 3, 4],
[2, 3],
],
[[1, 2, 3], [4, 5, 6], []],
[
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
],
[
["a", "b", "c"],
["b", "c", "d"],
["b", "c"],
],
])(
"intersect(%o, %o, %o)",
async (
/** @type {(string|number)[]} */ a,
/** @type {(string|number)[]} */ b,
/** @type {(string|number)[]} */ result,
) => {
const setA = new Set(a);
const setB = new Set(b);
const setResult = new Set(result);

// Check both orders, result should be same
expect(intersect(setA, setB)).toEqual(setResult);
expect(intersect(setB, setA)).toEqual(setResult);
},
);
});
55 changes: 55 additions & 0 deletions .github/workflows/src/summarize-checks/dump-trigger-metadata.js
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from summarize-checks.yaml mostly unchanged. I prefer scripts over a few lines in a separate JS file, for editing ergonomics if nothing else.

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// @ts-check

/**
* @param {import('@actions/github-script').AsyncFunctionArguments} AsyncFunctionArguments
* @returns {Promise<void>}
*/
export default async function dumpTriggerMetadata({ context, core }) {
core.info(`Event name: ${context.eventName}`);
core.info(`Action: ${context.payload.action}`);

if (
context.eventName === "workflow_run" &&
context.payload.action === "completed" &&
context.payload.workflow_run
) {
const payload = /** @type {import("@octokit/webhooks-types").WorkflowRunCompletedEvent} */ (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added type comment

context.payload
);

const run = payload.workflow_run;
core.info(`Triggering workflow: ${run.name}`);
core.info(`Triggering workflow ID: ${run.id}`);
core.info(`Triggering run ID: ${run.run_number}`);
core.info(`Triggering event: ${run.event}`);
core.info(`Triggering status: ${run.status}`);
core.info(`Triggering conclusion: ${run.conclusion}`);
core.info(`Triggering branch: ${run.head_branch}`);
core.info(`Triggering SHA: ${run.head_sha}`);
core.info(`Triggering actor: ${run.actor?.login || "unknown"}`);

// Create clickable URL to the triggering workflow run
const triggeringRunUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${run.id}`;
core.info(`🔗 Triggering workflow run URL: ${triggeringRunUrl}`);

// If there's a pull request associated, show that too
if (run.pull_requests && run.pull_requests.length > 0) {
run.pull_requests.forEach((pr) => {
const prUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${pr.number}`;
core.info(`🔗 Associated PR: ${prUrl}`);
});
}
} else if (context.eventName === "pull_request_target" && context.payload.pull_request) {
const payload = /** @type {import("@octokit/webhooks-types").PullRequestEvent} */ (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added type comment

context.payload
);

const pr = payload.pull_request;
core.info(`PR number: ${pr.number}`);
core.info(`PR title: ${pr.title}`);
core.info(`PR state: ${pr.state}`);
core.info(`PR head SHA: ${pr.head.sha}`);
core.info(`PR base branch: ${pr.base.ref}`);
core.info(`🔗 PR URL: ${pr.html_url}`);
}
}
19 changes: 5 additions & 14 deletions .github/workflows/src/summarize-checks/summarize-checks.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// @ts-check

/*
Expand All @@ -23,6 +23,7 @@
// import { commentOrUpdate } from "../comment.js";
import { execFile } from "../../../shared/src/exec.js";
import { CheckConclusion, PER_PAGE_MAX } from "../../../shared/src/github.js";
import { intersect } from "../../../shared/src/set.js";
import {
brChRevApproval,
getViolatedRequiredLabelsRules,
Expand Down Expand Up @@ -292,12 +293,13 @@
return;
}

// TODO: This is triggered by pull_request_target AND workflow_run. If workflow_run, targetBranch will be undefined.
// Is this OK? If not, we should be able to get the base ref by calling a GH API to fetch the PR metadata.
const targetBranch = context.payload.pull_request?.base?.ref;
core.info(`PR target branch: ${targetBranch}`);

await summarizeChecksImpl(
github,
context,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused param

core,
owner,
repo,
Expand Down Expand Up @@ -332,7 +334,6 @@

/**
* @param {import('@actions/github-script').AsyncFunctionArguments['github']} github
* @param {import('@actions/github').context } context
* @param {typeof import("@actions/core")} core
* @param {string} owner
* @param {string} repo
Expand All @@ -344,7 +345,6 @@
*/
export async function summarizeChecksImpl(
github,
context,
core,
owner,
repo,
Expand Down Expand Up @@ -507,8 +507,7 @@
issue_number: issue_number,
per_page: PER_PAGE_MAX,
});
/** @type {string[]} */
return labels.map((/** @type {{ name: string; }} */ label) => label.name);
return labels.map((label) => label.name);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to omit type comments if the type can be inferred

}

// #endregion
Expand All @@ -518,7 +517,7 @@
* @param {Set<string>} labelsToRemove
*/
function warnIfLabelSetsIntersect(labelsToAdd, labelsToRemove) {
const intersection = Array.from(labelsToAdd).filter((label) => labelsToRemove.has(label));
const intersection = [...intersect(labelsToAdd, labelsToRemove)];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our (unofficial) standard is [...foo] instead of Array.from(foo)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved intersect() to shared, it's generally useful

if (intersection.length > 0) {
console.warn(
"ASSERTION VIOLATION! The intersection of labelsToRemove and labelsToAdd is non-empty! " +
Expand Down Expand Up @@ -550,8 +549,6 @@
};

if (impactAssessment) {
console.log(`Downloaded impact assessment: ${JSON.stringify(impactAssessment)}`);

// will further update the label context if necessary
processImpactAssessment(labelContext, impactAssessment);
}
Expand Down Expand Up @@ -719,15 +716,9 @@
}

const filteredReqCheckRuns = reqCheckRuns.filter(
/**
* @param {CheckRunData} checkRun
*/
(checkRun) => !excludedCheckNames.includes(checkRun.name),
);
const filteredFyiCheckRuns = fyiCheckRuns.filter(
/**
* @param {CheckRunData} checkRun
*/
(checkRun) => !excludedCheckNames.includes(checkRun.name),
);

Expand Down
38 changes: 3 additions & 35 deletions .github/workflows/summarize-checks.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: "[TEST-IGNORE] Summarize Checks"

on:
Expand Down Expand Up @@ -55,41 +55,9 @@
uses: actions/github-script@v7
with:
script: |
console.log(`Event name: ${context.eventName}`);
console.log(`Action: ${context.payload.action}`);

if (context.eventName === 'workflow_run' && context.payload.workflow_run) {
const run = context.payload.workflow_run;
console.log(`Triggering workflow: ${run.name}`);
console.log(`Triggering workflow ID: ${run.id}`);
console.log(`Triggering run ID: ${run.run_number}`);
console.log(`Triggering event: ${run.event}`);
console.log(`Triggering status: ${run.status}`);
console.log(`Triggering conclusion: ${run.conclusion}`);
console.log(`Triggering branch: ${run.head_branch}`);
console.log(`Triggering SHA: ${run.head_sha}`);
console.log(`Triggering actor: ${run.actor?.login || 'unknown'}`);

// Create clickable URL to the triggering workflow run
const triggeringRunUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${run.id}`;
console.log(`🔗 Triggering workflow run URL: ${triggeringRunUrl}`);

// If there's a pull request associated, show that too
if (run.pull_requests && run.pull_requests.length > 0) {
run.pull_requests.forEach(pr => {
const prUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/pull/${pr.number}`;
console.log(`🔗 Associated PR: ${prUrl}`);
});
}
} else if (context.eventName === 'pull_request_target' && context.payload.pull_request) {
const pr = context.payload.pull_request;
console.log(`PR number: ${pr.number}`);
console.log(`PR title: ${pr.title}`);
console.log(`PR state: ${pr.state}`);
console.log(`PR head SHA: ${pr.head.sha}`);
console.log(`PR base branch: ${pr.base.ref}`);
console.log(`🔗 PR URL: ${pr.html_url}`);
}
const { default: dumpTriggerMetadata } =
await import('${{ github.workspace }}/.github/workflows/src/summarize-checks/dump-trigger-metadata.js');
return await dumpTriggerMetadata({ context, core });

- id: summarize-checks
name: Summarize Checks
Expand Down
Loading