Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modified: src/automerge.py #5

Merged
merged 11 commits into from
Dec 4, 2024
26 changes: 23 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ jobs:
runs-on: [ubuntu-latest]
outputs:
matrix: ${{ steps.list.outputs.value }}
token: ${{ steps.automerge_token.outputs.token }}
steps:
- name: 'Generate GitHub App Token'
id: automerge_token
uses: actions/[email protected]
with:
app-id: ${{ secrets.AUTOMERGE_APP_ID }}
private-key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: 'Check out devops repo'
env:
token: ${{ steps.automerge_token.outputs.token }}
uses: actions/[email protected]
- id: list
name: 'List automerge repos'
run: echo "value=$(cat test/automerge.json | tr -d '\n')" >> $GITHUB_OUTPUT

automerge-test:
name: 'Automerge'
runs-on: [ubuntu-latest]
Expand All @@ -28,7 +38,17 @@ jobs:
matrix:
value: ${{fromJson(needs.list.outputs.matrix)}}
steps:
- name: 'Generate GitHub App Token'
id: automerge_token
uses: actions/[email protected]
with:
app-id: ${{ secrets.AUTOMERGE_APP_ID }}
private-key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}

- name: 'Check Automerge Repo to Test'
env:
token: ${{ steps.automerge_token.outputs.token }}
uses: actions/checkout@v4

- name: 'Automerge runtimeverification/${{ matrix.value }}'
Expand All @@ -37,7 +57,7 @@ jobs:
with:
org: 'runtimeverification'
repo: ${{ matrix.value }}
token: ${{ secrets.JENKINS_GITHUB_PAT }}
token: ${{ steps.automerge_token.outputs.token }}
debug: --dry-run

- name: 'Automerge runtimeverification/${{ matrix.value }}'
Expand All @@ -46,7 +66,7 @@ jobs:
with:
org: 'runtimeverification'
repo: ${{ matrix.value }}
token: ${{ secrets.JENKINS_GITHUB_PAT }}
token: ${{ steps.automerge_token.outputs.token }}
debug: --dry-run
comment: 'true'

26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ Any PR with the following criteria will be updated and test will be run before m
- PR is passing PR Tests
- PR is out-of-date

A Github App is required to generate the appropriate Permissions for Automerge to work.
- The Github App is not public and requires each org to generate their own.
Adding a token generation step to their automerge workflow. See Example Workflow below.
- Specific repositories can be granted access using the app instead of ALL repositories under the org.

Github App Permissions:
- Content Read/Write -- For Updating PRs
- Pull Request Read/Write -- For Updating PRs
- Repository Administration Read -- For read access to repositories under the Org.
- Checks Read -- For reading the check statuses of the PR

## Table of Contents
- [Automerge PR Action](#automerge-pr-action)
- [Table of Contents](#table-of-contents)
Expand Down Expand Up @@ -62,7 +73,13 @@ jobs:
- id: list
name: 'List automerge repos'
run: echo "value=$(cat test/automerge.json | tr -d '\n')" >> $GITHUB_OUTPUT

- name: 'Generate GitHub App Token'
id: automerge_token
uses: actions/[email protected]
with:
app_id: ${{ secrets.AUTOMERGE_APP_ID }}
private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }}

automerge-test:
name: 'Automerge'
runs-on: [ubuntu-latest]
Expand All @@ -73,7 +90,7 @@ jobs:
value: ${{fromJson(needs.list.outputs.matrix)}}
steps:
- name: 'Automerge runtimeverification/${{ matrix.value }}'
uses: ./ # This uses the action in the root directory
uses: runtimeverification/[email protected] # This uses the action in the root directory
with:
org: 'runtimeverification' # As long as the token you use has access, any org is valid here
repo: ${{ matrix.value }}
Expand Down Expand Up @@ -112,8 +129,9 @@ Checkout the repository you wish to run automerge on to a local directory.
git clone [email protected]:org/automerge.git
cd automerge
```

Now you need to run the command from this new directory
Setup `GITHUB_TOKEN` with the appropriate permissions: Content Read/Write, Pull Request Read/Write, Adminstration Read, Checks Read.
Now you need to run the command from this new directory.
RV setup a test repository with Pull Requests in Known States to validate the action is working as expected.
```bash
$(pwd)/../src/automerge.py --org runtimeverification --repo automerger-test --dry-run
```
Expand Down
30 changes: 11 additions & 19 deletions src/automerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

_LOGGER: Final = logging.getLogger(__name__)
_LOG_FORMAT: Final = '%(levelname)s %(asctime)s %(name)s - %(message)s'
logging.basicConfig(level=logging.INFO)

if args.dry_run:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)

def pr_to_display_string(pr):
return f'- {pr.number}: {pr.title}\n\t\t{pr.html_url}'
Expand Down Expand Up @@ -89,24 +91,14 @@ def run_git_command(command_args: str) -> subprocess.CompletedProcess:
out_of_date_passing_prs = []
for pr in automerge_prs:
base_branch = repo.get_branch(pr.base.ref)
if base_branch.protected:
required_status_checks = base_branch.get_required_status_checks()
latest_commit = pr.get_commits().reversed[0]
latest_commit_checks = {check_run.name: check_run for check_run in latest_commit.get_check_runs()}
all_checks_passed = True
for required_check in required_status_checks.contexts:
if required_check not in latest_commit_checks:
print(f"Required check {required_check} is missing in the latest commit.")
all_checks_passed = False
else:
check_run = latest_commit_checks[required_check]
if check_run.conclusion == 'success':
print(f"Required check {required_check} passed on PR#{pr.number}")
else:
print(f"Required check {required_check} failed or is pending on PR#{pr.number}")
all_checks_passed = False
commit = [c for c in pr.get_commits() if c.sha == pr.head.sha][0]
combined_status = commit.get_combined_status().state
commit_check_runs = commit.get_check_runs()
all_checks_passed = all(run.conclusion == "success" for run in commit_check_runs)
_LOGGER.debug(f'HEAD Commit: {commit}')
_LOGGER.debug(f'All Checks Passed? {all_checks_passed}')
if args.dry_run:
for check_run in commit_check_runs:
_LOGGER.debug(f'Check Run: {check_run}')
if pr.mergeable_state == 'clean' and all_checks_passed:
up_to_date_passing_prs.append(pr)
elif pr.mergeable_state == 'behind' or pr.mergeable_state == 'blocked':
Expand Down
Loading