Пример #1
0
    def _init_scratch_org(self, org_config):
        if not org_config.scratch:
            # Only run against scratch orgs
            return

        # Set up the logger to output to the build.log field
        init_logger(self.build)

        # Create the scratch org and get its info
        info = org_config.scratch_info

        org_json = json.dumps(org_config.config, cls=DjangoJSONEncoder)

        # Create a ScratchOrgInstance to store the org info
        instance = ScratchOrgInstance(
            org=org_config.org,
            build=self.build,
            sf_org_id=info["org_id"],
            username=info["username"],
            json=org_json,
            expiration_date=org_config.expires,
        )
        instance.save()
        org_config.org_instance = instance

        return org_config
Пример #2
0
 def get_org(self, project_config, retries=3):
     self.logger = init_logger(self)
     attempt = 1
     if self.org:
         # If the build's org was already set, keep using it
         org_name = self.org.name
     else:
         org_name = self.plan.org
     while True:
         try:
             org_config = project_config.keychain.get_org(org_name)
             break
         except ScratchOrgException as e:
             if (str(e).startswith(FAILED_TO_CREATE_SCRATCH_ORG)
                     and attempt <= retries):
                 self.logger.warning(str(e))
                 self.logger.info(
                     "Retrying create scratch org " +
                     "(retry {} of {})".format(attempt, retries))
                 attempt += 1
                 continue
             else:
                 raise e
     self.org = org_config.org
     if self.current_rebuild:
         self.current_rebuild.org_instance = org_config.org_instance
         self.current_rebuild.save()
     else:
         self.org_instance = org_config.org_instance
     self.save()
     return org_config
Пример #3
0
    def delete_org(self, org_config):
        self.logger = init_logger(self)
        if not org_config.scratch:
            return
        if self.keep_org:
            self.logger.info(
                "Skipping scratch org deletion since keep_org was requested")
            return
        if self.status == "error" and self.plan.keep_org_on_error:
            self.logger.info(
                "Skipping scratch org deletion since keep_org_on_error is enabled"
            )
            return
        if self.status == "fail" and self.plan.keep_org_on_fail:
            self.logger.info(
                "Skipping scratch org deletion since keep_org_on_fail is enabled"
            )
            return

        try:
            org_instance = self.get_org_instance()
            org_instance.delete_org(org_config)
        except Exception as e:
            self.logger.error(str(e))
            self.save()
Пример #4
0
 def get_org(self, project_config, retries=3):
     self.logger = init_logger(self)
     attempt = 1
     while True:
         try:
             org_config = project_config.keychain.get_org(self.plan.org)
             break
         except ScratchOrgException as e:
             if (e.message.startswith(FAILED_TO_CREATE_SCRATCH_ORG)
                     and attempt <= retries):
                 self.logger.warning(e.message)
                 self.logger.info(
                     'Retrying create scratch org ' +
                     '(retry {} of {})'.format(attempt, retries))
                 attempt += 1
                 continue
             else:
                 raise e
     self.org = org_config.org
     if self.current_rebuild:
         self.current_rebuild.org_instance = org_config.org_instance
         self.current_rebuild.save()
     else:
         self.org_instance = org_config.org_instance
     self.save()
     return org_config
Пример #5
0
 def delete_org(self, org_config):
     self.logger = init_logger(self)
     if not org_config.scratch:
         return
     if self.keep_org:
         self.logger.info(
             'Skipping scratch org deletion since keep_org was requested')
         return
     try:
         org_instance = self.get_org_instance()
         org_instance.delete_org(org_config)
     except Exception as e:
         self.logger.error(str(e))
         self.save()
Пример #6
0
    def run(self, project_config, org_config):
        # Record the start
        set_build_info(self, status='running', time_start=timezone.now())

        # Set up logger
        self.logger = init_logger(self)

        try:
            # Run the flow
            result = self.run_flow(project_config, org_config)

            # Load test results
            self.load_test_results()

            # Record result
            exception = None
            status = 'success'

        except MetadataComponentFailure as e:
            exception = e
            status = 'fail'

        except ApexTestException as e:
            exception = e
            self.load_test_results()
            status = 'fail'

        except BrowserTestFailure as e:
            exception = e
            self.load_test_results()
            status = 'fail'

        except Exception as e:
            exception = e
            status = 'error'

        kwargs = {
            'status': status,
            'time_end': timezone.now(),
        }
        if exception:
            if status == 'error':
                self.logger.error(unicode(e))
            kwargs['error_message'] = unicode(e)
            kwargs['exception'] = e.__class__.__name__
        set_build_info(self, **kwargs)
Пример #7
0
    def run(self, project_config, org_config, root_dir):
        self.root_dir = root_dir
        # Record the start
        set_build_info(self, status="running", time_start=timezone.now())

        # Update github status
        if settings.GITHUB_STATUS_UPDATES_ENABLED:
            set_github_status.delay(self.build_id)

        # Set up logger
        self.logger = init_logger(self)

        try:
            # Run the flow
            self.run_flow(project_config, org_config)

            # Determine build commit status
            self.set_commit_status()

            # Load test results
            self.load_test_results()

            # Record result
            exception = None
            status = "success"

        except FAIL_EXCEPTIONS as e:
            self.logger.error(traceback.format_exc())
            exception = e
            self.load_test_results()
            status = "fail"

        except Exception as e:
            self.logger.error(traceback.format_exc())
            exception = e
            status = "error"

        kwargs = {"status": status, "time_end": timezone.now()}
        if exception:
            kwargs["error_message"] = str(exception)
            kwargs["exception"] = exception.__class__.__name__
            kwargs["traceback"] = "".join(
                traceback.format_tb(exception.__traceback__))
        set_build_info(self, **kwargs)
Пример #8
0
    def run(self, project_config, org_config, root_dir):
        self.root_dir = root_dir
        # Record the start
        set_build_info(self, status='running', time_start=timezone.now())

        # Update github status
        if settings.GITHUB_STATUS_UPDATES_ENABLED:
            set_github_status.delay(self.build_id)

        # Set up logger
        self.logger = init_logger(self)

        try:
            # Run the flow
            result = self.run_flow(project_config, org_config)

            # Load test results
            self.load_test_results()

            # Record result
            exception = None
            status = 'success'

        except FAIL_EXCEPTIONS as e:
            exception = e
            self.load_test_results()
            status = 'fail'

        except Exception as e:
            exception = e
            status = 'error'

        kwargs = {
            'status': status,
            'time_end': timezone.now(),
        }
        if exception:
            if status == 'error':
                self.logger.error(str(exception))
            kwargs['error_message'] = str(exception)
            kwargs['exception'] = exception.__class__.__name__
            kwargs['traceback'] = ''.join(
                traceback.format_tb(exception.__traceback__))
        set_build_info(self, **kwargs)
Пример #9
0
    def run(self):
        self.logger = init_logger(self)
        worker_str = f"in {self.worker_id}" if self.worker_id else ""
        self.logger.info(
            f"-- Building commit {self.commit} {worker_str} with CumulusCI version {cumulusci_version}"
        )
        self.flush_log()
        build = self.current_rebuild if self.current_rebuild else self
        set_build_info(build, status="running", time_start=timezone.now())

        if self.schedule:
            self.logger.info("Build triggered by {} schedule #{}".format(
                self.schedule.schedule, self.schedule.id))

        try:
            # Extract the repo to a temp build dir
            self.build_dir = self.checkout()
            self.root_dir = os.getcwd()

            # Change directory to the build_dir
            os.chdir(self.build_dir)

            # Initialize the project config
            project_config = self.get_project_config()

            # Set the sentry context for build errors
            sentry_environment = "metaci"
            project_config.config["sentry_environment"] = sentry_environment

            # Look up or spin up the org
            org_config = self.get_org(project_config)

        except Exception as e:
            self.logger.error(str(e))
            set_build_info(
                build,
                status="error",
                time_end=timezone.now(),
                error_message=str(e),
                exception=e.__class__.__name__,
                traceback="".join(traceback.format_tb(e.__traceback__)),
            )
            self.delete_build_dir()
            self.flush_log()
            return

        try:
            self.org_api_version = org_config.latest_api_version
        except Exception as e:
            self.logger.warn(f"Could not retrieve salesforce API version: {e}")

        # Run flows
        try:
            flows = [flow.strip() for flow in self.plan.flows.split(",")]
            for flow in flows:
                self.logger = init_logger(self)
                self.logger.info("Running flow: {}".format(flow))
                self.save()

                build_flow = BuildFlow(build=self,
                                       rebuild=self.current_rebuild,
                                       flow=flow)
                build_flow.save()
                build_flow.run(project_config, org_config, self.root_dir)

                if build_flow.status != "success":
                    self.logger = init_logger(self)
                    self.logger.error(
                        "Build flow {} completed with status {}".format(
                            flow, build_flow.status))
                    self.logger.error("    {}: {}".format(
                        build_flow.exception, build_flow.error_message))
                    set_build_info(
                        build,
                        status=build_flow.status,
                        exception=build_flow.exception,
                        traceback=build_flow.traceback,
                        error_message=build_flow.error_message,
                        time_end=timezone.now(),
                    )
                    self.flush_log()
                    if org_config.created:
                        self.delete_org(org_config)
                    return
                else:
                    self.logger = init_logger(self)
                    self.logger.info(
                        "Build flow {} completed successfully".format(flow))
                    self.flush_log()
                    self.save()

        except Exception as e:
            set_build_info(
                build,
                exception=str(e),
                traceback="".join(traceback.format_tb(e.__traceback__)),
                status="error",
                time_end=timezone.now(),
            )
            if org_config.created:
                self.delete_org(org_config)
            self.logger = init_logger(self)
            self.logger.error(str(e))
            self.delete_build_dir()
            self.flush_log()
            return

        if self.plan.role == "release":
            send_release_webhook(project_config, self.release)

        if self.plan.role == "qa":
            self.logger.info("Build complete, org is now ready for QA testing")
        elif org_config.created:
            self.delete_org(org_config)

        self.delete_build_dir()
        self.flush_log()

        if self.plan.role == "qa":
            set_build_info(
                build,
                status="qa",
                time_end=timezone.now(),
                time_qa_start=timezone.now(),
            )
        else:
            set_build_info(build, status="success", time_end=timezone.now())
Пример #10
0
    def run(self):
        self.logger = init_logger(self)
        self.logger.info('-- Building commit {}'.format(self.commit))
        self.flush_log()
        build = self.current_rebuild if self.current_rebuild else self
        set_build_info(build, status='running', time_start=timezone.now())

        try:
            # Extract the repo to a temp build dir
            self.build_dir = self.checkout()
            self.root_dir = os.getcwd()

            # Change directory to the build_dir
            os.chdir(self.build_dir)

            # Initialize the project config
            project_config = self.get_project_config()

            # Set the sentry context for build errors
            sentry_environment = 'metaci'
            project_config.config['sentry_environment'] = sentry_environment

            # Look up the org
            org_config = self.get_org(project_config)

        except Exception as e:
            self.logger.error(str(e))
            set_build_info(build, status='error', time_end=timezone.now())
            self.delete_build_dir()
            self.flush_log()
            return

        # Run flows
        try:
            flows = [flow.strip() for flow in self.plan.flows.split(',')]
            for flow in flows:
                self.logger = init_logger(self)
                self.logger.info('Running flow: {}'.format(flow))
                self.save()

                build_flow = BuildFlow(
                    build=self,
                    rebuild=self.current_rebuild,
                    flow=flow,
                )
                build_flow.save()
                build_flow.run(project_config, org_config, self.root_dir)

                if build_flow.status != 'success':
                    self.logger = init_logger(self)
                    self.logger.error(
                        'Build flow {} completed with status {}'.format(
                            flow, build_flow.status))
                    self.logger.error('    {}: {}'.format(
                        build_flow.exception, build_flow.error_message))
                    set_build_info(
                        build,
                        status=build_flow.status,
                        exception=build_flow.exception,
                        traceback=build_flow.traceback,
                        error_message=build_flow.error_message,
                        time_end=timezone.now(),
                    )
                    self.flush_log()
                    if org_config.created:
                        self.delete_org(org_config)
                    return
                else:
                    self.logger = init_logger(self)
                    self.logger.info(
                        'Build flow {} completed successfully'.format(flow))
                    self.flush_log()
                    self.save()

        except Exception as e:
            set_build_info(
                build,
                exception=str(e),
                traceback=''.join(traceback.format_tb(e.__traceback__)),
                status='error',
                time_end=timezone.now(),
            )
            if org_config.created:
                self.delete_org(org_config)
            self.logger = init_logger(self)
            self.logger.error(str(e))
            self.delete_build_dir()
            self.flush_log()
            return

        if self.plan.role == 'qa':
            self.logger.info('Build complete, org is now ready for QA testing')
        elif org_config.created:
            self.delete_org(org_config)

        self.delete_build_dir()
        self.flush_log()

        if self.plan.role == 'qa':
            set_build_info(
                build,
                status='qa',
                time_end=timezone.now(),
                time_qa_start=timezone.now(),
            )
        else:
            set_build_info(build, status='success', time_end=timezone.now())
Пример #11
0
    def run(self):
        self.logger = init_logger(self)
        self.logger.info('-- Building commit {}'.format(self.commit))
        self.flush_log()
        build = self.current_rebuild if self.current_rebuild else self
        set_build_info(build, status='running', time_start=timezone.now())

        if self.schedule:
            self.logger.info('Build triggered by {} schedule #{}'.format(
                self.schedule.schedule, self.schedule.id))

        try:
            # Extract the repo to a temp build dir
            self.build_dir = self.checkout()

            # Change directory to the build_dir
            os.chdir(self.build_dir)

            # Initialize the project config
            project_config = self.get_project_config()

            # Set the sentry context for build errors
            sentry_environment = 'metaci'
            project_config.config['sentry_environment'] = sentry_environment

            # Look up the org
            org_config = self.get_org(project_config)

        except Exception as e:
            self.logger.error(unicode(e))
            set_build_info(build, status='error', time_end=timezone.now())
            self.delete_build_dir()
            self.flush_log()
            return

        # Run flows
        try:
            flows = [flow.strip() for flow in self.plan.flows.split(',')]
            for flow in flows:
                self.logger = init_logger(self)
                self.logger.info('Running flow: {}'.format(flow))
                self.save()

                build_flow = BuildFlow(
                    build=self,
                    rebuild=self.current_rebuild,
                    flow=flow,
                )
                build_flow.save()
                build_flow.run(project_config, org_config)

                if build_flow.status != 'success':
                    self.logger = init_logger(self)
                    self.logger.error(
                        'Build flow {} completed with status {}'.format(
                            flow, build_flow.status))
                    self.logger.error('    {}: {}'.format(build_flow.exception,
                                                          build_flow.error_message))
                    set_build_info(
                        build,
                        status=build_flow.status,
                        exception=build_flow.exception,
                        error_message=build_flow.error_message,
                        time_end=timezone.now(),
                    )
                    self.flush_log()
                    if org_config.created:
                        self.delete_org(org_config)
                    return
                else:
                    self.logger = init_logger(self)
                    self.logger.info(
                        'Build flow {} completed successfully'.format(
                            flow))
                    self.flush_log()
                    self.save()

        except Exception as e:
            set_build_info(build, status='error', time_end=timezone.now())
            if org_config.created:
                self.delete_org(org_config)
            self.logger = init_logger(self)
            self.logger.error(unicode(e))
            self.delete_build_dir()
            self.flush_log()
            return

        if org_config.created:
            self.delete_org(org_config)

        self.delete_build_dir()
        self.flush_log()
        set_build_info(build, status='success', time_end=timezone.now())