Skip to content

Commit

Permalink
Automerge every 4 hours any labeled PR with passing tests (#675)
Browse files Browse the repository at this point in the history
* Automerge every 4-hours any PR with passing tests labeled with 'automerge'
* Make sure the bot can approve the PRs too
* Update Bot information only if git email currently unset
* consistently use private key secret to setup ssh git-remote
* Rename secret to BOT_SSH_KEY
* Reimagine auto-merge scripts as python
  • Loading branch information
addyess authored and cdkbot committed Sep 17, 2024
1 parent 22f04c6 commit f79b5c1
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 8 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/auto-merge-successful-prs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Auto-merge Successful PRs

on:
workflow_dispatch:
schedule:
- cron: "0 */4 * * *" # Every 4 hours

permissions:
contents: read
pull-requests: write

jobs:
merge-successful-prs:
runs-on: ubuntu-latest

steps:
- name: Harden Runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Checking out repo
uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.BOT_SSH_KEY }}
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Auto-merge pull requests if all status checks pass
env:
GH_TOKEN: ${{ github.token }}
run: |
build-scripts/hack/auto-merge-successful-pr.py
2 changes: 1 addition & 1 deletion .github/workflows/update-branches.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Sync ${{ github.ref }} to ${{ steps.determine.outputs.branch }}
uses: actions/checkout@v4
with:
ssh-key: ${{ secrets.DEPLOY_KEY_TO_UPDATE_STRICT_BRANCH }}
ssh-key: ${{ secrets.BOT_SSH_KEY }}
- name: Apply ${{ matrix.patch }} patch
run: |
git checkout -b ${{ steps.determine.outputs.branch }}
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/update-components.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ matrix.branch }}
ssh-key: ${{ secrets.DEPLOY_KEY_TO_UPDATE_STRICT_BRANCH }}
ssh-key: ${{ secrets.BOT_SSH_KEY }}

- name: Setup Python
uses: actions/setup-python@v5
Expand All @@ -51,10 +51,11 @@ jobs:
- name: Create pull request
uses: peter-evans/create-pull-request@v6
with:
git-token: ${{ secrets.DEPLOY_KEY_TO_UPDATE_STRICT_BRANCH }}
commit-message: "[${{ matrix.branch }}] Update component versions"
title: "[${{ matrix.branch }}] Update component versions"
body: "[${{ matrix.branch }}] Update component versions"
branch: "autoupdate/sync/${{ matrix.branch }}"
labels: |
automerge
delete-branch: true
base: ${{ matrix.branch }}
55 changes: 55 additions & 0 deletions build-scripts/hack/auto-merge-successful-pr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/env python3

import shlex
import subprocess
import json

LABEL = "automerge"
APPROVE_MSG = "All status checks passed for PR #{}."


def sh(cmd: str) -> str:
"""Run a shell command and return its output."""
_pipe = subprocess.PIPE
result = subprocess.run(shlex.split(cmd), stdout=_pipe, stderr=_pipe, text=True)
if result.returncode != 0:
raise Exception(f"Error running command: {cmd}\nError: {result.stderr}")
return result.stdout.strip()


def get_pull_requests() -> list:
"""Fetch open pull requests matching some label."""
prs_json = sh("gh pr list --state open --json number,labels")
prs = json.loads(prs_json)
return [pr for pr in prs if any(label["name"] == LABEL for label in pr["labels"])]


def check_pr_passed(pr_number) -> bool:
"""Check if all status checks passed for the given PR."""
checks_json = sh(f"gh pr checks {pr_number} --json bucket")
checks = json.loads(checks_json)
return all(check["bucket"] == "pass" for check in checks)


def approve_and_merge_pr(pr_number) -> None:
"""Approve and merge the PR."""
print(APPROVE_MSG.format(pr_number) + "Proceeding with merge...")
sh(f'gh pr review {pr_number} --approve -b "{APPROVE_MSG.format(pr_number)}"')
sh(f"gh pr merge {pr_number} --auto --squash")


def process_pull_requests():
"""Process the PRs and merge if checks have passed."""
prs = get_pull_requests()

for pr in prs:
pr_number: int = pr["number"]

if check_pr_passed(pr_number):
approve_and_merge_pr(pr_number)
else:
print(f"Status checks have not passed for PR #{pr_number}. Skipping merge.")


if __name__ == "__main__":
process_pull_requests()
9 changes: 6 additions & 3 deletions build-scripts/patches/moonray/apply
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

DIR="$(realpath "$(dirname "${0}")")"

# Configure git author
git config user.email k8s-bot@canonical.com
git config user.name k8s-bot
# Configure git author if unset
git_email=$(git config --default "" user.email)
if [ -z "${git_email}" ]; then
git config user.email k8s-team-ci@canonical.com
git config user.name 'k8s-team-ci (CDK Bot)'
fi

# Remove unrelated tests
rm "${DIR}/../../../tests/integration/tests/test_cilium_e2e.py"
Expand Down
7 changes: 5 additions & 2 deletions build-scripts/patches/strict/apply
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
DIR="$(realpath "$(dirname "${0}")")"

# Configure git author
git config user.email k8s-bot@canonical.com
git config user.name k8s-bot
git_email=$(git config --default "" user.email)
if [ -z "${git_email}" ]; then
git config user.email k8s-team-ci@canonical.com
git config user.name 'k8s-team-ci (CDK Bot)'
fi

# Apply strict patch
git am "${DIR}/0001-Strict-patch.patch"

0 comments on commit f79b5c1

Please sign in to comment.