Skip to content

Commit

Permalink
Add check-for-reproducer action (facebook#38338)
Browse files Browse the repository at this point in the history
Summary:
This PR adds a "check-for-reproducer" GitHub action proposed in facebook#35591.
This GitHub action automatically labels an issue with when no link to GitHub repository under the authors name or link to Snack is present either in the issue body or in the comments.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[INTERNAL] [ADDED] - Add check-for-reproducer GitHub action

Pull Request resolved: facebook#38338

Test Plan:
This action was tested on a private repro mimicking on how GitHub actions are set-up in `facebook/react-native` repository. If you'd want to play around with the action on this private repo just ask for access - provided you're a maintainer.

### Regarding issue body

1. Labels "Needs: Repro" when no link to Expo Snack or a Github repo under the author's name is present in the issue body:

![image](https://github.com/facebook/react-native/assets/39658211/b8e6d4aa-bc9a-471d-99b8-3b551f2c46c6)

2. Removes the "Needs: Repro" label and deletes the Missing Repro comment when the author edits the issue and provides a link to GitHub repo under their name

![image](https://github.com/facebook/react-native/assets/39658211/2dc13fae-b6ca-432f-88a2-f5c340f28c86)

3. Removes the "Needs: Repro" label and deletes the Missing Repro comment when the author edits the issue and provides a valid link to Expo Snack

![image](https://github.com/facebook/react-native/assets/39658211/e82e744e-b2fb-4979-84de-08f95686feb3)

### Regarding comments

3. Removes the "Needs: Repro" label and deletes the Missing Repro comment when there's a comment with a link to reproduction under issue author's name

![image](https://github.com/facebook/react-native/assets/39658211/eefb5978-29d3-4486-8bd7-878fb2c07c05)

4. Removes the "Needs: Repro" label and deletes the Missing Repro comment when there's a comment with a link to Expo Snack

![image](https://github.com/facebook/react-native/assets/39658211/5769ff77-0d9f-4dac-bb36-6d257e6c2a35)

### Regarding false-positives

5. Adds a "Needs: Repro" label when a link to reprository isn't under the issue author's name

![image](https://github.com/facebook/react-native/assets/39658211/01c93ea3-88b9-4920-a8f8-bcd123d214de)

6. Adds a "Needs: Repro" label when a link to Expo Snack's homepage was sent

![image](https://github.com/facebook/react-native/assets/39658211/568c9824-67af-402a-b102-c1c355651d21)

7. Adds a "Needs: Repro" label when a random link was sent

![image](https://github.com/facebook/react-native/assets/39658211/23bb58b3-cc07-4284-a562-6651f2077a3c)

Reviewed By: NickGerleman

Differential Revision: D47511745

Pulled By: cortinico

fbshipit-source-id: 2c0e5a989f52b4e50992a3954283f122b14153e0
  • Loading branch information
kacperkapusciak authored and juniorklawa committed Jul 20, 2023
1 parent 64787e2 commit c52ea81
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflow-scripts/actOnLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ module.exports = async (github, context, labelWithContext) => {
await addComment(
`| :warning: | Missing Reproducible Example |\n` +
`| --- | --- |\n` +
`| :information_source: | It looks like your issue is missing a reproducible example. Please provide either: <br /><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)</li></ul> |`,
`| :information_source: | We could not detect a reproducible example in your issue report. Please provide either: <br /><ul><li>If your bug is UI related: a [Snack](https://snack.expo.dev)</li><li> If your bug is build/update related: use our [Reproducer Template](https://github.com/react-native-community/reproducer-react-native/generate)</li></ul> |`,
);
await requestAuthorFeedback();
return;
Expand Down
79 changes: 79 additions & 0 deletions .github/workflow-scripts/checkForReproducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* 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_REPRO_MESSAGE = '| Missing Reproducible Example |';

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 botComment = comments.data.find(comment =>
comment.body.includes(NEEDS_REPRO_MESSAGE),
);

let commentBodies = comments.data.map(comment => comment.body);
if (botComment) {
commentBodies = commentBodies.filter(body => body !== botComment.body);
}

const issueAndComments = [issue.data.body, ...commentBodies];
const issueAndCommentsUniq = [...new Set(issueAndComments)];

const user = issue.data.user.login;

const hasValidReproducer = issueAndCommentsUniq.some(body => {
const hasExpoSnackLink = containsPattern(
body,
`https?:\\/\\/snack\\.expo\\.dev\\/[^\\s)\\]]+`,
);
const hasGithubRepoLink = containsPattern(
body,
`https?:\\/\\/github\\.com\\/(${user})\\/[^/]+\\/?\\s?`,
);

return 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;
}
}

if (!botComment) return;

await github.rest.issues.deleteComment({
...issueData,
comment_id: botComment.id,
});
} else {
await github.rest.issues.addLabels({
...issueData,
labels: [NEEDS_REPRO_LABEL],
});
}
};

function containsPattern(body, pattern) {
const regexp = new RegExp(pattern, 'gm');
return body.search(regexp) !== -1;
}
21 changes: 21 additions & 0 deletions .github/workflows/check-for-reproducer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Check for reproducer
# This workflow is triggered when issue is created or edited.
# Also, when a comment is added, edited or deleted.
on:
issues:
types: [opened, edited]
issue_comment:
types: [created, edited, deleted]

jobs:
check-for-reproducer:
runs-on: ubuntu-latest
if: github.repository == 'facebook/react-native'
steps:
- uses: actions/checkout@v3
- uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const checkForReproducer = require('./.github/workflow-scripts/checkForReproducer.js')
await checkForReproducer(github, context)

0 comments on commit c52ea81

Please sign in to comment.