| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,6 +71,14 @@ Register a new runner:: | |||
| 71 | 71 | ||
| 72 | 72 | runner = gl.runners.create({'token': secret_token}) | |
| 73 | 73 | ||
| 74 | + .. note:: | ||
| 75 | + | ||
| 76 | + A new runner registration workflow has been introduced since GitLab 16.0. This new | ||
| 77 | + workflow comes with a new API endpoint to create runners, which does not use | ||
| 78 | + registration tokens. | ||
| 79 | + | ||
| 80 | + The new endpoint can be called using ``gl.user.runners.create() after authenticating with `gl.auth()```. | ||
| 81 | + | ||
| 74 | 82 | Update a runner:: | |
| 75 | 83 | ||
| 76 | 84 | runner = gl.runners.get(runner_id) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -456,3 +456,60 @@ Get the users activities:: | |||
| 456 | 456 | query_parameters={'from': '2018-07-01'}, | |
| 457 | 457 | get_all=True, | |
| 458 | 458 | ) | |
| 459 | + | ||
| 460 | + Create new runner | ||
| 461 | + ================= | ||
| 462 | + | ||
| 463 | + References | ||
| 464 | + ---------- | ||
| 465 | + | ||
| 466 | + * New runner registration API endpoint (see `Migrating to the new runner registration workflow <https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html#creating-runners-programmatically>`_) | ||
| 467 | + | ||
| 468 | + * v4 API: | ||
| 469 | + | ||
| 470 | + + :class:`gitlab.v4.objects.CurrentUserRunner` | ||
| 471 | + + :class:`gitlab.v4.objects.CurrentUserRunnerManager` | ||
| 472 | + + :attr:`gitlab.Gitlab.user.runners` | ||
| 473 | + | ||
| 474 | + * GitLab API : https://docs.gitlab.com/ee/api/users.html#create-a-runner | ||
| 475 | + | ||
| 476 | + Examples | ||
| 477 | + -------- | ||
| 478 | + | ||
| 479 | + Create an instance-wide runner:: | ||
| 480 | + | ||
| 481 | + runner = gl.user.runners.create({ | ||
| 482 | + "runner_type": "instance_type", | ||
| 483 | + "description": "My brand new runner", | ||
| 484 | + "paused": True, | ||
| 485 | + "locked": False, | ||
| 486 | + "run_untagged": True | ||
| 487 | + "tag_list": ["linux", "docker", "testing"], | ||
| 488 | + "access_level": "not_protected" | ||
| 489 | + }) | ||
| 490 | + | ||
| 491 | + Create a group runner:: | ||
| 492 | + | ||
| 493 | + runner = gl.user.runners.create({ | ||
| 494 | + "runner_type": "group_type", | ||
| 495 | + "group_id": 12345678, | ||
| 496 | + "description": "My brand new runner", | ||
| 497 | + "paused": True, | ||
| 498 | + "locked": False, | ||
| 499 | + "run_untagged": True | ||
| 500 | + "tag_list": ["linux", "docker", "testing"], | ||
| 501 | + "access_level": "not_protected" | ||
| 502 | + }) | ||
| 503 | + | ||
| 504 | + Create a project runner:: | ||
| 505 | + | ||
| 506 | + runner = gl.user.runners.create({ | ||
| 507 | + "runner_type": "project_type", | ||
| 508 | + "project_id": 987564321, | ||
| 509 | + "description": "My brand new runner", | ||
| 510 | + "paused": True, | ||
| 511 | + "locked": False, | ||
| 512 | + "run_untagged": True | ||
| 513 | + "tag_list": ["linux", "docker", "testing"], | ||
| 514 | + "access_level": "not_protected" | ||
| 515 | + }) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,6 +36,8 @@ | |||
| 36 | 36 | "CurrentUserGPGKeyManager", | |
| 37 | 37 | "CurrentUserKey", | |
| 38 | 38 | "CurrentUserKeyManager", | |
| 39 | + "CurrentUserRunner", | ||
| 40 | + "CurrentUserRunnerManager", | ||
| 39 | 41 | "CurrentUserStatus", | |
| 40 | 42 | "CurrentUserStatusManager", | |
| 41 | 43 | "CurrentUser", | |
@@ -111,6 +113,31 @@ def get( | |||
| 111 | 113 | return cast(CurrentUserKey, super().get(id=id, lazy=lazy, **kwargs)) | |
| 112 | 114 | ||
| 113 | 115 | ||
| 116 | + class CurrentUserRunner(RESTObject): | ||
| 117 | + pass | ||
| 118 | + | ||
| 119 | + | ||
| 120 | + class CurrentUserRunnerManager(CreateMixin, RESTManager): | ||
| 121 | + _path = "/user/runners" | ||
| 122 | + _obj_cls = CurrentUserRunner | ||
| 123 | + _types = {"tag_list": types.CommaSeparatedListAttribute} | ||
| 124 | + _create_attrs = RequiredOptional( | ||
| 125 | + required=("runner_type",), | ||
| 126 | + optional=( | ||
| 127 | + "group_id", | ||
| 128 | + "project_id", | ||
| 129 | + "description", | ||
| 130 | + "paused", | ||
| 131 | + "locked", | ||
| 132 | + "run_untagged", | ||
| 133 | + "tag_list", | ||
| 134 | + "access_level", | ||
| 135 | + "maximum_timeout", | ||
| 136 | + "maintenance_note", | ||
| 137 | + ), | ||
| 138 | + ) | ||
| 139 | + | ||
| 140 | + | ||
| 114 | 141 | class CurrentUserStatus(SaveMixin, RESTObject): | |
| 115 | 142 | _id_attr = None | |
| 116 | 143 | _repr_attr = "message" | |
@@ -132,6 +159,7 @@ class CurrentUser(RESTObject): | |||
| 132 | 159 | emails: CurrentUserEmailManager | |
| 133 | 160 | gpgkeys: CurrentUserGPGKeyManager | |
| 134 | 161 | keys: CurrentUserKeyManager | |
| 162 | + runners: CurrentUserRunnerManager | ||
| 135 | 163 | status: CurrentUserStatusManager | |
| 136 | 164 | ||
| 137 | 165 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,5 @@ | |||
| 1 | 1 | import pytest | |
| 2 | + import responses | ||
| 2 | 3 | ||
| 3 | 4 | import gitlab | |
| 4 | 5 | from tests.unit import helpers | |
@@ -59,6 +60,23 @@ def gl_retry(): | |||
| 59 | 60 | ) | |
| 60 | 61 | ||
| 61 | 62 | ||
| 63 | + @pytest.fixture | ||
| 64 | + def resp_get_current_user(): | ||
| 65 | + with responses.RequestsMock() as rsps: | ||
| 66 | + rsps.add( | ||
| 67 | + method=responses.GET, | ||
| 68 | + url="http://localhost/api/v4/user", | ||
| 69 | + json={ | ||
| 70 | + "id": 1, | ||
| 71 | + "username": "username", | ||
| 72 | + "web_url": "http://localhost/username", | ||
| 73 | + }, | ||
| 74 | + content_type="application/json", | ||
| 75 | + status=200, | ||
| 76 | + ) | ||
| 77 | + yield rsps | ||
| 78 | + | ||
| 79 | + | ||
| 62 | 80 | # Todo: parametrize, but check what tests it's really useful for | |
| 63 | 81 | @pytest.fixture | |
| 64 | 82 | def gl_trailing(): | |
@@ -129,6 +147,12 @@ def user(gl): | |||
| 129 | 147 | return gl.users.get(1, lazy=True) | |
| 130 | 148 | ||
| 131 | 149 | ||
| 150 | + @pytest.fixture | ||
| 151 | + def current_user(gl, resp_get_current_user): | ||
| 152 | + gl.auth() | ||
| 153 | + return gl.user | ||
| 154 | + | ||
| 155 | + | ||
| 132 | 156 | @pytest.fixture | |
| 133 | 157 | def migration(gl): | |
| 134 | 158 | return gl.bulk_imports.get(1, lazy=True) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -241,6 +241,19 @@ def resp_starred_projects(): | |||
| 241 | 241 | yield rsps | |
| 242 | 242 | ||
| 243 | 243 | ||
| 244 | + @pytest.fixture | ||
| 245 | + def resp_runner_create(): | ||
| 246 | + with responses.RequestsMock() as rsps: | ||
| 247 | + rsps.add( | ||
| 248 | + method=responses.POST, | ||
| 249 | + url="http://localhost/api/v4/user/runners", | ||
| 250 | + json={"id": "6", "token": "6337ff461c94fd3fa32ba3b1ff4125"}, | ||
| 251 | + content_type="application/json", | ||
| 252 | + status=201, | ||
| 253 | + ) | ||
| 254 | + yield rsps | ||
| 255 | + | ||
| 256 | + | ||
| 244 | 257 | def test_get_user(gl, resp_get_user): | |
| 245 | 258 | user = gl.users.get(1) | |
| 246 | 259 | assert isinstance(user, User) | |
@@ -304,3 +317,9 @@ def test_list_starred_projects(user, resp_starred_projects): | |||
| 304 | 317 | projects = user.starred_projects.list() | |
| 305 | 318 | assert isinstance(projects[0], StarredProject) | |
| 306 | 319 | assert projects[0].id == project_content["id"] | |
| 320 | + | ||
| 321 | + | ||
| 322 | + def test_create_user_runner(current_user, resp_runner_create): | ||
| 323 | + runner = current_user.runners.create({"runner_type": "instance_type"}) | ||
| 324 | + assert runner.id == "6" | ||
| 325 | + assert runner.token == "6337ff461c94fd3fa32ba3b1ff4125" | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments