From 844be844e6043344e3d3be493b3b8e18e9465df1 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 26 Nov 2024 21:33:30 -0700 Subject: [PATCH 01/11] modified: src/automerge.py - Modify api end points used to check status. Previous did not have a permission option with fine-grained tokens. - This reduces permissioni requirements to use automerger --- src/automerge.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/automerge.py b/src/automerge.py index 0d9e245..475b221 100755 --- a/src/automerge.py +++ b/src/automerge.py @@ -90,21 +90,12 @@ def run_git_command(command_args: str) -> subprocess.CompletedProcess: 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 = pr.get_commits().reversed[0] + combined_status = commit.get_combined_status() + all_checks_passed = combined_status.state == 'success' + + if not all_checks_passed: + _LOGGER.info(f"Checks are not passing ({combined_status.state}) on PR#{pr.number}") commit = [c for c in pr.get_commits() if c.sha == pr.head.sha][0] combined_status = commit.get_combined_status().state if pr.mergeable_state == 'clean' and all_checks_passed: From 3f63d9d884c6e94684bf05b5b4b7264f94bcbaa2 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 26 Nov 2024 21:37:43 -0700 Subject: [PATCH 02/11] modified: .github/workflows/test.yaml - Update tests to use the new less permissive token. --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 7bcab26..e4b4d4a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -37,7 +37,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ secrets.JENKINS_GITHUB_PAT }} + token: ${{ secrets.AUTOMERGE_TOKEN }} debug: --dry-run - name: 'Automerge runtimeverification/${{ matrix.value }}' @@ -46,7 +46,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ secrets.JENKINS_GITHUB_PAT }} + token: ${{ secrets.AUTOMERGE_TOKEN }} debug: --dry-run comment: 'true' \ No newline at end of file From 801d63e3a65ea4720ece06e0e2130d20710610c2 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Wed, 27 Nov 2024 20:10:40 -0700 Subject: [PATCH 03/11] modified: src/automerge.py - Checking the 'chech' statuses per commit - Ccombined commit was not always accurate to the mergeable state of a PR due to annotations and other items checked not important to basic check passed? Approved? Up to datae? Yes? Merge. --- src/automerge.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/automerge.py b/src/automerge.py index 475b221..25e1a6c 100755 --- a/src/automerge.py +++ b/src/automerge.py @@ -91,11 +91,12 @@ def run_git_command(command_args: str) -> subprocess.CompletedProcess: base_branch = repo.get_branch(pr.base.ref) if base_branch.protected: commit = pr.get_commits().reversed[0] - combined_status = commit.get_combined_status() - all_checks_passed = combined_status.state == 'success' + statuses = commit.get_statuses() + all_checks_passed = all(print(status) for status in statuses) + list_statuses = [status.state for status in statuses] if not all_checks_passed: - _LOGGER.info(f"Checks are not passing ({combined_status.state}) on PR#{pr.number}") + _LOGGER.info(f"Checks are not passing ({list_statuses[-1]}) on PR#{pr.number}") commit = [c for c in pr.get_commits() if c.sha == pr.head.sha][0] combined_status = commit.get_combined_status().state if pr.mergeable_state == 'clean' and all_checks_passed: From 447f127e650196837257a173f10167a7571f0bcd Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 13:06:19 -0700 Subject: [PATCH 04/11] modified: src/automerge.py - Rework logic. - New dependency for infrastructure to run. Install Github App AutomergePR Permission Control to have access to check statuses. Bug in Github fine-grained tokens or deprecated documentaiton never removed. --- src/automerge.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/automerge.py b/src/automerge.py index 25e1a6c..4171007 100755 --- a/src/automerge.py +++ b/src/automerge.py @@ -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}' @@ -89,16 +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: - commit = pr.get_commits().reversed[0] - statuses = commit.get_statuses() - all_checks_passed = all(print(status) for status in statuses) - list_statuses = [status.state for status in statuses] - - if not all_checks_passed: - _LOGGER.info(f"Checks are not passing ({list_statuses[-1]}) on PR#{pr.number}") 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': From 58979d7d293a5ae1b242c715af86fe6fce7e4552 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 13:56:32 -0700 Subject: [PATCH 05/11] modified: .github/workflows/test.yaml - Updating workflow test to use the GH APP credentials modified: README.md - Modifying instructions and informating need for github and what permissions are needed for the github App --- .github/workflows/test.yaml | 10 ++++++++-- README.md | 26 ++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e4b4d4a..fb1a0f7 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,6 +18,12 @@ 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/create-github-app-token@v1.11.0 + with: + app_id: ${{ secrets.AUTOMERGE_APP_ID }} + private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} automerge-test: name: 'Automerge' @@ -37,7 +43,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ secrets.AUTOMERGE_TOKEN }} + token: ${{ needs.list.outputs.token }} debug: --dry-run - name: 'Automerge runtimeverification/${{ matrix.value }}' @@ -46,7 +52,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ secrets.AUTOMERGE_TOKEN }} + token: ${{ needs.list.outputs.token }} debug: --dry-run comment: 'true' \ No newline at end of file diff --git a/README.md b/README.md index 51508a7..260e0f5 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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/create-github-app-token@v1.11.0 + with: + app_id: ${{ secrets.AUTOMERGE_APP_ID }} + private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} + automerge-test: name: 'Automerge' runs-on: [ubuntu-latest] @@ -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/automerge@v1.0.4 # 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 }} @@ -112,8 +129,9 @@ Checkout the repository you wish to run automerge on to a local directory. git clone git@github.com: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 ``` From e7ed705b6d2ccdb3d2aa6a323136fb16a17441df Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 14:02:11 -0700 Subject: [PATCH 06/11] Rearrange Github app token step and use app token for check steps --- .github/workflows/test.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index fb1a0f7..4debea2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -13,18 +13,18 @@ jobs: outputs: matrix: ${{ steps.list.outputs.value }} steps: - - name: 'Check out devops repo' - uses: actions/checkout@v4.0.0 - - 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/create-github-app-token@v1.11.0 with: app_id: ${{ secrets.AUTOMERGE_APP_ID }} private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} - + - name: 'Check out devops repo' + uses: actions/checkout@v4.0.0 + - 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] @@ -35,6 +35,8 @@ jobs: value: ${{fromJson(needs.list.outputs.matrix)}} steps: - name: 'Check Automerge Repo to Test' + env: + GITHUB_TOKEN: ${{ needs.list.outputs.token }} uses: actions/checkout@v4 - name: 'Automerge runtimeverification/${{ matrix.value }}' From 2764b42107c8fdf6f57306bca2b278a96775eb72 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 14:03:53 -0700 Subject: [PATCH 07/11] Missed first job adding 'token' --- .github/workflows/test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4debea2..e06dea2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,6 +20,8 @@ jobs: app_id: ${{ secrets.AUTOMERGE_APP_ID }} private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} - name: 'Check out devops repo' + env: + token: ${{ needs.list.outputs.token }} uses: actions/checkout@v4.0.0 - id: list name: 'List automerge repos' @@ -36,7 +38,7 @@ jobs: steps: - name: 'Check Automerge Repo to Test' env: - GITHUB_TOKEN: ${{ needs.list.outputs.token }} + token: ${{ needs.list.outputs.token }} uses: actions/checkout@v4 - name: 'Automerge runtimeverification/${{ matrix.value }}' From eddef9d7c9d4c5d0d3aa9add1b157815d2d8bac0 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 14:06:00 -0700 Subject: [PATCH 08/11] References to token were mixed up between jobs and steps outside originating job --- .github/workflows/test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e06dea2..802eee5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -12,6 +12,7 @@ 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 @@ -21,7 +22,7 @@ jobs: private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} - name: 'Check out devops repo' env: - token: ${{ needs.list.outputs.token }} + token: ${{ steps.automerge_token.outputs.token }} uses: actions/checkout@v4.0.0 - id: list name: 'List automerge repos' From 03faaef295c86d87909eba2a2e4e79b852c48255 Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 14:11:50 -0700 Subject: [PATCH 09/11] Generate token for all repositories under current owner running the action --- .github/workflows/test.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 802eee5..d3488dc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,8 +18,9 @@ jobs: id: automerge_token uses: actions/create-github-app-token@v1.11.0 with: - app_id: ${{ secrets.AUTOMERGE_APP_ID }} - private_key: ${{ secrets.AUTOMERGE_APP_PRIVATE_KEY }} + 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 }} From 53976a8d7df9334b128c5cb32089b94ba59fc75c Mon Sep 17 00:00:00 2001 From: F-WRunTime Date: Tue, 3 Dec 2024 14:14:51 -0700 Subject: [PATCH 10/11] Generate a new token for each job --- .github/workflows/test.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d3488dc..8ba6005 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -38,9 +38,17 @@ jobs: matrix: value: ${{fromJson(needs.list.outputs.matrix)}} steps: + - name: 'Generate GitHub App Token' + id: automerge_token + uses: actions/create-github-app-token@v1.11.0 + 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: ${{ needs.list.outputs.token }} + token: ${{ steps.automerge_token.outputs.token }} uses: actions/checkout@v4 - name: 'Automerge runtimeverification/${{ matrix.value }}' @@ -49,7 +57,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ needs.list.outputs.token }} + token: ${{ steps.automerge_token.outputs.token }} debug: --dry-run - name: 'Automerge runtimeverification/${{ matrix.value }}' @@ -58,7 +66,7 @@ jobs: with: org: 'runtimeverification' repo: ${{ matrix.value }} - token: ${{ needs.list.outputs.token }} + token: ${{ steps.automerge_token.outputs.token }} debug: --dry-run comment: 'true' \ No newline at end of file From 7fb171e2006f4809de13d640d735f1d375733e15 Mon Sep 17 00:00:00 2001 From: Freeman <105403280+F-WRunTime@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:48:51 -0700 Subject: [PATCH 11/11] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grammar fix in readme. Co-authored-by: Tamás Tóth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 260e0f5..1d4cea4 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ Checkout the repository you wish to run automerge on to a local directory. git clone git@github.com:org/automerge.git cd automerge ``` -Setup GITHUB_TOKEN with the appropriate permissions. Content Read/Write, Pull Request Read/Write, adminstration Read, Checks Read. +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