def test_get_copr_build(clean_before_and_after, a_copr_build_for_pr):
    assert a_copr_build_for_pr.id
    b = CoprBuildModel.get_by_build_id(a_copr_build_for_pr.build_id, TARGET)
    assert b.id == a_copr_build_for_pr.id
    # let's make sure passing int works as well
    b = CoprBuildModel.get_by_build_id(int(a_copr_build_for_pr.build_id), TARGET)
    assert b.id == a_copr_build_for_pr.id
    b2 = CoprBuildModel.get_by_id(b.id)
    assert b2.id == a_copr_build_for_pr.id
def test_get_by_build_id(clean_before_and_after, multiple_copr_builds):
    # these are not iterable and thus should be accessible directly
    build_a = CoprBuildModel.get_by_build_id(str(123456), "fedora-42-x86_64")
    assert build_a.project_name == "SomeUser-hello-world-9"
    assert build_a.target == "fedora-42-x86_64"
    build_b = CoprBuildModel.get_by_build_id(str(123456), "fedora-43-x86_64")
    assert build_b.project_name == "SomeUser-hello-world-9"
    assert build_b.target == "fedora-43-x86_64"
    build_c = CoprBuildModel.get_by_build_id(str(987654), "fedora-43-x86_64")
    assert build_c.project_name == "SomeUser-random-text-7"
Example #3
0
def test_get_by_build_id(clean_before_and_after, multiple_copr_builds):
    # these are not iterable and thus should be accessible directly
    build_a = CoprBuildModel.get_by_build_id(SampleValues.build_id,
                                             SampleValues.target)
    assert build_a.project_name == "the-project-name"
    assert build_a.target == "fedora-42-x86_64"
    build_b = CoprBuildModel.get_by_build_id(SampleValues.build_id,
                                             SampleValues.different_target)
    assert build_b.project_name == "the-project-name"
    assert build_b.target == "fedora-43-x86_64"
    build_c = CoprBuildModel.get_by_build_id(SampleValues.different_build_id,
                                             SampleValues.target)
    assert build_c.project_name == "different-project-name"
Example #4
0
 def _payload_install_test(self, build_id: int, chroot: str) -> dict:
     """
     If the project doesn't use fmf, but still wants to run tests in TF.
     TF provides 'installation test', we request it in ['test']['fmf']['url'].
     We don't specify 'artifacts' as in _payload(), but 'variables'.
     """
     copr_build = CoprBuildModel.get_by_build_id(build_id)
     compose, arch = self.get_compose_arch(chroot)
     return {
         "api_key": self.service_config.testing_farm_secret,
         "test": {
             "fmf": {
                 "url": TESTING_FARM_INSTALLABILITY_TEST_URL,
             },
         },
         "environments": [
             {
                 "arch": arch,
                 "os": {"compose": compose},
                 "variables": {
                     "REPOSITORY": f"{copr_build.owner}/{copr_build.project_name}",
                 },
             }
         ],
         "notification": {
             "webhook": {
                 "url": f"{self.api_url}/testing-farm/results",
                 "token": self.service_config.testing_farm_secret,
             },
         },
     }
Example #5
0
def test_copr_build_set_status(clean_before_and_after, a_copr_build_for_pr):
    assert a_copr_build_for_pr.status == "pending"
    a_copr_build_for_pr.set_status("awesome")
    assert a_copr_build_for_pr.status == "awesome"
    b = CoprBuildModel.get_by_build_id(a_copr_build_for_pr.build_id,
                                       SampleValues.target)
    assert b.status == "awesome"
Example #6
0
 def from_build_id(
     cls,
     topic: str,
     build_id: int,
     chroot: str,
     status: int,
     owner: str,
     project_name: str,
     pkg: str,
 ) -> Optional["CoprBuildEvent"]:
     """ Return cls instance or None if build_id not in CoprBuildDB"""
     build = CoprBuildModel.get_by_build_id(str(build_id), chroot)
     if not build:
         logger.warning(f"Build id: {build_id} not in CoprBuildDB")
         return None
     return cls(
         topic,
         build_id,
         build,
         chroot,
         status,
         owner,
         project_name,
         pkg,
     )
    def run(self):
        if self.event.chroot == "srpm-builds":
            # we don't want to set the check status for this
            msg = "SRPM build in copr has started"
            logger.debug(msg)
            return HandlerResults(success=True, details={"msg": msg})

        # TODO: drop the code below once we move to PG completely; the build is present in event
        # pg
        build = CoprBuildModel.get_by_build_id(str(self.event.build_id),
                                               self.event.chroot)
        if not build:
            msg = f"Copr build {self.event.build_id} not in CoprBuildDB"
            logger.warning(msg)
            return HandlerResults(success=False, details={"msg": msg})

        url = get_log_url(build.id)
        build.set_status("pending")
        copr_build_logs = get_copr_build_logs_url(self.event)
        build.set_build_logs_url(copr_build_logs)

        self.build_job_helper.report_status_to_all_for_chroot(
            description="RPM build has started...",
            state=CommitStatus.pending,
            url=url,
            chroot=self.event.chroot,
        )
        msg = f"Build on {self.event.chroot} in copr has started..."
        return HandlerResults(success=True, details={"msg": msg})
Example #8
0
    def get(self):
        """ List all Copr builds. """

        # Return relevant info thats concise
        # Usecases like the packit-dashboard copr-builds table

        result = []

        first, last = indices()
        for build in CoprBuildModel.get_merged_chroots(first, last):
            build_info = CoprBuildModel.get_by_build_id(build.build_id, None)
            project_info = build_info.get_project()
            build_dict = {
                "project": build_info.project_name,
                "build_id": build.build_id,
                "status_per_chroot": {},
                "build_submitted_time": optional_time(build_info.build_submitted_time),
                "web_url": build_info.web_url,
                "ref": build_info.commit_sha,
                "pr_id": build_info.get_pr_id(),
                "branch_name": build_info.get_branch_name(),
                "repo_namespace": project_info.namespace,
                "repo_name": project_info.repo_name,
            }

            for count, chroot in enumerate(build.target):
                # [0] because sqlalchemy returns a single element sub-list
                build_dict["status_per_chroot"][chroot[0]] = build.status[count][0]

            result.append(build_dict)

        resp = response_maker(result, status=HTTPStatus.PARTIAL_CONTENT,)
        resp.headers["Content-Range"] = f"copr-builds {first + 1}-{last}/*"
        return resp
Example #9
0
    def from_build_id(
        cls,
        topic: str,
        build_id: int,
        chroot: str,
        status: int,
        owner: str,
        project_name: str,
        pkg: str,
        timestamp,
    ) -> Optional["AbstractCoprBuildEvent"]:
        """Return cls instance or None if build_id not in CoprBuildDB"""
        build: Optional[Union[SRPMBuildModel, CoprBuildModel]]
        if chroot == COPR_SRPM_CHROOT:
            build = SRPMBuildModel.get_by_copr_build_id(str(build_id))
        else:
            build = CoprBuildModel.get_by_build_id(str(build_id), chroot)

        if not build:
            logger.warning(
                f"Build id {build_id} not in "
                f"{'SRPMBuildDB' if chroot == COPR_SRPM_CHROOT else 'CoprBuildDB'}."
            )
            return None

        return cls(topic, build_id, build, chroot, status, owner, project_name,
                   pkg, timestamp)
Example #10
0
def test_copr_build_set_build_logs_url(clean_before_and_after,
                                       a_copr_build_for_pr):
    url = "https://copr.fp.o/logs/12456/build.log"
    a_copr_build_for_pr.set_build_logs_url(url)
    assert a_copr_build_for_pr.build_logs_url == url
    b = CoprBuildModel.get_by_build_id(a_copr_build_for_pr.build_id,
                                       SampleValues.target)
    assert b.build_logs_url == url
Example #11
0
 def build(self):
     if not self._build:
         build_id = str(self.copr_event.build_id)
         if self.copr_event.chroot == COPR_SRPM_CHROOT:
             self._build = SRPMBuildModel.get_by_copr_build_id(build_id)
         else:
             self._build = CoprBuildModel.get_by_build_id(
                 build_id, self.copr_event.chroot)
     return self._build
Example #12
0
def test_get_copr_build(clean_before_and_after, a_copr_build_for_pr):
    assert a_copr_build_for_pr.id

    # pass in a build_id and a target
    b = CoprBuildModel.get_by_build_id(a_copr_build_for_pr.build_id,
                                       SampleValues.target)
    assert b.id == a_copr_build_for_pr.id
    # let's make sure passing int works as well
    b2 = CoprBuildModel.get_by_build_id(int(a_copr_build_for_pr.build_id),
                                        SampleValues.target)
    assert b2.id == a_copr_build_for_pr.id

    # pass in a build_id and without a target
    b3 = CoprBuildModel.get_by_build_id(a_copr_build_for_pr.build_id, None)
    assert b3.commit_sha == a_copr_build_for_pr.commit_sha

    b4 = CoprBuildModel.get_by_id(b.id)
    assert b4.id == a_copr_build_for_pr.id
Example #13
0
def test_copr_build_info_view(client, clean_before_and_after,
                              multiple_copr_builds):
    build = CoprBuildModel.get_by_build_id(123456, SampleValues.chroots[0])
    build.set_build_logs_url(
        "https://copr.somewhere/results/owner/package/target/build.logs")
    response = client.get(url_for("builds.copr_build_info", id_=str(build.id)))
    response = response.data.decode()

    assert "Builds for the-namespace/the-repo-name: PR #342" in response
    assert build.status in response
    assert build.target in response
    assert str(build.srpm_build_id) in response
    assert build.build_logs_url in response
    assert f"Status: {build.status}" in response
    assert "For more info see" in response
    assert "just now" in response
Example #14
0
def test_copr_build_info_view(client, clean_before_and_after,
                              multiple_copr_builds):
    flexmock(models).should_receive("optional_time").and_return(
        "2020-05-19 16:17:14 UTC")

    build = CoprBuildModel.get_by_build_id(123456, SampleValues.chroots[0])
    build.set_build_logs_url(
        "https://copr.somewhere/results/owner/package/target/build.logs")
    response = client.get(url_for("builds.copr_build_info", id_=str(build.id)))
    response = response.data.decode()

    assert "Builds for the-namespace/the-repo-name: PR #342" in response
    assert "2020-05-19 16:17:14 UTC" in response
    assert build.status in response
    assert build.target in response
    assert str(build.srpm_build_id) in response
    assert build.build_logs_url in response
Example #15
0
def test_copr_build_logs_view(client, clean_before_and_after,
                              multiple_copr_builds):
    flexmock(models).should_receive("optional_time").and_return(
        "19/05/2020 16:17:14")

    build = CoprBuildModel.get_by_build_id(123456, SampleValues.chroots[0])
    response = client.get(
        url_for("builds.get_copr_build_logs_by_id", id_=str(build.id)))
    assert response.data.decode() == (
        "<html><head><title>COPR build the-namespace/the-repo-name: "
        "PR #342</title></head><body>COPR build ID: 123456<br>"
        "Submitted: 19/05/2020 16:17:14<br>"
        "State: pending<br><br>"
        "Build web interface URL: "
        '<a href="https://copr.something.somewhere/123456">'
        "https://copr.something.somewhere/123456</a>"
        "<br>SRPM creation logs:<br><br><pre>"
        "some\nboring\nlogs</pre><br></body></html>")
    def run(self):
        build_job_helper = CoprBuildJobHelper(
            config=self.config,
            package_config=self.event.package_config,
            project=self.event.project,
            event=self.event,
        )

        if self.event.chroot == "srpm-builds":
            # we don't want to set the check status for this
            msg = "SRPM build in copr has started."
            logger.debug(msg)
            return HandlerResults(success=True, details={"msg": msg})

        # TODO: drop the code below once we move to PG completely; the build is present in event
        # pg
        build = CoprBuildModel.get_by_build_id(
            str(self.event.build_id), self.event.chroot
        )
        if not build:
            msg = f"Copr build {self.event.build_id} not in CoprBuildDB."
            logger.warning(msg)
            return HandlerResults(success=False, details={"msg": msg})

        start_time = (
            datetime.utcfromtimestamp(self.event.timestamp)
            if self.event.timestamp
            else None
        )
        build.set_start_time(start_time)
        url = get_copr_build_log_url_from_flask(build.id)
        build.set_status("pending")
        copr_build_logs = get_copr_build_logs_url(self.event)
        build.set_build_logs_url(copr_build_logs)

        build_job_helper.report_status_to_all_for_chroot(
            description="RPM build is in progress...",
            state=CommitStatus.pending,
            url=url,
            chroot=self.event.chroot,
        )
        msg = f"Build on {self.event.chroot} in copr has started..."
        return HandlerResults(success=True, details={"msg": msg})
Example #17
0
 def build(self):
     if not self._build:
         self._build = CoprBuildModel.get_by_build_id(
             str(self.copr_event.build_id), self.copr_event.chroot)
     return self._build
    def run(self):
        build_job_helper = CoprBuildJobHelper(
            config=self.config,
            package_config=self.event.package_config,
            project=self.event.project,
            event=self.event,
        )

        if self.event.chroot == "srpm-builds":
            # we don't want to set check for this
            msg = "SRPM build in copr has finished."
            logger.debug(msg)
            return HandlerResults(success=True, details={"msg": msg})
        build = CoprBuildModel.get_by_build_id(
            str(self.event.build_id), self.event.chroot
        )
        if not build:
            # TODO: how could this happen?
            msg = f"Copr build {self.event.build_id} not in CoprBuildDB."
            logger.warning(msg)
            return HandlerResults(success=False, details={"msg": msg})
        if build.status in [
            PG_COPR_BUILD_STATUS_FAILURE,
            PG_COPR_BUILD_STATUS_SUCCESS,
        ]:
            msg = (
                f"Copr build {self.event.build_id} is already"
                f" processed (status={build.status})."
            )
            logger.info(msg)
            return HandlerResults(success=True, details={"msg": msg})

        end_time = (
            datetime.utcfromtimestamp(self.event.timestamp)
            if self.event.timestamp
            else None
        )
        build.set_end_time(end_time)
        url = get_copr_build_log_url_from_flask(build.id)

        # https://pagure.io/copr/copr/blob/master/f/common/copr_common/enums.py#_42
        if self.event.status != COPR_API_SUCC_STATE:
            failed_msg = "RPMs failed to be built."
            build_job_helper.report_status_to_all_for_chroot(
                state=CommitStatus.failure,
                description=failed_msg,
                url=url,
                chroot=self.event.chroot,
            )
            build.set_status(PG_COPR_BUILD_STATUS_FAILURE)
            return HandlerResults(success=False, details={"msg": failed_msg})

        if (
            build_job_helper.job_build
            and build_job_helper.job_build.trigger == JobConfigTriggerType.pull_request
            and self.event.pr_id
            and isinstance(self.event.project, GithubProject)
            and not self.was_last_packit_comment_with_congratulation()
            and self.event.package_config.notifications.pull_request.successful_build
        ):
            msg = (
                f"Congratulations! One of the builds has completed. :champagne:\n\n"
                "You can install the built RPMs by following these steps:\n\n"
                "* `sudo yum install -y dnf-plugins-core` on RHEL 8\n"
                "* `sudo dnf install -y dnf-plugins-core` on Fedora\n"
                f"* `dnf copr enable {self.event.owner}/{self.event.project_name}`\n"
                "* And now you can install the packages.\n"
                "\nPlease note that the RPMs should be used only in a testing environment."
            )
            self.event.project.pr_comment(pr_id=self.event.pr_id, body=msg)

        build_job_helper.report_status_to_build_for_chroot(
            state=CommitStatus.success,
            description="RPMs were built successfully.",
            url=url,
            chroot=self.event.chroot,
        )
        build_job_helper.report_status_to_test_for_chroot(
            state=CommitStatus.pending,
            description="RPMs were built successfully.",
            url=url,
            chroot=self.event.chroot,
        )
        build.set_status(PG_COPR_BUILD_STATUS_SUCCESS)

        if (
            build_job_helper.job_tests
            and self.event.chroot in build_job_helper.tests_targets
        ):
            testing_farm_handler = GithubTestingFarmHandler(
                config=self.config,
                job_config=build_job_helper.job_tests,
                event=self.event,
                chroot=self.event.chroot,
            )
            testing_farm_handler.run()
        else:
            logger.debug("Testing farm not in the job config.")

        return HandlerResults(success=True, details={})