From 5d91fee078c9a9966f833bd4395788ea6fcdcd95 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Thu, 15 Oct 2026 13:22:55 +0100 Subject: [PATCH] Accept stacked PR base branches in analyze-pr --- .../__tests__/checkBranchTarget-test.js | 47 +++++++++++++++++++ .github/workflow-scripts/checkBranchTarget.js | 6 ++- .github/workflows/analyze-pr.yml | 7 +++ 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 .github/workflow-scripts/__tests__/checkBranchTarget-test.js diff --git a/.github/workflow-scripts/__tests__/checkBranchTarget-test.js b/.github/workflow-scripts/__tests__/checkBranchTarget-test.js new file mode 100644 index 000000000000..3524fd39f6c1 --- /dev/null +++ b/.github/workflow-scripts/__tests__/checkBranchTarget-test.js @@ -0,0 +1,47 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +'use strict'; + +const checkBranchTarget = require('../checkBranchTarget'); + +describe('checkBranchTarget', () => { + test('passes for main', () => { + expect(checkBranchTarget('main')).toEqual({ + message: '', + status: 'PASS', + shouldAddPickLabel: false, + }); + }); + + test('passes for a stable branch and adds the pick label', () => { + expect(checkBranchTarget('0.76-stable')).toEqual({ + message: '', + status: 'PASS', + shouldAddPickLabel: true, + }); + }); + + test('passes for the head branch of another open PR', () => { + expect(checkBranchTarget('pr58950', true)).toEqual({ + message: '', + status: 'PASS', + shouldAddPickLabel: false, + }); + }); + + test('fails for any other branch', () => { + const {message, status, shouldAddPickLabel} = + checkBranchTarget('feature-branch'); + + expect(status).toBe('FAIL'); + expect(message).toContain('`feature-branch`'); + expect(shouldAddPickLabel).toBe(false); + }); +}); diff --git a/.github/workflow-scripts/checkBranchTarget.js b/.github/workflow-scripts/checkBranchTarget.js index 78e95a5e8142..68009e83819a 100644 --- a/.github/workflow-scripts/checkBranchTarget.js +++ b/.github/workflow-scripts/checkBranchTarget.js @@ -13,15 +13,17 @@ * Validates that the PR targets an appropriate base branch. * * @param {string} baseRef - The base branch ref (e.g., 'main', '0.76-stable') + * @param {boolean} [isStacked] - Whether the base branch is the head of another + * open PR, as in a stack of PRs * @returns {{message: string, status: 'PASS'|'FAIL', shouldAddPickLabel: boolean}} */ -function checkBranchTarget(baseRef) { +function checkBranchTarget(baseRef, isStacked = false) { const isMain = baseRef === 'main'; const isStable = baseRef.endsWith('-stable'); let message = ''; let status = 'PASS'; - if (!isMain && !isStable) { + if (!isMain && !isStable && !isStacked) { status = 'FAIL'; message = `> [!CAUTION] > **Invalid Base Branch** diff --git a/.github/workflows/analyze-pr.yml b/.github/workflows/analyze-pr.yml index 18c72a16e317..825fbd415980 100644 --- a/.github/workflows/analyze-pr.yml +++ b/.github/workflows/analyze-pr.yml @@ -44,8 +44,15 @@ jobs: repo: context.repo.repo, pull_number: context.issue.number, }); + const {data: basePullRequests} = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head: `${context.repo.owner}:${pullRequest.base.ref}`, + }); const {message, status, shouldAddPickLabel} = checkBranchTarget( pullRequest.base.ref, + basePullRequests.length > 0, ); if (shouldAddPickLabel) {