Coverage for src/gitlabracadabra/objects/group.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-10 17:02 +0100

1# 

2# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com> 

3# 

4# This program is free software: you can redistribute it and/or modify 

5# it under the terms of the GNU Lesser General Public License as published by 

6# the Free Software Foundation, either version 3 of the License, or 

7# (at your option) any later version. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU Lesser General Public License for more details. 

13# 

14# You should have received a copy of the GNU Lesser General Public License 

15# along with this program. If not, see <http://www.gnu.org/licenses/>. 

16 

17from typing import ClassVar 

18 

19from gitlabracadabra.mixins.boards import BoardsMixin 

20from gitlabracadabra.mixins.groups import GroupsMixin 

21from gitlabracadabra.mixins.labels import LabelsMixin 

22from gitlabracadabra.mixins.members import MembersMixin 

23from gitlabracadabra.mixins.milestones import MilestonesMixin 

24from gitlabracadabra.mixins.variables import VariablesMixin 

25from gitlabracadabra.objects.object import GitLabracadabraObject 

26 

27 

28class GitLabracadabraGroup( 

29 BoardsMixin, GroupsMixin, LabelsMixin, MembersMixin, MilestonesMixin, VariablesMixin, GitLabracadabraObject 

30): 

31 EXAMPLE_YAML_HEADER: ClassVar[str] = "mygroup/:\n" 

32 DOC: ClassVar[list[str]] = [ 

33 "# Group lifecycle", 

34 "gitlab_id", 

35 "create_object", 

36 "delete_object", 

37 "# Manage", 

38 "## Members", 

39 "members", 

40 "unknown_members", 

41 "groups", 

42 "unknown_groups", 

43 "## Labels", 

44 "labels", 

45 "unknown_labels", 

46 "# Plan", 

47 "## Issue boards", 

48 "boards", 

49 "unknown_boards", 

50 "unknown_board_lists", 

51 "## Milestones", 

52 "milestones", 

53 "unknown_milestones", 

54 "# General Settings", 

55 "## Naming, visibility", 

56 "name", 

57 "description", 

58 # 'avatar', # FIXME: GitLabracadabra 

59 "visibility", 

60 "## Permissions and group features", 

61 "prevent_sharing_groups_outside_hierarchy", 

62 "share_with_group_lock", 

63 "mentions_disabled", 

64 "emails_enabled", 

65 "ip_restriction_ranges", 

66 "allowed_email_domains_list", 

67 "wiki_access_level", 

68 "lfs_enabled", 

69 "enabled_git_access_protocol", 

70 "project_creation_level", 

71 "subgroup_creation_level", 

72 "prevent_forking_outside_group", 

73 "require_two_factor_authentication", 

74 "two_factor_grace_period", 

75 "request_access_enabled", 

76 "membership_lock", 

77 "## GitLab Duo features", 

78 "duo_features_enabled", 

79 "lock_duo_features_enabled", 

80 "## Repository Settings", 

81 "### Default branch", 

82 "default_branch", 

83 # 'default_branch_protection_defaults', 

84 "## CI / CD Settings", 

85 "### Variables", 

86 "variables", 

87 "unknown_variables", 

88 "### Runners", 

89 "shared_runners_setting", 

90 "### Auto DevOps", 

91 "auto_devops_enabled", 

92 "# Deprecated", 

93 "emails_disabled", 

94 ] 

95 SCHEMA: ClassVar[dict] = { 

96 "$schema": "http://json-schema.org/draft-04/schema#", 

97 "title": "Group", 

98 "type": "object", 

99 "properties": { 

100 # Standard properties 

101 "gitlab_id": { 

102 "type": "string", 

103 "description": "GitLab id", 

104 "_example": "gitlab", 

105 "_doc_link": "action_file.md#gitlab_id", 

106 }, 

107 "create_object": { 

108 "type": "boolean", 

109 "description": "Create object if it does not exists", 

110 }, 

111 "delete_object": { 

112 "type": "boolean", 

113 "description": "Delete object if it exists", 

114 }, 

115 # From https://docs.gitlab.com/ee/api/members.html#add-a-member-to-a-group-or-project 

116 # FIXME: expires_at not supported 

117 "members": { 

118 "type": "object", 

119 "description": "Members", 

120 "additionalProperties": { 

121 "type": "string", 

122 "description": "The permissions level to grant the member.", 

123 "enum": ["guest", "reporter", "developer", "maintainer", "owner"], 

124 }, 

125 "_example": ( 

126 "\n" 

127 " foo: developer\n" 

128 " bar: maintainer # one of guest, reporter, developer, maintainer, owner\n" 

129 ), 

130 }, 

131 "unknown_members": { # GitLabracadabra 

132 "type": "string", 

133 "description": "What to do with unknown members (`warn` by default).", 

134 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

135 }, 

136 # From https://docs.gitlab.com/ee/api/groups.html#create-a-link-to-share-a-group-with-another-group 

137 # and https://docs.gitlab.com/ee/api/groups.html#delete-link-sharing-group-with-another-group 

138 # FIXME: expires_at not supported 

139 "groups": { 

140 "type": "object", 

141 "description": "Groups", 

142 "additionalProperties": { 

143 "type": "string", 

144 "description": "The permissions level to grant the group.", 

145 "enum": ["guest", "reporter", "developer", "maintainer"], 

146 }, 

147 "_example": ( 

148 "\n" 

149 " group/foo: guest\n" 

150 " group/bar: reporter # one of guest, reporter, developer, maintainer\n" 

151 ), 

152 }, 

153 "unknown_groups": { # GitLabracadabra 

154 "type": "string", 

155 "description": "What to do with unknown groups (`warn` by default).", 

156 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

157 }, 

158 # From https://docs.gitlab.com/ee/api/group_labels.html#create-a-new-group-label 

159 "labels": { 

160 "type": "array", 

161 "description": "The list of group's labels", 

162 "items": { 

163 "type": "object", 

164 "properties": { 

165 "name": { 

166 "type": "string", 

167 "description": "The name of the label.", 

168 }, 

169 "color": { 

170 "type": "string", 

171 "description": "The color of the label.", 

172 }, 

173 "description": { 

174 "type": "string", 

175 "description": "The description of the label.", 

176 }, 

177 }, 

178 "required": ["name", "color"], 

179 "additionalProperties": False, 

180 }, 

181 "uniqueItems": True, 

182 "_example": ( 

183 "\n" 

184 " - name: bug\n" 

185 " color: '#d9534f'\n" 

186 " description: ''\n" 

187 " - name: confirmed\n" 

188 " color: '#d9534f'\n" 

189 " description: ''\n" 

190 " - name: critical\n" 

191 " color: '#d9534f'\n" 

192 " description: ''\n" 

193 " - name: discussion\n" 

194 " color: '#428bca'\n" 

195 " description: ''\n" 

196 " - name: documentation\n" 

197 " color: '#f0ad4e'\n" 

198 " description: ''\n" 

199 " - name: enhancement\n" 

200 " color: '#5cb85c'\n" 

201 " description: ''\n" 

202 " - name: suggestion\n" 

203 " color: '#428bca'\n" 

204 " description: ''\n" 

205 " - name: support\n" 

206 " color: '#f0ad4e'\n" 

207 " description: ''\n" 

208 ), 

209 }, 

210 "unknown_labels": { # GitLabracadabra 

211 "type": "string", 

212 "description": "What to do with unknown labels (`warn` by default).", 

213 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

214 }, 

215 # From https://docs.gitlab.com/ee/api/group_boards.html 

216 "boards": { 

217 "type": "array", 

218 "description": "The list of group's boards", 

219 "items": { 

220 "type": "object", 

221 "properties": { 

222 "name": { 

223 "type": "string", 

224 "description": "The name of the board.", 

225 }, 

226 "old_name": { 

227 "type": "string", 

228 "description": "The previous name of the board.", 

229 }, 

230 "hide_backlog_list": { 

231 "type": "boolean", 

232 "description": "Hide the Open list", 

233 }, 

234 "hide_closed_list": { 

235 "type": "boolean", 

236 "description": "Hide the Closed list", 

237 }, 

238 "lists": { 

239 "type": "array", 

240 "description": "Ordered list of labels", 

241 "items": { 

242 "type": "object", 

243 "properties": { 

244 "label": { 

245 "type": "string", 

246 "description": "The name of a label", 

247 }, 

248 }, 

249 }, 

250 }, 

251 "unknown_lists": { # GitLabracadabra 

252 "type": "string", 

253 "description": ( 

254 "What to do with unknown board lists " "(Value of `unknown_board_lists` by default)." 

255 ), 

256 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

257 }, 

258 }, 

259 "required": ["name"], 

260 "additionalProperties": False, 

261 }, 

262 "uniqueItems": True, 

263 "_example": ( 

264 "\n" 

265 " - name: My group board\n" 

266 " # old_name: Development # Use this to rename a board\n" 

267 " hide_backlog_list: false\n" 

268 " hide_closed_list: false\n" 

269 " lists:\n" 

270 " - label: TODO\n" 

271 " - label: WIP\n" 

272 ), 

273 }, 

274 "unknown_boards": { # GitLabracadabra 

275 "type": "string", 

276 "description": "What to do with unknown boards (`warn` by default).", 

277 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

278 }, 

279 "unknown_board_lists": { # GitLabracadabra 

280 "type": "string", 

281 "description": "What to do with unknown board lists (`delete` by default).", 

282 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

283 }, 

284 # From https://docs.gitlab.com/ee/api/group_milestones.html#edit-milestone 

285 "milestones": { 

286 "type": "array", 

287 "description": "The list of group's milestones", 

288 "items": { 

289 "type": "object", 

290 "properties": { 

291 "title": { 

292 "type": "string", 

293 "description": "The title of a milestone", 

294 }, 

295 "description": { 

296 "type": "string", 

297 "description": "The description of a milestone", 

298 }, 

299 "due_date": { 

300 "type": "string", 

301 "description": "The due date of the milestone", 

302 "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$", 

303 }, 

304 "start_date": { 

305 "type": "string", 

306 "description": "The start date of the milestone", 

307 "pattern": "^(\\d{4}-\\d{2}-\\d{2})?$", 

308 }, 

309 "state": { 

310 "type": "string", 

311 "description": "The state event of the milestone", 

312 "enum": ["closed", "active"], 

313 }, 

314 }, 

315 "required": ["title"], 

316 "additionalProperties": False, 

317 }, 

318 "uniqueItems": True, 

319 "_example": ( 

320 "\n" 

321 " - title: '1.0'\n" 

322 " description: Version 1.0\n" 

323 " due_date: '2021-01-23' # Quotes are mandatory\n" 

324 " start_date: '2020-01-23' # Quotes are mandatory\n" 

325 " state: active # or closed\n" 

326 ), 

327 }, 

328 "unknown_milestones": { # GitLabracadabra 

329 "type": "string", 

330 "description": "What to do with unknown milestones (`warn` by default).", 

331 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

332 }, 

333 # From https://docs.gitlab.com/ee/api/groups.html#new-group 

334 "name": { 

335 "type": "string", 

336 "description": "The name of the group", 

337 }, 

338 # 'path': { 

339 # 'type': 'string', 

340 # 'description': 'The path of the group', 

341 # }, 

342 "description": { 

343 "type": "string", 

344 "description": "The group's description", 

345 }, 

346 "visibility": { 

347 "type": "string", 

348 "description": "The group's visibility. Can be private, internal, or public.", 

349 "enum": ["private", "internal", "public"], 

350 }, 

351 "prevent_sharing_groups_outside_hierarchy": { 

352 "type": "boolean", 

353 "description": ( 

354 "Prevent group sharing outside the group hierarchy. " 

355 "This attribute is only available on top-level groups." 

356 ), 

357 }, 

358 "share_with_group_lock": { 

359 "type": "boolean", 

360 "description": "Prevent sharing a project with another group within this group", 

361 }, 

362 "mentions_disabled": { 

363 "type": "boolean", 

364 "description": "Disable the capability of a group from getting mentioned.", 

365 }, 

366 "emails_enabled": { 

367 "type": "boolean", 

368 "description": "Enable email notifications.", 

369 }, 

370 "ip_restriction_ranges": { 

371 "type": "string", 

372 "description": "Comma-separated list of IP addresses or subnet masks to restrict group access.", 

373 }, 

374 "allowed_email_domains_list": { 

375 "type": "string", 

376 "description": "Comma-separated list of email address domains to allow group access.", 

377 }, 

378 "wiki_access_level": { 

379 "type": "string", 

380 "description": "The wiki access level.", 

381 "enum": ["disabled", "private", "enabled"], 

382 }, 

383 "lfs_enabled": { 

384 "type": "boolean", 

385 "description": "Enable/disable Large File Storage (LFS) for the projects in this group", 

386 }, 

387 "enabled_git_access_protocol": { 

388 "type": "string", 

389 "description": "Enabled protocols for Git access.", 

390 "enum": ["ssh", "http", "all"], 

391 }, 

392 "project_creation_level": { 

393 "type": "string", 

394 "description": "Determine if developers can create projects in the group", 

395 "enum": ["noone", "maintainer", "developer"], 

396 }, 

397 "subgroup_creation_level": { 

398 "type": "string", 

399 "description": "Allowed to create subgroups", 

400 "enum": ["owner", "maintainer"], 

401 }, 

402 "prevent_forking_outside_group": { 

403 "type": "boolean", 

404 "description": "When enabled, users can not fork projects from this group to external namespaces.", 

405 }, 

406 "require_two_factor_authentication": { 

407 "type": "boolean", 

408 "description": "Require all users in this group to setup Two-factor authentication", 

409 }, 

410 "two_factor_grace_period": { 

411 "type": "integer", 

412 "description": "Time before Two-factor authentication is enforced (in hours)", 

413 }, 

414 "request_access_enabled": { 

415 "type": "boolean", 

416 "description": "Allow users to request member access.", 

417 }, 

418 "membership_lock": { 

419 "type": "boolean", 

420 "description": "Prevent adding new members to project membership within this group", 

421 }, 

422 "duo_features_enabled": { 

423 "type": "boolean", 

424 "description": "ndicates whether GitLab Duo features are enabled for this group.", 

425 }, 

426 "lock_duo_features_enabled": { 

427 "type": "boolean", 

428 "description": ( 

429 "Indicates whether the GitLab Duo features enabled setting is enforced" " for all subgroups." 

430 ), 

431 }, 

432 "default_branch": { 

433 "type": "string", 

434 "description": "The default branch name for group's projects.", 

435 }, 

436 # From https://docs.gitlab.com/ee/api/group_level_variables.html#create-variable 

437 "variables": { 

438 "type": "array", 

439 "description": "The list of group's variables", 

440 "items": { 

441 "type": "object", 

442 "properties": { 

443 "key": { 

444 "type": "string", 

445 "description": "The key of a variable.", 

446 "pattern": "[a-zA-Z0-9_]+", 

447 "maxLength": 255, 

448 }, 

449 "value": { 

450 "type": "string", 

451 "description": "The value of a variable.", 

452 }, 

453 "description": { 

454 "type": "string", 

455 "description": "The description of the variable.", 

456 }, 

457 "variable_type": { 

458 "type": "string", 

459 "description": "The type of a variable. Available types are: env_var (default) and file.", 

460 "enum": ["env_var", "file"], 

461 }, 

462 "protected": { 

463 "type": "boolean", 

464 "description": "Whether the variable is protected.", 

465 }, 

466 "masked": { 

467 "type": "boolean", 

468 "description": "Whether the variable is masked.", 

469 }, 

470 "raw": { 

471 "type": "boolean", 

472 "description": "Whether the variable is treated as a raw string.", 

473 }, 

474 "environment_scope": { # Premium+/Silver+ 

475 "type": "string", 

476 "description": "The environment_scope of the variable.", 

477 }, 

478 }, 

479 "required": ["key"], 

480 "additionalProperties": False, 

481 }, 

482 "uniqueItems": True, 

483 "_example": ( 

484 "\n" 

485 " - key: DAST_DISABLED\n" 

486 " value: '1'\n" 

487 " description: Disabled SAST\n" 

488 " masked: false\n" 

489 " protected: false\n" 

490 " raw: false # Expand variables\n" 

491 " environment_scope: '*'\n" 

492 " variable_type: env_var\n" 

493 ), 

494 }, 

495 "unknown_variables": { # GitLabracadabra 

496 "type": "string", 

497 "description": "What to do with unknown variables (`warn` by default).", 

498 "enum": ["warn", "delete", "remove", "ignore", "skip"], 

499 }, 

500 # From https://docs.gitlab.com/ee/api/groups.html#new-group 

501 "shared_runners_setting": { 

502 "type": "string", 

503 "description": "Enable or disable shared runners for a group's subgroups and projects.", 

504 "enum": ["enabled", "disabled_and_overridable", "disabled_and_unoverridable"], 

505 }, 

506 "auto_devops_enabled": { 

507 "type": "boolean", 

508 "description": "Default to Auto DevOps pipeline for all projects within this group", 

509 }, 

510 "emails_disabled": { 

511 "type": "boolean", 

512 "description": "Disable email notifications", 

513 }, 

514 # From https://docs.gitlab.com/ee/api/groups.html#new-group 

515 # Below are undocumented settings 

516 "file_template_project_id": { 

517 "type": "integer", 

518 "description": "(Premium) The ID of a project to load custom file templates from", 

519 "multipleOf": 1, 

520 "minimum": 0, 

521 }, 

522 "shared_runners_minutes_limit": { 

523 "type": "integer", 

524 "description": "(admin-only) Pipeline minutes quota for this group.", 

525 "multipleOf": 1, 

526 "minimum": 0, 

527 }, 

528 "extra_shared_runners_minutes_limit": { 

529 "type": "integer", 

530 "description": "(admin-only) Extra pipeline minutes quota for this group.", 

531 "multipleOf": 1, 

532 "minimum": 0, 

533 }, 

534 }, 

535 "additionalProperties": False, 

536 } 

537 

538 IGNORED_PARAMS: ClassVar[list[str]] = [ 

539 "unknown_boards", 

540 "unknown_board_lists", 

541 "unknown_groups", 

542 "unknown_labels", 

543 "unknown_members", 

544 "unknown_milestones", 

545 "unknown_variables", 

546 ] 

547 

548 CREATE_KEY = "name"