0
# Project Management
1
2
Comprehensive project lifecycle management including creation, configuration, access control, and administrative operations. The Project object serves as the central hub for accessing all project-related resources and provides extensive project management capabilities.
3
4
## Capabilities
5
6
### Project Class and Operations
7
8
The main Project class representing a GitLab project with all associated resources and operations.
9
10
```python { .api }
11
class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, UploadMixin, RESTObject):
12
"""
13
GitLab project object with comprehensive resource management.
14
15
Key Attributes:
16
- id: Project ID
17
- name: Project name
18
- path: Project path (URL slug)
19
- path_with_namespace: Full project path including namespace
20
- description: Project description
21
- visibility: Project visibility level ("private", "internal", "public")
22
- default_branch: Default branch name
23
- web_url: Project web URL
24
- created_at: Creation timestamp
25
- updated_at: Last update timestamp
26
"""
27
28
def save(self) -> None:
29
"""
30
Save project changes to GitLab server.
31
32
Raises:
33
GitlabUpdateError: If the update fails
34
"""
35
36
def delete(self) -> None:
37
"""
38
Delete the project permanently.
39
40
Raises:
41
GitlabDeleteError: If the deletion fails
42
"""
43
44
def refresh(self) -> None:
45
"""Refresh project data from server."""
46
```
47
48
#### Project Actions
49
50
```python { .api }
51
def star(self) -> None:
52
"""
53
Star the project.
54
55
Raises:
56
GitlabCreateError: If starring fails
57
"""
58
59
def unstar(self) -> None:
60
"""
61
Unstar the project.
62
63
Raises:
64
GitlabDeleteError: If unstarring fails
65
"""
66
67
def archive(self) -> None:
68
"""
69
Archive the project.
70
71
Raises:
72
GitlabCreateError: If archiving fails
73
"""
74
75
def unarchive(self) -> None:
76
"""
77
Unarchive the project.
78
79
Raises:
80
GitlabDeleteError: If unarchiving fails
81
"""
82
83
def transfer_project(self, to_namespace: str) -> dict:
84
"""
85
Transfer project to another namespace.
86
87
Parameters:
88
- to_namespace: Target namespace name or ID
89
90
Returns:
91
Dictionary with transfer result
92
93
Raises:
94
GitlabTransferProjectError: If transfer fails
95
"""
96
97
def fork(self, namespace: str | None = None, name: str | None = None, path: str | None = None) -> dict:
98
"""
99
Fork the project.
100
101
Parameters:
102
- namespace: Target namespace for fork (optional)
103
- name: Name for forked project (optional)
104
- path: Path for forked project (optional)
105
106
Returns:
107
Dictionary with fork information
108
109
Raises:
110
GitlabCreateError: If forking fails
111
"""
112
113
def create_fork_relation(self, forked_from_id: int) -> None:
114
"""
115
Create fork relationship between projects.
116
117
Parameters:
118
- forked_from_id: ID of the source project
119
120
Raises:
121
GitlabCreateError: If relation creation fails
122
"""
123
124
def delete_fork_relation(self) -> None:
125
"""
126
Delete fork relationship.
127
128
Raises:
129
GitlabDeleteError: If relation deletion fails
130
"""
131
132
def languages(self) -> dict[str, float]:
133
"""
134
Get programming languages used in project with percentages.
135
136
Returns:
137
Dictionary mapping language names to percentage values
138
"""
139
140
def share(self, group_id: int, group_access: int, expires_at: str | None = None) -> dict:
141
"""
142
Share project with a group.
143
144
Parameters:
145
- group_id: ID of group to share with
146
- group_access: Access level (10=Guest, 20=Reporter, 30=Developer, 40=Maintainer, 50=Owner)
147
- expires_at: Share expiration date (ISO format, optional)
148
149
Returns:
150
Dictionary with sharing result
151
"""
152
153
def unshare(self, group_id: int) -> None:
154
"""
155
Stop sharing project with a group.
156
157
Parameters:
158
- group_id: ID of group to stop sharing with
159
"""
160
161
def housekeeping(self) -> None:
162
"""
163
Start housekeeping task for project repository.
164
165
Raises:
166
GitlabHousekeepingError: If housekeeping fails
167
"""
168
169
def snapshot(self, wiki: bool = False) -> dict:
170
"""
171
Create project snapshot.
172
173
Parameters:
174
- wiki: Include wiki in snapshot
175
176
Returns:
177
Dictionary with snapshot information
178
"""
179
```
180
181
### Project Manager
182
183
```python { .api }
184
class ProjectManager(CRUDMixin[Project]):
185
"""Manager for GitLab projects with comprehensive filtering and creation options."""
186
187
def list(
188
self,
189
archived: bool | None = None,
190
visibility: str | None = None,
191
order_by: str | None = None,
192
sort: str | None = None,
193
search: str | None = None,
194
search_namespaces: bool | None = None,
195
simple: bool | None = None,
196
owned: bool | None = None,
197
membership: bool | None = None,
198
starred: bool | None = None,
199
statistics: bool | None = None,
200
with_custom_attributes: bool | None = None,
201
with_issues_enabled: bool | None = None,
202
with_merge_requests_enabled: bool | None = None,
203
with_programming_language: str | None = None,
204
wiki_checksum_failed: bool | None = None,
205
repository_checksum_failed: bool | None = None,
206
min_access_level: int | None = None,
207
id_after: int | None = None,
208
id_before: int | None = None,
209
last_activity_after: str | None = None,
210
last_activity_before: str | None = None,
211
repository_storage: str | None = None,
212
topic: str | None = None,
213
**kwargs
214
) -> list[Project]:
215
"""
216
List projects with extensive filtering options.
217
218
Parameters:
219
- archived: Filter by archived status
220
- visibility: Filter by visibility ("private", "internal", "public")
221
- order_by: Order by field ("id", "name", "path", "created_at", "updated_at", "last_activity_at")
222
- sort: Sort direction ("asc", "desc")
223
- search: Search in project name and description
224
- search_namespaces: Include namespaces in search
225
- simple: Return minimal project information
226
- owned: Show only owned projects
227
- membership: Show only projects where user is member
228
- starred: Show only starred projects
229
- statistics: Include project statistics
230
- with_custom_attributes: Include custom attributes
231
- with_issues_enabled: Filter by issues enabled
232
- with_merge_requests_enabled: Filter by merge requests enabled
233
- with_programming_language: Filter by programming language
234
- min_access_level: Minimum access level
235
- id_after: Return projects with ID after this value
236
- id_before: Return projects with ID before this value
237
- last_activity_after: Filter by last activity date (ISO format)
238
- last_activity_before: Filter by last activity date (ISO format)
239
- topic: Filter by topic
240
241
Returns:
242
List of Project objects
243
"""
244
245
def get(self, id: int | str, lazy: bool = False, **kwargs) -> Project:
246
"""
247
Get a specific project.
248
249
Parameters:
250
- id: Project ID or path with namespace
251
- lazy: Return object without making API call
252
- statistics: Include project statistics
253
- license: Include license information
254
- with_custom_attributes: Include custom attributes
255
256
Returns:
257
Project object
258
259
Raises:
260
GitlabGetError: If project not found or access denied
261
"""
262
263
def create(self, data: dict, **kwargs) -> Project:
264
"""
265
Create a new project.
266
267
Parameters:
268
- data: Project creation parameters
269
270
Required fields in data:
271
- name: Project name
272
273
Optional fields in data:
274
- path: Project path (defaults to name)
275
- namespace_id: Namespace ID for project
276
- description: Project description
277
- issues_enabled: Enable issues (default: True)
278
- merge_requests_enabled: Enable merge requests (default: True)
279
- jobs_enabled: Enable CI/CD jobs (default: True)
280
- wiki_enabled: Enable wiki (default: True)
281
- snippets_enabled: Enable snippets (default: True)
282
- resolve_outdated_diff_discussions: Auto-resolve outdated discussions
283
- container_registry_enabled: Enable container registry
284
- shared_runners_enabled: Enable shared runners
285
- visibility: Project visibility ("private", "internal", "public")
286
- import_url: Git repository URL to import
287
- public_builds: Make builds public
288
- only_allow_merge_if_pipeline_succeeds: Require pipeline success for merge
289
- only_allow_merge_if_all_discussions_are_resolved: Require resolved discussions
290
- merge_method: Merge method ("merge", "rebase_merge", "ff")
291
- lfs_enabled: Enable Git LFS
292
- request_access_enabled: Allow access requests
293
- tag_list: List of project tags
294
- printing_merge_request_link_enabled: Print MR link after push
295
- build_git_strategy: Git strategy for builds
296
- build_timeout: Build timeout in seconds
297
- auto_cancel_pending_pipelines: Auto-cancel pending pipelines
298
- build_coverage_regex: Coverage parsing regex
299
- ci_config_path: CI config file path
300
- repository_storage: Repository storage name
301
- approvals_before_merge: Required approvals before merge
302
- external_authorization_classification_label: Classification label
303
- mirror: Enable repository mirroring
304
- mirror_user_id: Mirror user ID
305
- mirror_trigger_builds: Trigger builds on mirror
306
- initialize_with_readme: Create initial README
307
- template_name: Project template name
308
- template_project_id: Template project ID
309
- use_custom_template: Use custom template
310
- group_with_project_templates_id: Group with project templates
311
- packages_enabled: Enable package registry
312
313
Returns:
314
New Project object
315
316
Raises:
317
GitlabCreateError: If project creation fails
318
"""
319
320
def import_project(
321
self,
322
file: io.BufferedReader,
323
path: str,
324
name: str | None = None,
325
namespace: str | None = None,
326
overwrite: bool = False,
327
override_params: dict | None = None,
328
**kwargs
329
) -> dict:
330
"""
331
Import project from file.
332
333
Parameters:
334
- file: Project export file
335
- path: Project path
336
- name: Project name (optional)
337
- namespace: Target namespace (optional)
338
- overwrite: Overwrite existing project
339
- override_params: Override project parameters
340
341
Returns:
342
Dictionary with import information
343
"""
344
```
345
346
### Project Resource Managers
347
348
The Project class provides access to all project-related resources through manager attributes:
349
350
```python { .api }
351
# Core project resources
352
@property
353
def issues(self) -> ProjectIssueManager:
354
"""Access project issues."""
355
356
@property
357
def issues_statistics(self) -> ProjectIssuesStatisticsManager:
358
"""Access project issue statistics."""
359
360
@property
361
def mergerequests(self) -> ProjectMergeRequestManager:
362
"""Access project merge requests."""
363
364
@property
365
def milestones(self) -> ProjectMilestoneManager:
366
"""Access project milestones."""
367
368
@property
369
def labels(self) -> ProjectLabelManager:
370
"""Access project labels."""
371
372
# Repository and code management
373
@property
374
def commits(self) -> ProjectCommitManager:
375
"""Access project commits."""
376
377
@property
378
def branches(self) -> ProjectBranchManager:
379
"""Access project branches."""
380
381
@property
382
def tags(self) -> ProjectTagManager:
383
"""Access project tags."""
384
385
@property
386
def files(self) -> ProjectFileManager:
387
"""Access project repository files."""
388
389
@property
390
def protectedbranches(self) -> ProjectProtectedBranchManager:
391
"""Access protected branches."""
392
393
@property
394
def protectedtags(self) -> ProjectProtectedTagManager:
395
"""Access protected tags."""
396
397
# CI/CD resources
398
@property
399
def pipelines(self) -> ProjectPipelineManager:
400
"""Access project pipelines."""
401
402
@property
403
def jobs(self) -> ProjectJobManager:
404
"""Access project jobs."""
405
406
@property
407
def runners(self) -> ProjectRunnerManager:
408
"""Access project runners."""
409
410
@property
411
def variables(self) -> ProjectVariableManager:
412
"""Access project CI/CD variables."""
413
414
@property
415
def triggers(self) -> ProjectTriggerManager:
416
"""Access pipeline triggers."""
417
418
@property
419
def pipelineschedules(self) -> ProjectPipelineScheduleManager:
420
"""Access pipeline schedules."""
421
422
# Access control and members
423
@property
424
def members(self) -> ProjectMemberManager:
425
"""Access project members."""
426
427
@property
428
def members_all(self) -> ProjectMemberAllManager:
429
"""Access all project members including inherited."""
430
431
@property
432
def accessrequests(self) -> ProjectAccessRequestManager:
433
"""Access project access requests."""
434
435
@property
436
def access_tokens(self) -> ProjectAccessTokenManager:
437
"""Access project access tokens."""
438
439
# Deployment and environments
440
@property
441
def environments(self) -> ProjectEnvironmentManager:
442
"""Access project environments."""
443
444
@property
445
def deployments(self) -> ProjectDeploymentManager:
446
"""Access project deployments."""
447
448
@property
449
def deploytokens(self) -> ProjectDeployTokenManager:
450
"""Access deploy tokens."""
451
452
@property
453
def keys(self) -> ProjectKeyManager:
454
"""Access deploy keys."""
455
456
# Integration and webhooks
457
@property
458
def hooks(self) -> ProjectHookManager:
459
"""Access project webhooks."""
460
461
@property
462
def integrations(self) -> ProjectIntegrationManager:
463
"""Access project integrations."""
464
465
@property
466
def services(self) -> ProjectServiceManager:
467
"""Access project services (deprecated, use integrations)."""
468
469
# Additional resources (40+ more managers available)
470
@property
471
def wikis(self) -> ProjectWikiManager:
472
"""Access project wiki pages."""
473
474
@property
475
def snippets(self) -> ProjectSnippetManager:
476
"""Access project snippets."""
477
478
@property
479
def packages(self) -> ProjectPackageManager:
480
"""Access project packages."""
481
482
@property
483
def releases(self) -> ProjectReleaseManager:
484
"""Access project releases."""
485
486
@property
487
def badges(self) -> ProjectBadgeManager:
488
"""Access project badges."""
489
490
@property
491
def boards(self) -> ProjectBoardManager:
492
"""Access project issue boards."""
493
```
494
495
### Usage Examples
496
497
```python
498
import gitlab
499
500
# Initialize client
501
gl = gitlab.Gitlab("https://gitlab.example.com", private_token="your-token")
502
503
# List projects with filtering
504
projects = gl.projects.list(
505
owned=True,
506
visibility="private",
507
order_by="updated_at",
508
sort="desc",
509
search="api"
510
)
511
512
# Get specific project
513
project = gl.projects.get(123)
514
# or by path
515
project = gl.projects.get("group/project-name")
516
517
# Create new project
518
project_data = {
519
"name": "My New Project",
520
"description": "A sample project",
521
"visibility": "private",
522
"issues_enabled": True,
523
"merge_requests_enabled": True,
524
"wiki_enabled": False,
525
"initialize_with_readme": True
526
}
527
new_project = gl.projects.create(project_data)
528
529
# Project operations
530
project.star()
531
project.fork(namespace="my-namespace")
532
533
# Transfer project
534
project.transfer_project("new-namespace")
535
536
# Share project with group
537
project.share(group_id=456, group_access=30) # Developer access
538
539
# Get project languages
540
languages = project.languages()
541
print(f"Languages: {languages}")
542
543
# Access project resources
544
issues = project.issues.list(state="opened")
545
mrs = project.mergerequests.list(state="merged")
546
branches = project.branches.list()
547
548
# Project statistics
549
if hasattr(project, 'statistics'):
550
stats = project.statistics
551
print(f"Commit count: {stats['commit_count']}")
552
print(f"Storage size: {stats['storage_size']}")
553
554
# Delete project (careful!)
555
# project.delete()
556
```
557
558
### Fork Management
559
560
```python { .api }
561
class ProjectFork(RESTObject):
562
"""Represents a project fork relationship."""
563
pass
564
565
class ProjectForkManager(ListMixin[ProjectFork]):
566
"""Manager for project forks."""
567
568
def list(self, **kwargs) -> list[ProjectFork]:
569
"""List project forks."""
570
```
571
572
### Project Groups and Sharing
573
574
```python { .api }
575
class ProjectGroup(RESTObject):
576
"""Represents a group that has access to the project."""
577
pass
578
579
class ProjectGroupManager(ListMixin[ProjectGroup]):
580
"""Manager for groups with project access."""
581
582
def list(
583
self,
584
search: str | None = None,
585
skip_groups: list[int] | None = None,
586
with_shared: bool | None = None,
587
shared_min_access_level: int | None = None,
588
shared_visible_only: bool | None = None,
589
**kwargs
590
) -> list[ProjectGroup]:
591
"""List groups with access to project."""
592
```
593
594
### Error Handling
595
596
```python { .api }
597
class GitlabTransferProjectError(GitlabOperationError):
598
"""Raised when project transfer fails."""
599
pass
600
601
class GitlabHousekeepingError(GitlabOperationError):
602
"""Raised when housekeeping operation fails."""
603
pass
604
```
605
606
Example error handling:
607
```python
608
try:
609
project = gl.projects.get("nonexistent/project")
610
except gitlab.GitlabGetError as e:
611
if e.response_code == 404:
612
print("Project not found")
613
elif e.response_code == 403:
614
print("Access denied")
615
else:
616
print(f"Error: {e}")
617
618
try:
619
project.transfer_project("invalid-namespace")
620
except gitlab.GitlabTransferProjectError as e:
621
print(f"Transfer failed: {e}")
622
```