Add Github Pull Request comments

Contents

Add Github Pull Request comments#

# nuclio: ignore
import nuclio
%nuclio config spec.image = "mlrun/mlrun"
%nuclio config kind = "job"
%nuclio: setting spec.image to 'mlrun/mlrun'
%nuclio: setting kind to 'job'
import requests
import os
from mlrun import DataItem, get_run_db, mlconf

def pr_comment(context, repo: str, issue : int,
               message: str = '', 
               message_file: DataItem = None):

    token = context.get_secret('GITHUB_TOKEN') or os.environ.get('GITHUB_TOKEN')
    if message_file and not message:
        message = message_file.get()
    elif not message and not message_file:
        raise ValueError('pr message or message file must be provided')
        
    headers = {'Accept': 'application/vnd.github.v3+json',
               'Authorization': f'token {token}'}
    url = f'https://api.github.com/repos/{repo}/issues/{issue}/comments'

    resp = requests.post(url=url, json={"body": str(message)}, headers=headers)
    if not resp.ok:
        errmsg = f'bad pr comment resp!!\n{resp.text}'
        context.logger.error(errmsg)
        raise IOError(errmsg)
    
def run_summary_comment(context, workflow_id, repo: str, issue : int, project=''):
    db = get_run_db().connect()
    project=project or context.project
    runs = db.list_runs(project=project, labels=f'workflow={workflow_id}')
    
    had_errors = i = 0
    for r in runs:
        name = r['metadata']['name']
        if r['status'].get('state', '') == 'error':
            had_errors += 1
        if name == context.name:
            del runs[i]
        i += 1

    print('errors:', had_errors)
    
    html = '### Run Results\nWorkflow {} finished with {} errors'.format(workflow_id, had_errors)
    html += '<br>click the hyper links below to see detailed results<br>'
    html += runs.show(display=False, short=True)
    if repo:
        pr_comment(context, repo, issue, html)
    else:
        print('repo not defined')
        print(html)
    
# nuclio: end-code
# marks the end of a code section
from mlrun import mlconf
import os

mlconf.dbpath = mlconf.dbpath or 'http://mlrun-api:8080'
mlconf.artifact_path = mlconf.artifact_path or f'{os.environ["HOME"]}/artifacts'
from mlrun import code_to_function 
# create job function object from notebook code
fn = code_to_function("github_utils")

# add metadata (for templates and reuse)
fn.spec.default_handler = "run_summary_comment"
fn.spec.description = "add comments to github pull requests"
fn.metadata.categories = ["notifications", "utils"]
fn.metadata.labels = {"author": "yaronh"}
fn.export("function.yaml")
[mlrun] 2020-05-10 10:32:10,234 function spec saved to path: function.yaml
<mlrun.runtimes.kubejob.KubejobRuntime at 0x7f1d91729cc0>

tests#

from mlrun import run_local, NewTask

token = "<your github token>"
task = NewTask('git-comment', handler=run_summary_comment)
task.with_params(workflow_id='57e00382-6d43-4e14-a370-5f8e81fc0c19', repo='yaronha/tstactions', issue=2, project='sk-project')
task.with_secrets('inline', {'GITHUB_TOKEN': token})

run_local(task)
[mlrun] 2020-05-10 10:30:55,894 starting run git-comment uid=ef006abc3d1242528b5a78da5d8ef5fd  -> http://10.199.227.162:8080
errors: 0
project uid iter start state name labels inputs parameters results artifacts
default 0 May 10 10:30:55 completed git-comment
v3io_user=admin
kind=handler
owner=admin
host=jupyter-65887d7ffb-5jsn2
workflow_id=57e00382-6d43-4e14-a370-5f8e81fc0c19
repo=yaronha/tstactions
issue=2
project=sk-project
to track results use .show() or .logs() or in CLI: 
!mlrun get run ef006abc3d1242528b5a78da5d8ef5fd --project default , !mlrun logs ef006abc3d1242528b5a78da5d8ef5fd --project default
[mlrun] 2020-05-10 10:30:59,008 run executed, status=completed
<mlrun.model.RunObject at 0x7f1dc44aae10>