Skip to content

Commit 6cbb9eb

Browse files
authored
Ensure blocked based on versioning review is honored (#36630)
* and add tests for the same
1 parent d70362c commit 6cbb9eb

File tree

4 files changed

+215
-3
lines changed

4 files changed

+215
-3
lines changed

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,13 +642,15 @@ async function processARMReviewWorkflowLabels(
642642

643643
const armSignedOffLabel = new Label("ARMSignedOff", labelContext.present);
644644

645+
const blockedOnVersioningPolicy = getBlockedOnVersioningPolicy(labelContext);
646+
645647
const blockedOnRpaas = getBlockedOnRpaas(
646648
ciNewRPNamespaceWithoutRpaaSLabelShouldBePresent,
647649
rpaasExceptionLabelShouldBePresent,
648650
ciRpaasRPNotInPrivateRepoLabelShouldBePresent,
649651
);
650652

651-
const blocked = blockedOnRpaas;
653+
const blocked = blockedOnRpaas || blockedOnVersioningPolicy;
652654

653655
// If given PR is in scope of ARM review and it is blocked for any reason,
654656
// the "NotReadyForARMReview" label should be present, to the exclusion
@@ -710,6 +712,23 @@ async function processARMReviewWorkflowLabels(
710712
return;
711713
}
712714

715+
/**
716+
* @param {LabelContext} labelContext
717+
* @returns {boolean}
718+
*/
719+
function getBlockedOnVersioningPolicy(labelContext) {
720+
const pendingVersioningReview =
721+
labelContext.present.has("VersioningReviewRequired") &&
722+
!anyApprovalLabelPresent("SameVersion", [...labelContext.present]);
723+
724+
const pendingBreakingChangeReview =
725+
labelContext.present.has("BreakingChangeReviewRequired") &&
726+
!anyApprovalLabelPresent("CrossVersion", [...labelContext.present]);
727+
728+
const blockedOnVersioningPolicy = pendingVersioningReview || pendingBreakingChangeReview;
729+
return blockedOnVersioningPolicy;
730+
}
731+
713732
/**
714733
* @param {boolean} ciNewRPNamespaceWithoutRpaaSLabelShouldBePresent
715734
* @param {boolean} rpaasExceptionLabelShouldBePresent

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,6 @@ export default async function summarizeChecks({ github, context, core }) {
295295
return;
296296
}
297297

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

.github/workflows/test/summarize-checks/labelling.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,67 @@ describe("update labels", () => {
157157
targetBranch: "main",
158158
},
159159
},
160+
{
161+
description:
162+
"Shouldn't remove NotReadyForARMReview label when not ready for ARM review due to being blocked on versioning or breaking change review.",
163+
existingLabels: [
164+
"ARMReview",
165+
"NotReadyForARMReview",
166+
"PipelineBotTrigger",
167+
"PublishToCustomers",
168+
"resource-manager",
169+
"RPaaS",
170+
"TypeSpec",
171+
"VersioningReviewRequired",
172+
],
173+
expectedLabelsToAdd: [],
174+
expectedLabelsToRemove: [],
175+
impactAssessment: {
176+
suppressionReviewRequired: false,
177+
rpaasChange: true,
178+
newRP: false,
179+
rpaasRPMissing: false,
180+
rpaasRpNotInPrivateRepo: false,
181+
resourceManagerRequired: true,
182+
dataPlaneRequired: false,
183+
rpaasExceptionRequired: false,
184+
typeSpecChanged: true,
185+
isNewApiVersion: false,
186+
isDraft: false,
187+
targetBranch: "RPSaaSMaster",
188+
},
189+
},
190+
{
191+
description:
192+
"Should remove NotReadyForARMReview and add WaitForARMFeedback when VersioningReviewRequired is approved.",
193+
existingLabels: [
194+
"ARMReview",
195+
"NotReadyForARMReview",
196+
"PipelineBotTrigger",
197+
"PublishToCustomers",
198+
"resource-manager",
199+
"RPaaS",
200+
"TypeSpec",
201+
"VersioningReviewRequired",
202+
"Versioning-Approved-Benign",
203+
],
204+
expectedLabelsToAdd: ["WaitForARMFeedback"],
205+
expectedLabelsToRemove: ["NotReadyForARMReview"],
206+
impactAssessment: {
207+
suppressionReviewRequired: false,
208+
rpaasChange: true,
209+
newRP: false,
210+
rpaasRPMissing: false,
211+
rpaasRpNotInPrivateRepo: false,
212+
resourceManagerRequired: true,
213+
dataPlaneRequired: false,
214+
rpaasExceptionRequired: false,
215+
typeSpecChanged: true,
216+
isNewApiVersion: false,
217+
isDraft: false,
218+
targetBranch: "RPSaaSMaster",
219+
},
220+
},
160221
];
161222
it.each(testCases)(
162223
"$description",

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

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,140 @@ describe("Summarize Checks Unit Tests", () => {
763763
expect(output).toEqual(expectedOutput);
764764
});
765765

766+
it("Should generate error summary for a PR scenario where NotReadyForARMReview is present", async () => {
767+
const repo = "azure-rest-api-specs-pr";
768+
const targetBranch = "RPSaaSMaster";
769+
const labelNames = [
770+
"ARMReview",
771+
"NotReadyForARMReview",
772+
"PipelineBotTrigger",
773+
"PublishToCustomers",
774+
"resource-manager",
775+
"RPaaS",
776+
"TypeSpec",
777+
"VersioningReviewRequired",
778+
];
779+
const fyiCheckRuns = [];
780+
const expectedComment =
781+
`<h2>Next Steps to Merge</h2>Next steps that must be taken to merge this PR: <br/><ul><li>❌ ` +
782+
`This PR is in purview of the ARM review (label: <code>ARMReview</code>). This PR must get <code>ARMSignedOff</code> label ` +
783+
`from an ARM reviewer.<br/>This PR is not ready for ARM review (label: <code>NotReadyForARMReview</code>). This PR will not ` +
784+
`be reviewed by ARM until relevant problems are fixed. Consult the rest of this <code>Next Steps to Merge</code> comment ` +
785+
`for details.<br/>Once the blocking problems are addressed, add to the PR a comment with contents <code>/azp run</code>. ` +
786+
`Automation will re-evaluate this PR and if everything looks good, it will add <code>WaitForARMFeedback</code> label which ` +
787+
`will put this PR on the ARM review queue.<br/>For details of the ARM review, see <a href="https://aka.ms/azsdk/pr-arm-review">` +
788+
`aka.ms/azsdk/pr-arm-review</a><br/></li><li>❌ This PR is <code>NotReadyForARMReview</code> because it has the <code>VersioningReviewRequired</code> ` +
789+
`label.<br/></li><li>❌ This PR has at least one change violating Azure versioning policy ` +
790+
`(label: <code>VersioningReviewRequired</code>).<br/>To unblock this PR, either a) introduce a new API version with these ` +
791+
`changes instead of modifying an existing API version, or b) follow the process at <a href="https://aka.ms/brch">aka.ms/brch</a>.</li>` +
792+
`<li>❌ The required check named <code>Swagger BreakingChange</code> has failed. To unblock this PR, follow the process at <a href="https://aka.ms/brch">` +
793+
`aka.ms/brch</a>.</li></ul><br /><br />Comment generated by <a href="http://github.com/a/fake/workflowrun/url">summarize-checks</a> workflow run.`;
794+
795+
const expectedOutput = [
796+
expectedComment,
797+
{
798+
name: "[TEST-IGNORE] Automated merging requirements met",
799+
result: "FAILURE",
800+
summary:
801+
"❌ This PR cannot be merged because some requirements are not met. See the details.",
802+
},
803+
];
804+
805+
const requiredCheckRuns = [
806+
{
807+
name: "license/cla",
808+
status: "QUEUED",
809+
conclusion: null,
810+
checkInfo: getCheckInfo("license/cla"),
811+
},
812+
{
813+
name: "Swagger PrettierCheck",
814+
status: "COMPLETED",
815+
conclusion: "SUCCESS",
816+
checkInfo: getCheckInfo("Swagger PrettierCheck"),
817+
},
818+
{
819+
name: "TypeSpec Validation",
820+
status: "COMPLETED",
821+
conclusion: "SUCCESS",
822+
checkInfo: getCheckInfo("TypeSpec Validation"),
823+
},
824+
{
825+
name: "Swagger SemanticValidation",
826+
status: "COMPLETED",
827+
conclusion: "SUCCESS",
828+
checkInfo: getCheckInfo("Swagger SemanticValidation"),
829+
},
830+
{
831+
name: "TypeSpec Requirement",
832+
status: "COMPLETED",
833+
conclusion: "SUCCESS",
834+
checkInfo: getCheckInfo("TypeSpec Requirement"),
835+
},
836+
{
837+
name: "Protected Files",
838+
status: "COMPLETED",
839+
conclusion: "SUCCESS",
840+
checkInfo: getCheckInfo("Protected Files"),
841+
},
842+
{
843+
name: "SpellCheck",
844+
status: "COMPLETED",
845+
conclusion: "SUCCESS",
846+
checkInfo: getCheckInfo("SpellCheck"),
847+
},
848+
{
849+
name: "Swagger ModelValidation",
850+
status: "COMPLETED",
851+
conclusion: "SUCCESS",
852+
checkInfo: getCheckInfo("Swagger ModelValidation"),
853+
},
854+
{
855+
name: "SDK Validation Status",
856+
status: "COMPLETED",
857+
conclusion: "SUCCESS",
858+
checkInfo: getCheckInfo("SDK Validation Status"),
859+
},
860+
{
861+
name: "Breaking Change(Cross-Version)",
862+
status: "COMPLETED",
863+
conclusion: "SUCCESS",
864+
checkInfo: getCheckInfo("Breaking Change(Cross-Version)"),
865+
},
866+
{
867+
name: "Swagger BreakingChange",
868+
status: "COMPLETED",
869+
conclusion: "FAILURE",
870+
checkInfo: getCheckInfo("Swagger BreakingChange"),
871+
},
872+
{
873+
name: "Swagger Avocado",
874+
status: "COMPLETED",
875+
conclusion: "SUCCESS",
876+
checkInfo: getCheckInfo("Swagger Avocado"),
877+
},
878+
{
879+
name: "Swagger LintDiff",
880+
status: "COMPLETED",
881+
conclusion: "SUCCESS",
882+
checkInfo: getCheckInfo("Swagger LintDiff"),
883+
},
884+
];
885+
886+
const output = await createNextStepsComment(
887+
mockCore,
888+
repo,
889+
labelNames,
890+
targetBranch,
891+
requiredCheckRuns,
892+
fyiCheckRuns,
893+
true, // assessmentCompleted
894+
WORKFLOW_URL,
895+
);
896+
897+
expect(output).toEqual(expectedOutput);
898+
});
899+
766900
it("Should generate error summary for a PR scenario with labeling issues", async () => {
767901
const repo = "azure-rest-api-specs";
768902
const targetBranch = "main";

0 commit comments

Comments
 (0)