Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package obs-scm-bridge for openSUSE:Factory checked in at 2026-07-17 01:43:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/obs-scm-bridge (Old) and /work/SRC/openSUSE:Factory/.obs-scm-bridge.new.24530 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "obs-scm-bridge" Fri Jul 17 01:43:47 2026 rev:26 rq:1366151 version:0.7.5 Changes: -------- --- /work/SRC/openSUSE:Factory/obs-scm-bridge/obs-scm-bridge.changes 2026-03-19 17:41:53.993052467 +0100 +++ /work/SRC/openSUSE:Factory/.obs-scm-bridge.new.24530/obs-scm-bridge.changes 2026-07-17 01:44:28.903280145 +0200 @@ -1,0 +2,9 @@ +Thu Jul 16 08:41:49 UTC 2026 - Adrian Schröter <[email protected]> + +- 0.7.5 + * Fix handling of x-bit files + * fixed mtime handling when creating obscpio server side + * respect onlybuild filter on local links + * general code cleanup + +------------------------------------------------------------------- Old: ---- obs-scm-bridge-0.7.4.obscpio New: ---- obs-scm-bridge-0.7.5.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ obs-scm-bridge.spec ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:29.691306452 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:29.695306586 +0200 @@ -29,7 +29,7 @@ %endif Name: obs-scm-bridge -Version: 0.7.4 +Version: 0.7.5 Release: 0 Summary: A help service to work with git repositories in OBS License: GPL-2.0-or-later @@ -37,7 +37,7 @@ Source0: %{name}-%{version}.tar.xz BuildRequires: %{primary_python} BuildRequires: %{primary_python}-PyYAML -Requires: %{build_pkg_name} >= 20211125 +Requires: %{build_pkg_name} >= 20260323 # these are just recommends in build package, but we need it here Requires: perl(Date::Parse) Requires: git-lfs ++++++ PKGBUILD ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:29.779309390 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:29.783309523 +0200 @@ -1,5 +1,5 @@ pkgname=obs-scm-bridge -pkgver=0.7.4 +pkgver=0.7.5 pkgrel=0 pkgdesc='A help service to work with git repositories in OBS' arch=('any') ++++++ _service ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:29.839311393 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:29.839311393 +0200 @@ -2,8 +2,8 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/openSUSE/obs-scm-bridge</param> <param name="scm">git</param> - <param name="revision">0.7.4</param> - <param name="version">0.7.4</param> + <param name="revision">0.7.5</param> + <param name="version">0.7.5</param> </service> <service mode="manual" name="set_version" /> ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:29.883312862 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:29.887312995 +0200 @@ -1,4 +1,4 @@ -build (0.7.4) unstable; urgency=low +build (0.7.5) unstable; urgency=low * Update to current git trunk - add sles11sp2 build config and adapt autodetection ++++++ obs-scm-bridge-0.7.4.obscpio -> obs-scm-bridge-0.7.5.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/obs-scm-bridge-0.7.4/obs-scm-bridge.spec new/obs-scm-bridge-0.7.5/obs-scm-bridge.spec --- old/obs-scm-bridge-0.7.4/obs-scm-bridge.spec 2025-07-28 15:52:01.000000000 +0200 +++ new/obs-scm-bridge-0.7.5/obs-scm-bridge.spec 2026-07-16 12:33:25.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package obs-scm-bridge # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,24 +16,34 @@ # -%if 0%{?fedora} || 0%{?rhel} -%define build_pkg_name obs-build +%if %{undefined primary_python} +%define primary_python python3 +%endif + +%if 0%{?suse_version} +%global build_pkg_name build +%global git_pkg_name git-core %else -%define build_pkg_name build +%global build_pkg_name obs-build +%global git_pkg_name git %endif + Name: obs-scm-bridge -Version: 0.4.2 +Version: 0.7.5 Release: 0 Summary: A help service to work with git repositories in OBS License: GPL-2.0-or-later URL: https://github.com/openSUSE/obs-scm-bridge Source0: %{name}-%{version}.tar.xz -BuildRequires: python311-PyYAML -BuildRequires: python311-PyYAML -Requires: %{build_pkg_name} >= 20211125 -Requires: git-lfs +BuildRequires: %{primary_python} +BuildRequires: %{primary_python}-PyYAML +Requires: %{build_pkg_name} >= 20260323 # these are just recommends in build package, but we need it here Requires: perl(Date::Parse) +Requires: git-lfs +BuildRequires: %{git_pkg_name} >= 2.46 +Requires: %{git_pkg_name} >= 2.46 +Requires: perl(LWP::Protocol::https) Requires: perl(LWP::UserAgent) Requires: perl(Net::SSL) Requires: perl(Pod::Usage) @@ -41,14 +51,9 @@ Requires: perl(URI) Requires: perl(XML::Parser) Requires: perl(YAML::LibYAML) -Requires: python311-PyYAML -Recommends: python311-packaging BuildArch: noarch -%if 0%{?fedora} || 0%{?rhel} -Requires: git -%else -Requires: git-core -%endif +Requires: %{primary_python}-PyYAML +Recommends: %{primary_python}-packaging %description @@ -58,9 +63,24 @@ %build %install -%make_install +make DESTDIR=%{buildroot} install + +mkdir -p %buildroot/etc/obs/services/scm-bridge +echo "src.opensuse.org" > %buildroot/etc/obs/services/scm-bridge/critical-instances +# we would need to configure permissions and owner ship for this file +# but we don't want to enforce obs server package for userid +#echo "" > %buildroot/etc/obs/services/scm-bridge/credentials %files %{_prefix}/lib/obs/service +%dir /etc/obs +%dir /etc/obs/services +%dir /etc/obs/services/scm-bridge +%config(noreplace) /etc/obs/services/scm-bridge/critical-instances + +%check +# the test suite requires online resources unfortunatly +# so let's at least test if our python version understands our syntax +python3 obs_scm_bridge --help %changelog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/obs-scm-bridge-0.7.4/obs_scm_bridge new/obs-scm-bridge-0.7.5/obs_scm_bridge --- old/obs-scm-bridge-0.7.4/obs_scm_bridge 2025-07-28 15:52:01.000000000 +0200 +++ new/obs-scm-bridge-0.7.5/obs_scm_bridge 2026-07-16 12:33:25.000000000 +0200 @@ -56,11 +56,12 @@ class ObsGit(object): - _REGEXP = re.compile(r"^[a-zA-Z0-9\-\_\+][a-zA-Z0-9\.\-\_\+]*$"); + _REGEXP = re.compile(r"^[a-zA-Z0-9\-\_\+][a-zA-Z0-9\.\-\_\+]*$") def __init__(self, outdir: str, url: str, projectscmsync: str) -> None: self.outdir = outdir self.clonedir = None + self.tstamp = None self.revision = None self.trackingbranch = None self.subdir = None @@ -179,8 +180,8 @@ self.run_cmd(cmd, fatal="git config credential.helper") with open(cred_file, "r", encoding="utf-8") as cred: - for l in cred.readlines(): - line = l.rstrip() + for line in cred.readlines(): + line = line.rstrip() entry = line.split(' ') if len(entry) != 4: continue @@ -287,6 +288,14 @@ # implement a switch for that. if len(self.revision) == 64: objectformat='--object-format=sha256' + else: + # Detect SHA type of the server + # We need to do this to support different type of SHA-256 submodule in a SHA-1 git repo + cmd = [ 'git', 'ls-remote', self.scmtoolurl, 'HEAD' ] + output = self.run_cmd(cmd, fatal="git ls-remote") + lastline = output.splitlines()[-1] + if len(lastline.rstrip()) == 69: # SHA-256 plus \t plus HEAD + objectformat='--object-format=sha256' cmd = [ 'git', 'init', objectformat, outdir ] self.run_cmd(cmd, fatal="git init") cmd = [ 'git', '-C', outdir, 'remote', 'add', 'origin', self.scmtoolurl ] @@ -326,20 +335,24 @@ self.verify_subdir(self.subdir) branch = self.revision reset_to_commit = None + do_shallow_clone = self.shallow_clone if self.revision and re.match(r"^[0-9a-fA-F]{40,}$", self.revision): if follow_tracking_branch: branch = self.trackingbranch reset_to_commit = self.revision + do_shallow_clone = False else: self.do_clone_commit(outdir, include_submodules=include_submodules) return cmd = [ 'git', 'clone', self.scmtoolurl, outdir ] if include_submodules: if self.subdir: - cmd += [ "--recurse-submodules=" + self.subdir ] + cmd += [ "--recurse-submodules=" + self.subdir ] else: - cmd += [ '--recurse-submodules' ] - if self.shallow_clone and not reset_to_commit: + cmd += [ '--recurse-submodules' ] + # git submodule cloning may fail if we shallow clone + # do_shallow_clone = False + if do_shallow_clone: cmd += [ '--depth', '1' ] if self.subdir: cmd += [ '--filter=blob:none' ] @@ -375,6 +388,7 @@ cmd = [ 'git', 'log', '-n1', '--no-show-signature', '--pretty=format:%H %ct', '--end-of-options', self.subdir] line = self.run_cmd(cmd, cwd=self.clonedir, fatal="git log") commit, tstamp = line.split() + self.tstamp = tstamp infofile = os.path.join(self.outdir, '_scmsync.obsinfo') if os.path.lexists(infofile): self.die("the _scmsync.obsinfo file must not be part of the git repository") @@ -446,17 +460,23 @@ logging.info("fetching all tags") self.run_cmd(cmd, fatal="fetch --tags") - def cpio_directory(self, directory: str) -> None: + def cpio_directory(self, directory: str, mtime: Optional[str]=None) -> None: logging.info("create archivefile for %s", directory) - cmd = [ download_assets, '--create-cpio', '--', directory ] + cmd = [ download_assets, '--create-cpio' ] + if mtime is not None: + cmd += [ '--mtime', mtime ] + cmd += [ '--', directory ] with open(directory + '.obscpio', 'x') as archivefile: self.run_cmd(cmd, stdout=archivefile, fatal="cpio creation") - def cpio_specials(self, specials: List[str]) -> None: + def cpio_specials(self, specials: List[str], mtime: Optional[str]=None) -> None: if not specials: return logging.info("create archivefile for specials") - cmd = [ download_assets, '--create-cpio', '--', '.' ] + specials + cmd = [ download_assets, '--create-cpio' ] + if mtime is not None: + cmd += [ '--mtime', mtime ] + cmd += [ '--', '.' ] + specials with open('build.specials.obscpio', 'x') as archivefile: self.run_cmd(cmd, stdout=archivefile, fatal="cpio creation") @@ -465,6 +485,7 @@ os.chdir(self.outdir) listing = sorted(os.listdir(".")) specials = [] + xbitspecials = [] for name in listing: if name in ('.git', '.gitattributes') and not self.keep_meta: # we do not store git meta data by default to avoid bloat storage @@ -475,12 +496,17 @@ if os.path.islink(name): specials.append(name) continue + # FIXME: better way would be to store all permission flags git stores + # and re-apply them without moving them. + if os.path.isfile(name) and os.access(name, os.X_OK): + xbitspecials.append(name) + continue if os.path.isdir(name): logging.info("CPIO %s ", name) - self.cpio_directory(name) + self.cpio_directory(name, mtime=self.tstamp) shutil.rmtree(name) - if specials: - self.cpio_specials(specials) + if specials or xbitspecials: + self.cpio_specials(specials + xbitspecials, mtime=self.tstamp) for name in specials: if os.path.isdir(name): shutil.rmtree(name) @@ -526,7 +552,7 @@ for line in output.splitlines(): lstree = line.split(maxsplit=4) if len(lstree[2]) >= 40: - return lstree[2] + return lstree[2] self.die(f"could not determine tree info of {path}") def write_info_file(self, filename: str, info: str) -> None: @@ -549,7 +575,7 @@ self.write_info_file(os.path.join(self.outdir, "_service_info"), info) def write_package_xml_file(self, name: str, url: str, projectscmsync: str=None) -> None: - if self.onlybuild and not name in self.onlybuild.keys(): + if self.onlybuild and name not in self.onlybuild.keys(): return filename = f"{self.outdir}/{name}.xml" with open(filename, 'x') as xmlfile: @@ -561,6 +587,8 @@ xmlfile.write(f"""<scmsync>{escape(url)}</scmsync>\n</package>\n""") def write_package_xml_local_link(self, name: str, target: str, projectscmsync: str=None) -> None: + if self.onlybuild and not name in self.onlybuild.keys(): + return filename = f"{self.outdir}/{name}.xml" with open(filename, 'x') as xmlfile: xmlfile.write(f"""<package name="{escape(name)}">""") @@ -568,7 +596,7 @@ xmlfile.write(f"""<bcntsynctag>{escape(name)}</bcntsynctag>""") if projectscmsync: xmlfile.write(f"""<url>{escape(projectscmsync)}</url>\n""") - xmlfile.write(f"""</package>""") + xmlfile.write("""</package>""") filename = f"{self.outdir}/{name}.link" with open(filename, 'x') as linkfile: linkfile.write(f"""<link package="{escape(target)}" cicount="copy" />""") @@ -585,12 +613,12 @@ def process_package_submodule(self, name: str, subdir: str) -> None: if not self._REGEXP.match(name): - logging.warn("submodule name contains invalid char: %s", name) + logging.warning("submodule name contains invalid char: %s", name) return section = self.gsmpath[subdir + name] if not section: - logging.warn("submodule not configured for %s", subdir + name) + logging.warning("submodule not configured for %s", subdir + name) return gsmsection = self.gsmconfig[section] @@ -610,19 +638,19 @@ url = list(urllib.parse.urlparse(urlstr)) url[5] = revision if 'branch' in gsmsection: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['trackingbranch'] = [gsmsection['branch']] url[4] = urllib.parse.urlencode(query, doseq=True) if self.arch: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['arch'] = self.arch url[4] = urllib.parse.urlencode(query, doseq=True) if self.asset_types_filter: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['buildtype'] = self.asset_types_filter url[4] = urllib.parse.urlencode(query, doseq=True) if self.add_noobsinfo: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['noobsinfo'] = [ '1' ] url[4] = urllib.parse.urlencode(query, doseq=True) @@ -644,7 +672,7 @@ def process_package_subdirectory(self, name: str, subdir: str) -> None: # current directory is self.outdir if not self._REGEXP.match(name): - logging.warn("directory name contains invalid char: %s", name) + logging.warning("directory name contains invalid char: %s", name) return # add subdir info file @@ -659,15 +687,15 @@ if self.revision: url[5] = self.revision if self.arch: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['arch'] = self.arch url[4] = urllib.parse.urlencode(query, doseq=True) if self.asset_types_filter: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['buildtype'] = self.asset_types_filter url[4] = urllib.parse.urlencode(query, doseq=True) if self.add_noobsinfo: - query = urllib.parse.parse_qs(url[4], keep_blank_values=True); + query = urllib.parse.parse_qs(url[4], keep_blank_values=True) query['noobsinfo'] = 1 url[4] = urllib.parse.urlencode(query, doseq=True) @@ -675,10 +703,10 @@ def process_package_locallink(self, name: str, target: str) -> None: if not self._REGEXP.match(name): - logging.warn("locallink name contains invalid char: %s", name) + logging.warning("locallink name contains invalid char: %s", name) return if not self._REGEXP.match(target): - logging.warn("locallink target contains invalid char: %s", target) + logging.warning("locallink target contains invalid char: %s", target) return self.write_package_xml_local_link(name, target) @@ -696,12 +724,12 @@ gsmpath = {} for section in self.gsmconfig.sections(): gsmconfig = self.gsmconfig[section] - if not 'path' in gsmconfig: - logging.warn("path not defined for git submodule " + section) + if 'path' not in gsmconfig: + logging.warning("path not defined for git submodule " + section) continue path = gsmconfig['path'] if path in gsmpath: - logging.warn("multiple definitions of %s path in git submodule config", path) + logging.warning("multiple definitions of %s path in git submodule config", path) continue gsmpath[path] = section self.gsmpath = gsmpath @@ -735,10 +763,10 @@ if manifest_yml.get('packages'): for name in manifest_yml['packages']: if not name or name.startswith('.') or name.startswith('/'): - logging.warn("illegal packages entry '%s'", name) + logging.warning("illegal packages entry '%s'", name) continue if '/' in name or '*' in name: # for now - logging.warn("packages entry with '/' or '*' not implemented yet") + logging.warning("packages entry with '/' or '*' not implemented yet") continue packages.append(name) if manifest_yml.get('subdirectories'): @@ -799,10 +827,12 @@ if self.keep_meta and subdir == '': shutil.move(fname, '.') self.processed[name] = True + elif name[0] == '.': + continue elif os.path.islink(fname): target = os.readlink(fname).rstrip('/') # this is no recursive lookup, but is there a usecase? if not target or '/' in target or target.startswith('.'): - logging.warn("only local links are supported, skipping: %s -> %s", name, target) + logging.warning("only local links are supported, skipping: %s -> %s", name, target) continue if not os.path.isdir(directory + '/' + target): logging.debug("skipping dangling symlink %s -> %s", name, target) @@ -853,9 +883,9 @@ obsgit = ObsGit(outdir, url, projectscmsync) obsgit.add_critical_instance("src.opensuse.org") if os.path.isfile(critical_instances_config): - with open(critical_instances_config) as conf: - for line in conf.readlines(): - obsgit.add_critical_instance(line.rstrip()) + with open(critical_instances_config) as conf: + for line in conf.readlines(): + obsgit.add_critical_instance(line.rstrip()) if os.path.isfile(credentials_config): obsgit.setup_credentials(credentials_config) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/obs-scm-bridge-0.7.4/pyproject.toml new/obs-scm-bridge-0.7.5/pyproject.toml --- old/obs-scm-bridge-0.7.4/pyproject.toml 2025-07-28 15:52:01.000000000 +0200 +++ new/obs-scm-bridge-0.7.5/pyproject.toml 2026-07-16 12:33:25.000000000 +0200 @@ -1,6 +1,6 @@ [tool.poetry] name = "obs-scm-bridge" -version = "0.2.1" +version = "0.7.5" description = "A helper service to work with git repositories in OBS" authors = ["Adrian Schröter <[email protected]>", "Michael Schroeder <[email protected]>"] license = "GPL-2.0-or-later" ++++++ obs-scm-bridge.dsc ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:30.171322476 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:30.175322610 +0200 @@ -1,6 +1,6 @@ Format: 1.0 Source: build -Version: 0.7.4 +Version: 0.7.5 Binary: build Maintainer: Adrian Schroeter <[email protected]> Architecture: all ++++++ obs-scm-bridge.obsinfo ++++++ --- /var/tmp/diff_new_pack.RGkO3t/_old 2026-07-17 01:44:30.199323411 +0200 +++ /var/tmp/diff_new_pack.RGkO3t/_new 2026-07-17 01:44:30.203323545 +0200 @@ -1,5 +1,5 @@ name: obs-scm-bridge -version: 0.7.4 -mtime: 1753710721 -commit: c5b542abe52ff191614e0ac071496cbc2f83c8f1 +version: 0.7.5 +mtime: 1784198005 +commit: ee841c773542fb47489f3d40f4a85eaad5630e0c
