Skip to content

Commit

Permalink
Feat/configurable check name (#2402)
Browse files Browse the repository at this point in the history
Feat/configurable check name

TODO:

 Write new tests or update the old ones to cover new functionality.
 Update doc-strings where appropriate.
 Update or write new documentation in packit/packit.dev.
 [FIXME]: retriggering via GitHub re-run BROKEN




RELEASE NOTES BEGIN
We have introduced a new status_name_template option that allows you to configure status name for a Packit job. For further details have a look at our docs. This feature is still experimental and it is not possible to retry those jobs via GitHub Checks' re-run at the moment.
RELEASE NOTES END

Reviewed-by: Laura Barcziová
Reviewed-by: Matej Focko
Reviewed-by: František Lachman <flachman@redhat.com>
  • Loading branch information
2 parents 75d8818 + 026b2a3 commit d228244
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 48 deletions.
77 changes: 39 additions & 38 deletions packit_service/worker/handlers/copr.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,43 +422,44 @@ def handle_srpm_end(self):
return TaskResults(success=True, details={"msg": msg})

def handle_testing_farm(self):
if self.copr_build_helper.job_tests_all:
event_dict = self.data.get_dict()

for job_config in self.copr_build_helper.job_tests_all:
if (
not job_config.skip_build
and not job_config.manual_trigger
# we need to check the labels here
# the same way as when scheduling jobs for event
and (
job_config.trigger != JobConfigTriggerType.pull_request
or not (
job_config.require.label.present
or job_config.require.label.absent
)
or pr_labels_match_configuration(
pull_request=self.copr_build_helper.pull_request_object,
configured_labels_absent=job_config.require.label.absent,
configured_labels_present=job_config.require.label.present,
)
if not self.copr_build_helper.job_tests_all:
logger.debug("Testing farm not in the job config.")
return

event_dict = self.data.get_dict()

for job_config in self.copr_build_helper.job_tests_all:
if (
not job_config.skip_build
and not job_config.manual_trigger
# we need to check the labels here
# the same way as when scheduling jobs for event
and (
job_config.trigger != JobConfigTriggerType.pull_request
or not (
job_config.require.label.present
or job_config.require.label.absent
)
and self.copr_event.chroot
in self.copr_build_helper.build_targets_for_test_job(job_config)
):
event_dict["tests_targets_override"] = list(
self.copr_build_helper.build_target2test_targets_for_test_job(
self.copr_event.chroot, job_config
)
or pr_labels_match_configuration(
pull_request=self.copr_build_helper.pull_request_object,
configured_labels_absent=job_config.require.label.absent,
configured_labels_present=job_config.require.label.present,
)
signature(
TaskName.testing_farm.value,
kwargs={
"package_config": dump_package_config(self.package_config),
"job_config": dump_job_config(job_config),
"event": event_dict,
"build_id": self.build.id,
},
).apply_async()
else:
logger.debug("Testing farm not in the job config.")
)
and self.copr_event.chroot
in self.copr_build_helper.build_targets_for_test_job(job_config)
):
event_dict["tests_targets_override"] = list(
self.copr_build_helper.build_target2test_targets_for_test_job(
self.copr_event.chroot, job_config
)
)
signature(
TaskName.testing_farm.value,
kwargs={
"package_config": dump_package_config(self.package_config),
"job_config": dump_job_config(job_config),
"event": event_dict,
"build_id": self.build.id,
},
).apply_async()
49 changes: 42 additions & 7 deletions packit_service/worker/helpers/build/build_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,14 +385,31 @@ def get_check_cls(
chroot: str = None,
project_event_identifier: Optional[str] = None,
identifier: Optional[str] = None,
package: Optional[str] = None,
template: Optional[str] = None,
):
if project_event_identifier:
project_event_identifier = project_event_identifier.replace(":", "-")

try:
if template is not None:
return template.format(
job_name=job_name,
chroot=chroot,
event=project_event_identifier,
identifier=identifier,
package=package,
)
except Exception as e:
logger.warning(
"Failed to use the template for status check, falling back to default: %s",
e,
)
pass

chroot_str = f":{chroot}" if chroot else ""
# replace ':' in the project event identifier
trigger_str = (
f":{project_event_identifier.replace(':', '-')}"
if project_event_identifier
else ""
)
trigger_str = f":{project_event_identifier}" if project_event_identifier else ""
optional_suffix = f":{identifier}" if identifier else ""
return f"{job_name}{trigger_str}{chroot_str}{optional_suffix}"

Expand All @@ -402,9 +419,16 @@ def get_build_check_cls(
chroot: str = None,
project_event_identifier: Optional[str] = None,
identifier: Optional[str] = None,
package: Optional[str] = None,
template: Optional[str] = None,
):
return cls.get_check_cls(
cls.status_name_build, chroot, project_event_identifier, identifier
cls.status_name_build,
chroot,
project_event_identifier,
identifier,
package=package,
template=template,
)

@classmethod
Expand All @@ -413,9 +437,16 @@ def get_test_check_cls(
chroot: str = None,
project_event_identifier: Optional[str] = None,
identifier: Optional[str] = None,
package: Optional[str] = None,
template: Optional[str] = None,
):
return cls.get_check_cls(
cls.status_name_test, chroot, project_event_identifier, identifier
cls.status_name_test,
chroot,
project_event_identifier,
identifier,
package=package,
template=template,
)

@property
Expand All @@ -437,6 +468,8 @@ def get_build_check(self, chroot: str = None) -> str:
chroot,
self.project_event_identifier_for_status,
self.job_build_or_job_config.identifier,
package=self.get_package_name(),
template=self.job_build_or_job_config.status_name_template,
)

def test_check_names_for_test_job(self, test_job_config: JobConfig) -> List[str]:
Expand All @@ -450,6 +483,8 @@ def test_check_names_for_test_job(self, test_job_config: JobConfig) -> List[str]
target,
self.project_event_identifier_for_status,
test_job_config.identifier,
package=self.get_package_name(),
template=test_job_config.status_name_template,
)
for target in self.tests_targets_for_test_job(test_job_config)
]
Expand Down
6 changes: 5 additions & 1 deletion packit_service/worker/helpers/testing_farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,11 @@ def tests_targets(self) -> Set[str]:

def get_test_check(self, chroot: str = None) -> str:
return self.get_test_check_cls(
chroot, self.project_event_identifier_for_status, self.job_config.identifier
chroot,
self.project_event_identifier_for_status,
self.job_config.identifier,
package=self.get_package_name(),
template=self.job_config.status_name_template,
)

@property
Expand Down
14 changes: 12 additions & 2 deletions tests/unit/test_allowlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,12 @@ def test_check_and_report(
)
]
flexmock(PullRequestGithubEvent).should_receive("get_packages_config").and_return(
flexmock(jobs=job_configs, get_package_config_for=lambda job_config: flexmock())
flexmock(
jobs=job_configs,
get_package_config_for=lambda job_config: flexmock(
packages={"package": {}}
),
)
)
_, _ = add_pull_request_event_with_empty_sha

Expand Down Expand Up @@ -805,7 +810,12 @@ def test_check_and_report_actor_pull_request(
)
]
flexmock(PullRequestGithubEvent).should_receive("get_packages_config").and_return(
flexmock(jobs=job_configs, get_package_config_for=lambda job_config: flexmock())
flexmock(
jobs=job_configs,
get_package_config_for=lambda job_config: flexmock(
packages={"package": {}}
),
)
)
_, _ = add_pull_request_event_with_empty_sha

Expand Down
154 changes: 154 additions & 0 deletions tests/unit/test_status_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

# import re
from dataclasses import dataclass
from typing import Optional
import logging

# from flexmock import flexmock
import pytest

from packit_service.worker.helpers.build.build_helper import BaseBuildJobHelper
from packit_service.worker.helpers.build.copr_build import CoprBuildJobHelper
from packit_service.worker.helpers.testing_farm import TestingFarmJobHelper

logger = logging.getLogger(__name__)


@dataclass
class StatusNameTestcase:
job_name: Optional[str] = None
chroot: Optional[str] = None
event: Optional[str] = None
identifier: Optional[str] = None
package: Optional[str] = None
template: Optional[str] = None
expected: str = None


@pytest.mark.parametrize(
"testcase",
[
pytest.param(
StatusNameTestcase(
job_name="copr",
chroot="centos-10",
event="pr-42",
identifier=None,
package="packit",
template=None,
expected="copr:pr-42:centos-10",
),
id="default template",
),
pytest.param(
StatusNameTestcase(
job_name="copr",
chroot="centos-10",
event="pr-42",
identifier=None,
package="packit",
template="packit:{job_name}:{event}:{chroot}",
expected="packit:copr:pr-42:centos-10",
),
id="custom template",
),
pytest.param(
StatusNameTestcase(
job_name="copr",
chroot="fedora-40",
event="stable",
identifier="custom-build",
package="special-package",
template="packit:rpm-build:{package}:{identifier}:{chroot}",
expected="packit:rpm-build:special-package:custom-build:fedora-40",
),
id="custom template #2",
),
],
)
def test_get_check_cls(testcase):
assert (
BaseBuildJobHelper.get_check_cls(
job_name=testcase.job_name,
chroot=testcase.chroot,
project_event_identifier=testcase.event,
identifier=testcase.identifier,
package=testcase.package,
template=testcase.template,
)
== testcase.expected
)


@pytest.mark.parametrize(
"testcase",
[
pytest.param(
StatusNameTestcase(
chroot="centos-10",
event="stable",
identifier="release-build",
expected="rpm-build:stable:centos-10:release-build",
),
id="default template",
),
pytest.param(
StatusNameTestcase(
chroot="fedora-40-x86_64",
event="pr-42069",
identifier="release-build",
template="copr-build:pr:{chroot}:{identifier}",
expected="copr-build:pr:fedora-40-x86_64:release-build",
),
id="custom template",
),
],
)
def test_get_copr_build_check_cls(testcase):
assert (
CoprBuildJobHelper.get_build_check_cls(
chroot=testcase.chroot,
project_event_identifier=testcase.event,
identifier=testcase.identifier,
template=testcase.template,
)
== testcase.expected
)


@pytest.mark.parametrize(
"testcase",
[
pytest.param(
StatusNameTestcase(
chroot="centos-10",
event="stable",
identifier="release-test",
expected="testing-farm:stable:centos-10:release-test",
),
id="default template",
),
pytest.param(
StatusNameTestcase(
chroot="fedora-40-x86_64",
event="pr-42069",
identifier="revdep-on-release-build",
template="tests:pr:{chroot}:{identifier}",
expected="tests:pr:fedora-40-x86_64:revdep-on-release-build",
),
id="custom template",
),
],
)
def test_get_copr_test_check_cls(testcase):
assert (
TestingFarmJobHelper.get_test_check_cls(
chroot=testcase.chroot,
project_event_identifier=testcase.event,
identifier=testcase.identifier,
template=testcase.template,
)
== testcase.expected
)
3 changes: 3 additions & 0 deletions tests/unit/test_testing_farm.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ def test_testing_farm_response(
},
),
],
packages={
"package": {},
},
)
flexmock(PackageConfigGetter).should_receive(
"get_package_config_from_repo"
Expand Down

0 comments on commit d228244

Please sign in to comment.