コード例 #1
0
ファイル: cancelflow.py プロジェクト: bbhunter/Bludger
def cancelWorkflow(slug: str, template: str):
    '''
    Cancels a workflow run for the template supplied
    '''
    global baseurl, runsurl
    log = logging.getLogger('cancelFlow')

    if not template or not slug:
        log.error('One or more required parameters got passed invalid params.')
        return None

    template = '{}.yml'.format(template)
    runsurl = runsurl.format(slug, template)
    req = sendQuery("GET", runsurl, params=None)

    if req is not None:
        runid = req.json()['workflow_runs'][0]['id']
        baseurl = baseurl.format(slug, runid)

        req = sendQuery("POST", baseurl, json=None)
        if req is not None:
            print(G,
                  'Successfully requested a cancel for workflow: %s' % runid)
            return True

        else:
            log.fatal('Could not canel the workflow. Something went wrong!')
            sys.exit(1)
コード例 #2
0
ファイル: deleteflow.py プロジェクト: bbhunter/Bludger
def deleteFlow(slug: str, template: str, path='.github/workflows/'):
    '''
    Deletes a workflow for the authenticated user
    '''
    global baseurl
    log = logging.getLogger('deleteFlow')

    if not slug:
        log.error('One or more required parameters got passed invalid params.')
        return None

    template = '%s.yml' % template
    wholepath = os.path.join(path, template)
    baseurl = baseurl.format(slug, wholepath)

    log.debug('Getting SHA of the file...')
    req = sendQuery("GET", baseurl, params=None)

    if req is not None:
        sha = req.json()['sha']
        log.info('Received file SHA: %s' % sha)
        log.info('Trying to delete the file: %s' % wholepath)

        payload = {'message': 'Deleting %s' % wholepath, 'sha': sha}

        req = sendQuery("DELETE", baseurl, json=payload)

        if req is not None:
            print(G, 'Successfully deleted the workflow: %s' % wholepath)
            return True
        else:
            log.fatal('File deletion failed. Stopping all processes.')
            sys.exit(1)
コード例 #3
0
def triggerWorkflow(slug: str, template: bool):
    '''
    Creates a workflow run for the authenticated user
    '''
    global baseurl
    log = logging.getLogger('triggerFlow')

    if not template or not slug:
        log.error('One or more required parameters got passed invalid params.')
        return None

    template = '{}.yml'.format(template)
    baseurl = baseurl.format(slug, template)

    payload = {
        "ref" : "master"
    }
    log.debug('Sending payload: %s' % payload)

    # pause for a few seconds, otheriwse github api gives out a 404
    log.warning("Pausing for a few seconds to prevent race condition between API endpoints...")
    time.sleep(10)

    # github REST API is extrememly buggy about the name conventions
    # between the master and main, although they are the same thing
    # useless bullshit in my opinion.
    req = sendQuery("POST", baseurl, json=payload)
    if req is not None:
        print(G, 'Successfully triggered a workflow for: %s' % template)
        return True

    else:
        log.critical('Couldn\'t trigger a workflow! Ref seems to be messing up.')
        log.info('Retrying the request with different ref: master')
        # retry the request using ref as master instead of main
        # usually returns a 422 unprocessable identity
        payload = {
            "ref" : "main"
        }
        log.debug('Sending payload: %s' % payload)

        req = sendQuery("POST", baseurl, json=payload)
        if req is not None:
            print(G, 'Successfully triggered a workflow for: %s' % template)
            return True
        else:
            log.fatal('Could not trigger a workflow. Something went wrong!')
            sys.exit(1)
コード例 #4
0
ファイル: createrepo.py プロジェクト: bbhunter/Bludger
def createRepo(reponame: str, isprivate: bool):
    '''
    Creates a repository for the authenticated user
    '''
    log = logging.getLogger('createRepo')

    if not reponame or not isprivate:
        log.error('One or more required parameters got passed invalid params.')
        return None

    log.info('Trying to create the repository...')

    payload = {
        "name": reponame,
        "description": "My Custom Automation Setup",
        "private": isprivate,
    }

    req = sendQuery("POST", baseurl, json=payload)
    if req is not None:
        print(G, 'Successfully created: %s' % req.json()['html_url'])
        log.debug('Repo ID: ' + str(req.json()['id']) + ' | Repo URL: ' +
                  req.json()['html_url'])
        return req.json()['full_name']
    else:
        log.info(
            'Another repository with the same name already exists on your account! Deleting it with --delete flag and trying again.'
        )
        log.fatal('Repository creation failed. Stopping all processes.')
        sys.exit(1)
コード例 #5
0
ファイル: getlogs.py プロジェクト: bbhunter/Bludger
def getLogs(url: str, path: str):
    '''
    Grabs the logs for a run and saves it to a directory
    '''
    log = logging.getLogger('getLogs')

    if not url and not path:
        log.error('One or more required parameters got passed invalid params.')
        return None

    if not os.path.exists(path):
        log.error('Path %s doesn\'t exist on your filesystem.' % path)
        log.info('Creating the dir: %s' % path)
        os.makedirs(path)

    log.info('Trying to download the logs...')
    req = sendQuery("GET", url, redirection=True, stream=True, params=None)
    if req is not None:
        try:
            filename = re.search(r'(?i)filename=([^;]+)',
                                 req.headers['content-disposition'])
            log.info('Inflating the zipped logs: %s' % filename.group(1))

            zipf = zipfile.ZipFile(io.BytesIO(req.content))
            zipf.extractall(path)

            print(G, 'Successfully saved all logs to: %s' % path)

        except Exception as e:
            log.error('Error: %s' % e.__str__())

    return None
コード例 #6
0
def deleteRepo(slug: str):
    '''
    Deletes a repository for the authenticated user
    '''
    global baseurl
    log = logging.getLogger('deleteRepo')

    if not slug:
        log.error('One or more required parameters got passed invalid params.')
        return None

    log.info('Trying to delete the repository: %s' % slug)
    baseurl = baseurl.format(slug)
    req = sendQuery("DELETE", baseurl, json=None)

    if req is not None:
        print(G, 'Successfully deleted the repository: %s' % slug)
        return True
    else:
        log.fatal('Repository deletion failed. Stopping all processes.')
        sys.exit(1)
コード例 #7
0
ファイル: commitfile.py プロジェクト: bbhunter/Bludger
def commitFile(file: str, path: str, repo: str):
    '''
    Commits a file to the GitHub Repository
    '''
    global baseurl
    log = logging.getLogger('commitFile')

    if path is not None:
        path = '.github/workflows/{}.yml'.format(path)
        log.debug('Target file to create: %s' % path)
    else:
        path = '.github/workflows/{}.yml'.format('default')
        with open('templates/default.yml', 'r') as rf:
            file = rf.read()

    baseurl = baseurl.format(repo, path)

    log.debug('Encoding the file to base64.')
    file64 = base64.b64encode(file.encode('ascii'))
    file64msg = file64.decode('ascii')

    log.debug('Content to commit: %s' % file64msg)

    payload = {
        "content": file64msg,
        "message": 'Added workflow file',
    }

    log.debug('Trying to create the file...')
    req = sendQuery("PUT", baseurl, json=payload)

    if req is not None:
        print(G, 'File successfully committed to GitHub: %s' % path)
        return True

    return False
コード例 #8
0
def checkRun(slug: str, template: str, path=None):
    '''
    Checks workflow status of a template
    '''
    global runsurl, jobsurl, logsurl
    log = logging.getLogger('checkRun')

    # Pause for a few seconds for the workflow to actually trigger
    log.info('Pausing for a few seconds for the workflow to trigger...')
    time.sleep(10)

    template = '%s.yml' % template
    runsurl = runsurl.format(slug, template)

    req = sendQuery("GET", runsurl, params=None)

    if req is not None:
        # get the last workflow run
        # retry for one more time if the API doesn't give a valid response
        while True:
            if len(req.json()['workflow_runs']) == 0:
                log.debug('Waiting for workflow to trigger...')
                time.sleep(10)
                req = sendQuery("GET", runsurl, params=None)
            else:
                break

        jobid = req.json()['workflow_runs'][0]['id']
        print(G, 'Job ID:', jobid)
        jobsurl = jobsurl.format(slug, jobid)
        logsurl = req.json()['workflow_runs'][0]['logs_url']
        log.debug('Jobs URL: %s' % jobsurl)
        log.debug('Logs URL: %s' % logsurl)

        # continuously monitor the workflow for completion
        while True:
            req = sendQuery("GET", jobsurl, params=None)

            if req is not None:
                if req.json()['jobs'][0]['status'] == "completed":
                    print(G, 'Job seems to have successfully completed!')
                    break
                else:
                    log.debug('Workflow not completed yet.')

                    laststep = None
                    for step in req.json()['jobs'][0]['steps']:
                        if step['status'] == 'completed':
                            laststep = step['name']

                    print(GR, 'Last step executed: %s' % laststep)
                    log.debug('Pausing for 7 seconds before checking again...')
                    time.sleep(7)
                    continue

        if req.json()['jobs'][0]['conclusion'] != "success":
            log.error('Job completed but errored out!')
            log.error('Visit: %s for more information' %
                      req.json()['jobs'][0]['html_url'])

        if path is not None:
            # fetch the logs now
            #logsurl = logsurl.format(slug, jobid)
            getLogs(logsurl, path)