forked from idaholab/moose
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes idaholab#29514
- Loading branch information
Showing
1 changed file
with
148 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
#!/usr/bin/env python3 | ||
#* This file is part of the MOOSE framework | ||
#* https://www.mooseframework.org | ||
#* | ||
#* All rights reserved, see COPYRIGHT for full restrictions | ||
#* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
#* | ||
#* Licensed under LGPL 2.1, please see LICENSE for details | ||
#* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
import sys | ||
import os | ||
import argparse | ||
|
||
try: | ||
import requests # type: ignore # for exceptions | ||
except ModuleNotFoundError: | ||
print('Could not load `requests`. Please install this package.') | ||
sys.exit(1) | ||
try: | ||
import github # type: ignore # for exceptions | ||
from github import Github, Auth # type: ignore | ||
except ModuleNotFoundError: | ||
print('Could not load `pygithub` module. Please install the GitHub Python API module.') | ||
sys.exit(1) | ||
|
||
parser = argparse.ArgumentParser(description='Output links associated with CI/CD', | ||
epilog=f'Example usage: {os.path.basename(__file__)} ' | ||
'-t /path/to/token' | ||
f' github.com/idaholab/moose abc123') | ||
# ASCII Color codes | ||
RED = '\033[91m' | ||
GREEN = '\033[92m' | ||
RESET = '\033[0m' | ||
|
||
class GitHubAPI(): | ||
""" handle GH calls """ | ||
def __init__(self, github_args): | ||
auth = Auth.Token(github_args.token) | ||
(self.__host, self.__owner, self.__repo) = github_args.uri.split('/') | ||
self.sha = github_args.sha | ||
self.gh = Github(base_url=f'https://api.{self.__host}', auth=auth) | ||
|
||
@staticmethod | ||
def get_merge(commit) -> str: | ||
""" return SHA responsible for creating SHA """ | ||
return commit.raw_data['parents'][-1]['sha'] | ||
|
||
def get_commbined_status(self, commit) ->str: | ||
""" | ||
return status dictionary of supplied commit | ||
(only works with PR commits) | ||
""" | ||
return commit.get_combined_status() | ||
|
||
def get_repo(self) ->(object): | ||
""" return repo object """ | ||
try: | ||
repo = self.gh.get_repo(f'{self.__owner}/{self.__repo}') | ||
except github.GithubException as e: | ||
print(e.status, e.data['message']) | ||
sys.exit(1) | ||
except requests.exceptions.ConnectionError as e: | ||
print(f'Error connecting to server: {self.__host}\n\n{e}') | ||
sys.exit(1) | ||
return repo | ||
|
||
def get_commit(self, sha=None) ->object: | ||
""" get {OWNER}/{REPO}/commits/{HASH} """ | ||
repo = self.get_repo() | ||
sha = sha if sha is not None else self.sha | ||
try: | ||
commit = repo.get_commit(sha=sha) | ||
except github.GithubException as e: | ||
print(e.status, e.data['message']) | ||
sys.exit(1) | ||
return commit | ||
|
||
def parse_args(argv): | ||
""" parses arguments """ | ||
parser.add_argument('uri', nargs='?', metavar='URI', | ||
help='URI to GitHub repo. exp: github.com/idaholab/moose') | ||
parser.add_argument('sha', nargs='?', metavar='SHA', | ||
help='Povided SHA to be considered for release') | ||
parser.add_argument('-t','--token', nargs='?', | ||
help='Your GitHub API Token. Can either be an environment variable' | ||
' containing your token, or a path to a file containing your token, or ' | ||
' the token itself. For security purposes, ideally this should be a path' | ||
' to your token. To create a token, see:' | ||
' https://github.com/settings/tokens') | ||
|
||
return parser.parse_args(argv) | ||
|
||
def check_args(argv): | ||
""" checks command line options """ | ||
c_args = parse_args(argv) | ||
|
||
# verify all arguments are supplied | ||
if not c_args.uri or not c_args.sha or not c_args.token: | ||
print('ERROR: required arguments missing. Usage:\n') | ||
parser.print_help() | ||
sys.exit(1) | ||
|
||
# verify proper URI | ||
if len(c_args.uri.split('/')) != 3: | ||
print(f'\nSupplied URI not properly constructed: {c_args.uri}\nThe URI should contain' | ||
' three items separated by forward slashes.\n\n\thostname/namespace/repo\n') | ||
sys.exit(1) | ||
|
||
### determine how to handle token | ||
# ...supplied path to token | ||
if os.path.exists(c_args.token): | ||
with open(c_args.token, 'r', encoding='utf-8') as t_file: | ||
c_args.token = str(t_file.read()).strip() | ||
# ...supplied environment variable with path to token | ||
elif os.getenv(c_args.token, None) and os.path.exists(os.getenv(c_args.token, None)): | ||
with open(os.getenv(c_args.token, None), 'r', encoding='utf-8') as t_file: | ||
c_args.token = str(t_file.read()).strip() | ||
# ...supplied environment variable with token | ||
elif os.getenv(c_args.token, None): | ||
c_args.token = os.getenv(c_args.token) | ||
elif len(c_args.token) != 40: | ||
print('WARING: supplied token is not of the correct length, and is therefor' | ||
' probably\nwrong. Permission errors mar occur.\n') | ||
# ...if nothing was true, then assume argument supplied is the token | ||
|
||
return c_args | ||
|
||
def get_parent(gh, commit): | ||
""" return commits responsible for merge """ | ||
_sha = gh.get_merge(commit) | ||
return gh.get_commit(_sha) | ||
|
||
def main(args): | ||
""" entry point """ | ||
gh = GitHubAPI(args) | ||
commit = gh.get_commit() | ||
_p = get_parent(gh, commit) | ||
status = gh.get_commbined_status(_p) | ||
print(f'PR: {status.state}\nGitHub: {_p.html_url}') | ||
print(status.raw_data) | ||
for status in status.statuses: | ||
print(f'\t{status.state} {status.target_url} {status.context}') | ||
#print(f'{RED}{status}{RESET}\nstatuses: {status.statuses}') | ||
|
||
if __name__ == '__main__': | ||
m_args = check_args(sys.argv[1:]) | ||
sys.exit(main(m_args)) |