Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/gl_objects/pipelines_and_jobs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions gitlab/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ class GitlabJobEraseError(GitlabRetryError):
pass


class GitlabPipelinePlayError(GitlabRetryError):
pass


class GitlabPipelineRetryError(GitlabRetryError):
pass

Expand Down
65 changes: 65 additions & 0 deletions gitlab/tests/objects/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,51 @@ 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."""

Expand Down Expand Up @@ -480,3 +525,23 @@ def test_update_service(self):
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"])
18 changes: 18 additions & 0 deletions gitlab/v4/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -3775,6 +3775,24 @@ def take_ownership(self, **kwargs):
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"
Expand Down