diff --git a/debian/changelog b/debian/changelog index d1ed623819733e4996314dce2948368445919c57..89e912501884bb38363eec0fd2e6961bbe966056 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,29 @@ +apertis-dev-tools (0.2026.1) apertis; urgency=medium + + * import-debian-package: stop using a PosixPath object as context manager. + This is no longer supported since Python 3.13 and triggers an error. + + -- Dylan Aïssi <dylan.aissi@collabora.com> Tue, 25 Feb 2025 09:47:11 +0100 + +apertis-dev-tools (0.2026.0) apertis; urgency=medium + + * apertis-pkg-merge-upstream-to-downstreams: + - Don't print useless information while canceling pipelines. + - ensure merge request is created against the right project: + In case of a forked project, like we are doing with the test of the + rebase, the GitLab API creates by default the MR against the original + project instead of the forked project. To ensure the merge request is + created against the forked project, we use the push option + merge_request.target_project to overwrite the default behavior and to + create the merge request against the forked project. + * Use upstream recommended workaround to still return a RunningCommand object + of an executed sh command. This is required due to a breaking change in + python3-sh 2.x. + * Keep compatibility with python3-sh 1.x, by using _return_cmd + only when required. + + -- Walter Lozano <walter.lozano@collabora.com> Wed, 19 Feb 2025 13:55:39 +0100 + apertis-dev-tools (0.2024.19) apertis; urgency=medium * ci-license-scan: Add proposed whitelist. diff --git a/tools/apertis-pkg-merge-updates b/tools/apertis-pkg-merge-updates index 93667b53ec837843b7f664e1cb8daea106d476ba..78070a6193518ecbd8b61ee78dd0e83dbad93843 100755 --- a/tools/apertis-pkg-merge-updates +++ b/tools/apertis-pkg-merge-updates @@ -15,10 +15,12 @@ from pathlib import Path from debian.changelog import Changelog, VersionError, format_date from debian.debian_support import Version +from sh import __version__ as sh_version from sh.contrib import git APERTIS_CI_NAME = "Apertis CI" APERTIS_CI_EMAIL = "devel@lists.apertis.org" +RETURN_CMD = {} if sh_version.startswith("1.") else {"_return_cmd": True} def git_dir() -> str: @@ -176,6 +178,7 @@ def main(): "merge", "--ff-only", rebase_tip, + **RETURN_CMD, _ok_code=[0, 128], _out="/dev/stdout", _err="/dev/stderr", @@ -215,6 +218,7 @@ def main(): args.upstream, ":!debian/changelog", ":!debian/apertis/*", + **RETURN_CMD, _ok_code=[0, 1], ) msg = [f"Sync from {args.upstream}."] diff --git a/tools/apertis-pkg-merge-upstream-to-downstreams b/tools/apertis-pkg-merge-upstream-to-downstreams index aca0aea9fdd2c7217820a9117b0e0e86deb5249d..8927cdb865033d5a36bfd5367d45ad8566df3ba1 100755 --- a/tools/apertis-pkg-merge-upstream-to-downstreams +++ b/tools/apertis-pkg-merge-upstream-to-downstreams @@ -16,9 +16,13 @@ import urllib.parse import urllib.request from functools import partial -from sh import ErrorReturnCode, ErrorReturnCode_2, apertis_pkg_merge_updates, echo +from sh import ErrorReturnCode, ErrorReturnCode_2 +from sh import __version__ as sh_version +from sh import apertis_pkg_merge_updates, echo from sh.contrib import git +RETURN_CMD = {} if sh_version.startswith("1.") else {"_return_cmd": True} + @dataclasses.dataclass class Conflict: @@ -91,6 +95,7 @@ def is_minor_change(upstream, downstream): downstream, ":!debian/changelog", ":!debian/apertis/*", + **RETURN_CMD, _ok_code=[0, 1], ) return o.exit_code == 0 @@ -117,7 +122,6 @@ def cancel_branch_context_pipeline(project_id, branch, token, project_url): try: res = urllib.request.urlopen(get_id_req) json_res = json.load(res) - print(json_res) latest_job_id = json_res["id"] except urllib.error.HTTPError as e: print("ERROR:", e.read().decode()) @@ -136,7 +140,6 @@ def cancel_branch_context_pipeline(project_id, branch, token, project_url): print(f"Canceling useless pipeline on {branch}") try: res = urllib.request.urlopen(cancel_req).read().decode("utf-8") - print(res) except urllib.error.HTTPError as e: print("ERROR:", e.read().decode()) @@ -185,6 +188,32 @@ def ensure_downstream_branch(project_url, downstream, dry_run): raise +def get_path_with_namespace(project_url): + url = urllib.parse.urlsplit(project_url) + project_id = urllib.parse.quote(removesuffix(url.path.strip("/"), ".git"), safe="") + # drop the inline auth data as urllib does not like it + auth, netloc_no_auth = url.netloc.split("@", 1) + token = auth.split(":", 1)[-1] + url = url._replace( + path=f"/api/v4/projects/{project_id}", + netloc=netloc_no_auth, + ) + project_metadata = url.geturl() + req_project_metadata = urllib.request.Request( + url=project_metadata, + headers={"PRIVATE-TOKEN": token}, + ) + try: + res = urllib.request.urlopen(req_project_metadata) + json_res = json.load(res) + path_with_namespace = json_res["path_with_namespace"] + except urllib.error.HTTPError as e: + print("ERROR:", e.read().decode()) + raise + + return path_with_namespace + + def push_merge_request( project_url, proposed_branch, upstream, downstream, auto_merge="", dry_run=False ): @@ -215,8 +244,11 @@ def push_merge_request( ensure_downstream_branch(project_url, downstream, dry_run) + project_path = get_path_with_namespace(project_url) + print( - f"Create merge request from '{proposed_branch}' to '{downstream}'", flush=True + f"Create merge request from '{proposed_branch}' to '{project_path}/{downstream}'", + flush=True, ) git_push_custom( "-o", @@ -226,6 +258,8 @@ def push_merge_request( "-o", f"merge_request.target={downstream}", "-o", + f"merge_request.target_project={project_path}", + "-o", f"merge_request.title={title}", project_url, f"{proposed_branch}:{proposed_branch}", @@ -327,6 +361,7 @@ def main(): "--is-ancestor", upstream_branch, downstream_branch, + **RETURN_CMD, _ok_code=[0, 1], ).exit_code == 0 @@ -406,7 +441,11 @@ def main(): conflicts.append(conflict) else: o = git( - "diff", "--quiet", f"HEAD..{downstream_branch}", _ok_code=[0, 1] + "diff", + "--quiet", + f"HEAD..{downstream_branch}", + **RETURN_CMD, + _ok_code=[0, 1], ) if o.exit_code == 0: print(f"No merge required for {downstream_branch}, skipping ") diff --git a/tools/apertis-pkg-pull-updates b/tools/apertis-pkg-pull-updates index 3dbc3417d5522da2aa7eb0f3322997eecc3d075a..7f71c77806efae6eae7140dcbe2217c3363e3258 100755 --- a/tools/apertis-pkg-pull-updates +++ b/tools/apertis-pkg-pull-updates @@ -23,8 +23,11 @@ from itertools import chain import yaml from debian.changelog import Changelog from debian.debian_support import Version +from sh import __version__ as sh_version from sh.contrib import git +RETURN_CMD = {} if sh_version.startswith("1.") else {"_return_cmd": True} + def debian_branch(suite): return "debian/" + suite @@ -55,7 +58,15 @@ def parse_ref(ref: str) -> str: def is_ancestor(this: str, other: str): return ( - git("merge-base", "--is-ancestor", this, other, _ok_code=[0, 1]).exit_code == 0 + git( + "merge-base", + "--is-ancestor", + this, + other, + **RETURN_CMD, + _ok_code=[0, 1], + ).exit_code + == 0 ) @@ -433,6 +444,7 @@ def main(): "merge", "--ff-only", local_version_branch, + **RETURN_CMD, _out="/dev/stdout", _err="/dev/stderr", ) diff --git a/tools/import-debian-package b/tools/import-debian-package index bad0725787bb109b4397fca89c93b80f978bd4ec..eda6a4762a0215a905ecc15858bc67f7b33907f2 100755 --- a/tools/import-debian-package +++ b/tools/import-debian-package @@ -19,7 +19,7 @@ import sys from functools import lru_cache from gettext import gettext as _ from pathlib import Path -from tempfile import TemporaryDirectory +from tempfile import TemporaryDirectory, mkdtemp from typing import Mapping, Optional from urllib.error import HTTPError, URLError from urllib.parse import quote @@ -393,32 +393,36 @@ def do_import(args): if parse_ref(apertis_tag): raise Abort(f"Apertis tag {apertis_tag} already exists, cannot continue") - with ensure_dir_or_none(args.cache_dir) or TemporaryDirectory() as downloaddir: - if args.import_local_dsc: - logging.info(f"Overlaying Apertis package version {version}") - downloaded = args.import_local_dsc.name - else: - logging.info("Fetching the package information") + downloaddir = ( + ensure_dir_or_none(args.cache_dir) + if ensure_dir_or_none(args.cache_dir) is not None + else mkdtemp() + ) + if args.import_local_dsc: + logging.info(f"Overlaying Apertis package version {version}") + downloaded = args.import_local_dsc.name + else: + logging.info("Fetching the package information") - cached_dsc = get_cached_dsc(package, version, args.cache_dir) + cached_dsc = get_cached_dsc(package, version, args.cache_dir) - try: - url = args.mirror.rstrip("/") + get_debian_dsc_path(package, version) - except KeyboardInterrupt: - raise - except (KeyError, HTTPError, URLError): - if not cached_dsc: - raise Abort( - f"Unable to download source package {package} version {version}" - ) - else: - logging.warning( - f"Unable to download source package {package} version {version}, but found cached .dsc" - ) - url = cached_dsc - - downloaded = fetch(package, version, url, downloaddir, cached_dsc) - import_debian_dsc(args, downloaded, upstream, downstream, version) + try: + url = args.mirror.rstrip("/") + get_debian_dsc_path(package, version) + except KeyboardInterrupt: + raise + except (KeyError, HTTPError, URLError): + if not cached_dsc: + raise Abort( + f"Unable to download source package {package} version {version}" + ) + else: + logging.warning( + f"Unable to download source package {package} version {version}, but found cached .dsc" + ) + url = cached_dsc + + downloaded = fetch(package, version, url, downloaddir, cached_dsc) + import_debian_dsc(args, downloaded, upstream, downstream, version) if args.dsc: d = deb822.Dsc(args.dsc)