From d6e19eda6e92552ff18becc15aa7afc1320e0ab3 Mon Sep 17 00:00:00 2001 From: Anton Medvedev Date: May 25 2026 00:48:08 +0000 Subject: feat(request_unretirement): deviding branches into koji_tags and distgit_branches and changing key name for ticket body Signed-off-by: Anton Medvedev --- diff --git a/fedpkg/cli.py b/fedpkg/cli.py index 07fcee2..b37b695 100644 --- a/fedpkg/cli.py +++ b/fedpkg/cli.py @@ -630,7 +630,7 @@ class fedpkgClient(cliClient): required=False, nargs='+', dest="branches", - help="Comma-separated list of branches for unretirement." + help="Space-separated list of branches for unretirement." ) request_unretirement_parser.set_defaults(command=self.request_unretirement) @@ -1610,7 +1610,12 @@ class fedpkgClient(cliClient): " So there is nothing to unretire.".format(requested_branches) ) - for branch in branches: + pagure_branches = get_pagure_branches( + logger, distgit_url, ns, repo_name) + koji_tags = sorted(branches) + distgit_branches = sorted(b for b in branches if b in pagure_branches) + + for branch in distgit_branches: commit_date = get_last_commit_date(distgit_url, ns, repo_name, branch) committed_time = datetime.fromtimestamp(commit_date) difference_in_days = (current_time - committed_time).days @@ -1648,9 +1653,10 @@ class fedpkgClient(cliClient): ticket_body = { 'action': 'unretirement', - 'name': repo_name, + 'repo': repo_name, 'type': ns, - 'branches': branches, + 'koji_tags': koji_tags, + 'branches': distgit_branches, 'review_bugzilla': bug_id, 'maintainer': fas_name, } diff --git a/test/test_cli.py b/test/test_cli.py index 9b5ef3a..747c20f 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -2632,16 +2632,19 @@ class TestRequestUnretirement(CliTestCase): with patch('sys.argv', new=cli_cmd): return self.new_cli(name=name, cfg=cfg, user_cfg=user_cfg) + @patch("fedpkg.cli.get_pagure_branches") @patch("fedpkg.cli.get_last_commit_date") @patch("fedpkg.cli.get_release_branches") @patch("requests.post") @patch('sys.stdout', new=io.StringIO()) - def test_request_unretirement(self, mock_request_post, mock_grb, mock_gcd): + def test_request_unretirement(self, mock_request_post, mock_grb, mock_gcd, + mock_gpb): """Tests request-unretirement command.""" mock_grb.return_value = { 'fedora': ['f39', 'f40', 'f41'], 'epel': ['epel9', 'epel10'], } + mock_gpb.return_value = ['f40'] mock_rv = Mock() mock_rv.ok = True @@ -2661,8 +2664,9 @@ class TestRequestUnretirement(CliTestCase): expected_issue_content = { 'action': 'unretirement', - 'name': 'testpkg', + 'repo': 'testpkg', 'type': 'rpms', + 'koji_tags': ['f40'], 'branches': ['f40'], 'review_bugzilla': None, 'maintainer': 'root', @@ -2707,25 +2711,27 @@ class TestRequestUnretirement(CliTestCase): except rpkgError as error: self.assertEqual(str(error), expected_error) + @patch("fedpkg.cli.get_pagure_branches") @patch("fedpkg.cli.get_last_commit_date") @patch("fedpkg.cli.get_release_branches") @patch("requests.post") @patch('sys.stdout', new=io.StringIO()) def test_request_unretirement_bugzilla_needed_but_not_provided( - self, mock_request_post, mock_grb, mock_gcd + self, mock_request_post, mock_grb, mock_gcd, mock_gpb ): """Tests request-unretirement that require to check bugzilla, but bug id wasn't provided""" mock_grb.return_value = { 'fedora': ['f39', 'f40', 'f41'], 'epel': ['epel9', 'epel10'], } + mock_gpb.return_value = ['f40'] mock_rv = Mock() mock_rv.ok = True mock_rv.json.return_value = {'issue': {'id': 41}} mock_request_post.return_value = mock_rv - commit_time = (datetime.now() - timedelta(days=57)).timestamp() + commit_time = (datetime.now() - timedelta(days=60)).timestamp() mock_gcd.return_value = commit_time expected_error = ( @@ -2735,7 +2741,10 @@ class TestRequestUnretirement(CliTestCase): self.run_cmd(['git', 'checkout', '-b', 'f40'], cwd=self.cloned_repo_path) - cli_cmd = ['fedpkg-stage', '--path', self.cloned_repo_path, 'request-unretirement'] + cli_cmd = [ + 'fedpkg-stage', '--path', self.cloned_repo_path, + 'request-unretirement', '-b', 'f40', + ] cli = self.get_cli(cli_cmd) try: @@ -2745,25 +2754,27 @@ class TestRequestUnretirement(CliTestCase): self.assertEqual(str(error), expected_error) @patch("fedpkg.bugzilla.BugzillaClient.get_review_bug") + @patch("fedpkg.cli.get_pagure_branches") @patch("fedpkg.cli.get_last_commit_date") @patch("fedpkg.cli.get_release_branches") @patch("requests.post") @patch('sys.stdout', new=io.StringIO()) def test_request_unretirement_bz_id_provided( - self, mock_request_post, mock_grb, mock_gcd, mock_bz_grb + self, mock_request_post, mock_grb, mock_gcd, mock_gpb, mock_bz_grb ): """Tests request-unretirement command when bz_id provided""" mock_grb.return_value = { 'fedora': ['f39', 'f40', 'f41'], 'epel': ['epel9', 'epel10'], } + mock_gpb.return_value = ['f40'] mock_rv = Mock() mock_rv.ok = True mock_rv.json.return_value = {'issue': {'id': 41}} mock_request_post.return_value = mock_rv - commit_time = (datetime.now() - timedelta(days=57)).timestamp() + commit_time = (datetime.now() - timedelta(days=60)).timestamp() mock_gcd.return_value = commit_time self.run_cmd(['git', 'checkout', '-b', 'f40'], cwd=self.cloned_repo_path) @@ -2777,8 +2788,9 @@ class TestRequestUnretirement(CliTestCase): expected_issue_content = { 'action': 'unretirement', - 'name': 'testpkg', + 'repo': 'testpkg', 'type': 'rpms', + 'koji_tags': ['f40'], 'branches': ['f40'], 'review_bugzilla': '1234567', 'maintainer': 'root', @@ -2794,25 +2806,27 @@ class TestRequestUnretirement(CliTestCase): self.assertEqual(output, expected_output) @patch("fedpkg.bugzilla.BugzillaClient.get_review_bug") + @patch("fedpkg.cli.get_pagure_branches") @patch("fedpkg.cli.get_last_commit_date") @patch("fedpkg.cli.get_release_branches") @patch("requests.post") @patch('sys.stdout', new=io.StringIO()) def test_request_unretirement_bz_url_provided( - self, mock_request_post, mock_grb, mock_gcd, mock_bz_grb + self, mock_request_post, mock_grb, mock_gcd, mock_gpb, mock_bz_grb ): """Tests request-unretirement command when bz url provided""" mock_grb.return_value = { 'fedora': ['f39', 'f40', 'f41'], 'epel': ['epel9', 'epel10'], } + mock_gpb.return_value = ['f40'] mock_rv = Mock() mock_rv.ok = True mock_rv.json.return_value = {'issue': {'id': 41}} mock_request_post.return_value = mock_rv - commit_time = (datetime.now() - timedelta(days=57)).timestamp() + commit_time = (datetime.now() - timedelta(days=60)).timestamp() mock_gcd.return_value = commit_time self.run_cmd(['git', 'checkout', '-b', 'f40'], cwd=self.cloned_repo_path) @@ -2827,8 +2841,9 @@ class TestRequestUnretirement(CliTestCase): expected_issue_content = { 'action': 'unretirement', - 'name': 'testpkg', + 'repo': 'testpkg', 'type': 'rpms', + 'koji_tags': ['f40'], 'branches': ['f40'], 'review_bugzilla': '1234567', 'maintainer': 'root', @@ -2843,18 +2858,20 @@ class TestRequestUnretirement(CliTestCase): 'fedora-scm-requests/issue/41') self.assertEqual(output, expected_output) + @patch("fedpkg.cli.get_pagure_branches") @patch("fedpkg.cli.get_last_commit_date") @patch("fedpkg.cli.get_release_branches") @patch("requests.post") @patch('sys.stdout', new=io.StringIO()) def test_request_unretirement_repo_name_provided( - self, mock_request_post, mock_grb, mock_gcd + self, mock_request_post, mock_grb, mock_gcd, mock_gpb ): """Tests request-unretirement command.""" mock_grb.return_value = { 'fedora': ['f39', 'f40', 'f41'], 'epel': ['epel9', 'epel10'], } + mock_gpb.return_value = ['f40'] mock_rv = Mock() mock_rv.ok = True @@ -2874,8 +2891,9 @@ class TestRequestUnretirement(CliTestCase): expected_issue_content = { 'action': 'unretirement', - 'name': 'belusha', + 'repo': 'belusha', 'type': 'rpms', + 'koji_tags': ['f40'], 'branches': ['f40'], 'review_bugzilla': None, 'maintainer': 'root', @@ -2889,3 +2907,51 @@ class TestRequestUnretirement(CliTestCase): expected_output = ('https://pagure.stg.example.com/releng/' 'fedora-scm-requests/issue/41') self.assertEqual(output, expected_output) + + @patch("fedpkg.cli.get_pagure_branches") + @patch("fedpkg.cli.get_last_commit_date") + @patch("fedpkg.cli.get_release_branches") + @patch("requests.post") + @patch('sys.stdout', new=io.StringIO()) + def test_request_unretirement_koji_tags_and_branches( + self, mock_request_post, mock_grb, mock_gcd, mock_gpb + ): + """Tests branches are split into dist-git and koji-only groups.""" + mock_grb.return_value = { + 'fedora': ['f39', 'f40', 'f41'], + 'epel': ['epel9', 'epel10'], + } + mock_gpb.return_value = ['f40'] + + mock_rv = Mock() + mock_rv.ok = True + mock_rv.json.return_value = {'issue': {'id': 41}} + mock_request_post.return_value = mock_rv + + commit_time = (datetime.now() - timedelta(days=1)).timestamp() + mock_gcd.return_value = commit_time + + cli_cmd = [ + 'fedpkg-stage', '--path', self.cloned_repo_path, '--user', 'root', + 'request-unretirement', '-b', 'f40', 'f41', + ] + + cli = self.get_cli(cli_cmd) + cli.request_unretirement() + + expected_issue_content = { + 'action': 'unretirement', + 'repo': 'testpkg', + 'type': 'rpms', + 'koji_tags': ['f40', 'f41'], + 'branches': ['f40'], + 'review_bugzilla': None, + 'maintainer': 'root', + } + + post_data = mock_request_post.call_args_list[0][1]['data'] + actual_issue_content = json.loads(json.loads( + post_data)['issue_content'].strip('```')) + self.assertEqual(expected_issue_content, actual_issue_content) + mock_gcd.assert_called_once_with( + 'https://src.example.com', 'rpms', 'testpkg', 'f40')