public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/fedpkg] 1.48-1: A few patches:
@ 2026-08-10 21:46
0 siblings, 0 replies; 4+ messages in thread
From: @ 2026-08-10 21:46 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/fedpkg
Branch : 1.48-1
Commit : 89e5e05f1904a92fae7f5c7f97b3dffa04576143
Author : Ondřej Nosek <onosek@redhat.com>
Date : 2025-01-07T22:59:26+00:00
Stats : +300/-1 in 7 file(s)
URL : https://src.fedoraproject.org/rpms/fedpkg/c/89e5e05f1904a92fae7f5c7f97b3dffa04576143?branch=1.48-1
Log:
A few patches:
- gitignore the name-version-build/ directory created by fedpkg prep/local
- Fixing unittests for py36
- Fix tests on EPEL 9/10.
- Add setuptools to dependencies for Python 3.12+
- Update expired token exception instructions
- Clone epel10 branches with clone -B
Signed-off-by: Ondřej Nosek <onosek@redhat.com>
---
diff --git a/0028-gitignore-the-name-version-build-directory-created-b.patch b/0028-gitignore-the-name-version-build-directory-created-b.patch
new file mode 100644
index 0000000..d68d2e8
--- /dev/null
+++ b/0028-gitignore-the-name-version-build-directory-created-b.patch
@@ -0,0 +1,44 @@
+From 062ab746dbd43ff502da9e20f84466adc33345df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
+Date: Mon, 18 Nov 2024 18:09:31 +0100
+Subject: [PATCH 1/6] gitignore the name-version-build/ directory created by
+ fedpkg prep/local
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This directory is created by RPM 4.20+
+
+Signed-off-by: Miro Hrončok <miro@hroncok.cz>
+---
+ conf/etc/rpkg/fedpkg-stage.conf | 1 +
+ conf/etc/rpkg/fedpkg.conf | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/conf/etc/rpkg/fedpkg-stage.conf b/conf/etc/rpkg/fedpkg-stage.conf
+index 8f92fc8..87d66fe 100644
+--- a/conf/etc/rpkg/fedpkg-stage.conf
++++ b/conf/etc/rpkg/fedpkg-stage.conf
+@@ -46,6 +46,7 @@ git_excludes =
+ /*.src.rpm
+ /build*.log
+ /.build-*.log
++ /*-build/
+ results/
+ results_*/
+ clog
+diff --git a/conf/etc/rpkg/fedpkg.conf b/conf/etc/rpkg/fedpkg.conf
+index c4ab51a..ed4c318 100644
+--- a/conf/etc/rpkg/fedpkg.conf
++++ b/conf/etc/rpkg/fedpkg.conf
+@@ -46,6 +46,7 @@ git_excludes =
+ /*.src.rpm
+ /build*.log
+ /.build-*.log
++ /*-build/
+ results/
+ results_*/
+ clog
+--
+2.47.1
+
diff --git a/0029-Fixing-unittests-for-py36.patch b/0029-Fixing-unittests-for-py36.patch
new file mode 100644
index 0000000..22c8020
--- /dev/null
+++ b/0029-Fixing-unittests-for-py36.patch
@@ -0,0 +1,33 @@
+From 985e42039a399846a54a41aecd637d128197ba7f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Tue, 7 Jan 2025 04:10:16 +0100
+Subject: [PATCH 2/6] Fixing unittests for py36
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is an issue with the newest pycurl library in PyPI.
+Use the older one for this environment.
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ tox.ini | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tox.ini b/tox.ini
+index ea4dc6b..3450087 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -23,6 +23,9 @@ setenv=
+
+ [testenv:py36]
+ package = sdist
++deps =
++ {[testenv]deps}
++ pycurl<7.45.4
+
+ [testenv:flake8]
+ skip_install = True
+--
+2.47.1
+
diff --git a/0030-Fix-tests-on-EPEL-9-10.patch b/0030-Fix-tests-on-EPEL-9-10.patch
new file mode 100644
index 0000000..c2c9d67
--- /dev/null
+++ b/0030-Fix-tests-on-EPEL-9-10.patch
@@ -0,0 +1,47 @@
+From 042ee46d6ee69ed33e978b8a51e7a0e6d8260ac4 Mon Sep 17 00:00:00 2001
+From: Romain Geissler <romain.geissler@amadeus.com>
+Date: Sun, 5 Jan 2025 23:26:50 +0000
+Subject: [PATCH 3/6] Fix tests on EPEL 9/10.
+
+Indeed in EPEL distro.like() returns "rhel fedora" while on fedora it
+returns an empty string.
+
+Signed-off-by: Romain Geissler <romain.geissler@amadeus.com>
+---
+ test/test_commands.py | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/test/test_commands.py b/test/test_commands.py
+index d160da9..b08a7fe 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -24,20 +24,23 @@ class TestDetermineRuntimeEnv(CommandTestCase):
+ self.cmd = self.make_commands()
+
+ @patch('distro.id', return_value='fedora')
++ @patch('distro.like', return_value='')
+ @patch('distro.major_version', return_value='25')
+- def test_return_fedora_disttag(self, mock_ver, mock_id):
++ def test_return_fedora_disttag(self, mock_ver, mock_like, mock_id):
+ result = self.cmd._determine_runtime_env()
+ self.assertEqual('fc25', result)
+
+ @patch('distro.id', return_value='')
+- def test_return_None_if_os_is_unknown(self, mock_id):
++ @patch('distro.like', return_value='')
++ def test_return_None_if_os_is_unknown(self, mock_like, mock_id):
+ self.assertEqual(None, self.cmd._determine_runtime_env())
+
+ @patch('distro.os_release_info', return_value={'variant': 'ELN'})
+ @patch('distro.id', return_value='fedora')
++ @patch('distro.like', return_value='')
+ @patch('distro.major_version', return_value='41')
+ @patch('pyrpkg.Commands.kojisession', new_callable=PropertyMock)
+- def test_return_for_eln(self, mock_koji, mock_ver, mock_id, mock_info):
++ def test_return_for_eln(self, mock_koji, mock_ver, mock_like, mock_id, mock_info):
+ self.cmd._kojisession = Mock()
+ koji_session = mock_koji.return_value
+ koji_session.getBuildConfig.return_value = {
+--
+2.47.1
+
diff --git a/0031-Add-setuptools-to-dependencies-for-Python-3.12.patch b/0031-Add-setuptools-to-dependencies-for-Python-3.12.patch
new file mode 100644
index 0000000..fd1a23d
--- /dev/null
+++ b/0031-Add-setuptools-to-dependencies-for-Python-3.12.patch
@@ -0,0 +1,30 @@
+From 0939d87670cbfccef1422254c3c83cc20b7f2341 Mon Sep 17 00:00:00 2001
+From: "FeRD (Frank Dana)" <ferdnyc@gmail.com>
+Date: Sun, 22 Sep 2024 02:36:49 -0400
+Subject: [PATCH 4/6] Add setuptools to dependencies for Python 3.12+
+
+Since the package still uses pkg_resources, in Python 3.12 it requires
+the installation of setuptools which is no longer available by default.
+
+Merges: https://pagure.io/fedpkg/pull-request/571
+
+Signed-off-by: FeRD (Frank Dana) <ferdnyc@gmail.com>
+---
+ pyproject.toml | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/pyproject.toml b/pyproject.toml
+index 8cf7880..fdc00ad 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -29,6 +29,7 @@ dependencies = [
+ "openidc-client",
+ "python-bugzilla",
+ "rpkg",
++ "setuptools;python_version>='3.12'",
+ ]
+
+ [project.scripts]
+--
+2.47.1
+
diff --git a/0032-Update-expired-token-exception-instructions.patch b/0032-Update-expired-token-exception-instructions.patch
new file mode 100644
index 0000000..1f4dceb
--- /dev/null
+++ b/0032-Update-expired-token-exception-instructions.patch
@@ -0,0 +1,55 @@
+From c0f9604f9c9c58e13c2a667745efc6612a891131 Mon Sep 17 00:00:00 2001
+From: "FeRD (Frank Dana)" <ferdnyc@gmail.com>
+Date: Sun, 22 Sep 2024 01:51:06 -0400
+Subject: [PATCH 5/6] Update expired token exception instructions
+
+The exception used to instruct the user to run the command
+`fedpkg set-pagure-token <token>`, which doesn't work. The command
+only accepts the token interactively at a prompt, not on the command
+line (presumably for security purposes). Exception message and
+unit test for same adjusted accordingly.
+
+Merges: https://pagure.io/fedpkg/pull-request/570
+
+Signed-off-by: FeRD (Frank Dana) <ferdnyc@gmail.com>
+---
+ fedpkg/utils.py | 6 ++++--
+ test/test_utils.py | 5 +++--
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fedpkg/utils.py b/fedpkg/utils.py
+index 0669c3f..0c54ba1 100644
+--- a/fedpkg/utils.py
++++ b/fedpkg/utils.py
+@@ -93,8 +93,10 @@ def new_pagure_issue(logger, url, token, title, body, cli_name):
+ # show hint for expired token
+ if re.search(r"Invalid or expired token", rv_error, re.IGNORECASE):
+ base_error_msg += '\nFor invalid or expired tokens please ' \
+- 'set a new token in your user configuration with:' \
+- '\n\n\t{0} set-pagure-token <token>\n'.format(cli_name)
++ 'set a new token in your user configuration by running:' \
++ '\n\n\t{0} set-pagure-token\n\n' \
++ 'The command is interactive; enter the new token when ' \
++ 'prompted.\n'.format(cli_name)
+ raise rpkgError(base_error_msg.format(rv_error))
+
+ return '{0}/releng/fedora-scm-requests/issue/{1}'.format(
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 09ddbdb..19ad2f8 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -388,8 +388,9 @@ class TestNewPagureIssue(unittest.TestCase):
+ self.assertRaisesRegex(
+ rpkgError,
+ '\nFor invalid or expired tokens please '
+- 'set a new token in your user configuration with:'
+- '\n\n\tfedpkg set-pagure-token <token>\n',
++ 'set a new token in your user configuration by running:'
++ '\n\n\tfedpkg set-pagure-token\n\n'
++ 'The command is interactive; enter the new token when prompted.',
+ utils.new_pagure_issue,
+ logger, 'http://distgit/', '123456', 'new package', {'repo': 'pkg1'}, 'fedpkg')
+
+--
+2.47.1
+
diff --git a/0033-Clone-epel10-branches-with-clone-B.patch b/0033-Clone-epel10-branches-with-clone-B.patch
new file mode 100644
index 0000000..8ce737a
--- /dev/null
+++ b/0033-Clone-epel10-branches-with-clone-B.patch
@@ -0,0 +1,76 @@
+From 6511fa265649b0f36ee2acf7f9e99782c30d5c3f Mon Sep 17 00:00:00 2001
+From: Carl George <carlwgeorge@gmail.com>
+Date: Thu, 3 Oct 2024 01:10:16 -0500
+Subject: [PATCH 6/6] Clone epel10 branches with clone -B
+
+Running `fedpkg clone -B` relies on the configured branch regex to
+determine the branches to clone. The current regex doesn't match EPEL
+branches with more that one digit. We recently started having epel10
+branches, and in the future we'll also have epel10.0, epel10.1, and so
+forth. This adjusts the regex to account for these branch names.
+
+Merges: https://pagure.io/fedpkg/pull-request/572
+
+Signed-off-by: Carl George <carlwgeorge@gmail.com>
+---
+ conf/etc/rpkg/fedpkg-stage.conf | 2 +-
+ conf/etc/rpkg/fedpkg.conf | 2 +-
+ test/fedpkg-stage.conf | 2 +-
+ test/fedpkg-test.conf | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/conf/etc/rpkg/fedpkg-stage.conf b/conf/etc/rpkg/fedpkg-stage.conf
+index 87d66fe..e6f6f15 100644
+--- a/conf/etc/rpkg/fedpkg-stage.conf
++++ b/conf/etc/rpkg/fedpkg-stage.conf
+@@ -4,7 +4,7 @@ lookasidehash = sha512
+ lookaside_cgi = https://src.stg.fedoraproject.org/repo/pkgs/upload.cgi
+ gitbaseurl = ssh://%(user)s@pkgs.stg.fedoraproject.org/%(repo)s
+ anongiturl = https://src.stg.fedoraproject.org/%(repo)s.git
+-branchre = f\d$|f\d\d$|el\d$|olpc\d$|rawhide$
++branchre = f\d$|f\d\d$|epel\d+(?:\.\d+)?$|olpc\d$|rawhide$
+ kojiprofile = stg
+ build_client = koji
+ clone_config_rpms =
+diff --git a/conf/etc/rpkg/fedpkg.conf b/conf/etc/rpkg/fedpkg.conf
+index ed4c318..d7da904 100644
+--- a/conf/etc/rpkg/fedpkg.conf
++++ b/conf/etc/rpkg/fedpkg.conf
+@@ -4,7 +4,7 @@ lookasidehash = sha512
+ lookaside_cgi = https://src.fedoraproject.org/repo/pkgs/upload.cgi
+ gitbaseurl = ssh://%(user)s@pkgs.fedoraproject.org/%(repo)s
+ anongiturl = https://src.fedoraproject.org/%(repo)s.git
+-branchre = f\d$|f\d\d$|el\d$|olpc\d$|rawhide$
++branchre = f\d$|f\d\d$|epel\d+(?:\.\d+)?$|olpc\d$|rawhide$
+ kojiprofile = koji
+ build_client = koji
+ clone_config_rpms =
+diff --git a/test/fedpkg-stage.conf b/test/fedpkg-stage.conf
+index 14748a1..60fde62 100644
+--- a/test/fedpkg-stage.conf
++++ b/test/fedpkg-stage.conf
+@@ -4,7 +4,7 @@ gitbaseurl = ssh://%(user)s@pkgs.stg.example.com/%(repo)s
+ lookaside_cgi = https://pkgs.stg.example.com/repo/pkgs/upload.cgi
+ lookasidehash = sha512
+ lookaside = http://pkgs.stg.example.com/repo/pkgs
+-branchre = f\d$|f\d\d$|el\d$|olpc\d$|rawhide$
++branchre = f\d$|f\d\d$|epel\d+(?:\.\d+)?$|olpc\d$|rawhide$
+ kojiprofile = koji
+ build_client = koji
+ distgit_namespaced = True
+diff --git a/test/fedpkg-test.conf b/test/fedpkg-test.conf
+index 44b331a..51d2de3 100644
+--- a/test/fedpkg-test.conf
++++ b/test/fedpkg-test.conf
+@@ -4,7 +4,7 @@ gitbaseurl = ssh://%(user)s@pkgs.example.com/%(repo)s
+ lookaside_cgi = https://pkgs.example.com/repo/pkgs/upload.cgi
+ lookasidehash = sha512
+ lookaside = http://pkgs.example.com/repo/pkgs
+-branchre = f\d$|f\d\d$|el\d$|olpc\d$|rawhide$
++branchre = f\d$|f\d\d$|epel\d+(?:\.\d+)?$|olpc\d$|rawhide$
+ kojiprofile = koji
+ build_client = koji
+ distgit_namespaced = True
+--
+2.47.1
+
diff --git a/fedpkg.spec b/fedpkg.spec
index 5b26575..18138a1 100644
--- a/fedpkg.spec
+++ b/fedpkg.spec
@@ -5,7 +5,7 @@
Name: fedpkg
Version: 1.45
-Release: 5%{?dist}
+Release: 6%{?dist}
Summary: Fedora utility for working with dist-git
# Automatically converted from old format: GPLv2+ - review is highly recommended.
@@ -41,6 +41,12 @@ Patch24: 0024-Get-macros-from-epel-candidate-build-target.patch
Patch25: 0025-Improvements-on-string-parsing.patch
Patch26: 0026-Add-tests-cases-for-runtime_disttag-removal-when-wor.patch
Patch27: 0027-Handle-rhel-runtimes-when-minor-version-exists-in-di.patch
+Patch28: 0028-gitignore-the-name-version-build-directory-created-b.patch
+Patch29: 0029-Fixing-unittests-for-py36.patch
+Patch30: 0030-Fix-tests-on-EPEL-9-10.patch
+Patch31: 0031-Add-setuptools-to-dependencies-for-Python-3.12.patch
+Patch32: 0032-Update-expired-token-exception-instructions.patch
+Patch33: 0033-Clone-epel10-branches-with-clone-B.patch
BuildRequires: pkgconfig
BuildRequires: bash-completion
@@ -123,6 +129,14 @@ mv %{buildroot}%{compdir}/fedpkg.bash %{buildroot}%{compdir}/fedpkg
%changelog
+* Tue Jan 07 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-6
+- gitignore the name-version-build/ directory created by fedpkg prep/local
+- Fixing unittests for py36
+- Fix tests on EPEL 9/10.
+- Add setuptools to dependencies for Python 3.12+
+- Update expired token exception instructions
+- Clone epel10 branches with clone -B
+
* Wed Sep 18 2024 Ondřej Nosek <onosek@redhat.com> - 1.45-5
- Add py313 environment as that's current
- Drop support for bodhi-client <= 5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [rpms/fedpkg] 1.48-1: A few patches:
@ 2026-08-10 21:46
0 siblings, 0 replies; 4+ messages in thread
From: @ 2026-08-10 21:46 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/fedpkg
Branch : 1.48-1
Commit : 6c63bce5bb444e16de5465431185c0b9a6aed58b
Author : Ondřej Nosek <onosek@redhat.com>
Date : 2025-02-26T01:43:35+00:00
Stats : +462/-1 in 4 file(s)
URL : https://src.fedoraproject.org/rpms/fedpkg/c/6c63bce5bb444e16de5465431185c0b9a6aed58b?branch=1.48-1
Log:
A few patches:
- Dynamically exclude Rawhide branch from fedpkg branching
- Do not auto-request EPEL x.y modules
- Don't allow to request repositories in modules/ namespace
Signed-off-by: Ondřej Nosek <onosek@redhat.com>
---
diff --git a/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch b/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
new file mode 100644
index 0000000..a747965
--- /dev/null
+++ b/0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
@@ -0,0 +1,368 @@
+From ffe82116bf3bc01ea8a6bd57d7b1cac995e3b906 Mon Sep 17 00:00:00 2001
+From: Samyak Jain <samyak.jn11@gmail.com>
+Date: Thu, 3 Oct 2024 12:58:50 +0530
+Subject: [PATCH 1/3] Dynamically exclude Rawhide branch from fedpkg branching
+
+JIRA: RHELCMP-14182
+Fixes: #566
+Relates: https://pagure.io/releng/issue/12311
+Merges: https://pagure.io/fedpkg/pull-request/573
+
+Signed-off-by: Samyak Jain <samyak.jn11@gmail.com>
+---
+ fedpkg/cli.py | 4 +-
+ fedpkg/utils.py | 55 ++++++++++-----
+ test/test_utils.py | 165 ++++++++++++++++++++++++++++++++++-----------
+ test/utils.py | 1 -
+ 4 files changed, 170 insertions(+), 55 deletions(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index a4381a7..aa57451 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -1427,7 +1427,9 @@ class fedpkgClient(cliClient):
+ 'Package %s has stream branches: %r',
+ self.cmd.repo_name, [item for item in stream_branches])
+
+- if not self.is_stream_branch(stream_branches, self.cmd.branch_merge):
++ # rawhide was removed from the list of stream branches, but for rawhide branch
++ # the local config should be checked and therefore it has to skip this condition
++ if not self.is_stream_branch(stream_branches + ['rawhide'], self.cmd.branch_merge):
+ return super(fedpkgClient, self)._build(sets)
+
+ self.log.debug('Current branch %s is a stream branch.',
+diff --git a/fedpkg/utils.py b/fedpkg/utils.py
+index 4595c44..1ce9177 100644
+--- a/fedpkg/utils.py
++++ b/fedpkg/utils.py
+@@ -23,10 +23,10 @@ from urllib.parse import urlparse
+
+
+ def query_bodhi(server_url, timeout=60):
+- query_arg = '/?exclude_archived=True'
++ query_arg = '?exclude_archived=True'
+ api_url = '{0}/releases/{1}'.format(server_url.rstrip('/'), query_arg)
+ try:
+- rv = requests.get(api_url, timeout=60)
++ rv = requests.get(api_url, timeout=timeout)
+ except ConnectionError as error:
+ error_msg = ('The connection to BODHI failed while trying to get '
+ 'the active release branches. The error was: {0}'
+@@ -39,9 +39,19 @@ def query_bodhi(server_url, timeout=60):
+ raise rpkgError(base_error_msg.format(rv.text))
+
+ rv_json = rv.json()
+- if rv_json['releases']:
+- for branch in rv_json['releases']:
+- yield branch['branch']
++ branches = []
++
++ # Collect all branches, maintaining order
++ seen_branches = set()
++ for release in rv_json['releases']:
++ branch = release['branch']
++ if branch == 'rawhide':
++ branch = "f{0}".format(release['version']) # Replace 'rawhide' with the version
++ if branch not in seen_branches:
++ branches.append(branch)
++ seen_branches.add(branch)
++
++ return branches
+
+
+ def new_pagure_issue(logger, url, token, title, body, cli_name):
+@@ -244,20 +254,35 @@ def get_pagure_branches(logger, url, namespace, repo_name):
+
+ def get_release_branches(server_url):
+ """
+- Get the active Fedora release branches from Bodhi
++ Get the active Fedora release branches from Bodhi.
+
+- :param str url: a string of the URL to Bodhi
+- :return: a mapping containing the active Fedora releases and EPEL branches.
++ :param str server_url: The URL to Bodhi API.
++ :return: A mapping containing the active Fedora releases and EPEL branches, excluding rawhide.
+ :rtype: dict
+ """
++ # Fetch all branches from Bodhi
++ all_branches = query_bodhi(server_url)
++
+ releases = {}
+- for product_version in query_bodhi(server_url):
+- if product_version == "rawhide":
++ rawhide_branch = None
++
++ # Traverse the branches once to categorize and find the rawhide branch
++ for branch in all_branches:
++ # Assume the rawhide branch is the latest f-version branch
++ if branch.startswith('f') and branch[1:].isdigit():
++ # Check if this is the highest f-version, hence rawhide
++ if rawhide_branch is None or int(branch[1:]) > int(rawhide_branch[1:]):
++ rawhide_branch = branch
++
++ # Categorize branches into Fedora and EPEL, excluding rawhide
++ for branch in all_branches:
++ if branch == rawhide_branch:
+ continue
+- short_name = "fedora" if product_version.startswith("f") else "epel"
+- releases.setdefault(short_name, set()).add(product_version)
+
+- return {key: sorted(list(value)) for key, value in releases.items()}
++ short_name = "fedora" if branch.startswith("f") else "epel"
++ releases.setdefault(short_name, set()).add(branch)
++
++ return {key: sorted(value) for key, value in releases.items()}
+
+
+ def sl_list_to_dict(sls):
+@@ -454,7 +479,7 @@ def get_stream_branches(server_url, package_name, apibaseurl, logger):
+ release branch name.
+ :rtype: list
+ """
+- active_branches = set(query_bodhi(server_url))
++ active_branches = query_bodhi(server_url)
+
+ package_branches = get_pagure_branches(logger, apibaseurl, "rpms", package_name)
+
+@@ -464,7 +489,7 @@ def get_stream_branches(server_url, package_name, apibaseurl, logger):
+
+ stream_branches = []
+ for item in intersection:
+- if re.match(r'^(f|el)\d+$', item):
++ if re.match(r'^f\d+$', item):
+ continue
+ # epel7 is regular release branch
+ # epel8 and above should be considered a stream branch to use
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 19ad2f8..051e813 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -14,12 +14,11 @@ from configparser import NoOptionError, NoSectionError
+ import json
+ import unittest
+ from unittest.mock import Mock, patch
+-
+ from requests.exceptions import ConnectionError
+-
+ from fedpkg import utils
+ from freezegun import freeze_time
+ from pyrpkg.errors import rpkgError
++import requests
+
+
+ class TestUtils(unittest.TestCase):
+@@ -100,11 +99,18 @@ class TestUtils(unittest.TestCase):
+ {'name': 'F39', 'branch': 'f39'},
+ {'name': 'F39C', 'branch': 'f39'},
+ {'name': 'F39F', 'branch': 'f39'},
++ {'name': 'F40', 'branch': 'f40'},
++ {'name': 'F40C', 'branch': 'f40'},
++ {'name': 'F40F', 'branch': 'f40'},
++ {'name': 'F41', 'branch': 'f41'},
++ {'name': 'F41C', 'branch': 'f41'},
++ {'name': 'F41F', 'branch': 'f41'},
++ {'name': 'F42', 'branch': 'f42'},
+ ], 'page': 1, 'pages': 1, 'rows_per_page': 20, 'total': 12}
+ mock_request_get.return_value = mock_rv
+ expected = {
+ 'epel': ['epel7', 'epel8', 'epel8-next', 'epel9', 'epel9-next'],
+- 'fedora': ['f38', 'f38m', 'f39'],
++ 'fedora': ['f38', 'f38m', 'f39', 'f40', 'f41'],
+ }
+ actual = utils.get_release_branches('http://src.local')
+ actual_sorted = {key: sorted(value) for key, value in sorted(actual.items())}
+@@ -434,43 +440,101 @@ class TestNewPagureIssue(unittest.TestCase):
+
+ @patch("requests.get")
+ class TestQueryBodhi(unittest.TestCase):
+- """Test utils.query_bodhi"""
++ """Test suite for utils.query_bodhi"""
+
+- def test_connection_error(self, get):
+- get.side_effect = ConnectionError
++ def test_connection_error(self, mock_get):
++ """Test that a ConnectionError raises an rpkgError with the correct message."""
++ # Simulate a connection error when making the get request
++ mock_get.side_effect = requests.exceptions.ConnectionError('Mocked connection error')
++
++ with self.assertRaises(rpkgError) as cm:
++ utils.query_bodhi('http://localhost/')
++
++ self.assertIn(
++ 'The connection to BODHI failed while trying to get the active release branches. '
++ 'The error was: Mocked connection error',
++ str(cm.exception),
++ "Expected error message is missing or incorrect"
++ )
++
++ def test_response_not_ok(self, mock_get):
++ """Test that a non-OK response raises an rpkgError with the correct message."""
++ # Mock a response with .ok as False and a text message
++ mock_rv = Mock()
++ mock_rv.ok = False
++ mock_rv.text = 'Mocked error message'
++ mock_get.return_value = mock_rv
++
++ with self.assertRaises(rpkgError) as cm:
++ utils.query_bodhi('http://localhost/')
+
++ self.assertIn(
++ 'The following error occurred while trying to get the active release '
++ 'branches in Bodhi: Mocked error message',
++ str(cm.exception),
++ "Expected error message is missing or incorrect"
++ )
++
++ def test_read_data_normally(self, mock_get):
++ """Test that query_bodhi returns the correct branch list from a normal response."""
++ # Mock a valid response from the Bodhi API
++ mock_rv = Mock()
++ mock_rv.ok = True
++ mock_rv.json.return_value = {
++ 'releases': [
++ {'name': 'F40', 'branch': 'f40'},
++ {'name': 'F41', 'branch': 'f41'},
++ {'name': 'Rawhide Release', 'branch': 'rawhide', 'version': '42'},
++ {'name': 'EPEL9', 'branch': 'epel9'},
++ {'name': 'EPEL8', 'branch': 'epel8'}
++ ]
++ }
++ mock_get.return_value = mock_rv
++
++ # The expected branch list to be returned by query_bodhi
++ expected = ['f40', 'f41', 'f42', 'epel9', 'epel8']
++
++ # Call query_bodhi and compare the result to the expected list
+ result = utils.query_bodhi('http://localhost/')
+- self.assertRaisesRegex(
+- rpkgError, 'The connection to BODHI failed',
+- list, result)
++ self.assertEqual(result, expected, f"Expected branches {expected}, but got {result}")
+
+- def test_response_not_ok(self, get):
+- get.return_value.ok = False
++ def test_rawhide_not_present(self, mock_get):
++ """Test that if rawhide is not present in the releases,
++ it does not construct a rawhide branch."""
++ # Mock a response without a rawhide entry
++ mock_rv = Mock()
++ mock_rv.ok = True
++ mock_rv.json.return_value = {
++ 'releases': [
++ {'name': 'F40', 'branch': 'f40'},
++ {'name': 'F41', 'branch': 'f41'},
++ {'name': 'EPEL9', 'branch': 'epel9'},
++ {'name': 'EPEL8', 'branch': 'epel8'}
++ ]
++ }
++ mock_get.return_value = mock_rv
++
++ # The expected branch list without a rawhide branch
++ expected = ['f40', 'f41', 'epel9', 'epel8']
+
++ # Call query_bodhi and compare the result to the expected list
+ result = utils.query_bodhi('http://localhost/')
+- self.assertRaisesRegex(
+- rpkgError, 'The following error occurred',
+- list, result)
++ self.assertEqual(result, expected, f"Expected branches {expected}, but got {result}")
+
+- def test_read_yield_data_normally(self, get):
+- rv = Mock()
+- rv.ok = True
+- rv.json.side_effect = [
+- {'releases': [
+- {'name': 'item1', 'branch': 'item2'},
+- {'name': 'item5', 'branch': 'item6'},
+- {'name': 'item3', 'branch': 'item4'},
+- ]}
+- ]
+- get.return_value = rv
++ def test_empty_releases(self, mock_get):
++ """Test that an empty releases list returns an empty branches list."""
++ # Mock a response with no releases
++ mock_rv = Mock()
++ mock_rv.ok = True
++ mock_rv.json.return_value = {'releases': []}
++ mock_get.return_value = mock_rv
++
++ # Expected branches should be an empty list
++ expected = []
+
++ # Call query_bodhi and compare the result to the expected empty list
+ result = utils.query_bodhi('http://localhost/')
+- v = next(result)
+- self.assertEqual('item2', v)
+- v = next(result)
+- self.assertEqual('item6', v)
+- v = next(result)
+- self.assertEqual('item4', v)
++ self.assertEqual(result, expected, "Expected an empty list of branches, but got some")
+
+
+ class TestGetStreamBranches(unittest.TestCase):
+@@ -482,13 +546,18 @@ class TestGetStreamBranches(unittest.TestCase):
+ logger = Mock()
+ apibaseurl = "https://bodhiurl"
+ rv = Mock(ok=True)
+- rv.json.return_value = {'releases': [
+- {'name': 'ELN', 'branch': 'eln'},
+- {'name': 'F40', 'branch': 'rawhide'},
+- {'name': 'F40C', 'branch': 'f40'},
+- {'name': 'epel8', 'branch': 'epel8'},
+- ], 'page': 1, 'pages': 1, 'rows_per_page': 20, 'total': 3}
+- {'releases': [], 'page': 1, 'pages': 0, 'rows_per_page': 20, 'total': 0}
++ rv.json.return_value = {
++ 'releases': [
++ {'name': 'ELN', 'branch': 'eln', 'version': '8'},
++ {'name': 'F40', 'branch': 'rawhide', 'version': '40'},
++ {'name': 'F40C', 'branch': 'f40', 'version': '40'},
++ {'name': 'epel8', 'branch': 'epel8', 'version': '8'},
++ ],
++ 'page': 1,
++ 'pages': 1,
++ 'rows_per_page': 20,
++ 'total': 4
++ }
+ get.return_value = rv
+ pagure_branches.return_value = ["epel7", "epel8", "epel9", "f38", "f39"]
+
+@@ -573,3 +642,23 @@ class TestGetFedoraReleaseState(unittest.TestCase):
+ self.assertRaisesRegex(rpkgError, r"Could not get release state for Fedora \(F30M\): "
+ "No option 'releases_service' in section: 'fedpkg.bodhi'.",
+ utils.get_fedora_release_state, config, 'fedpkg', 'F30M')
++
++
++class TestGetReleaseBranches(unittest.TestCase):
++ """Test utils.get_release_branches"""
++
++ @patch('fedpkg.utils.query_bodhi')
++ def test_get_release_branches_excludes_rawhide(self, mock_query_bodhi):
++ """Test that get_release_branches correctly excludes the rawhide branch."""
++ # Mocking the branches returned by query_bodhi
++ mock_query_bodhi.return_value = ['f40', 'f41', 'f42', 'epel9', 'epel8'] # f42 is rawhide
++
++ expected_output = {
++ 'fedora': ['f40', 'f41'],
++ 'epel': ['epel8', 'epel9']
++ }
++
++ # Run the method and assert that rawhide branch (f42) is excluded
++ result = utils.get_release_branches('https://bodhi.fedoraproject.org/releases/')
++ self.assertEqual(result, expected_output,
++ msg=f"Expected branches {expected_output}, but got {result}")
+diff --git a/test/utils.py b/test/utils.py
+index b4ce20c..f4e71f3 100644
+--- a/test/utils.py
++++ b/test/utils.py
+@@ -17,7 +17,6 @@ import shutil
+ import subprocess
+ import tempfile
+ import unittest
+-
+ import fedpkg.cli
+ import pyrpkg
+ from fedpkg import Commands
+--
+2.48.1
+
diff --git a/0039-Do-not-auto-request-EPEL-x.y-modules.patch b/0039-Do-not-auto-request-EPEL-x.y-modules.patch
new file mode 100644
index 0000000..76a92fc
--- /dev/null
+++ b/0039-Do-not-auto-request-EPEL-x.y-modules.patch
@@ -0,0 +1,40 @@
+From d8df43d8e7a2bbd0ad82318b173d00ffe0b55c3b Mon Sep 17 00:00:00 2001
+From: Carl George <carlwgeorge@gmail.com>
+Date: Wed, 19 Feb 2025 02:00:27 -0600
+Subject: [PATCH 2/3] Do not auto-request EPEL x.y modules
+
+After the EPEL 10.0 mass branching, we discovered that running `fedpkg
+request-branch epel10.0` would file SCM requests for:
+
+- New Branch "epel10.0" for "rpms/<name>"
+- New Repo for "modules/<name>"
+- New Branch "epel10.0" for "modules/<name>"
+
+The second two are invalid and unwanted. Thankfully Fabio Valentini
+(@decathorpe) noticed that this was similar to what was happening for
+ELN a while back, an pointed me to RELEASE_BRANCH_REGEX. This adjust
+that regex to also accept EPEL minor version branches.
+
+Related: #564
+
+Signed-off-by: Carl George <carlwgeorge@gmail.com>
+---
+ fedpkg/cli.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index aa57451..33dbd91 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -46,7 +46,7 @@ from fedpkg.utils import (assert_new_tests_repo, assert_valid_epel_package,
+ get_release_branches, get_stream_branches, is_epel,
+ new_pagure_issue, sl_list_to_dict, verify_sls)
+
+-RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|eln|epel\d+)$'
++RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|eln|epel\d+|epel\d+\.\d+)$'
+ LOCAL_PACKAGE_CONFIG = 'package.cfg'
+
+ BODHI_TEMPLATE = """\
+--
+2.48.1
+
diff --git a/0040-Don-t-allow-to-request-repositories-in-modules-names.patch b/0040-Don-t-allow-to-request-repositories-in-modules-names.patch
new file mode 100644
index 0000000..7d7c52f
--- /dev/null
+++ b/0040-Don-t-allow-to-request-repositories-in-modules-names.patch
@@ -0,0 +1,45 @@
+From d3db72608e395720857d2eb91fe81627991c1454 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
+Date: Sat, 22 Feb 2025 19:17:10 +0100
+Subject: [PATCH 3/3] Don't allow to request repositories in modules/ namespace
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are no new modules in Fedora distgit.
+
+Signed-off-by: Miro Hrončok <miro@hroncok.cz>
+---
+ conf/etc/rpkg/fedpkg-stage.conf | 2 +-
+ conf/etc/rpkg/fedpkg.conf | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/conf/etc/rpkg/fedpkg-stage.conf b/conf/etc/rpkg/fedpkg-stage.conf
+index e6f6f15..d33b4cc 100644
+--- a/conf/etc/rpkg/fedpkg-stage.conf
++++ b/conf/etc/rpkg/fedpkg-stage.conf
+@@ -26,7 +26,7 @@ clone_config_container =
+ bz.default-component %(repo)s
+ sendemail.to container-%(repo)s-maintainers@fedoraproject.org
+ distgit_namespaced = True
+-distgit_namespaces = rpms container modules flatpaks
++distgit_namespaces = rpms container flatpaks
+ lookaside_namespaced = True
+ kerberos_realms = STG.FEDORAPROJECT.ORG
+ oidc_id_provider = https://id.stg.fedoraproject.org/openidc/
+diff --git a/conf/etc/rpkg/fedpkg.conf b/conf/etc/rpkg/fedpkg.conf
+index d7da904..fa08a8a 100644
+--- a/conf/etc/rpkg/fedpkg.conf
++++ b/conf/etc/rpkg/fedpkg.conf
+@@ -26,7 +26,7 @@ clone_config_container =
+ bz.default-component %(repo)s
+ sendemail.to container-%(repo)s-maintainers@fedoraproject.org
+ distgit_namespaced = True
+-distgit_namespaces = rpms container modules flatpaks
++distgit_namespaces = rpms container flatpaks
+ lookaside_namespaced = True
+ kerberos_realms = FEDORAPROJECT.ORG
+ oidc_id_provider = https://id.fedoraproject.org/openidc/
+--
+2.48.1
+
diff --git a/fedpkg.spec b/fedpkg.spec
index 33ea85c..a4dab3a 100644
--- a/fedpkg.spec
+++ b/fedpkg.spec
@@ -5,7 +5,7 @@
Name: fedpkg
Version: 1.45
-Release: 9%{?dist}
+Release: 10%{?dist}
Summary: Fedora utility for working with dist-git
# Automatically converted from old format: GPLv2+ - review is highly recommended.
@@ -51,6 +51,9 @@ Patch34: 0034-Update-expired-token-exception-instructions.patch
Patch35: 0035-releases-info-should-always-show-the-same-order.patch
Patch36: 0036-Python-3.13-environment-and-renew-testing-image.patch
Patch37: 0037-Fix-unittests-when-building-for-ELN-target.patch
+Patch38: 0038-Dynamically-exclude-Rawhide-branch-from-fedpkg-branc.patch
+Patch39: 0039-Do-not-auto-request-EPEL-x.y-modules.patch
+Patch40: 0040-Don-t-allow-to-request-repositories-in-modules-names.patch
BuildRequires: pkgconfig
BuildRequires: bash-completion
@@ -133,6 +136,11 @@ mv %{buildroot}%{compdir}/fedpkg.bash %{buildroot}%{compdir}/fedpkg
%changelog
+* Wed Feb 26 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-10
+- Dynamically exclude Rawhide branch from fedpkg branching
+- Do not auto-request EPEL x.y modules
+- Don't allow to request repositories in modules/ namespace
+
* Tue Feb 18 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-9
- `releases-info` should always show the same order
- Python 3.13 environment and renew testing image
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [rpms/fedpkg] 1.48-1: A few patches:
@ 2026-08-10 21:46
0 siblings, 0 replies; 4+ messages in thread
From: @ 2026-08-10 21:46 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/fedpkg
Branch : 1.48-1
Commit : f9f53f99a384e8df950d856b66327c4dcee7dd14
Author : Ondřej Nosek <onosek@redhat.com>
Date : 2025-02-18T02:29:14+00:00
Stats : +173/-1 in 4 file(s)
URL : https://src.fedoraproject.org/rpms/fedpkg/c/f9f53f99a384e8df950d856b66327c4dcee7dd14?branch=1.48-1
Log:
A few patches:
- `releases-info` should always show the same order
- Python 3.13 environment and renew testing image
- Fix unittests when building for ELN target
Signed-off-by: Ondřej Nosek <onosek@redhat.com>
---
diff --git a/0035-releases-info-should-always-show-the-same-order.patch b/0035-releases-info-should-always-show-the-same-order.patch
new file mode 100644
index 0000000..a601452
--- /dev/null
+++ b/0035-releases-info-should-always-show-the-same-order.patch
@@ -0,0 +1,32 @@
+From d8f18b789de07a375bc63787ee1964cb16f0aa1b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Wed, 22 Jan 2025 04:36:16 +0100
+Subject: [PATCH 1/3] `releases-info` should always show the same order
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes: #569
+JIRA: RHELCMP-14101
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ fedpkg/utils.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fedpkg/utils.py b/fedpkg/utils.py
+index dbee142..4595c44 100644
+--- a/fedpkg/utils.py
++++ b/fedpkg/utils.py
+@@ -257,7 +257,7 @@ def get_release_branches(server_url):
+ short_name = "fedora" if product_version.startswith("f") else "epel"
+ releases.setdefault(short_name, set()).add(product_version)
+
+- return {key: list(value) for key, value in releases.items()}
++ return {key: sorted(list(value)) for key, value in releases.items()}
+
+
+ def sl_list_to_dict(sls):
+--
+2.48.1
+
diff --git a/0036-Python-3.13-environment-and-renew-testing-image.patch b/0036-Python-3.13-environment-and-renew-testing-image.patch
new file mode 100644
index 0000000..15267d0
--- /dev/null
+++ b/0036-Python-3.13-environment-and-renew-testing-image.patch
@@ -0,0 +1,75 @@
+From 1603cdac055fbf2166c332fd46e8293fe1323584 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Wed, 29 Jan 2025 03:30:49 +0100
+Subject: [PATCH 2/3] Python 3.13 environment and renew testing image
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+JIRA: RHELCMP-14330
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ README.rst | 2 +-
+ jenkins_test.dockerfile | 3 ++-
+ pyproject.toml | 1 +
+ setup.py | 1 +
+ 4 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/README.rst b/README.rst
+index 7af6c69..f25b0f5 100644
+--- a/README.rst
++++ b/README.rst
+@@ -3,7 +3,7 @@ Introduction
+
+ This is the fedpkg project, which mostly is a subclass of the rpkg project.
+
+-fedpkg works with Python 3.6, 3.9, 3.12
++fedpkg works with Python 3.6, 3.9, 3.12 and 3.13
+
+ License
+ =======
+diff --git a/jenkins_test.dockerfile b/jenkins_test.dockerfile
+index b4a2af8..f848fd2 100644
+--- a/jenkins_test.dockerfile
++++ b/jenkins_test.dockerfile
+@@ -1,4 +1,4 @@
+-FROM fedora:39
++FROM fedora:41
+ LABEL \
+ name="fedpkg test" \
+ description="Run tests using tox with Python 3" \
+@@ -9,6 +9,7 @@ RUN dnf -y update && dnf -y install \
+ python3-setuptools \
+ rpm-build \
+ python3-tox \
++ python3.6 \
+ gcc \
+ libcurl-devel \
+ krb5-devel \
+diff --git a/pyproject.toml b/pyproject.toml
+index fdc00ad..32fe550 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -20,6 +20,7 @@ classifiers = [
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.12",
++ "Programming Language :: Python :: 3.13",
+ "Topic :: Software Development :: Build Tools",
+ ]
+ dependencies = [
+diff --git a/setup.py b/setup.py
+index fbe34d7..ea8a8e1 100755
+--- a/setup.py
++++ b/setup.py
+@@ -67,5 +67,6 @@ setup(
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.12',
++ 'Programming Language :: Python :: 3.13',
+ ],
+ )
+--
+2.48.1
+
diff --git a/0037-Fix-unittests-when-building-for-ELN-target.patch b/0037-Fix-unittests-when-building-for-ELN-target.patch
new file mode 100644
index 0000000..2064d0f
--- /dev/null
+++ b/0037-Fix-unittests-when-building-for-ELN-target.patch
@@ -0,0 +1,57 @@
+From 215c7add2f131c011fcdf19aa097f460a512e129 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Tue, 18 Feb 2025 01:25:08 +0100
+Subject: [PATCH 3/3] Fix unittests when building for ELN target
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+JIRA: RHELCMP-14347
+Fixes: #589
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ test/test_cli.py | 3 ++-
+ test/test_commands.py | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/test/test_cli.py b/test/test_cli.py
+index d201e7f..f002f65 100644
+--- a/test/test_cli.py
++++ b/test/test_cli.py
+@@ -2270,13 +2270,14 @@ class TestBuildFromStreamBranch(CliTestCase):
+
+ _build.assert_called_once_with(None)
+
++ @patch('distro.os_release_info', return_value={'variant': 'non-ELN'})
+ @patch('pyrpkg.cli.cliClient._build')
+ @patch('fedpkg.Commands.build_target')
+ @patch('fedpkg.cli.get_stream_branches')
+ @patch('fedpkg.cli.get_release_branches')
+ def test_submit_builds(
+ self, get_release_branches, get_stream_branches, build_target,
+- _build):
++ _build, os_release_info):
+ get_release_branches.return_value = {
+ 'fedora': ['f28', 'f27'],
+ 'epel': ['epel7', 'epel8', 'epel9'],
+diff --git a/test/test_commands.py b/test/test_commands.py
+index b08a7fe..a168335 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -23,10 +23,11 @@ class TestDetermineRuntimeEnv(CommandTestCase):
+ super(TestDetermineRuntimeEnv, self).setUp()
+ self.cmd = self.make_commands()
+
++ @patch('distro.os_release_info', return_value={'variant': 'non-ELN'})
+ @patch('distro.id', return_value='fedora')
+ @patch('distro.like', return_value='')
+ @patch('distro.major_version', return_value='25')
+- def test_return_fedora_disttag(self, mock_ver, mock_like, mock_id):
++ def test_return_fedora_disttag(self, mock_ver, mock_like, mock_id, mock_release_info):
+ result = self.cmd._determine_runtime_env()
+ self.assertEqual('fc25', result)
+
+--
+2.48.1
+
diff --git a/fedpkg.spec b/fedpkg.spec
index 0ea7b44..33ea85c 100644
--- a/fedpkg.spec
+++ b/fedpkg.spec
@@ -5,7 +5,7 @@
Name: fedpkg
Version: 1.45
-Release: 8%{?dist}
+Release: 9%{?dist}
Summary: Fedora utility for working with dist-git
# Automatically converted from old format: GPLv2+ - review is highly recommended.
@@ -48,6 +48,9 @@ Patch31: 0031-Add-setuptools-to-dependencies-for-Python-3.12.patch
Patch32: 0032-Update-expired-token-exception-instructions.patch
Patch33: 0033-Clone-epel10-branches-with-clone-B.patch
Patch34: 0034-Update-expired-token-exception-instructions.patch
+Patch35: 0035-releases-info-should-always-show-the-same-order.patch
+Patch36: 0036-Python-3.13-environment-and-renew-testing-image.patch
+Patch37: 0037-Fix-unittests-when-building-for-ELN-target.patch
BuildRequires: pkgconfig
BuildRequires: bash-completion
@@ -130,6 +133,11 @@ mv %{buildroot}%{compdir}/fedpkg.bash %{buildroot}%{compdir}/fedpkg
%changelog
+* Tue Feb 18 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-9
+- `releases-info` should always show the same order
+- Python 3.13 environment and renew testing image
+- Fix unittests when building for ELN target
+
* Mon Feb 17 2025 Ondřej Nosek <onosek@redhat.com> - 1.45-8
- Patch: Update expired token exception instructions
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [rpms/fedpkg] 1.48-1: A few patches:
@ 2026-08-10 21:46
0 siblings, 0 replies; 4+ messages in thread
From: @ 2026-08-10 21:46 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/fedpkg
Branch : 1.48-1
Commit : 7185284dac1eaabaa38a57911848b65aa0b8ed72
Author : Ondřej Nosek <onosek@redhat.com>
Date : 2024-09-18T04:20:46+00:00
Stats : +2405/-3 in 17 file(s)
URL : https://src.fedoraproject.org/rpms/fedpkg/c/7185284dac1eaabaa38a57911848b65aa0b8ed72?branch=1.48-1
Log:
A few patches:
Various modernizations, including dropping use of python-fedora and support for bodhi-client < 6
by Adam Williamson:
- Add py313 environment as that's current
- Drop support for bodhi-client <= 5
- Drop all usage of six
- Replace and update use of deprecated 'linux_distribution'
- Modernize and clean unittest imports
- Update check_bodhi_version to check for >= 6.0.0
- Fix URL of Bodhi in staging
- Fixes missing key in distro.os_release_info()
- Do not auto-request ELN modules
Get EPEL10 minor version from koji when it's not available from the branch name
by Diego Herreraa:
- Fix minor requirements for EPEL10+ in test
- Use minor value from koji when no minor in branch name
- Fix EPEL10 branch expression to cover 2 or more digits.
- Get macros from epel-candidate build target.
- Improvements on string parsing
- Add tests cases for runtime_disttag removal when working with epel10
- Handle rhel runtimes when minor version exists in disttag
Signed-off-by: Ondřej Nosek <onosek@redhat.com>
---
diff --git a/0012-Add-py313-environment-as-that-s-current.patch b/0012-Add-py313-environment-as-that-s-current.patch
new file mode 100644
index 0000000..654f15a
--- /dev/null
+++ b/0012-Add-py313-environment-as-that-s-current.patch
@@ -0,0 +1,69 @@
+From d1246d9972c892b5db9ea98d971b3269675b0346 Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 18:53:56 -0400
+Subject: [PATCH 1/6] Add py313 environment as that's current
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ Jenkinsfile | 2 +-
+ Makefile | 2 +-
+ jenkins_test.dockerfile | 2 +-
+ tox.ini | 3 ++-
+ 4 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/Jenkinsfile b/Jenkinsfile
+index b4eaa28..253e7d9 100644
+--- a/Jenkinsfile
++++ b/Jenkinsfile
+@@ -53,7 +53,7 @@ git merge --no-ff "proposed/$params.BRANCH" -m "Merge PR"
+ git clone https://pagure.io/rpkg.git
+ # docker image will contain ENV: PYTHONPATH=./rpkg
+
+-podman run --rm -v .:/src:Z quay.io/exd-guild-source-tools/fedpkg-test:latest tox -e py36,py39,py312,flake8,bandit --workdir /tmp/tox ${TOX_POSARGS}
++podman run --rm -v .:/src:Z quay.io/exd-guild-source-tools/fedpkg-test:latest tox -e py36,py39,py312,py313,flake8,bandit --workdir /tmp/tox ${TOX_POSARGS}
+ """
+ sh "cat job.sh"
+ sh "ssh -o StrictHostKeyChecking=no root@$hostname mkdir $remote_dir"
+diff --git a/Makefile b/Makefile
+index a935264..0e28977 100644
+--- a/Makefile
++++ b/Makefile
+@@ -5,5 +5,5 @@ test: $(default_targets)
+ tox:
+ @python3 -m venv .env
+ @.env/bin/pip install tox
+- @.env/bin/tox -e py36,py39,py312,flake --parallel=auto ${TOX_POSARGS}
++ @.env/bin/tox -e py36,py39,py312,py313,flake8 --parallel=auto ${TOX_POSARGS}
+ .PHONY: tox
+diff --git a/jenkins_test.dockerfile b/jenkins_test.dockerfile
+index 9628fc5..b4a2af8 100644
+--- a/jenkins_test.dockerfile
++++ b/jenkins_test.dockerfile
+@@ -22,4 +22,4 @@ WORKDIR /src
+
+ ENV PYTHONPATH "${PYTHONPATH}:./rpkg"
+
+-CMD ["tox", "-e", "py36,py39,py312,flake8,bandit"]
++CMD ["tox", "-e", "py36,py39,py312,py313,flake8,bandit"]
+diff --git a/tox.ini b/tox.ini
+index 3498249..ea4dc6b 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -1,5 +1,5 @@
+ [tox]
+-envlist = py36,py39,py312,flake8,doc,bandit
++envlist = py36,py39,py312,py313,flake8,doc,bandit
+
+ [testenv]
+ sitepackages=false
+@@ -7,6 +7,7 @@ basepython=
+ py36: {env:TOXPYTHON:python3.6}
+ py39: {env:TOXPYTHON:python3.9}
+ py312: {env:TOXPYTHON:python3.12}
++ py313: {env:TOXPYTHON:python3.13}
+ flake8: {env:TOXPYTHON:python3.6}
+ doc: {env:TOXPYTHON:python3}
+ bandit: {env:TOXPYTHON:python3}
+--
+2.46.0
+
diff --git a/0013-Drop-support-for-bodhi-client-5.patch b/0013-Drop-support-for-bodhi-client-5.patch
new file mode 100644
index 0000000..44dd825
--- /dev/null
+++ b/0013-Drop-support-for-bodhi-client-5.patch
@@ -0,0 +1,430 @@
+From cca0ca9ceed6c31c1f8ae56a2ffeefba603c39dc Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 09:14:36 -0400
+Subject: [PATCH 2/6] Drop support for bodhi-client <= 5
+
+It cannot possibly work any more, since OpenID auth no longer
+works on our current Bodhi deployments and will not be "fixed",
+and bodhi-client < 6 cannot authenticate any other way.
+
+This is the last usage of python-fedora in fedpkg, so we can
+drop that dependency. We also drop some now-unnecessary checks
+and conditionals.
+
+Keeping limited fedpkg's functionality without communication
+with Bodhi on EPEL 8 (Python 3.6).
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ fedpkg/__init__.py | 22 ++----
+ fedpkg/bodhi_5.py | 63 -----------------
+ pyproject.toml | 1 -
+ requirements.txt | 1 -
+ test/test_cli.py | 171 +++++++--------------------------------------
+ 5 files changed, 30 insertions(+), 228 deletions(-)
+ delete mode 100644 fedpkg/bodhi_5.py
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index b3e9b3b..dca48da 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -19,17 +19,14 @@ from datetime import datetime, timedelta, timezone
+
+ # doc/fedpkg_man_page.py uses the 'cli' import
+ from . import cli # noqa
+-from .lookaside import FedoraLookasideCache
+-from pyrpkg.utils import cached_property
+-# Use deprecated pkg_resources if importlib isn't available (python 3.6)
+-try:
+- from importlib.metadata import distribution
+-except ImportError:
+- from pkg_resources import get_distribution as distribution
++
+ try:
+- from packaging.version import parse as parse_version
++ from .bodhi_6 import BodhiClient, UPDATE_TYPES, REQUEST_TYPES, SUGGEST_TYPES
+ except ImportError:
+- from pkg_resources import parse_version
++ # working bodhi-client is not available for el8 (Python3.6)
++ BodhiClient = None
++from .lookaside import FedoraLookasideCache
++from pyrpkg.utils import cached_property
+
+ try:
+ from distro import linux_distribution # noqa
+@@ -37,13 +34,6 @@ except ImportError:
+ from platform import linux_distribution # noqa
+
+
+-bodhi_version = distribution('bodhi-client').version
+-if parse_version(bodhi_version) < parse_version("6.0.0"):
+- from .bodhi_5 import BodhiClient, UPDATE_TYPES, REQUEST_TYPES, SUGGEST_TYPES
+-else:
+- from .bodhi_6 import BodhiClient, UPDATE_TYPES, REQUEST_TYPES, SUGGEST_TYPES
+-
+-
+ class Commands(pyrpkg.Commands):
+
+ def __init__(self, *args, **kwargs):
+diff --git a/fedpkg/bodhi_5.py b/fedpkg/bodhi_5.py
+deleted file mode 100644
+index 9ffa1df..0000000
+--- a/fedpkg/bodhi_5.py
++++ /dev/null
+@@ -1,63 +0,0 @@
+-# fedpkg - a Python library for RPM Packagers
+-#
+-# Copyright (C) 2011 Red Hat Inc.
+-# Author(s): Jesse Keating <jkeating@redhat.com>
+-#
+-# This program is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License as published by the
+-# Free Software Foundation; either version 2 of the License, or (at your
+-# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+-# the full text of the license.
+-
+-from bodhi.client.bindings import BodhiClient as _BodhiClient
+-from fedora.client import AuthError
+-
+-
+-UPDATE_TYPES = ['bugfix', 'security', 'enhancement', 'newpackage']
+-REQUEST_TYPES = ['testing', 'stable']
+-SUGGEST_TYPES = ['unspecified', 'reboot', 'logout']
+-
+-
+-def clear_csrf_and_retry(func):
+- """Clear csrf token and retry
+-
+- fedpkg uses Bodhi Python binding API list_overrides first before other
+- save and extend APIs. That causes a readonly csrf token is received,
+- which will be got again when next time to construct request data to
+- modify updates. That is not expected and AuthError will be raised.
+-
+- So, the solution is to capture the AuthError error, clear the token and
+- try to modify update again by requesting another token with user's
+- credential.
+- """
+- def _decorator(self, *args, **kwargs):
+- try:
+- return func(self, *args, **kwargs)
+- except AuthError:
+- self._session.cookies.clear()
+- self.csrf_token = None
+- return func(self, *args, **kwargs)
+- return _decorator
+-
+-
+-class BodhiClient(_BodhiClient):
+- """Customized BodhiClient for fedpkg"""
+-
+- @clear_csrf_and_retry
+- def save(self, *args, **kwargs):
+- return super(BodhiClient, self).save(*args, **kwargs)
+-
+- @clear_csrf_and_retry
+- def save_override(self, *args, **kwargs):
+- return super(BodhiClient, self).save_override(*args, **kwargs)
+-
+- @clear_csrf_and_retry
+- def extend_override(self, override, expiration_date):
+- data = dict(
+- nvr=override['nvr'],
+- notes=override['notes'],
+- expiration_date=expiration_date,
+- csrf_token=self.csrf(),
+- )
+- return self.send_request(
+- 'overrides/', verb='POST', auth=True, data=data)
+diff --git a/pyproject.toml b/pyproject.toml
+index 1be99b5..ac60b0f 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -28,7 +28,6 @@ dependencies = [
+ "distro",
+ "openidc-client",
+ "python-bugzilla",
+- "python-fedora",
+ "rpkg",
+ "six",
+ ]
+diff --git a/requirements.txt b/requirements.txt
+index cb3de2c..7e52a2c 100644
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -2,6 +2,5 @@ argcomplete
+ bodhi-client
+ openidc-client
+ python-bugzilla
+-python-fedora
+ rpkg
+ six
+diff --git a/test/test_cli.py b/test/test_cli.py
+index 3aa6737..c819614 100644
+--- a/test/test_cli.py
++++ b/test/test_cli.py
+@@ -26,13 +26,17 @@ try:
+ from packaging.version import parse as parse_version
+ except ImportError:
+ from pkg_resources import parse_version
++# Use deprecated pkg_resources if importlib isn't available (python 3.6)
++try:
++ from importlib.metadata import distribution
++except ImportError:
++ from pkg_resources import get_distribution as distribution
+
+ import six
+ from six.moves import StringIO
+ from six.moves.configparser import NoOptionError, NoSectionError
+
+ import fedpkg.cli
+-from fedpkg import bodhi_version
+ from fedpkg.bugzilla import BugzillaClient
+ from fedpkg.cli import check_bodhi_version
+ from freezegun import freeze_time
+@@ -51,7 +55,8 @@ except ImportError:
+
+ try:
+ import bodhi
+- if parse_version(bodhi_version) < parse_version("5.0.0"):
++ bodhi_version = distribution('bodhi-client').version
++ if parse_version(bodhi_version) < parse_version("6.0.0"):
+ raise ImportError("Unsupported bodhi-client")
+ except ImportError:
+ bodhi = None
+@@ -150,11 +155,10 @@ class TestUpdate(CliTestCase):
+ with io.open(clog_file, 'w', encoding='utf-8') as f:
+ f.write(os.linesep.join(self.fake_clog))
+
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher = patch(
+- 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
+- )
+- self.oidcmeta_patcher.start()
++ self.oidcmeta_patcher = patch(
++ 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
++ )
++ self.oidcmeta_patcher.start()
+
+ def tearDown(self):
+ if os.path.exists('bodhi.template'):
+@@ -168,8 +172,7 @@ class TestUpdate(CliTestCase):
+ self.check_bodhi_version_patcher.stop()
+ self.run_command_patcher.stop()
+ self.nvr_patcher.stop()
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher.stop()
++ self.oidcmeta_patcher.stop()
+ rmdir(self.tempdir)
+ super(TestUpdate, self).tearDown()
+
+@@ -179,9 +182,7 @@ class TestUpdate(CliTestCase):
+
+ @patch('bodhi.client.bindings.BodhiClient.csrf')
+ @patch('bodhi.client.bindings.BodhiClient.send_request')
+- # Do not operate OpenIDC session file with lock
+- @patch('fedora.client.OpenIdBaseClient._load_cookies')
+- def assert_bodhi_update(self, cli, _load_cookies, send_request, csrf,
++ def assert_bodhi_update(self, cli, send_request, csrf,
+ update_type=None, request_type=None, notes=None,
+ stable_karma=None, unstable_karma=None,
+ suggest=None, severity=None):
+@@ -1663,11 +1664,10 @@ class TestBodhiOverride(CliTestCase):
+ self.os_environ_patcher = patch.dict('os.environ', {'EDITOR': 'vi', 'HOME': self.tempdir})
+ self.os_environ_patcher.start()
+
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher = patch(
+- 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
+- )
+- self.oidcmeta_patcher.start()
++ self.oidcmeta_patcher = patch(
++ 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
++ )
++ self.oidcmeta_patcher.start()
+
+ # Fake build returned from Koji for the specified build NVR in tests
+ self.kojisession.getBuild.return_value = {'build_id': 1}
+@@ -1676,8 +1676,7 @@ class TestBodhiOverride(CliTestCase):
+ self.anon_kojisession_p.stop()
+ self.cbv_p.stop()
+ self.os_environ_patcher.stop()
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher.stop()
++ self.oidcmeta_patcher.stop()
+ rmdir(self.tempdir)
+ super(TestBodhiOverride, self).tearDown()
+
+@@ -1703,10 +1702,8 @@ class TestBodhiOverride(CliTestCase):
+ @patch('bodhi.client.bindings.BodhiClient.list_overrides')
+ @patch('bodhi.client.bindings.BodhiClient.save_override')
+ @patch('bodhi.client.bindings.BodhiClient.override_str')
+- # Do not acquire lock for local openidc cache file
+- @patch('fedora.client.OpenIdBaseClient._load_cookies')
+ def test_create_for_given_build(
+- self, _load_cookies, override_str, save_override, list_overrides):
++ self, override_str, save_override, list_overrides):
+ list_overrides.return_value = {'total': 0}
+ expiration_date = datetime.now() + timedelta(days=7)
+ new_override = {
+@@ -1817,50 +1814,6 @@ class TestBodhiOverride(CliTestCase):
+ 'Buildroot override for %s already exists and not '
+ 'expired.', 'rpkg-1.54-2.fc28')
+
+- @unittest.skipIf(
+- parse_version(bodhi_version) >= parse_version("6.0.0"),
+- "Retrying is built in Bodhi 6"
+- )
+- @patch('fedora.client.OpenIdBaseClient._load_cookies')
+- @patch('bodhi.client.bindings.BodhiClient.list_overrides')
+- @patch('bodhi.client.bindings.BodhiClient.save_override')
+- @patch('fedpkg.Commands.nvr', new_callable=PropertyMock)
+- def test_retry_create(
+- self, nvr, save_override, list_overrides, _load_cookies):
+- nvr.return_value = 'rpkg-1.54-2.fc28'
+- list_overrides.return_value = {'total': 0}
+-
+- # For save_override raises AuthError twice.
+- from fedora.client import AuthError
+- save_override.side_effect = AuthError
+-
+- cli_cmd = [
+- 'fedpkg', '--path', self.cloned_repo_path,
+- 'override', 'create',
+- '--duration', '7', '--notes', 'build for fedpkg',
+- ]
+-
+- with patch('sys.argv', new=cli_cmd):
+- cli = self.new_cli()
+-
+- # This is raised when call save_override in the second time due to
+- # the AuthError is raised again. This is expected for running this
+- # test.
+- six.assertRaisesRegex(self, rpkgError, 'Cannot create override',
+- cli.create_buildroot_override)
+-
+- # First call to save_override should raise AuthError, and it must be
+- # called twice.
+- self.assertEqual(2, save_override.call_count)
+- save_override.assert_has_calls([
+- call(nvr='rpkg-1.54-2.fc28',
+- duration=7,
+- notes='build for fedpkg'),
+- call(nvr='rpkg-1.54-2.fc28',
+- duration=7,
+- notes='build for fedpkg')
+- ])
+-
+ def test_invalid_duration_option(self):
+ cli_cmds = (
+ (
+@@ -1910,26 +1863,19 @@ class TestBodhiOverrideExtend(CliTestCase):
+ self.os_environ_patcher = patch.dict('os.environ', {'EDITOR': 'vi', 'HOME': self.tempdir})
+ self.os_environ_patcher.start()
+
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher = patch(
+- 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
+- )
+- self.oidcmeta_patcher.start()
+-
+- self.load_cookies_p = patch(
+- 'fedora.client.OpenIdBaseClient._load_cookies')
+- self.mock_load_cookies = self.load_cookies_p.start()
++ self.oidcmeta_patcher = patch(
++ 'bodhi.client.oidcclient.OIDCClient._get_provider_metadata', _mock_metadata
++ )
++ self.oidcmeta_patcher.start()
+
+ # Fake build returned from Koji for the specified build NVR in tests
+ self.kojisession.getBuild.return_value = {'build_id': 1}
+
+ def tearDown(self):
+- self.load_cookies_p.stop()
+ self.anon_kojisession_p.stop()
+ self.cbv_p.stop()
+ self.os_environ_patcher.stop()
+- if parse_version(bodhi_version) >= parse_version("6.0.0"):
+- self.oidcmeta_patcher.stop()
++ self.oidcmeta_patcher.stop()
+ rmdir(self.tempdir)
+ super(TestBodhiOverrideExtend, self).tearDown()
+
+@@ -2162,75 +2108,6 @@ class TestBodhiOverrideExtend(CliTestCase):
+ six.assertRaisesRegex(self, rpkgError, '',
+ cli.extend_buildroot_override)
+
+- @unittest.skipIf(
+- parse_version(bodhi_version) >= parse_version("6.0.0"),
+- "Retrying is built in Bodhi 6"
+- )
+- @patch('fedpkg.BodhiClient.list_overrides')
+- @patch('fedpkg.BodhiClient.csrf')
+- @patch('fedpkg.BodhiClient.send_request')
+- def test_retry_to_extend_override_by_days(
+- self, send_request, csrf, list_overrides):
+- utcnow = datetime.now(timezone.utc).replace(tzinfo=None)
+- override_expiration_date = utcnow + timedelta(days=7)
+-
+- from fedora.client import AuthError
+- send_request.side_effect = AuthError
+-
+- csrf.side_effect = ['123456', '678901']
+-
+- build_nvr = 'somepkg-1.54-2.fc28'
+- build_override = {
+- 'expiration_date': override_expiration_date.strftime('%Y-%m-%d %H:%M:%S'),
+- 'nvr': build_nvr,
+- 'notes': 'build for other package',
+- 'build': {'nvr': build_nvr},
+- 'submitter': {'name': 'someone'},
+- 'expired_date': utcnow - timedelta(days=20)
+- }
+-
+- list_overrides.return_value = {
+- 'total': 1,
+- 'overrides': [build_override]
+- }
+- edited_override = build_override.copy()
+- expected_expiration_date = override_expiration_date + timedelta(days=2)
+- edited_override['expiration_date'] = \
+- expected_expiration_date.strftime('%Y-%m-%d %H:%M:%S')
+- send_request.return_value = edited_override
+-
+- cli_cmd = [
+- 'fedpkg', '--path', self.cloned_repo_path,
+- 'override', 'extend', '2', build_nvr
+- ]
+-
+- with patch('sys.argv', new=cli_cmd):
+- cli = self.new_cli()
+-
+- # This error is expected due to the design for this test. See also
+- # above explanation to test of `override create`.
+- six.assertRaisesRegex(
+- self, rpkgError, '', cli.extend_buildroot_override)
+-
+- # Ensure no microsecond is included in the expected expiration data
+- new_date = override_expiration_date + timedelta(days=2)
+- expected_expiration_date = datetime(year=new_date.year,
+- month=new_date.month,
+- day=new_date.day,
+- hour=new_date.hour,
+- minute=new_date.minute,
+- second=new_date.second)
+-
+- send_request.assert_has_calls([
+- call('overrides/', verb='POST', auth=True, data={
+- 'expiration_date': expected_expiration_date,
+- 'nvr': build_nvr,
+- 'notes': build_override['notes'],
+- 'csrf_token': token,
+- })
+- for token in csrf.side_effect
+- ])
+-
+ @freeze_time('2018-07-22')
+ @patch('fedpkg.BodhiClient.list_overrides')
+ def test_raise_error_if_duration_less_than_today(self, list_overrides):
+--
+2.46.0
+
diff --git a/0014-Drop-all-usage-of-six.patch b/0014-Drop-all-usage-of-six.patch
new file mode 100644
index 0000000..1046ab9
--- /dev/null
+++ b/0014-Drop-all-usage-of-six.patch
@@ -0,0 +1,994 @@
+From 6787fe01cdef04409bcb6f8fd16438803f04cb25 Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 09:57:41 -0400
+Subject: [PATCH 3/6] Drop all usage of six
+
+We no longer support Python 2, so there's no need for it. This
+also drops some early Python 3-era compatibility things there
+is no longer any need for.
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ doc/fedpkg_man_page.py | 2 +-
+ fedpkg/__init__.py | 3 +-
+ fedpkg/__main__.py | 7 +--
+ fedpkg/cli.py | 15 ++---
+ fedpkg/utils.py | 4 +-
+ pyproject.toml | 1 -
+ requirements.txt | 1 -
+ test/test_bugzilla.py | 14 ++---
+ test/test_cli.py | 137 ++++++++++++++++++++---------------------
+ test/test_commands.py | 7 +--
+ test/test_retire.py | 6 +-
+ test/test_utils.py | 97 ++++++++++++++---------------
+ test/utils.py | 3 +-
+ 13 files changed, 137 insertions(+), 160 deletions(-)
+
+diff --git a/doc/fedpkg_man_page.py b/doc/fedpkg_man_page.py
+index 786264f..58e4d40 100755
+--- a/doc/fedpkg_man_page.py
++++ b/doc/fedpkg_man_page.py
+@@ -4,7 +4,7 @@
+ import os
+ import sys
+
+-from six.moves.configparser import ConfigParser
++from configparser import ConfigParser
+
+ if __name__ == '__main__':
+ module_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index dca48da..3c5e7d9 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -13,7 +13,6 @@ import pyrpkg
+ import os
+ import git
+ import re
+-import six
+
+ from datetime import datetime, timedelta, timezone
+
+@@ -265,7 +264,7 @@ class Commands(pyrpkg.Commands):
+ """Returns the latest commit message on the current branch"""
+
+ try:
+- commitmsg = six.next(self.repo.iter_commits()).message
++ commitmsg = next(self.repo.iter_commits()).message
+ except TypeError:
+ commitmsg = ""
+
+diff --git a/fedpkg/__main__.py b/fedpkg/__main__.py
+index c440f08..1a2c3f8 100644
+--- a/fedpkg/__main__.py
++++ b/fedpkg/__main__.py
+@@ -15,17 +15,12 @@ import logging
+ import os
+ import sys
+
+-import six
+-
+ import fedpkg
+ import fedpkg.utils
+ import pyrpkg
+ import pyrpkg.utils
+
+-if six.PY3: # SafeConfigParser == ConfigParser, former deprecated in >= 3.2
+- from six.moves.configparser import ConfigParser
+-else:
+- from six.moves.configparser import SafeConfigParser as ConfigParser
++from configparser import ConfigParser
+
+
+ cli_name = os.path.basename(sys.argv[0])
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index d6c7715..d27b8b1 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -26,12 +26,10 @@ try:
+ import importlib.metadata
+ except ImportError:
+ import pkg_resources
+-import six
+ from pyrpkg import rpkgError
+ from pyrpkg.cli import cliClient
+-from six.moves import configparser
+-from six.moves.configparser import NoOptionError, NoSectionError
+-from six.moves.urllib_parse import urlparse
++import configparser
++from urllib.parse import urlparse
+
+ from fedpkg.bugzilla import BugzillaClient
+ from fedpkg.completers import (build_arches, distgit_branches, fedpkg_packages,
+@@ -793,7 +791,7 @@ class fedpkgClient(cliClient):
+ return {
+ 'staging': self.config.getboolean(section, 'staging'),
+ }
+- except (ValueError, NoOptionError, NoSectionError) as e:
++ except (ValueError, configparser.NoOptionError, configparser.NoSectionError) as e:
+ self.log.error(str(e))
+ raise rpkgError('Could not get bodhi options. It seems configuration is changed. '
+ 'Please try to reinstall %s or consult developers to see what '
+@@ -863,10 +861,9 @@ class fedpkgClient(cliClient):
+ nvr = "FILL_IN_NVR_HERE"
+ bodhi_args = {
+ 'nvr': nvr,
+- 'bugs': six.u(''),
+- 'display_name': six.u(''),
+- 'descr': six.u(
+- 'Here is where you give an explanation of your update.'),
++ 'bugs': '',
++ 'display_name': '',
++ 'descr': 'Here is where you give an explanation of your update.',
+ 'request': self.args.request,
+ 'autokarma': str(self.args.autokarma),
+ 'stable_karma': self.args.stable_karma,
+diff --git a/fedpkg/utils.py b/fedpkg/utils.py
+index 6f7d2be..0669c3f 100644
+--- a/fedpkg/utils.py
++++ b/fedpkg/utils.py
+@@ -18,8 +18,8 @@ import git
+ import requests
+ from pyrpkg import rpkgError
+ from requests.exceptions import ConnectionError
+-from six.moves.configparser import NoOptionError, NoSectionError
+-from six.moves.urllib.parse import urlparse
++from configparser import NoOptionError, NoSectionError
++from urllib.parse import urlparse
+
+
+ def query_bodhi(server_url, timeout=60):
+diff --git a/pyproject.toml b/pyproject.toml
+index ac60b0f..8cf7880 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -29,7 +29,6 @@ dependencies = [
+ "openidc-client",
+ "python-bugzilla",
+ "rpkg",
+- "six",
+ ]
+
+ [project.scripts]
+diff --git a/requirements.txt b/requirements.txt
+index 7e52a2c..3c788cd 100644
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -3,4 +3,3 @@ bodhi-client
+ openidc-client
+ python-bugzilla
+ rpkg
+-six
+diff --git a/test/test_bugzilla.py b/test/test_bugzilla.py
+index 83b608e..6fcc8ad 100644
+--- a/test/test_bugzilla.py
++++ b/test/test_bugzilla.py
+@@ -10,8 +10,6 @@
+ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+ # the full text of the license.
+
+-import six
+-
+ from fedpkg.bugzilla import BugzillaClient
+ from pyrpkg import rpkgError
+ from utils import unittest
+@@ -60,8 +58,8 @@ class TestGetReviewBug(unittest.TestCase):
+ Bugzilla.return_value.getbug.side_effect = ValueError
+
+ bzc = BugzillaClient('http://bugzilla.example.com')
+- six.assertRaisesRegex(
+- self, rpkgError, 'The Bugzilla bug could not be verified.',
++ self.assertRaisesRegex(
++ rpkgError, 'The Bugzilla bug could not be verified.',
+ bzc.get_review_bug, 123, 'rpms', 'mypkg')
+
+ @patch('bugzilla.Bugzilla')
+@@ -69,8 +67,8 @@ class TestGetReviewBug(unittest.TestCase):
+ Bugzilla.return_value.getbug.return_value = Mock()
+
+ bzc = BugzillaClient('http://bugzilla.example.com')
+- six.assertRaisesRegex(
+- self, rpkgError, 'not the proper type',
++ self.assertRaisesRegex(
++ rpkgError, 'not the proper type',
+ bzc.get_review_bug, 123, 'xxx', 'mypkg')
+
+ @patch('bugzilla.Bugzilla')
+@@ -80,6 +78,6 @@ class TestGetReviewBug(unittest.TestCase):
+ bzc = BugzillaClient('http://bugzilla.example.com')
+ # namespace container requires bug component is Container Review,
+ # but fake bug has a different component.
+- six.assertRaisesRegex(
+- self, rpkgError, 'not the proper type',
++ self.assertRaisesRegex(
++ rpkgError, 'not the proper type',
+ bzc.get_review_bug, 123, 'container', 'mypkg')
+diff --git a/test/test_cli.py b/test/test_cli.py
+index c819614..b73bb02 100644
+--- a/test/test_cli.py
++++ b/test/test_cli.py
+@@ -16,6 +16,7 @@ import json
+ import os
+ import re
+ import sys
++from configparser import NoOptionError, NoSectionError
+ from datetime import datetime, timedelta, timezone
+ from os import rmdir
+ from tempfile import mkdtemp, mkstemp
+@@ -32,10 +33,6 @@ try:
+ except ImportError:
+ from pkg_resources import get_distribution as distribution
+
+-import six
+-from six.moves import StringIO
+-from six.moves.configparser import NoOptionError, NoSectionError
+-
+ import fedpkg.cli
+ from fedpkg.bugzilla import BugzillaClient
+ from fedpkg.cli import check_bodhi_version
+@@ -89,19 +86,19 @@ class TestIsUpdateAborted(CliTestCase):
+
+ def test_all_line_are_commented_out(self):
+ with io.open(self.bodhi_template, 'w', encoding='utf-8') as f:
+- f.write(six.u('# line 1\n#line 2\n#line 3\n'))
++ f.write('# line 1\n#line 2\n#line 3\n')
+
+ self.assertTrue(self._is_update_aborted())
+
+ def test_template_is_ok(self):
+ with io.open(self.bodhi_template, 'w', encoding='utf-8') as f:
+- f.write(six.u('[fedpkg-1.34-1.fc28]\ntype=\nnotes=abc\n'))
++ f.write('[fedpkg-1.34-1.fc28]\ntype=\nnotes=abc\n')
+
+ self.assertFalse(self._is_update_aborted())
+
+ def test_template_content_is_broken(self):
+ with io.open(self.bodhi_template, 'w', encoding='utf-8') as f:
+- f.write(six.u('#[fedpkg-1.34-1.fc28]\ntype=\nnotes=abc\n'))
++ f.write('#[fedpkg-1.34-1.fc28]\ntype=\nnotes=abc\n')
+
+ self.assertTrue(self._is_update_aborted())
+
+@@ -142,7 +139,7 @@ class TestUpdate(CliTestCase):
+ self.clog_patcher.start()
+
+ # Logs will be read in the tests which do not specify --notes option
+- self.fake_clog = list(six.moves.map(six.u, [
++ self.fake_clog = [
+ 'Add tests for command update',
+ 'New command update - #1000', # invalid bug id format
+ 'Fix tests - #2000, #notabug', # both invalid bug id format
+@@ -150,7 +147,7 @@ class TestUpdate(CliTestCase):
+ 'fix: rh#10001',
+ 'Fixes: rhbz#20001',
+ ' close: fedora#30001', # test whitespace at the beginning
+- ]))
++ ]
+ clog_file = os.path.join(self.cloned_repo_path, 'clog')
+ with io.open(clog_file, 'w', encoding='utf-8') as f:
+ f.write(os.linesep.join(self.fake_clog))
+@@ -216,7 +213,7 @@ class TestUpdate(CliTestCase):
+ expected_data = {
+ 'autokarma': 'True',
+ 'bugs': '10001,20001,30001',
+- 'display_name': six.u(''),
++ 'display_name': '',
+ 'builds': ' {0} '.format(self.mock_nvr.return_value),
+ 'close_bugs': True,
+ 'request': 'testing',
+@@ -259,7 +256,7 @@ class TestUpdate(CliTestCase):
+ else:
+ self.assertTrue(self.fake_clog[0] in bodhi_template)
+ rest_clog = os.linesep.join([
+- six.u('# {0}').format(line) for line in self.fake_clog[1:]
++ '# {0}'.format(line) for line in self.fake_clog[1:]
+ ])
+ self.assertTrue(rest_clog in bodhi_template)
+
+@@ -269,21 +266,21 @@ class TestUpdate(CliTestCase):
+
+ with patch.object(cli.config, 'get',
+ side_effect=NoOptionError('url', 'bodhi')):
+- six.assertRaisesRegex(
+- self, rpkgError, 'Could not get bodhi options.', cli.update)
++ self.assertRaisesRegex(
++ rpkgError, 'Could not get bodhi options.', cli.update)
+
+ with patch.object(cli.config, 'get',
+ side_effect=NoSectionError('bodhi')):
+- six.assertRaisesRegex(
+- self, rpkgError, 'Could not get bodhi options.', cli.update)
++ self.assertRaisesRegex(
++ rpkgError, 'Could not get bodhi options.', cli.update)
+
+ @patch('os.path.isfile', return_value=False)
+ def test_fail_if_bodhi_template_is_not_a_file(self, isfile):
+ cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update']
+
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(
+- self, rpkgError, 'No bodhi update details saved',
++ self.assertRaisesRegex(
++ rpkgError, 'No bodhi update details saved',
+ self.assert_bodhi_update, cli)
+
+ self.mock_run_command.assert_called_once_with(
+@@ -323,8 +320,8 @@ class TestUpdate(CliTestCase):
+ cli_cmd = ['fedpkg', '--path', self.cloned_repo_path, 'update']
+
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(
+- self, rpkgError, 'Could not generate update request',
++ self.assertRaisesRegex(
++ rpkgError, 'Could not generate update request',
+ self.assert_bodhi_update, cli)
+
+ def test_create_update_in_stage_bodhi(self):
+@@ -340,30 +337,30 @@ class TestUpdate(CliTestCase):
+ def test_missing_update_type_in_template(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path, 'update']
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(self, rpkgError, 'Missing update type',
+- self.assert_bodhi_update, cli)
++ self.assertRaisesRegex(rpkgError, 'Missing update type',
++ self.assert_bodhi_update, cli)
+
+ def test_incorrect_update_type_in_template(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path, 'update']
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(self, rpkgError, 'Incorrect update type',
+- self.assert_bodhi_update, cli, update_type='xxx')
++ self.assertRaisesRegex(rpkgError, 'Incorrect update type',
++ self.assert_bodhi_update, cli, update_type='xxx')
+
+ def test_incorrect_request_type_in_template(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path, 'update']
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(self, rpkgError, 'Incorrect request type',
+- self.assert_bodhi_update, cli,
+- update_type='enhancement',
+- request_type='xxx')
++ self.assertRaisesRegex(rpkgError, 'Incorrect request type',
++ self.assert_bodhi_update, cli,
++ update_type='enhancement',
++ request_type='xxx')
+
+ def test_incorrect_suggest_type_in_template(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path, 'update']
+ cli = self.get_cli(cli_cmd)
+- six.assertRaisesRegex(self, rpkgError, 'Incorrect suggest type',
+- self.assert_bodhi_update, cli,
+- update_type='enhancement',
+- suggest='123')
++ self.assertRaisesRegex(rpkgError, 'Incorrect suggest type',
++ self.assert_bodhi_update, cli,
++ update_type='enhancement',
++ suggest='123')
+
+ def test_create_with_cli_options(self):
+ cli_cmd = [
+@@ -413,7 +410,7 @@ class TestUpdate(CliTestCase):
+ self.assert_bodhi_update(
+ cli, update_type='bugfix', notes='Line 1\nLine 2\nLine 3')
+
+- @patch('sys.stderr', new=six.StringIO())
++ @patch('sys.stderr', new=io.StringIO())
+ def test_invalid_stable_karma_option(self):
+ with self.assertRaises(SystemExit):
+ self.get_cli([
+@@ -427,7 +424,7 @@ class TestUpdate(CliTestCase):
+ 'update', '--stable-karma', '-3'
+ ])
+
+- @patch('sys.stderr', new=six.StringIO())
++ @patch('sys.stderr', new=io.StringIO())
+ def test_invalid_unstable_karma_option(self):
+ with self.assertRaises(SystemExit):
+ self.get_cli([
+@@ -441,7 +438,7 @@ class TestUpdate(CliTestCase):
+ 'update', '--unstable-karma', '3'
+ ])
+
+- @patch('sys.stderr', new=six.StringIO())
++ @patch('sys.stderr', new=io.StringIO())
+ def test_invalid_bug(self):
+ with self.assertRaises(SystemExit):
+ self.get_cli([
+@@ -493,7 +490,7 @@ class TestRequestRepo(CliTestCase):
+ return self.new_cli(name=name, cfg=cfg, user_cfg=user_cfg)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo(self, mock_request_post, mock_bz):
+ """Tests a standard request-repo call"""
+ self.mock_bug.summary = ('Review Request: testpkg - a description')
+@@ -531,7 +528,7 @@ class TestRequestRepo(CliTestCase):
+ self.assertEqual(output, expected_output)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo_override(self, mock_request_post, mock_bz):
+ """Tests a request-repo call with an overridden repo name"""
+ mock_bz.getbug.return_value = self.mock_bug
+@@ -569,7 +566,7 @@ class TestRequestRepo(CliTestCase):
+ self.assertEqual(output, expected_output)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo_module(self, mock_request_post, mock_bz):
+ """Tests a request-repo call for a new module"""
+ self.mock_bug.product = 'Fedora Modules'
+@@ -608,7 +605,7 @@ class TestRequestRepo(CliTestCase):
+ self.assertEqual(output, expected_output)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo_container(self, mock_request_post, mock_bz):
+ """Tests a request-repo call for a new container"""
+ self.mock_bug.product = 'Fedora Container Images'
+@@ -650,7 +647,7 @@ class TestRequestRepo(CliTestCase):
+ self.assertEqual(output, expected_output)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo_with_optional_details(
+ self, mock_request_post, mock_bz):
+ """Tests a request-repo call with the optional details"""
+@@ -690,7 +687,7 @@ class TestRequestRepo(CliTestCase):
+ self.assertEqual(output, expected_output)
+
+ @patch('requests.post')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_repo_exception(self, mock_request_post, mock_bz):
+ """Tests a request-repo call with the exception flag"""
+ mock_rv = Mock()
+@@ -935,7 +932,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch(self, mock_grb, mock_request_post, mock_request_get):
+ """Tests request-branch"""
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -981,7 +978,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_existing_branch(self, mock_grb, mock_request_post, mock_request_get):
+ """Tests request-existing-branch"""
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -1008,7 +1005,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_override(self, mock_grb, mock_request_post, mock_request_get):
+ """Tests request-branch with an overridden package and branch name"""
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -1051,7 +1048,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_epel_branch_override(
+ self, mock_grb, mock_request_post, mock_request_get
+ ):
+@@ -1100,7 +1097,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_module(self, mock_grb, mock_request_post, mock_request_get):
+ """Tests request-branch for a new module branch"""
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -1178,14 +1175,14 @@ class TestRequestBranch(CliTestCase):
+ 'fedora-scm-requests/issue/2')
+ self.assertEqual(output, expected_output)
+
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_with_global_option_name_and_namespace(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path,
+ '--name', 'nethack', '--namespace', 'container',
+ 'request-branch', 'f27']
+ self.assert_request_branch_container(cli_cmd)
+
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_with_its_own_option_repo_and_namespace(self):
+ cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path,
+ 'request-branch',
+@@ -1196,7 +1193,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+ @patch('fedpkg.cli.verify_sls')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_sls(self, mock_verify_sls, mock_grb,
+ mock_request_post, mock_request_get):
+ """Tests request-branch with service levels"""
+@@ -1299,7 +1296,7 @@ class TestRequestBranch(CliTestCase):
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_branch_all_releases(self, mock_grb, mock_request_post, mock_request_get):
+ """Tests request-branch with the '--all-releases' option """
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -1489,13 +1486,13 @@ https://pagure.stg.example.com/releng/fedora-scm-requests/issue/3"""
+ 'supported arches, therefore, it cannot be in EPEL. If this is a '
+ 'mistake or you have an exception, please contact the Release '
+ 'Engineering team.')
+- with six.assertRaisesRegex(self, rpkgError, expected_error):
++ with self.assertRaisesRegex(rpkgError, expected_error):
+ cli.request_branch()
+
+ @patch('requests.get')
+ @patch('requests.post')
+ @patch('fedpkg.cli.get_release_branches')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_with_repo_option(self, mock_grb, mock_request_post, mock_request_get):
+ """Test request branch with option --repo"""
+ mock_grb.return_value = {'fedora': ['f25', 'f26', 'f27'],
+@@ -1550,7 +1547,7 @@ class TestRequestTestsRepo(CliTestCase):
+
+ @patch('requests.post')
+ @patch('requests.get')
+- @patch('sys.stdout', new=StringIO())
++ @patch('sys.stdout', new=io.StringIO())
+ def test_request_tests_repo(self, mock_request_get, mock_request_post):
+ """Tests request-tests-repo"""
+
+@@ -1626,8 +1623,8 @@ try:
+ def test_no_2_x_version_installed(self, distribution):
+ distribution.side_effect = importlib.metadata.PackageNotFoundError
+
+- six.assertRaisesRegex(
+- self, rpkgError, r'bodhi-client < 2\.0 is not supported\.',
++ self.assertRaisesRegex(
++ rpkgError, r'bodhi-client < 2\.0 is not supported\.',
+ check_bodhi_version)
+
+ except ImportError:
+@@ -1640,8 +1637,8 @@ except ImportError:
+ def test_no_2_x_version_installed(self, get_distribution):
+ get_distribution.side_effect = pkg_resources.DistributionNotFound
+
+- six.assertRaisesRegex(
+- self, rpkgError, r'bodhi-client < 2\.0 is not supported\.',
++ self.assertRaisesRegex(
++ rpkgError, r'bodhi-client < 2\.0 is not supported\.',
+ check_bodhi_version)
+
+
+@@ -1693,8 +1690,8 @@ class TestBodhiOverride(CliTestCase):
+
+ with patch('sys.argv', new=cli_cmd):
+ cli = self.new_cli()
+- six.assertRaisesRegex(
+- self, rpkgError, 'Build {0} does not exist'.format(build_nvr),
++ self.assertRaisesRegex(
++ rpkgError, 'Build {0} does not exist'.format(build_nvr),
+ cli.create_buildroot_override)
+
+ self.kojisession.getBuild.assert_called_once_with(build_nvr)
+@@ -1836,7 +1833,7 @@ class TestBodhiOverride(CliTestCase):
+
+ for cmd, expected_output in cli_cmds:
+ with patch('sys.argv', new=cmd):
+- with patch('sys.stderr', new=StringIO()):
++ with patch('sys.stderr', new=io.StringIO()):
+ with self.assertRaises(SystemExit):
+ self.new_cli()
+ output = sys.stderr.getvalue()
+@@ -1889,8 +1886,8 @@ class TestBodhiOverrideExtend(CliTestCase):
+
+ with patch('sys.argv', new=cli_cmd):
+ cli = self.new_cli()
+- six.assertRaisesRegex(
+- self, rpkgError, 'Build somepkg-1.54-2.fc28 does not exist.',
++ self.assertRaisesRegex(
++ rpkgError, 'Build somepkg-1.54-2.fc28 does not exist.',
+ cli.extend_buildroot_override)
+
+ @patch('fedpkg.BodhiClient.list_overrides')
+@@ -2105,8 +2102,8 @@ class TestBodhiOverrideExtend(CliTestCase):
+
+ with patch('sys.argv', new=cli_cmd):
+ cli = self.new_cli()
+- six.assertRaisesRegex(self, rpkgError, '',
+- cli.extend_buildroot_override)
++ self.assertRaisesRegex(rpkgError, '',
++ cli.extend_buildroot_override)
+
+ @freeze_time('2018-07-22')
+ @patch('fedpkg.BodhiClient.list_overrides')
+@@ -2134,8 +2131,8 @@ class TestBodhiOverrideExtend(CliTestCase):
+ ]
+ with patch('sys.argv', new=cli_cmd):
+ cli = self.new_cli()
+- six.assertRaisesRegex(
+- self, rpkgError,
++ self.assertRaisesRegex(
++ rpkgError,
+ 'specified expiration date .+ should be future date',
+ cli.extend_buildroot_override)
+
+@@ -2145,7 +2142,7 @@ class TestBodhiOverrideExtend(CliTestCase):
+ 'override', 'extend', '2019/01/10', 'rpkg-1.10-1.fc28'
+ ]
+ with patch('sys.argv', new=cli_cmd):
+- with patch('sys.stderr', new=StringIO()):
++ with patch('sys.stderr', new=io.StringIO()):
+ with self.assertRaises(SystemExit):
+ self.new_cli()
+ output = sys.stderr.getvalue()
+@@ -2173,7 +2170,7 @@ class TestReadReleasesFromLocalConfig(CliTestCase):
+ error_msg = 'given path \'{0}\' doesn\'t exist'.format(self.cloned_repo_path)
+ validate_path.side_effect = argparse.ArgumentTypeError(error_msg)
+ with patch('sys.argv', new=self.fake_cmd):
+- with patch('sys.stderr', new=six.StringIO()):
++ with patch('sys.stderr', new=io.StringIO()):
+ # argparse.ArgumentTypeError turns to SystemExit
+ with self.assertRaises(SystemExit):
+ self.new_cli()
+@@ -2197,8 +2194,8 @@ class TestReadReleasesFromLocalConfig(CliTestCase):
+ with patch('fedpkg.cli.configparser.ConfigParser.read') as read:
+ read.return_value = []
+
+- six.assertRaisesRegex(
+- self, rpkgError, '.+ not accessible',
++ self.assertRaisesRegex(
++ rpkgError, '.+ not accessible',
+ cli.read_releases_from_local_config, self.active_releases)
+
+ def test_get_expanded_releases(self):
+@@ -2344,7 +2341,7 @@ class TestReleasesInfo(CliTestCase):
+ def assert_output_releases(self, expected_output, option=[]):
+ with patch('sys.argv', ['fedpkg', 'releases-info'] + option):
+ cli = self.new_cli()
+- with patch('sys.stdout', new=six.StringIO()):
++ with patch('sys.stdout', new=io.StringIO()):
+ cli.show_releases_info()
+ output = sys.stdout.getvalue().strip()
+ self.assertEqual(expected_output, output)
+diff --git a/test/test_commands.py b/test/test_commands.py
+index a5b5ed5..df6a2ac 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -9,8 +9,7 @@
+ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+ # the full text of the license.
+
+-import six
+-from six.moves import builtins
++import builtins
+
+ from pyrpkg.errors import rpkgError
+ from utils import CommandTestCase
+@@ -411,8 +410,8 @@ class TestFindRawhideBranch(CommandTestCase):
+ # As the code shows, any error will be caught
+ koji_session.getBuildTarget.side_effect = ValueError
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'Unable to find rawhide target',
++ self.assertRaisesRegex(
++ rpkgError, 'Unable to find rawhide target',
+ self.cmd._findrawhidebranch)
+
+
+diff --git a/test/test_retire.py b/test/test_retire.py
+index 98d7385..9b10caf 100644
+--- a/test/test_retire.py
++++ b/test/test_retire.py
+@@ -1,13 +1,12 @@
+ # -*- coding: utf-8 -*-
+
++import configparser
+ import os
+ import shutil
+ import subprocess
+ import tempfile
+
+-import six
+ from pyrpkg.errors import rpkgError
+-from six.moves import configparser
+ from utils import unittest
+
+ from fedpkg.cli import fedpkgClient
+@@ -130,8 +129,7 @@ class RetireTestCase(unittest.TestCase):
+
+ args = ['fedpkg', '--release=rawhide', 'disable-monitoring']
+ client = self._fake_client(args)
+- six.assertRaisesRegex(
+- self,
++ self.assertRaisesRegex(
+ rpkgError,
+ "The following error occurred while disabling monitoring: Invalid or expired token\n"
+ "For invalid or expired tokens please set a new token",
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 7a38740..04ea22a 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -10,11 +10,10 @@
+ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+ # the full text of the license.
+
++from configparser import NoOptionError, NoSectionError
+ import json
+
+-import six
+ from requests.exceptions import ConnectionError
+-from six.moves.configparser import NoOptionError, NoSectionError
+
+ from fedpkg import utils
+ from freezegun import freeze_time
+@@ -123,15 +122,15 @@ class TestAssertNewTestsRepo(unittest.TestCase):
+ def test_should_raise_error_if_connection_error_to_distgit(self, get):
+ get.side_effect = ConnectionError
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The error was',
++ self.assertRaisesRegex(
++ rpkgError, 'The error was',
+ utils.assert_new_tests_repo, 'testrepo', 'http://distgit/')
+
+ def test_test_repo_exists(self, get):
+ get.return_value = Mock(ok=True)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'Repository .+ already exists',
++ self.assertRaisesRegex(
++ rpkgError, 'Repository .+ already exists',
+ utils.assert_new_tests_repo, 'testrepo', 'http://distgit/')
+
+ def test_keep_quiet_if_repo_not_exist(self, get):
+@@ -155,23 +154,21 @@ class TestGetPagureToken(unittest.TestCase):
+ config = Mock()
+
+ config.get.side_effect = NoOptionError('token', 'fedpkg.pagure')
+- six.assertRaisesRegex(self,
+- rpkgError, "Missing option 'token' in the section 'fedpkg.pagure'",
+- utils.config_get_safely,
+- config,
+- 'fedpkg.pagure', 'token')
++ self.assertRaisesRegex(rpkgError, "Missing option 'token' in the section 'fedpkg.pagure'",
++ utils.config_get_safely,
++ config,
++ 'fedpkg.pagure', 'token')
+
+ config.get.side_effect = NoSectionError('fedpkg.pagure')
+- six.assertRaisesRegex(self, rpkgError, "Missing section 'fedpkg.pagure'",
+- utils.config_get_safely, config, 'fedpkg.pagure', 'token')
++ self.assertRaisesRegex(rpkgError, "Missing section 'fedpkg.pagure'",
++ utils.config_get_safely, config, 'fedpkg.pagure', 'token')
+
+
+ class TestVerifySLS(unittest.TestCase):
+ """Test verify_sls"""
+
+ def test_sl_date_format_is_invalid(self):
+- six.assertRaisesRegex(
+- self,
++ self.assertRaisesRegex(
+ rpkgError,
+ "The EOL date .+ is in an invalid format",
+ utils.verify_sls,
+@@ -233,22 +230,22 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_raise_error_if_connection_error(self, get):
+ get.side_effect = ConnectionError
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The error was:',
++ self.assertRaisesRegex(
++ rpkgError, 'The error was:',
+ utils.assert_valid_epel_package, 'pkg', 'epel7')
+
+ def test_raise_error_if_GET_response_not_ok(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel7')
+
+ def test_correct_url_epel7(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel7')
+ get.assert_called_once_with(
+ 'https://infrastructure.fedoraproject.org/repo/json/pkg_el7.json',
+@@ -257,8 +254,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_correct_url_epel8(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel8')
+ get.assert_called_once_with(
+ 'https://infrastructure.fedoraproject.org/repo/json/pkg_el8.json',
+@@ -267,8 +264,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_correct_url_epel8_next(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel8-next')
+ get.assert_called_once_with(
+ 'https://infrastructure.fedoraproject.org/repo/json/pkg_el8.json',
+@@ -277,8 +274,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_correct_url_epel9(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel9')
+ get.assert_called_once_with(
+ 'https://composes.stream.centos.org/production/'
+@@ -288,8 +285,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_correct_url_epel10(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel10')
+ get.assert_called_once_with(
+ 'https://composes.stream.centos.org/stream-10/production'
+@@ -299,8 +296,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ def test_correct_url_epel10_10(self, get):
+ get.return_value = Mock(ok=False, status_code=404)
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The status code was: 404',
++ self.assertRaisesRegex(
++ rpkgError, 'The status code was: 404',
+ utils.assert_valid_epel_package, 'pkg', 'epel10.10')
+ get.assert_called_once_with(
+ 'https://composes.stream.centos.org/stream-10/production'
+@@ -320,8 +317,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ }
+ }
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'is built on all supported arches',
++ self.assertRaisesRegex(
++ rpkgError, 'is built on all supported arches',
+ utils.assert_valid_epel_package, 'pkg1', 'el6')
+
+ def test_should_not_have_epel_branch_for_el7_pkg(self, get):
+@@ -337,8 +334,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ }
+ }
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'is built on all supported arches',
++ self.assertRaisesRegex(
++ rpkgError, 'is built on all supported arches',
+ utils.assert_valid_epel_package, 'pkg1', 'epel7')
+
+ def test_raise_error_if_package_has_noarch_only(self, get):
+@@ -353,8 +350,8 @@ class TestAssertValidEPELPackage(unittest.TestCase):
+ }
+ }
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'This package is already an EL package',
++ self.assertRaisesRegex(
++ rpkgError, 'This package is already an EL package',
+ utils.assert_valid_epel_package, 'pkg1', 'epel7')
+
+
+@@ -366,8 +363,8 @@ class TestNewPagureIssue(unittest.TestCase):
+ post.side_effect = ConnectionError
+ logger = Mock()
+
+- six.assertRaisesRegex(
+- self, rpkgError, 'The connection to Pagure failed',
++ self.assertRaisesRegex(
++ rpkgError, 'The connection to Pagure failed',
+ utils.new_pagure_issue,
+ logger, 'http://distgit/', '123456', 'new package', {'repo': 'pkg1'}, 'fedpkg')
+
+@@ -377,8 +374,8 @@ class TestNewPagureIssue(unittest.TestCase):
+ post.return_value = rv
+ logger = Mock()
+
+- six.assertRaisesRegex(
+- self, rpkgError,
++ self.assertRaisesRegex(
++ rpkgError,
+ 'The following error occurred while creating a new issue',
+ utils.new_pagure_issue,
+ logger, 'http://distgit/', '123456', 'new package', {'repo': 'pkg1'}, 'fedpkg')
+@@ -392,8 +389,8 @@ class TestNewPagureIssue(unittest.TestCase):
+ post.return_value = rv
+ logger = Mock()
+
+- six.assertRaisesRegex(
+- self, rpkgError,
++ self.assertRaisesRegex(
++ rpkgError,
+ '\nFor invalid or expired tokens please '
+ 'set a new token in your user configuration with:'
+ '\n\n\tfedpkg set-pagure-token <token>\n',
+@@ -446,16 +443,16 @@ class TestQueryBodhi(unittest.TestCase):
+ get.side_effect = ConnectionError
+
+ result = utils.query_bodhi('http://localhost/')
+- six.assertRaisesRegex(
+- self, rpkgError, 'The connection to BODHI failed',
++ self.assertRaisesRegex(
++ rpkgError, 'The connection to BODHI failed',
+ list, result)
+
+ def test_response_not_ok(self, get):
+ get.return_value.ok = False
+
+ result = utils.query_bodhi('http://localhost/')
+- six.assertRaisesRegex(
+- self, rpkgError, 'The following error occurred',
++ self.assertRaisesRegex(
++ rpkgError, 'The following error occurred',
+ list, result)
+
+ def test_read_yield_data_normally(self, get):
+@@ -576,6 +573,6 @@ class TestGetFedoraReleaseState(unittest.TestCase):
+ def test_config_does_not_have_option(self):
+ config = Mock()
+ config.get.side_effect = NoOptionError('releases_service', 'fedpkg.bodhi')
+- six.assertRaisesRegex(self, rpkgError, r"Could not get release state for Fedora \(F30M\): "
+- "No option 'releases_service' in section: 'fedpkg.bodhi'.",
+- utils.get_fedora_release_state, config, 'fedpkg', 'F30M')
++ self.assertRaisesRegex(rpkgError, r"Could not get release state for Fedora \(F30M\): "
++ "No option 'releases_service' in section: 'fedpkg.bodhi'.",
++ utils.get_fedora_release_state, config, 'fedpkg', 'F30M')
+diff --git a/test/utils.py b/test/utils.py
+index 3899412..c98f7ec 100644
+--- a/test/utils.py
++++ b/test/utils.py
+@@ -10,14 +10,13 @@
+ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+ # the full text of the license.
+
++import configparser
+ import logging
+ import os
+ import shutil
+ import subprocess
+ import tempfile
+
+-from six.moves import configparser
+-
+ import fedpkg.cli
+ import pyrpkg
+ from fedpkg import Commands
+--
+2.46.0
+
diff --git a/0015-Replace-and-update-use-of-deprecated-linux_distribut.patch b/0015-Replace-and-update-use-of-deprecated-linux_distribut.patch
new file mode 100644
index 0000000..f238143
--- /dev/null
+++ b/0015-Replace-and-update-use-of-deprecated-linux_distribut.patch
@@ -0,0 +1,158 @@
+From f9259808159842e1600563c6604ce13d09831bad Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 17:27:55 -0400
+Subject: [PATCH 4/6] Replace and update use of deprecated 'linux_distribution'
+
+This uses distro.id and distro.version instead, and adjusts the
+handling appropriately. The value we get here is only ever used
+for comparison with Commands._disttag, which is set in
+_load_rpmdefines_branch. There is handling there for Fedora
+(tag is always 'fcNN'), various forms of EL (with possible tags
+like 'elN', 'elN_N' or 'elN.next'), OLPC (tag 'olpcNN', I think
+this is obsolete) and ELN (tag 'elnNN', I think). disttags that
+show up in the test suite are 'fc26', 'el6', 'el7', 'el8.next',
+'el10', 'el10_10', 'fc28', 'olpc7' and 'eln104'.
+
+This handles Fedora in the obvious way. It handles RHEL, CentOS
+and Alma flavors of EL, assuming branch names (and hence dist
+tags) with major version only; I don't think we can handle
+minor versions, really, because e.g. RHEL or Alma 9.4 report
+their distro.version as '9.4', but we want the tag to be 'el9'.
+I think the major_minor thing is meant for EPEL 10, so *possibly*
+we could handle it with differing behaviour between EL >= 10
+and EL < 10, but I'm really not enough of an expert to know. At
+least this should be no worse than before. It handles ELN by
+checking for the variant if the id is Fedora (ELN looks a lot
+like Fedora but can be distinguished by variant) then doing the
+counterpart to what the dist tag definition does (reading the
+'eln' build macro to get the digits). The old code did not handle
+ELN.
+
+I don't think it's possible to handle EPEL next; the old code
+did not either. I don't think it's worth handling OLPC.
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ fedpkg/__init__.py | 25 ++++++++-------------
+ test/test_commands.py | 51 ++++++++++++++++++++++++-------------------
+ 2 files changed, 37 insertions(+), 39 deletions(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 3c5e7d9..57a6eae 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -27,10 +27,7 @@ except ImportError:
+ from .lookaside import FedoraLookasideCache
+ from pyrpkg.utils import cached_property
+
+-try:
+- from distro import linux_distribution # noqa
+-except ImportError:
+- from platform import linux_distribution # noqa
++import distro
+
+
+ class Commands(pyrpkg.Commands):
+@@ -279,18 +276,14 @@ class Commands(pyrpkg.Commands):
+ """Need to know what the runtime env is, so we can unset anything
+ conflicting
+ """
+- try:
+- runtime_os, runtime_version, _ = linux_distribution()
+- except Exception:
+- return None
+-
+- if runtime_os in ['redhat', 'centos']:
+- return 'el%s' % runtime_version
+- if runtime_os == 'Fedora':
+- return 'fc%s' % runtime_version
+- if (runtime_os == 'Red Hat Enterprise Linux Server' or
+- runtime_os.startswith('CentOS')):
+- return 'el{0}'.format(runtime_version.split('.')[0])
++ if distro.id() == 'rhel' or 'rhel' in distro.like().split():
++ return 'el%s' % distro.major_version()
++ if distro.id() == 'fedora':
++ if distro.os_release_info()['variant'] == 'ELN':
++ macros = self._get_build_macros('eln-candidate')
++ return 'eln%s' % macros['eln']
++ return 'fc%s' % distro.major_version()
++ return None
+
+ def check_inheritance(self, build_target, dest_tag):
+ """Disable check inheritance
+diff --git a/test/test_commands.py b/test/test_commands.py
+index df6a2ac..2923ca0 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -27,40 +27,45 @@ class TestDetermineRuntimeEnv(CommandTestCase):
+ super(TestDetermineRuntimeEnv, self).setUp()
+ self.cmd = self.make_commands()
+
+- @patch('fedpkg.linux_distribution')
+- def test_return_fedora_disttag(self, linux_distribution):
+- linux_distribution.return_value = ('Fedora', '25', 'Twenty Five')
+-
++ @patch('distro.id', return_value='fedora')
++ @patch('distro.major_version', return_value='25')
++ def test_return_fedora_disttag(self, mock_ver, mock_id):
+ result = self.cmd._determine_runtime_env()
+ self.assertEqual('fc25', result)
+
+- @patch('fedpkg.linux_distribution')
+- def test_return_None_if_os_is_unknown(self, linux_distribution):
+- linux_distribution.side_effect = ValueError
+-
++ @patch('distro.id', return_value='')
++ def test_return_None_if_os_is_unknown(self, mock_id):
+ self.assertEqual(None, self.cmd._determine_runtime_env())
+
+- @patch('fedpkg.linux_distribution')
+- def test_return_for_rhel(self, linux_distribution):
+- linux_distribution.return_value = ('Red Hat Enterprise Linux Server',
+- '6.8',
+- 'Santiago')
+-
++ @patch('distro.os_release_info', return_value={'variant': 'ELN'})
++ @patch('distro.id', return_value='fedora')
++ @patch('distro.major_version', return_value='41')
++ @patch('pyrpkg.Commands.kojisession', new_callable=PropertyMock)
++ def test_return_for_eln(self, mock_koji, mock_ver, mock_id, mock_info):
++ self.cmd._kojisession = Mock()
++ koji_session = mock_koji.return_value
++ koji_session.getBuildConfig.return_value = {
++ # minimal subset of the real koji response
++ 'extra': {
++ 'rpm.macro.eln': '128',
++ },
++ }
+ result = self.cmd._determine_runtime_env()
+- self.assertEqual('el6', result)
++ self.assertEqual('eln128', result)
+
+ def test_return_for_el(self):
+ dists = [
+- (('CentOS', '6.9', 'Final'), 'el6'),
+- (('CentOS Linux', '7.3.1611', 'Core'), 'el7'),
+- (('redhat', '6', None), 'el6'),
+- (('centos', '6', None), 'el6'),
++ ('centos', '8', 'rhel', 'el8'),
++ ('rhel', '9', '', 'el9'),
++ ('almalinux', '10', 'rhel', 'el10'),
+ ]
+
+- for dist, expected_dist_tag in dists:
+- with patch('fedpkg.linux_distribution', return_value=dist):
+- result = self.cmd._determine_runtime_env()
+- self.assertEqual(expected_dist_tag, result)
++ for did, dver, like, exptag in dists:
++ with patch('distro.id', return_value=did):
++ with patch('distro.like', return_value=like):
++ with patch('distro.major_version', return_value=dver):
++ result = self.cmd._determine_runtime_env()
++ self.assertEqual(exptag, result)
+
+
+ class TestLoadTarget(CommandTestCase):
+--
+2.46.0
+
diff --git a/0016-Modernize-and-clean-unittest-imports.patch b/0016-Modernize-and-clean-unittest-imports.patch
new file mode 100644
index 0000000..19343d8
--- /dev/null
+++ b/0016-Modernize-and-clean-unittest-imports.patch
@@ -0,0 +1,170 @@
+From 32c93a48327098b987a739fe5824b3880af3b03e Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 18:52:21 -0400
+Subject: [PATCH 5/6] Modernize and clean unittest imports
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ test/test_bugzilla.py | 9 +++------
+ test/test_cli.py | 12 ++----------
+ test/test_commands.py | 6 +-----
+ test/test_retire.py | 9 ++-------
+ test/test_utils.py | 8 ++------
+ test/utils.py | 6 +-----
+ 6 files changed, 11 insertions(+), 39 deletions(-)
+
+diff --git a/test/test_bugzilla.py b/test/test_bugzilla.py
+index 6fcc8ad..c0a8b02 100644
+--- a/test/test_bugzilla.py
++++ b/test/test_bugzilla.py
+@@ -10,14 +10,11 @@
+ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for
+ # the full text of the license.
+
++import unittest
++from unittest.mock import Mock, patch
++
+ from fedpkg.bugzilla import BugzillaClient
+ from pyrpkg import rpkgError
+-from utils import unittest
+-
+-try:
+- from unittest.mock import Mock, patch
+-except ImportError:
+- from mock import Mock, patch
+
+
+ class BugzillaSideEffect(object):
+diff --git a/test/test_cli.py b/test/test_cli.py
+index b73bb02..e2d82dc 100644
+--- a/test/test_cli.py
++++ b/test/test_cli.py
+@@ -16,10 +16,12 @@ import json
+ import os
+ import re
+ import sys
++import unittest
+ from configparser import NoOptionError, NoSectionError
+ from datetime import datetime, timedelta, timezone
+ from os import rmdir
+ from tempfile import mkdtemp, mkstemp
++from unittest.mock import Mock, PropertyMock, call, patch
+
+ import git
+ # Use deprecated pkg_resources if packaging library isn't available (python 3.6)
+@@ -40,16 +42,6 @@ from freezegun import freeze_time
+ from pyrpkg.errors import rpkgError
+ from utils import CliTestCase
+
+-try:
+- import unittest2 as unittest
+-except ImportError:
+- import unittest
+-
+-try:
+- from unittest.mock import Mock, PropertyMock, call, patch
+-except ImportError:
+- from mock import Mock, PropertyMock, call, patch
+-
+ try:
+ import bodhi
+ bodhi_version = distribution('bodhi-client').version
+diff --git a/test/test_commands.py b/test/test_commands.py
+index 2923ca0..8a90668 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -10,15 +10,11 @@
+ # the full text of the license.
+
+ import builtins
++from unittest.mock import Mock, PropertyMock, call, mock_open, patch
+
+ from pyrpkg.errors import rpkgError
+ from utils import CommandTestCase
+
+-try:
+- from unittest.mock import Mock, PropertyMock, call, mock_open, patch
+-except ImportError:
+- from mock import Mock, PropertyMock, call, mock_open, patch
+-
+
+ class TestDetermineRuntimeEnv(CommandTestCase):
+ """Test Commands._determine_runtime_env"""
+diff --git a/test/test_retire.py b/test/test_retire.py
+index 9b10caf..e6f371e 100644
+--- a/test/test_retire.py
++++ b/test/test_retire.py
+@@ -5,21 +5,16 @@ import os
+ import shutil
+ import subprocess
+ import tempfile
++from unittest import mock, TestCase
+
+ from pyrpkg.errors import rpkgError
+-from utils import unittest
+
+ from fedpkg.cli import fedpkgClient
+
+-try:
+- from unittest import mock
+-except ImportError:
+- import mock
+-
+ TEST_CONFIG = os.path.join(os.path.dirname(__file__), 'fedpkg-test.conf')
+
+
+-class RetireTestCase(unittest.TestCase):
++class RetireTestCase(TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+ self.log = mock.Mock()
+diff --git a/test/test_utils.py b/test/test_utils.py
+index 04ea22a..09ddbdb 100644
+--- a/test/test_utils.py
++++ b/test/test_utils.py
+@@ -12,18 +12,14 @@
+
+ from configparser import NoOptionError, NoSectionError
+ import json
++import unittest
++from unittest.mock import Mock, patch
+
+ from requests.exceptions import ConnectionError
+
+ from fedpkg import utils
+ from freezegun import freeze_time
+ from pyrpkg.errors import rpkgError
+-from utils import unittest
+-
+-try:
+- from unittest.mock import Mock, patch
+-except ImportError:
+- from mock import Mock, patch
+
+
+ class TestUtils(unittest.TestCase):
+diff --git a/test/utils.py b/test/utils.py
+index c98f7ec..b4ce20c 100644
+--- a/test/utils.py
++++ b/test/utils.py
+@@ -16,16 +16,12 @@ import os
+ import shutil
+ import subprocess
+ import tempfile
++import unittest
+
+ import fedpkg.cli
+ import pyrpkg
+ from fedpkg import Commands
+
+-try:
+- import unittest2 as unittest
+-except ImportError:
+- import unittest
+-
+
+ class Assertions(object):
+
+--
+2.46.0
+
diff --git a/0017-Update-check_bodhi_version-to-check-for-6.0.0.patch b/0017-Update-check_bodhi_version-to-check-for-6.0.0.patch
new file mode 100644
index 0000000..d0f5ed6
--- /dev/null
+++ b/0017-Update-check_bodhi_version-to-check-for-6.0.0.patch
@@ -0,0 +1,109 @@
+From 565bdcbc65391bbbc1e595cb3c46cea91c14fc26 Mon Sep 17 00:00:00 2001
+From: Adam Williamson <awilliam@redhat.com>
+Date: Sat, 10 Aug 2024 19:21:56 -0400
+Subject: [PATCH 6/6] Update check_bodhi_version to check for >= 6.0.0
+
+This loses the logic for handling an exception if we're under
+2.0 or bodhi-client isn't installed at all, but ehhh, that seems
+unnecessary. It's pretty unlikely anyone could manage to have
+< 2.0 at this point.
+
+Merges: https://pagure.io/fedpkg/pull-request/560
+
+Signed-off-by: Adam Williamson <awilliam@redhat.com>
+---
+ fedpkg/cli.py | 22 ++++++++++------------
+ test/test_cli.py | 35 ++++++++---------------------------
+ 2 files changed, 18 insertions(+), 39 deletions(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index d27b8b1..d42f848 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -23,9 +23,14 @@ import textwrap
+ from datetime import datetime
+ # Use deprecated pkg_resources if importlib isn't available (python 3.6)
+ try:
+- import importlib.metadata
++ from importlib.metadata import distribution
+ except ImportError:
+- import pkg_resources
++ from pkg_resources import get_distribution as distribution
++# Use deprecated pkg_resources if packaging library isn't available (python 3.6)
++try:
++ from packaging.version import parse as parse_version
++except ImportError:
++ from pkg_resources import parse_version
+ from pyrpkg import rpkgError
+ from pyrpkg.cli import cliClient
+ import configparser
+@@ -94,16 +99,9 @@ require_testcases=%(require_testcases)s
+
+ def check_bodhi_version():
+ # Use deprecated pkg_resources if importlib isn't available (python 3.6)
+- try:
+- try:
+- importlib.metadata.distribution('bodhi_client')
+- except importlib.metadata.PackageNotFoundError:
+- raise rpkgError('bodhi-client < 2.0 is not supported.')
+- except NameError:
+- try:
+- pkg_resources.get_distribution('bodhi_client')
+- except pkg_resources.DistributionNotFound:
+- raise rpkgError('bodhi-client < 2.0 is not supported.')
++ bodhi_version = distribution('bodhi-client').version
++ if parse_version(bodhi_version) < parse_version("6.0.0"):
++ raise rpkgError('bodhi-client < 6.0.0 is not supported.')
+
+
+ class fedpkgClient(cliClient):
+diff --git a/test/test_cli.py b/test/test_cli.py
+index e2d82dc..d201e7f 100644
+--- a/test/test_cli.py
++++ b/test/test_cli.py
+@@ -1604,34 +1604,15 @@ class TestRequestTestsRepo(CliTestCase):
+ self.assertEqual(str(error), expected_error)
+
+
+-# Use deprecated pkg_resources if importlib isn't available (python 3.6)
+-try:
+- import importlib.metadata
+-
+- class TestCheckBodhiVersion(unittest.TestCase):
+- """Test check_bodhi_version"""
+-
+- @patch('importlib.metadata.distribution')
+- def test_no_2_x_version_installed(self, distribution):
+- distribution.side_effect = importlib.metadata.PackageNotFoundError
+-
+- self.assertRaisesRegex(
+- rpkgError, r'bodhi-client < 2\.0 is not supported\.',
+- check_bodhi_version)
++class TestCheckBodhiVersion(unittest.TestCase):
++ """Test check_bodhi_version"""
+
+-except ImportError:
+- import pkg_resources
+-
+- class TestCheckBodhiVersion(unittest.TestCase):
+- """Test check_bodhi_version"""
+-
+- @patch('pkg_resources.get_distribution')
+- def test_no_2_x_version_installed(self, get_distribution):
+- get_distribution.side_effect = pkg_resources.DistributionNotFound
+-
+- self.assertRaisesRegex(
+- rpkgError, r'bodhi-client < 2\.0 is not supported\.',
+- check_bodhi_version)
++ @patch('fedpkg.cli.distribution')
++ def test_no_6_x_version_installed(self, mock_distribution):
++ mock_distribution.return_value.version = '5.7.5'
++ self.assertRaisesRegex(
++ rpkgError, r'bodhi-client < 6\.0\.0 is not supported\.',
++ check_bodhi_version)
+
+
+ @unittest.skipUnless(bodhi, 'Skip if no supported bodhi-client is available')
+--
+2.46.0
+
diff --git a/0018-Fix-URL-of-Bodhi-in-staging.patch b/0018-Fix-URL-of-Bodhi-in-staging.patch
new file mode 100644
index 0000000..5721e7b
--- /dev/null
+++ b/0018-Fix-URL-of-Bodhi-in-staging.patch
@@ -0,0 +1,33 @@
+From 7191f8a255deaa2936e419ac7645322346c373e0 Mon Sep 17 00:00:00 2001
+From: Nils Philippsen <nils@redhat.com>
+Date: Thu, 15 Aug 2024 20:17:34 +0200
+Subject: [PATCH] Fix URL of Bodhi in staging
+
+Otherwise, it errors out like this:
+
+```
+$ fedpkg-stage build
+Could not execute build: Invalid URL 'bodhi.stg.fedoraproject.org/releases//?exclude_archived=True': No scheme supplied. Perhaps you meant https://bodhi.stg.fedoraproject.org/releases//?exclude_archived=True?
+```
+
+Signed-off-by: Nils Philippsen <nils@redhat.com>
+---
+ conf/etc/rpkg/fedpkg-stage.conf | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/conf/etc/rpkg/fedpkg-stage.conf b/conf/etc/rpkg/fedpkg-stage.conf
+index 144ce76..8f92fc8 100644
+--- a/conf/etc/rpkg/fedpkg-stage.conf
++++ b/conf/etc/rpkg/fedpkg-stage.conf
+@@ -57,7 +57,7 @@ lookaside_delay = 15
+ # Refer to fedpkg.conf
+ staging = True
+ releases_service = https://bodhi.stg.fedoraproject.org/releases/%(release)s
+-url = bodhi.stg.fedoraproject.org/
++url = https://bodhi.stg.fedoraproject.org/
+
+ [fedpkg-stage.mbs]
+ auth_method = oidc
+--
+2.46.0
+
diff --git a/0019-Fixes-missing-key-in-distro.os_release_info.patch b/0019-Fixes-missing-key-in-distro.os_release_info.patch
new file mode 100644
index 0000000..40bc202
--- /dev/null
+++ b/0019-Fixes-missing-key-in-distro.os_release_info.patch
@@ -0,0 +1,32 @@
+From 05c4cb3b113eb9e3679f6344d2c7283e281581f4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Wed, 18 Sep 2024 04:51:06 +0200
+Subject: [PATCH] Fixes missing key in distro.os_release_info()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+During building in Koji unit test fails on missing key 'variant'.
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ fedpkg/__init__.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 57a6eae..2d3ed7e 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -279,7 +279,8 @@ class Commands(pyrpkg.Commands):
+ if distro.id() == 'rhel' or 'rhel' in distro.like().split():
+ return 'el%s' % distro.major_version()
+ if distro.id() == 'fedora':
+- if distro.os_release_info()['variant'] == 'ELN':
++ os_release_info = distro.os_release_info()
++ if 'variant' in os_release_info and os_release_info['variant'] == 'ELN':
+ macros = self._get_build_macros('eln-candidate')
+ return 'eln%s' % macros['eln']
+ return 'fc%s' % distro.major_version()
+--
+2.46.0
+
diff --git a/0020-Do-not-auto-request-ELN-modules.patch b/0020-Do-not-auto-request-ELN-modules.patch
new file mode 100644
index 0000000..5c21ab7
--- /dev/null
+++ b/0020-Do-not-auto-request-ELN-modules.patch
@@ -0,0 +1,33 @@
+From bc1d18e659bf04bc33c8a627fedb323036f1f438 Mon Sep 17 00:00:00 2001
+From: Yaakov Selkowitz <yselkowi@redhat.com>
+Date: Mon, 26 Aug 2024 17:46:51 -0400
+Subject: [PATCH] Do not auto-request ELN modules
+
+ELN is a release branch. While acceptance of the --sl argument is
+determined from Bodhi, this regex is still used to determine when modules
+should be auto-requested.
+
+Relates: https://pagure.io/releng/issue/12273
+Merges: https://pagure.io/fedpkg/pull-request/564
+
+Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
+---
+ fedpkg/cli.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fedpkg/cli.py b/fedpkg/cli.py
+index d42f848..a4381a7 100644
+--- a/fedpkg/cli.py
++++ b/fedpkg/cli.py
+@@ -46,7 +46,7 @@ from fedpkg.utils import (assert_new_tests_repo, assert_valid_epel_package,
+ get_release_branches, get_stream_branches, is_epel,
+ new_pagure_issue, sl_list_to_dict, verify_sls)
+
+-RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|epel\d+)$'
++RELEASE_BRANCH_REGEX = r'^(f\d+|el\d+|eln|epel\d+)$'
+ LOCAL_PACKAGE_CONFIG = 'package.cfg'
+
+ BODHI_TEMPLATE = """\
+--
+2.46.0
+
diff --git a/0021-Fix-minor-requirements-for-EPEL10-in-test.patch b/0021-Fix-minor-requirements-for-EPEL10-in-test.patch
new file mode 100644
index 0000000..18d31e0
--- /dev/null
+++ b/0021-Fix-minor-requirements-for-EPEL10-in-test.patch
@@ -0,0 +1,48 @@
+From 284e7988a22bf743eb0de1c0380110cf6de12e7e Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 16 Aug 2024 13:50:27 -0400
+Subject: [PATCH 1/7] Fix minor requirements for EPEL10+ in test
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ test/test_commands.py | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/test/test_commands.py b/test/test_commands.py
+index 8a90668..b2ae3fa 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -266,17 +266,27 @@ class TestLoadRpmDefines(CommandTestCase):
+
+ self.assert_rpmdefines()
+
++ @patch('pyrpkg.Commands.kojisession', new_callable=PropertyMock)
+ @patch('pyrpkg.Commands.branch_merge', new_callable=PropertyMock)
+- def test_load_epel10_dist_tag(self, branch_merge):
++ def test_load_epel10_dist_tag(self, branch_merge, kojisession):
+ branch_merge.return_value = 'epel10'
+
++ self.cmd._kojisession = Mock()
++ koji_session = kojisession.return_value
++ koji_session.getBuildConfig.return_value = {
++ # minimal subset of the real koji response
++ 'extra': {
++ 'rpm.macro.distcore': '.el10_3',
++ },
++ }
++
+ self.cmd.load_rpmdefines()
+
+ self.assertEqual('10', self.cmd._distval)
+ self.assertEqual('rhel', self.cmd._distvar)
+- self.assertEqual('el10', self.cmd._disttag)
++ self.assertEqual('el10_3', self.cmd._disttag)
+ self.assertEqual('epel-10-i686', self.cmd.mockconfig)
+- self.assertEqual('epel10-override', self.cmd.override)
++ self.assertEqual('epel10.3-override', self.cmd.override)
+ self.assertTrue(hasattr(self.cmd, '_distunset'))
+
+ self.assert_rpmdefines()
+--
+2.46.0
+
diff --git a/0022-Use-minor-value-from-koji-when-no-minor-in-branch-na.patch b/0022-Use-minor-value-from-koji-when-no-minor-in-branch-na.patch
new file mode 100644
index 0000000..0b1308a
--- /dev/null
+++ b/0022-Use-minor-value-from-koji-when-no-minor-in-branch-na.patch
@@ -0,0 +1,59 @@
+From 083d3b35734805ab0606adfec525d93e0d6bf33f Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 16 Aug 2024 13:51:32 -0400
+Subject: [PATCH 2/7] Use minor value from koji when no minor in branch name
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ fedpkg/__init__.py | 32 ++++++++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 2d3ed7e..9edd11f 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -74,17 +74,33 @@ class Commands(pyrpkg.Commands):
+ self.mockconfig = 'fedora-%s-%s' % (self._distval, self.localarch)
+ self.override = 'f%s-override' % self._distval
+ self._distunset = 'rhel'
++ # Works until RHEL 10
+ elif re.match(r'el\d$', branch) or \
+- re.match(r'epel\d+(?:\.\d+)?$', branch):
+- major, minor = re.findall(r'(\d+)(?:\.(\d+))?', branch)[0]
++ re.match(r'epel\d$', branch):
++ self._distval = branch.split('el')[1]
++ self._distvar = 'rhel'
++ self._disttag = 'el%s' % self._distval
++ self.mockconfig = 'epel-%s-%s' % (self._distval, self.localarch)
++ self.override = 'epel%s-override' % self._distval
++ self._distunset = 'fedora'
++ # EPEL 10+ without minor
++ elif re.match(r'epel\d\d$', branch):
++ macros = self._get_build_macros('epel%s' % branch.split('el')[1])
++ major, minor = re.findall(r'.el(\d+)_(\d+)$', macros['distcore'])[0]
++ self._distval = major
++ self._distvar = 'rhel'
++ self._disttag = macros['distcore'].split('.')[1]
++ self.mockconfig = 'epel-%s-%s' % (major, self.localarch)
++ self.override = 'epel%s.%s-override' % (major, minor)
++ self._distunset = 'fedora'
++ # EPEL 10+ with minor
++ elif re.match(r'epel\d\d+\.\d+$', branch):
++ major, minor = re.findall(r'epel(\d+)\.(\d+)$', branch)[0]
+ self._distval = major
+ self._distvar = 'rhel'
+- self._disttag = 'el%s' % major if minor == '' \
+- else 'el%s_%s' % (major, minor)
+- self.mockconfig = 'epel-%s-%s' % (major, self.localarch) if minor == '' \
+- else 'epel-%s.%s-%s' % (major, minor, self.localarch)
+- self.override = 'epel%s-override' % self._distval if minor == '' \
+- else 'epel%s.%s-override' % (major, minor)
++ self._disttag = 'el%s_%s' % (major, minor)
++ self.mockconfig = 'epel-%s.%s-%s' % (major, minor, self.localarch)
++ self.override = 'epel%s.%s-override' % (major, minor)
+ self._distunset = 'fedora'
+ elif re.match(r'epel\d+-next$', branch):
+ self._distval = re.search(r'\d+', branch).group(0)
+--
+2.46.0
+
diff --git a/0023-Fix-EPEL10-branch-expression-to-cover-2-or-more-digi.patch b/0023-Fix-EPEL10-branch-expression-to-cover-2-or-more-digi.patch
new file mode 100644
index 0000000..6f4b53a
--- /dev/null
+++ b/0023-Fix-EPEL10-branch-expression-to-cover-2-or-more-digi.patch
@@ -0,0 +1,35 @@
+From 81ba9bb99cc93db6467c6d27ce6f723642100ef8 Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 16 Aug 2024 16:03:38 -0400
+Subject: [PATCH 3/7] Fix EPEL10 branch expression to cover 2 or more digits.
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ fedpkg/__init__.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 9edd11f..4e72dbd 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -84,7 +84,7 @@ class Commands(pyrpkg.Commands):
+ self.override = 'epel%s-override' % self._distval
+ self._distunset = 'fedora'
+ # EPEL 10+ without minor
+- elif re.match(r'epel\d\d$', branch):
++ elif re.match(r'epel\d{2,}$', branch):
+ macros = self._get_build_macros('epel%s' % branch.split('el')[1])
+ major, minor = re.findall(r'.el(\d+)_(\d+)$', macros['distcore'])[0]
+ self._distval = major
+@@ -94,7 +94,7 @@ class Commands(pyrpkg.Commands):
+ self.override = 'epel%s.%s-override' % (major, minor)
+ self._distunset = 'fedora'
+ # EPEL 10+ with minor
+- elif re.match(r'epel\d\d+\.\d+$', branch):
++ elif re.match(r'epel\d{2,}\.\d+$', branch):
+ major, minor = re.findall(r'epel(\d+)\.(\d+)$', branch)[0]
+ self._distval = major
+ self._distvar = 'rhel'
+--
+2.46.0
+
diff --git a/0024-Get-macros-from-epel-candidate-build-target.patch b/0024-Get-macros-from-epel-candidate-build-target.patch
new file mode 100644
index 0000000..c152ff4
--- /dev/null
+++ b/0024-Get-macros-from-epel-candidate-build-target.patch
@@ -0,0 +1,26 @@
+From 54079bf1121ac0eaebbb598888333c3a36d1508f Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 16 Aug 2024 16:36:53 -0400
+Subject: [PATCH 4/7] Get macros from epel-candidate build target.
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ fedpkg/__init__.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 4e72dbd..e9d41b2 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -85,7 +85,7 @@ class Commands(pyrpkg.Commands):
+ self._distunset = 'fedora'
+ # EPEL 10+ without minor
+ elif re.match(r'epel\d{2,}$', branch):
+- macros = self._get_build_macros('epel%s' % branch.split('el')[1])
++ macros = self._get_build_macros('epel%s-candidate' % branch.split('el')[1])
+ major, minor = re.findall(r'.el(\d+)_(\d+)$', macros['distcore'])[0]
+ self._distval = major
+ self._distvar = 'rhel'
+--
+2.46.0
+
diff --git a/0025-Improvements-on-string-parsing.patch b/0025-Improvements-on-string-parsing.patch
new file mode 100644
index 0000000..4424fa8
--- /dev/null
+++ b/0025-Improvements-on-string-parsing.patch
@@ -0,0 +1,39 @@
+From ff03aa603fb505824d0132561938bd78dd743b9c Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Tue, 20 Aug 2024 15:09:37 -0400
+Subject: [PATCH 5/7] Improvements on string parsing
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ fedpkg/__init__.py | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index e9d41b2..3d54c56 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -85,17 +85,17 @@ class Commands(pyrpkg.Commands):
+ self._distunset = 'fedora'
+ # EPEL 10+ without minor
+ elif re.match(r'epel\d{2,}$', branch):
+- macros = self._get_build_macros('epel%s-candidate' % branch.split('el')[1])
+- major, minor = re.findall(r'.el(\d+)_(\d+)$', macros['distcore'])[0]
++ macros = self._get_build_macros('epel%s-candidate' % branch[4:])
++ major, minor = macros['distcore'][3:].split('_')
+ self._distval = major
+ self._distvar = 'rhel'
+- self._disttag = macros['distcore'].split('.')[1]
++ self._disttag = macros['distcore'][1:]
+ self.mockconfig = 'epel-%s-%s' % (major, self.localarch)
+ self.override = 'epel%s.%s-override' % (major, minor)
+ self._distunset = 'fedora'
+ # EPEL 10+ with minor
+ elif re.match(r'epel\d{2,}\.\d+$', branch):
+- major, minor = re.findall(r'epel(\d+)\.(\d+)$', branch)[0]
++ major, minor = branch[4:].split('.')
+ self._distval = major
+ self._distvar = 'rhel'
+ self._disttag = 'el%s_%s' % (major, minor)
+--
+2.46.0
+
diff --git a/0026-Add-tests-cases-for-runtime_disttag-removal-when-wor.patch b/0026-Add-tests-cases-for-runtime_disttag-removal-when-wor.patch
new file mode 100644
index 0000000..767f1dc
--- /dev/null
+++ b/0026-Add-tests-cases-for-runtime_disttag-removal-when-wor.patch
@@ -0,0 +1,99 @@
+From 79cee4a69457251374d4fcaf28cdde3a8d1e4030 Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 30 Aug 2024 14:37:15 -0400
+Subject: [PATCH 6/7] Add tests cases for runtime_disttag removal when working
+ with epel10
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ test/test_commands.py | 74 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 74 insertions(+)
+
+diff --git a/test/test_commands.py b/test/test_commands.py
+index b2ae3fa..d160da9 100644
+--- a/test/test_commands.py
++++ b/test/test_commands.py
+@@ -369,6 +369,80 @@ class TestLoadRpmDefines(CommandTestCase):
+ self.assert_rpmdefines(extra_rpmdefines)
+
+
++class TestLoadRpmDefinesRuntimes(CommandTestCase):
++ """Test Commands.load_rpmdefines"""
++
++ def setUp(self):
++ super(TestLoadRpmDefinesRuntimes, self).setUp()
++
++ self.localarch = patch(
++ 'pyrpkg.Commands.localarch',
++ new_callable=PropertyMock,
++ return_value='i686')
++ self.localarch.start()
++
++ self.cmd = self.make_commands()
++
++ def tearDown(self):
++ self.localarch.stop()
++ super(TestLoadRpmDefinesRuntimes, self).tearDown()
++
++ def assert_rpmdefines(self, extra_rpmdefines=[]):
++ """Assert Commands._rpmdefines after calling load_rpmdefines"""
++ expected_rpmdefines = [
++ "--define", "_sourcedir %s" % self.cmd.layout.sourcedir,
++ "--define", "_specdir %s" % self.cmd.layout.specdir,
++ "--define", "_builddir %s" % self.cmd.layout.builddir,
++ "--define", "_srcrpmdir %s" % self.cmd.layout.srcrpmdir,
++ "--define", "_rpmdir %s" % self.cmd.layout.rpmdir,
++ "--define", "_rpmfilename %s" % self.cmd.layout.rpmfilename,
++ "--define", "dist %%{?distprefix}.%s" % self.cmd._disttag,
++ "--define", "%s %s" % (self.cmd._distvar, self.cmd._distval),
++ "--eval", "%%undefine %s" % self.cmd._distunset,
++ "--define", "%s 1" % self.cmd._disttag.replace(".", "_")
++ ]
++ expected_rpmdefines.extend(extra_rpmdefines)
++ self.assertEqual(expected_rpmdefines, self.cmd._rpmdefines)
++
++ @patch('fedpkg.Commands._determine_runtime_env')
++ @patch('pyrpkg.Commands.branch_merge', new_callable=PropertyMock)
++ def test_load_fc40_on_el10_8_runtime(self, branch_merge, _determine_runtime_env):
++ _determine_runtime_env.return_value = 'fc40'
++ branch_merge.return_value = 'epel10.8'
++
++ self.cmd.load_rpmdefines()
++ extra_rpmdefines = [
++ "--eval", "%%undefine %s" % self.cmd._runtime_disttag]
++ self.assert_rpmdefines(extra_rpmdefines)
++
++ @patch('fedpkg.Commands._determine_runtime_env')
++ @patch('pyrpkg.Commands.kojisession', new_callable=PropertyMock)
++ @patch('pyrpkg.Commands.branch_merge', new_callable=PropertyMock)
++ def test_load_epel10_on_el10_runtime(self, branch_merge, kojisession, _determine_runtime_env):
++ _determine_runtime_env.return_value = 'el10'
++ branch_merge.return_value = 'epel10'
++
++ self.cmd._kojisession = Mock()
++ koji_session = kojisession.return_value
++ koji_session.getBuildConfig.return_value = {
++ # minimal subset of the real koji response
++ 'extra': {
++ 'rpm.macro.distcore': '.el10_8',
++ },
++ }
++ self.cmd.load_rpmdefines()
++ self.assert_rpmdefines()
++
++ @patch('fedpkg.Commands._determine_runtime_env')
++ @patch('pyrpkg.Commands.branch_merge', new_callable=PropertyMock)
++ def test_load_epel10_4_on_el10_runtime(self, branch_merge, _determine_runtime_env):
++ _determine_runtime_env.return_value = 'el10'
++ branch_merge.return_value = 'epel10.4'
++
++ self.cmd.load_rpmdefines()
++ self.assert_rpmdefines()
++
++
+ class TestFindRawhideBranch(CommandTestCase):
+ """Test Commands._findrawhidebranch"""
+
+--
+2.46.0
+
diff --git a/0027-Handle-rhel-runtimes-when-minor-version-exists-in-di.patch b/0027-Handle-rhel-runtimes-when-minor-version-exists-in-di.patch
new file mode 100644
index 0000000..8b56ab8
--- /dev/null
+++ b/0027-Handle-rhel-runtimes-when-minor-version-exists-in-di.patch
@@ -0,0 +1,36 @@
+From 7559b4cdb93d5a92c6b14b28b09cabebcc5965f9 Mon Sep 17 00:00:00 2001
+From: Diego Herrera <dherrera@redhat.com>
+Date: Fri, 30 Aug 2024 17:58:58 -0400
+Subject: [PATCH 7/7] Handle rhel runtimes when minor version exists in disttag
+
+Signed-off-by: Diego Herrera <dherrera@redhat.com>
+---
+ fedpkg/__init__.py | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/fedpkg/__init__.py b/fedpkg/__init__.py
+index 3d54c56..7683f45 100644
+--- a/fedpkg/__init__.py
++++ b/fedpkg/__init__.py
+@@ -177,10 +177,15 @@ class Commands(pyrpkg.Commands):
+ "--define", "%s 1" % self._disttag.replace(".", "_")]
+ # TODO: consider removing macro "%s 1; it has unknown/dubious functionality"
+
++ # If the runtime is known, and is different from
++ # the target, we need to unset the _runtime_disttag
+ if self._runtime_disttag:
+- if self._disttag != self._runtime_disttag:
+- # This means that the runtime is known, and is different from
+- # the target, so we need to unset the _runtime_disttag
++ # In the case of rhel like runtimes, only the major needs to be different
++ if re.match(r'^el\d', self._runtime_disttag):
++ if not self._disttag.startswith(self._runtime_disttag):
++ self._rpmdefines.extend(["--eval", "%%undefine %s" %
++ self._runtime_disttag])
++ elif self._disttag != self._runtime_disttag:
+ self._rpmdefines.extend(["--eval", "%%undefine %s" %
+ self._runtime_disttag])
+
+--
+2.46.0
+
diff --git a/fedpkg.spec b/fedpkg.spec
index e697ef8..5b26575 100644
--- a/fedpkg.spec
+++ b/fedpkg.spec
@@ -5,7 +5,7 @@
Name: fedpkg
Version: 1.45
-Release: 4%{?dist}
+Release: 5%{?dist}
Summary: Fedora utility for working with dist-git
# Automatically converted from old format: GPLv2+ - review is highly recommended.
@@ -25,6 +25,22 @@ Patch8: 0008-Add-EPEL10-branch-name-cases-as-valid.patch
Patch9: 0009-Test-url-usage-in-assert_valid_epel_package.patch
Patch10: 0010-Add-EPEL10-url-pattern-on-assert_valid_epel_package.patch
Patch11: 0011-Extend-load_rpmdefines-to-work-with-EPEL10.patch
+Patch12: 0012-Add-py313-environment-as-that-s-current.patch
+Patch13: 0013-Drop-support-for-bodhi-client-5.patch
+Patch14: 0014-Drop-all-usage-of-six.patch
+Patch15: 0015-Replace-and-update-use-of-deprecated-linux_distribut.patch
+Patch16: 0016-Modernize-and-clean-unittest-imports.patch
+Patch17: 0017-Update-check_bodhi_version-to-check-for-6.0.0.patch
+Patch18: 0018-Fix-URL-of-Bodhi-in-staging.patch
+Patch19: 0019-Fixes-missing-key-in-distro.os_release_info.patch
+Patch20: 0020-Do-not-auto-request-ELN-modules.patch
+Patch21: 0021-Fix-minor-requirements-for-EPEL10-in-test.patch
+Patch22: 0022-Use-minor-value-from-koji-when-no-minor-in-branch-na.patch
+Patch23: 0023-Fix-EPEL10-branch-expression-to-cover-2-or-more-digi.patch
+Patch24: 0024-Get-macros-from-epel-candidate-build-target.patch
+Patch25: 0025-Improvements-on-string-parsing.patch
+Patch26: 0026-Add-tests-cases-for-runtime_disttag-removal-when-wor.patch
+Patch27: 0027-Handle-rhel-runtimes-when-minor-version-exists-in-di.patch
BuildRequires: pkgconfig
BuildRequires: bash-completion
@@ -39,7 +55,6 @@ Requires: redhat-rpm-config
BuildRequires: python3-devel
BuildRequires: python3-rpkg >= 1.67-1
BuildRequires: python3-distro
-BuildRequires: python3-fedora
# For testing
BuildRequires: python3-pytest
BuildRequires: python3-setuptools
@@ -51,7 +66,6 @@ BuildRequires: python3-bodhi-client
Requires: python3-bugzilla
Requires: python3-rpkg >= 1.67-1
Requires: python3-distro
-Requires: python3-fedora
Requires: python3-openidc-client >= 0.6.0
Requires: python3-bodhi-client
Requires: python3-setuptools
@@ -109,6 +123,24 @@ mv %{buildroot}%{compdir}/fedpkg.bash %{buildroot}%{compdir}/fedpkg
%changelog
+* Wed Sep 18 2024 Ondřej Nosek <onosek@redhat.com> - 1.45-5
+- Add py313 environment as that's current
+- Drop support for bodhi-client <= 5
+- Drop all usage of six
+- Replace and update use of deprecated 'linux_distribution'
+- Modernize and clean unittest imports
+- Update check_bodhi_version to check for >= 6.0.0
+- Fix URL of Bodhi in staging
+- Fixes missing key in distro.os_release_info()
+- Do not auto-request ELN modules
+- Fix minor requirements for EPEL10+ in test
+- Use minor value from koji when no minor in branch name
+- Fix EPEL10 branch expression to cover 2 or more digits.
+- Get macros from epel-candidate build target.
+- Improvements on string parsing
+- Add tests cases for runtime_disttag removal when working with epel10
+- Handle rhel runtimes when minor version exists in disttag
+
* Thu Jul 25 2024 Miroslav Suchý <msuchy@redhat.com> - 1.45-4
- convert license to SPDX
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-10 21:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-10 21:46 [rpms/fedpkg] 1.48-1: A few patches:
2026-08-10 21:46
2026-08-10 21:46
2026-08-10 21:46
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox