Skip to content

Commit 24bd27a

Browse files
authored
summarize-checks defaults [TEST-IGNORE] Automated merge requirements met to in-progress` (#36366)
* more unit tests, adding tests that can be easily used for the labelling decisions and impact assessment logic
1 parent d19d4d8 commit 24bd27a

File tree

3 files changed

+861
-317
lines changed

3 files changed

+861
-317
lines changed

.github/workflows/src/summarize-checks/summarize-checks.js

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ const FYI_CHECK_NAMES = [
138138
"Swagger BreakingChange",
139139
"Swagger PrettierCheck",
140140
];
141-
const AUTOMATED_CHECK_NAME = "Automated merging requirements met";
141+
const AUTOMATED_CHECK_NAME = "[TEST-IGNORE] Automated merging requirements met";
142142
const NEXT_STEPS_COMMENT_ID = "NextStepsToMerge";
143143

144144
/** @type {CheckMetadata[]} */
@@ -370,15 +370,15 @@ export async function summarizeChecksImpl(
370370

371371
outputRunDetails(core, requiredCheckRuns, fyiCheckRuns);
372372

373-
if (!impactAssessment) {
373+
if (impactAssessment) {
374+
core.info(`ImpactAssessment: ${JSON.stringify(impactAssessment)}`);
375+
} else {
374376
core.info(
375-
"Bailing out early without taking any further action, PR impact assessment is not yet complete.",
377+
`No impact assessment found for ${owner}/${repo}#${issue_number}. ` +
378+
`No labels will be added or removed in this run, and only "pending" status check will be set.`,
376379
);
377-
return;
378380
}
379381

380-
core.info(`ImpactAssessment: ${JSON.stringify(impactAssessment)}`);
381-
382382
let labelContext = await updateLabels(labelNames, impactAssessment);
383383

384384
core.info(
@@ -425,6 +425,7 @@ export async function summarizeChecksImpl(
425425
targetBranch,
426426
requiredCheckRuns,
427427
fyiCheckRuns,
428+
impactAssessment !== undefined,
428429
);
429430

430431
core.info(
@@ -441,15 +442,7 @@ export async function summarizeChecksImpl(
441442
// )
442443

443444
// finally, update the "Automated merging requirements met" commit status
444-
await updateCommitStatus(
445-
github,
446-
core,
447-
owner,
448-
repo,
449-
head_sha,
450-
"[TEST-IGNORE] Automated merging requirements met",
451-
automatedChecksMet,
452-
);
445+
await updateCommitStatus(github, core, owner, repo, head_sha, automatedChecksMet);
453446

454447
core.info(
455448
`Summarize checks has identified that status of "[TEST-IGNORE] Automated merging requirements met" commit status should be updated to: ${JSON.stringify(automatedChecksMet)}.`,
@@ -463,19 +456,10 @@ export async function summarizeChecksImpl(
463456
* @param {string} owner
464457
* @param {string} repo
465458
* @param {string} head_sha
466-
* @param {string} statusContext
467459
* @param {CheckRunResult} checkResult
468460
* @returns {Promise<void>}
469461
*/
470-
export async function updateCommitStatus(
471-
github,
472-
core,
473-
owner,
474-
repo,
475-
head_sha,
476-
statusContext,
477-
checkResult,
478-
) {
462+
export async function updateCommitStatus(github, core, owner, repo, head_sha, checkResult) {
479463
// Map CheckRunResult status to commit status state
480464
/** @type {"pending" | "success" | "failure" | "error"} */
481465
let state;
@@ -497,12 +481,12 @@ export async function updateCommitStatus(
497481
checkResult.summary.length > 140
498482
? checkResult.summary.substring(0, 137) + "..."
499483
: checkResult.summary,
500-
context: statusContext,
484+
context: checkResult.name,
501485
// target_url: undefined, // Optional: add a URL if you want to link to more details
502486
});
503487

504488
core.info(
505-
`Created commit status for ${statusContext} with state: ${state} and description: ${checkResult.summary}`,
489+
`Created commit status for ${checkResult.name} with state: ${state} and description: ${checkResult.summary}`,
506490
);
507491
}
508492

@@ -775,7 +759,7 @@ export function checkRunIsSuccessful(checkRun) {
775759
* @param {any} response - GraphQL response data
776760
* @returns {[CheckRunData[], CheckRunData[], number | undefined]}
777761
*/
778-
function extractRunsFromGraphQLResponse(response) {
762+
export function extractRunsFromGraphQLResponse(response) {
779763
/** @type {CheckRunData[]} */
780764
const reqCheckRuns = [];
781765
/** @type {CheckRunData[]} */
@@ -792,22 +776,12 @@ function extractRunsFromGraphQLResponse(response) {
792776
(checkSuiteNode) => {
793777
if (checkSuiteNode.checkRuns?.nodes) {
794778
checkSuiteNode.checkRuns.nodes.forEach((checkRunNode) => {
795-
// We have some specific guidance for some of the required checks.
796-
const checkInfo =
797-
CHECK_METADATA.find((metadata) => metadata.name === checkRunNode.name) ||
798-
/** @type {CheckMetadata} */ ({
799-
precedence: 1000,
800-
name: checkRunNode.name,
801-
suppressionLabels: [],
802-
troubleshootingGuide: defaultTsg,
803-
});
804-
805779
if (checkRunNode.isRequired) {
806780
reqCheckRuns.push({
807781
name: checkRunNode.name,
808782
status: checkRunNode.status,
809783
conclusion: checkRunNode.conclusion,
810-
checkInfo: checkInfo,
784+
checkInfo: getCheckInfo(checkRunNode.name),
811785
});
812786
}
813787
// Note the "else" here. It means that:
@@ -820,7 +794,7 @@ function extractRunsFromGraphQLResponse(response) {
820794
name: checkRunNode.name,
821795
status: checkRunNode.status,
822796
conclusion: checkRunNode.conclusion,
823-
checkInfo: checkInfo,
797+
checkInfo: getCheckInfo(checkRunNode.name),
824798
});
825799
}
826800
});
@@ -851,6 +825,23 @@ function extractRunsFromGraphQLResponse(response) {
851825
}
852826
return [reqCheckRuns, fyiCheckRuns, impactAssessmentWorkflowRun];
853827
}
828+
/**
829+
* Get metadata for a specific check from our index.
830+
* @param {string} checkName
831+
* @returns {CheckMetadata}
832+
*/
833+
export function getCheckInfo(checkName) {
834+
return (
835+
CHECK_METADATA.find((metadata) => metadata.name === checkName) ||
836+
/** @type {CheckMetadata} */ ({
837+
precedence: 1000,
838+
name: checkName,
839+
suppressionLabels: [],
840+
troubleshootingGuide: defaultTsg,
841+
})
842+
);
843+
}
844+
854845
// #endregion
855846
// #region next steps
856847
/**
@@ -861,6 +852,7 @@ function extractRunsFromGraphQLResponse(response) {
861852
* @param {string} targetBranch
862853
* @param {CheckRunData[]} requiredRuns
863854
* @param {CheckRunData[]} fyiRuns
855+
* @param {boolean} assessmentCompleted
864856
* @returns {Promise<[string, CheckRunResult]>}
865857
*/
866858
export async function createNextStepsComment(
@@ -870,13 +862,15 @@ export async function createNextStepsComment(
870862
targetBranch,
871863
requiredRuns,
872864
fyiRuns,
865+
assessmentCompleted,
873866
) {
874867
// select just the metadata that we need about the runs.
875868
const requiredCheckInfos = requiredRuns
876869
.filter((run) => checkRunIsSuccessful(run) === false)
877870
.map((run) => run.checkInfo);
878871

879-
// determine if required runs have any successful runs.
872+
// determine if required runs have any in-progress or queued runs
873+
// if there are any, we consider the requirements not met.
880874
const requiredCheckInfosPresent = requiredRuns.some((run) => {
881875
const status = run.status.toLowerCase();
882876
return status !== "queued" && status !== "in_progress";
@@ -892,6 +886,7 @@ export async function createNextStepsComment(
892886
requiredCheckInfosPresent,
893887
requiredCheckInfos,
894888
fyiCheckInfos,
889+
assessmentCompleted,
895890
);
896891

897892
return [commentBody, automatedChecksMet];
@@ -904,6 +899,7 @@ export async function createNextStepsComment(
904899
* @param {boolean} requiredCheckInfosPresent
905900
* @param {CheckMetadata[]} failingReqChecksInfo
906901
* @param {CheckMetadata[]} failingFyiChecksInfo
902+
* @param {boolean} assessmentCompleted
907903
* @returns {Promise<[string, CheckRunResult]>}
908904
*/
909905
async function buildNextStepsToMergeCommentBody(
@@ -913,6 +909,7 @@ async function buildNextStepsToMergeCommentBody(
913909
requiredCheckInfosPresent,
914910
failingReqChecksInfo,
915911
failingFyiChecksInfo,
912+
assessmentCompleted,
916913
) {
917914
// Build the comment header
918915
const commentTitle = `<h2>Next Steps to Merge</h2>`;
@@ -922,10 +919,13 @@ async function buildNextStepsToMergeCommentBody(
922919
// we are "blocked" if we have any violated labelling rules OR if we have any failing required checks
923920
const anyBlockerPresent = failingReqChecksInfo.length > 0 || violatedReqLabelsRules.length > 0;
924921
const anyFyiPresent = failingFyiChecksInfo.length > 0;
925-
// we consider requirements met if there are no blockers (which INCLUDES violated labelling rules) AND
926-
// that we have at least one required check that is not in progress or queued.
927-
// This might be too aggressive, but it's a good start.
928-
const requirementsMet = !anyBlockerPresent && requiredCheckInfosPresent;
922+
// we consider requirements met if there are:
923+
// - no blockers (which includes violated labelling rules in its definition) (anyBlockerPresent)
924+
// - that none of the required checks are in_progress or queued (requiredCheckInfosPresent)
925+
// - and that the assessment is completed. If it is not, we assume we are still evaluating the requirements. Not having
926+
// the assessment completed is a blocker, as we may end up having violated labelling rules that would be detected only after
927+
// it is completed.
928+
const requirementsMet = !anyBlockerPresent && requiredCheckInfosPresent && assessmentCompleted;
929929

930930
// Compose the body based on the current state
931931
const [commentBody, automatedChecksMet] = getCommentBody(
@@ -958,7 +958,6 @@ function getCommentBody(
958958
failingFyiChecksInfo,
959959
violatedRequiredLabelsRules,
960960
) {
961-
let title = "Automated merging requirements are being evaluated";
962961
/** @type {"pending" | keyof typeof CheckConclusion} */
963962
let status = "pending";
964963
let summaryData = "The requirements for merging this PR are still being evaluated. Please wait.";
@@ -971,7 +970,6 @@ function getCommentBody(
971970
bodyProper += getBlockerPresentBody(failingReqChecksInfo, violatedRequiredLabelsRules);
972971
summaryData =
973972
"❌ This PR cannot be merged because some requirements are not met. See the details.";
974-
title = "Some automated merging requirements are not met";
975973
status = "FAILURE";
976974
}
977975

@@ -983,8 +981,6 @@ function getCommentBody(
983981
bodyProper += getFyiPresentBody(failingFyiChecksInfo);
984982
if (!anyBlockerPresent) {
985983
bodyProper += `If you still want to proceed merging this PR without addressing the above failures, ${diagramTsg(4, false)}.`;
986-
title =
987-
"All automated merging requirements are met, though there are some non-required failures.";
988984
summaryData =
989985
`⚠️ Some important automated merging requirements have failed. As of today you can still merge this PR, ` +
990986
`but soon these requirements will be blocking.` +
@@ -1003,7 +999,6 @@ function getCommentBody(
1003999
`<br/>To merge this PR, refer to ` +
10041000
`<a href="https://aka.ms/azsdk/specreview/merge">aka.ms/azsdk/specreview/merge</a>.` +
10051001
"<br/>For help, consult comments on this PR and see [aka.ms/azsdk/pr-getting-help](https://aka.ms/azsdk/pr-getting-help).";
1006-
title = "Automated merging requirements are met";
10071002
status = "SUCCESS";
10081003
} else {
10091004
bodyProper =
@@ -1013,7 +1008,7 @@ function getCommentBody(
10131008

10141009
/** @type {CheckRunResult} */
10151010
const automatedChecksMet = {
1016-
name: title,
1011+
name: AUTOMATED_CHECK_NAME,
10171012
summary: summaryData,
10181013
result: status,
10191014
};

0 commit comments

Comments
 (0)