Skip to content

Commit 9ae68b5

Browse files
Fix PR link regexes after the move to react/react-native (#59128)
Summary: Two workflows stopped working after the move to `react/react-native`, because their regexes only allow `github.com/facebook/react-native`: - **Merged pull requests no longer get the release FAQ comment.** Before the move, `react-native-bot` posted "This pull request was successfully merged by author in **sha**" with links to "When will my fix make it into a release?" and "How to file a pick request?". The last one is on #56769 (June 9). Pull requests merged on October 15 (#59122, #59050, #59016) only have the `meta-codesync` comment. - **Issues that link a pull request as the reproducer still get `Needs: Repro`.** Examples: #58970, #58495, #58445, #55708. The bot's message for `Needs: Repro` asks for a pull request that edits `RNTesterPlayground.js`, but the bot does not accept a link to one. ### Why 1. `.github/workflows/close-pr.yml` looks for `Pull Request resolved: https://github.com/facebook/react-native/pull/N` in the commit message. Commits now say `https://github.com/react/react-native/pull/N`, so `getClosedPrIfExists` returns `undefined` and the script stops before `createComment`. #57167 changed the `if:` line in this file to `react/react-native`, but not the regex. The regex is written with escaped slashes (`facebook\/react-native`). 2. `.github/workflow-scripts/checkForReproducer.js` builds the pull request pattern in a template literal with single backslashes. In a template literal, `\d` is just `d`, so the pattern is `https?://github.com/facebook/react-native/pull/d+/?`. It did not match real links even before the move (the line was added in #50848). The other two patterns in the same function use `\\` and work. In the whole repo, `facebook\/react-native` appears only in these two lines. ### Fix Both regexes now accept `facebook` and `react`. People still write links with `facebook`: the four issues above all do. In `checkForReproducer.js`, the pattern now uses `\\` like the other two patterns. `(?:...)` does not capture, so the group numbers in `close-pr.yml` do not change. The new test file is `checkForReproducer-links-test.js`, so it does not conflict with `checkForReproducer-test.js` from #58429. That PR fixes a different problem in the same script: the bot treats its own `Needs: Repro` label as a maintainer change. Because of that, an issue that already has the label keeps it after an edit, also with this PR. New issues with a pull request link do not get the label. ## Changelog: [INTERNAL] [FIXED] - Fix pull request link regexes in the close-pr and check-for-reproducer workflows after the move to react/react-native Pull Request resolved: #59128 Test Plan: Windows 11, Node 22.17.1, Yarn 1.22.22. New Jest test for `checkForReproducer` with 4 cases: a link to a pull request in `react/react-native`, the same link with `facebook/react-native`, a pull request in another repository, and no link. ``` yarn test .github/workflow-scripts ``` | Code | Result | | --- | --- | | `main` (e04aaf6) | 2 of the 4 new tests fail: both pull request links are not accepted | | this PR | 11 suites, 72 tests pass | Each part of the fix is needed: - `facebook|react` with single backslashes: both link tests fail. - Double backslashes with only `facebook`: the `react` link test fails. `close-pr.yml` runs an inline script, so it has no Jest test. I took `prClosingRegex` from the file and ran `getClosedPrIfExists` (copied from the file) on real commit messages from `main`: | Commit message | `main` | this PR | | --- | --- | --- | | #59016: `Pull Request resolved: https://github.com/react/react-native/pull/59016` | `undefined` | `59016` | | #56769: `Pull Request resolved: https://github.com/facebook/react-native/pull/56769` | `56769` | `56769` | | "Update React Native DevTools binaries", no pull request link | `undefined` | `undefined` | `npx prettier --check` passes for the 3 files. Not covered: - I did not run the workflows. They run on push to `main` and on issue events in this repository. - `yarn lint` does not check these files, because ESLint skips the `.github` folder. Reviewed By: cipolleschi Differential Revision: D125650549 Pulled By: cortinico fbshipit-source-id: c1d1b49381730f755d13e3c822ac1df33a4808b8
1 parent bf4fac3 commit 9ae68b5

3 files changed

Lines changed: 73 additions & 2 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
'use strict';
11+
12+
const checkForReproducer = require('../checkForReproducer');
13+
14+
const ISSUE_AUTHOR = 'issue-author';
15+
16+
function buildGithub(body) {
17+
return {
18+
rest: {
19+
issues: {
20+
get: jest.fn().mockResolvedValue({
21+
data: {
22+
user: {login: ISSUE_AUTHOR},
23+
created_at: '2026-10-01T00:00:00Z',
24+
body,
25+
},
26+
}),
27+
listComments: jest.fn().mockResolvedValue({data: []}),
28+
listEventsForTimeline: jest.fn().mockResolvedValue({data: []}),
29+
removeLabel: jest.fn().mockResolvedValue({}),
30+
addLabels: jest.fn().mockResolvedValue({}),
31+
},
32+
},
33+
};
34+
}
35+
36+
const context = {
37+
repo: {owner: 'react', repo: 'react-native'},
38+
payload: {issue: {number: 1}},
39+
};
40+
41+
describe('checkForReproducer reproducer links', () => {
42+
test.each([
43+
'https://github.com/react/react-native/pull/58972',
44+
'https://github.com/facebook/react-native/pull/58972',
45+
])('accepts a pull request link as a reproducer: %s', async link => {
46+
const github = buildGithub(`Reproducer: ${link}`);
47+
48+
await checkForReproducer(github, context);
49+
50+
expect(github.rest.issues.removeLabel).toHaveBeenCalledWith(
51+
expect.objectContaining({name: 'Needs: Repro'}),
52+
);
53+
expect(github.rest.issues.addLabels).not.toHaveBeenCalled();
54+
});
55+
56+
test.each([
57+
'Reproducer: https://github.com/someone-else/some-repo/pull/12',
58+
'It crashes when I scroll.',
59+
])('asks for a reproducer when there is none: %s', async body => {
60+
const github = buildGithub(body);
61+
62+
await checkForReproducer(github, context);
63+
64+
expect(github.rest.issues.addLabels).toHaveBeenCalledWith(
65+
expect.objectContaining({
66+
labels: ['Needs: Repro', 'Needs: Author Feedback'],
67+
}),
68+
);
69+
expect(github.rest.issues.removeLabel).not.toHaveBeenCalled();
70+
});
71+
});

‎.github/workflow-scripts/checkForReproducer.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module.exports = async (github, context) => {
4343
const hasValidReproducer = entities.some(entity => {
4444
const hasPullRequestRepoLink = containsPattern(
4545
entity.body,
46-
`https?:\/\/github\.com\/facebook\/react-native\/pull\/\d+\/?`,
46+
`https?:\\/\\/github\\.com\\/(?:facebook|react)\\/react-native\\/pull\\/\\d+\\/?`,
4747
);
4848

4949
const hasExpoSnackLink = containsPattern(

‎.github/workflows/close-pr.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
// Looking at the commit message, checks which PR number, if any, was closed by this commit
2727
const getClosedPrIfExists = (commit) => {
2828
if(!commit || !commit.message) return;
29-
const prClosingRegex = /Closes https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)|Pull Request resolved: https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)/;
29+
const prClosingRegex = /Closes https:\/\/github.com\/(?:facebook|react)\/react-native\/pull\/([0-9]+)|Pull Request resolved: https:\/\/github.com\/(?:facebook|react)\/react-native\/pull\/([0-9]+)/;
3030
const prClosingMatch = commit.message.match(prClosingRegex);
3131
if(!prClosingMatch || (!prClosingMatch[1] && ! prClosingMatch[2])) return;
3232
return prClosingMatch[1] ?? prClosingMatch[2];

0 commit comments

Comments
 (0)