diff --git a/.github/scripts/automerge.py b/.github/scripts/automerge.py new file mode 100644 index 0000000000..3518579d9d --- /dev/null +++ b/.github/scripts/automerge.py @@ -0,0 +1,60 @@ +# ------------------------------------------------------------ +# Copyright (c) Microsoft Corporation and Dapr Contributors. +# Licensed under the MIT License. +# ------------------------------------------------------------ + +# This script automerges PRs + +import os + +from github import Github + + +g = Github(os.getenv("GITHUB_TOKEN")) +repo = g.get_repo(os.getenv("GITHUB_REPOSITORY")) +maintainers = [m.strip() for m in os.getenv("MAINTAINERS").split(',')] + +def fetch_pulls(mergeable_state): + return [pr for pr in repo.get_pulls(state='open', sort='created') \ + if pr.mergeable_state == mergeable_state and 'auto-merge' in [l.name for l in pr.labels]] + +def is_approved(pr): + approvers = [r.user.login for r in pr.get_reviews() if r.state == 'APPROVED' and r.user.login in maintainers] + return len([a for a in approvers if repo.get_collaborator_permission(a) in ['admin', 'write']]) > 0 + +# First, find a PR that can be merged +pulls = fetch_pulls('clean') +print(f"Detected {len(pulls)} open pull requests in {repo.name} to be automerged.") +merged = False +for pr in pulls: + if is_approved(pr): + # Merge only one PR per run. + print(f"Merging PR {pr.html_url}") + try: + pr.merge(merge_method='squash') + merged = True + break + except: + print(f"Failed to merge PR {pr.html_url}") + +if len(pulls) > 0 and not merged: + print("No PR was automerged.") + +# Now, update all PRs that are behind. +pulls = fetch_pulls('behind') +print(f"Detected {len(pulls)} open pull requests in {repo.name} to be updated.") +for pr in pulls: + if is_approved(pr): + # Update all PRs since there is no guarantee they will all pass. + print(f"Updating PR {pr.html_url}") + try: + pr.update_branch() + except: + print(f"Failed to update PR {pr.html_url}") + +pulls = fetch_pulls('dirty') +print(f"Detected {len(pulls)} open pull requests in {repo.name} to be automerged but are in dirty state.") +for pr in pulls: + print(f"PR is in dirty state: {pr.html_url}") + +print("Done.") \ No newline at end of file diff --git a/.github/workflows/automerge-bot.yml b/.github/workflows/automerge-bot.yml new file mode 100644 index 0000000000..554e0ce5f4 --- /dev/null +++ b/.github/workflows/automerge-bot.yml @@ -0,0 +1,26 @@ +# ------------------------------------------------------------ +# Copyright (c) Microsoft Corporation and Dapr Contributors. +# Licensed under the MIT License. +# ------------------------------------------------------------ + +name: dapr-java-sdk-automerge-bot + +on: + schedule: + - cron: '*/30 * * * *' + workflow_dispatch: +jobs: + automerge: + if: github.repository_owner == 'dapr' + name: Automerge and update PRs. + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Install dependencies + run: pip install PyGithub + - name: Automerge and update + env: + MAINTAINERS: artursouza,mukundansundar + GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }} + run: python ./.github/scripts/automerge.py