Пример #1
0
 def execute(self, context):
     hook = CloudBuildHook(gcp_conn_id=self.gcp_conn_id, impersonation_chain=self.impersonation_chain)
     result = hook.cancel_build(
         id_=self.id_,
         project_id=self.project_id,
         retry=self.retry,
         timeout=self.timeout,
         metadata=self.metadata,
     )
     return Build.to_dict(result)
Пример #2
0
    def process_body(self) -> Build:
        """
        Processes the body passed in the constructor

        :return: the body.
        :rtype: `google.cloud.devtools.cloudbuild_v1.types.Build`
        """
        if 'source' in self.build:
            self._verify_source()
            self._reformat_source()
        return Build(self.build)
Пример #3
0
 def execute(self, context):
     hook = CloudBuildHook(gcp_conn_id=self.gcp_conn_id, impersonation_chain=self.impersonation_chain)
     result = hook.run_build_trigger(
         trigger_id=self.trigger_id,
         source=self.source,
         project_id=self.project_id,
         wait=self.wait,
         retry=self.retry,
         timeout=self.timeout,
         metadata=self.metadata,
     )
     return Build.to_dict(result)
Пример #4
0
 def execute(self, context):
     hook = CloudBuildHook(gcp_conn_id=self.gcp_conn_id, impersonation_chain=self.impersonation_chain)
     results = hook.list_builds(
         project_id=self.project_id,
         location=self.location,
         page_size=self.page_size,
         filter_=self.filter_,
         retry=self.retry,
         timeout=self.timeout,
         metadata=self.metadata,
     )
     return [Build.to_dict(result) for result in results]
Пример #5
0
    def execute(self, context):
        hook = CloudBuildHook(gcp_conn_id=self.gcp_conn_id, impersonation_chain=self.impersonation_chain)

        build = BuildProcessor(build=self.build).process_body()

        result = hook.create_build(
            build=build,
            project_id=self.project_id,
            wait=self.wait,
            retry=self.retry,
            timeout=self.timeout,
            metadata=self.metadata,
        )
        return Build.to_dict(result)
Пример #6
0
def main(event, context):
    """ Triggers a new downstream build based on a PubSub message originating from a parent cloudbuild """
    # if cloud build project is not set, exit
    if not os.getenv('CLOUDBUILD_PROJECT'):
        logging.warn('Cloud Build project not set')
        sys.exit(1)
    # if no data in PubSub event, log and exit
    if 'data' not in event:
        logging.info('Unable to find data in PubSub event')
        sys.exit(1)
    # decode data in PubSub event
    data = json.loads(base64.b64decode(event['data']).decode('utf-8'))
    # if the parent build originated from CF, ignore
    if data['substitutions'].get('_IS_TRIGGERED_BY_CF', False):
        logging.warn('Triggered by CF, Ignoring')
        return
    logging.info('Parent build not triggered by CF')
    # if parent build is not a lint build, ignore
    if 'lint' not in data['tags']:
        logging.warn('Parent build is not a lint build')
        return
    # if parent build has not started, or is in any other state, ignore
    if data['status'] != 'WORKING':
        logging.warn('Parent build is not in WORKING status')
        return
    logging.info('Parent build is in WORKING status')
    # if repo ref for the parent build has not enabled PR bot, ignore
    if data['substitutions']['REPO_NAME'] not in ENABLED_MODULES:
        logging.warn('Not a supported repo')
        return
    if data['substitutions'].get('_DOCKER_TAG_VERSION_DEVELOPER_TOOLS', False):
        logging.info(
            f'Found _DOCKER_TAG_VERSION_DEVELOPER_TOOLS. Setting tools image version to {data["substitutions"]["_DOCKER_TAG_VERSION_DEVELOPER_TOOLS"]}'
        )
        CFT_TOOLS_DEFAULT_IMAGE_VERSION = data['substitutions'][
            '_DOCKER_TAG_VERSION_DEVELOPER_TOOLS']
    # Cloud Build seems to have a bug where if a build is re run through Github UI, it will not set _PR_NUMBER or _HEAD_REPO_URL
    # workaround using the GH API to infer PR number and _HEAD_REPO_URL
    PR_NUMBER = data['substitutions'].get('_PR_NUMBER', False)
    _HEAD_REPO_URL = data['substitutions'].get('_HEAD_REPO_URL', False)
    # default clone repo step
    get_repo_args = [
        '-c',
        'git clone $$REPO_URL && cd $$REPO_NAME && git checkout $$COMMIT_SHA && git status',
    ]
    if not (PR_NUMBER or _HEAD_REPO_URL):
        logging.warn(
            'Unable to infer PR number via Cloud Build. Trying via GH API')
        # get list of github PRs that have this SHA
        response = requests.get(
            f'https://api.github.com/search/issues?q={data["substitutions"]["COMMIT_SHA"]}'
        )
        response.raise_for_status()
        response_obj = response.json()
        # if more than one PR, ignore
        if response_obj['total_count'] != 1:
            logging.info(f'Multiple associated PRs found. Exiting...')
            return
        # if only one PR, its safe to assume that is associated with parent build's PR
        logging.info(
            f'One associated PR found: {response_obj["items"][0]["number"]}')
        PR_NUMBER = response_obj['items'][0]['number']
        # get target repo URL
        pr_url = response_obj['items'][0]['html_url']
        _HEAD_REPO_URL = pr_url[:pr_url.find('/pull')]
        # fetch PR at head using PR number
        get_repo_args = [
            '-c',
            'git clone $$REPO_URL && cd $$REPO_NAME && git fetch origin pull/$$_PR_NUMBER/head:$$_PR_NUMBER && git checkout $$_PR_NUMBER && git show --name-only',
        ]

    # prepare env vars
    env = [
        f'_PR_NUMBER={PR_NUMBER}',
        f'REPO_NAME={data["substitutions"]["REPO_NAME"]}',
        f'REPO_URL={_HEAD_REPO_URL}',
        f'COMMIT_SHA={data["substitutions"]["COMMIT_SHA"]}',
    ]
    get_repo_step = BuildStep(
        name='gcr.io/cloud-builders/git',
        env=env,
        args=get_repo_args,
        id='get_repo',
        entrypoint='bash',
    )
    # lint comment step
    lint_args = [
        '-c',
        'source /usr/local/bin/task_helper_functions.sh && printenv && post_lint_status_pr_comment',
    ]
    lint_step = BuildStep(
        name=f'{CFT_TOOLS_DEFAULT_IMAGE}:{CFT_TOOLS_DEFAULT_IMAGE_VERSION}',
        env=env,
        args=lint_args,
        id='lint_comment',
        entrypoint='/bin/bash',
    )
    # substitutions
    sub = {
        '_IS_TRIGGERED_BY_CF': '1',
    }
    # create and trigger build
    build = Build(
        steps=[get_repo_step, lint_step],
        options=BuildOptions(substitution_option='ALLOW_LOOSE'),
        substitutions=sub,
    )
    response = cloudbuild().create_build(os.getenv('CLOUDBUILD_PROJECT'),
                                         build)
    logging.info(response)
Пример #7
0
 def __init__(self, build: Union[Dict, Build]) -> None:
     if isinstance(build, Build):
         self.build = Build(build)
     self.build = deepcopy(build)