mirror of
https://github.com/facebook/react-native.git
synced 2026-03-31 09:02:15 +00:00
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50848 This clarifies our reproducer guidelines. It's also currently pending on this other PR on the website: https://github.com/facebook/react-native-website/pull/4589 Changelog: [Internal] [Changed] - Reviewed By: cipolleschi Differential Revision: D73194317 fbshipit-source-id: 35a0e6b4def734c8cff5099ab426d024f9ff6c4d
106 lines
2.9 KiB
JavaScript
106 lines
2.9 KiB
JavaScript
/**
|
|
* 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
|
|
*/
|
|
|
|
const NEEDS_REPRO_LABEL = 'Needs: Repro';
|
|
const NEEDS_AUTHOR_FEEDBACK_LABEL = 'Needs: Author Feedback';
|
|
const SKIP_ISSUES_OLDER_THAN = '2023-07-01T00:00:00Z';
|
|
|
|
module.exports = async (github, context) => {
|
|
const issueData = {
|
|
issue_number: context.payload.issue.number,
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
};
|
|
|
|
const issue = await github.rest.issues.get(issueData);
|
|
const comments = await github.rest.issues.listComments(issueData);
|
|
const author = issue.data.user.login;
|
|
|
|
const issueDate = issue.data.created_at;
|
|
if (isDateBefore(issueDate, SKIP_ISSUES_OLDER_THAN)) {
|
|
return;
|
|
}
|
|
|
|
const maintainerChangedLabel = await hasMaintainerChangedLabel(
|
|
github,
|
|
issueData,
|
|
author,
|
|
);
|
|
|
|
if (maintainerChangedLabel) {
|
|
return;
|
|
}
|
|
|
|
const entities = [issue.data, ...comments.data];
|
|
|
|
// Look for Snack or a GH repo associated with the user that added an issue or comment
|
|
const hasValidReproducer = entities.some(entity => {
|
|
const hasPullRequestRepoLink = containsPattern(
|
|
entity.body,
|
|
`https?:\/\/github\.com\/facebook\/react-native\/pull\/\d+\/?`,
|
|
);
|
|
|
|
const hasExpoSnackLink = containsPattern(
|
|
entity.body,
|
|
`https?:\\/\\/snack\\.expo\\.dev\\/[^\\s)\\]]+`,
|
|
);
|
|
|
|
const hasGithubRepoLink = containsPattern(
|
|
entity.body,
|
|
`https?:\\/\\/github\\.com\\/(${entity.user.login})\\/[^/]+\\/?\\s?`,
|
|
);
|
|
return hasPullRequestRepoLink || hasExpoSnackLink || hasGithubRepoLink;
|
|
});
|
|
|
|
if (hasValidReproducer) {
|
|
try {
|
|
await github.rest.issues.removeLabel({
|
|
...issueData,
|
|
name: NEEDS_REPRO_LABEL,
|
|
});
|
|
} catch (error) {
|
|
if (!/Label does not exist/.test(error.message)) {
|
|
throw error;
|
|
}
|
|
}
|
|
} else {
|
|
await github.rest.issues.addLabels({
|
|
...issueData,
|
|
labels: [NEEDS_REPRO_LABEL, NEEDS_AUTHOR_FEEDBACK_LABEL],
|
|
});
|
|
}
|
|
};
|
|
|
|
function containsPattern(body, pattern) {
|
|
const regexp = new RegExp(pattern, 'gm');
|
|
return body.search(regexp) !== -1;
|
|
}
|
|
|
|
// Prevents the bot from responding when maintainer has changed the 'Needs: Repro' label
|
|
async function hasMaintainerChangedLabel(github, issueData, author) {
|
|
const timeline = await github.rest.issues.listEventsForTimeline(issueData);
|
|
|
|
const labeledEvents = timeline.data.filter(
|
|
event => event.event === 'labeled' || event.event === 'unlabeled',
|
|
);
|
|
const userEvents = labeledEvents.filter(event => event.actor.type !== 'Bot');
|
|
|
|
return userEvents.some(
|
|
event =>
|
|
event.actor.login !== author && event.label.name === NEEDS_REPRO_LABEL,
|
|
);
|
|
}
|
|
|
|
function isDateBefore(firstDate, secondDate) {
|
|
const date1 = new Date(firstDate);
|
|
const date2 = new Date(secondDate);
|
|
|
|
return date1.getTime() < date2.getTime();
|
|
}
|