From 6dbddda9a98ed5ec1d95dd06733f6e84efdfa69d Mon Sep 17 00:00:00 2001 From: Lars Hupfeldt Date: Sun, 12 Jan 2025 15:31:11 +0100 Subject: [PATCH] Codeberg (Forgejo) support. No code changes, just test and documentation. --- README.rst | 18 +++++++- src/jenkins_api.py | 4 +- test/conftest.py | 3 +- test/github_folder_test.py | 68 ----------------------------- test/invalid_job_names_test.py | 6 ++- test/organization_folder_test.py | 73 ++++++++++++++++++++++++++++++++ 6 files changed, 98 insertions(+), 74 deletions(-) delete mode 100644 test/github_folder_test.py create mode 100644 test/organization_folder_test.py diff --git a/README.rst b/README.rst index c98b936..4b8c870 100644 --- a/README.rst +++ b/README.rst @@ -251,7 +251,23 @@ Test .. note:: - To run the GitHub folder job test a GitHub test repository is needed! TODO: Describe the setup. + To run the Codeberg folder job test a `Codeberg `_ test and Jenkins configuration repository is needed! + + Fork `codeberg test repo `_ to your own organization/user account. + Add the `Gitea plugin `_ to Jenkins. In system config add a Gitea server name `Codeberg`, URL `https://codeberg.org/`. + Add an `Organization Folder` job named `codeberg-org`, with server `Codeberg`. Set `owner` to your organization/account and + `Script path` to `Jenkinsfile.jenkinsflow-test`. + + .. note:: + + To run the GitHub folder job test a `GitHub `_ test and Jenkins configuration repository is needed! + + Fork `github test repo `_ to your own organization/user account. + Add a GitHub App in your organization and install it on the repo. + Create the corresponfig GitHubApp credentilal in Jennkins, id `cred-github-jenkinsflow-test`. + Add the `Gitea plugin `_ to Jenkins. In system config add a Gitea server name `GitHub`, URL `https://github.com/`. + Add an `Organization Folder` job named `github-org`, with server `GitHub`. Set `owner` to your organization/account, credential + to `cred-github-jenkinsflow-test` and `Script path` to `Jenkinsfile.jenkinsflow-test`. #. Run the tests using ``nox``:: diff --git a/src/jenkins_api.py b/src/jenkins_api.py index da0dfcd..85c0824 100644 --- a/src/jenkins_api.py +++ b/src/jenkins_api.py @@ -27,9 +27,9 @@ # Initial query # Build a three level query to handle github organization folder jobs. # Note that 'name' in response does not contain first 'job/' from url, but does contain intermediate 'job/', so: -# 'name': 'gh-org/job/jenkinsflow-gh-folder-test/job/main' +# 'name': 'github-org-jenkinsflow-test/job/jenkinsflow-gh-folder-test/job/main' # Corresponds: -# 'url': 'http://:/job/gh-org/job/jenkinsflow-gh-folder-test/job/main' +# 'url': 'http://:/job/github-org-jenkinsflow-test/job/jenkinsflow-gh-folder-test/job/main' _ONE_LEVEL_JOBS_INFO_QUERY = f"jobs[name,{_GIVEN_JOB_QUERY_WITH_PARAM_DEFS}_RECURSE_]" _TWO_LEVELS_JOBS_INFO_QUERY = _ONE_LEVEL_JOBS_INFO_QUERY.replace("_RECURSE_", "," + _ONE_LEVEL_JOBS_INFO_QUERY) _THREE_LEVELS_JOBS_INFO_QUERY = _TWO_LEVELS_JOBS_INFO_QUERY.replace("_RECURSE_", "," + _ONE_LEVEL_JOBS_INFO_QUERY) diff --git a/test/conftest.py b/test/conftest.py index 2c15aa5..13b84f2 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -96,7 +96,8 @@ def filter_items_by_api_type(item): return # We must have an ApiType in name now, since api_type fixture was used - current_item_api = ApiType[item_api_type_regex.match(item.name).groups()[0]] + api_type_name, _, _ = (item_api_type_regex.match(item.name).groups()[0]).partition("-") # TODO, this cannot be the way to get api_type + current_item_api = ApiType[api_type_name] if current_item_api not in selected_api_types: print(f"{':'.join(str(place) for place in item.location)} DESELECTED ({current_item_api} not in {selected_api_types})") deselected.append(item) diff --git a/test/github_folder_test.py b/test/github_folder_test.py deleted file mode 100644 index ddf12d5..0000000 --- a/test/github_folder_test.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2024 Lars Hupfeldt Nielsen, Hupfeldt IT -# All rights reserved. This work is under a BSD license, see LICENSE.TXT. - -from datetime import datetime - -import pytest - -from jenkinsflow.flow import serial - - -from .framework.cfg import ApiType -from .framework import api_select - - -@pytest.mark.apis(ApiType.JENKINS) -def test_gh_folder_build_branch(api_type): - with api_select.api(__file__, api_type, existing_jobs=True) as api: - api.flow_job() - api.job("gh-org/jenkinsflow-gh-folder-test/main", max_fails=0, expect_invocations=1, expect_order=1) - - with serial(api, timeout=20, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org/jenkinsflow-gh-folder-test/main") - - -@pytest.mark.apis(ApiType.JENKINS) -def test_gh_folder_build_slow_branch(api_type): - with api_select.api(__file__, api_type, existing_jobs=True) as api: - api.flow_job() - api.job("gh-org/jenkinsflow-gh-folder-test/slow", max_fails=0, expect_invocations=1, expect_order=1) - - before = datetime.now() - with serial(api, timeout=70, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org/jenkinsflow-gh-folder-test/slow") - - # The job sleeps 10s - assert (datetime.now() - before).total_seconds() >= 10 - - -@pytest.mark.apis(ApiType.JENKINS) -def test_gh_folder_build_with_parameters(api_type): - with api_select.api(__file__, api_type, existing_jobs=True) as api: - api.flow_job() - api.job("gh-org/jenkinsflow-gh-folder-test/parameters", max_fails=0, expect_invocations=1, expect_order=1) - - with serial(api, timeout=70, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org/jenkinsflow-gh-folder-test/parameters", GREETING="Hi") - - -@pytest.mark.apis(ApiType.JENKINS) -def test_gh_folder_scan_organization(api_type): - with api_select.api(__file__, api_type, existing_jobs=True) as api: - api.flow_job() - api.job("gh-org", max_fails=0, expect_invocations=1, expect_order=1) - - # Scan time depends on the GitHub organization! - with serial(api, timeout=10, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org", assume_finished_after=5) - - -@pytest.mark.apis(ApiType.JENKINS) -def test_gh_folder_scan_repo(api_type): - with api_select.api(__file__, api_type, existing_jobs=True) as api: - api.flow_job() - api.job("gh-org/jenkinsflow-gh-folder-test", max_fails=0, expect_invocations=1, expect_order=1) - - # Repo scan time depends on the GitHub repo, it does not take too long, but can be queued for a while! - with serial(api, timeout=10, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org/jenkinsflow-gh-folder-test", assume_finished_after=5) diff --git a/test/invalid_job_names_test.py b/test/invalid_job_names_test.py index 8109305..e77d6bb 100644 --- a/test/invalid_job_names_test.py +++ b/test/invalid_job_names_test.py @@ -12,9 +12,11 @@ @pytest.mark.apis(ApiType.JENKINS) -def test_invalid_job_in_gh_folder_name(api_type): +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_invalid_job_in_org_folder_name(api_type, org_name): url = "http://localhost:8080" api = JenkinsApi(url) with pytest.raises(InvalidJobNameException): with serial(api, timeout=20, report_interval=1) as ctrl1: - ctrl1.invoke("gh-org/job/jenkinsflow-gh-folder-test/job/main") + # Name must not contain '/job/' + ctrl1.invoke(f"{org_name}/job/jenkinsflow-gh-folder-test/job/main") diff --git a/test/organization_folder_test.py b/test/organization_folder_test.py new file mode 100644 index 0000000..4941b11 --- /dev/null +++ b/test/organization_folder_test.py @@ -0,0 +1,73 @@ +# Copyright (c) 2024 Lars Hupfeldt Nielsen, Hupfeldt IT +# All rights reserved. This work is under a BSD license, see LICENSE.TXT. + +from datetime import datetime + +import pytest + +from jenkinsflow.flow import serial + + +from .framework.cfg import ApiType +from .framework import api_select + + +@pytest.mark.apis(ApiType.JENKINS) +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_org_folder_build_branch(api_type, org_name): + with api_select.api(__file__, api_type, existing_jobs=True) as api: + api.flow_job() + api.job(f"{org_name}/jenkinsflow-org-job-test/main", max_fails=0, expect_invocations=1, expect_order=1) + + with serial(api, timeout=20, report_interval=1) as ctrl1: + ctrl1.invoke(f"{org_name}/jenkinsflow-org-job-test/main") + + +@pytest.mark.apis(ApiType.JENKINS) +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_org_folder_build_slow_branch(api_type, org_name): + with api_select.api(__file__, api_type, existing_jobs=True) as api: + api.flow_job() + api.job(f"{org_name}/jenkinsflow-org-job-test/slow", max_fails=0, expect_invocations=1, expect_order=1) + + before = datetime.now() + with serial(api, timeout=70, report_interval=1) as ctrl1: + ctrl1.invoke(f"{org_name}/jenkinsflow-org-job-test/slow") + + # The job sleeps 10s + assert (datetime.now() - before).total_seconds() >= 10 + + +@pytest.mark.apis(ApiType.JENKINS) +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_org_folder_build_with_parameters(api_type, org_name): + with api_select.api(__file__, api_type, existing_jobs=True) as api: + api.flow_job() + api.job(f"{org_name}/jenkinsflow-org-job-test/parameters", max_fails=0, expect_invocations=1, expect_order=1) + + with serial(api, timeout=70, report_interval=1) as ctrl1: + ctrl1.invoke(f"{org_name}/jenkinsflow-org-job-test/parameters", GREETING="Hi") + + +@pytest.mark.apis(ApiType.JENKINS) +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_org_folder_scan_organization(api_type, org_name): + with api_select.api(__file__, api_type, existing_jobs=True) as api: + api.flow_job() + api.job(f"{org_name}", max_fails=0, expect_invocations=1, expect_order=1) + + # Scan time depends on the GitHub organization! + with serial(api, timeout=10, report_interval=1) as ctrl1: + ctrl1.invoke(f"{org_name}", assume_finished_after=5) + + +@pytest.mark.apis(ApiType.JENKINS) +@pytest.mark.parametrize("org_name", ["codeberg-org-jenkinsflow-test", "github-org-jenkinsflow-test"]) +def test_org_folder_scan_repo(api_type, org_name): + with api_select.api(__file__, api_type, existing_jobs=True) as api: + api.flow_job() + api.job(f"{org_name}/jenkinsflow-org-job-test", max_fails=0, expect_invocations=1, expect_order=1) + + # Repo scan time depends on the GitHub repo, it does not take too long, but can be queued for a while! + with serial(api, timeout=10, report_interval=1) as ctrl1: + ctrl1.invoke(f"{org_name}/jenkinsflow-org-job-test", assume_finished_after=5)