-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
recreate-dependabot-pr: re-create conflicting dependabot pr's
This script should be run in a GitHub push workflow on main where it would iterate over all open conflicting dependabot pull requests and recreate the most recent conflicting one by commenting to let dependabot recreate the pull request. Additional the `no-test` label ensures we don't run unneeded tests as re-creating still requires us to update the `node_modules` git submodule. The script has to retry the pull request detail endpoint as the `mergeable` state of a pull request can be `null` indicating GitHub is still determining if the pull request can be merged.
- Loading branch information
Showing
2 changed files
with
89 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#!/usr/bin/python3 | ||
|
||
# This file is part of Cockpit. | ||
# | ||
# Copyright (C) 2024 Red Hat, Inc. | ||
# | ||
# Cockpit is free software; you can redistribute it and/or modify it | ||
# under the terms of the GNU Lesser General Public License as published by | ||
# the Free Software Foundation; either version 2.1 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# Cockpit is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# Lesser General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>. | ||
|
||
# Update COCKPIT_REPO_COMMIT to cockpit HEAD automatically, defaults to | ||
# Makefile as input optionally the full path can be provided. (For example | ||
# Anaconda uses ui/webui/Makefile.am). | ||
|
||
import argparse | ||
import sys | ||
import time | ||
from typing import Optional | ||
|
||
import task | ||
Check notice Code scanning / CodeQL Module is imported with 'import' and 'import from' Note
Module 'task' is imported with both 'import' and 'import from'.
|
||
from lib.aio.jsonutil import get_dict, get_int, get_str | ||
from task import github | ||
|
||
sys.dont_write_bytecode = True | ||
|
||
|
||
def main() -> None: | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--repo', default='cockpit-project/cockpit', | ||
help="The GitHub repository to re-create dependabot pull requests for") | ||
args = parser.parse_args() | ||
|
||
api = github.GitHub(repo=args.repo) | ||
for pull in api.pulls(state="open"): | ||
number = get_int(pull, 'number') | ||
if number is None: | ||
continue | ||
|
||
user = get_dict(pull, 'user') | ||
if get_str(user, 'login') != 'dependabot[bot]': | ||
continue | ||
|
||
pull_details = api.get(f'pulls/{number}') | ||
|
||
# Ignore dependabot PR's with multiple commits, they might be work in progress. | ||
if get_int(pull_details, 'commits') > 1: | ||
print(f'Skipping pull {number}, it is being worked on') | ||
continue | ||
|
||
mergeable: Optional[bool] = pull_details['mergeable'] | ||
# State is unknown, retry with a timeout | ||
if mergeable is None: | ||
for retry in range(3): | ||
pull_details = api.get(f'pulls/{number}') | ||
mergeable = pull_details['mergeable'] | ||
if mergeable is not None: | ||
break | ||
|
||
print(f'Retrying to obtain mergeable status for pull={number}, retry={retry}') | ||
time.sleep(5) | ||
|
||
if mergeable: | ||
print(f'Skipping pull {number}, it is in a mergeable state') | ||
continue | ||
else: | ||
# Not mergeable and a dependabot PR, add a `no-test` label and re-create the PR. | ||
task.label(pull_details, ['no-test', 'dependabot-recreated']) # type: ignore[no-untyped-call] | ||
task.comment(pull_details, '@dependabot recreate') # type: ignore[no-untyped-call] | ||
|
||
# Stop at the first dependabot PR as we can only land one at a time. | ||
break | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |