Skip to content

Commit

Permalink
Allow passing versions as list for sync_release
Browse files Browse the repository at this point in the history
  • Loading branch information
lbarcziova committed May 20, 2024
1 parent f6b656f commit feb6e83
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 35 deletions.
117 changes: 86 additions & 31 deletions packit/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ def check_version_distance(
current,
proposed,
target_branch,
) -> None:
) -> bool:
"""Following this guidelines:
https://docs.fedoraproject.org/en-US/fesco/Updates_Policy/#philosophy
we want to avoid major updates of packages within a **stable** release.
Expand All @@ -771,14 +771,12 @@ def check_version_distance(
and masked_proposed
and masked_current.group(0) != masked_proposed.group(0)
):
raise ReleaseSkippedPackitException(
f"The upstream released version {current} does not match "
f"specfile version {proposed} at branch {target_branch} "
f"using the version_update_mask "
f'"{self.package_config.version_update_mask}".'
"\nYou can change the version_update_mask with an empty string "
"to skip this check.",
logger.debug(
f"Masked {current} and {proposed} ({masked_current} and {masked_proposed}) "
f"do not match.",
)
return False
return True

@staticmethod
def get_upstream_release_monitoring_bug(
Expand Down Expand Up @@ -826,12 +824,48 @@ def get_upstream_release_monitoring_bug(

return None

def determine_version(self, versions: list[str], branch: str):
"""
Determine version to propose the update for considering
the version in the specfile of the particular branch
and version_update_mask configuration option.
"""
logger.info(f"Determining version to propose from {versions}")
downstream_spec_ver = None

try:
downstream_spec_ver = self.dg.get_specfile_version()
self.dg.refresh_specfile()
logger.debug(f"Version in specfile: {downstream_spec_ver}")
except Exception as ex:
logger.debug(ex)

if not downstream_spec_ver:
logger.debug(
"Specfile version not found, picking the first one from the list.",
)
return versions[0]

# should be ordered from the latest
for version_ in versions:
# we could check here also upstream_tag_include and upstream_tag_exclude
if self.check_version_distance(
downstream_spec_ver,
version_,
branch,
):
logger.info(f"Determined version: {version_}")
return version_

return None

@overload
def sync_release(
self,
dist_git_branch: Optional[str] = None,
version: Optional[str] = None,
tag: Optional[str] = None,
versions: Optional[list[str]] = None,
use_local_content=False,
add_new_sources=True,
force_new_sources=False,
Expand Down Expand Up @@ -859,6 +893,7 @@ def sync_release(
dist_git_branch: Optional[str] = None,
version: Optional[str] = None,
tag: Optional[str] = None,
versions: Optional[list[str]] = None,
use_local_content=False,
add_new_sources=True,
force_new_sources=False,
Expand All @@ -885,6 +920,7 @@ def sync_release(
dist_git_branch: Optional[str] = None,
version: Optional[str] = None,
tag: Optional[str] = None,
versions: Optional[list[str]] = None,
use_local_content=False,
add_new_sources=True,
force_new_sources=False,
Expand Down Expand Up @@ -957,15 +993,15 @@ def sync_release(
raise PackitException(
"Function parameters version and tag are mutually exclusive.",
)
if not tag:
if not tag and not versions:
version = version or self.up.get_latest_released_version()
if not version:
raise PackitException(
"Could not figure out version of latest upstream release. "
"You can specify it as an argument.",
)
upstream_tag = self.up.convert_version_to_tag(version)
else:
elif tag and not versions:
upstream_tag = tag
version = self.up.get_version_from_tag(tag)

Expand All @@ -983,20 +1019,27 @@ def sync_release(
upstream_ref = self.up._expand_git_ref(
upstream_ref or self.package_config.upstream_ref,
)
# don't reference Upstream Release Monitoring bug for CentOS
if not resolved_bugs and self.package_config.pkg_tool in (None, "fedpkg"):
upstream_release_monitoring_bug = self.get_upstream_release_monitoring_bug(
package_name=self.dg.local_project.repo_name,
version=version,
)
resolved_bugs = (
[upstream_release_monitoring_bug]
if upstream_release_monitoring_bug
else []
)

current_up_branch = self.up.active_branch
try:
self.dg.create_branch(
dist_git_branch,
base=f"remotes/origin/{dist_git_branch}",
setup_tracking=True,
)
# fetch and reset --hard upstream/$branch?
logger.info(f"Using {dist_git_branch!r} dist-git branch.")
self.dg.update_branch(dist_git_branch)
self.dg.switch_branch(dist_git_branch, force=True)

if versions:
version = self.determine_version(versions, dist_git_branch)
if not version:
raise ReleaseSkippedPackitException(
"No newer version to propose an update for.",
)
upstream_tag = self.up.convert_version_to_tag(version)

# we want to check out the tag only when local_content is not set
# and it's an actual upstream repo and not source-git
if upstream_ref:
Expand All @@ -1007,15 +1050,19 @@ def sync_release(
elif not use_local_content:
self.up.local_project.checkout_release(upstream_tag)

self.dg.create_branch(
dist_git_branch,
base=f"remotes/origin/{dist_git_branch}",
setup_tracking=True,
)
# fetch and reset --hard upstream/$branch?
logger.info(f"Using {dist_git_branch!r} dist-git branch.")
self.dg.update_branch(dist_git_branch)
self.dg.switch_branch(dist_git_branch, force=True)
# don't reference Upstream Release Monitoring bug for CentOS
if not resolved_bugs and self.package_config.pkg_tool in (None, "fedpkg"):
upstream_release_monitoring_bug = (
self.get_upstream_release_monitoring_bug(
package_name=self.dg.local_project.repo_name,
version=version,
)
)
resolved_bugs = (
[upstream_release_monitoring_bug]
if upstream_release_monitoring_bug
else []
)

# do not add anything between distgit clone/checkout and saving gpg keys!
self.up.allowed_gpg_keys = (
Expand Down Expand Up @@ -1054,7 +1101,15 @@ def sync_release(
if compare_versions(version, spec_ver) > 0:
logger.warning(f"Version {spec_ver!r} in spec file is outdated.")

self.check_version_distance(version, spec_ver, dist_git_branch)
if not self.check_version_distance(version, spec_ver, dist_git_branch):
raise ReleaseSkippedPackitException(
f"The upstream released version {version} does not match "
f"specfile version {spec_ver} at branch {dist_git_branch} "
f"using the version_update_mask "
f'"{self.package_config.version_update_mask}".'
"\nYou can change the version_update_mask with an empty string "
"to skip this check.",
)

self.dg.check_last_commit()

Expand Down
34 changes: 30 additions & 4 deletions tests/unit/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,23 +506,23 @@ def test_pkg_tool_property(package_config, config, expected_pkg_tool):
"4.0.0",
"rawhide",
None,
does_not_raise(),
True,
id="skip version distance check for rawhide",
),
pytest.param(
"3.10.0",
"4.0.0",
"f38",
r"\d+\.\d+\.",
pytest.raises(PackitException),
False,
id="proposed version far too distant for f38",
),
pytest.param(
"3.10.0",
"3.10.1",
"f38",
r"\d+\.\d+\.",
does_not_raise(),
True,
id="proposed version ok for f38",
),
),
Expand All @@ -540,12 +540,14 @@ def test_check_version_distance(
)
config = Config()

with exp:
assert (
PackitAPI(config, package_config).check_version_distance(
current_version,
proposed_version,
target_branch,
)
== exp
)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -586,3 +588,27 @@ def test_get_upstream_release_monitoring_bug(package_name, version, response, re
assert (
PackitAPI.get_upstream_release_monitoring_bug(package_name, version) == result
)


@pytest.mark.parametrize(
"versions, version, branch, version_update_mask, exp_version",
(
pytest.param(["1.1.0"], "1.0.0", "f39", None, "1.1.0"),
pytest.param(["1.1.0"], "1.0.0", "f39", r"\d+\.\d+\.", None),
pytest.param(["1.1.0", "1.0.1"], "1.0.0", "f39", r"\d+\.\d+\.", "1.0.1"),
pytest.param(["1.1.0"], "1.0.0", "rawhide", r"\d+\.\d+\.", "1.1.0"),
),
)
def test_determine_version(
versions,
version,
branch,
version_update_mask,
exp_version,
api_mock,
):
flexmock(api).should_receive("get_branches").and_return(["f39"])
api_mock.dg.should_receive("get_specfile_version").and_return(version)
api_mock.dg.should_receive("refresh_specfile")
api_mock.dg.package_config.version_update_mask = version_update_mask
assert api_mock.determine_version(versions, branch) == exp_version

0 comments on commit feb6e83

Please sign in to comment.