blob: 8437e3481ce6f35bdbc3e32fb5cfd918b871f5a4 [file] [log] [blame]
# issue_on_error_post.py
# Requires python 3.6+ and GitHub CLI in the environment.
#
# Creates or updates an issue on action failure related to a workflow.
#
# Looks though REPO for open issues with FLAG_LABEL. If none,
# creates a new issue. If there is an open issue with FLAG_LABEL,
# looks for WORKFLOW in body. If none, creates an issue. If an
# issue for WORKFLOW exists, makes adds a comment.
#
# Requires the environment provide the variables in the block below.
# TOKEN must have access to update issues.
#
# If called with an optional PR_NUMBER and PR_LINK the issue will
# include a link to the PR.
from datetime import datetime
import os
import json
import subprocess
REPO_NAME = os.environ['REPO']
WORKFLOW = os.environ['WORKFLOW']
FLAG_LABEL = os.environ['FLAG_LABEL']
RUN_NUMBER = os.environ['RUN_NUMBER']
RUN_ID = os.environ['RUN_ID']
# optional variables
PR_NUMBER = os.getenv('PR_NUMBER')
PR_LINK = os.getenv('PR_LINK')
def get_tagged_issues(flag_label, workflow):
issues = subprocess.check_output(["gh", "issue", "list",
"--state", "open",
"--label", flag_label,
"--json", "title,number,body"],
encoding="utf-8")
issues = json.loads(issues)
tagged_issues =[]
for issue in issues:
if workflow in issue["body"]:
tagged_issues.append(issue)
return(tagged_issues)
def create_issue(flag_label, workflow, run_number, run_id, repo_name, pr_number, pr_link):
run_link = f"http://github.com/{repo_name}/actions/runs/{run_id}"
body_string = ""
title_string = f"{workflow} CI Run Failed"
if pr_number:
body_string = f"PR {pr_number} ({pr_link}) had a CI failure: \n"
title_string = f"PR #{pr_number} CI Run Failed"
body_string += f"{workflow} [run number {run_number}]({run_link}) failed. \n\n"
body_string += "This issue has been automatically generated for "
body_string += "notification purposes."
new_issue = subprocess.check_output(["gh", "issue", "create",
"--title", title_string,
"--body", body_string,
"--label", flag_label],
encoding="utf-8")
return(new_issue)
def add_comment(issue_number, run_number, run_id, repo_name):
dt_string = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
run_link = f"http://github.com/{repo_name}/actions/runs/{run_id}"
msg_string = f"Error reoccurred: {dt_string}\n"
msg_string += f"[Run number: {run_number}]({run_link})\n"
subprocess.run(["gh", "issue", "comment", issue_number,
"--body", msg_string])
return()
if __name__ == "__main__":
tagged_issues = get_tagged_issues(FLAG_LABEL, WORKFLOW)
# The logic catches the case where an issue exists for the workflow
# but we are testing against a PR and want a created issue to link to the PR.
# Otherwise, we just add a comment to the existing issue.
if not tagged_issues:
create_issue(FLAG_LABEL, WORKFLOW, RUN_NUMBER, RUN_ID, REPO_NAME, PR_NUMBER, PR_LINK)
else:
for issue in tagged_issues:
if PR_NUMBER:
if PR_LINK in issue["body"]:
add_comment(str(issue["number"]), RUN_NUMBER, RUN_ID, REPO_NAME)
else:
create_issue(FLAG_LABEL, WORKFLOW, RUN_NUMBER, RUN_ID, REPO_NAME,
PR_NUMBER, PR_LINK)
else:
add_comment(str(issue["number"]), RUN_NUMBER, RUN_ID, REPO_NAME)
for issue in tagged_issues:
print(issue["number"])