Skip to content

feat: Add play command to project pipeline schedules #1069

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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