diff options
Diffstat (limited to 'gitlab')
| -rw-r--r-- | gitlab/tests/objects/conftest.py | 5 | ||||
| -rw-r--r-- | gitlab/tests/objects/test_job_artifacts.py | 31 | ||||
| -rw-r--r-- | gitlab/tests/objects/test_packages.py | 119 | ||||
| -rw-r--r-- | gitlab/v4/objects.py | 69 |
4 files changed, 224 insertions, 0 deletions
diff --git a/gitlab/tests/objects/conftest.py b/gitlab/tests/objects/conftest.py index 76f76d1..d8a40d9 100644 --- a/gitlab/tests/objects/conftest.py +++ b/gitlab/tests/objects/conftest.py @@ -22,6 +22,11 @@ def created_content(): @pytest.fixture +def no_content(): + return {"message": "204 No Content"} + + +@pytest.fixture def resp_export(accepted_content, binary_content): """Common fixture for group and project exports.""" export_status_content = { diff --git a/gitlab/tests/objects/test_job_artifacts.py b/gitlab/tests/objects/test_job_artifacts.py new file mode 100644 index 0000000..c441b4b --- /dev/null +++ b/gitlab/tests/objects/test_job_artifacts.py @@ -0,0 +1,31 @@ +""" +GitLab API: https://docs.gitlab.com/ee/api/job_artifacts.html +""" + +import pytest +import responses + + +ref_name = "master" +job = "build" + + +@pytest.fixture +def resp_artifacts_by_ref_name(binary_content): + url = f"http://localhost/api/v4/projects/1/jobs/artifacts/{ref_name}/download?job={job}" + + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url=url, + body=binary_content, + content_type="application/octet-stream", + status=200, + ) + yield rsps + + +def test_download_artifacts_by_ref_name(gl, binary_content, resp_artifacts_by_ref_name): + project = gl.projects.get(1, lazy=True) + artifacts = project.artifacts(ref_name=ref_name, job=job) + assert artifacts == binary_content diff --git a/gitlab/tests/objects/test_packages.py b/gitlab/tests/objects/test_packages.py new file mode 100644 index 0000000..d4d97ff --- /dev/null +++ b/gitlab/tests/objects/test_packages.py @@ -0,0 +1,119 @@ +""" +GitLab API: https://docs.gitlab.com/ce/api/packages.html +""" +import re + +import pytest +import responses + +from gitlab.v4.objects import GroupPackage, ProjectPackage + + +package_content = { + "id": 1, + "name": "com/mycompany/my-app", + "version": "1.0-SNAPSHOT", + "package_type": "maven", + "_links": { + "web_path": "/namespace1/project1/-/packages/1", + "delete_api_path": "/namespace1/project1/-/packages/1", + }, + "created_at": "2019-11-27T03:37:38.711Z", + "pipeline": { + "id": 123, + "status": "pending", + "ref": "new-pipeline", + "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", + "web_url": "https://example.com/foo/bar/pipelines/47", + "created_at": "2016-08-11T11:28:34.085Z", + "updated_at": "2016-08-11T11:32:35.169Z", + "user": { + "name": "Administrator", + "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + }, + }, + "versions": [ + { + "id": 2, + "version": "2.0-SNAPSHOT", + "created_at": "2020-04-28T04:42:11.573Z", + "pipeline": { + "id": 234, + "status": "pending", + "ref": "new-pipeline", + "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a", + "web_url": "https://example.com/foo/bar/pipelines/58", + "created_at": "2016-08-11T11:28:34.085Z", + "updated_at": "2016-08-11T11:32:35.169Z", + "user": { + "name": "Administrator", + "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + }, + }, + } + ], +} + + +@pytest.fixture +def resp_list_packages(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url=re.compile(r"http://localhost/api/v4/(groups|projects)/1/packages"), + json=[package_content], + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_get_package(): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/packages/1", + json=package_content, + content_type="application/json", + status=200, + ) + yield rsps + + +@pytest.fixture +def resp_delete_package(no_content): + with responses.RequestsMock() as rsps: + rsps.add( + method=responses.DELETE, + url="http://localhost/api/v4/projects/1/packages/1", + json=no_content, + content_type="application/json", + status=204, + ) + yield rsps + + +def test_list_project_packages(project, resp_list_packages): + packages = project.packages.list() + assert isinstance(packages, list) + assert isinstance(packages[0], ProjectPackage) + assert packages[0].version == "1.0-SNAPSHOT" + + +def test_list_group_packages(group, resp_list_packages): + packages = group.packages.list() + assert isinstance(packages, list) + assert isinstance(packages[0], GroupPackage) + assert packages[0].version == "1.0-SNAPSHOT" + + +def test_get_project_package(project, resp_get_package): + package = project.packages.get(1) + assert isinstance(package, ProjectPackage) + assert package.version == "1.0-SNAPSHOT" + + +def test_delete_project_package(project, resp_delete_package): + package = project.packages.get(1, lazy=True) + package.delete() diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py index e515ea1..e7d7d23 100644 --- a/gitlab/v4/objects.py +++ b/gitlab/v4/objects.py @@ -1291,6 +1291,23 @@ class GroupNotificationSettingsManager(NotificationSettingsManager): _from_parent_attrs = {"group_id": "id"} +class GroupPackage(RESTObject): + pass + + +class GroupPackageManager(ListMixin, RESTManager): + _path = "/groups/%(group_id)s/packages" + _obj_cls = GroupPackage + _from_parent_attrs = {"group_id": "id"} + _list_filters = ( + "exclude_subgroups", + "order_by", + "sort", + "package_type", + "package_name", + ) + + class GroupProject(RESTObject): pass @@ -1377,6 +1394,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject): ("mergerequests", "GroupMergeRequestManager"), ("milestones", "GroupMilestoneManager"), ("notificationsettings", "GroupNotificationSettingsManager"), + ("packages", "GroupPackageManager"), ("projects", "GroupProjectManager"), ("runners", "GroupRunnerManager"), ("subgroups", "GroupSubgroupManager"), @@ -2863,6 +2881,22 @@ class ProjectNotificationSettingsManager(NotificationSettingsManager): _from_parent_attrs = {"project_id": "id"} +class ProjectPackage(ObjectDeleteMixin, RESTObject): + pass + + +class ProjectPackageManager(ListMixin, GetMixin, DeleteMixin, RESTManager): + _path = "/projects/%(project_id)s/packages" + _obj_cls = ProjectPackage + _from_parent_attrs = {"project_id": "id"} + _list_filters = ( + "order_by", + "sort", + "package_type", + "package_name", + ) + + class ProjectPagesDomain(SaveMixin, ObjectDeleteMixin, RESTObject): _id_attr = "domain" @@ -4572,6 +4606,7 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject): ("milestones", "ProjectMilestoneManager"), ("notes", "ProjectNoteManager"), ("notificationsettings", "ProjectNotificationSettingsManager"), + ("packages", "ProjectPackageManager"), ("pagesdomains", "ProjectPagesDomainManager"), ("pipelines", "ProjectPipelineManager"), ("protectedbranches", "ProjectProtectedBranchManager"), @@ -5111,6 +5146,40 @@ class Project(SaveMixin, ObjectDeleteMixin, RESTObject): path, post_data={"namespace": to_namespace}, **kwargs ) + @cli.register_custom_action("Project", ("ref_name", "job"), ("job_token",)) + @exc.on_http_error(exc.GitlabGetError) + def artifacts( + self, ref_name, job, streamed=False, action=None, chunk_size=1024, **kwargs + ): + """Get the job artifacts archive from a specific tag or branch. + + Args: + ref_name (str): Branch or tag name in repository. HEAD or SHA references + are not supported. + artifact_path (str): Path to a file inside the artifacts archive. + job (str): The name of the job. + job_token (str): Job token for multi-project pipeline triggers. + streamed (bool): If True the data will be processed by chunks of + `chunk_size` and each chunk is passed to `action` for + treatment + action (callable): Callable responsible of dealing with chunk of + data + chunk_size (int): Size of each chunk + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabGetError: If the artifacts could not be retrieved + + Returns: + str: The artifacts if `streamed` is False, None otherwise. + """ + path = "/projects/%s/jobs/artifacts/%s/download" % (self.get_id(), ref_name) + result = self.manager.gitlab.http_get( + path, job=job, streamed=streamed, raw=True, **kwargs + ) + return utils.response_content(result, streamed, action, chunk_size) + @cli.register_custom_action("Project", ("ref_name", "artifact_path", "job")) @exc.on_http_error(exc.GitlabGetError) def artifact( |
