Skip to content

Commit 9d66cb3

Browse files
authored
Merge pull request #1069 from zillow/feat/add-custom-pipeline-schedule-play
feat: Add play command to project pipeline schedules
2 parents 7907e5a + 930122b commit 9d66cb3

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

docs/gl_objects/pipelines_and_jobs.rst

+5
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ Update a schedule::
155155
sched.cron = '1 2 * * *'
156156
sched.save()
157157

158+
Trigger a pipeline schedule immediately::
159+
160+
sched = projects.pipelineschedules.get(schedule_id)
161+
sched.play()
162+
158163
Delete a schedule::
159164

160165
sched.delete()

gitlab/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class GitlabJobEraseError(GitlabRetryError):
145145
pass
146146

147147

148+
class GitlabPipelinePlayError(GitlabRetryError):
149+
pass
150+
151+
148152
class GitlabPipelineRetryError(GitlabRetryError):
149153
pass
150154

gitlab/tests/objects/test_projects.py

+65
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,51 @@ def resp_get_active_services(url, request):
257257
return response(200, content, headers, None, 5, request)
258258

259259

260+
@urlmatch(
261+
scheme="http",
262+
netloc="localhost",
263+
path="/api/v4/projects/1/pipeline_schedules$",
264+
method="post",
265+
)
266+
def resp_create_project_pipeline_schedule(url, request):
267+
"""Mock for creating project pipeline Schedules POST response."""
268+
content = """{
269+
"id": 14,
270+
"description": "Build packages",
271+
"ref": "master",
272+
"cron": "0 1 * * 5",
273+
"cron_timezone": "UTC",
274+
"next_run_at": "2017-05-26T01:00:00.000Z",
275+
"active": true,
276+
"created_at": "2017-05-19T13:43:08.169Z",
277+
"updated_at": "2017-05-19T13:43:08.169Z",
278+
"last_pipeline": null,
279+
"owner": {
280+
"name": "Administrator",
281+
"username": "root",
282+
"id": 1,
283+
"state": "active",
284+
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
285+
"web_url": "https://gitlab.example.com/root"
286+
}
287+
}"""
288+
content = content.encode("utf-8")
289+
return response(200, content, headers, None, 5, request)
290+
291+
292+
@urlmatch(
293+
scheme="http",
294+
netloc="localhost",
295+
path="/api/v4/projects/1/pipeline_schedules/14/play",
296+
method="post",
297+
)
298+
def resp_play_project_pipeline_schedule(url, request):
299+
"""Mock for playing a project pipeline schedule POST response."""
300+
content = """{"message": "201 Created"}"""
301+
content = content.encode("utf-8")
302+
return response(200, content, headers, None, 5, request)
303+
304+
260305
class TestProject(unittest.TestCase):
261306
"""Base class for GitLab Project tests."""
262307

@@ -480,3 +525,23 @@ def test_update_service(self):
480525
service.issues_events = True
481526
service.save()
482527
self.assertEqual(service.issues_events, True)
528+
529+
530+
class TestProjectPipelineSchedule(TestProject):
531+
@with_httmock(
532+
resp_create_project_pipeline_schedule, resp_play_project_pipeline_schedule
533+
)
534+
def test_project_pipeline_schedule_play(self):
535+
description = "Build packages"
536+
cronline = "0 1 * * 5"
537+
sched = self.project.pipelineschedules.create(
538+
{"ref": "master", "description": description, "cron": cronline}
539+
)
540+
self.assertIsNotNone(sched)
541+
self.assertEqual(description, sched.description)
542+
self.assertEqual(cronline, sched.cron)
543+
544+
play_result = sched.play()
545+
self.assertIsNotNone(play_result)
546+
self.assertIn("message", play_result)
547+
self.assertEqual("201 Created", play_result["message"])

gitlab/v4/objects.py

+18
Original file line numberDiff line numberDiff line change
@@ -3775,6 +3775,24 @@ def take_ownership(self, **kwargs):
37753775
server_data = self.manager.gitlab.http_post(path, **kwargs)
37763776
self._update_attrs(server_data)
37773777

3778+
@cli.register_custom_action("ProjectPipelineSchedule")
3779+
@exc.on_http_error(exc.GitlabPipelinePlayError)
3780+
def play(self, **kwargs):
3781+
"""Trigger a new scheduled pipeline, which runs immediately.
3782+
The next scheduled run of this pipeline is not affected.
3783+
3784+
Args:
3785+
**kwargs: Extra options to send to the server (e.g. sudo)
3786+
3787+
Raises:
3788+
GitlabAuthenticationError: If authentication is not correct
3789+
GitlabPipelinePlayError: If the request failed
3790+
"""
3791+
path = "%s/%s/play" % (self.manager.path, self.get_id())
3792+
server_data = self.manager.gitlab.http_post(path, **kwargs)
3793+
self._update_attrs(server_data)
3794+
return server_data
3795+
37783796

37793797
class ProjectPipelineScheduleManager(CRUDMixin, RESTManager):
37803798
_path = "/projects/%(project_id)s/pipeline_schedules"

0 commit comments

Comments
 (0)