0
# CI/CD Management
1
2
Continuous integration and deployment pipeline control, job management, runner administration, and artifact handling. Comprehensive coverage of GitLab's CI/CD system including pipelines, jobs, runners, variables, and deployment workflows.
3
4
## Capabilities
5
6
### Pipeline Management
7
8
```python { .api }
9
class ProjectPipeline(RefreshMixin, ObjectDeleteMixin, RESTObject):
10
"""
11
CI/CD pipeline object with comprehensive lifecycle management.
12
13
Key Attributes:
14
- id: Pipeline ID
15
- iid: Internal pipeline ID
16
- status: Pipeline status ("created", "waiting_for_resource", "preparing", "pending", "running", "success", "failed", "canceled", "skipped", "manual", "scheduled")
17
- source: Pipeline trigger source ("push", "web", "trigger", "schedule", "api", "external", "pipeline", "chat", "webide", "merge_request_event", "external_pull_request_event", "parent_pipeline", "ondemand_dast_scan", "ondemand_dast_validation")
18
- ref: Git reference (branch/tag)
19
- sha: Commit SHA
20
- before_sha: Previous commit SHA
21
- tag: Tag flag
22
- yaml_errors: YAML validation errors
23
- user: User who triggered pipeline
24
- created_at: Creation timestamp
25
- updated_at: Update timestamp
26
- started_at: Start timestamp
27
- finished_at: Completion timestamp
28
- committed_at: Commit timestamp
29
- duration: Pipeline duration in seconds
30
- queued_duration: Queue duration in seconds
31
- coverage: Code coverage percentage
32
- web_url: Pipeline web URL
33
"""
34
35
def cancel(self) -> dict:
36
"""
37
Cancel the pipeline.
38
39
Returns:
40
Dictionary with cancellation result
41
42
Raises:
43
GitlabPipelineCancelError: If cancellation fails
44
"""
45
46
def retry(self) -> dict:
47
"""
48
Retry the pipeline.
49
50
Returns:
51
Dictionary with retry result
52
53
Raises:
54
GitlabPipelineRetryError: If retry fails
55
"""
56
57
def play(self, job_variables: dict | None = None) -> dict:
58
"""
59
Play/trigger manual pipeline.
60
61
Parameters:
62
- job_variables: Variables to pass to jobs
63
64
Returns:
65
Dictionary with play result
66
67
Raises:
68
GitlabPipelinePlayError: If play fails
69
"""
70
71
def delete(self) -> None:
72
"""Delete pipeline and its jobs."""
73
74
class ProjectPipelineManager(CRUDMixin[ProjectPipeline]):
75
"""Manager for project pipelines."""
76
77
def list(
78
self,
79
scope: str | None = None,
80
status: str | None = None,
81
ref: str | None = None,
82
sha: str | None = None,
83
yaml_errors: bool | None = None,
84
name: str | None = None,
85
username: str | None = None,
86
updated_after: str | None = None,
87
updated_before: str | None = None,
88
order_by: str | None = None,
89
sort: str | None = None,
90
source: str | None = None,
91
**kwargs
92
) -> list[ProjectPipeline]:
93
"""List project pipelines with filtering."""
94
95
def create(self, data: dict, **kwargs) -> ProjectPipeline:
96
"""
97
Create new pipeline.
98
99
Required fields:
100
- ref: Git reference (branch/tag/commit)
101
102
Optional fields:
103
- variables: List of pipeline variables
104
"""
105
```
106
107
### Job Management
108
109
```python { .api }
110
class ProjectJob(RefreshMixin, RESTObject):
111
"""
112
CI/CD job object with execution control.
113
114
Key Attributes:
115
- id: Job ID
116
- name: Job name
117
- stage: Pipeline stage
118
- status: Job status ("created", "pending", "running", "success", "failed", "canceled", "skipped", "manual")
119
- created_at: Creation timestamp
120
- started_at: Start timestamp
121
- finished_at: Completion timestamp
122
- duration: Job duration in seconds
123
- queued_duration: Queue duration in seconds
124
- user: User information
125
- commit: Commit information
126
- pipeline: Pipeline information
127
- web_url: Job web URL
128
- artifacts: Artifacts information
129
- artifacts_file: Artifacts file information
130
- artifacts_expire_at: Artifacts expiration
131
- tag_list: Runner tags
132
- runner: Runner information
133
- coverage: Code coverage percentage
134
- allow_failure: Allow failure flag
135
- failure_reason: Failure reason
136
- erased_at: Erasure timestamp
137
- erased_by: User who erased job
138
"""
139
140
def cancel(self) -> dict:
141
"""
142
Cancel the job.
143
144
Returns:
145
Dictionary with cancellation result
146
147
Raises:
148
GitlabJobCancelError: If cancellation fails
149
"""
150
151
def retry(self) -> dict:
152
"""
153
Retry the job.
154
155
Returns:
156
Dictionary with retry result
157
158
Raises:
159
GitlabJobRetryError: If retry fails
160
"""
161
162
def play(self, job_variables_attributes: list[dict] | None = None) -> dict:
163
"""
164
Play/trigger manual job.
165
166
Parameters:
167
- job_variables_attributes: List of job variables
168
169
Returns:
170
Dictionary with play result
171
172
Raises:
173
GitlabJobPlayError: If play fails
174
"""
175
176
def erase(self) -> dict:
177
"""
178
Erase job artifacts and trace.
179
180
Returns:
181
Dictionary with erase result
182
183
Raises:
184
GitlabJobEraseError: If erasure fails
185
"""
186
187
def keep_artifacts(self) -> dict:
188
"""Keep job artifacts (prevent expiration)."""
189
190
def delete_artifacts(self) -> dict:
191
"""Delete job artifacts."""
192
193
def trace(self) -> bytes:
194
"""Get job execution trace/log."""
195
196
class ProjectJobManager(RetrieveMixin[ProjectJob], ListMixin[ProjectJob]):
197
"""Manager for project jobs."""
198
199
def list(
200
self,
201
scope: str | None = None,
202
include_retried: bool | None = None,
203
**kwargs
204
) -> list[ProjectJob]:
205
"""
206
List project jobs.
207
208
Parameters:
209
- scope: Job scope ("created", "pending", "running", "failed", "success", "canceled", "skipped", "manual")
210
- include_retried: Include retried jobs
211
"""
212
```
213
214
### Runner Management
215
216
```python { .api }
217
class Runner(SaveMixin, ObjectDeleteMixin, RESTObject):
218
"""
219
GitLab runner object with configuration management.
220
221
Key Attributes:
222
- id: Runner ID
223
- description: Runner description
224
- active: Active status
225
- paused: Paused status
226
- is_shared: Shared runner flag
227
- runner_type: Runner type ("instance_type", "group_type", "project_type")
228
- name: Runner name
229
- online: Online status
230
- status: Runner status
231
- ip_address: Runner IP address
232
- tag_list: Runner tags
233
- version: Runner version
234
- revision: Runner revision
235
- platform: Runner platform
236
- architecture: Runner architecture
237
- contacted_at: Last contact timestamp
238
- token: Registration token (masked)
239
- locked: Locked to project flag
240
- access_level: Access level
241
- maximum_timeout: Maximum job timeout
242
- groups: Associated groups
243
- projects: Associated projects
244
"""
245
246
def save(self) -> None:
247
"""Save runner configuration changes."""
248
249
def delete(self) -> None:
250
"""Delete runner permanently."""
251
252
class RunnerManager(CRUDMixin[Runner]):
253
"""Manager for GitLab runners."""
254
255
def list(
256
self,
257
scope: str | None = None,
258
type: str | None = None,
259
status: str | None = None,
260
paused: bool | None = None,
261
tag_list: list[str] | None = None,
262
**kwargs
263
) -> list[Runner]:
264
"""
265
List runners with filtering.
266
267
Parameters:
268
- scope: Runner scope ("active", "paused", "online", "offline")
269
- type: Runner type ("instance_type", "group_type", "project_type")
270
- status: Runner status ("online", "offline", "stale", "never_contacted")
271
- paused: Filter by paused status
272
- tag_list: Filter by runner tags
273
"""
274
275
class ProjectRunner(RESTObject):
276
"""Project-specific runner information."""
277
278
class ProjectRunnerManager(ListMixin[ProjectRunner], CreateMixin[ProjectRunner], DeleteMixin[ProjectRunner]):
279
"""Manager for project runners."""
280
281
def create(self, data: dict, **kwargs) -> ProjectRunner:
282
"""
283
Enable runner for project.
284
285
Required fields:
286
- runner_id: Runner ID to enable
287
"""
288
```
289
290
### CI/CD Variables
291
292
```python { .api }
293
class ProjectVariable(SaveMixin, ObjectDeleteMixin, RESTObject):
294
"""
295
Project CI/CD variable object.
296
297
Attributes:
298
- key: Variable name
299
- value: Variable value (may be masked)
300
- variable_type: Variable type ("env_var", "file")
301
- protected: Protected variable flag
302
- masked: Masked variable flag
303
- raw: Raw variable flag
304
- environment_scope: Environment scope
305
- description: Variable description
306
"""
307
308
def save(self) -> None:
309
"""Save variable changes."""
310
311
def delete(self) -> None:
312
"""Delete variable."""
313
314
class ProjectVariableManager(CRUDMixin[ProjectVariable]):
315
"""Manager for project CI/CD variables."""
316
317
def create(self, data: dict, **kwargs) -> ProjectVariable:
318
"""
319
Create new variable.
320
321
Required fields:
322
- key: Variable name
323
- value: Variable value
324
325
Optional fields:
326
- variable_type: Variable type ("env_var", "file")
327
- protected: Protect variable (accessible only in protected branches/tags)
328
- masked: Mask variable in logs
329
- raw: Treat as raw variable
330
- environment_scope: Environment scope pattern
331
- description: Variable description
332
"""
333
```
334
335
### Pipeline Triggers
336
337
```python { .api }
338
class ProjectTrigger(SaveMixin, ObjectDeleteMixin, RESTObject):
339
"""
340
Pipeline trigger token object.
341
342
Attributes:
343
- id: Trigger ID
344
- description: Trigger description
345
- created_at: Creation timestamp
346
- last_used: Last usage timestamp
347
- token: Trigger token
348
- updated_at: Update timestamp
349
- owner: Token owner
350
"""
351
352
def save(self) -> None:
353
"""Save trigger changes."""
354
355
def delete(self) -> None:
356
"""Delete trigger."""
357
358
class ProjectTriggerManager(CRUDMixin[ProjectTrigger]):
359
"""Manager for pipeline triggers."""
360
361
def create(self, data: dict, **kwargs) -> ProjectTrigger:
362
"""
363
Create new trigger.
364
365
Required fields:
366
- description: Trigger description
367
"""
368
```
369
370
### Pipeline Schedules
371
372
```python { .api }
373
class ProjectPipelineSchedule(SaveMixin, ObjectDeleteMixin, RESTObject):
374
"""
375
Pipeline schedule object for automated pipeline execution.
376
377
Attributes:
378
- id: Schedule ID
379
- description: Schedule description
380
- ref: Git reference
381
- cron: Cron expression
382
- cron_timezone: Timezone
383
- next_run_at: Next execution timestamp
384
- active: Active status
385
- created_at: Creation timestamp
386
- updated_at: Update timestamp
387
- owner: Schedule owner
388
- last_pipeline: Last pipeline information
389
"""
390
391
def save(self) -> None:
392
"""Save schedule changes."""
393
394
def delete(self) -> None:
395
"""Delete schedule."""
396
397
def play(self) -> dict:
398
"""Trigger schedule immediately."""
399
400
def take_ownership(self) -> dict:
401
"""Take ownership of schedule."""
402
403
class ProjectPipelineScheduleManager(CRUDMixin[ProjectPipelineSchedule]):
404
"""Manager for pipeline schedules."""
405
406
def create(self, data: dict, **kwargs) -> ProjectPipelineSchedule:
407
"""
408
Create new schedule.
409
410
Required fields:
411
- description: Schedule description
412
- ref: Git reference
413
- cron: Cron expression
414
415
Optional fields:
416
- cron_timezone: Timezone (default: UTC)
417
- active: Active status (default: true)
418
"""
419
```
420
421
### Usage Examples
422
423
```python
424
import gitlab
425
426
gl = gitlab.Gitlab("https://gitlab.example.com", private_token="your-token")
427
project = gl.projects.get(123)
428
429
# Pipeline management
430
pipelines = project.pipelines.list(
431
status="running",
432
ref="main",
433
order_by="updated_at"
434
)
435
436
# Create pipeline
437
pipeline_data = {
438
"ref": "main",
439
"variables": [
440
{"key": "DEPLOY_ENV", "value": "staging"},
441
{"key": "DEBUG", "value": "true"}
442
]
443
}
444
pipeline = project.pipelines.create(pipeline_data)
445
446
# Pipeline operations
447
pipeline.cancel()
448
pipeline.retry()
449
450
# Job management
451
jobs = project.jobs.list(scope="failed")
452
for job in jobs:
453
print(f"Job {job.name}: {job.status}")
454
if job.status == "failed":
455
job.retry()
456
457
# Get job trace
458
job = project.jobs.get(456)
459
trace = job.trace()
460
print(trace.decode('utf-8'))
461
462
# Job operations
463
job.cancel()
464
job.play()
465
job.erase()
466
job.keep_artifacts()
467
468
# Runner management
469
runners = gl.runners.list(scope="online", type="project_type")
470
471
# Enable runner for project
472
project.runners.create({"runner_id": 789})
473
474
# CI/CD Variables
475
variables = project.variables.list()
476
477
# Create variable
478
var_data = {
479
"key": "DATABASE_URL",
480
"value": "postgresql://user:pass@host/db",
481
"protected": True,
482
"masked": True,
483
"environment_scope": "production"
484
}
485
variable = project.variables.create(var_data)
486
487
# Update variable
488
variable.value = "new_value"
489
variable.save()
490
491
# Pipeline triggers
492
triggers = project.triggers.list()
493
494
# Create trigger
495
trigger_data = {"description": "External deployment trigger"}
496
trigger = project.triggers.create(trigger_data)
497
498
# Pipeline schedules
499
schedules = project.pipelineschedules.list()
500
501
# Create schedule
502
schedule_data = {
503
"description": "Nightly build",
504
"ref": "main",
505
"cron": "0 2 * * *", # 2 AM daily
506
"cron_timezone": "UTC",
507
"active": True
508
}
509
schedule = project.pipelineschedules.create(schedule_data)
510
511
# Schedule operations
512
schedule.play() # Run immediately
513
schedule.take_ownership()
514
515
# Pipeline artifacts
516
artifacts = pipeline.jobs.list()
517
for job in artifacts:
518
if job.artifacts_file:
519
print(f"Job {job.name} has artifacts")
520
job.delete_artifacts()
521
```
522
523
### Error Handling
524
525
```python { .api }
526
class GitlabPipelineCancelError(GitlabCancelError):
527
"""Raised when pipeline cancellation fails."""
528
pass
529
530
class GitlabPipelineRetryError(GitlabRetryError):
531
"""Raised when pipeline retry fails."""
532
pass
533
534
class GitlabPipelinePlayError(GitlabRetryError):
535
"""Raised when pipeline play fails."""
536
pass
537
538
class GitlabJobCancelError(GitlabCancelError):
539
"""Raised when job cancellation fails."""
540
pass
541
542
class GitlabJobRetryError(GitlabRetryError):
543
"""Raised when job retry fails."""
544
pass
545
546
class GitlabJobPlayError(GitlabRetryError):
547
"""Raised when job play fails."""
548
pass
549
550
class GitlabJobEraseError(GitlabRetryError):
551
"""Raised when job erasure fails."""
552
pass
553
```
554
555
Example error handling:
556
```python
557
try:
558
pipeline.cancel()
559
except gitlab.GitlabPipelineCancelError as e:
560
print(f"Cannot cancel pipeline: {e}")
561
562
try:
563
job.retry()
564
except gitlab.GitlabJobRetryError as e:
565
print(f"Job retry failed: {e}")
566
```