From 07b99881dfa6efa9665245647460e99846ccd341 Mon Sep 17 00:00:00 2001 From: Christopher Zorn Date: Wed, 8 Apr 2020 17:02:29 -0700 Subject: feat: add play command to project pipeline schedules fix: remove version from setup feat: add pipeline schedule play error exception docs: add documentation for pipeline schedule play --- docs/gl_objects/pipelines_and_jobs.rst | 5 +++++ gitlab/exceptions.py | 4 ++++ gitlab/v4/objects.py | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/docs/gl_objects/pipelines_and_jobs.rst b/docs/gl_objects/pipelines_and_jobs.rst index 30b45f2..c79d19f 100644 --- a/docs/gl_objects/pipelines_and_jobs.rst +++ b/docs/gl_objects/pipelines_and_jobs.rst @@ -155,6 +155,11 @@ Update a schedule:: sched.cron = '1 2 * * *' sched.save() +Trigger a pipeline schedule immediately:: + + sched = projects.pipelineschedules.get(schedule_id) + sched.play() + Delete a schedule:: sched.delete() diff --git a/gitlab/exceptions.py b/gitlab/exceptions.py index f95e686..fd2ff2a 100644 --- a/gitlab/exceptions.py +++ b/gitlab/exceptions.py @@ -145,6 +145,10 @@ class GitlabJobEraseError(GitlabRetryError): pass +class GitlabPipelinePlayError(GitlabRetryError): + pass + + class GitlabPipelineRetryError(GitlabRetryError): pass diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py index 756ec4f..f6c09d9 100644 --- a/gitlab/v4/objects.py +++ b/gitlab/v4/objects.py @@ -3775,6 +3775,24 @@ class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject): server_data = self.manager.gitlab.http_post(path, **kwargs) self._update_attrs(server_data) + @cli.register_custom_action("ProjectPipelineSchedule") + @exc.on_http_error(exc.GitlabPipelinePlayError) + def play(self, **kwargs): + """Trigger a new scheduled pipeline, which runs immediately. + The next scheduled run of this pipeline is not affected. + + Args: + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabPipelinePlayError: If the request failed + """ + path = "%s/%s/play" % (self.manager.path, self.get_id()) + server_data = self.manager.gitlab.http_post(path, **kwargs) + self._update_attrs(server_data) + return server_data + class ProjectPipelineScheduleManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/pipeline_schedules" -- cgit v1.2.1 From 9f04560e59f372f80ac199aeee16378d8f80610c Mon Sep 17 00:00:00 2001 From: Christopher Zorn Date: Tue, 21 Apr 2020 09:14:13 -0700 Subject: ci: add a test for creating and triggering pipeline schedule --- gitlab/tests/objects/test_projects.py | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py index 6a2840a..9f74bdb 100644 --- a/gitlab/tests/objects/test_projects.py +++ b/gitlab/tests/objects/test_projects.py @@ -257,6 +257,45 @@ def resp_get_active_services(url, request): return response(200, content, headers, None, 5, request) +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/1/pipeline_schedules$", method="post", +) +def resp_create_project_pipeline_schedule(url, request): + """Mock for creating project pipeline Schedules POST response.""" + content = """{ + "id": 14, + "description": "Build packages", + "ref": "master", + "cron": "0 1 * * 5", + "cron_timezone": "UTC", + "next_run_at": "2017-05-26T01:00:00.000Z", + "active": true, + "created_at": "2017-05-19T13:43:08.169Z", + "updated_at": "2017-05-19T13:43:08.169Z", + "last_pipeline": null, + "owner": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "https://gitlab.example.com/root" + } +}""" + content = content.encode("utf-8") + return response(200, content, headers, None, 5, request) + + +@urlmatch( + scheme="http", netloc="localhost", path="/api/v4/projects/1/pipeline_schedules/14/play", method="post", +) +def resp_play_project_pipeline_schedule(url, request): + """Mock for playing a project pipeline schedule POST response.""" + content = """{"message": "201 Created"}""" + content = content.encode("utf-8") + return response(200, content, headers, None, 5, request) + + class TestProject(unittest.TestCase): """Base class for GitLab Project tests.""" @@ -480,3 +519,25 @@ class TestProjectServices(TestProject): service.issues_events = True service.save() self.assertEqual(service.issues_events, True) + + +class TestProjectPipelineSchedule(TestProject): + + @with_httmock(resp_create_project_pipeline_schedule, + resp_play_project_pipeline_schedule) + def test_project_pipeline_schedule_play(self): + description = 'Build packages' + cronline = '0 1 * * 5' + sched = self.project.pipelineschedules.create({ + 'ref': 'master', + 'description': description, + 'cron': cronline}) + self.assertIsNotNone(sched) + self.assertEqual(description, sched.description) + self.assertEqual(cronline, sched.cron) + + play_result = sched.play() + self.assertIsNotNone(play_result) + self.assertIn('message', play_result) + self.assertEqual('201 Created', play_result['message']) + -- cgit v1.2.1 From 930122b1848b3d42af1cf8567a065829ec0eb44f Mon Sep 17 00:00:00 2001 From: Christopher Zorn Date: Tue, 21 Apr 2020 16:00:40 -0700 Subject: ci: lint fixes --- gitlab/tests/objects/test_projects.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/gitlab/tests/objects/test_projects.py b/gitlab/tests/objects/test_projects.py index 9f74bdb..ca7e0c8 100644 --- a/gitlab/tests/objects/test_projects.py +++ b/gitlab/tests/objects/test_projects.py @@ -258,7 +258,10 @@ def resp_get_active_services(url, request): @urlmatch( - scheme="http", netloc="localhost", path="/api/v4/projects/1/pipeline_schedules$", method="post", + scheme="http", + netloc="localhost", + path="/api/v4/projects/1/pipeline_schedules$", + method="post", ) def resp_create_project_pipeline_schedule(url, request): """Mock for creating project pipeline Schedules POST response.""" @@ -287,7 +290,10 @@ def resp_create_project_pipeline_schedule(url, request): @urlmatch( - scheme="http", netloc="localhost", path="/api/v4/projects/1/pipeline_schedules/14/play", method="post", + scheme="http", + netloc="localhost", + path="/api/v4/projects/1/pipeline_schedules/14/play", + method="post", ) def resp_play_project_pipeline_schedule(url, request): """Mock for playing a project pipeline schedule POST response.""" @@ -522,22 +528,20 @@ class TestProjectServices(TestProject): class TestProjectPipelineSchedule(TestProject): - - @with_httmock(resp_create_project_pipeline_schedule, - resp_play_project_pipeline_schedule) + @with_httmock( + resp_create_project_pipeline_schedule, resp_play_project_pipeline_schedule + ) def test_project_pipeline_schedule_play(self): - description = 'Build packages' - cronline = '0 1 * * 5' - sched = self.project.pipelineschedules.create({ - 'ref': 'master', - 'description': description, - 'cron': cronline}) + description = "Build packages" + cronline = "0 1 * * 5" + sched = self.project.pipelineschedules.create( + {"ref": "master", "description": description, "cron": cronline} + ) self.assertIsNotNone(sched) self.assertEqual(description, sched.description) self.assertEqual(cronline, sched.cron) play_result = sched.play() self.assertIsNotNone(play_result) - self.assertIn('message', play_result) - self.assertEqual('201 Created', play_result['message']) - + self.assertIn("message", play_result) + self.assertEqual("201 Created", play_result["message"]) -- cgit v1.2.1