From b317624baa76bffc30242dbbbbe97c29d726aace Mon Sep 17 00:00:00 2001 From: David Arthur Date: Mon, 9 Sep 2024 13:58:16 -0400 Subject: [PATCH] MINOR Enable the GitHub build by default (#17105) Reviewers: Chia-Ping Tsai --- .github/workflows/build.yml | 8 +-- .github/workflows/ci.yml | 1 - approve-workflows.py | 116 ++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 approve-workflows.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8dbe5a4feea5..60f2a132b7e4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,10 +26,6 @@ on: description: "Should the Gradle cache be write-only?" default: "false" type: string - github-actions-opt-in: - description: "Should we run the opt-in steps?" - default: "false" - type: string is-public-fork: description: "Is this CI run from a public fork?" default: "true" @@ -78,8 +74,7 @@ jobs: if-no-files-found: ignore - name: Annotate checkstyle errors # Avoid duplicate annotations, only run on java 21 - # For now, limit to "gh-" PRs - if: ${{ inputs.github-actions-opt-in && failure() && matrix.java == '21' }} + if: ${{ failure() && matrix.java == '21' }} run: python .github/scripts/checkstyle.py env: GITHUB_WORKSPACE: ${{ github.workspace }} @@ -91,7 +86,6 @@ jobs: fail-fast: false matrix: java: [ 17, 11 ] - if: ${{ inputs.github-actions-opt-in == 'true' }} name: JUnit tests Java ${{ matrix.java }} steps: - name: Checkout code diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fa43d53670ae..2fc39b4965a0d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,6 @@ jobs: with: gradle-cache-read-only: ${{ github.ref != 'refs/heads/trunk' }} gradle-cache-write-only: ${{ github.ref == 'refs/heads/trunk' }} - github-actions-opt-in: ${{ github.ref == 'refs/heads/trunk' || contains(github.head_ref, 'gh-') }} is-public-fork: ${{ github.event.pull_request.head.repo.full_name != 'apache/kafka' }} secrets: inherit diff --git a/approve-workflows.py b/approve-workflows.py new file mode 100644 index 0000000000000..1f5a09efb47b2 --- /dev/null +++ b/approve-workflows.py @@ -0,0 +1,116 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import subprocess +import shlex +import webbrowser + + +def prompt_user() -> str: + choices = "ynw?" + while True: + try: + user_input = input(f"Make a selection [{','.join(choices)}]: ") + except (KeyboardInterrupt, EOFError): + exit(0) + clean_input = user_input.strip().lower() + if clean_input == "?": + print("\ny: approve the run\nn: do nothing\nw: open the URL for this run") + continue + if clean_input not in choices: + print(f"\nInvalid selection '{clean_input}'. Valid choices are:") + print("y: approve the run\nn: do nothing\nw: open the URL for this run") + continue + else: + return clean_input + + +def run_gh_command(cmd: str) -> str: + "Run a gh CLI command and return the stdout" + p = subprocess.run( + shlex.split(cmd), + capture_output=True + ) + if p.returncode == 4: + # Not auth'd + print(p.stderr.decode()) + exit(1) + elif p.returncode == 0: + return p.stdout.decode() + else: + print(f"Had an error running '{cmd}'.\nSTDOUT: {p.stdout.decode()}\nSTDERR: {p.stderr.decode()}") + + +def list_pending_workflow_runs(): + command = r"gh run list --limit 20 --repo apache/kafka --workflow CI --status action_required --json 'databaseId,headBranch'" + out = run_gh_command(command) + pending_workflows = json.loads(out) + runs_by_branch = dict() + for workflow in pending_workflows: + run_id = workflow.get("databaseId") + branch = workflow.get("headBranch") + if branch in runs_by_branch: + print(f"Ignoring run {run_id} since there is a newer one: {runs_by_branch[branch]}") + continue + runs_by_branch[branch] = run_id + return runs_by_branch.values() + +def load_workflow_run(run_id: str): + command = rf"gh api --method GET -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/apache/kafka/actions/runs/{run_id}" + out = run_gh_command(command) + workflow_run = json.loads(out) + return workflow_run + + +def approve_workflow_run(run_id: str): + command = rf"gh api --method POST -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/apache/kafka/actions/runs/{run_id}/approve" + out = run_gh_command(command) + workflow_run = json.loads(out) + return workflow_run + + +if __name__ == "__main__": + """ + Interactive script to approve pending CI workflow runs. This script can only be used by committers. + + Requires the GitHub CLI. See https://cli.github.com/ for installation instructions. + + Once installed authenticate with: gh auth login + """ + pending_runs = list_pending_workflow_runs() + for run_id in pending_runs: + run = load_workflow_run(run_id) + branch = run.get("head_branch") + run_id = run.get("id") + title = run.get("display_title") + repo = run.get("head_repository", {}).get("full_name") + actor = run.get("actor", {}).get("login") + url = run.get("html_url") + updated = run.get("updated_at") + print("-"*80) + print(f"PR: {title}") + print(f"Actor: {actor}") + print(f"Branch: {repo} {branch}") + print(f"Updated: {updated}") + print(f"URL: {url}") + print("") + selection = prompt_user() + if selection == "y": + approve_workflow_run(run_id) + elif selection == "n": + continue + elif selection == "w": + webbrowser.open(url)