From 502c986486d3a5d3fbf522bb9a6ba4b9b6ed42e4 Mon Sep 17 00:00:00 2001 From: Ricardo Dias Date: Wed, 14 Oct 2026 16:22:56 +0100 Subject: [PATCH] project release: fall back to another instance's release value for owned keys Signed-off-by: Ricardo Dias --- percona_obs/cmd_project.py | 14 ++++++++------ tests/test_project_release.py | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/percona_obs/cmd_project.py b/percona_obs/cmd_project.py index 0b77618d8..577f08d66 100644 --- a/percona_obs/cmd_project.py +++ b/percona_obs/cmd_project.py @@ -2604,10 +2604,13 @@ def _merge_release_obs_data(parts: "list[_ReleaseObsData]") -> _ReleaseObsData: """Union per-instance CHANGELOG inputs. A key's source value comes from the first part that has it; its release - value comes from that SAME part, so an instance's source is never diffed - against another instance's (possibly stale) release copy. Keys no part - has on the source side (removal candidates) take the first part's release - value that has them. Instances hold disjoint slices of a release, so an + value comes from that same part when it has one (so a stale copy elsewhere + never shadows the owner's), otherwise from the first part that has it: the + previous release of a slice may live on another instance (labs holds + staging for the UBI slice while the previous release was cut from + build.opensuse.org). Keys no part has on the source side (removal + candidates) take the first part's release value that has them. Instances + hold disjoint slices of a release, so an image present on two instances is the same image and is not an error (unlike the within-instance ``_merge_container_pkgs`` check). ``release_versions`` stays ``None`` only when no instance has the release @@ -2627,8 +2630,7 @@ def _paired( merged_rel: dict[str, Any] = {} for rel in releases: for k, v in (rel or {}).items(): - if k not in owner: - merged_rel.setdefault(k, v) + merged_rel.setdefault(k, v) for k, i in owner.items(): owner_rel = releases[i] if owner_rel is not None and k in owner_rel: diff --git a/tests/test_project_release.py b/tests/test_project_release.py index 6622ac45d..1560332b5 100644 --- a/tests/test_project_release.py +++ b/tests/test_project_release.py @@ -1387,13 +1387,23 @@ def test_merge_release_obs_data_pairs_release_with_source_instance(tmp_path): assert "h3 (extras)" not in section -def test_merge_release_obs_data_source_owner_without_release_entry(): - # The owning instance has no release entry: the key is new there, the - # other instance's stale release copy is not borrowed. +def test_merge_release_obs_data_source_owner_falls_back_to_other_instance(): + # The owning instance has no release entry: the previous release lives on + # another instance, so its value is used. boo = _obs_data(source_versions={}, release_versions={"h3 (extras)": "4.4.0-1"}) labs = _obs_data(source_versions={"h3 (extras)": "4.5.0-1"}, release_versions={}) merged = cmd_project._merge_release_obs_data([boo, labs]) - assert merged.release_versions == {} + assert merged.release_versions == {"h3 (extras)": "4.4.0-1"} + + +def test_merge_release_obs_data_fallback_yields_update_line(tmp_path): + boo = _obs_data(source_versions={}, release_versions={"h3 (extras)": "4.4.0-1"}) + labs = _obs_data(source_versions={"h3 (extras)": "4.5.0-1"}, release_versions=None) + merged = cmd_project._merge_release_obs_data([boo, labs]) + section = cmd_project._build_changelog_section( + "17.11-2", merged.source_versions, merged.release_versions, tmp_path + ) + assert "- h3 (extras): update upstream version 4.5.0" in section def test_merge_release_obs_data_removal_candidate_first_wins():