diff --git a/.github/workflows/merged-prs.yml b/.github/workflows/merged-prs.yml new file mode 100644 index 0000000000000..37fc6c67f000b --- /dev/null +++ b/.github/workflows/merged-prs.yml @@ -0,0 +1,41 @@ +name: "Add buildbot information to first PRs from new contributors" + +permissions: + contents: read + +on: + # It's safe to use pull_request_target here, because we aren't checking out + # code from the pull request branch. + # See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ + pull_request_target: + types: + - closed + +jobs: + buildbot_comment: + runs-on: ubuntu-latest + permissions: + pull-requests: write + if: >- + (github.repository == 'llvm/llvm-project') && + (github.event.pull_request.merged == true) + steps: + - name: Checkout Automation Script + uses: actions/checkout@v4 + with: + sparse-checkout: llvm/utils/git/ + ref: main + + - name: Setup Automation Script + working-directory: ./llvm/utils/git/ + run: | + pip install -r requirements.txt + + - name: Add Buildbot information comment + working-directory: ./llvm/utils/git/ + run: | + python3 ./github-automation.py \ + --token '${{ secrets.GITHUB_TOKEN }}' \ + pr-buildbot-information \ + --issue-number "${{ github.event.pull_request.number }}" \ + --author "${{ github.event.pull_request.user.login }}" diff --git a/llvm/utils/git/github-automation.py b/llvm/utils/git/github-automation.py index 897705166c640..f9d48ae5fb477 100755 --- a/llvm/utils/git/github-automation.py +++ b/llvm/utils/git/github-automation.py @@ -208,6 +208,8 @@ def _get_curent_team(self) -> Optional[github.Team.Team]: class PRGreeter: + COMMENT_TAG = "\n" + def __init__(self, token: str, repo: str, pr_number: int): repo = github.Github(token).get_repo(repo) self.pr = repo.get_issue(pr_number).as_pull_request() @@ -217,7 +219,9 @@ def run(self) -> bool: # by a user new to LLVM and/or GitHub itself. # This text is using Markdown formatting. + comment = f"""\ +{PRGreeter.COMMENT_TAG} Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be @@ -240,6 +244,61 @@ def run(self) -> bool: return True +class PRBuildbotInformation: + COMMENT_TAG = "\n" + + def __init__(self, token: str, repo: str, pr_number: int, author: str): + repo = github.Github(token).get_repo(repo) + self.pr = repo.get_issue(pr_number).as_pull_request() + self.author = author + + def should_comment(self) -> bool: + # As soon as a new contributor has a PR merged, they are no longer a new contributor. + # We can tell that they were a new contributor previously because we would have + # added a new contributor greeting comment when they opened the PR. + found_greeting = False + for comment in self.pr.as_issue().get_comments(): + if PRGreeter.COMMENT_TAG in comment.body: + found_greeting = True + elif PRBuildbotInformation.COMMENT_TAG in comment.body: + # When an issue is reopened, then closed as merged again, we should not + # add a second comment. This event will be rare in practice as it seems + # like it's only possible when the main branch is still at the exact + # revision that the PR was merged on to, beyond that it's closed forever. + return False + return found_greeting + + def run(self) -> bool: + if not self.should_comment(): + return + + # This text is using Markdown formatting. Some of the lines are longer + # than others so that the final text is some reasonable looking paragraphs + # after the long URLs are rendered. + comment = f"""\ +{PRBuildbotInformation.COMMENT_TAG} +@{self.author} Congratulations on having your first Pull Request (PR) merged into the LLVM Project! + +Your changes will be combined with recent changes from other authors, then tested +by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, +you may recieve a report in an email or a comment on this PR. + +Please check whether problems have been caused by your change specifically, as +the builds can include changes from many authors. It is not uncommon for your +change to be included in a build that fails due to someone else's changes, or +infrastructure issues. + +How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr). + +If your change does cause a problem, it may be reverted, or you can revert it yourself. +This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again. + +If you don't get any reports, no action is required from you. Your changes are working as expected, well done! +""" + self.pr.as_issue().create_comment(comment) + return True + + def setup_llvmbot_git(git_dir="."): """ Configure the git repo in `git_dir` with the llvmbot account so @@ -585,6 +644,10 @@ def execute_command(self) -> bool: pr_greeter_parser = subparsers.add_parser("pr-greeter") pr_greeter_parser.add_argument("--issue-number", type=int, required=True) +pr_buildbot_information_parser = subparsers.add_parser("pr-buildbot-information") +pr_buildbot_information_parser.add_argument("--issue-number", type=int, required=True) +pr_buildbot_information_parser.add_argument("--author", type=str, required=True) + release_workflow_parser = subparsers.add_parser("release-workflow") release_workflow_parser.add_argument( "--llvm-project-dir", @@ -633,6 +696,11 @@ def execute_command(self) -> bool: elif args.command == "pr-greeter": pr_greeter = PRGreeter(args.token, args.repo, args.issue_number) pr_greeter.run() +elif args.command == "pr-buildbot-information": + pr_buildbot_information = PRBuildbotInformation( + args.token, args.repo, args.issue_number, args.author + ) + pr_buildbot_information.run() elif args.command == "release-workflow": release_workflow = ReleaseWorkflow( args.token,