Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package openSUSE-release-tools for
openSUSE:Factory checked in at 2026-09-18 22:07:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openSUSE-release-tools (Old)
and /work/SRC/openSUSE:Factory/.openSUSE-release-tools.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openSUSE-release-tools"
Fri Sep 18 22:07:36 2026 rev:559 rq:1378763 version:20260911.6454091f
Changes:
--------
---
/work/SRC/openSUSE:Factory/openSUSE-release-tools/openSUSE-release-tools.changes
2026-08-31 15:59:13.614268730 +0200
+++
/work/SRC/openSUSE:Factory/.openSUSE-release-tools.new.383539/openSUSE-release-tools.changes
2026-09-18 22:08:31.766599758 +0200
@@ -1,0 +2,43 @@
+Fri Sep 11 07:41:39 UTC 2026 - [email protected]
+
+- Update to version 20260911.6454091f:
+ * staging_accept: update Factory version in devel:ARM:Factory:ARMv9 on accept
+ * staging_accept: update Factory version in LegacyARM port on accept
+
+-------------------------------------------------------------------
+Thu Sep 10 14:29:29 UTC 2026 - [email protected]
+
+- Update to version 20260910.2da304ae:
+ * dashboard: Add LegacyARM and ARMv9
+
+-------------------------------------------------------------------
+Thu Sep 10 09:11:24 UTC 2026 - [email protected]
+
+- Update to version 20260910.71fb706c:
+ * gocd: Add configuration for openSUSE:Factory:LegacyARM
+
+-------------------------------------------------------------------
+Fri Sep 04 12:08:10 UTC 2026 - [email protected]
+
+- Update to version 20260904.0a94d671:
+ * container_cleaner.py: Always log packages being deleted
+
+-------------------------------------------------------------------
+Fri Sep 04 09:39:46 UTC 2026 - [email protected]
+
+- Update to version 20260904.a50a34d6:
+ * container_cleaner.py: Handle multibuild flavors separately
+
+-------------------------------------------------------------------
+Wed Sep 02 09:33:57 UTC 2026 - [email protected]
+
+- Update to version 20260902.9b3f47fc:
+ * check_source.py: Do not skip unchanged URLs
+
+-------------------------------------------------------------------
+Tue Sep 01 14:27:25 UTC 2026 - [email protected]
+
+- Update to version 20260901.eb52bd92:
+ * gocd: Enable productcompose pkglist-generation for Staging
+
+-------------------------------------------------------------------
Old:
----
openSUSE-release-tools-20260824.b49927f7.obscpio
New:
----
openSUSE-release-tools-20260911.6454091f.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ openSUSE-release-tools.spec ++++++
--- /var/tmp/diff_new_pack.7z3nkk/_old 2026-09-18 22:08:32.856645441 +0200
+++ /var/tmp/diff_new_pack.7z3nkk/_new 2026-09-18 22:08:32.860645609 +0200
@@ -21,7 +21,7 @@
%define announcer_filename factory-package-news
%define services osrt-slsa.target [email protected]
[email protected] [email protected] [email protected]
[email protected] [email protected]
Name: openSUSE-release-tools
-Version: 20260824.b49927f7
+Version: 20260911.6454091f
Release: 0
Summary: Tools to aid in staging and release work for openSUSE/SUSE
License: GPL-2.0-or-later AND MIT
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.7z3nkk/_old 2026-09-18 22:08:32.928648459 +0200
+++ /var/tmp/diff_new_pack.7z3nkk/_new 2026-09-18 22:08:32.937648836 +0200
@@ -1,7 +1,7 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/openSUSE/openSUSE-release-tools.git</param>
- <param
name="changesrevision">b49927f739ddffa0e29c91e0d74d9e5260de477d</param>
+ <param
name="changesrevision">6454091f081b30022dd358bc361bd59079e8740b</param>
</service>
</servicedata>
++++++ openSUSE-release-tools-20260824.b49927f7.obscpio ->
openSUSE-release-tools-20260911.6454091f.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/check_source.py
new/openSUSE-release-tools-20260911.6454091f/check_source.py
--- old/openSUSE-release-tools-20260824.b49927f7/check_source.py
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/check_source.py
2026-09-11 09:40:33.000000000 +0200
@@ -702,26 +702,7 @@
return True
- def _snipe_out_existing_urls(self, old, directory, specs):
- if not os.path.isdir(old):
- return
- oldsources = self._mentioned_sources(old, specs)
- for spec in specs:
- specfn = os.path.join(directory, spec)
- nspecfn = specfn + '.new'
- wf = open(nspecfn, 'w')
- with open(specfn) as rf:
- for line in rf:
- m = re.match(r'(Source[0-9]*\s*):\s*(.*)$', line)
- if m and m.group(2) in oldsources:
- wf.write(m.group(1) + ":" +
os.path.basename(m.group(2)) + "\n")
- continue
- wf.write(line)
- wf.close()
- os.rename(nspecfn, specfn)
-
def check_urls(self, old, directory, specs):
- self._snipe_out_existing_urls(old, directory, specs)
oldcwd = os.getcwd()
with tempfile.TemporaryDirectory() as tmpdir:
os.chdir(directory)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/container_cleaner.py
new/openSUSE-release-tools-20260911.6454091f/container_cleaner.py
--- old/openSUSE-release-tools-20260824.b49927f7/container_cleaner.py
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/container_cleaner.py
2026-09-11 09:40:33.000000000 +0200
@@ -8,7 +8,7 @@
import ToolBase
import sys
import re
-from collections import defaultdict
+from collections import defaultdict, namedtuple
from lxml import etree as xml
@@ -27,94 +27,78 @@
return xml.parse(self.retried_GET(url))
def findSourcepkgsToDelete(self, project):
- # Get a list of all images
- srccontainers = self.getDirEntries(["source", project])
+ # Get a set of all srccontainers in the project
+ srccontainers = set(self.getDirEntries(["source", project]))
- # Sort the released packages into buckets for each origin package:
- # {"opensuse-tumbleweed-image":
["opensuse-tumbleweed-image.20190402134201", ...]}
- buckets = defaultdict(list)
- regex_maintenance_release = re.compile(R"^(.+)\.[0-9]+$")
- for srccontainer in srccontainers:
- # Get the right bucket
- match = regex_maintenance_release.match(srccontainer)
- if match:
- # Maintenance release
- package = match.group(1)
- else:
- # Not renamed
- package = srccontainer
-
- if srccontainer not in buckets[package]:
- buckets[package] += [srccontainer]
-
- for package in buckets:
- # Sort each bucket: Newest provider first
- buckets[package].sort(reverse=True)
- logging.debug("Found %d providers of %s", len(buckets[package]),
package)
+ # List of all binaries in the project
+ resultlist = self.getBinaryList(project)
- # Get a hash for sourcecontainer -> arch with binaries
- # {"opensuse-tumbleweed-image.20190309164844": ["aarch64", "armv7l",
"armv6l"],
- # "kubic-pause-image.20190306124139": ["x86_64", "i586"], ... }
- srccontainerarchs = defaultdict(list)
+ # The bot keeps five releases of each image alive. "Same image" is
defined by
+ # having the same package name, flavor and architecture.
+ ImageKey = namedtuple("ProvidedImage", ["pkgname", "flavor", "arch"])
+
+ # A released image. maint_release kept as first tuple member to act
for sorting.
+ ReleasedImage = namedtuple("ReleasedImage", ["maint_release",
"buildcontainer", "srccontainer"])
+
+ # Sort the released packages into buckets for each image it provides:
+ # {ImageKey("opensuse-tumbleweed-image", "docker", "x86_64"):
+ # [ReleasedImage(20190402134201,
"container-image.20190402134201:docker", "container-image.20190402134201"),
...]}
+ buckets = defaultdict(list)
- resultlist = self.getBinaryList(project)
+ # Split a buildcontainer name like "sourcepkg.01234:flavor" into its
parts
+ regex_buildcontainer = re.compile(R"^([^:]+)\.([0-9]+)(:[^:]+)?$")
- regex_srccontainer = re.compile(R"^([^:]+)(:[^:]+)?$")
for arch_result in resultlist.xpath("result"):
arch = arch_result.get("arch")
for binarylist in arch_result.xpath("binarylist"):
buildcontainer = binarylist.get("package")
- if len(binarylist.xpath("binary")) > 0:
- match = regex_srccontainer.match(buildcontainer)
- if not match:
- raise Exception(f"Could not map {buildcontainer} to
source container")
-
- srccontainer = match.group(1)
- if srccontainer not in srccontainers:
- raise Exception(f"Mapped {buildcontainer} to wrong
source container ({srccontainer})")
+ if len(binarylist.xpath("binary")) == 0:
+ continue
- logging.debug("%s provides binaries for %s", srccontainer,
arch)
- srccontainerarchs[srccontainer] += [arch]
+ match = regex_buildcontainer.match(buildcontainer)
+ if not match:
+ raise Exception(f"Could not parse {buildcontainer} as
build container")
+
+ pkgname, maint_release, flavor = match.group(1, 2, 3)
+ srccontainer = f"{pkgname}.{maint_release}"
+ if srccontainer not in srccontainers:
+ raise Exception(f"Mapped {buildcontainer} to wrong source
container ({srccontainer})")
+
+ imgbucket = ImageKey(pkgname, flavor, arch)
+ logging.debug("%s provides binaries for %s through %s",
buildcontainer, imgbucket, srccontainer)
+ buckets[imgbucket] += [ReleasedImage(maint_release,
buildcontainer, srccontainer)]
+
+ # The list of srccontainers referenced by released images
+ seen_srccontainers = set([img.srccontainer for pkg in buckets for img
in buckets[pkg]])
+ srccontainers_not_seen = set(srccontainers) - seen_srccontainers
+ if srccontainers_not_seen:
+ logging.warning(f"The following srccontainers have no binaries and
will not be touched: {srccontainers_not_seen}")
+ else:
+ logging.debug("All srccontainers have binaries!")
# Now go through each bucket and find out what doesn't contribute to
the newest five
- can_delete = []
+ srccontainers_referenced = set()
for package in buckets:
- # {"x86_64": 1, "aarch64": 2, ...}
- archs_found = defaultdict(lambda: 0)
+ # Sort each bucket: Newest provider first
+ buckets[package].sort(reverse=True)
+ logging.debug("Found %d providers of %s", len(buckets[package]),
package)
- for srccontainer in buckets[package]:
- contributes = False
- for arch in srccontainerarchs[srccontainer]:
- if archs_found[arch] < 5:
- archs_found[arch] += 1
- contributes = True
-
- if len(srccontainerarchs[srccontainer]) == 0:
- logging.warning("%s has no binaries (any flavor/any arch)
- skipping", srccontainer)
- elif contributes:
- logging.debug("%s contributes to %s", srccontainer,
package)
- else:
- logging.info("%s does not contribute", srccontainer)
- if len([count for count in archs_found.values() if count >
0]) == 0:
- # If there are A, B, C and D, with only C and D
providing binaries,
- # A and B aren't deleted because they have newer
sources. This is
- # to avoid deleting something due to unforeseen
circumstances, e.g.
- # OBS didn't copy the binaries yet.
- logging.warning("No newer provider found either,
ignoring")
- else:
- can_delete += [srccontainer]
+ for released_image in buckets[package][:5]:
+ logging.debug(f"\t{released_image} needed")
+ srccontainers_referenced.add(released_image.srccontainer)
+ for released_image in buckets[package][5:]:
+ logging.debug(f"\t{released_image} no longer needed")
- return can_delete
+ return seen_srccontainers - srccontainers_referenced
def run(self, project):
packages = self.findSourcepkgsToDelete(project)
for package in packages:
url = self.makeurl(["source", project, package])
- if self.dryrun:
- logging.info("DELETE %s", url)
- else:
+ logging.info("DELETE %s", url)
+ if not self.dryrun:
osc.core.http_DELETE(url)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/dashboard/generate.py
new/openSUSE-release-tools-20260911.6454091f/dashboard/generate.py
--- old/openSUSE-release-tools-20260824.b49927f7/dashboard/generate.py
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/dashboard/generate.py
2026-09-11 09:40:33.000000000 +0200
@@ -51,6 +51,14 @@
'openqa_groupid': 75,
},
{
+ 'name': 'openSUSE:Factory:LegacyARM',
+ 'nick': 'Legacy ARM',
+ 'download_url':
'https://download.opensuse.org/ports/armv7hl/tumbleweed/iso/',
+ 'openqa_group': 'openSUSE Tumbleweed Legacy ARM',
+ 'openqa_version': 'Tumbleweed',
+ 'openqa_groupid': 143,
+ },
+ {
'name': 'openSUSE:Factory:PowerPC',
'nick': 'Power',
'download_url':
'https://download.opensuse.org/ports/ppc/tumbleweed/iso/',
@@ -74,6 +82,14 @@
'openqa_version': 'Tumbleweed',
'openqa_groupid': 34,
},
+ {
+ 'name': 'devel:ARM:Factory:ARMv9',
+ 'nick': 'ARMv9',
+ 'download_url':
'https://download.opensuse.org/repositories/devel:/ARM:/Factory:/ARMv9:/ToTest/images/iso/',
+ 'openqa_group': 'Devel Tumbleweed ARMv9',
+ 'openqa_version': 'Tumbleweed',
+ 'openqa_groupid': 137,
+ },
]
LEAP_PROJECTS = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen.opensuse.gocd.yaml
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen.opensuse.gocd.yaml
---
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen.opensuse.gocd.yaml
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen.opensuse.gocd.yaml
2026-09-11 09:40:33.000000000 +0200
@@ -56,6 +56,14 @@
python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyX86 -s target
--only-release-packages --force
python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyX86 -s target
python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyX86 -s target
--engine=product_composer --force
+ openSUSE_Factory_LegacyARM_target:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |
+ python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyARM -s target
--only-release-packages --force
+ python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyARM -s target
+ python3 -u ./pkglistgen.py -d -A https://api.opensuse.org
update_and_solve -p openSUSE:Factory:LegacyARM -s target
--engine=product_composer --force
openSUSE_Factory_PowerPC:
resources:
- repo-checker
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen.opensuse.gocd.yaml.erb
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen.opensuse.gocd.yaml.erb
---
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen.opensuse.gocd.yaml.erb
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen.opensuse.gocd.yaml.erb
2026-09-11 09:40:33.000000000 +0200
@@ -16,7 +16,7 @@
approval:
type: manual
jobs:
-<% ['openSUSE:Factory/target', 'openSUSE:Factory/ring1',
'openSUSE:Factory:ARM/target', 'openSUSE:Factory:ARM/ring1',
'openSUSE:Factory:LegacyX86/target', 'openSUSE:Factory:PowerPC',
'openSUSE:Factory:zSystems', 'openSUSE:Factory:RISCV'].each do |project|
+<% ['openSUSE:Factory/target', 'openSUSE:Factory/ring1',
'openSUSE:Factory:ARM/target', 'openSUSE:Factory:ARM/ring1',
'openSUSE:Factory:LegacyX86/target', 'openSUSE:Factory:LegacyARM/target',
'openSUSE:Factory:PowerPC', 'openSUSE:Factory:zSystems',
'openSUSE:Factory:RISCV'].each do |project|
project=project.split('/')
name=project[0].gsub(':', '_')
if project.size > 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen_staging.gocd.yaml
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen_staging.gocd.yaml
---
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen_staging.gocd.yaml
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen_staging.gocd.yaml
2026-09-11 09:40:33.000000000 +0200
@@ -189,12 +189,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -255,12 +269,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -321,12 +349,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -387,12 +429,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -453,12 +509,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -519,12 +589,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -585,12 +669,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -651,12 +749,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -717,12 +829,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -783,12 +909,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -849,12 +989,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -915,12 +1069,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -981,12 +1149,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -1047,12 +1229,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -1113,12 +1309,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -1179,12 +1389,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
@@ -1245,12 +1469,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen_staging.gocd.yaml.erb
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen_staging.gocd.yaml.erb
---
old/openSUSE-release-tools-20260824.b49927f7/gocd/pkglistgen_staging.gocd.yaml.erb
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/gocd/pkglistgen_staging.gocd.yaml.erb
2026-09-11 09:40:33.000000000 +0200
@@ -80,12 +80,26 @@
exit 1
fi
+ - Update.000productcompose:
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ export PYTHONPATH=scripts
+ if ./scripts/pkglistgen.py --debug -A $STAGING_API
update_and_solve --staging $STAGING_PROJECT --engine=product_composer --force;
then
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s success
+ else
+ ./scripts/gocd/report-status.py -A $STAGING_API -p
$STAGING_PROJECT -n packagelists -r standard -s failure
+ exit 1
+ fi
+
- Enable.images.repo:
resources:
- staging-bot
tasks:
- script: |-
osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=images&flag=build"
+ osc -A $STAGING_API api -X POST
"/source/$STAGING_PROJECT?cmd=remove_flag&repository=product&flag=build"
export PYTHONPATH=$PWD/scripts
while osc -A $STAGING_API api
"/build/$STAGING_PROJECT/_result?view=summary&repository=images" | grep
'dirty=.true.'; do
sleep 60
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/rebuild-trigger.gocd.yaml
new/openSUSE-release-tools-20260911.6454091f/gocd/rebuild-trigger.gocd.yaml
--- old/openSUSE-release-tools-20260824.b49927f7/gocd/rebuild-trigger.gocd.yaml
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/gocd/rebuild-trigger.gocd.yaml
2026-09-11 09:40:33.000000000 +0200
@@ -40,6 +40,26 @@
- script: |-
echo "openSUSE:Factory:LegacyX86"
./project-installcheck.py --debug check --store
home:repo-checker/rebuilds openSUSE:Factory:LegacyX86
+ Trigger.Rebuild.Factory.LegacyARM:
+ group: openSUSE.Checkers
+ lock_behavior: unlockWhenFinished
+ environment_variables:
+ OSC_CONFIG: /home/go/config/oscrc-factory-maintainer
+ materials:
+ script:
+ git: https://github.com/openSUSE/openSUSE-release-tools.git
+ timer:
+ spec: 0 0 * ? * *
+ only_on_changes: false
+ stages:
+ - Run:
+ approval: manual
+ resources:
+ - repo-checker
+ tasks:
+ - script: |-
+ echo "openSUSE:Factory:LegacyARM"
+ ./project-installcheck.py --debug check --store
home:repo-checker/rebuilds openSUSE:Factory:LegacyARM
Trigger.Rebuild.Factory.Power:
group: openSUSE.Checkers
lock_behavior: unlockWhenFinished
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/totestmanager.gocd.yaml
new/openSUSE-release-tools-20260911.6454091f/gocd/totestmanager.gocd.yaml
--- old/openSUSE-release-tools-20260824.b49927f7/gocd/totestmanager.gocd.yaml
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/gocd/totestmanager.gocd.yaml
2026-09-11 09:40:33.000000000 +0200
@@ -63,6 +63,27 @@
- script: |-
install -D /home/go/config/openqa-client.conf
/home/go/.config/openqa/client.conf
scripts/totest-manager.py -A https://api.opensuse.org --debug run
openSUSE:Factory:LegacyX86
+ TTM.Factory_LegacyARM:
+ group: openSUSE.Checkers
+ lock_behavior: unlockWhenFinished
+ environment_variables:
+ OSC_CONFIG: /home/go/config/oscrc-totest-manager
+ materials:
+ script:
+ git: https://github.com/openSUSE/openSUSE-release-tools.git
+ destination: scripts
+ timer:
+ spec: 0 */15 * ? * *
+ only_on_changes: false
+ stages:
+ - Run:
+ approval: manual
+ resources:
+ - staging-bot
+ tasks:
+ - script: |-
+ install -D /home/go/config/openqa-client.conf
/home/go/.config/openqa/client.conf
+ scripts/totest-manager.py -A https://api.opensuse.org --debug run
openSUSE:Factory:LegacyARM
TTM.Factory_PowerPC:
group: openSUSE.Checkers
lock_behavior: unlockWhenFinished
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/gocd/totestmanager.gocd.yaml.erb
new/openSUSE-release-tools-20260911.6454091f/gocd/totestmanager.gocd.yaml.erb
---
old/openSUSE-release-tools-20260824.b49927f7/gocd/totestmanager.gocd.yaml.erb
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/gocd/totestmanager.gocd.yaml.erb
2026-09-11 09:40:33.000000000 +0200
@@ -4,6 +4,7 @@
openSUSE:Factory
openSUSE:Factory:ARM
openSUSE:Factory:LegacyX86
+ openSUSE:Factory:LegacyARM
openSUSE:Factory:PowerPC
openSUSE:Factory:RISCV
openSUSE:Factory:zSystems
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/osclib/accept_command.py
new/openSUSE-release-tools-20260911.6454091f/osclib/accept_command.py
--- old/openSUSE-release-tools-20260824.b49927f7/osclib/accept_command.py
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/osclib/accept_command.py
2026-09-11 09:40:33.000000000 +0200
@@ -275,12 +275,17 @@
self.update_version_attribute(project, curr_version)
- ports_prjs = ['ARM', 'LegacyX86', 'PowerPC', 'RISCV', 'zSystems']
+ ports_prjs = ['ARM', 'LegacyX86', 'LegacyARM', 'PowerPC', 'RISCV',
'zSystems']
for ports in ports_prjs:
project = self.api.project + ':' + ports
if self.api.item_exists(project):
self.update_version_attribute(project, curr_version)
+ # Also update devel:ARM:Factory:ARMv9
+ project = 'devel:ARM:Factory:ARMv9'
+ if self.api.item_exists(project):
+ self.update_version_attribute(project, curr_version)
+
def sync_buildfailures(self):
"""
Trigger rebuild of packages that failed build in either
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/tests/check_source_tests.py
new/openSUSE-release-tools-20260911.6454091f/tests/check_source_tests.py
--- old/openSUSE-release-tools-20260824.b49927f7/tests/check_source_tests.py
2026-08-24 12:59:06.000000000 +0200
+++ new/openSUSE-release-tools-20260911.6454091f/tests/check_source_tests.py
2026-09-11 09:40:33.000000000 +0200
@@ -386,7 +386,7 @@
@pytest.mark.usefixtures("default_config")
def test_existing_source_urls(self):
- """Accepts invalid source URLs if previously present"""
+ """Refuses invalid source URLs even if previously present"""
self._setup_devel_project(devel_files='blowfish-with-urls',
target_files='blowfish-with-existing-url')
req_id = self.wf.create_submit_request(self.devel_package.project,
@@ -397,7 +397,10 @@
self.review_bot.set_request_ids([req_id])
self.review_bot.check_requests()
- self.assertReview(req_id, by_user=(self.bot_user, 'accepted'))
+ # not declined but not accepted either
+ review = self.assertReview(req_id, by_user=(self.bot_user, 'new'))
+ self.assertIn("Source URLs are not valid. Try `osc service runall
download_files`.", review.comment)
+ self.assertIn("ERROR: Failed to download
\"https://example.com/blowfish-1.tar.gz\"", review.comment)
@pytest.mark.usefixtures("default_config")
def test_two_patches_in_one_line(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openSUSE-release-tools-20260824.b49927f7/tests/container_cleaner_tests.py
new/openSUSE-release-tools-20260911.6454091f/tests/container_cleaner_tests.py
---
old/openSUSE-release-tools-20260824.b49927f7/tests/container_cleaner_tests.py
2026-08-24 12:59:06.000000000 +0200
+++
new/openSUSE-release-tools-20260911.6454091f/tests/container_cleaner_tests.py
2026-09-11 09:40:33.000000000 +0200
@@ -6,6 +6,7 @@
class MockedContainerCleaner(ContainerCleaner):
def __init__(self, container_arch_map):
+ super().__init__()
self.container_arch_map = container_arch_map
def getDirEntries(self, path):
@@ -43,7 +44,7 @@
class TestContainerCleaner(unittest.TestCase):
def doTest(self, container_arch_map, to_be_deleted_exp):
cleaner = MockedContainerCleaner(container_arch_map)
- to_be_deleted = cleaner.findSourcepkgsToDelete("mock:prj")
+ to_be_deleted = list(cleaner.findSourcepkgsToDelete("mock:prj"))
to_be_deleted.sort()
self.assertEqual(to_be_deleted, to_be_deleted_exp)
@@ -57,7 +58,7 @@
def test_nothingToDo(self):
"""Non-empty project, still do nothing"""
- container_arch_map = {"c": ["i586", "x86_64"],
+ container_arch_map = {"c.00": ["i586", "x86_64"],
"c.01": ["i586"],
"c.02": ["x86_64"],
"c.04": ["i586", "x86_64"],
@@ -73,7 +74,7 @@
def test_multiplePackages(self):
"""Multiple packages in one project"""
- container_arch_map = {"c": ["i586", "x86_64"],
+ container_arch_map = {"c.00": ["i586", "x86_64"],
"c.01": ["i586"],
"c.02": ["x86_64"],
"c.03": [],
@@ -94,15 +95,14 @@
"e.56": ["i586"],
"e.57": ["i586"]}
- to_be_deleted_exp = ["c", "c.01", "c.02", "c.04",
+ to_be_deleted_exp = ["c.00", "c.01", "c.02", "c.04",
"e.51"]
return self.doTest(container_arch_map, to_be_deleted_exp)
def test_multibuild(self):
- """Packages using _multbuild.
- There is no special handling for _multibuild - It's enough if any
flavor has binaries."""
- container_arch_map = {"c:docker": ["i586", "x86_64"],
+ """_multibuild flavors are treated like separate binaries"""
+ container_arch_map = {"c.00:docker": ["i586", "x86_64"],
"c.01:docker": ["i586"],
"c.02:lxc": ["x86_64"],
"c.03:docker": [],
@@ -114,7 +114,8 @@
"c.09:docker": ["i586", "x86_64"],
"c.10:docker": ["i586", "x86_64"],
"c.11:docker": [],
- "d.42:lxc": [], "d.43": [],
+ "d.42:lxc": [],
+ "d.43": [],
"e.51": ["i586"],
"e.52": ["aarch64"],
"e.53": ["i586"],
@@ -123,7 +124,45 @@
"e.56": ["i586"],
"e.57": ["i586"]}
- to_be_deleted_exp = ["c", "c.01", "c.02", "c.04",
- "e.51"]
+ to_be_deleted_exp = ["c.00", "c.01"]
return self.doTest(container_arch_map, to_be_deleted_exp)
+
+ def test_multibuild_independent(self):
+ """_multibuild flavors are treated like separate binaries"""
+ container_arch_map = {"f.0:a": ["x86_64"],
+ "f.0:b": ["x86_64"],
+ "f.1:b": ["x86_64"],
+ "f.2:b": ["x86_64"],
+ "f.3:b": ["x86_64"],
+ "f.4:b": ["x86_64"],
+ "f.5:b": ["x86_64"],
+ "f.6:b": ["x86_64"]}
+
+ # f.0 is needed for f.0:a, keep it
+ to_be_deleted_exp = ["f.1"]
+
+ self.doTest(container_arch_map, to_be_deleted_exp)
+
+ def test_multibuild_manyflavors(self):
+ """Packages using _multbuild with many flavors
+ Ensure that every flavors is accounted for separately."""
+ container_arch_map = {}
+
+ # Generate five releases of a container with six flavors each.
+ # The flavors are released separately, so each flavor gets a new
maintenance release
+ # number, i.e. c.00:fl0 and c.01:fl1 have binaries,
+ # while c.00:fl1-fl6, c.01:fl0 and c.01:fl2-6 do not.
+ relcounter = 0
+ for release in range(0, 4):
+ for flavor in range(0, 6):
+ relcounter = 6 * release + flavor
+ for allflavor in range(0, 6):
+ container_arch_map[f"c.{relcounter}:fl{allflavor}"] = []
+
+ container_arch_map[f"c.{relcounter}:fl{flavor}"] = ["x86_64"]
+
+ # For each c:flX release, there are five binaries, thus nothing should
get deleted.
+ to_be_deleted_exp = []
+
+ self.doTest(container_arch_map, to_be_deleted_exp)
++++++ openSUSE-release-tools.obsinfo ++++++
--- /var/tmp/diff_new_pack.7z3nkk/_old 2026-09-18 22:08:33.785684377 +0200
+++ /var/tmp/diff_new_pack.7z3nkk/_new 2026-09-18 22:08:33.793684712 +0200
@@ -1,5 +1,5 @@
name: openSUSE-release-tools
-version: 20260824.b49927f7
-mtime: 1787569146
-commit: b49927f739ddffa0e29c91e0d74d9e5260de477d
+version: 20260911.6454091f
+mtime: 1789112433
+commit: 6454091f081b30022dd358bc361bd59079e8740b