From ade9bd28ee5a29ba075b246ee79b3d4eb2d54f78 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Sun, 25 May 2025 00:50:17 +0000 Subject: [PATCH 01/20] chore: update go-gitlab to latest --- go.mod | 2 +- go.sum | 4 - pkg/client/gitlab/webhook_client.go | 6 +- pkg/reconciler/source/gitlabsource.go | 2 +- vendor/github.com/xanzy/go-gitlab/.travis.yml | 29 - .../github.com/xanzy/go-gitlab/CHANGELOG.md | 27 - vendor/github.com/xanzy/go-gitlab/README.md | 191 -- .../xanzy/go-gitlab/access_requests.go | 236 -- .../xanzy/go-gitlab/award_emojis.go | 467 ---- vendor/github.com/xanzy/go-gitlab/boards.go | 344 --- vendor/github.com/xanzy/go-gitlab/branches.go | 244 -- .../xanzy/go-gitlab/broadcast_messages.go | 172 -- .../xanzy/go-gitlab/ci_yml_templates.go | 69 - .../xanzy/go-gitlab/client_options.go | 59 - vendor/github.com/xanzy/go-gitlab/commits.go | 589 ---- .../github.com/xanzy/go-gitlab/deploy_keys.go | 234 -- .../xanzy/go-gitlab/deploy_tokens.go | 221 -- .../github.com/xanzy/go-gitlab/deployments.go | 193 -- .../github.com/xanzy/go-gitlab/discussions.go | 1112 -------- .../xanzy/go-gitlab/environments.go | 212 -- .../github.com/xanzy/go-gitlab/epic_issues.go | 133 - vendor/github.com/xanzy/go-gitlab/epics.go | 246 -- .../xanzy/go-gitlab/event_parsing.go | 233 -- .../xanzy/go-gitlab/event_systemhook_types.go | 133 - .../xanzy/go-gitlab/event_webhook_types.go | 834 ------ vendor/github.com/xanzy/go-gitlab/events.go | 146 - .../xanzy/go-gitlab/feature_flags.go | 79 - vendor/github.com/xanzy/go-gitlab/gitlab.go | 790 ------ .../xanzy/go-gitlab/group_badges.go | 213 -- .../xanzy/go-gitlab/group_boards.go | 351 --- .../github.com/xanzy/go-gitlab/group_hooks.go | 199 -- .../xanzy/go-gitlab/group_labels.go | 225 -- .../xanzy/go-gitlab/group_members.go | 275 -- .../xanzy/go-gitlab/group_milestones.go | 291 -- .../xanzy/go-gitlab/group_variables.go | 199 -- vendor/github.com/xanzy/go-gitlab/groups.go | 655 ----- .../github.com/xanzy/go-gitlab/issue_links.go | 127 - vendor/github.com/xanzy/go-gitlab/issues.go | 706 ----- .../xanzy/go-gitlab/issues_statistics.go | 186 -- vendor/github.com/xanzy/go-gitlab/jobs.go | 433 --- vendor/github.com/xanzy/go-gitlab/keys.go | 65 - vendor/github.com/xanzy/go-gitlab/labels.go | 305 --- .../go-gitlab/merge_request_approvals.go | 392 --- .../xanzy/go-gitlab/merge_requests.go | 902 ------- .../github.com/xanzy/go-gitlab/milestones.go | 269 -- .../github.com/xanzy/go-gitlab/namespaces.go | 122 - vendor/github.com/xanzy/go-gitlab/notes.go | 678 ----- .../xanzy/go-gitlab/notifications.go | 213 -- .../xanzy/go-gitlab/pages_domains.go | 196 -- .../xanzy/go-gitlab/pipeline_schedules.go | 346 --- .../xanzy/go-gitlab/pipeline_triggers.go | 231 -- .../github.com/xanzy/go-gitlab/pipelines.go | 347 --- .../xanzy/go-gitlab/project_badges.go | 207 -- .../xanzy/go-gitlab/project_import_export.go | 196 -- .../xanzy/go-gitlab/project_members.go | 234 -- .../xanzy/go-gitlab/project_mirror.go | 145 - .../xanzy/go-gitlab/project_snippets.go | 206 -- .../xanzy/go-gitlab/project_variables.go | 201 -- vendor/github.com/xanzy/go-gitlab/projects.go | 1632 ----------- .../xanzy/go-gitlab/protected_branches.go | 213 -- .../xanzy/go-gitlab/protected_tags.go | 145 - vendor/github.com/xanzy/go-gitlab/registry.go | 223 -- .../xanzy/go-gitlab/releaselinks.go | 176 -- vendor/github.com/xanzy/go-gitlab/releases.go | 212 -- .../xanzy/go-gitlab/repositories.go | 331 --- .../xanzy/go-gitlab/repository_files.go | 376 --- .../xanzy/go-gitlab/request_options.go | 30 - vendor/github.com/xanzy/go-gitlab/runners.go | 454 ---- vendor/github.com/xanzy/go-gitlab/search.go | 354 --- vendor/github.com/xanzy/go-gitlab/services.go | 1110 -------- vendor/github.com/xanzy/go-gitlab/settings.go | 409 --- vendor/github.com/xanzy/go-gitlab/snippets.go | 230 -- vendor/github.com/xanzy/go-gitlab/tags.go | 244 -- .../github.com/xanzy/go-gitlab/time_stats.go | 162 -- vendor/github.com/xanzy/go-gitlab/todos.go | 176 -- vendor/github.com/xanzy/go-gitlab/types.go | 444 --- vendor/github.com/xanzy/go-gitlab/users.go | 974 ------- vendor/github.com/xanzy/go-gitlab/validate.go | 40 - vendor/github.com/xanzy/go-gitlab/wikis.go | 204 -- .../gitlab-org/api/client-go}/.gitignore | 10 + .../gitlab-org/api/client-go/.gitlab-ci.yml | 205 ++ .../gitlab-org/api/client-go/.golangci.yml | 70 + .../gitlab-org/api/client-go/.tool-versions | 1 + .../gitlab-org/api/client-go/CONTRIBUTING.md | 58 + .../gitlab-org/api/client-go/Dangerfile | 11 + .../gitlab-org/api/client-go}/LICENSE | 4 +- .../gitlab-org/api/client-go/Makefile | 41 + .../gitlab-org/api/client-go/README.md | 181 ++ .../api/client-go/access_requests.go | 268 ++ .../api/client-go/alert_management.go | 175 ++ .../gitlab-org/api/client-go/appearance.go | 121 + .../api/client-go/application_statistics.go | 68 + .../gitlab-org/api/client-go}/applications.go | 52 +- .../gitlab-org/api/client-go/audit_events.go | 217 ++ .../gitlab-org/api/client-go/avatar.go | 72 + .../gitlab-org/api/client-go/award_emojis.go | 499 ++++ .../gitlab-org/api/client-go/boards.go | 384 +++ .../gitlab-org/api/client-go/branches.go | 195 ++ .../api/client-go/broadcast_messages.go | 197 ++ .../gitlab-org/api/client-go/bulk_imports.go | 80 + .../api/client-go/ci_yml_templates.go | 104 + .../api/client-go/client_options.go | 142 + .../api/client-go/cluster_agents.go | 309 +++ .../gitlab-org/api/client-go/commits.go | 634 +++++ .../api/client-go/container_registry.go | 326 +++ .../container_registry_protection_rules.go | 178 ++ .../gitlab-org/api/client-go/context.go | 33 + .../api/client-go}/custom_attributes.go | 96 +- .../api/client-go/database_migrations.go | 62 + .../gitlab-org/api/client-go/dependencies.go | 103 + .../api/client-go/dependency_list_export.go | 136 + .../api/client-go/dependency_proxy.go | 56 + .../gitlab-org/api/client-go/deploy_keys.go | 293 ++ .../gitlab-org/api/client-go/deploy_tokens.go | 304 +++ .../gitlab-org/api/client-go/deployments.go | 274 ++ .../client-go/deployments_merge_requests.go | 62 + .../gitlab-org/api/client-go/discussions.go | 1184 ++++++++ .../api/client-go/dockerfile_templates.go | 103 + .../gitlab-org/api/client-go/dora_metrics.go | 117 + .../gitlab-org/api/client-go/draft_notes.go | 248 ++ .../api/client-go/enterprise_users.go | 125 + .../gitlab-org/api/client-go/environments.go | 267 ++ .../gitlab-org/api/client-go/epic_issues.go | 181 ++ .../gitlab-org/api/client-go/epics.go | 310 +++ .../api/client-go/error_tracking.go | 209 ++ .../gitlab-org/api/client-go/event_parsing.go | 312 +++ .../api/client-go/event_systemhook_types.go | 249 ++ .../api/client-go/event_webhook_types.go | 1279 +++++++++ .../gitlab-org/api/client-go/events.go | 241 ++ .../api/client-go/external_status_checks.go | 233 ++ .../api/client-go/feature_flag_user_lists.go | 204 ++ .../gitlab-org/api/client-go/feature_flags.go | 172 ++ .../api/client-go}/freeze_periods.go | 84 +- .../api/client-go/generic_packages.go | 169 ++ .../gitlab-org/api/client-go/geo_nodes.go | 473 ++++ .../gitlab-org/api/client-go/geo_sites.go | 513 ++++ .../api/client-go}/gitignore_templates.go | 55 +- .../gitlab-org/api/client-go/gitlab.go | 1123 ++++++++ .../gitlab-org/api/client-go/graphql.go | 102 + .../api/client-go/group_access_tokens.go | 237 ++ .../api/client-go/group_activity_analytics.go | 148 + .../gitlab-org/api/client-go/group_badges.go | 251 ++ .../gitlab-org/api/client-go/group_boards.go | 370 +++ .../api/client-go}/group_clusters.go | 106 +- .../api/client-go/group_epic_boards.go | 113 + .../gitlab-org/api/client-go/group_hooks.go | 373 +++ .../api/client-go/group_import_export.go | 190 ++ .../api/client-go/group_iterations.go | 98 + .../gitlab-org/api/client-go/group_labels.go | 293 ++ .../api/client-go/group_markdown_uploads.go | 97 + .../gitlab-org/api/client-go/group_members.go | 455 ++++ .../api/client-go/group_milestones.go | 339 +++ .../client-go/group_protected_environments.go | 293 ++ .../api/client-go/group_releases.go | 69 + .../group_repository_storage_move.go | 206 ++ .../gitlab-org/api/client-go/group_scim.go | 142 + .../api/client-go/group_security_settings.go | 90 + .../api/client-go/group_serviceaccounts.go | 204 ++ .../api/client-go/group_ssh_certificates.go | 116 + .../api/client-go/group_variables.go | 243 ++ .../gitlab-org/api/client-go/group_wikis.go | 217 ++ .../gitlab-org/api/client-go/groups.go | 1313 +++++++++ .../gitlab-org/api/client-go/import.go | 278 ++ .../api/client-go}/instance_clusters.go | 76 +- .../api/client-go}/instance_variables.go | 81 +- .../gitlab-org/api/client-go/invites.go | 187 ++ .../gitlab-org/api/client-go/issue_links.go | 197 ++ .../gitlab-org/api/client-go/issues.go | 887 ++++++ .../api/client-go/issues_statistics.go | 197 ++ .../api/client-go/job_token_scope.go | 298 ++ .../gitlab-org/api/client-go/jobs.go | 609 +++++ .../gitlab-org/api/client-go/keys.go | 106 + .../gitlab-org/api/client-go/labels.go | 340 +++ .../gitlab-org/api/client-go}/license.go | 67 +- .../api/client-go}/license_templates.go | 58 +- .../gitlab-org/api/client-go/markdown.go | 55 + .../api/client-go/markdown_uploads.go | 168 ++ .../gitlab-org/api/client-go/member_roles.go | 215 ++ .../merge_request_approval_settings.go | 185 ++ .../api/client-go/merge_request_approvals.go | 420 +++ .../api/client-go/merge_requests.go | 1373 ++++++++++ .../gitlab-org/api/client-go/merge_trains.go | 184 ++ .../gitlab-org/api/client-go/metadata.go | 72 + .../gitlab-org/api/client-go/milestones.go | 289 ++ .../gitlab-org/api/client-go/namespaces.go | 186 ++ .../gitlab-org/api/client-go/notes.go | 743 +++++ .../gitlab-org/api/client-go/notifications.go | 255 ++ .../gitlab-org/api/client-go/packages.go | 273 ++ .../gitlab-org/api/client-go/pages.go | 141 + .../gitlab-org/api/client-go/pages_domains.go | 229 ++ .../gitlab-org/api/client-go/pagination.go | 159 ++ .../api/client-go/personal_access_tokens.go | 247 ++ .../api/client-go/pipeline_schedules.go | 409 +++ .../api/client-go/pipeline_triggers.go | 235 ++ .../gitlab-org/api/client-go/pipelines.go | 501 ++++ .../gitlab-org/api/client-go/plan_limits.go | 113 + .../api/client-go/project_access_tokens.go | 231 ++ .../api/client-go/project_badges.go | 243 ++ .../api/client-go}/project_clusters.go | 106 +- .../api/client-go/project_feature_flags.go | 258 ++ .../api/client-go/project_import_export.go | 237 ++ .../api/client-go/project_iterations.go | 98 + .../api/client-go/project_markdown_uploads.go | 134 + .../api/client-go/project_members.go | 272 ++ .../api/client-go/project_mirror.go | 240 ++ .../project_repository_storage_move.go | 212 ++ .../client-go/project_security_settings.go | 123 + .../api/client-go/project_snippets.go | 228 ++ .../api/client-go/project_templates.go | 119 + .../api/client-go/project_variables.go | 246 ++ .../api/client-go/project_vulnerabilities.go | 170 ++ .../gitlab-org/api/client-go/projects.go | 2356 ++++++++++++++++ .../api/client-go/protected_branches.go | 247 ++ .../api/client-go/protected_environments.go | 294 ++ .../api/client-go/protected_tags.go | 187 ++ .../gitlab-org/api/client-go/releaselinks.go | 213 ++ .../gitlab-org/api/client-go/releases.go | 336 +++ .../gitlab-org/api/client-go/repositories.go | 439 +++ .../api/client-go/repository_files.go | 446 +++ .../api/client-go/repository_submodules.go | 101 + .../api/client-go/request_options.go | 138 + .../api/client-go/resource_group.go | 176 ++ .../client-go/resource_iteration_events.go | 131 + .../api/client-go}/resource_label_events.go | 101 +- .../client-go/resource_milestone_events.go | 166 ++ .../api/client-go/resource_state_events.go | 165 ++ .../api/client-go/resource_weight_events.go | 88 + .../gitlab-org/api/client-go/runners.go | 649 +++++ .../gitlab-org/api/client-go/search.go | 381 +++ .../gitlab-org/api/client-go/secure_files.go | 233 ++ .../gitlab-org/api/client-go/services.go | 2387 +++++++++++++++++ .../gitlab-org/api/client-go/settings.go | 1000 +++++++ .../api/client-go}/sidekiq_metrics.go | 63 +- .../snippet_repository_storage_move.go | 217 ++ .../gitlab-org/api/client-go/snippets.go | 330 +++ .../gitlab-org/api/client-go}/strings.go | 11 +- .../gitlab-org/api/client-go}/system_hooks.go | 89 +- .../gitlab-org/api/client-go/tags.go | 237 ++ .../gitlab-org/api/client-go/time_stats.go | 180 ++ .../gitlab-org/api/client-go/todos.go | 174 ++ .../gitlab-org/api/client-go/topics.go | 234 ++ .../gitlab-org/api/client-go/types.go | 900 +++++++ .../gitlab-org/api/client-go/usage_data.go | 203 ++ .../gitlab-org/api/client-go/users.go | 1740 ++++++++++++ .../gitlab-org/api/client-go/validate.go | 149 + .../gitlab-org/api/client-go}/version.go | 36 +- .../gitlab-org/api/client-go/wikis.go | 277 ++ 247 files changed, 47394 insertions(+), 24628 deletions(-) delete mode 100644 vendor/github.com/xanzy/go-gitlab/.travis.yml delete mode 100644 vendor/github.com/xanzy/go-gitlab/CHANGELOG.md delete mode 100644 vendor/github.com/xanzy/go-gitlab/README.md delete mode 100644 vendor/github.com/xanzy/go-gitlab/access_requests.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/award_emojis.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/boards.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/branches.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/broadcast_messages.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/client_options.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/commits.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/deploy_keys.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/deploy_tokens.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/deployments.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/discussions.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/environments.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/epic_issues.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/epics.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/event_parsing.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/event_webhook_types.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/events.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/feature_flags.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/gitlab.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_badges.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_boards.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_hooks.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_labels.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_members.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_milestones.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/group_variables.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/groups.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/issue_links.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/issues.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/issues_statistics.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/jobs.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/keys.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/labels.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/merge_requests.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/milestones.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/namespaces.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/notes.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/notifications.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/pages_domains.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/pipelines.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_badges.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_import_export.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_members.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_mirror.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_snippets.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/project_variables.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/projects.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/protected_branches.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/protected_tags.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/registry.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/releaselinks.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/releases.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/repositories.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/repository_files.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/request_options.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/runners.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/search.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/services.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/settings.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/snippets.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/tags.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/time_stats.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/todos.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/types.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/users.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/validate.go delete mode 100644 vendor/github.com/xanzy/go-gitlab/wikis.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/.gitignore (78%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/.gitlab-ci.yml create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/.golangci.yml create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/.tool-versions create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/CONTRIBUTING.md create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/Dangerfile rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/LICENSE (99%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/Makefile create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/README.md create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/access_requests.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/alert_management.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/appearance.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/application_statistics.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/applications.go (63%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/audit_events.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/avatar.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/award_emojis.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/boards.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/branches.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/broadcast_messages.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/bulk_imports.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/ci_yml_templates.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/client_options.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/cluster_agents.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/commits.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/container_registry.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/container_registry_protection_rules.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/context.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/custom_attributes.go (59%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/database_migrations.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/dependencies.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/dependency_list_export.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/dependency_proxy.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/deploy_keys.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/deploy_tokens.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/deployments.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/deployments_merge_requests.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/discussions.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/dockerfile_templates.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/dora_metrics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/draft_notes.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/enterprise_users.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/environments.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/epic_issues.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/epics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/error_tracking.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/event_parsing.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/event_systemhook_types.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/event_webhook_types.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/events.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/external_status_checks.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/feature_flag_user_lists.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/feature_flags.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/freeze_periods.go (53%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/generic_packages.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/geo_nodes.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/geo_sites.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/gitignore_templates.go (51%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/gitlab.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/graphql.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_access_tokens.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_activity_analytics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_badges.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_boards.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/group_clusters.go (57%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_epic_boards.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_hooks.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_import_export.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_iterations.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_labels.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_markdown_uploads.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_members.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_milestones.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_protected_environments.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_releases.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_repository_storage_move.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_scim.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_security_settings.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_serviceaccounts.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_ssh_certificates.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_variables.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_wikis.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/groups.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/import.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/instance_clusters.go (56%) rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/instance_variables.go (63%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/invites.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/issue_links.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/issues.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/issues_statistics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/job_token_scope.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/jobs.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/keys.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/labels.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/license.go (62%) rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/license_templates.go (53%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/markdown.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/markdown_uploads.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/member_roles.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approval_settings.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approvals.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/merge_requests.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/merge_trains.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/metadata.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/milestones.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/namespaces.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/notes.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/notifications.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/packages.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pages.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pages_domains.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pagination.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/personal_access_tokens.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pipeline_schedules.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pipeline_triggers.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/pipelines.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/plan_limits.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_access_tokens.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_badges.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/project_clusters.go (61%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_feature_flags.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_import_export.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_iterations.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_markdown_uploads.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_members.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_mirror.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_repository_storage_move.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_security_settings.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_snippets.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_templates.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_variables.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_vulnerabilities.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/projects.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/protected_branches.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/protected_environments.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/protected_tags.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/releaselinks.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/releases.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/repositories.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/repository_files.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/repository_submodules.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/request_options.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/resource_group.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/resource_iteration_events.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/resource_label_events.go (52%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/resource_milestone_events.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/resource_state_events.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/resource_weight_events.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/runners.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/search.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/secure_files.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/services.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/settings.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/sidekiq_metrics.go (63%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/snippet_repository_storage_move.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/snippets.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/strings.go (89%) rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/system_hooks.go (56%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/tags.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/time_stats.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/todos.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/topics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/types.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/usage_data.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/users.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/validate.go rename vendor/{github.com/xanzy/go-gitlab => gitlab.com/gitlab-org/api/client-go}/version.go (57%) create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/wikis.go diff --git a/go.mod b/go.mod index 02ec13613..6ed35194f 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/hashicorp/golang-lru v1.0.2 github.com/kelseyhightower/envconfig v1.4.0 github.com/stretchr/testify v1.11.1 - github.com/xanzy/go-gitlab v0.39.0 + gitlab.com/gitlab-org/api/client-go v0.129.0 go.uber.org/zap v1.27.0 gopkg.in/go-playground/webhooks.v5 v5.15.0 k8s.io/api v0.33.4 diff --git a/go.sum b/go.sum index 5440b74b6..6b91b3b56 100644 --- a/go.sum +++ b/go.sum @@ -78,7 +78,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI= github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -90,13 +89,10 @@ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrR github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= diff --git a/pkg/client/gitlab/webhook_client.go b/pkg/client/gitlab/webhook_client.go index 4ed44922e..fb33d435a 100644 --- a/pkg/client/gitlab/webhook_client.go +++ b/pkg/client/gitlab/webhook_client.go @@ -27,7 +27,7 @@ import ( "knative.dev/eventing-gitlab/pkg/secret" "knative.dev/pkg/apis" - gitlab "github.com/xanzy/go-gitlab" + gitlab "gitlab.com/gitlab-org/api/client-go" ) // WebhookClient is a client which can interact with the webhook configuration @@ -75,7 +75,7 @@ func (c *webhookClient) Add(eventTypes []string, webhookURL *apis.URL, tls bool) enabled := true hookOptions := gitlab.AddProjectHookOptions{ - URL: gitlab.String(webhookURL.String()), + URL: gitlab.Ptr(webhookURL.String()), EnableSSLVerification: &tls, Token: c.secretToken, } @@ -121,7 +121,7 @@ func (c *webhookClient) Edit(hookID int, eventTypes []string, webhookURL *apis.U enabled, disabled := true, false hookOptions := gitlab.EditProjectHookOptions{ - URL: gitlab.String(webhookURL.String()), + URL: gitlab.Ptr(webhookURL.String()), EnableSSLVerification: &tls, Token: c.secretToken, diff --git a/pkg/reconciler/source/gitlabsource.go b/pkg/reconciler/source/gitlabsource.go index 770e22b63..65116a77b 100644 --- a/pkg/reconciler/source/gitlabsource.go +++ b/pkg/reconciler/source/gitlabsource.go @@ -38,7 +38,7 @@ import ( servingclientv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1" servinglisters "knative.dev/serving/pkg/client/listers/serving/v1" - gogitlab "github.com/xanzy/go-gitlab" + gogitlab "gitlab.com/gitlab-org/api/client-go" "knative.dev/eventing-gitlab/pkg/apis/sources/v1alpha1" "knative.dev/eventing-gitlab/pkg/client/gitlab" diff --git a/vendor/github.com/xanzy/go-gitlab/.travis.yml b/vendor/github.com/xanzy/go-gitlab/.travis.yml deleted file mode 100644 index 79772fc50..000000000 --- a/vendor/github.com/xanzy/go-gitlab/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: go -arch: - - amd64 - - ppc64le - -go: - - 1.13.x - - 1.14.x - - master - -stages: - - lint - - test - -jobs: - include: - - stage: lint - script: - - go get golang.org/x/lint/golint - - golint -set_exit_status - - go vet -v - - stage: test - script: - - go test -v - -matrix: - allow_failures: - - go: master - fast_finish: true diff --git a/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md b/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md deleted file mode 100644 index 29e93fff7..000000000 --- a/vendor/github.com/xanzy/go-gitlab/CHANGELOG.md +++ /dev/null @@ -1,27 +0,0 @@ -go-github CHANGELOG -=================== - -0.6.0 ------ -- Add support for the V4 Gitlab API. This means the older V3 API is no longer fully supported - with this version. If you still need that version, please use the `f-api-v3` branch. - -0.4.0 ------ -- Add support to use [`sudo`](https://docs.gitlab.com/ce/api/README.html#sudo) for all API calls. -- Add support for the Notification Settings API. -- Add support for the Time Tracking API. -- Make sure that the error response correctly outputs any returned errors. -- And a reasonable number of smaller enhanchements and bugfixes. - -0.3.0 ------ -- Moved the tags related API calls to their own service, following the Gitlab API structure. - -0.2.0 ------ -- Convert all Option structs to use pointers for their fields. - -0.1.0 ------ -- Initial release. diff --git a/vendor/github.com/xanzy/go-gitlab/README.md b/vendor/github.com/xanzy/go-gitlab/README.md deleted file mode 100644 index da5cf7b09..000000000 --- a/vendor/github.com/xanzy/go-gitlab/README.md +++ /dev/null @@ -1,191 +0,0 @@ -# go-gitlab - -A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way - -[![Build Status](https://travis-ci.org/xanzy/go-gitlab.svg?branch=master)](https://travis-ci.org/xanzy/go-gitlab) -[![GitHub license](https://img.shields.io/github/license/xanzy/go-gitlab.svg)](https://github.com/xanzy/go-gitlab/blob/master/LICENSE) -[![Sourcegraph](https://sourcegraph.com/github.com/xanzy/go-gitlab/-/badge.svg)](https://sourcegraph.com/github.com/xanzy/go-gitlab?badge) -[![GoDoc](https://godoc.org/github.com/xanzy/go-gitlab?status.svg)](https://godoc.org/github.com/xanzy/go-gitlab) -[![Go Report Card](https://goreportcard.com/badge/github.com/xanzy/go-gitlab)](https://goreportcard.com/report/github.com/xanzy/go-gitlab) -[![GitHub issues](https://img.shields.io/github/issues/xanzy/go-gitlab.svg)](https://github.com/xanzy/go-gitlab/issues) - -## NOTE - -Release v0.6.0 (released on 25-08-2017) no longer supports the older V3 Gitlab API. If -you need V3 support, please use the `f-api-v3` branch. This release contains some backwards -incompatible changes that were needed to fully support the V4 Gitlab API. - -## Coverage - -This API client package covers most of the existing Gitlab API calls and is updated regularly -to add new and/or missing endpoints. Currently the following services are supported: - -- [x] Applications -- [x] Award Emojis -- [x] Branches -- [x] Broadcast Messages -- [x] Commits -- [x] Container Registry -- [x] Custom Attributes -- [x] Deploy Keys -- [x] Deployments -- [ ] Discussions (threaded comments) -- [x] Environments -- [ ] Epic Issues -- [ ] Epics -- [x] Events -- [x] Feature Flags -- [ ] Geo Nodes -- [x] GitLab CI Config Templates -- [x] Gitignores Templates -- [x] Group Access Requests -- [x] Group Issue Boards -- [x] Group Members -- [x] Group Milestones -- [x] Group-Level Variables -- [x] Groups -- [x] Instance Clusters -- [x] Issue Boards -- [x] Issues -- [x] Jobs -- [x] Keys -- [x] Labels -- [x] License -- [x] Merge Request Approvals -- [x] Merge Requests -- [x] Namespaces -- [x] Notes (comments) -- [x] Notification Settings -- [x] Open Source License Templates -- [x] Pages Domains -- [x] Pipeline Schedules -- [x] Pipeline Triggers -- [x] Pipelines -- [x] Project Access Requests -- [x] Project Badges -- [x] Project Clusters -- [x] Project Import/export -- [x] Project Members -- [x] Project Milestones -- [x] Project Snippets -- [x] Project-Level Variables -- [x] Projects (including setting Webhooks) -- [x] Protected Branches -- [x] Protected Tags -- [x] Repositories -- [x] Repository Files -- [x] Runners -- [x] Search -- [x] Services -- [x] Settings -- [x] Sidekiq Metrics -- [x] System Hooks -- [x] Tags -- [x] Todos -- [x] Users -- [x] Validate CI Configuration -- [x] Version -- [x] Wikis - -## Usage - -```go -import "github.com/xanzy/go-gitlab" -``` - -Construct a new GitLab client, then use the various services on the client to -access different parts of the GitLab API. For example, to list all -users: - -```go -git, err := gitlab.NewClient("yourtokengoeshere") -if err != nil { - log.Fatalf("Failed to create client: %v", err) -} -users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{}) -``` - -There are a few `With...` option functions that can be used to customize -the API client. For example, to set a custom base URL: - -```go -git, err := gitlab.NewClient("yourtokengoeshere", gitlab.WithBaseURL("https://git.mydomain.com/api/v4")) -if err != nil { - log.Fatalf("Failed to create client: %v", err) -} -users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{}) -``` - -Some API methods have optional parameters that can be passed. For example, -to list all projects for user "svanharmelen": - -```go -git := gitlab.NewClient("yourtokengoeshere") -opt := &ListProjectsOptions{Search: gitlab.String("svanharmelen")} -projects, _, err := git.Projects.ListProjects(opt) -``` - -### Examples - -The [examples](https://github.com/xanzy/go-gitlab/tree/master/examples) directory -contains a couple for clear examples, of which one is partially listed here as well: - -```go -package main - -import ( - "log" - - "github.com/xanzy/go-gitlab" -) - -func main() { - git, err := gitlab.NewClient("yourtokengoeshere") - if err != nil { - log.Fatalf("Failed to create client: %v", err) - } - - // Create new project - p := &gitlab.CreateProjectOptions{ - Name: gitlab.String("My Project"), - Description: gitlab.String("Just a test project to play with"), - MergeRequestsEnabled: gitlab.Bool(true), - SnippetsEnabled: gitlab.Bool(true), - Visibility: gitlab.Visibility(gitlab.PublicVisibility), - } - project, _, err := git.Projects.CreateProject(p) - if err != nil { - log.Fatal(err) - } - - // Add a new snippet - s := &gitlab.CreateProjectSnippetOptions{ - Title: gitlab.String("Dummy Snippet"), - FileName: gitlab.String("snippet.go"), - Content: gitlab.String("package main...."), - Visibility: gitlab.Visibility(gitlab.PublicVisibility), - } - _, _, err = git.ProjectSnippets.CreateSnippet(project.ID, s) - if err != nil { - log.Fatal(err) - } -} -``` - -For complete usage of go-gitlab, see the full [package docs](https://godoc.org/github.com/xanzy/go-gitlab). - -## ToDo - -- The biggest thing this package still needs is tests :disappointed: - -## Issues - -- If you have an issue: report it on the [issue tracker](https://github.com/xanzy/go-gitlab/issues) - -## Author - -Sander van Harmelen () - -## License - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at diff --git a/vendor/github.com/xanzy/go-gitlab/access_requests.go b/vendor/github.com/xanzy/go-gitlab/access_requests.go deleted file mode 100644 index fa00d75db..000000000 --- a/vendor/github.com/xanzy/go-gitlab/access_requests.go +++ /dev/null @@ -1,236 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// AccessRequest represents a access request for a group or project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html -type AccessRequest struct { - ID int `json:"id"` - Username string `json:"username"` - Name string `json:"name"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - RequestedAt *time.Time `json:"requested_at"` - AccessLevel AccessLevelValue `json:"access_level"` -} - -// AccessRequestsService handles communication with the project/group -// access requests related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/access_requests.html -type AccessRequestsService struct { - client *Client -} - -// ListAccessRequestsOptions represents the available -// ListProjectAccessRequests() or ListGroupAccessRequests() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project -type ListAccessRequestsOptions ListOptions - -// ListProjectAccessRequests gets a list of access requests -// viewable by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project -func (s *AccessRequestsService) ListProjectAccessRequests(pid interface{}, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/access_requests", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ars []*AccessRequest - resp, err := s.client.Do(req, &ars) - if err != nil { - return nil, resp, err - } - - return ars, resp, err -} - -// ListGroupAccessRequests gets a list of access requests -// viewable by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project -func (s *AccessRequestsService) ListGroupAccessRequests(gid interface{}, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/access_requests", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ars []*AccessRequest - resp, err := s.client.Do(req, &ars) - if err != nil { - return nil, resp, err - } - - return ars, resp, err -} - -// RequestProjectAccess requests access for the authenticated user -// to a group or project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#request-access-to-a-group-or-project -func (s *AccessRequestsService) RequestProjectAccess(pid interface{}, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/access_requests", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - ar := new(AccessRequest) - resp, err := s.client.Do(req, ar) - if err != nil { - return nil, resp, err - } - - return ar, resp, err -} - -// RequestGroupAccess requests access for the authenticated user -// to a group or project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#request-access-to-a-group-or-project -func (s *AccessRequestsService) RequestGroupAccess(gid interface{}, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/access_requests", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - ar := new(AccessRequest) - resp, err := s.client.Do(req, ar) - if err != nil { - return nil, resp, err - } - - return ar, resp, err -} - -// ApproveAccessRequestOptions represents the available -// ApproveProjectAccessRequest() and ApproveGroupAccessRequest() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request -type ApproveAccessRequestOptions struct { - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` -} - -// ApproveProjectAccessRequest approves an access request for the given user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request -func (s *AccessRequestsService) ApproveProjectAccessRequest(pid interface{}, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/access_requests/%d/approve", pathEscape(project), user) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ar := new(AccessRequest) - resp, err := s.client.Do(req, ar) - if err != nil { - return nil, resp, err - } - - return ar, resp, err -} - -// ApproveGroupAccessRequest approves an access request for the given user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request -func (s *AccessRequestsService) ApproveGroupAccessRequest(gid interface{}, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/access_requests/%d/approve", pathEscape(group), user) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ar := new(AccessRequest) - resp, err := s.client.Do(req, ar) - if err != nil { - return nil, resp, err - } - - return ar, resp, err -} - -// DenyProjectAccessRequest denies an access request for the given user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#deny-an-access-request -func (s *AccessRequestsService) DenyProjectAccessRequest(pid interface{}, user int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/access_requests/%d", pathEscape(project), user) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DenyGroupAccessRequest denies an access request for the given user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/access_requests.html#deny-an-access-request -func (s *AccessRequestsService) DenyGroupAccessRequest(gid interface{}, user int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/access_requests/%d", pathEscape(group), user) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/award_emojis.go b/vendor/github.com/xanzy/go-gitlab/award_emojis.go deleted file mode 100644 index d36547276..000000000 --- a/vendor/github.com/xanzy/go-gitlab/award_emojis.go +++ /dev/null @@ -1,467 +0,0 @@ -// -// Copyright 2017, Arkbriar -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// AwardEmojiService handles communication with the emoji awards related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html -type AwardEmojiService struct { - client *Client -} - -// AwardEmoji represents a GitLab Award Emoji. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html -type AwardEmoji struct { - ID int `json:"id"` - Name string `json:"name"` - User struct { - Name string `json:"name"` - Username string `json:"username"` - ID int `json:"id"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"user"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - AwardableID int `json:"awardable_id"` - AwardableType string `json:"awardable_type"` -} - -const ( - awardMergeRequest = "merge_requests" - awardIssue = "issues" - awardSnippets = "snippets" -) - -// ListAwardEmojiOptions represents the available options for listing emoji -// for each resources -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html -type ListAwardEmojiOptions ListOptions - -// ListMergeRequestAwardEmoji gets a list of all award emoji on the merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) ListMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...) -} - -// ListIssueAwardEmoji gets a list of all award emoji on the issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) ListIssueAwardEmoji(pid interface{}, issueIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmoji(pid, awardIssue, issueIID, opt, options...) -} - -// ListSnippetAwardEmoji gets a list of all award emoji on the snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) ListSnippetAwardEmoji(pid interface{}, snippetID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmoji(pid, awardSnippets, snippetID, opt, options...) -} - -func (s *AwardEmojiService) listAwardEmoji(pid interface{}, resource string, resourceID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/award_emoji", - pathEscape(project), - resource, - resourceID, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var as []*AwardEmoji - resp, err := s.client.Do(req, &as) - if err != nil { - return nil, resp, err - } - - return as, resp, err -} - -// GetMergeRequestAwardEmoji get an award emoji from merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) GetMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...) -} - -// GetIssueAwardEmoji get an award emoji from issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) GetIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getAwardEmoji(pid, awardIssue, issueIID, awardID, options...) -} - -// GetSnippetAwardEmoji get an award emoji from snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji -func (s *AwardEmojiService) GetSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getAwardEmoji(pid, awardSnippets, snippetID, awardID, options...) -} - -func (s *AwardEmojiService) getAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", - pathEscape(project), - resource, - resourceID, - awardID, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - a := new(AwardEmoji) - resp, err := s.client.Do(req, &a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// CreateAwardEmojiOptions represents the available options for awarding emoji -// for a resource -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji -type CreateAwardEmojiOptions struct { - Name string `json:"name"` -} - -// CreateMergeRequestAwardEmoji get an award emoji from merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji -func (s *AwardEmojiService) CreateMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...) -} - -// CreateIssueAwardEmoji get an award emoji from issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji -func (s *AwardEmojiService) CreateIssueAwardEmoji(pid interface{}, issueIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmoji(pid, awardIssue, issueIID, opt, options...) -} - -// CreateSnippetAwardEmoji get an award emoji from snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji -func (s *AwardEmojiService) CreateSnippetAwardEmoji(pid interface{}, snippetID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmoji(pid, awardSnippets, snippetID, opt, options...) -} - -func (s *AwardEmojiService) createAwardEmoji(pid interface{}, resource string, resourceID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/award_emoji", - pathEscape(project), - resource, - resourceID, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - a := new(AwardEmoji) - resp, err := s.client.Do(req, &a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// DeleteIssueAwardEmoji delete award emoji on an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note -func (s *AwardEmojiService) DeleteIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmoji(pid, awardMergeRequest, issueIID, awardID, options...) -} - -// DeleteMergeRequestAwardEmoji delete award emoji on a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note -func (s *AwardEmojiService) DeleteMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...) -} - -// DeleteSnippetAwardEmoji delete award emoji on a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note -func (s *AwardEmojiService) DeleteSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmoji(pid, awardMergeRequest, snippetID, awardID, options...) -} - -// DeleteAwardEmoji Delete an award emoji on the specified resource. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#delete-an-award-emoji -func (s *AwardEmojiService) deleteAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", pathEscape(project), resource, - resourceID, awardID) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - return s.client.Do(req, nil) -} - -// ListIssuesAwardEmojiOnNote gets a list of all award emoji on a note from the -// issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) ListIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...) -} - -// ListMergeRequestAwardEmojiOnNote gets a list of all award emoji on a note -// from the merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) ListMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...) -} - -// ListSnippetAwardEmojiOnNote gets a list of all award emoji on a note from the -// snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) ListSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - return s.listAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...) -} - -func (s *AwardEmojiService) listAwardEmojiOnNote(pid interface{}, resources string, ressourceID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", pathEscape(project), resources, - ressourceID, noteID) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var as []*AwardEmoji - resp, err := s.client.Do(req, &as) - if err != nil { - return nil, resp, err - } - - return as, resp, err -} - -// GetIssuesAwardEmojiOnNote gets an award emoji on a note from an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) GetIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getSingleNoteAwardEmoji(pid, awardIssue, issueID, noteID, awardID, options...) -} - -// GetMergeRequestAwardEmojiOnNote gets an award emoji on a note from a -// merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) GetMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getSingleNoteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, noteID, awardID, - options...) -} - -// GetSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) GetSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.getSingleNoteAwardEmoji(pid, awardSnippets, snippetIID, noteID, awardID, options...) -} - -func (s *AwardEmojiService) getSingleNoteAwardEmoji(pid interface{}, ressource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d", - pathEscape(project), - ressource, - resourceID, - noteID, - awardID, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - a := new(AwardEmoji) - resp, err := s.client.Do(req, &a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// CreateIssuesAwardEmojiOnNote gets an award emoji on a note from an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) CreateIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...) -} - -// CreateMergeRequestAwardEmojiOnNote gets an award emoji on a note from a -// merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) CreateMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...) -} - -// CreateSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) CreateSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - return s.createAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...) -} - -// CreateAwardEmojiOnNote award emoji on a note. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note -func (s *AwardEmojiService) createAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", - pathEscape(project), - resource, - resourceID, - noteID, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - a := new(AwardEmoji) - resp, err := s.client.Do(req, &a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// DeleteIssuesAwardEmojiOnNote deletes an award emoji on a note from an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) DeleteIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmojiOnNote(pid, awardIssue, issueID, noteID, awardID, options...) -} - -// DeleteMergeRequestAwardEmojiOnNote deletes an award emoji on a note from a -// merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) DeleteMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, awardID, - options...) -} - -// DeleteSnippetAwardEmojiOnNote deletes an award emoji on a note from a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes -func (s *AwardEmojiService) DeleteSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { - return s.deleteAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, awardID, options...) -} - -func (s *AwardEmojiService) deleteAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d", - pathEscape(project), - resource, - resourceID, - noteID, - awardID, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/boards.go b/vendor/github.com/xanzy/go-gitlab/boards.go deleted file mode 100644 index eed377c8d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/boards.go +++ /dev/null @@ -1,344 +0,0 @@ -// -// Copyright 2015, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// IssueBoardsService handles communication with the issue board related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html -type IssueBoardsService struct { - client *Client -} - -// IssueBoard represents a GitLab issue board. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html -type IssueBoard struct { - ID int `json:"id"` - Name string `json:"name"` - Project *Project `json:"project"` - Milestone *Milestone `json:"milestone"` - Lists []*BoardList `json:"lists"` -} - -func (b IssueBoard) String() string { - return Stringify(b) -} - -// BoardList represents a GitLab board list. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html -type BoardList struct { - ID int `json:"id"` - Label *Label `json:"label"` - Position int `json:"position"` -} - -func (b BoardList) String() string { - return Stringify(b) -} - -// CreateIssueBoardOptions represents the available CreateIssueBoard() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter -type CreateIssueBoardOptions struct { - Name *string `url:"name" json:"name"` -} - -// CreateIssueBoard creates a new issue board. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter -func (s *IssueBoardsService) CreateIssueBoard(pid interface{}, opt *CreateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - board := new(IssueBoard) - resp, err := s.client.Do(req, board) - if err != nil { - return nil, resp, err - } - - return board, resp, err -} - -// UpdateIssueBoardOptions represents the available UpdateIssueBoard() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#update-a-board-starter -type UpdateIssueBoardOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - Weight *int `url:"weight,omitempty" json:"weight,omitempty"` -} - -// UpdateIssueBoard update an issue board. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter -func (s *IssueBoardsService) UpdateIssueBoard(pid interface{}, board int, opt *UpdateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - is := new(IssueBoard) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// DeleteIssueBoard deletes an issue board. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#delete-a-board-starter -func (s *IssueBoardsService) DeleteIssueBoard(pid interface{}, board int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListIssueBoardsOptions represents the available ListIssueBoards() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board -type ListIssueBoardsOptions ListOptions - -// ListIssueBoards gets a list of all issue boards in a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board -func (s *IssueBoardsService) ListIssueBoards(pid interface{}, opt *ListIssueBoardsOptions, options ...RequestOptionFunc) ([]*IssueBoard, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var is []*IssueBoard - resp, err := s.client.Do(req, &is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// GetIssueBoard gets a single issue board of a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board -func (s *IssueBoardsService) GetIssueBoard(pid interface{}, board int, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ib := new(IssueBoard) - resp, err := s.client.Do(req, ib) - if err != nil { - return nil, resp, err - } - - return ib, resp, err -} - -// GetIssueBoardListsOptions represents the available GetIssueBoardLists() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists -type GetIssueBoardListsOptions ListOptions - -// GetIssueBoardLists gets a list of the issue board's lists. Does not include -// backlog and closed lists. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists -func (s *IssueBoardsService) GetIssueBoardLists(pid interface{}, board int, opt *GetIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d/lists", pathEscape(project), board) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var bl []*BoardList - resp, err := s.client.Do(req, &bl) - if err != nil { - return nil, resp, err - } - - return bl, resp, err -} - -// GetIssueBoardList gets a single issue board list. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board-list -func (s *IssueBoardsService) GetIssueBoardList(pid interface{}, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", - pathEscape(project), - board, - list, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - bl := new(BoardList) - resp, err := s.client.Do(req, bl) - if err != nil { - return nil, resp, err - } - - return bl, resp, err -} - -// CreateIssueBoardListOptions represents the available CreateIssueBoardList() -// options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list -type CreateIssueBoardListOptions struct { - LabelID *int `url:"label_id" json:"label_id"` -} - -// CreateIssueBoardList creates a new issue board list. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list -func (s *IssueBoardsService) CreateIssueBoardList(pid interface{}, board int, opt *CreateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d/lists", pathEscape(project), board) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - bl := new(BoardList) - resp, err := s.client.Do(req, bl) - if err != nil { - return nil, resp, err - } - - return bl, resp, err -} - -// UpdateIssueBoardListOptions represents the available UpdateIssueBoardList() -// options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list -type UpdateIssueBoardListOptions struct { - Position *int `url:"position" json:"position"` -} - -// UpdateIssueBoardList updates the position of an existing issue board list. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list -func (s *IssueBoardsService) UpdateIssueBoardList(pid interface{}, board, list int, opt *UpdateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", - pathEscape(project), - board, - list, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - bl := new(BoardList) - resp, err := s.client.Do(req, bl) - if err != nil { - return nil, resp, err - } - - return bl, resp, err -} - -// DeleteIssueBoardList soft deletes an issue board list. Only for admins and -// project owners. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/boards.html#delete-a-board-list -func (s *IssueBoardsService) DeleteIssueBoardList(pid interface{}, board, list int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", - pathEscape(project), - board, - list, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/branches.go b/vendor/github.com/xanzy/go-gitlab/branches.go deleted file mode 100644 index df5facd7d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/branches.go +++ /dev/null @@ -1,244 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" -) - -// BranchesService handles communication with the branch related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html -type BranchesService struct { - client *Client -} - -// Branch represents a GitLab branch. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html -type Branch struct { - Commit *Commit `json:"commit"` - Name string `json:"name"` - Protected bool `json:"protected"` - Merged bool `json:"merged"` - Default bool `json:"default"` - CanPush bool `json:"can_push"` - DevelopersCanPush bool `json:"developers_can_push"` - DevelopersCanMerge bool `json:"developers_can_merge"` - WebURL string `json:"web_url"` -} - -func (b Branch) String() string { - return Stringify(b) -} - -// ListBranchesOptions represents the available ListBranches() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches -type ListBranchesOptions struct { - ListOptions - Search *string `url:"search,omitempty" json:"search,omitempty"` -} - -// ListBranches gets a list of repository branches from a project, sorted by -// name alphabetically. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches -func (s *BranchesService) ListBranches(pid interface{}, opts *ListBranchesOptions, options ...RequestOptionFunc) ([]*Branch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, nil, err - } - - var b []*Branch - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// GetBranch gets a single project repository branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#get-single-repository-branch -func (s *BranchesService) GetBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches/%s", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - b := new(Branch) - resp, err := s.client.Do(req, b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// ProtectBranchOptions represents the available ProtectBranch() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch -type ProtectBranchOptions struct { - DevelopersCanPush *bool `url:"developers_can_push,omitempty" json:"developers_can_push,omitempty"` - DevelopersCanMerge *bool `url:"developers_can_merge,omitempty" json:"developers_can_merge,omitempty"` -} - -// ProtectBranch protects a single project repository branch. This is an -// idempotent function, protecting an already protected repository branch -// still returns a 200 OK status code. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch -func (s *BranchesService) ProtectBranch(pid interface{}, branch string, opts *ProtectBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches/%s/protect", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("PUT", u, opts, options) - if err != nil { - return nil, nil, err - } - - b := new(Branch) - resp, err := s.client.Do(req, b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// UnprotectBranch unprotects a single project repository branch. This is an -// idempotent function, unprotecting an already unprotected repository branch -// still returns a 200 OK status code. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#unprotect-repository-branch -func (s *BranchesService) UnprotectBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches/%s/unprotect", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("PUT", u, nil, options) - if err != nil { - return nil, nil, err - } - - b := new(Branch) - resp, err := s.client.Do(req, b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// CreateBranchOptions represents the available CreateBranch() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch -type CreateBranchOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` -} - -// CreateBranch creates branch from commit SHA or existing branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch -func (s *BranchesService) CreateBranch(pid interface{}, opt *CreateBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - b := new(Branch) - resp, err := s.client.Do(req, b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// DeleteBranch deletes an existing branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#delete-repository-branch -func (s *BranchesService) DeleteBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/repository/branches/%s", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteMergedBranches deletes all branches that are merged into the project's default branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/branches.html#delete-merged-branches -func (s *BranchesService) DeleteMergedBranches(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/repository/merged_branches", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/broadcast_messages.go b/vendor/github.com/xanzy/go-gitlab/broadcast_messages.go deleted file mode 100644 index 08247103f..000000000 --- a/vendor/github.com/xanzy/go-gitlab/broadcast_messages.go +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// BroadcastMessagesService handles communication with the broadcast -// messages methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/broadcast_messages.html -type BroadcastMessagesService struct { - client *Client -} - -// BroadcastMessage represents a GitLab issue board. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages -type BroadcastMessage struct { - Message string `json:"message"` - StartsAt *time.Time `json:"starts_at"` - EndsAt *time.Time `json:"ends_at"` - Color string `json:"color"` - Font string `json:"font"` - ID int `json:"id"` - Active bool `json:"active"` -} - -// ListBroadcastMessagesOptions represents the available ListBroadcastMessages() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages -type ListBroadcastMessagesOptions ListOptions - -// ListBroadcastMessages gets a list of all broadcasted messages. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages -func (s *BroadcastMessagesService) ListBroadcastMessages(opt *ListBroadcastMessagesOptions, options ...RequestOptionFunc) ([]*BroadcastMessage, *Response, error) { - req, err := s.client.NewRequest("GET", "broadcast_messages", opt, options) - if err != nil { - return nil, nil, err - } - - var bs []*BroadcastMessage - resp, err := s.client.Do(req, &bs) - if err != nil { - return nil, resp, err - } - - return bs, resp, err -} - -// GetBroadcastMessage gets a single broadcast message. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-a-specific-broadcast-message -func (s *BroadcastMessagesService) GetBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { - u := fmt.Sprintf("broadcast_messages/%d", broadcast) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - b := new(BroadcastMessage) - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// CreateBroadcastMessageOptions represents the available CreateBroadcastMessage() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message -type CreateBroadcastMessageOptions struct { - Message *string `url:"message" json:"message"` - StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"` - EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"` - Color *string `url:"color,omitempty" json:"color,omitempty"` - Font *string `url:"font,omitempty" json:"font,omitempty"` -} - -// CreateBroadcastMessage creates a message to broadcast. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message -func (s *BroadcastMessagesService) CreateBroadcastMessage(opt *CreateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { - req, err := s.client.NewRequest("POST", "broadcast_messages", opt, options) - if err != nil { - return nil, nil, err - } - - b := new(BroadcastMessage) - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// UpdateBroadcastMessageOptions represents the available CreateBroadcastMessage() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message -type UpdateBroadcastMessageOptions struct { - Message *string `url:"message,omitempty" json:"message,omitempty"` - StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"` - EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"` - Color *string `url:"color,omitempty" json:"color,omitempty"` - Font *string `url:"font,omitempty" json:"font,omitempty"` -} - -// UpdateBroadcastMessage update a broadcasted message. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message -func (s *BroadcastMessagesService) UpdateBroadcastMessage(broadcast int, opt *UpdateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { - u := fmt.Sprintf("broadcast_messages/%d", broadcast) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - b := new(BroadcastMessage) - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b, resp, err -} - -// DeleteBroadcastMessage deletes a broadcasted message. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/broadcast_messages.html#delete-a-broadcast-message -func (s *BroadcastMessagesService) DeleteBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("broadcast_messages/%d", broadcast) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go b/vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go deleted file mode 100644 index 1f5ca5ccc..000000000 --- a/vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go +++ /dev/null @@ -1,69 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// CIYMLTemplatesService handles communication with the gitlab -// CI YML templates related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html -type CIYMLTemplatesService struct { - client *Client -} - -// CIYMLTemplate represents a GitLab CI YML template. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html -type CIYMLTemplate struct { - Name string `json:"name"` - Content string `json:"content"` -} - -// ListCIYMLTemplatesOptions represents the available ListAllTemplates() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates -type ListCIYMLTemplatesOptions ListOptions - -// ListAllTemplates get all GitLab CI YML templates. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html#list-gitlab-ci-yml-templates -func (s *CIYMLTemplatesService) ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplate, *Response, error) { - req, err := s.client.NewRequest("GET", "templates/gitlab_ci_ymls", opt, options) - if err != nil { - return nil, nil, err - } - - var cts []*CIYMLTemplate - resp, err := s.client.Do(req, &cts) - if err != nil { - return nil, resp, err - } - - return cts, resp, err -} - -// GetTemplate get a single GitLab CI YML template. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html#single-gitlab-ci-yml-template -func (s *CIYMLTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*CIYMLTemplate, *Response, error) { - u := fmt.Sprintf("templates/gitlab_ci_ymls/%s", pathEscape(key)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ct := new(CIYMLTemplate) - resp, err := s.client.Do(req, ct) - if err != nil { - return nil, resp, err - } - - return ct, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/client_options.go b/vendor/github.com/xanzy/go-gitlab/client_options.go deleted file mode 100644 index 4d9b0d698..000000000 --- a/vendor/github.com/xanzy/go-gitlab/client_options.go +++ /dev/null @@ -1,59 +0,0 @@ -package gitlab - -import ( - "net/http" - - retryablehttp "github.com/hashicorp/go-retryablehttp" -) - -// ClientOptionFunc can be used customize a new GitLab API client. -type ClientOptionFunc func(*Client) error - -// WithBaseURL sets the base URL for API requests to a custom endpoint. -func WithBaseURL(urlStr string) ClientOptionFunc { - return func(c *Client) error { - return c.setBaseURL(urlStr) - } -} - -// WithCustomBackoff can be used to configure a custom backoff policy. -func WithCustomBackoff(backoff retryablehttp.Backoff) ClientOptionFunc { - return func(c *Client) error { - c.client.Backoff = backoff - return nil - } -} - -// WithCustomLimiter injects a custom rate limiter to the client. -func WithCustomLimiter(limiter RateLimiter) ClientOptionFunc { - return func(c *Client) error { - c.configureLimiterOnce.Do(func() { - c.limiter = limiter - }) - return nil - } -} - -// WithCustomRetry can be used to configure a custom retry policy. -func WithCustomRetry(checkRetry retryablehttp.CheckRetry) ClientOptionFunc { - return func(c *Client) error { - c.client.CheckRetry = checkRetry - return nil - } -} - -// WithHTTPClient can be used to configure a custom HTTP client. -func WithHTTPClient(httpClient *http.Client) ClientOptionFunc { - return func(c *Client) error { - c.client.HTTPClient = httpClient - return nil - } -} - -// WithoutRetries disables the default retry logic. -func WithoutRetries() ClientOptionFunc { - return func(c *Client) error { - c.disableRetries = true - return nil - } -} diff --git a/vendor/github.com/xanzy/go-gitlab/commits.go b/vendor/github.com/xanzy/go-gitlab/commits.go deleted file mode 100644 index 36b355b7f..000000000 --- a/vendor/github.com/xanzy/go-gitlab/commits.go +++ /dev/null @@ -1,589 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" - "time" -) - -// CommitsService handles communication with the commit related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html -type CommitsService struct { - client *Client -} - -// Commit represents a GitLab commit. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html -type Commit struct { - ID string `json:"id"` - ShortID string `json:"short_id"` - Title string `json:"title"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - AuthoredDate *time.Time `json:"authored_date"` - CommitterName string `json:"committer_name"` - CommitterEmail string `json:"committer_email"` - CommittedDate *time.Time `json:"committed_date"` - CreatedAt *time.Time `json:"created_at"` - Message string `json:"message"` - ParentIDs []string `json:"parent_ids"` - Stats *CommitStats `json:"stats"` - Status *BuildStateValue `json:"status"` - LastPipeline *PipelineInfo `json:"last_pipeline"` - ProjectID int `json:"project_id"` - WebURL string `json:"web_url"` -} - -// CommitStats represents the number of added and deleted files in a commit. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html -type CommitStats struct { - Additions int `json:"additions"` - Deletions int `json:"deletions"` - Total int `json:"total"` -} - -func (c Commit) String() string { - return Stringify(c) -} - -// ListCommitsOptions represents the available ListCommits() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-repository-commits -type ListCommitsOptions struct { - ListOptions - RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"` - Since *time.Time `url:"since,omitempty" json:"since,omitempty"` - Until *time.Time `url:"until,omitempty" json:"until,omitempty"` - Path *string `url:"path,omitempty" json:"path,omitempty"` - All *bool `url:"all,omitempty" json:"all,omitempty"` - WithStats *bool `url:"with_stats,omitempty" json:"with_stats,omitempty"` - FirstParent *bool `url:"first_parent,omitempty" json:"first_parent,omitempty"` -} - -// ListCommits gets a list of repository commits in a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-commits -func (s *CommitsService) ListCommits(pid interface{}, opt *ListCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var c []*Commit - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// CommitRef represents the reference of branches/tags in a commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to -type CommitRef struct { - Type string `json:"type"` - Name string `json:"name"` -} - -// GetCommitRefsOptions represents the available GetCommitRefs() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to -type GetCommitRefsOptions struct { - ListOptions - Type *string `url:"type,omitempty" json:"type,omitempty"` -} - -// GetCommitRefs gets all references (from branches or tags) a commit is pushed to -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to -func (s *CommitsService) GetCommitRefs(pid interface{}, sha string, opt *GetCommitRefsOptions, options ...RequestOptionFunc) ([]*CommitRef, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/refs", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var cs []*CommitRef - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} - -// GetCommit gets a specific commit identified by the commit hash or name of a -// branch or tag. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-a-single-commit -func (s *CommitsService) GetCommit(pid interface{}, sha string, options ...RequestOptionFunc) (*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - if sha == "" { - return nil, nil, fmt.Errorf("SHA must be a non-empty string") - } - u := fmt.Sprintf("projects/%s/repository/commits/%s", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - c := new(Commit) - resp, err := s.client.Do(req, c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// CreateCommitOptions represents the available options for a new commit. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions -type CreateCommitOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` - CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` - StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` - StartSHA *string `url:"start_sha,omitempty" json:"start_sha,omitempty"` - StartProject *string `url:"start_project,omitempty" json:"start_project,omitempty"` - Actions []*CommitActionOptions `url:"actions,omitempty" json:"actions,omitempty"` - AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` - AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` - Stats *bool `url:"stats,omitempty" json:"stats,omitempty"` - Force *bool `url:"force,omitempty" json:"force,omitempty"` -} - -// CommitActionOptions represents the available options for a new single -// file action. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions -type CommitActionOptions struct { - Action *FileAction `url:"action,omitempty" json:"action,omitempty"` - FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` - PreviousPath *string `url:"previous_path,omitempty" json:"previous_path,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` - LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` - ExecuteFilemode *bool `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"` -} - -// CreateCommit creates a commit with multiple files and actions. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions -func (s *CommitsService) CreateCommit(pid interface{}, opt *CreateCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(Commit) - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// Diff represents a GitLab diff. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html -type Diff struct { - Diff string `json:"diff"` - NewPath string `json:"new_path"` - OldPath string `json:"old_path"` - AMode string `json:"a_mode"` - BMode string `json:"b_mode"` - NewFile bool `json:"new_file"` - RenamedFile bool `json:"renamed_file"` - DeletedFile bool `json:"deleted_file"` -} - -func (d Diff) String() string { - return Stringify(d) -} - -// GetCommitDiffOptions represents the available GetCommitDiff() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit -type GetCommitDiffOptions ListOptions - -// GetCommitDiff gets the diff of a commit in a project.. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit -func (s *CommitsService) GetCommitDiff(pid interface{}, sha string, opt *GetCommitDiffOptions, options ...RequestOptionFunc) ([]*Diff, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var d []*Diff - resp, err := s.client.Do(req, &d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CommitComment represents a GitLab commit comment. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html -type CommitComment struct { - Note string `json:"note"` - Path string `json:"path"` - Line int `json:"line"` - LineType string `json:"line_type"` - Author Author `json:"author"` -} - -// Author represents a GitLab commit author -type Author struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - Blocked bool `json:"blocked"` - CreatedAt *time.Time `json:"created_at"` -} - -func (c CommitComment) String() string { - return Stringify(c) -} - -// GetCommitCommentsOptions represents the available GetCommitComments() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit -type GetCommitCommentsOptions ListOptions - -// GetCommitComments gets the comments of a commit in a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit -func (s *CommitsService) GetCommitComments(pid interface{}, sha string, opt *GetCommitCommentsOptions, options ...RequestOptionFunc) ([]*CommitComment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var c []*CommitComment - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// PostCommitCommentOptions represents the available PostCommitComment() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit -type PostCommitCommentOptions struct { - Note *string `url:"note,omitempty" json:"note,omitempty"` - Path *string `url:"path" json:"path"` - Line *int `url:"line" json:"line"` - LineType *string `url:"line_type" json:"line_type"` -} - -// PostCommitComment adds a comment to a commit. Optionally you can post -// comments on a specific line of a commit. Therefor both path, line_new and -// line_old are required. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit -func (s *CommitsService) PostCommitComment(pid interface{}, sha string, opt *PostCommitCommentOptions, options ...RequestOptionFunc) (*CommitComment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(CommitComment) - resp, err := s.client.Do(req, c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// GetCommitStatusesOptions represents the available GetCommitStatuses() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit -type GetCommitStatusesOptions struct { - ListOptions - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Stage *string `url:"stage,omitempty" json:"stage,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - All *bool `url:"all,omitempty" json:"all,omitempty"` -} - -// CommitStatus represents a GitLab commit status. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit -type CommitStatus struct { - ID int `json:"id"` - SHA string `json:"sha"` - Ref string `json:"ref"` - Status string `json:"status"` - Name string `json:"name"` - TargetURL string `json:"target_url"` - Description string `json:"description"` - CreatedAt *time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at"` - FinishedAt *time.Time `json:"finished_at"` - Author Author `json:"author"` -} - -// GetCommitStatuses gets the statuses of a commit in a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit -func (s *CommitsService) GetCommitStatuses(pid interface{}, sha string, opt *GetCommitStatusesOptions, options ...RequestOptionFunc) ([]*CommitStatus, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var cs []*CommitStatus - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} - -// SetCommitStatusOptions represents the available SetCommitStatus() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit -type SetCommitStatusOptions struct { - State BuildStateValue `url:"state" json:"state"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Context *string `url:"context,omitempty" json:"context,omitempty"` - TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Coverage *float64 `url:"coverage,omitempty" json:"coverage,omitempty"` - PipelineID *int `url:"pipeline_id,omitempty" json:"pipeline_id,omitempty"` -} - -// SetCommitStatus sets the status of a commit in a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit -func (s *CommitsService) SetCommitStatus(pid interface{}, sha string, opt *SetCommitStatusOptions, options ...RequestOptionFunc) (*CommitStatus, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/statuses/%s", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - cs := new(CommitStatus) - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} - -// GetMergeRequestsByCommit gets merge request associated with a commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/commits.html#list-merge-requests-associated-with-a-commit -func (s *CommitsService) GetMergeRequestsByCommit(pid interface{}, sha string, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/merge_requests", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var mrs []*MergeRequest - resp, err := s.client.Do(req, &mrs) - if err != nil { - return nil, resp, err - } - - return mrs, resp, err -} - -// CherryPickCommitOptions represents the available CherryPickCommit() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit -type CherryPickCommitOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` -} - -// CherryPickCommit cherry picks a commit to a given branch. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit -func (s *CommitsService) CherryPickCommit(pid interface{}, sha string, opt *CherryPickCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(Commit) - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// RevertCommitOptions represents the available RevertCommit() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#revert-a-commit -type RevertCommitOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` -} - -// RevertCommit reverts a commit in a given branch. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#revert-a-commit -func (s *CommitsService) RevertCommit(pid interface{}, sha string, opt *RevertCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/revert", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(Commit) - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// GPGSignature represents a Gitlab commit's GPG Signature. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/commits.html#get-gpg-signature-of-a-commit -type GPGSignature struct { - KeyID int `json:"gpg_key_id"` - KeyPrimaryKeyID string `json:"gpg_key_primary_keyid"` - KeyUserName string `json:"gpg_key_user_name"` - KeyUserEmail string `json:"gpg_key_user_email"` - VerificationStatus string `json:"verification_status"` - KeySubkeyID int `json:"gpg_key_subkey_id"` -} - -// GetGPGSiganature gets a GPG signature of a commit. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#get-gpg-signature-of-a-commit -func (s *CommitsService) GetGPGSiganature(pid interface{}, sha string, options ...RequestOptionFunc) (*GPGSignature, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/signature", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - sig := new(GPGSignature) - resp, err := s.client.Do(req, &sig) - if err != nil { - return nil, resp, err - } - - return sig, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/deploy_keys.go b/vendor/github.com/xanzy/go-gitlab/deploy_keys.go deleted file mode 100644 index 9d71bffe5..000000000 --- a/vendor/github.com/xanzy/go-gitlab/deploy_keys.go +++ /dev/null @@ -1,234 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// DeployKeysService handles communication with the keys related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_keys.html -type DeployKeysService struct { - client *Client -} - -// DeployKey represents a GitLab deploy key. -type DeployKey struct { - ID int `json:"id"` - Title string `json:"title"` - Key string `json:"key"` - CanPush *bool `json:"can_push"` - CreatedAt *time.Time `json:"created_at"` -} - -func (k DeployKey) String() string { - return Stringify(k) -} - -// ListAllDeployKeys gets a list of all deploy keys -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#list-all-deploy-keys -func (s *DeployKeysService) ListAllDeployKeys(options ...RequestOptionFunc) ([]*DeployKey, *Response, error) { - req, err := s.client.NewRequest("GET", "deploy_keys", nil, options) - if err != nil { - return nil, nil, err - } - - var ks []*DeployKey - resp, err := s.client.Do(req, &ks) - if err != nil { - return nil, resp, err - } - - return ks, resp, err -} - -// ListProjectDeployKeysOptions represents the available ListProjectDeployKeys() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys -type ListProjectDeployKeysOptions ListOptions - -// ListProjectDeployKeys gets a list of a project's deploy keys -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys -func (s *DeployKeysService) ListProjectDeployKeys(pid interface{}, opt *ListProjectDeployKeysOptions, options ...RequestOptionFunc) ([]*DeployKey, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ks []*DeployKey - resp, err := s.client.Do(req, &ks) - if err != nil { - return nil, resp, err - } - - return ks, resp, err -} - -// GetDeployKey gets a single deploy key. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#single-deploy-key -func (s *DeployKeysService) GetDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*DeployKey, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - k := new(DeployKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// AddDeployKeyOptions represents the available ADDDeployKey() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key -type AddDeployKeyOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Key *string `url:"key,omitempty" json:"key,omitempty"` - CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"` -} - -// AddDeployKey creates a new deploy key for a project. If deploy key already -// exists in another project - it will be joined to project but only if -// original one was is accessible by same user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key -func (s *DeployKeysService) AddDeployKey(pid interface{}, opt *AddDeployKeyOptions, options ...RequestOptionFunc) (*DeployKey, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - k := new(DeployKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// DeleteDeployKey deletes a deploy key from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#delete-deploy-key -func (s *DeployKeysService) DeleteDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// EnableDeployKey enables a deploy key. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#enable-deploy-key -func (s *DeployKeysService) EnableDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*DeployKey, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys/%d/enable", pathEscape(project), deployKey) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - k := new(DeployKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// UpdateDeployKeyOptions represents the available UpdateDeployKey() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#update-deploy-key -type UpdateDeployKeyOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"` -} - -// UpdateDeployKey updates a deploy key for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_keys.html#update-deploy-key -func (s *DeployKeysService) UpdateDeployKey(pid interface{}, deployKey int, opt *UpdateDeployKeyOptions, options ...RequestOptionFunc) (*DeployKey, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - k := new(DeployKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/deploy_tokens.go b/vendor/github.com/xanzy/go-gitlab/deploy_tokens.go deleted file mode 100644 index 6d6ece396..000000000 --- a/vendor/github.com/xanzy/go-gitlab/deploy_tokens.go +++ /dev/null @@ -1,221 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// DeployTokensService handles communication with the deploy tokens related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_tokens.html -type DeployTokensService struct { - client *Client -} - -// DeployToken represents a GitLab deploy token. -type DeployToken struct { - ID int `json:"id"` - Name string `json:"name"` - Username string `json:"username"` - ExpiresAt *time.Time `json:"expires_at"` - Token string `json:"token,omitempty"` - Scopes []string `json:"scopes"` -} - -func (k DeployToken) String() string { - return Stringify(k) -} - -// ListAllDeployTokens gets a list of all deploy tokens. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-all-deploy-tokens -func (s *DeployTokensService) ListAllDeployTokens(options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { - req, err := s.client.NewRequest("GET", "deploy_tokens", nil, options) - if err != nil { - return nil, nil, err - } - - var ts []*DeployToken - resp, err := s.client.Do(req, &ts) - if err != nil { - return nil, resp, err - } - - return ts, resp, err -} - -// ListProjectDeployTokensOptions represents the available ListProjectDeployTokens() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens -type ListProjectDeployTokensOptions ListOptions - -// ListProjectDeployTokens gets a list of a project's deploy tokens. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens -func (s *DeployTokensService) ListProjectDeployTokens(pid interface{}, opt *ListProjectDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_tokens", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ts []*DeployToken - resp, err := s.client.Do(req, &ts) - if err != nil { - return nil, resp, err - } - - return ts, resp, err -} - -// CreateProjectDeployTokenOptions represents the available CreateProjectDeployToken() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-project-deploy-token -type CreateProjectDeployTokenOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Scopes []string `url:"scopes,omitempty" json:"scopes,omitempty"` -} - -// CreateProjectDeployToken creates a new deploy token for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-project-deploy-token -func (s *DeployTokensService) CreateProjectDeployToken(pid interface{}, opt *CreateProjectDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deploy_tokens", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(DeployToken) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// DeleteProjectDeployToken removes a deploy token from the project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#delete-a-project-deploy-token -func (s *DeployTokensService) DeleteProjectDeployToken(pid interface{}, deployToken int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/deploy_tokens/%d", pathEscape(project), deployToken) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListGroupDeployTokensOptions represents the available ListGroupDeployTokens() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-group-deploy-deploy-tokens -type ListGroupDeployTokensOptions ListOptions - -// ListGroupDeployTokens gets a list of a group’s deploy tokens. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens -func (s *DeployTokensService) ListGroupDeployTokens(gid interface{}, opt *ListGroupDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/deploy_tokens", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ts []*DeployToken - resp, err := s.client.Do(req, &ts) - if err != nil { - return nil, resp, err - } - - return ts, resp, err -} - -// CreateGroupDeployTokenOptions represents the available CreateGroupDeployToken() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-group-deploy-token -type CreateGroupDeployTokenOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Scopes []string `url:"scopes,omitempty" json:"scopes,omitempty"` -} - -// CreateGroupDeployToken creates a new deploy token for a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-group-deploy-token -func (s *DeployTokensService) CreateGroupDeployToken(gid interface{}, opt *CreateGroupDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/deploy_tokens", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(DeployToken) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// DeleteGroupDeployToken removes a deploy token from the group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deploy_tokens.html#delete-a-group-deploy-token -func (s *DeployTokensService) DeleteGroupDeployToken(gid interface{}, deployToken int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/deploy_tokens/%d", pathEscape(group), deployToken) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/deployments.go b/vendor/github.com/xanzy/go-gitlab/deployments.go deleted file mode 100644 index 2855f9146..000000000 --- a/vendor/github.com/xanzy/go-gitlab/deployments.go +++ /dev/null @@ -1,193 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gitlab - -import ( - "fmt" - "time" -) - -// DeploymentsService handles communication with the deployment related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html -type DeploymentsService struct { - client *Client -} - -// Deployment represents the Gitlab deployment -type Deployment struct { - ID int `json:"id"` - IID int `json:"iid"` - Ref string `json:"ref"` - SHA string `json:"sha"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - User *ProjectUser `json:"user"` - Environment *Environment `json:"environment"` - Deployable struct { - ID int `json:"id"` - Status string `json:"status"` - Stage string `json:"stage"` - Name string `json:"name"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - Coverage float64 `json:"coverage"` - CreatedAt *time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at"` - FinishedAt *time.Time `json:"finished_at"` - Duration float64 `json:"duration"` - User *User `json:"user"` - Commit *Commit `json:"commit"` - Pipeline struct { - ID int `json:"id"` - SHA string `json:"sha"` - Ref string `json:"ref"` - Status string `json:"status"` - } `json:"pipeline"` - Runner *Runner `json:"runner"` - } `json:"deployable"` -} - -// ListProjectDeploymentsOptions represents the available ListProjectDeployments() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments -type ListProjectDeploymentsOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"update_before,omitempty" json:"updated_before,omitempty"` - Environment *string `url:"environment,omitempty" json:"environment,omitempty"` - Status *string `url:"status,omitempty" json:"status,omitempty"` -} - -// ListProjectDeployments gets a list of deployments in a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments -func (s *DeploymentsService) ListProjectDeployments(pid interface{}, opts *ListProjectDeploymentsOptions, options ...RequestOptionFunc) ([]*Deployment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deployments", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, nil, err - } - - var ds []*Deployment - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetProjectDeployment get a deployment for a project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#get-a-specific-deployment -func (s *DeploymentsService) GetProjectDeployment(pid interface{}, deployment int, options ...RequestOptionFunc) (*Deployment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deployments/%d", pathEscape(project), deployment) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Deployment) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateProjectDeploymentOptions represents the available -// CreateProjectDeployment() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment -type CreateProjectDeploymentOptions struct { - Environment *string `url:"environment,omitempty" json:"environment,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - SHA *string `url:"sha,omitempty" json:"sha,omitempty"` - Tag *bool `url:"tag,omitempty" json:"tag,omitempty"` - Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"` -} - -// CreateProjectDeployment creates a project deployment. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment -func (s *DeploymentsService) CreateProjectDeployment(pid interface{}, opt *CreateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deployments", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Deployment) - resp, err := s.client.Do(req, &d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// UpdateProjectDeploymentOptions represents the available -// UpdateProjectDeployment() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment -type UpdateProjectDeploymentOptions struct { - Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"` -} - -// UpdateProjectDeployment updates a project deployment. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment -func (s *DeploymentsService) UpdateProjectDeployment(pid interface{}, deployment int, opt *UpdateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/deployments/%d", pathEscape(project), deployment) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Deployment) - resp, err := s.client.Do(req, &d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/discussions.go b/vendor/github.com/xanzy/go-gitlab/discussions.go deleted file mode 100644 index 14a5401dd..000000000 --- a/vendor/github.com/xanzy/go-gitlab/discussions.go +++ /dev/null @@ -1,1112 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// DiscussionsService handles communication with the discussions related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/discussions.html -type DiscussionsService struct { - client *Client -} - -// Discussion represents a GitLab discussion. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/discussions.html -type Discussion struct { - ID string `json:"id"` - IndividualNote bool `json:"individual_note"` - Notes []*Note `json:"notes"` -} - -func (d Discussion) String() string { - return Stringify(d) -} - -// ListIssueDiscussionsOptions represents the available ListIssueDiscussions() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-issue-discussion-items -type ListIssueDiscussionsOptions ListOptions - -// ListIssueDiscussions gets a list of all discussions for a single -// issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-issue-discussion-items -func (s *DiscussionsService) ListIssueDiscussions(pid interface{}, issue int, opt *ListIssueDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions", pathEscape(project), issue) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ds []*Discussion - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetIssueDiscussion returns a single discussion for a specific project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#get-single-issue-discussion-item -func (s *DiscussionsService) GetIssueDiscussion(pid interface{}, issue int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s", - pathEscape(project), - issue, - discussion, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateIssueDiscussionOptions represents the available CreateIssueDiscussion() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-issue-thread -type CreateIssueDiscussionOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// CreateIssueDiscussion creates a new discussion to a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-issue-thread -func (s *DiscussionsService) CreateIssueDiscussion(pid interface{}, issue int, opt *CreateIssueDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions", pathEscape(project), issue) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// AddIssueDiscussionNoteOptions represents the available AddIssueDiscussionNote() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-issue-thread -type AddIssueDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// AddIssueDiscussionNote creates a new discussion to a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-issue-thread -func (s *DiscussionsService) AddIssueDiscussionNote(pid interface{}, issue int, discussion string, opt *AddIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes", - pathEscape(project), - issue, - discussion, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateIssueDiscussionNoteOptions represents the available -// UpdateIssueDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-issue-thread-note -type UpdateIssueDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// UpdateIssueDiscussionNote modifies existing discussion of an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-issue-thread-note -func (s *DiscussionsService) UpdateIssueDiscussionNote(pid interface{}, issue int, discussion string, note int, opt *UpdateIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d", - pathEscape(project), - issue, - discussion, - note, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteIssueDiscussionNote deletes an existing discussion of an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#delete-an-issue-thread-note -func (s *DiscussionsService) DeleteIssueDiscussionNote(pid interface{}, issue int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d", - pathEscape(project), - issue, - discussion, - note, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListSnippetDiscussionsOptions represents the available ListSnippetDiscussions() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-snippet-discussion-items -type ListSnippetDiscussionsOptions ListOptions - -// ListSnippetDiscussions gets a list of all discussions for a single -// snippet. Snippet discussions are comments users can post to a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-snippet-discussion-items -func (s *DiscussionsService) ListSnippetDiscussions(pid interface{}, snippet int, opt *ListSnippetDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions", pathEscape(project), snippet) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ds []*Discussion - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetSnippetDiscussion returns a single discussion for a given snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#get-single-snippet-discussion-item -func (s *DiscussionsService) GetSnippetDiscussion(pid interface{}, snippet int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s", - pathEscape(project), - snippet, - discussion, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateSnippetDiscussionOptions represents the available -// CreateSnippetDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-snippet-thread -type CreateSnippetDiscussionOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// CreateSnippetDiscussion creates a new discussion for a single snippet. -// Snippet discussions are comments users can post to a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-snippet-thread -func (s *DiscussionsService) CreateSnippetDiscussion(pid interface{}, snippet int, opt *CreateSnippetDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions", pathEscape(project), snippet) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// AddSnippetDiscussionNoteOptions represents the available -// AddSnippetDiscussionNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-snippet-thread -type AddSnippetDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// AddSnippetDiscussionNote creates a new discussion to a single project -// snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-snippet-thread -func (s *DiscussionsService) AddSnippetDiscussionNote(pid interface{}, snippet int, discussion string, opt *AddSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes", - pathEscape(project), - snippet, - discussion, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateSnippetDiscussionNoteOptions represents the available -// UpdateSnippetDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-snippet-thread-note -type UpdateSnippetDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// UpdateSnippetDiscussionNote modifies existing discussion of a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-snippet-thread-note -func (s *DiscussionsService) UpdateSnippetDiscussionNote(pid interface{}, snippet int, discussion string, note int, opt *UpdateSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d", - pathEscape(project), - snippet, - discussion, - note, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteSnippetDiscussionNote deletes an existing discussion of a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#delete-a-snippet-thread-note -func (s *DiscussionsService) DeleteSnippetDiscussionNote(pid interface{}, snippet int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d", - pathEscape(project), - snippet, - discussion, - note, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListGroupEpicDiscussionsOptions represents the available -// ListEpicDiscussions() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-group-epic-discussion-items -type ListGroupEpicDiscussionsOptions ListOptions - -// ListGroupEpicDiscussions gets a list of all discussions for a single -// epic. Epic discussions are comments users can post to a epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-group-epic-discussion-items -func (s *DiscussionsService) ListGroupEpicDiscussions(gid interface{}, epic int, opt *ListGroupEpicDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions", - pathEscape(group), - epic, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ds []*Discussion - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetEpicDiscussion returns a single discussion for a given epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#get-single-epic-discussion-item -func (s *DiscussionsService) GetEpicDiscussion(gid interface{}, epic int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s", - pathEscape(group), - epic, - discussion, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateEpicDiscussionOptions represents the available CreateEpicDiscussion() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-epic-thread -type CreateEpicDiscussionOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// CreateEpicDiscussion creates a new discussion for a single epic. Epic -// discussions are comments users can post to a epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-epic-thread -func (s *DiscussionsService) CreateEpicDiscussion(gid interface{}, epic int, opt *CreateEpicDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions", - pathEscape(group), - epic, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// AddEpicDiscussionNoteOptions represents the available -// AddEpicDiscussionNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-epic-thread -type AddEpicDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// AddEpicDiscussionNote creates a new discussion to a single project epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-epic-thread -func (s *DiscussionsService) AddEpicDiscussionNote(gid interface{}, epic int, discussion string, opt *AddEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes", - pathEscape(group), - epic, - discussion, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateEpicDiscussionNoteOptions represents the available UpdateEpicDiscussion() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-epic-thread-note -type UpdateEpicDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// UpdateEpicDiscussionNote modifies existing discussion of a epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-epic-thread-note -func (s *DiscussionsService) UpdateEpicDiscussionNote(gid interface{}, epic int, discussion string, note int, opt *UpdateEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d", - pathEscape(group), - epic, - discussion, - note, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteEpicDiscussionNote deletes an existing discussion of a epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#delete-an-epic-thread-note -func (s *DiscussionsService) DeleteEpicDiscussionNote(gid interface{}, epic int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d", - pathEscape(group), - epic, - discussion, - note, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListMergeRequestDiscussionsOptions represents the available -// ListMergeRequestDiscussions() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-merge-request-discussion-items -type ListMergeRequestDiscussionsOptions ListOptions - -// ListMergeRequestDiscussions gets a list of all discussions for a single -// merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-merge-request-discussion-items -func (s *DiscussionsService) ListMergeRequestDiscussions(pid interface{}, mergeRequest int, opt *ListMergeRequestDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions", - pathEscape(project), - mergeRequest, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ds []*Discussion - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetMergeRequestDiscussion returns a single discussion for a given merge -// request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#get-single-merge-request-discussion-item -func (s *DiscussionsService) GetMergeRequestDiscussion(pid interface{}, mergeRequest int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s", - pathEscape(project), - mergeRequest, - discussion, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateMergeRequestDiscussionOptions represents the available -// CreateMergeRequestDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-thread -type CreateMergeRequestDiscussionOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` - Position *NotePosition `url:"position,omitempty" json:"position,omitempty"` -} - -// CreateMergeRequestDiscussion creates a new discussion for a single merge -// request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-merge-request-thread -func (s *DiscussionsService) CreateMergeRequestDiscussion(pid interface{}, mergeRequest int, opt *CreateMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions", - pathEscape(project), - mergeRequest, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// ResolveMergeRequestDiscussionOptions represents the available -// ResolveMergeRequestDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#resolve-a-merge-request-thread -type ResolveMergeRequestDiscussionOptions struct { - Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"` -} - -// ResolveMergeRequestDiscussion resolves/unresolves whole discussion of a merge -// request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#resolve-a-merge-request-thread -func (s *DiscussionsService) ResolveMergeRequestDiscussion(pid interface{}, mergeRequest int, discussion string, opt *ResolveMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s", - pathEscape(project), - mergeRequest, - discussion, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// AddMergeRequestDiscussionNoteOptions represents the available -// AddMergeRequestDiscussionNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-merge-request-discussion -type AddMergeRequestDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// AddMergeRequestDiscussionNote creates a new discussion to a single project -// merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-merge-request-discussion -func (s *DiscussionsService) AddMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, opt *AddMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes", - pathEscape(project), - mergeRequest, - discussion, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateMergeRequestDiscussionNoteOptions represents the available -// UpdateMergeRequestDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-merge-request-discussion-note -type UpdateMergeRequestDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` - Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"` -} - -// UpdateMergeRequestDiscussionNote modifies existing discussion of a merge -// request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-existing-merge-request-discussion-note -func (s *DiscussionsService) UpdateMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, opt *UpdateMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d", - pathEscape(project), - mergeRequest, - discussion, - note, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteMergeRequestDiscussionNote deletes an existing discussion of a merge -// request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#delete-a-merge-request-discussion-note -func (s *DiscussionsService) DeleteMergeRequestDiscussionNote(pid interface{}, mergeRequest int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d", - pathEscape(project), - mergeRequest, - discussion, - note, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListCommitDiscussionsOptions represents the available -// ListCommitDiscussions() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussion-items -type ListCommitDiscussionsOptions ListOptions - -// ListCommitDiscussions gets a list of all discussions for a single -// commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#list-project-commit-discussion-items -func (s *DiscussionsService) ListCommitDiscussions(pid interface{}, commit string, opt *ListCommitDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions", - pathEscape(project), - commit, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ds []*Discussion - resp, err := s.client.Do(req, &ds) - if err != nil { - return nil, resp, err - } - - return ds, resp, err -} - -// GetCommitDiscussion returns a single discussion for a specific project -// commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#get-single-commit-discussion-item -func (s *DiscussionsService) GetCommitDiscussion(pid interface{}, commit string, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s", - pathEscape(project), - commit, - discussion, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// CreateCommitDiscussionOptions represents the available -// CreateCommitDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-thread -type CreateCommitDiscussionOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` - Position *NotePosition `url:"position,omitempty" json:"position,omitempty"` -} - -// CreateCommitDiscussion creates a new discussion to a single project commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#create-new-commit-thread -func (s *DiscussionsService) CreateCommitDiscussion(pid interface{}, commit string, opt *CreateCommitDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions", - pathEscape(project), - commit, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - d := new(Discussion) - resp, err := s.client.Do(req, d) - if err != nil { - return nil, resp, err - } - - return d, resp, err -} - -// AddCommitDiscussionNoteOptions represents the available -// AddCommitDiscussionNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-thread -type AddCommitDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// AddCommitDiscussionNote creates a new discussion to a single project commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#add-note-to-existing-commit-thread -func (s *DiscussionsService) AddCommitDiscussionNote(pid interface{}, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes", - pathEscape(project), - commit, - discussion, - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateCommitDiscussionNoteOptions represents the available -// UpdateCommitDiscussion() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-an-existing-commit-thread-note -type UpdateCommitDiscussionNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// UpdateCommitDiscussionNote modifies existing discussion of an commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#modify-an-existing-commit-thread-note -func (s *DiscussionsService) UpdateCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d", - pathEscape(project), - commit, - discussion, - note, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteCommitDiscussionNote deletes an existing discussion of an commit. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/discussions.html#delete-a-commit-thread-note -func (s *DiscussionsService) DeleteCommitDiscussionNote(pid interface{}, commit string, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d", - pathEscape(project), - commit, - discussion, - note, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/environments.go b/vendor/github.com/xanzy/go-gitlab/environments.go deleted file mode 100644 index f666cde89..000000000 --- a/vendor/github.com/xanzy/go-gitlab/environments.go +++ /dev/null @@ -1,212 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// EnvironmentsService handles communication with the environment related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html -type EnvironmentsService struct { - client *Client -} - -// Environment represents a GitLab environment. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html -type Environment struct { - ID int `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - State string `json:"state"` - ExternalURL string `json:"external_url"` - Project *Project `json:"project"` - LastDeployment *Deployment `json:"last_deployment"` -} - -func (env Environment) String() string { - return Stringify(env) -} - -// ListEnvironmentsOptions represents the available ListEnvironments() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#list-environments -type ListEnvironmentsOptions ListOptions - -// ListEnvironments gets a list of environments from a project, sorted by name -// alphabetically. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#list-environments -func (s *EnvironmentsService) ListEnvironments(pid interface{}, opts *ListEnvironmentsOptions, options ...RequestOptionFunc) ([]*Environment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/environments", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, nil, err - } - - var envs []*Environment - resp, err := s.client.Do(req, &envs) - if err != nil { - return nil, resp, err - } - - return envs, resp, err -} - -// GetEnvironment gets a specific environment from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#get-a-specific-environment -func (s *EnvironmentsService) GetEnvironment(pid interface{}, environment int, options ...RequestOptionFunc) (*Environment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - env := new(Environment) - resp, err := s.client.Do(req, env) - if err != nil { - return nil, resp, err - } - - return env, resp, err -} - -// CreateEnvironmentOptions represents the available CreateEnvironment() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment -type CreateEnvironmentOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` -} - -// CreateEnvironment adds an environment to a project. This is an idempotent -// method and can be called multiple times with the same parameters. Createing -// an environment that is already a environment does not affect the -// existing environmentship. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment -func (s *EnvironmentsService) CreateEnvironment(pid interface{}, opt *CreateEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/environments", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - env := new(Environment) - resp, err := s.client.Do(req, env) - if err != nil { - return nil, resp, err - } - - return env, resp, err -} - -// EditEnvironmentOptions represents the available EditEnvironment() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment -type EditEnvironmentOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` -} - -// EditEnvironment updates a project team environment to a specified access level.. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment -func (s *EnvironmentsService) EditEnvironment(pid interface{}, environment int, opt *EditEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - env := new(Environment) - resp, err := s.client.Do(req, env) - if err != nil { - return nil, resp, err - } - - return env, resp, err -} - -// DeleteEnvironment removes an environment from a project team. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/environments.html#remove-a-environment-from-a-group-or-project -func (s *EnvironmentsService) DeleteEnvironment(pid interface{}, environment int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// StopEnvironment stop an environment from a project team. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/environments.html#stop-an-environment -func (s *EnvironmentsService) StopEnvironment(pid interface{}, environmentID int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/environments/%d/stop", pathEscape(project), environmentID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/epic_issues.go b/vendor/github.com/xanzy/go-gitlab/epic_issues.go deleted file mode 100644 index 3286b84dc..000000000 --- a/vendor/github.com/xanzy/go-gitlab/epic_issues.go +++ /dev/null @@ -1,133 +0,0 @@ -package gitlab - -import "fmt" - -// EpicIssuesService handles communication with the epic issue related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epic_issues.html -type EpicIssuesService struct { - client *Client -} - -// EpicIssueAssignment contains both the epic and issue objects returned from -// Gitlab with the assignment ID. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epic_issues.html -type EpicIssueAssignment struct { - ID int `json:"id"` - Epic *Epic `json:"epic"` - Issue *Issue `json:"issue"` -} - -// ListEpicIssues get a list of epic issues. -// -// Gitlab API docs: -// https://docs.gitlab.com/ee/api/epic_issues.html#list-issues-for-an-epic -func (s *EpicIssuesService) ListEpicIssues(gid interface{}, epic int, opt *ListOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/issues", pathEscape(group), epic) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var is []*Issue - resp, err := s.client.Do(req, &is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// AssignEpicIssue assigns an existing issue to an epic. -// -// Gitlab API Docs: -// https://docs.gitlab.com/ee/api/epic_issues.html#assign-an-issue-to-the-epic -func (s *EpicIssuesService) AssignEpicIssue(gid interface{}, epic, issue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, issue) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - a := new(EpicIssueAssignment) - resp, err := s.client.Do(req, a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// RemoveEpicIssue removes an issue from an epic. -// -// Gitlab API Docs: -// https://docs.gitlab.com/ee/api/epic_issues.html#remove-an-issue-from-the-epic -func (s *EpicIssuesService) RemoveEpicIssue(gid interface{}, epic, epicIssue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, epicIssue) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - a := new(EpicIssueAssignment) - resp, err := s.client.Do(req, a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// UpdateEpicIsssueAssignmentOptions describes the UpdateEpicIssueAssignment() -// options. -// -// Gitlab API Docs: -// https://docs.gitlab.com/ee/api/epic_issues.html#update-epic---issue-association -type UpdateEpicIsssueAssignmentOptions struct { - *ListOptions - MoveBeforeID *int `url:"move_before_id,omitempty" json:"move_before_id,omitempty"` - MoveAfterID *int `url:"move_after_id,omitempty" json:"move_after_id,omitempty"` -} - -// UpdateEpicIssueAssignment moves an issue before or after another issue in an -// epic issue list. -// -// Gitlab API Docs: -// https://docs.gitlab.com/ee/api/epic_issues.html#update-epic---issue-association -func (s *EpicIssuesService) UpdateEpicIssueAssignment(gid interface{}, epic, epicIssue int, opt *UpdateEpicIsssueAssignmentOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, epicIssue) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - var is []*Issue - resp, err := s.client.Do(req, &is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/epics.go b/vendor/github.com/xanzy/go-gitlab/epics.go deleted file mode 100644 index 7f24c5029..000000000 --- a/vendor/github.com/xanzy/go-gitlab/epics.go +++ /dev/null @@ -1,246 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// EpicsService handles communication with the epic related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html -type EpicsService struct { - client *Client -} - -// EpicAuthor represents a author of the epic. -type EpicAuthor struct { - ID int `json:"id"` - State string `json:"state"` - WebURL string `json:"web_url"` - Name string `json:"name"` - AvatarURL string `json:"avatar_url"` - Username string `json:"username"` -} - -// Epic represents a GitLab epic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html -type Epic struct { - ID int `json:"id"` - IID int `json:"iid"` - GroupID int `json:"group_id"` - ParentID int `json:"parent_id"` - Title string `json:"title"` - Description string `json:"description"` - State string `json:"state"` - WebURL string `json:"web_url"` - Author *EpicAuthor `json:"author"` - StartDate *ISOTime `json:"start_date"` - StartDateIsFixed bool `json:"start_date_is_fixed"` - StartDateFixed *ISOTime `json:"start_date_fixed"` - StartDateFromMilestones *ISOTime `json:"start_date_from_milestones"` - DueDate *ISOTime `json:"due_date"` - DueDateIsFixed bool `json:"due_date_is_fixed"` - DueDateFixed *ISOTime `json:"due_date_fixed"` - DueDateFromMilestones *ISOTime `json:"due_date_from_milestones"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - Labels []string `json:"labels"` - Upvotes int `json:"upvotes"` - Downvotes int `json:"downvotes"` - UserNotesCount int `json:"user_notes_count"` - URL string `json:"url"` -} - -func (e Epic) String() string { - return Stringify(e) -} - -// ListGroupEpicsOptions represents the available ListGroupEpics() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#list-epics-for-a-group -type ListGroupEpicsOptions struct { - ListOptions - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"` - IncludeDescendantGroups *bool `url:"include_descendant_groups,omitempty" json:"include_descendant_groups,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` -} - -// ListGroupEpics gets a list of group epics. This function accepts pagination -// parameters page and per_page to return the list of group epics. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#list-epics-for-a-group -func (s *EpicsService) ListGroupEpics(gid interface{}, opt *ListGroupEpicsOptions, options ...RequestOptionFunc) ([]*Epic, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var es []*Epic - resp, err := s.client.Do(req, &es) - if err != nil { - return nil, resp, err - } - - return es, resp, err -} - -// GetEpic gets a single group epic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#single-epic -func (s *EpicsService) GetEpic(gid interface{}, epic int, options ...RequestOptionFunc) (*Epic, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - e := new(Epic) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// GetEpicLinks gets all child epics of an epic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epic_links.html -func (s *EpicsService) GetEpicLinks(gid interface{}, epic int, options ...RequestOptionFunc) ([]*Epic, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/epics", pathEscape(group), epic) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var e []*Epic - resp, err := s.client.Do(req, &e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// CreateEpicOptions represents the available CreateEpic() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#new-epic -type CreateEpicOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"` - StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"` - DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"` - DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"` -} - -// CreateEpic creates a new group epic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#new-epic -func (s *EpicsService) CreateEpic(gid interface{}, opt *CreateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - e := new(Epic) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// UpdateEpicOptions represents the available UpdateEpic() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#update-epic -type UpdateEpicOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"` - StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"` - DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"` - DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"` - StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` -} - -// UpdateEpic updates an existing group epic. This function is also used -// to mark an epic as closed. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#update-epic -func (s *EpicsService) UpdateEpic(gid interface{}, epic int, opt *UpdateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - e := new(Epic) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// DeleteEpic deletes a single group epic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#delete-epic -func (s *EpicsService) DeleteEpic(gid interface{}, epic int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/event_parsing.go b/vendor/github.com/xanzy/go-gitlab/event_parsing.go deleted file mode 100644 index a09b356c1..000000000 --- a/vendor/github.com/xanzy/go-gitlab/event_parsing.go +++ /dev/null @@ -1,233 +0,0 @@ -package gitlab - -import ( - "encoding/json" - "fmt" - "net/http" -) - -// EventType represents a Gitlab event type. -type EventType string - -// List of available event types. -const ( - EventTypeBuild EventType = "Build Hook" - EventTypeIssue EventType = "Issue Hook" - EventConfidentialIssue EventType = "Confidential Issue Hook" - EventTypeJob EventType = "Job Hook" - EventTypeMergeRequest EventType = "Merge Request Hook" - EventTypeNote EventType = "Note Hook" - EventConfidentialNote EventType = "Confidential Note Hook" - EventTypePipeline EventType = "Pipeline Hook" - EventTypePush EventType = "Push Hook" - EventTypeSystemHook EventType = "System Hook" - EventTypeTagPush EventType = "Tag Push Hook" - EventTypeWikiPage EventType = "Wiki Page Hook" -) - -const ( - noteableTypeCommit = "Commit" - noteableTypeMergeRequest = "MergeRequest" - noteableTypeIssue = "Issue" - noteableTypeSnippet = "Snippet" -) - -type noteEvent struct { - ObjectKind string `json:"object_kind"` - ObjectAttributes struct { - NoteableType string `json:"noteable_type"` - } `json:"object_attributes"` -} - -const eventTypeHeader = "X-Gitlab-Event" - -// HookEventType returns the event type for the given request. -func HookEventType(r *http.Request) EventType { - return EventType(r.Header.Get(eventTypeHeader)) -} - -// ParseHook tries to parse both web- and system hooks. -// -// Example usage: -// -// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { -// payload, err := ioutil.ReadAll(r.Body) -// if err != nil { ... } -// event, err := gitlab.ParseHook(gitlab.HookEventType(r), payload) -// if err != nil { ... } -// switch event := event.(type) { -// case *gitlab.PushEvent: -// processPushEvent(event) -// case *gitlab.MergeEvent: -// processMergeEvent(event) -// ... -// } -// } -// -func ParseHook(eventType EventType, payload []byte) (event interface{}, err error) { - switch eventType { - case EventTypeSystemHook: - return ParseSystemhook(payload) - default: - return ParseWebhook(eventType, payload) - } -} - -// ParseSystemhook parses the event payload. For recognized event types, a -// value of the corresponding struct type will be returned. An error will be -// returned for unrecognized event types. -// -// Example usage: -// -// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { -// payload, err := ioutil.ReadAll(r.Body) -// if err != nil { ... } -// event, err := gitlab.ParseSystemhook(payload) -// if err != nil { ... } -// switch event := event.(type) { -// case *gitlab.PushSystemEvent: -// processPushSystemEvent(event) -// case *gitlab.MergeSystemEvent: -// processMergeSystemEvent(event) -// ... -// } -// } -// -func ParseSystemhook(payload []byte) (event interface{}, err error) { - e := &systemHookEvent{} - err = json.Unmarshal(payload, e) - if err != nil { - return nil, err - } - - switch e.EventName { - case "push": - event = &PushSystemEvent{} - case "tag_push": - event = &TagPushSystemEvent{} - case "repository_update": - event = &RepositoryUpdateSystemEvent{} - case - "project_create", - "project_update", - "project_destroy", - "project_transfer", - "project_rename": - event = &ProjectSystemEvent{} - case - "group_create", - "group_destroy", - "group_rename": - event = &GroupSystemEvent{} - case - "key_create", - "key_destroy": - event = &KeySystemEvent{} - case - "user_create", - "user_destroy", - "user_rename": - event = &UserSystemEvent{} - case - "user_add_to_group", - "user_remove_from_group", - "user_update_for_group": - event = &UserGroupSystemEvent{} - case - "user_add_to_team", - "user_remove_from_team", - "user_update_for_team": - event = &UserTeamSystemEvent{} - default: - switch e.ObjectKind { - case "merge_request": - event = &MergeEvent{} - default: - return nil, fmt.Errorf("unexpected system hook type %s", e.EventName) - } - } - - if err := json.Unmarshal(payload, event); err != nil { - return nil, err - } - - return event, nil -} - -// WebhookEventType returns the event type for the given request. -func WebhookEventType(r *http.Request) EventType { - return EventType(r.Header.Get(eventTypeHeader)) -} - -// ParseWebhook parses the event payload. For recognized event types, a -// value of the corresponding struct type will be returned. An error will -// be returned for unrecognized event types. -// -// Example usage: -// -// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { -// payload, err := ioutil.ReadAll(r.Body) -// if err != nil { ... } -// event, err := gitlab.ParseWebhook(gitlab.HookEventType(r), payload) -// if err != nil { ... } -// switch event := event.(type) { -// case *gitlab.PushEvent: -// processPushEvent(event) -// case *gitlab.MergeEvent: -// processMergeEvent(event) -// ... -// } -// } -// -func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err error) { - switch eventType { - case EventTypeBuild: - event = &BuildEvent{} - case EventTypeIssue, EventConfidentialIssue: - event = &IssueEvent{} - case EventTypeJob: - event = &JobEvent{} - case EventTypeMergeRequest: - event = &MergeEvent{} - case EventTypePipeline: - event = &PipelineEvent{} - case EventTypePush: - event = &PushEvent{} - case EventTypeTagPush: - event = &TagEvent{} - case EventTypeWikiPage: - event = &WikiPageEvent{} - case EventTypeNote, EventConfidentialNote: - note := ¬eEvent{} - err := json.Unmarshal(payload, note) - if err != nil { - return nil, err - } - - if note.ObjectKind != "note" { - return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind) - } - - switch note.ObjectAttributes.NoteableType { - case noteableTypeCommit: - event = &CommitCommentEvent{} - case noteableTypeMergeRequest: - event = &MergeCommentEvent{} - case noteableTypeIssue: - event = &IssueCommentEvent{} - case noteableTypeSnippet: - event = &SnippetCommentEvent{} - default: - return nil, fmt.Errorf("unexpected noteable type %s", note.ObjectAttributes.NoteableType) - } - - default: - return nil, fmt.Errorf("unexpected event type: %s", eventType) - } - - if err := json.Unmarshal(payload, event); err != nil { - return nil, err - } - - return event, nil -} diff --git a/vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go b/vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go deleted file mode 100644 index 4f3d527b5..000000000 --- a/vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go +++ /dev/null @@ -1,133 +0,0 @@ -package gitlab - -// systemHookEvent is used to pre-process events to determine the -// system hook event type. -type systemHookEvent struct { - BaseSystemEvent - ObjectKind string `json:"object_kind"` -} - -// BaseSystemEvent contains system hook's common properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type BaseSystemEvent struct { - EventName string `json:"event_name"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} - -// ProjectSystemEvent represents a project system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type ProjectSystemEvent struct { - BaseSystemEvent - Name string `json:"name"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - ProjectID int `json:"project_id"` - OwnerName string `json:"owner_name"` - OwnerEmail string `json:"owner_email"` - ProjectVisibility string `json:"project_visibility"` - OldPathWithNamespace string `json:"old_path_with_namespace,omitempty"` -} - -// GroupSystemEvent represents a group system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type GroupSystemEvent struct { - BaseSystemEvent - Name string `json:"name"` - Path string `json:"path"` - PathWithNamespace string `json:"full_path"` - GroupID int `json:"group_id"` - OwnerName string `json:"owner_name"` - OwnerEmail string `json:"owner_email"` - ProjectVisibility string `json:"project_visibility"` - OldPath string `json:"old_path,omitempty"` - OldPathWithNamespace string `json:"old_full_path,omitempty"` -} - -// KeySystemEvent represents a key system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type KeySystemEvent struct { - BaseSystemEvent - ID int `json:"id"` - Username string `json:"username"` - Key string `json:"key"` -} - -// UserSystemEvent represents a user system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type UserSystemEvent struct { - BaseSystemEvent - ID int `json:"user_id"` - Name string `json:"name"` - Username string `json:"username"` - OldUsername string `json:"old_username,omitempty"` - Email string `json:"email"` -} - -// UserGroupSystemEvent represents a user group system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type UserGroupSystemEvent struct { - BaseSystemEvent - ID int `json:"user_id"` - Name string `json:"user_name"` - Username string `json:"user_username"` - Email string `json:"user_email"` - GroupID int `json:"group_id"` - GroupName string `json:"group_name"` - GroupPath string `json:"group_path"` - GroupAccess string `json:"group_access"` -} - -// UserTeamSystemEvent represents a user team system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type UserTeamSystemEvent struct { - BaseSystemEvent - ID int `json:"user_id"` - Name string `json:"user_name"` - Username string `json:"user_username"` - Email string `json:"user_email"` - ProjectID int `json:"project_id"` - ProjectName string `json:"project_name"` - ProjectPath string `json:"project_path"` - ProjectPathWithNamespace string `json:"project_path_with_namespace"` - ProjectVisibility string `json:"project_visibility"` - AccessLevel string `json:"access_level"` -} - -// PushSystemEvent represents a push system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type PushSystemEvent struct { - BaseSystemEvent -} - -// TagPushSystemEvent represents a tag push system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type TagPushSystemEvent struct { - BaseSystemEvent -} - -// RepositoryUpdateSystemEvent represents a repository updated system event. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/system_hooks/system_hooks.html -type RepositoryUpdateSystemEvent struct { - BaseSystemEvent -} diff --git a/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go b/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go deleted file mode 100644 index d41379a4f..000000000 --- a/vendor/github.com/xanzy/go-gitlab/event_webhook_types.go +++ /dev/null @@ -1,834 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "encoding/json" - "fmt" - "strconv" - "time" -) - -// PushEvent represents a push event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#push-events -type PushEvent struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int `json:"user_id"` - UserName string `json:"user_name"` - UserUsername string `json:"user_username"` - UserEmail string `json:"user_email"` - UserAvatar string `json:"user_avatar"` - ProjectID int `json:"project_id"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - Commits []*struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - Added []string `json:"added"` - Modified []string `json:"modified"` - Removed []string `json:"removed"` - } `json:"commits"` - TotalCommitsCount int `json:"total_commits_count"` -} - -// TagEvent represents a tag event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#tag-events -type TagEvent struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int `json:"user_id"` - UserName string `json:"user_name"` - UserAvatar string `json:"user_avatar"` - UserEmail string `json:"user_email"` - ProjectID int `json:"project_id"` - Message string `json:"message"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - Commits []*struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - Added []string `json:"added"` - Modified []string `json:"modified"` - Removed []string `json:"removed"` - } `json:"commits"` - TotalCommitsCount int `json:"total_commits_count"` -} - -// IssueEvent represents a issue event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#issues-events -type IssueEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - Project struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - ObjectAttributes struct { - ID int `json:"id"` - Title string `json:"title"` - AssigneeID int `json:"assignee_id"` - AuthorID int `json:"author_id"` - ProjectID int `json:"project_id"` - CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) - UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) - Position int `json:"position"` - BranchName string `json:"branch_name"` - Description string `json:"description"` - MilestoneID int `json:"milestone_id"` - State string `json:"state"` - IID int `json:"iid"` - URL string `json:"url"` - Action string `json:"action"` - } `json:"object_attributes"` - Assignee struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` - } `json:"assignee"` - Assignees []struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` - } `json:"assignees"` - Labels []Label `json:"labels"` - Changes struct { - Labels struct { - Previous []Label `json:"previous"` - Current []Label `json:"current"` - } `json:"labels"` - UpdatedByID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"updated_by_id"` - } `json:"changes"` -} - -// JobEvent represents a job event. -// -// GitLab API docs: -// TODO: link to docs instead of src once they are published. -// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/data_builder/build.rb -type JobEvent struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - BuildID int `json:"build_id"` - BuildName string `json:"build_name"` - BuildStage string `json:"build_stage"` - BuildStatus string `json:"build_status"` - BuildStartedAt string `json:"build_started_at"` - BuildFinishedAt string `json:"build_finished_at"` - BuildDuration float64 `json:"build_duration"` - BuildAllowFailure bool `json:"build_allow_failure"` - PipelineID int `json:"pipeline_id"` - ProjectID int `json:"project_id"` - ProjectName string `json:"project_name"` - User struct { - ID int `json:"id"` - Name string `json:"name"` - Email string `json:"email"` - } `json:"user"` - Commit struct { - ID int `json:"id"` - SHA string `json:"sha"` - Message string `json:"message"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - AuthorURL string `json:"author_url"` - Status string `json:"status"` - Duration int `json:"duration"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` - } `json:"commit"` - Repository *Repository `json:"repository"` -} - -// CommitCommentEvent represents a comment on a commit event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-commit -type CommitCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - ObjectAttributes struct { - ID int `json:"id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment string `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - System bool `json:"system"` - StDiff struct { - Diff string `json:"diff"` - NewPath string `json:"new_path"` - OldPath string `json:"old_path"` - AMode string `json:"a_mode"` - BMode string `json:"b_mode"` - NewFile bool `json:"new_file"` - RenamedFile bool `json:"renamed_file"` - DeletedFile bool `json:"deleted_file"` - } `json:"st_diff"` - } `json:"object_attributes"` - Commit *struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - } `json:"commit"` -} - -// MergeCommentEvent represents a comment on a merge event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-merge-request -type MergeCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - ObjectAttributes struct { - ID int `json:"id"` - DiscussionID string `json:"discussion_id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment string `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - System bool `json:"system"` - StDiff *Diff `json:"st_diff"` - URL string `json:"url"` - } `json:"object_attributes"` - Repository *Repository `json:"repository"` - MergeRequest struct { - ID int `json:"id"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - AuthorID int `json:"author_id"` - AssigneeID int `json:"assignee_id"` - AssigneeIDs []int `json:"assignee_ids"` - Title string `json:"title"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - MilestoneID int `json:"milestone_id"` - State string `json:"state"` - MergeStatus string `json:"merge_status"` - TargetProjectID int `json:"target_project_id"` - IID int `json:"iid"` - Description string `json:"description"` - Position int `json:"position"` - LockedAt string `json:"locked_at"` - UpdatedByID int `json:"updated_by_id"` - MergeError string `json:"merge_error"` - MergeParams *MergeParams `json:"merge_params"` - MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` - MergeUserID int `json:"merge_user_id"` - MergeCommitSHA string `json:"merge_commit_sha"` - DeletedAt string `json:"deleted_at"` - InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` - LockVersion int `json:"lock_version"` - ApprovalsBeforeMerge string `json:"approvals_before_merge"` - RebaseCommitSHA string `json:"rebase_commit_sha"` - TimeEstimate int `json:"time_estimate"` - Squash bool `json:"squash"` - LastEditedAt string `json:"last_edited_at"` - LastEditedByID int `json:"last_edited_by_id"` - Source *Repository `json:"source"` - Target *Repository `json:"target"` - LastCommit struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - } `json:"last_commit"` - WorkInProgress bool `json:"work_in_progress"` - TotalTimeSpent int `json:"total_time_spent"` - HeadPipelineID int `json:"head_pipeline_id"` - } `json:"merge_request"` -} - -// IssueCommentEvent represents a comment on an issue event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-issue -type IssueCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - ObjectAttributes struct { - ID int `json:"id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment string `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - System bool `json:"system"` - StDiff []*Diff `json:"st_diff"` - URL string `json:"url"` - } `json:"object_attributes"` - Issue struct { - ID int `json:"id"` - IID int `json:"iid"` - ProjectID int `json:"project_id"` - MilestoneID int `json:"milestone_id"` - AuthorID int `json:"author_id"` - Description string `json:"description"` - State string `json:"state"` - Title string `json:"title"` - LastEditedAt string `json:"last_edit_at"` - LastEditedByID int `json:"last_edited_by_id"` - UpdatedAt string `json:"updated_at"` - UpdatedByID int `json:"updated_by_id"` - CreatedAt string `json:"created_at"` - ClosedAt string `json:"closed_at"` - DueDate *ISOTime `json:"due_date"` - URL string `json:"url"` - TimeEstimate int `json:"time_estimate"` - Confidential bool `json:"confidential"` - TotalTimeSpent int `json:"total_time_spent"` - HumanTotalTimeSpent string `json:"human_total_time_spent"` - HumanTimeEstimate string `json:"human_time_estimate"` - AssigneeIDs []int `json:"assignee_ids"` - AssigneeID int `json:"assignee_id"` - } `json:"issue"` -} - -// SnippetCommentEvent represents a comment on a snippet event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-code-snippet -type SnippetCommentEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - ProjectID int `json:"project_id"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Repository *Repository `json:"repository"` - ObjectAttributes struct { - ID int `json:"id"` - Note string `json:"note"` - NoteableType string `json:"noteable_type"` - AuthorID int `json:"author_id"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` - ProjectID int `json:"project_id"` - Attachment string `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int `json:"noteable_id"` - System bool `json:"system"` - StDiff *Diff `json:"st_diff"` - URL string `json:"url"` - } `json:"object_attributes"` - Snippet *Snippet `json:"snippet"` -} - -// MergeEvent represents a merge event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#merge-request-events -type MergeEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - Project struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - ObjectAttributes struct { - ID int `json:"id"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - AuthorID int `json:"author_id"` - AssigneeID int `json:"assignee_id"` - AssigneeIDs []int `json:"assignee_ids"` - Title string `json:"title"` - CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) - UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) - StCommits []*Commit `json:"st_commits"` - StDiffs []*Diff `json:"st_diffs"` - MilestoneID int `json:"milestone_id"` - State string `json:"state"` - MergeStatus string `json:"merge_status"` - TargetProjectID int `json:"target_project_id"` - IID int `json:"iid"` - Description string `json:"description"` - Position int `json:"position"` - LockedAt string `json:"locked_at"` - UpdatedByID int `json:"updated_by_id"` - MergeError string `json:"merge_error"` - MergeParams *MergeParams `json:"merge_params"` - MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"` - MergeUserID int `json:"merge_user_id"` - MergeCommitSHA string `json:"merge_commit_sha"` - DeletedAt string `json:"deleted_at"` - ApprovalsBeforeMerge string `json:"approvals_before_merge"` - RebaseCommitSHA string `json:"rebase_commit_sha"` - InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` - LockVersion int `json:"lock_version"` - TimeEstimate int `json:"time_estimate"` - Source *Repository `json:"source"` - Target *Repository `json:"target"` - LastCommit struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - } `json:"last_commit"` - WorkInProgress bool `json:"work_in_progress"` - URL string `json:"url"` - Action string `json:"action"` - OldRev string `json:"oldrev"` - Assignee MergeAssignee `json:"assignee"` - } `json:"object_attributes"` - Repository *Repository `json:"repository"` - Assignee MergeAssignee `json:"assignee"` - Labels []Label `json:"labels"` - Changes struct { - Assignees struct { - Previous []MergeAssignee `json:"previous"` - Current []MergeAssignee `json:"current"` - } `json:"assignees"` - Description struct { - Previous string `json:"previous"` - Current string `json:"current"` - } `json:"description"` - Labels struct { - Previous []Label `json:"previous"` - Current []Label `json:"current"` - } `json:"labels"` - SourceBranch struct { - Previous string `json:"previous"` - Current string `json:"current"` - } `json:"source_branch"` - SourceProjectID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"source_project_id"` - StateID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"state_id"` - TargetBranch struct { - Previous string `json:"previous"` - Current string `json:"current"` - } `json:"target_branch"` - TargetProjectID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"target_project_id"` - Title struct { - Previous string `json:"previous"` - Current string `json:"current"` - } `json:"title"` - UpdatedByID struct { - Previous int `json:"previous"` - Current int `json:"current"` - } `json:"updated_by_id"` - } `json:"changes"` -} - -// MergeAssignee represents a merge assignee. -type MergeAssignee struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` -} - -// MergeParams represents the merge params. -type MergeParams struct { - ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` -} - -// UnmarshalJSON decodes the merge parameters -// -// This allows support of ForceRemoveSourceBranch for both type bool (>11.9) and string (<11.9) -func (p *MergeParams) UnmarshalJSON(b []byte) error { - type Alias MergeParams - raw := struct { - *Alias - ForceRemoveSourceBranch interface{} `json:"force_remove_source_branch"` - }{ - Alias: (*Alias)(p), - } - - err := json.Unmarshal(b, &raw) - if err != nil { - return err - } - - switch v := raw.ForceRemoveSourceBranch.(type) { - case nil: - // No action needed. - case bool: - p.ForceRemoveSourceBranch = v - case string: - p.ForceRemoveSourceBranch, err = strconv.ParseBool(v) - if err != nil { - return err - } - default: - return fmt.Errorf("failed to unmarshal ForceRemoveSourceBranch of type: %T", v) - } - - return nil -} - -// WikiPageEvent represents a wiki page event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#wiki-page-events -type WikiPageEvent struct { - ObjectKind string `json:"object_kind"` - User *User `json:"user"` - Project struct { - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Wiki struct { - WebURL string `json:"web_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - } `json:"wiki"` - ObjectAttributes struct { - Title string `json:"title"` - Content string `json:"content"` - Format string `json:"format"` - Message string `json:"message"` - Slug string `json:"slug"` - URL string `json:"url"` - Action string `json:"action"` - } `json:"object_attributes"` -} - -// PipelineEvent represents a pipeline event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#pipeline-events -type PipelineEvent struct { - ObjectKind string `json:"object_kind"` - ObjectAttributes struct { - ID int `json:"id"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - SHA string `json:"sha"` - BeforeSHA string `json:"before_sha"` - Status string `json:"status"` - Stages []string `json:"stages"` - CreatedAt string `json:"created_at"` - FinishedAt string `json:"finished_at"` - Duration int `json:"duration"` - } `json:"object_attributes"` - MergeRequest struct { - ID int `json:"id"` - IID int `json:"iid"` - Title string `json:"title"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - TargetBranch string `json:"target_branch"` - TargetProjectID int `json:"target_project_id"` - State string `json:"state"` - MergeRequestStatus string `json:"merge_status"` - URL string `json:"url"` - } `json:"merge_request"` - User struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` - } `json:"user"` - Project struct { - ID int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` - WebURL string `json:"web_url"` - Visibility VisibilityValue `json:"visibility"` - } `json:"project"` - Commit struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp *time.Time `json:"timestamp"` - URL string `json:"url"` - Author struct { - Name string `json:"name"` - Email string `json:"email"` - } `json:"author"` - } `json:"commit"` - Builds []struct { - ID int `json:"id"` - Stage string `json:"stage"` - Name string `json:"name"` - Status string `json:"status"` - CreatedAt string `json:"created_at"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` - When string `json:"when"` - Manual bool `json:"manual"` - User struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` - } `json:"user"` - Runner struct { - ID int `json:"id"` - Description string `json:"description"` - Active bool `json:"active"` - IsShared bool `json:"is_shared"` - } `json:"runner"` - ArtifactsFile struct { - Filename string `json:"filename"` - Size int `json:"size"` - } `json:"artifacts_file"` - } `json:"builds"` -} - -//BuildEvent represents a build event -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#build-events -type BuildEvent struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - BuildID int `json:"build_id"` - BuildName string `json:"build_name"` - BuildStage string `json:"build_stage"` - BuildStatus string `json:"build_status"` - BuildStartedAt string `json:"build_started_at"` - BuildFinishedAt string `json:"build_finished_at"` - BuildDuration float64 `json:"build_duration"` - BuildAllowFailure bool `json:"build_allow_failure"` - ProjectID int `json:"project_id"` - ProjectName string `json:"project_name"` - User struct { - ID int `json:"id"` - Name string `json:"name"` - Email string `json:"email"` - } `json:"user"` - Commit struct { - ID int `json:"id"` - SHA string `json:"sha"` - Message string `json:"message"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - Status string `json:"status"` - Duration int `json:"duration"` - StartedAt string `json:"started_at"` - FinishedAt string `json:"finished_at"` - } `json:"commit"` - Repository *Repository `json:"repository"` -} diff --git a/vendor/github.com/xanzy/go-gitlab/events.go b/vendor/github.com/xanzy/go-gitlab/events.go deleted file mode 100644 index ed1160938..000000000 --- a/vendor/github.com/xanzy/go-gitlab/events.go +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// EventsService handles communication with the event related methods of -// the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/events.html -type EventsService struct { - client *Client -} - -// ContributionEvent represents a user's contribution -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events -type ContributionEvent struct { - Title string `json:"title"` - ProjectID int `json:"project_id"` - ActionName string `json:"action_name"` - TargetID int `json:"target_id"` - TargetIID int `json:"target_iid"` - TargetType string `json:"target_type"` - AuthorID int `json:"author_id"` - TargetTitle string `json:"target_title"` - CreatedAt *time.Time `json:"created_at"` - PushData struct { - CommitCount int `json:"commit_count"` - Action string `json:"action"` - RefType string `json:"ref_type"` - CommitFrom string `json:"commit_from"` - CommitTo string `json:"commit_to"` - Ref string `json:"ref"` - CommitTitle string `json:"commit_title"` - } `json:"push_data"` - Note *Note `json:"note"` - Author struct { - Name string `json:"name"` - Username string `json:"username"` - ID int `json:"id"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"author"` - AuthorUsername string `json:"author_username"` -} - -// ListContributionEventsOptions represents the options for GetUserContributionEvents -// -// GitLap API docs: -// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events -type ListContributionEventsOptions struct { - ListOptions - Action *EventTypeValue `url:"action,omitempty" json:"action,omitempty"` - TargetType *EventTargetTypeValue `url:"target_type,omitempty" json:"target_type,omitempty"` - Before *ISOTime `url:"before,omitempty" json:"before,omitempty"` - After *ISOTime `url:"after,omitempty" json:"after,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListUserContributionEvents retrieves user contribution events -// for the specified user, sorted from newest to oldest. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events -func (s *UsersService) ListUserContributionEvents(uid interface{}, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) { - user, err := parseID(uid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("users/%s/events", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var cs []*ContributionEvent - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} - -// ListCurrentUserContributionEvents gets a list currently authenticated user's events -// -// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#list-currently-authenticated-user-39-s-events -func (s *EventsService) ListCurrentUserContributionEvents(opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) { - req, err := s.client.NewRequest("GET", "events", opt, options) - if err != nil { - return nil, nil, err - } - - var cs []*ContributionEvent - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} - -// ListProjectVisibleEvents gets a list of visible events for a particular project -// -// GitLab API docs: https://docs.gitlab.com/ee/api/events.html#list-a-project-s-visible-events -func (s *EventsService) ListProjectVisibleEvents(pid interface{}, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/events", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var cs []*ContributionEvent - resp, err := s.client.Do(req, &cs) - if err != nil { - return nil, resp, err - } - - return cs, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/feature_flags.go b/vendor/github.com/xanzy/go-gitlab/feature_flags.go deleted file mode 100644 index f5926c283..000000000 --- a/vendor/github.com/xanzy/go-gitlab/feature_flags.go +++ /dev/null @@ -1,79 +0,0 @@ -package gitlab - -import ( - "fmt" - "net/url" -) - -// FeaturesService handles the communication with the application FeaturesService -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/features.html -type FeaturesService struct { - client *Client -} - -// Feature represents a GitLab feature flag. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/features.html -type Feature struct { - Name string `json:"name"` - State string `json:"state"` - Gates []Gate -} - -// Gate represents a gate of a GitLab feature flag. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/features.html -type Gate struct { - Key string `json:"key"` - Value interface{} `json:"value"` -} - -func (f Feature) String() string { - return Stringify(f) -} - -// ListFeatures gets a list of feature flags -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/features.html#list-all-features -func (s *FeaturesService) ListFeatures(options ...RequestOptionFunc) ([]*Feature, *Response, error) { - req, err := s.client.NewRequest("GET", "features", nil, options) - if err != nil { - return nil, nil, err - } - - var f []*Feature - resp, err := s.client.Do(req, &f) - if err != nil { - return nil, resp, err - } - return f, resp, err -} - -// SetFeatureFlag sets or creates a feature flag gate -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/features.html#set-or-create-a-feature -func (s *FeaturesService) SetFeatureFlag(name string, value interface{}, options ...RequestOptionFunc) (*Feature, *Response, error) { - u := fmt.Sprintf("features/%s", url.PathEscape(name)) - - opt := struct { - Value interface{} `url:"value" json:"value"` - }{ - value, - } - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - f := &Feature{} - resp, err := s.client.Do(req, f) - if err != nil { - return nil, resp, err - } - return f, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/gitlab.go b/vendor/github.com/xanzy/go-gitlab/gitlab.go deleted file mode 100644 index f8e4ee22d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/gitlab.go +++ /dev/null @@ -1,790 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// Package gitlab implements a GitLab API client. -package gitlab - -import ( - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net/http" - "net/url" - "sort" - "strconv" - "strings" - "sync" - "time" - - "github.com/google/go-querystring/query" - "github.com/hashicorp/go-cleanhttp" - retryablehttp "github.com/hashicorp/go-retryablehttp" - "golang.org/x/oauth2" - "golang.org/x/time/rate" -) - -const ( - defaultBaseURL = "https://gitlab.com/" - apiVersionPath = "api/v4/" - userAgent = "go-gitlab" - - headerRateLimit = "RateLimit-Limit" - headerRateReset = "RateLimit-Reset" -) - -// authType represents an authentication type within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -type authType int - -// List of available authentication types. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -const ( - basicAuth authType = iota - oAuthToken - privateToken -) - -// A Client manages communication with the GitLab API. -type Client struct { - // HTTP client used to communicate with the API. - client *retryablehttp.Client - - // Base URL for API requests. Defaults to the public GitLab API, but can be - // set to a domain endpoint to use with a self hosted GitLab server. baseURL - // should always be specified with a trailing slash. - baseURL *url.URL - - // disableRetries is used to disable the default retry logic. - disableRetries bool - - // configureLimiterOnce is used to make sure the limiter is configured exactly - // once and block all other calls until the initial (one) call is done. - configureLimiterOnce sync.Once - - // Limiter is used to limit API calls and prevent 429 responses. - limiter RateLimiter - - // Token type used to make authenticated API calls. - authType authType - - // Username and password used for basix authentication. - username, password string - - // Token used to make authenticated API calls. - token string - - // Protects the token field from concurrent read/write accesses. - tokenLock sync.RWMutex - - // User agent used when communicating with the GitLab API. - UserAgent string - - // Services used for talking to different parts of the GitLab API. - AccessRequests *AccessRequestsService - Applications *ApplicationsService - AwardEmoji *AwardEmojiService - Boards *IssueBoardsService - Branches *BranchesService - BroadcastMessage *BroadcastMessagesService - CIYMLTemplate *CIYMLTemplatesService - Commits *CommitsService - ContainerRegistry *ContainerRegistryService - CustomAttribute *CustomAttributesService - DeployKeys *DeployKeysService - DeployTokens *DeployTokensService - Deployments *DeploymentsService - Discussions *DiscussionsService - Environments *EnvironmentsService - EpicIssues *EpicIssuesService - Epics *EpicsService - Events *EventsService - Features *FeaturesService - GitIgnoreTemplates *GitIgnoreTemplatesService - GroupBadges *GroupBadgesService - GroupCluster *GroupClustersService - GroupIssueBoards *GroupIssueBoardsService - GroupLabels *GroupLabelsService - GroupMembers *GroupMembersService - GroupMilestones *GroupMilestonesService - GroupVariables *GroupVariablesService - Groups *GroupsService - InstanceCluster *InstanceClustersService - InstanceVariables *InstanceVariablesService - IssueLinks *IssueLinksService - Issues *IssuesService - IssuesStatistics *IssuesStatisticsService - Jobs *JobsService - Keys *KeysService - Labels *LabelsService - License *LicenseService - LicenseTemplates *LicenseTemplatesService - MergeRequestApprovals *MergeRequestApprovalsService - MergeRequests *MergeRequestsService - Milestones *MilestonesService - Namespaces *NamespacesService - Notes *NotesService - NotificationSettings *NotificationSettingsService - PagesDomains *PagesDomainsService - PipelineSchedules *PipelineSchedulesService - PipelineTriggers *PipelineTriggersService - Pipelines *PipelinesService - ProjectBadges *ProjectBadgesService - ProjectCluster *ProjectClustersService - ProjectImportExport *ProjectImportExportService - ProjectMembers *ProjectMembersService - ProjectMirrors *ProjectMirrorService - ProjectSnippets *ProjectSnippetsService - ProjectVariables *ProjectVariablesService - Projects *ProjectsService - ProtectedBranches *ProtectedBranchesService - ProtectedTags *ProtectedTagsService - ReleaseLinks *ReleaseLinksService - Releases *ReleasesService - Repositories *RepositoriesService - RepositoryFiles *RepositoryFilesService - ResourceLabelEvents *ResourceLabelEventsService - Runners *RunnersService - Search *SearchService - Services *ServicesService - Settings *SettingsService - Sidekiq *SidekiqService - Snippets *SnippetsService - SystemHooks *SystemHooksService - Tags *TagsService - Todos *TodosService - Users *UsersService - Validate *ValidateService - Version *VersionService - Wikis *WikisService -} - -// ListOptions specifies the optional parameters to various List methods that -// support pagination. -type ListOptions struct { - // For paginated result sets, page of results to retrieve. - Page int `url:"page,omitempty" json:"page,omitempty"` - - // For paginated result sets, the number of results to include per page. - PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"` -} - -// RateLimiter describes the interface that all (custom) rate limiters must implement. -type RateLimiter interface { - Wait(context.Context) error -} - -// NewClient returns a new GitLab API client. To use API methods which require -// authentication, provide a valid private or personal token. -func NewClient(token string, options ...ClientOptionFunc) (*Client, error) { - client, err := newClient(options...) - if err != nil { - return nil, err - } - client.authType = privateToken - client.token = token - return client, nil -} - -// NewBasicAuthClient returns a new GitLab API client. To use API methods which -// require authentication, provide a valid username and password. -func NewBasicAuthClient(username, password string, options ...ClientOptionFunc) (*Client, error) { - client, err := newClient(options...) - if err != nil { - return nil, err - } - - client.authType = basicAuth - client.username = username - client.password = password - - return client, nil -} - -// NewOAuthClient returns a new GitLab API client. To use API methods which -// require authentication, provide a valid oauth token. -func NewOAuthClient(token string, options ...ClientOptionFunc) (*Client, error) { - client, err := newClient(options...) - if err != nil { - return nil, err - } - client.authType = oAuthToken - client.token = token - return client, nil -} - -func newClient(options ...ClientOptionFunc) (*Client, error) { - c := &Client{UserAgent: userAgent} - - // Configure the HTTP client. - c.client = &retryablehttp.Client{ - Backoff: c.retryHTTPBackoff, - CheckRetry: c.retryHTTPCheck, - ErrorHandler: retryablehttp.PassthroughErrorHandler, - HTTPClient: cleanhttp.DefaultPooledClient(), - RetryWaitMin: 100 * time.Millisecond, - RetryWaitMax: 400 * time.Millisecond, - RetryMax: 5, - } - - // Set the default base URL. - c.setBaseURL(defaultBaseURL) - - // Apply any given client options. - for _, fn := range options { - if fn == nil { - continue - } - if err := fn(c); err != nil { - return nil, err - } - } - - // Create the internal timeStats service. - timeStats := &timeStatsService{client: c} - - // Create all the public services. - c.AccessRequests = &AccessRequestsService{client: c} - c.Applications = &ApplicationsService{client: c} - c.AwardEmoji = &AwardEmojiService{client: c} - c.Boards = &IssueBoardsService{client: c} - c.Branches = &BranchesService{client: c} - c.BroadcastMessage = &BroadcastMessagesService{client: c} - c.CIYMLTemplate = &CIYMLTemplatesService{client: c} - c.Commits = &CommitsService{client: c} - c.ContainerRegistry = &ContainerRegistryService{client: c} - c.CustomAttribute = &CustomAttributesService{client: c} - c.DeployKeys = &DeployKeysService{client: c} - c.DeployTokens = &DeployTokensService{client: c} - c.Deployments = &DeploymentsService{client: c} - c.Discussions = &DiscussionsService{client: c} - c.Environments = &EnvironmentsService{client: c} - c.EpicIssues = &EpicIssuesService{client: c} - c.Epics = &EpicsService{client: c} - c.Events = &EventsService{client: c} - c.Features = &FeaturesService{client: c} - c.GitIgnoreTemplates = &GitIgnoreTemplatesService{client: c} - c.GroupBadges = &GroupBadgesService{client: c} - c.GroupCluster = &GroupClustersService{client: c} - c.GroupIssueBoards = &GroupIssueBoardsService{client: c} - c.GroupLabels = &GroupLabelsService{client: c} - c.GroupMembers = &GroupMembersService{client: c} - c.GroupMilestones = &GroupMilestonesService{client: c} - c.GroupVariables = &GroupVariablesService{client: c} - c.Groups = &GroupsService{client: c} - c.InstanceCluster = &InstanceClustersService{client: c} - c.IssueLinks = &IssueLinksService{client: c} - c.Issues = &IssuesService{client: c, timeStats: timeStats} - c.IssuesStatistics = &IssuesStatisticsService{client: c} - c.Jobs = &JobsService{client: c} - c.Keys = &KeysService{client: c} - c.Labels = &LabelsService{client: c} - c.License = &LicenseService{client: c} - c.LicenseTemplates = &LicenseTemplatesService{client: c} - c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c} - c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats} - c.Milestones = &MilestonesService{client: c} - c.Namespaces = &NamespacesService{client: c} - c.Notes = &NotesService{client: c} - c.NotificationSettings = &NotificationSettingsService{client: c} - c.PagesDomains = &PagesDomainsService{client: c} - c.PipelineSchedules = &PipelineSchedulesService{client: c} - c.PipelineTriggers = &PipelineTriggersService{client: c} - c.Pipelines = &PipelinesService{client: c} - c.ProjectBadges = &ProjectBadgesService{client: c} - c.ProjectCluster = &ProjectClustersService{client: c} - c.ProjectImportExport = &ProjectImportExportService{client: c} - c.ProjectMembers = &ProjectMembersService{client: c} - c.ProjectMirrors = &ProjectMirrorService{client: c} - c.ProjectSnippets = &ProjectSnippetsService{client: c} - c.ProjectVariables = &ProjectVariablesService{client: c} - c.Projects = &ProjectsService{client: c} - c.ProtectedBranches = &ProtectedBranchesService{client: c} - c.ProtectedTags = &ProtectedTagsService{client: c} - c.ReleaseLinks = &ReleaseLinksService{client: c} - c.Releases = &ReleasesService{client: c} - c.Repositories = &RepositoriesService{client: c} - c.RepositoryFiles = &RepositoryFilesService{client: c} - c.ResourceLabelEvents = &ResourceLabelEventsService{client: c} - c.Runners = &RunnersService{client: c} - c.Search = &SearchService{client: c} - c.Services = &ServicesService{client: c} - c.Settings = &SettingsService{client: c} - c.Sidekiq = &SidekiqService{client: c} - c.Snippets = &SnippetsService{client: c} - c.SystemHooks = &SystemHooksService{client: c} - c.Tags = &TagsService{client: c} - c.Todos = &TodosService{client: c} - c.Users = &UsersService{client: c} - c.Validate = &ValidateService{client: c} - c.Version = &VersionService{client: c} - c.Wikis = &WikisService{client: c} - - return c, nil -} - -// retryHTTPCheck provides a callback for Client.CheckRetry which -// will retry both rate limit (429) and server (>= 500) errors. -func (c *Client) retryHTTPCheck(ctx context.Context, resp *http.Response, err error) (bool, error) { - if ctx.Err() != nil { - return false, ctx.Err() - } - if err != nil { - return false, err - } - if !c.disableRetries && (resp.StatusCode == 429 || resp.StatusCode >= 500) { - return true, nil - } - return false, nil -} - -// retryHTTPBackoff provides a generic callback for Client.Backoff which -// will pass through all calls based on the status code of the response. -func (c *Client) retryHTTPBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { - // Use the rate limit backoff function when we are rate limited. - if resp != nil && resp.StatusCode == 429 { - return rateLimitBackoff(min, max, attemptNum, resp) - } - - // Set custom duration's when we experience a service interruption. - min = 700 * time.Millisecond - max = 900 * time.Millisecond - - return retryablehttp.LinearJitterBackoff(min, max, attemptNum, resp) -} - -// rateLimitBackoff provides a callback for Client.Backoff which will use the -// RateLimit-Reset header to determine the time to wait. We add some jitter -// to prevent a thundering herd. -// -// min and max are mainly used for bounding the jitter that will be added to -// the reset time retrieved from the headers. But if the final wait time is -// less then min, min will be used instead. -func rateLimitBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { - // rnd is used to generate pseudo-random numbers. - rnd := rand.New(rand.NewSource(time.Now().UnixNano())) - - // First create some jitter bounded by the min and max durations. - jitter := time.Duration(rnd.Float64() * float64(max-min)) - - if resp != nil { - if v := resp.Header.Get(headerRateReset); v != "" { - if reset, _ := strconv.ParseInt(v, 10, 64); reset > 0 { - // Only update min if the given time to wait is longer. - if wait := time.Until(time.Unix(reset, 0)); wait > min { - min = wait - } - } - } - } - - return min + jitter -} - -// configureLimiter configures the rate limiter. -func (c *Client) configureLimiter() error { - // Set default values for when rate limiting is disabled. - limit := rate.Inf - burst := 0 - - defer func() { - // Create a new limiter using the calculated values. - c.limiter = rate.NewLimiter(limit, burst) - }() - - // Create a new request. - req, err := http.NewRequest("GET", c.baseURL.String(), nil) - if err != nil { - return err - } - - // Make a single request to retrieve the rate limit headers. - resp, err := c.client.HTTPClient.Do(req) - if err != nil { - return err - } - resp.Body.Close() - - if v := resp.Header.Get(headerRateLimit); v != "" { - if rateLimit, _ := strconv.ParseFloat(v, 64); rateLimit > 0 { - // The rate limit is based on requests per minute, so for our limiter to - // work correctly we devide the limit by 60 to get the limit per second. - rateLimit /= 60 - // Configure the limit and burst using a split of 2/3 for the limit and - // 1/3 for the burst. This enables clients to burst 1/3 of the allowed - // calls before the limiter kicks in. The remaining calls will then be - // spread out evenly using intervals of time.Second / limit which should - // prevent hitting the rate limit. - limit = rate.Limit(rateLimit * 0.66) - burst = int(rateLimit * 0.33) - } - } - - return nil -} - -// BaseURL return a copy of the baseURL. -func (c *Client) BaseURL() *url.URL { - u := *c.baseURL - return &u -} - -// setBaseURL sets the base URL for API requests to a custom endpoint. -func (c *Client) setBaseURL(urlStr string) error { - // Make sure the given URL end with a slash - if !strings.HasSuffix(urlStr, "/") { - urlStr += "/" - } - - baseURL, err := url.Parse(urlStr) - if err != nil { - return err - } - - if !strings.HasSuffix(baseURL.Path, apiVersionPath) { - baseURL.Path += apiVersionPath - } - - // Update the base URL of the client. - c.baseURL = baseURL - - return nil -} - -// NewRequest creates an API request. A relative URL path can be provided in -// path, in which case it is resolved relative to the base URL of the Client. -// Relative URL paths should always be specified without a preceding slash. If -// specified, the value pointed to by body is JSON encoded and included as the -// request body. -func (c *Client) NewRequest(method, path string, opt interface{}, options []RequestOptionFunc) (*retryablehttp.Request, error) { - u := *c.baseURL - unescaped, err := url.PathUnescape(path) - if err != nil { - return nil, err - } - - // Set the encoded path data - u.RawPath = c.baseURL.Path + path - u.Path = c.baseURL.Path + unescaped - - // Create a request specific headers map. - reqHeaders := make(http.Header) - reqHeaders.Set("Accept", "application/json") - - if c.UserAgent != "" { - reqHeaders.Set("User-Agent", c.UserAgent) - } - - var body interface{} - switch { - case method == "POST" || method == "PUT": - reqHeaders.Set("Content-Type", "application/json") - - if opt != nil { - body, err = json.Marshal(opt) - if err != nil { - return nil, err - } - } - case opt != nil: - q, err := query.Values(opt) - if err != nil { - return nil, err - } - u.RawQuery = q.Encode() - } - - req, err := retryablehttp.NewRequest(method, u.String(), body) - if err != nil { - return nil, err - } - - for _, fn := range options { - if fn == nil { - continue - } - if err := fn(req); err != nil { - return nil, err - } - } - - // Set the request specific headers. - for k, v := range reqHeaders { - req.Header[k] = v - } - - return req, nil -} - -// Response is a GitLab API response. This wraps the standard http.Response -// returned from GitLab and provides convenient access to things like -// pagination links. -type Response struct { - *http.Response - - // These fields provide the page values for paginating through a set of - // results. Any or all of these may be set to the zero value for - // responses that are not part of a paginated set, or for which there - // are no additional pages. - TotalItems int - TotalPages int - ItemsPerPage int - CurrentPage int - NextPage int - PreviousPage int -} - -// newResponse creates a new Response for the provided http.Response. -func newResponse(r *http.Response) *Response { - response := &Response{Response: r} - response.populatePageValues() - return response -} - -const ( - xTotal = "X-Total" - xTotalPages = "X-Total-Pages" - xPerPage = "X-Per-Page" - xPage = "X-Page" - xNextPage = "X-Next-Page" - xPrevPage = "X-Prev-Page" -) - -// populatePageValues parses the HTTP Link response headers and populates the -// various pagination link values in the Response. -func (r *Response) populatePageValues() { - if totalItems := r.Response.Header.Get(xTotal); totalItems != "" { - r.TotalItems, _ = strconv.Atoi(totalItems) - } - if totalPages := r.Response.Header.Get(xTotalPages); totalPages != "" { - r.TotalPages, _ = strconv.Atoi(totalPages) - } - if itemsPerPage := r.Response.Header.Get(xPerPage); itemsPerPage != "" { - r.ItemsPerPage, _ = strconv.Atoi(itemsPerPage) - } - if currentPage := r.Response.Header.Get(xPage); currentPage != "" { - r.CurrentPage, _ = strconv.Atoi(currentPage) - } - if nextPage := r.Response.Header.Get(xNextPage); nextPage != "" { - r.NextPage, _ = strconv.Atoi(nextPage) - } - if previousPage := r.Response.Header.Get(xPrevPage); previousPage != "" { - r.PreviousPage, _ = strconv.Atoi(previousPage) - } -} - -// Do sends an API request and returns the API response. The API response is -// JSON decoded and stored in the value pointed to by v, or returned as an -// error if an API error has occurred. If v implements the io.Writer -// interface, the raw response body will be written to v, without attempting to -// first decode it. -func (c *Client) Do(req *retryablehttp.Request, v interface{}) (*Response, error) { - // If not yet configured, try to configure the rate limiter. Fail - // silently as the limiter will be disabled in case of an error. - c.configureLimiterOnce.Do(func() { c.configureLimiter() }) - - // Wait will block until the limiter can obtain a new token. - err := c.limiter.Wait(req.Context()) - if err != nil { - return nil, err - } - - // Set the correct authentication header. If using basic auth, then check - // if we already have a token and if not first authenticate and get one. - var basicAuthToken string - switch c.authType { - case basicAuth: - c.tokenLock.RLock() - basicAuthToken = c.token - c.tokenLock.RUnlock() - if basicAuthToken == "" { - // If we don't have a token yet, we first need to request one. - basicAuthToken, err = c.requestOAuthToken(req.Context(), basicAuthToken) - if err != nil { - return nil, err - } - } - req.Header.Set("Authorization", "Bearer "+basicAuthToken) - case oAuthToken: - req.Header.Set("Authorization", "Bearer "+c.token) - case privateToken: - req.Header.Set("PRIVATE-TOKEN", c.token) - } - - resp, err := c.client.Do(req) - if err != nil { - return nil, err - } - - if resp.StatusCode == http.StatusUnauthorized && c.authType == basicAuth { - resp.Body.Close() - // The token most likely expired, so we need to request a new one and try again. - if _, err := c.requestOAuthToken(req.Context(), basicAuthToken); err != nil { - return nil, err - } - return c.Do(req, v) - } - defer resp.Body.Close() - - response := newResponse(resp) - - err = CheckResponse(resp) - if err != nil { - // Even though there was an error, we still return the response - // in case the caller wants to inspect it further. - return response, err - } - - if v != nil { - if w, ok := v.(io.Writer); ok { - _, err = io.Copy(w, resp.Body) - } else { - err = json.NewDecoder(resp.Body).Decode(v) - } - } - - return response, err -} - -func (c *Client) requestOAuthToken(ctx context.Context, token string) (string, error) { - c.tokenLock.Lock() - defer c.tokenLock.Unlock() - - // Return early if the token was updated while waiting for the lock. - if c.token != token { - return c.token, nil - } - - config := &oauth2.Config{ - Endpoint: oauth2.Endpoint{ - AuthURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/authorize", - TokenURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/token", - }, - } - - ctx = context.WithValue(ctx, oauth2.HTTPClient, c.client.HTTPClient) - t, err := config.PasswordCredentialsToken(ctx, c.username, c.password) - if err != nil { - return "", err - } - c.token = t.AccessToken - - return c.token, nil -} - -// Helper function to accept and format both the project ID or name as project -// identifier for all API calls. -func parseID(id interface{}) (string, error) { - switch v := id.(type) { - case int: - return strconv.Itoa(v), nil - case string: - return v, nil - default: - return "", fmt.Errorf("invalid ID type %#v, the ID must be an int or a string", id) - } -} - -// Helper function to escape a project identifier. -func pathEscape(s string) string { - return strings.Replace(url.PathEscape(s), ".", "%2E", -1) -} - -// An ErrorResponse reports one or more errors caused by an API request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/README.html#data-validation-and-error-reporting -type ErrorResponse struct { - Body []byte - Response *http.Response - Message string -} - -func (e *ErrorResponse) Error() string { - path, _ := url.QueryUnescape(e.Response.Request.URL.Path) - u := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, path) - return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, u, e.Response.StatusCode, e.Message) -} - -// CheckResponse checks the API response for errors, and returns them if present. -func CheckResponse(r *http.Response) error { - switch r.StatusCode { - case 200, 201, 202, 204, 304: - return nil - } - - errorResponse := &ErrorResponse{Response: r} - data, err := ioutil.ReadAll(r.Body) - if err == nil && data != nil { - errorResponse.Body = data - - var raw interface{} - if err := json.Unmarshal(data, &raw); err != nil { - errorResponse.Message = "failed to parse unknown error format" - } else { - errorResponse.Message = parseError(raw) - } - } - - return errorResponse -} - -// Format: -// { -// "message": { -// "": [ -// "", -// "", -// ... -// ], -// "": { -// "": [ -// "", -// "", -// ... -// ], -// } -// }, -// "error": "" -// } -func parseError(raw interface{}) string { - switch raw := raw.(type) { - case string: - return raw - - case []interface{}: - var errs []string - for _, v := range raw { - errs = append(errs, parseError(v)) - } - return fmt.Sprintf("[%s]", strings.Join(errs, ", ")) - - case map[string]interface{}: - var errs []string - for k, v := range raw { - errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v))) - } - sort.Strings(errs) - return strings.Join(errs, ", ") - - default: - return fmt.Sprintf("failed to parse unexpected error type: %T", raw) - } -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_badges.go b/vendor/github.com/xanzy/go-gitlab/group_badges.go deleted file mode 100644 index 8f284c897..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_badges.go +++ /dev/null @@ -1,213 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// GroupBadgesService handles communication with the group badges -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html -type GroupBadgesService struct { - client *Client -} - -// BadgeKind represents a GitLab Badge Kind -type BadgeKind string - -// all possible values Badge Kind -const ( - ProjectBadgeKind BadgeKind = "project" - GroupBadgeKind BadgeKind = "group" -) - -// GroupBadge represents a group badge. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html -type GroupBadge struct { - ID int `json:"id"` - LinkURL string `json:"link_url"` - ImageURL string `json:"image_url"` - RenderedLinkURL string `json:"rendered_link_url"` - RenderedImageURL string `json:"rendered_image_url"` - Kind BadgeKind `json:"kind"` -} - -// ListGroupBadgesOptions represents the available ListGroupBadges() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#list-all-badges-of-a-group -type ListGroupBadgesOptions ListOptions - -// ListGroupBadges gets a list of a group badges. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#list-all-badges-of-a-group -func (s *GroupBadgesService) ListGroupBadges(gid interface{}, opt *ListGroupBadgesOptions, options ...RequestOptionFunc) ([]*GroupBadge, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/badges", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gb []*GroupBadge - resp, err := s.client.Do(req, &gb) - if err != nil { - return nil, resp, err - } - - return gb, resp, err -} - -// GetGroupBadge gets a group badge. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#get-a-badge-of-a-group -func (s *GroupBadgesService) GetGroupBadge(gid interface{}, badge int, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gb := new(GroupBadge) - resp, err := s.client.Do(req, gb) - if err != nil { - return nil, resp, err - } - - return gb, resp, err -} - -// AddGroupBadgeOptions represents the available AddGroupBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#add-a-badge-to-a-group -type AddGroupBadgeOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// AddGroupBadge adds a badge to a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#add-a-badge-to-a-group -func (s *GroupBadgesService) AddGroupBadge(gid interface{}, opt *AddGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/badges", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gb := new(GroupBadge) - resp, err := s.client.Do(req, gb) - if err != nil { - return nil, resp, err - } - - return gb, resp, err -} - -// EditGroupBadgeOptions represents the available EditGroupBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#edit-a-badge-of-a-group -type EditGroupBadgeOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// EditGroupBadge updates a badge of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#edit-a-badge-of-a-group -func (s *GroupBadgesService) EditGroupBadge(gid interface{}, badge int, opt *EditGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - gb := new(GroupBadge) - resp, err := s.client.Do(req, gb) - if err != nil { - return nil, resp, err - } - - return gb, resp, err -} - -// DeleteGroupBadge removes a badge from a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#remove-a-badge-from-a-group -func (s *GroupBadgesService) DeleteGroupBadge(gid interface{}, badge int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// GroupBadgePreviewOptions represents the available PreviewGroupBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#preview-a-badge-from-a-group -type GroupBadgePreviewOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// PreviewGroupBadge returns how the link_url and image_url final URLs would be after -// resolving the placeholder interpolation. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_badges.html#preview-a-badge-from-a-group -func (s *GroupBadgesService) PreviewGroupBadge(gid interface{}, opt *GroupBadgePreviewOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/badges/render", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - gb := new(GroupBadge) - resp, err := s.client.Do(req, &gb) - if err != nil { - return nil, resp, err - } - - return gb, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_boards.go b/vendor/github.com/xanzy/go-gitlab/group_boards.go deleted file mode 100644 index 86186546c..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_boards.go +++ /dev/null @@ -1,351 +0,0 @@ -// -// Copyright 2018, Patrick Webster -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// GroupIssueBoardsService handles communication with the group issue board -// related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html -type GroupIssueBoardsService struct { - client *Client -} - -// GroupIssueBoard represents a GitLab group issue board. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html -type GroupIssueBoard struct { - ID int `json:"id"` - Name string `json:"name"` - Group *Group `json:"group"` - Milestone *Milestone `json:"milestone"` - Lists []*BoardList `json:"lists"` -} - -func (b GroupIssueBoard) String() string { - return Stringify(b) -} - -// ListGroupIssueBoardsOptions represents the available -// ListGroupIssueBoards() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#group-board -type ListGroupIssueBoardsOptions ListOptions - -// ListGroupIssueBoards gets a list of all issue boards in a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#group-board -func (s *GroupIssueBoardsService) ListGroupIssueBoards(gid interface{}, opt *ListGroupIssueBoardsOptions, options ...RequestOptionFunc) ([]*GroupIssueBoard, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gs []*GroupIssueBoard - resp, err := s.client.Do(req, &gs) - if err != nil { - return nil, resp, err - } - - return gs, resp, err -} - -// CreateGroupIssueBoardOptions represents the available -// CreateGroupIssueBoard() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#create-a-group-issue-board-premium -type CreateGroupIssueBoardOptions struct { - Name *string `url:"name" json:"name"` -} - -// CreateGroupIssueBoard creates a new issue board. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#create-a-group-issue-board-premium -func (s *GroupIssueBoardsService) CreateGroupIssueBoard(gid interface{}, opt *CreateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gib := new(GroupIssueBoard) - resp, err := s.client.Do(req, gib) - if err != nil { - return nil, resp, err - } - - return gib, resp, err -} - -// GetGroupIssueBoard gets a single issue board of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#single-board -func (s *GroupIssueBoardsService) GetGroupIssueBoard(gid interface{}, board int, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gib := new(GroupIssueBoard) - resp, err := s.client.Do(req, gib) - if err != nil { - return nil, resp, err - } - - return gib, resp, err -} - -// UpdateGroupIssueBoardOptions represents a group issue board. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#update-a-group-issue-board-premium -type UpdateGroupIssueBoardOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - Weight *int `url:"weight,omitempty" json:"weight,omitempty"` -} - -// UpdateIssueBoard updates a single issue board of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#update-a-group-issue-board-premium -func (s *GroupIssueBoardsService) UpdateIssueBoard(gid interface{}, board int, opt *UpdateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - gib := new(GroupIssueBoard) - resp, err := s.client.Do(req, gib) - if err != nil { - return nil, resp, err - } - - return gib, resp, err -} - -// DeleteIssueBoard delete a single issue board of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#delete-a-group-issue-board-premium -func (s *GroupIssueBoardsService) DeleteIssueBoard(gid interface{}, board int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListGroupIssueBoardListsOptions represents the available -// ListGroupIssueBoardLists() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#list-board-lists -type ListGroupIssueBoardListsOptions ListOptions - -// ListGroupIssueBoardLists gets a list of the issue board's lists. Does not include -// backlog and closed lists. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/group_boards.html#list-board-lists -func (s *GroupIssueBoardsService) ListGroupIssueBoardLists(gid interface{}, board int, opt *ListGroupIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d/lists", pathEscape(group), board) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gbl []*BoardList - resp, err := s.client.Do(req, &gbl) - if err != nil { - return nil, resp, err - } - - return gbl, resp, err -} - -// GetGroupIssueBoardList gets a single issue board list. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#single-board-list -func (s *GroupIssueBoardsService) GetGroupIssueBoardList(gid interface{}, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", - pathEscape(group), - board, - list, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gbl := new(BoardList) - resp, err := s.client.Do(req, gbl) - if err != nil { - return nil, resp, err - } - - return gbl, resp, err -} - -// CreateGroupIssueBoardListOptions represents the available -// CreateGroupIssueBoardList() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#new-board-list -type CreateGroupIssueBoardListOptions struct { - LabelID *int `url:"label_id" json:"label_id"` -} - -// CreateGroupIssueBoardList creates a new issue board list. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#new-board-list -func (s *GroupIssueBoardsService) CreateGroupIssueBoardList(gid interface{}, board int, opt *CreateGroupIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d/lists", pathEscape(group), board) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gbl := new(BoardList) - resp, err := s.client.Do(req, gbl) - if err != nil { - return nil, resp, err - } - - return gbl, resp, err -} - -// UpdateGroupIssueBoardListOptions represents the available -// UpdateGroupIssueBoardList() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#edit-board-list -type UpdateGroupIssueBoardListOptions struct { - Position *int `url:"position" json:"position"` -} - -// UpdateIssueBoardList updates the position of an existing -// group issue board list. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#edit-board-list -func (s *GroupIssueBoardsService) UpdateIssueBoardList(gid interface{}, board, list int, opt *UpdateGroupIssueBoardListOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", - pathEscape(group), - board, - list, - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gbl []*BoardList - resp, err := s.client.Do(req, gbl) - if err != nil { - return nil, resp, err - } - - return gbl, resp, err -} - -// DeleteGroupIssueBoardList soft deletes a group issue board list. -// Only for admins and group owners. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_boards.html#delete-a-board-list -func (s *GroupIssueBoardsService) DeleteGroupIssueBoardList(gid interface{}, board, list int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", - pathEscape(group), - board, - list, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_hooks.go b/vendor/github.com/xanzy/go-gitlab/group_hooks.go deleted file mode 100644 index 704232b90..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_hooks.go +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright 2020, Eric Stevens -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// GroupHook represents a GitLab group hook. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks -type GroupHook struct { - ID int `json:"id"` - URL string `json:"url"` - GroupID int `json:"group_id"` - PushEvents bool `json:"push_events"` - IssuesEvents bool `json:"issues_events"` - ConfidentialIssuesEvents bool `json:"confidential_issues_events"` - ConfidentialNoteEvents bool `json:"confidential_note_events"` - MergeRequestsEvents bool `json:"merge_requests_events"` - TagPushEvents bool `json:"tag_push_events"` - NoteEvents bool `json:"note_events"` - JobEvents bool `json:"job_events"` - PipelineEvents bool `json:"pipeline_events"` - WikiPageEvents bool `json:"wiki_page_events"` - EnableSSLVerification bool `json:"enable_ssl_verification"` - CreatedAt *time.Time `json:"created_at"` -} - -// ListGroupHooks gets a list of group hooks. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks -func (s *GroupsService) ListGroupHooks(gid interface{}) ([]*GroupHook, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/hooks", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, nil, nil) - if err != nil { - return nil, nil, err - } - var gh []*GroupHook - resp, err := s.client.Do(req, &gh) - if err != nil { - return nil, resp, err - } - - return gh, resp, err -} - -// GetGroupHook gets a specific hook for a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#get-group-hook -func (s *GroupsService) GetGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*GroupHook, *Response, error) { - group, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gh := new(GroupHook) - resp, err := s.client.Do(req, gh) - if err != nil { - return nil, resp, err - } - - return gh, resp, err -} - -// AddGroupHookOptions represents the available AddGroupHook() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook -type AddGroupHookOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` - EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` - Token *string `url:"token,omitempty" json:"token,omitempty"` -} - -// AddGroupHook create a new group scoped webhook. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook -func (s *GroupsService) AddGroupHook(gid interface{}, opt *AddGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/hooks", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gh := new(GroupHook) - resp, err := s.client.Do(req, gh) - if err != nil { - return nil, resp, err - } - - return gh, resp, err -} - -// EditGroupHookOptions represents the available EditGroupHook() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook -type EditGroupHookOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` - EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` - Token *string `url:"token,omitempty" json:"token,omitempty"` -} - -// EditGroupHook edits a hook for a specified group. -// -// Gitlab API docs: -// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook -func (s *GroupsService) EditGroupHook(pid interface{}, hook int, opt *EditGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) { - group, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - gh := new(GroupHook) - resp, err := s.client.Do(req, gh) - if err != nil { - return nil, resp, err - } - - return gh, resp, err -} - -// DeleteGroupHook removes a hook from a group. This is an idempotent -// method and can be called multiple times. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#delete-group-hook -func (s *GroupsService) DeleteGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_labels.go b/vendor/github.com/xanzy/go-gitlab/group_labels.go deleted file mode 100644 index 87a5ea659..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_labels.go +++ /dev/null @@ -1,225 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// GroupLabelsService handles communication with the label related methods of the -// GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/group_labels.html -type GroupLabelsService struct { - client *Client -} - -// GroupLabel represents a GitLab group label. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/group_labels.html -type GroupLabel Label - -func (l GroupLabel) String() string { - return Stringify(l) -} - -// ListGroupLabelsOptions represents the available ListGroupLabels() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels -type ListGroupLabelsOptions ListOptions - -// ListGroupLabels gets all labels for given group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#list-group-labels -func (s *GroupLabelsService) ListGroupLabels(gid interface{}, opt *ListGroupLabelsOptions, options ...RequestOptionFunc) ([]*GroupLabel, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/labels", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var l []*GroupLabel - resp, err := s.client.Do(req, &l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// GetGroupLabel get a single label for a given group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#get-a-single-group-label -func (s *GroupLabelsService) GetGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/labels/%s", pathEscape(group), label) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var l *GroupLabel - resp, err := s.client.Do(req, &l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// CreateGroupLabelOptions represents the available CreateGroupLabel() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#create-a-new-group-label -type CreateGroupLabelOptions CreateLabelOptions - -// CreateGroupLabel creates a new label for given group with given name and -// color. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#create-a-new-group-label -func (s *GroupLabelsService) CreateGroupLabel(gid interface{}, opt *CreateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/labels", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - l := new(GroupLabel) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// DeleteGroupLabelOptions represents the available DeleteGroupLabel() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#delete-a-group-label -type DeleteGroupLabelOptions DeleteLabelOptions - -// DeleteGroupLabel deletes a group label given by its name. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label -func (s *GroupLabelsService) DeleteGroupLabel(gid interface{}, opt *DeleteGroupLabelOptions, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/labels", pathEscape(group)) - - req, err := s.client.NewRequest("DELETE", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// UpdateGroupLabelOptions represents the available UpdateGroupLabel() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#update-a-group-label -type UpdateGroupLabelOptions UpdateLabelOptions - -// UpdateGroupLabel updates an existing label with new name or now color. At least -// one parameter is required, to update the label. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#update-a-group-label -func (s *GroupLabelsService) UpdateGroupLabel(gid interface{}, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/labels", pathEscape(group)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - l := new(GroupLabel) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// SubscribeToGroupLabel subscribes the authenticated user to a label to receive -// notifications. If the user is already subscribed to the label, the status -// code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#subscribe-to-a-group-label -func (s *GroupLabelsService) SubscribeToGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/labels/%s/subscribe", pathEscape(group), label) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - l := new(GroupLabel) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// UnsubscribeFromGroupLabel unsubscribes the authenticated user from a label to not -// receive notifications from it. If the user is not subscribed to the label, the -// status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_labels.html#unsubscribe-from-a-group-label -func (s *GroupLabelsService) UnsubscribeFromGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/labels/%s/unsubscribe", pathEscape(group), label) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_members.go b/vendor/github.com/xanzy/go-gitlab/group_members.go deleted file mode 100644 index 7fc1d4ced..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_members.go +++ /dev/null @@ -1,275 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// GroupMembersService handles communication with the group members -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/members.html -type GroupMembersService struct { - client *Client -} - -// GroupMemberSAMLIdentity represents the SAML Identity link for the group member. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project -// Gitlab MR for API change: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20357 -// Gitlab MR for API Doc change: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25652 -type GroupMemberSAMLIdentity struct { - ExternUID string `json:"extern_uid"` - Provider string `json:"provider"` - SAMLProviderID int `json:"saml_provider_id"` -} - -// GroupMember represents a GitLab group member. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/members.html -type GroupMember struct { - ID int `json:"id"` - Username string `json:"username"` - Name string `json:"name"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - ExpiresAt *ISOTime `json:"expires_at"` - AccessLevel AccessLevelValue `json:"access_level"` - GroupSAMLIdentity *GroupMemberSAMLIdentity `json:"group_saml_identity"` -} - -// ListGroupMembersOptions represents the available ListGroupMembers() and -// ListAllGroupMembers() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project -type ListGroupMembersOptions struct { - ListOptions - Query *string `url:"query,omitempty" json:"query,omitempty"` -} - -// ListGroupMembers get a list of group members viewable by the authenticated -// user. Inherited members through ancestor groups are not included. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project -func (s *GroupsService) ListGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/members", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gm []*GroupMember - resp, err := s.client.Do(req, &gm) - if err != nil { - return nil, resp, err - } - - return gm, resp, err -} - -// ListAllGroupMembers get a list of group members viewable by the authenticated -// user. Returns a list including inherited members through ancestor groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project-including-inherited-members -func (s *GroupsService) ListAllGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/members/all", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var gm []*GroupMember - resp, err := s.client.Do(req, &gm) - if err != nil { - return nil, resp, err - } - - return gm, resp, err -} - -// AddGroupMemberOptions represents the available AddGroupMember() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project -type AddGroupMemberOptions struct { - UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` - ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` -} - -// GetGroupMember gets a member of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project -func (s *GroupMembersService) GetGroupMember(gid interface{}, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gm := new(GroupMember) - resp, err := s.client.Do(req, gm) - if err != nil { - return nil, resp, err - } - - return gm, resp, err -} - -// AddGroupMember adds a user to the list of group members. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project -func (s *GroupMembersService) AddGroupMember(gid interface{}, opt *AddGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/members", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gm := new(GroupMember) - resp, err := s.client.Do(req, gm) - if err != nil { - return nil, resp, err - } - - return gm, resp, err -} - -// ShareWithGroup shares a group with the group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#share-groups-with-groups -func (s *GroupMembersService) ShareWithGroup(gid interface{}, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/share", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - g := new(Group) - resp, err := s.client.Do(req, g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// DeleteShareWithGroup allows to unshare a group from a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#delete-link-sharing-group-with-another-group -func (s *GroupMembersService) DeleteShareWithGroup(gid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/share/%d", pathEscape(group), groupID) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// EditGroupMemberOptions represents the available EditGroupMember() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project -type EditGroupMemberOptions struct { - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` - ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` -} - -// EditGroupMember updates a member of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project -func (s *GroupMembersService) EditGroupMember(gid interface{}, user int, opt *EditGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - gm := new(GroupMember) - resp, err := s.client.Do(req, gm) - if err != nil { - return nil, resp, err - } - - return gm, resp, err -} - -// RemoveGroupMember removes user from user team. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#remove-a-member-from-a-group-or-project -func (s *GroupMembersService) RemoveGroupMember(gid interface{}, user int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_milestones.go b/vendor/github.com/xanzy/go-gitlab/group_milestones.go deleted file mode 100644 index b3249f7b2..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_milestones.go +++ /dev/null @@ -1,291 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// GroupMilestonesService handles communication with the milestone related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html -type GroupMilestonesService struct { - client *Client -} - -// GroupMilestone represents a GitLab milestone. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html -type GroupMilestone struct { - ID int `json:"id"` - IID int `json:"iid"` - GroupID int `json:"group_id"` - Title string `json:"title"` - Description string `json:"description"` - StartDate *ISOTime `json:"start_date"` - DueDate *ISOTime `json:"due_date"` - State string `json:"state"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` - Expired *bool `json:"expired"` -} - -func (m GroupMilestone) String() string { - return Stringify(m) -} - -// ListGroupMilestonesOptions represents the available -// ListGroupMilestones() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones -type ListGroupMilestonesOptions struct { - ListOptions - IIDs []int `url:"iids,omitempty" json:"iids,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - Title *string `url:"title,omitempty" json:"title,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - IncludeParentMilestones *bool `url:"include_parent_milestones,omitempty" json:"include_parent_milestones,omitempty"` -} - -// ListGroupMilestones returns a list of group milestones. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones -func (s *GroupMilestonesService) ListGroupMilestones(gid interface{}, opt *ListGroupMilestonesOptions, options ...RequestOptionFunc) ([]*GroupMilestone, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*GroupMilestone - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetGroupMilestone gets a single group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#get-single-milestone -func (s *GroupMilestonesService) GetGroupMilestone(gid interface{}, milestone int, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones/%d", pathEscape(group), milestone) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(GroupMilestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// CreateGroupMilestoneOptions represents the available CreateGroupMilestone() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone -type CreateGroupMilestoneOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` -} - -// CreateGroupMilestone creates a new group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone -func (s *GroupMilestonesService) CreateGroupMilestone(gid interface{}, opt *CreateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(GroupMilestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// UpdateGroupMilestoneOptions represents the available UpdateGroupMilestone() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone -type UpdateGroupMilestoneOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` - StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` -} - -// UpdateGroupMilestone updates an existing group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone -func (s *GroupMilestonesService) UpdateGroupMilestone(gid interface{}, milestone int, opt *UpdateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones/%d", pathEscape(group), milestone) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(GroupMilestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetGroupMilestoneIssuesOptions represents the available GetGroupMilestoneIssues() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone -type GetGroupMilestoneIssuesOptions ListOptions - -// GetGroupMilestoneIssues gets all issues assigned to a single group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone -func (s *GroupMilestonesService) GetGroupMilestoneIssues(gid interface{}, milestone int, opt *GetGroupMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones/%d/issues", pathEscape(group), milestone) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// GetGroupMilestoneMergeRequestsOptions represents the available -// GetGroupMilestoneMergeRequests() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone -type GetGroupMilestoneMergeRequestsOptions ListOptions - -// GetGroupMilestoneMergeRequests gets all merge requests assigned to a -// single group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone -func (s *GroupMilestonesService) GetGroupMilestoneMergeRequests(gid interface{}, milestone int, opt *GetGroupMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones/%d/merge_requests", pathEscape(group), milestone) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var mr []*MergeRequest - resp, err := s.client.Do(req, &mr) - if err != nil { - return nil, resp, err - } - - return mr, resp, err -} - -type BurndownChartEvent struct { - CreatedAt *time.Time `json:"created_at"` - Weight *int `json:"weight"` - Action *string `json:"action"` -} - -// GetGroupMilestoneBurndownChartEventsOptions represents the available -// GetGroupMilestoneBurndownChartEventsOptions() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter -type GetGroupMilestoneBurndownChartEventsOptions ListOptions - -// GetGroupMilestoneBurndownChartEvents gets all merge requests assigned to a -// single group milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter -func (s *GroupMilestonesService) GetGroupMilestoneBurndownChartEvents(gid interface{}, milestone int, opt *GetGroupMilestoneBurndownChartEventsOptions, options ...RequestOptionFunc) ([]*BurndownChartEvent, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/milestones/%d/burndown_events", pathEscape(group), milestone) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var be []*BurndownChartEvent - resp, err := s.client.Do(req, &be) - if err != nil { - return nil, resp, err - } - - return be, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/group_variables.go b/vendor/github.com/xanzy/go-gitlab/group_variables.go deleted file mode 100644 index fea12a20a..000000000 --- a/vendor/github.com/xanzy/go-gitlab/group_variables.go +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright 2018, Patrick Webster -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" -) - -// GroupVariablesService handles communication with the -// group variables related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html -type GroupVariablesService struct { - client *Client -} - -// GroupVariable represents a GitLab group Variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html -type GroupVariable struct { - Key string `json:"key"` - Value string `json:"value"` - VariableType VariableTypeValue `json:"variable_type"` - Protected bool `json:"protected"` - Masked bool `json:"masked"` -} - -func (v GroupVariable) String() string { - return Stringify(v) -} - -// ListGroupVariablesOptions represents the available options for listing variables -// for a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#list-group-variables -type ListGroupVariablesOptions ListOptions - -// ListVariables gets a list of all variables for a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#list-group-variables -func (s *GroupVariablesService) ListVariables(gid interface{}, opt *ListGroupVariablesOptions, options ...RequestOptionFunc) ([]*GroupVariable, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/variables", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var vs []*GroupVariable - resp, err := s.client.Do(req, &vs) - if err != nil { - return nil, resp, err - } - - return vs, resp, err -} - -// GetVariable gets a variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#show-variable-details -func (s *GroupVariablesService) GetVariable(gid interface{}, key string, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - v := new(GroupVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// CreateGroupVariableOptions represents the available CreateVariable() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#create-variable -type CreateGroupVariableOptions struct { - Key *string `url:"key,omitempty" json:"key,omitempty"` - Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` - Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` -} - -// CreateVariable creates a new group variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#create-variable -func (s *GroupVariablesService) CreateVariable(gid interface{}, opt *CreateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/variables", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - v := new(GroupVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// UpdateGroupVariableOptions represents the available UpdateVariable() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#update-variable -type UpdateGroupVariableOptions struct { - Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` - Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` -} - -// UpdateVariable updates the position of an existing -// group issue board list. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#update-variable -func (s *GroupVariablesService) UpdateVariable(gid interface{}, key string, opt *UpdateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - v := new(GroupVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// RemoveVariable removes a group's variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_level_variables.html#remove-variable -func (s *GroupVariablesService) RemoveVariable(gid interface{}, key string, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/groups.go b/vendor/github.com/xanzy/go-gitlab/groups.go deleted file mode 100644 index 2aae86539..000000000 --- a/vendor/github.com/xanzy/go-gitlab/groups.go +++ /dev/null @@ -1,655 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// GroupsService handles communication with the group related methods of -// the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html -type GroupsService struct { - client *Client -} - -// Group represents a GitLab group. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html -type Group struct { - ID int `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Description string `json:"description"` - MembershipLock bool `json:"membership_lock"` - Visibility VisibilityValue `json:"visibility"` - LFSEnabled bool `json:"lfs_enabled"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - RequestAccessEnabled bool `json:"request_access_enabled"` - FullName string `json:"full_name"` - FullPath string `json:"full_path"` - ParentID int `json:"parent_id"` - Projects []*Project `json:"projects"` - Statistics *StorageStatistics `json:"statistics"` - CustomAttributes []*CustomAttribute `json:"custom_attributes"` - ShareWithGroupLock bool `json:"share_with_group_lock"` - RequireTwoFactorAuth bool `json:"require_two_factor_authentication"` - TwoFactorGracePeriod int `json:"two_factor_grace_period"` - ProjectCreationLevel ProjectCreationLevelValue `json:"project_creation_level"` - AutoDevopsEnabled bool `json:"auto_devops_enabled"` - SubGroupCreationLevel SubGroupCreationLevelValue `json:"subgroup_creation_level"` - EmailsDisabled bool `json:"emails_disabled"` - MentionsDisabled bool `json:"mentions_disabled"` - RunnersToken string `json:"runners_token"` - SharedProjects []*Project `json:"shared_projects"` - SharedWithGroups []struct { - GroupID int `json:"group_id"` - GroupName string `json:"group_name"` - GroupFullPath string `json:"group_full_path"` - GroupAccessLevel int `json:"group_access_level"` - ExpiresAt *ISOTime `json:"expires_at"` - } `json:"shared_with_groups"` - LDAPCN string `json:"ldap_cn"` - LDAPAccess AccessLevelValue `json:"ldap_access"` - LDAPGroupLinks []*LDAPGroupLink `json:"ldap_group_links"` - SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` - ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"` - MarkedForDeletionOn *ISOTime `json:"marked_for_deletion_on"` - CreatedAt *time.Time `json:"created_at"` -} - -type LDAPGroupLink struct { - CN string `json:"cn"` - GroupAccess AccessLevelValue `json:"group_access"` - Provider string `json:"provider"` -} - -// ListGroupsOptions represents the available ListGroups() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups -type ListGroupsOptions struct { - ListOptions - AllAvailable *bool `url:"all_available,omitempty" json:"all_available,omitempty"` - MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - SkipGroups []int `url:"skip_groups,omitempty" json:"skip_groups,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` - TopLevelOnly *bool `url:"top_level_only,omitempty" json:"top_level_only,omitempty"` - WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` -} - -// ListGroups gets a list of groups (as user: my groups, as admin: all groups). -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-project-groups -func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { - req, err := s.client.NewRequest("GET", "groups", opt, options) - if err != nil { - return nil, nil, err - } - - var g []*Group - resp, err := s.client.Do(req, &g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// GetGroup gets all details of a group. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group -func (s *GroupsService) GetGroup(gid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - g := new(Group) - resp, err := s.client.Do(req, g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// CreateGroupOptions represents the available CreateGroup() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group -type CreateGroupOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - Path *string `url:"path,omitempty" json:"path,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` - ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"` - RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"` - TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"` - ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"` - AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` - SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"` - EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` - MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"` - LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` - RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` - ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` - SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"` - ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"` -} - -// CreateGroup creates a new project group. Available only for users who can -// create groups. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group -func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { - req, err := s.client.NewRequest("POST", "groups", opt, options) - if err != nil { - return nil, nil, err - } - - g := new(Group) - resp, err := s.client.Do(req, g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// TransferGroup transfers a project to the Group namespace. Available only -// for admin. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#transfer-project-to-group -func (s *GroupsService) TransferGroup(gid interface{}, pid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/projects/%s", pathEscape(group), pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - g := new(Group) - resp, err := s.client.Do(req, g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// UpdateGroupOptions represents the set of available options to update a Group; -// as of today these are exactly the same available when creating a new Group. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#update-group -type UpdateGroupOptions CreateGroupOptions - -// UpdateGroup updates an existing group; only available to group owners and -// administrators. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#update-group -func (s *GroupsService) UpdateGroup(gid interface{}, opt *UpdateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s", pathEscape(group)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - g := new(Group) - resp, err := s.client.Do(req, g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// DeleteGroup removes group with all projects inside. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#remove-group -func (s *GroupsService) DeleteGroup(gid interface{}, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s", pathEscape(group)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SearchGroup get all groups that match your string in their name or path. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group -func (s *GroupsService) SearchGroup(query string, options ...RequestOptionFunc) ([]*Group, *Response, error) { - var q struct { - Search string `url:"search,omitempty" json:"search,omitempty"` - } - q.Search = query - - req, err := s.client.NewRequest("GET", "groups", &q, options) - if err != nil { - return nil, nil, err - } - - var g []*Group - resp, err := s.client.Do(req, &g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// ListGroupProjectsOptions represents the available ListGroup() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects -type ListGroupProjectsOptions struct { - ListOptions - Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` - Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` - Starred *bool `url:"starred,omitempty" json:"starred,omitempty"` - WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"` - WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"` - WithShared *bool `url:"with_shared,omitempty" json:"with_shared,omitempty"` - IncludeSubgroups *bool `url:"include_subgroups,omitempty" json:"include_subgroups,omitempty"` - WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` -} - -// ListGroupProjects get a list of group projects -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects -func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/projects", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*Project - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ListSubgroupsOptions represents the available ListSubgroups() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups -type ListSubgroupsOptions ListGroupsOptions - -// ListSubgroups gets a list of subgroups for a given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups -func (s *GroupsService) ListSubgroups(gid interface{}, opt *ListSubgroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/subgroups", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var g []*Group - resp, err := s.client.Do(req, &g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// ListDescendantGroupsOptions represents the available ListDescendantGroups() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-descendant-groups -type ListDescendantGroupsOptions ListGroupsOptions - -// ListDescendantGroups gets a list of subgroups for a given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-descendant-groups -func (s *GroupsService) ListDescendantGroups(gid interface{}, opt *ListDescendantGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/descendant_groups", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var g []*Group - resp, err := s.client.Do(req, &g) - if err != nil { - return nil, resp, err - } - - return g, resp, err -} - -// ListGroupLDAPLinks lists the group's LDAP links. Available only for users who -// can edit groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#list-ldap-group-links-starter -func (s *GroupsService) ListGroupLDAPLinks(gid interface{}, options ...RequestOptionFunc) ([]*LDAPGroupLink, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/ldap_group_links", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var gl []*LDAPGroupLink - resp, err := s.client.Do(req, &gl) - if err != nil { - return nil, resp, err - } - - return gl, resp, nil -} - -// AddGroupLDAPLinkOptions represents the available AddGroupLDAPLink() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-starter -type AddGroupLDAPLinkOptions struct { - CN *string `url:"cn,omitempty" json:"cn,omitempty"` - GroupAccess *int `url:"group_access,omitempty" json:"group_access,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` -} - -// AddGroupLDAPLink creates a new group LDAP link. Available only for users who -// can edit groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-starter -func (s *GroupsService) AddGroupLDAPLink(gid interface{}, opt *AddGroupLDAPLinkOptions, options ...RequestOptionFunc) (*LDAPGroupLink, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/ldap_group_links", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gl := new(LDAPGroupLink) - resp, err := s.client.Do(req, gl) - if err != nil { - return nil, resp, err - } - - return gl, resp, err -} - -// DeleteGroupLDAPLink deletes a group LDAP link. Available only for users who -// can edit groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-starter -func (s *GroupsService) DeleteGroupLDAPLink(gid interface{}, cn string, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/ldap_group_links/%s", pathEscape(group), pathEscape(cn)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteGroupLDAPLinkForProvider deletes a group LDAP link from a specific -// provider. Available only for users who can edit groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-starter -func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid interface{}, provider, cn string, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf( - "groups/%s/ldap_group_links/%s/%s", - pathEscape(group), - pathEscape(provider), - pathEscape(cn), - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// GroupPushRules represents a group push rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#get-group-push-rules -type GroupPushRules struct { - ID int `json:"id"` - CreatedAt *time.Time `json:"created_at"` - CommitMessageRegex string `json:"commit_message_regex"` - CommitMessageNegativeRegex string `json:"commit_message_negative_regex"` - BranchNameRegex string `json:"branch_name_regex"` - DenyDeleteTag bool `json:"deny_delete_tag"` - MemberCheck bool `json:"member_check"` - PreventSecrets bool `json:"prevent_secrets"` - AuthorEmailRegex string `json:"author_email_regex"` - FileNameRegex string `json:"file_name_regex"` - MaxFileSize int `json:"max_file_size"` - CommitCommitterCheck bool `json:"commit_committer_check"` - RejectUnsignedCommits bool `json:"reject_unsigned_commits"` -} - -// GetGroupPushRules gets the push rules of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#get-group-push-rules -func (s *GroupsService) GetGroupPushRules(gid interface{}, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - gpr := new(GroupPushRules) - resp, err := s.client.Do(req, gpr) - if err != nil { - return nil, resp, err - } - - return gpr, resp, err -} - -// AddGroupPushRuleOptions represents the available AddGroupPushRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#add-group-push-rule -type AddGroupPushRuleOptions struct { - DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` - MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` - PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` - CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` - CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` - BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` - AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` - FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` - MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` - CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` - RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` -} - -// AddGroupPushRule adds push rules to the specified group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#add-group-push-rule -func (s *GroupsService) AddGroupPushRule(gid interface{}, opt *AddGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - gpr := new(GroupPushRules) - resp, err := s.client.Do(req, gpr) - if err != nil { - return nil, resp, err - } - - return gpr, resp, err -} - -// EditGroupPushRuleOptions represents the available EditGroupPushRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#edit-group-push-rule -type EditGroupPushRuleOptions struct { - DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` - MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` - PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` - CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` - CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` - BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` - AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` - FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` - MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` - CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` - RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` -} - -// EditGroupPushRule edits a push rule for a specified group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#edit-group-push-rule -func (s *GroupsService) EditGroupPushRule(gid interface{}, opt *EditGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - gpr := new(GroupPushRules) - resp, err := s.client.Do(req, gpr) - if err != nil { - return nil, resp, err - } - - return gpr, resp, err -} - -// DeleteGroupPushRule deletes the push rules of a group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/groups.html#delete-group-push-rule -func (s *GroupsService) DeleteGroupPushRule(gid interface{}, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/issue_links.go b/vendor/github.com/xanzy/go-gitlab/issue_links.go deleted file mode 100644 index 495793764..000000000 --- a/vendor/github.com/xanzy/go-gitlab/issue_links.go +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2017, Arkbriar -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// IssueLinksService handles communication with the issue relations related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html -type IssueLinksService struct { - client *Client -} - -// IssueLink represents a two-way relation between two issues. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html -type IssueLink struct { - SourceIssue *Issue `json:"source_issue"` - TargetIssue *Issue `json:"target_issue"` -} - -// ListIssueRelations gets a list of related issues of a given issue, -// sorted by the relationship creation datetime (ascending). -// -// Issues will be filtered according to the user authorizations. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issue_links.html#list-issue-relations -func (s *IssueLinksService) ListIssueRelations(pid interface{}, issueIID int, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/links", pathEscape(project), issueIID) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var is []*Issue - resp, err := s.client.Do(req, &is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// CreateIssueLinkOptions represents the available CreateIssueLink() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issue_links.html -type CreateIssueLinkOptions struct { - TargetProjectID *string `json:"target_project_id"` - TargetIssueIID *string `json:"target_issue_iid"` -} - -// CreateIssueLink creates a two-way relation between two issues. -// User must be allowed to update both issues in order to succeed. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issue_links.html#create-an-issue-link -func (s *IssueLinksService) CreateIssueLink(pid interface{}, issueIID int, opt *CreateIssueLinkOptions, options ...RequestOptionFunc) (*IssueLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/links", pathEscape(project), issueIID) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - i := new(IssueLink) - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// DeleteIssueLink deletes an issue link, thus removes the two-way relationship. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issue_links.html#delete-an-issue-link -func (s *IssueLinksService) DeleteIssueLink(pid interface{}, issueIID, issueLinkID int, options ...RequestOptionFunc) (*IssueLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/links/%d", - pathEscape(project), - issueIID, - issueLinkID) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - i := new(IssueLink) - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/issues.go b/vendor/github.com/xanzy/go-gitlab/issues.go deleted file mode 100644 index ffd412eeb..000000000 --- a/vendor/github.com/xanzy/go-gitlab/issues.go +++ /dev/null @@ -1,706 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "encoding/json" - "fmt" - "net/url" - "strings" - "time" -) - -// IssuesService handles communication with the issue related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html -type IssuesService struct { - client *Client - timeStats *timeStatsService -} - -// IssueAuthor represents a author of the issue. -type IssueAuthor struct { - ID int `json:"id"` - State string `json:"state"` - WebURL string `json:"web_url"` - Name string `json:"name"` - AvatarURL string `json:"avatar_url"` - Username string `json:"username"` -} - -// IssueAssignee represents a assignee of the issue. -type IssueAssignee struct { - ID int `json:"id"` - State string `json:"state"` - WebURL string `json:"web_url"` - Name string `json:"name"` - AvatarURL string `json:"avatar_url"` - Username string `json:"username"` -} - -// IssueReferences represents references of the issue. -type IssueReferences struct { - Short string `json:"short"` - Relative string `json:"relative"` - Full string `json:"full"` -} - -// IssueCloser represents a closer of the issue. -type IssueCloser struct { - ID int `json:"id"` - State string `json:"state"` - WebURL string `json:"web_url"` - Name string `json:"name"` - AvatarURL string `json:"avatar_url"` - Username string `json:"username"` -} - -// IssueLinks represents links of the issue. -type IssueLinks struct { - Self string `json:"self"` - Notes string `json:"notes"` - AwardEmoji string `json:"award_emoji"` - Project string `json:"project"` -} - -// Issue represents a GitLab issue. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html -type Issue struct { - ID int `json:"id"` - IID int `json:"iid"` - State string `json:"state"` - Description string `json:"description"` - Author *IssueAuthor `json:"author"` - Milestone *Milestone `json:"milestone"` - ProjectID int `json:"project_id"` - Assignees []*IssueAssignee `json:"assignees"` - Assignee *IssueAssignee `json:"assignee"` - UpdatedAt *time.Time `json:"updated_at"` - ClosedAt *time.Time `json:"closed_at"` - ClosedBy *IssueCloser `json:"closed_by"` - Title string `json:"title"` - CreatedAt *time.Time `json:"created_at"` - Labels Labels `json:"labels"` - LabelDetails []*LabelDetails `json:"label_details"` - Upvotes int `json:"upvotes"` - Downvotes int `json:"downvotes"` - DueDate *ISOTime `json:"due_date"` - WebURL string `json:"web_url"` - References *IssueReferences `json:"references"` - TimeStats *TimeStats `json:"time_stats"` - Confidential bool `json:"confidential"` - Weight int `json:"weight"` - DiscussionLocked bool `json:"discussion_locked"` - Subscribed bool `json:"subscribed"` - UserNotesCount int `json:"user_notes_count"` - Links *IssueLinks `json:"_links"` - IssueLinkID int `json:"issue_link_id"` - MergeRequestCount int `json:"merge_requests_count"` - EpicIssueID int `json:"epic_issue_id"` - Epic *Epic `json:"epic"` - TaskCompletionStatus struct { - Count int `json:"count"` - CompletedCount int `json:"completed_count"` - } `json:"task_completion_status"` -} - -func (i Issue) String() string { - return Stringify(i) -} - -func (i *Issue) UnmarshalJSON(data []byte) error { - type alias Issue - - raw := make(map[string]interface{}) - err := json.Unmarshal(data, &raw) - if err != nil { - return err - } - - labelDetails, ok := raw["labels"].([]interface{}) - if ok && len(labelDetails) > 0 { - // We only want to change anything if we got label details. - if _, ok := labelDetails[0].(map[string]interface{}); !ok { - return json.Unmarshal(data, (*alias)(i)) - } - - labels := make([]interface{}, len(labelDetails)) - for i, details := range labelDetails { - labels[i] = details.(map[string]interface{})["name"] - } - - // Set the correct values - raw["labels"] = labels - raw["label_details"] = labelDetails - - data, err = json.Marshal(raw) - if err != nil { - return err - } - } - - return json.Unmarshal(data, (*alias)(i)) -} - -// Labels is a custom type with specific marshaling characteristics. -type Labels []string - -// MarshalJSON implements the json.Marshaler interface. -func (l *Labels) MarshalJSON() ([]byte, error) { - if *l == nil { - return []byte(`null`), nil - } - return json.Marshal(strings.Join(*l, ",")) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (l *Labels) UnmarshalJSON(data []byte) error { - type alias Labels - if !bytes.HasPrefix(data, []byte("[")) { - data = []byte(fmt.Sprintf("[%s]", string(data))) - } - return json.Unmarshal(data, (*alias)(l)) -} - -// EncodeValues implements the query.EncodeValues interface -func (l *Labels) EncodeValues(key string, v *url.Values) error { - v.Set(key, strings.Join(*l, ",")) - return nil -} - -// LabelDetails represents detailed label information. -type LabelDetails struct { - ID int `json:"id"` - Name string `json:"name"` - Color string `json:"color"` - Description string `json:"description"` - DescriptionHTML string `json:"description_html"` - TextColor string `json:"text_color"` -} - -// ListIssuesOptions represents the available ListIssues() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues -type ListIssuesOptions struct { - ListOptions - State *string `url:"state,omitempty" json:"state,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - NotMilestone *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - NotAuthorID []int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - NotAssigneeID []int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` - AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - NotMyReactionEmoji []string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` - IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"` - In *string `url:"in,omitempty" json:"in,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` -} - -// ListIssues gets all issues created by authenticated user. This function -// takes pagination parameters page and per_page to restrict the list of issues. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues -func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - req, err := s.client.NewRequest("GET", "issues", opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// ListGroupIssuesOptions represents the available ListGroupIssues() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-group-issues -type ListGroupIssuesOptions struct { - ListOptions - State *string `url:"state,omitempty" json:"state,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - NotMilestone *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - NotAuthorID []int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` - AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - NotAssigneeID []int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` - AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - NotMyReactionEmoji []string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - In *string `url:"in,omitempty" json:"in,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` -} - -// ListGroupIssues gets a list of group issues. This function accepts -// pagination parameters page and per_page to return the list of group issues. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-group-issues -func (s *IssuesService) ListGroupIssues(pid interface{}, opt *ListGroupIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - group, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/issues", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// ListProjectIssuesOptions represents the available ListProjectIssues() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues -type ListProjectIssuesOptions struct { - ListOptions - IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - NotMilestone []string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - NotAuthorID []int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - NotAssigneeID []int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` - AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - NotMyReactionEmoji []string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - In *string `url:"in,omitempty" json:"in,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` -} - -// ListProjectIssues gets a list of project issues. This function accepts -// pagination parameters page and per_page to return the list of project issues. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues -func (s *IssuesService) ListProjectIssues(pid interface{}, opt *ListProjectIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// GetIssue gets a single project issue. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#single-issues -func (s *IssuesService) GetIssue(pid interface{}, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d", pathEscape(project), issue) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// CreateIssueOptions represents the available CreateIssue() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues -type CreateIssueOptions struct { - IID *int `url:"iid,omitempty" json:"iid,omitempty"` - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` - AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` - MergeRequestToResolveDiscussionsOf *int `url:"merge_request_to_resolve_discussions_of,omitempty" json:"merge_request_to_resolve_discussions_of,omitempty"` - DiscussionToResolve *string `url:"discussion_to_resolve,omitempty" json:"discussion_to_resolve,omitempty"` - Weight *int `url:"weight,omitempty" json:"weight,omitempty"` -} - -// CreateIssue creates a new project issue. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues -func (s *IssuesService) CreateIssue(pid interface{}, opt *CreateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// UpdateIssueOptions represents the available UpdateIssue() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issues.html#edit-issue -type UpdateIssueOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` - AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - AddLabels Labels `url:"add_labels,comma,omitempty" json:"add_labels,omitempty"` - RemoveLabels Labels `url:"remove_labels,comma,omitempty" json:"remove_labels,omitempty"` - StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` - UpdatedAt *time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` - Weight *int `url:"weight,omitempty" json:"weight,omitempty"` - DiscussionLocked *bool `url:"discussion_locked,omitempty" json:"discussion_locked,omitempty"` -} - -// UpdateIssue updates an existing project issue. This function is also used -// to mark an issue as closed. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues -func (s *IssuesService) UpdateIssue(pid interface{}, issue int, opt *UpdateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d", pathEscape(project), issue) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// DeleteIssue deletes a single project issue. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#delete-an-issue -func (s *IssuesService) DeleteIssue(pid interface{}, issue int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d", pathEscape(project), issue) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// MoveIssueOptions represents the available MoveIssue() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issues.html#move-an-issue -type MoveIssueOptions struct { - ToProjectID *int `url:"to_project_id,omitempty" json:"to_project_id,omitempty"` -} - -// MoveIssue updates an existing project issue. This function is also used -// to mark an issue as closed. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issues.html#move-an-issue -func (s *IssuesService) MoveIssue(pid interface{}, issue int, opt *MoveIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/move", pathEscape(project), issue) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// SubscribeToIssue subscribes the authenticated user to the given issue to -// receive notifications. If the user is already subscribed to the issue, the -// status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#subscribe-to-a-merge-request -func (s *IssuesService) SubscribeToIssue(pid interface{}, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/subscribe", pathEscape(project), issue) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// UnsubscribeFromIssue unsubscribes the authenticated user from the given -// issue to not receive notifications from that merge request. If the user -// is not subscribed to the issue, status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#unsubscribe-from-a-merge-request -func (s *IssuesService) UnsubscribeFromIssue(pid interface{}, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/unsubscribe", pathEscape(project), issue) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - i := new(Issue) - resp, err := s.client.Do(req, i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// ListMergeRequestsClosingIssueOptions represents the available -// ListMergeRequestsClosingIssue() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-that-will-close-issue-on-merge -type ListMergeRequestsClosingIssueOptions ListOptions - -// ListMergeRequestsClosingIssue gets all the merge requests that will close -// issue when merged. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-that-will-close-issue-on-merge -func (s *IssuesService) ListMergeRequestsClosingIssue(pid interface{}, issue int, opt *ListMergeRequestsClosingIssueOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("/projects/%s/issues/%d/closed_by", pathEscape(project), issue) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*MergeRequest - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// ListMergeRequestsRelatedToIssueOptions represents the available -// ListMergeRequestsRelatedToIssue() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-related-to-issue -type ListMergeRequestsRelatedToIssueOptions ListOptions - -// ListMergeRequestsRelatedToIssue gets all the merge requests that are -// related to the issue -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#list-merge-requests-related-to-issue -func (s *IssuesService) ListMergeRequestsRelatedToIssue(pid interface{}, issue int, opt *ListMergeRequestsRelatedToIssueOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("/projects/%s/issues/%d/related_merge_requests", - pathEscape(project), - issue, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*MergeRequest - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// SetTimeEstimate sets the time estimate for a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue -func (s *IssuesService) SetTimeEstimate(pid interface{}, issue int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.setTimeEstimate(pid, "issues", issue, opt, options...) -} - -// ResetTimeEstimate resets the time estimate for a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#reset-the-time-estimate-for-an-issue -func (s *IssuesService) ResetTimeEstimate(pid interface{}, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.resetTimeEstimate(pid, "issues", issue, options...) -} - -// AddSpentTime adds spent time for a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue -func (s *IssuesService) AddSpentTime(pid interface{}, issue int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.addSpentTime(pid, "issues", issue, opt, options...) -} - -// ResetSpentTime resets the spent time for a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#reset-spent-time-for-an-issue -func (s *IssuesService) ResetSpentTime(pid interface{}, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.resetSpentTime(pid, "issues", issue, options...) -} - -// GetTimeSpent gets the spent time for a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#get-time-tracking-stats -func (s *IssuesService) GetTimeSpent(pid interface{}, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.getTimeSpent(pid, "issues", issue, options...) -} - -// GetParticipants gets a list of issue participants. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/issues.html#participants-on-issues -func (s *IssuesService) GetParticipants(pid interface{}, issue int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/participants", pathEscape(project), issue) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var bu []*BasicUser - resp, err := s.client.Do(req, &bu) - if err != nil { - return nil, resp, err - } - - return bu, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/issues_statistics.go b/vendor/github.com/xanzy/go-gitlab/issues_statistics.go deleted file mode 100644 index 990544adb..000000000 --- a/vendor/github.com/xanzy/go-gitlab/issues_statistics.go +++ /dev/null @@ -1,186 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// IssuesStatisticsService handles communication with the issues statistics -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issues_statistics.html -type IssuesStatisticsService struct { - client *Client -} - -// IssuesStatistics represents a GitLab issues statistic. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/issues_statistics.html -type IssuesStatistics struct { - Statistics struct { - Counts struct { - All int `json:"all"` - Closed int `json:"closed"` - Opened int `json:"opened"` - } `json:"counts"` - } `json:"statistics"` -} - -func (n IssuesStatistics) String() string { - return Stringify(n) -} - -// GetIssuesStatisticsOptions represents the available GetIssuesStatistics() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics -type GetIssuesStatisticsOptions struct { - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - AssigneeUsername []string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - IIDs []int `url:"iids,omitempty" json:"iids,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - In *string `url:"in,omitempty" json:"in,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` -} - -// GetIssuesStatistics gets issues statistics on all issues the authenticated -// user has access to. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-issues-statistics -func (s *IssuesStatisticsService) GetIssuesStatistics(opt *GetIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { - req, err := s.client.NewRequest("GET", "issues_statistics", opt, options) - if err != nil { - return nil, nil, err - } - - is := new(IssuesStatistics) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// GetGroupIssuesStatisticsOptions represents the available GetGroupIssuesStatistics() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-group-issues-statistics -type GetGroupIssuesStatisticsOptions struct { - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - IIDs []int `url:"iids,omitempty" json:"iids,omitempty"` - Milestone *Milestone `url:"milestone,omitempty" json:"milestone,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - AssigneeUsername []string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` -} - -// GetGroupIssuesStatistics gets issues count statistics for given group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-group-issues-statistics -func (s *IssuesStatisticsService) GetGroupIssuesStatistics(gid interface{}, opt *GetGroupIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/issues_statistics", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - is := new(IssuesStatistics) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// GetProjectIssuesStatisticsOptions represents the available -// GetProjectIssuesStatistics() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-project-issues-statistics -type GetProjectIssuesStatisticsOptions struct { - IIDs []int `url:"iids,omitempty" json:"iids,omitempty"` - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - Milestone *Milestone `url:"milestone,omitempty" json:"milestone,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - AssigneeUsername []string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` -} - -// GetProjectIssuesStatistics gets issues count statistics for given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/issues_statistics.html#get-project-issues-statistics -func (s *IssuesStatisticsService) GetProjectIssuesStatistics(pid interface{}, opt *GetProjectIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues_statistics", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - is := new(IssuesStatistics) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/jobs.go b/vendor/github.com/xanzy/go-gitlab/jobs.go deleted file mode 100644 index 0aaa5832a..000000000 --- a/vendor/github.com/xanzy/go-gitlab/jobs.go +++ /dev/null @@ -1,433 +0,0 @@ -// -// Copyright 2017, Arkbriar -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" - "io" - "time" -) - -// JobsService handles communication with the ci builds related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/jobs.html -type JobsService struct { - client *Client -} - -// Job represents a ci build. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/jobs.html -type Job struct { - Commit *Commit `json:"commit"` - Coverage float64 `json:"coverage"` - AllowFailure bool `json:"allow_failure"` - CreatedAt *time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at"` - FinishedAt *time.Time `json:"finished_at"` - Duration float64 `json:"duration"` - ArtifactsExpireAt *time.Time `json:"artifacts_expire_at"` - ID int `json:"id"` - Name string `json:"name"` - Pipeline struct { - ID int `json:"id"` - Ref string `json:"ref"` - Sha string `json:"sha"` - Status string `json:"status"` - } `json:"pipeline"` - Ref string `json:"ref"` - Artifacts []struct { - FileType string `json:"file_type"` - Filename string `json:"filename"` - Size int `json:"size"` - FileFormat string `json:"file_format"` - } `json:"artifacts"` - ArtifactsFile struct { - Filename string `json:"filename"` - Size int `json:"size"` - } `json:"artifacts_file"` - Runner struct { - ID int `json:"id"` - Description string `json:"description"` - Active bool `json:"active"` - IsShared bool `json:"is_shared"` - Name string `json:"name"` - } `json:"runner"` - Stage string `json:"stage"` - Status string `json:"status"` - Tag bool `json:"tag"` - WebURL string `json:"web_url"` - User *User `json:"user"` -} - -// ListJobsOptions are options for two list apis -type ListJobsOptions struct { - ListOptions - Scope []BuildStateValue `url:"scope[],omitempty" json:"scope,omitempty"` -} - -// ListProjectJobs gets a list of jobs in a project. -// -// The scope of jobs to show, one or array of: created, pending, running, -// failed, success, canceled, skipped; showing all jobs if none provided -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#list-project-jobs -func (s *JobsService) ListProjectJobs(pid interface{}, opts *ListJobsOptions, options ...RequestOptionFunc) ([]Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, nil, err - } - - var jobs []Job - resp, err := s.client.Do(req, &jobs) - if err != nil { - return nil, resp, err - } - - return jobs, resp, err -} - -// ListPipelineJobs gets a list of jobs for specific pipeline in a -// project. If the pipeline ID is not found, it will respond with 404. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#list-pipeline-jobs -func (s *JobsService) ListPipelineJobs(pid interface{}, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d/jobs", pathEscape(project), pipelineID) - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, nil, err - } - - var jobs []*Job - resp, err := s.client.Do(req, &jobs) - if err != nil { - return nil, resp, err - } - - return jobs, resp, err -} - -// GetJob gets a single job of a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#get-a-single-job -func (s *JobsService) GetJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d", pathEscape(project), jobID) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// GetJobArtifacts get jobs artifacts of a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#get-job-artifacts -func (s *JobsService) GetJobArtifacts(pid interface{}, jobID int, options ...RequestOptionFunc) (io.Reader, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/artifacts", pathEscape(project), jobID) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - artifactsBuf := new(bytes.Buffer) - resp, err := s.client.Do(req, artifactsBuf) - if err != nil { - return nil, resp, err - } - - return artifactsBuf, resp, err -} - -// DownloadArtifactsFileOptions represents the available DownloadArtifactsFile() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#download-the-artifacts-archive -type DownloadArtifactsFileOptions struct { - Job *string `url:"job" json:"job"` -} - -// DownloadArtifactsFile download the artifacts file from the given -// reference name and job provided the job finished successfully. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#download-the-artifacts-archive -func (s *JobsService) DownloadArtifactsFile(pid interface{}, refName string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (io.Reader, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/artifacts/%s/download", pathEscape(project), refName) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - artifactsBuf := new(bytes.Buffer) - resp, err := s.client.Do(req, artifactsBuf) - if err != nil { - return nil, resp, err - } - - return artifactsBuf, resp, err -} - -// DownloadSingleArtifactsFile download a file from the artifacts from the -// given reference name and job provided the job finished successfully. -// Only a single file is going to be extracted from the archive and streamed -// to a client. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#download-a-single-artifact-file-by-job-id -func (s *JobsService) DownloadSingleArtifactsFile(pid interface{}, jobID int, artifactPath string, options ...RequestOptionFunc) (io.Reader, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - - u := fmt.Sprintf( - "projects/%s/jobs/%d/artifacts/%s", - pathEscape(project), - jobID, - artifactPath, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - artifactBuf := new(bytes.Buffer) - resp, err := s.client.Do(req, artifactBuf) - if err != nil { - return nil, resp, err - } - - return artifactBuf, resp, err -} - -// GetTraceFile gets a trace of a specific job of a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#get-a-trace-file -func (s *JobsService) GetTraceFile(pid interface{}, jobID int, options ...RequestOptionFunc) (io.Reader, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/trace", pathEscape(project), jobID) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - traceBuf := new(bytes.Buffer) - resp, err := s.client.Do(req, traceBuf) - if err != nil { - return nil, resp, err - } - - return traceBuf, resp, err -} - -// CancelJob cancels a single job of a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#cancel-a-job -func (s *JobsService) CancelJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/cancel", pathEscape(project), jobID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// RetryJob retries a single job of a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#retry-a-job -func (s *JobsService) RetryJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/retry", pathEscape(project), jobID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// EraseJob erases a single job of a project, removes a job -// artifacts and a job trace. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#erase-a-job -func (s *JobsService) EraseJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/erase", pathEscape(project), jobID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// KeepArtifacts prevents artifacts from being deleted when -// expiration is set. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#keep-artifacts -func (s *JobsService) KeepArtifacts(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/artifacts/keep", pathEscape(project), jobID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// PlayJob triggers a manual action to start a job. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/jobs.html#play-a-job -func (s *JobsService) PlayJob(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/play", pathEscape(project), jobID) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} - -// DeleteArtifacts delete artifacts of a job -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/job_artifacts.html#delete-artifacts -func (s *JobsService) DeleteArtifacts(pid interface{}, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/jobs/%d/artifacts", pathEscape(project), jobID) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - job := new(Job) - resp, err := s.client.Do(req, job) - if err != nil { - return nil, resp, err - } - - return job, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/keys.go b/vendor/github.com/xanzy/go-gitlab/keys.go deleted file mode 100644 index c52037713..000000000 --- a/vendor/github.com/xanzy/go-gitlab/keys.go +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2018, Patrick Webster -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// KeysService handles communication with the -// keys related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/keys.html -type KeysService struct { - client *Client -} - -// Key represents a GitLab user's SSH key. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/keys.html -type Key struct { - ID int `json:"id"` - Title string `json:"title"` - Key string `json:"key"` - CreatedAt *time.Time `json:"created_at"` - User User `json:"user"` -} - -// GetKeyWithUser gets a single key by id along with the associated -// user information. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/keys.html#get-ssh-key-with-user-by-id-of-an-ssh-key -func (s *KeysService) GetKeyWithUser(key int, options ...RequestOptionFunc) (*Key, *Response, error) { - u := fmt.Sprintf("keys/%d", key) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - k := new(Key) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/labels.go b/vendor/github.com/xanzy/go-gitlab/labels.go deleted file mode 100644 index 0aab8c5e2..000000000 --- a/vendor/github.com/xanzy/go-gitlab/labels.go +++ /dev/null @@ -1,305 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "encoding/json" - "fmt" -) - -// LabelsService handles communication with the label related methods of the -// GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html -type LabelsService struct { - client *Client -} - -// Label represents a GitLab label. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html -type Label struct { - ID int `json:"id"` - Name string `json:"name"` - Color string `json:"color"` - TextColor string `json:"text_color"` - Description string `json:"description"` - OpenIssuesCount int `json:"open_issues_count"` - ClosedIssuesCount int `json:"closed_issues_count"` - OpenMergeRequestsCount int `json:"open_merge_requests_count"` - Subscribed bool `json:"subscribed"` - Priority int `json:"priority"` - IsProjectLabel bool `json:"is_project_label"` -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (l *Label) UnmarshalJSON(data []byte) error { - type alias Label - if err := json.Unmarshal(data, (*alias)(l)); err != nil { - return err - } - - if l.Name == "" { - var raw map[string]interface{} - if err := json.Unmarshal(data, &raw); err != nil { - return err - } - if title, ok := raw["title"].(string); ok { - l.Name = title - } - } - - return nil -} - -func (l Label) String() string { - return Stringify(l) -} - -// ListLabelsOptions represents the available ListLabels() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels -type ListLabelsOptions struct { - ListOptions - WithCounts *bool `url:"with_counts,omitempty" json:"with_counts,omitempty"` - IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"` -} - -// ListLabels gets all labels for given project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels -func (s *LabelsService) ListLabels(pid interface{}, opt *ListLabelsOptions, options ...RequestOptionFunc) ([]*Label, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/labels", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var l []*Label - resp, err := s.client.Do(req, &l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// GetLabel get a single label for a given project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#get-a-single-project-label -func (s *LabelsService) GetLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Label, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/labels/%s", pathEscape(project), label) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var l *Label - resp, err := s.client.Do(req, &l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// CreateLabelOptions represents the available CreateLabel() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label -type CreateLabelOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - Color *string `url:"color,omitempty" json:"color,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` -} - -// CreateLabel creates a new label for given repository with given name and -// color. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label -func (s *LabelsService) CreateLabel(pid interface{}, opt *CreateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/labels", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - l := new(Label) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// DeleteLabelOptions represents the available DeleteLabel() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label -type DeleteLabelOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` -} - -// DeleteLabel deletes a label given by its name. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label -func (s *LabelsService) DeleteLabel(pid interface{}, opt *DeleteLabelOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/labels", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// UpdateLabelOptions represents the available UpdateLabel() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label -type UpdateLabelOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` - Color *string `url:"color,omitempty" json:"color,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` -} - -// UpdateLabel updates an existing label with new name or now color. At least -// one parameter is required, to update the label. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#edit-an-existing-label -func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/labels", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - l := new(Label) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// SubscribeToLabel subscribes the authenticated user to a label to receive -// notifications. If the user is already subscribed to the label, the status -// code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/labels.html#subscribe-to-a-label -func (s *LabelsService) SubscribeToLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Label, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/labels/%s/subscribe", pathEscape(project), label) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - l := new(Label) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, err -} - -// UnsubscribeFromLabel unsubscribes the authenticated user from a label to not -// receive notifications from it. If the user is not subscribed to the label, the -// status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/labels.html#unsubscribe-from-a-label -func (s *LabelsService) UnsubscribeFromLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/labels/%s/unsubscribe", pathEscape(project), label) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// PromoteLabel Promotes a project label to a group label. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/labels.html#promote-a-project-label-to-a-group-label -func (s *LabelsService) PromoteLabel(pid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - label, err := parseID(labelID) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/labels/%s/promote", pathEscape(project), label) - - req, err := s.client.NewRequest("PUT", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go b/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go deleted file mode 100644 index 9ef8a7e58..000000000 --- a/vendor/github.com/xanzy/go-gitlab/merge_request_approvals.go +++ /dev/null @@ -1,392 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// MergeRequestApprovalsService handles communication with the merge request -// approvals related methods of the GitLab API. This includes reading/updating -// approval settings and approve/unapproving merge requests -// -// GitLab API docs: https://docs.gitlab.com/ee/api/merge_request_approvals.html -type MergeRequestApprovalsService struct { - client *Client -} - -// MergeRequestApprovals represents GitLab merge request approvals. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals -type MergeRequestApprovals struct { - ID int `json:"id"` - ProjectID int `json:"project_id"` - Title string `json:"title"` - Description string `json:"description"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - MergeStatus string `json:"merge_status"` - ApprovalsBeforeMerge int `json:"approvals_before_merge"` - ApprovalsRequired int `json:"approvals_required"` - ApprovalsLeft int `json:"approvals_left"` - ApprovedBy []*MergeRequestApproverUser `json:"approved_by"` - Approvers []*MergeRequestApproverUser `json:"approvers"` - ApproverGroups []*MergeRequestApproverGroup `json:"approver_groups"` - SuggestedApprovers []*BasicUser `json:"suggested_approvers"` -} - -func (m MergeRequestApprovals) String() string { - return Stringify(m) -} - -// MergeRequestApproverGroup represents GitLab project level merge request approver group. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals -type MergeRequestApproverGroup struct { - Group struct { - ID int `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Description string `json:"description"` - Visibility string `json:"visibility"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - FullName string `json:"full_name"` - FullPath string `json:"full_path"` - LFSEnabled bool `json:"lfs_enabled"` - RequestAccessEnabled bool `json:"request_access_enabled"` - } -} - -// MergeRequestApprovalRule represents a GitLab merge request approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-merge-request-level-rules -type MergeRequestApprovalRule struct { - ID int `json:"id"` - Name string `json:"name"` - RuleType string `json:"rule_type"` - EligibleApprovers []*BasicUser `json:"eligible_approvers"` - ApprovalsRequired int `json:"approvals_required"` - SourceRule *ProjectApprovalRule `json:"source_rule"` - Users []*BasicUser `json:"users"` - Groups []*Group `json:"groups"` - ContainsHiddenGroups bool `json:"contains_hidden_groups"` - ApprovedBy []*BasicUser `json:"approved_by"` - Approved bool `json:"approved"` -} - -// MergeRequestApprovalState represents a GitLab merge request approval state. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-the-approval-state-of-merge-requests -type MergeRequestApprovalState struct { - ApprovalRulesOverwritten bool `json:"approval_rules_overwritten"` - Rules []*MergeRequestApprovalRule `json:"rules"` -} - -// String is a stringify for MergeRequestApprovalRule -func (s MergeRequestApprovalRule) String() string { - return Stringify(s) -} - -// MergeRequestApproverUser represents GitLab project level merge request approver user. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals -type MergeRequestApproverUser struct { - User *BasicUser -} - -// ApproveMergeRequestOptions represents the available ApproveMergeRequest() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request -type ApproveMergeRequestOptions struct { - SHA *string `url:"sha,omitempty" json:"sha,omitempty"` -} - -// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha -// is provided then it must match the sha at the HEAD of the MR. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request -func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid interface{}, mr int, opt *ApproveMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", pathEscape(project), mr) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequestApprovals) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// UnapproveMergeRequest unapproves a previously approved merge request on GitLab. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#unapprove-merge-request -func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid interface{}, mr int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", pathEscape(project), mr) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ChangeMergeRequestApprovalConfigurationOptions represents the available -// ChangeMergeRequestApprovalConfiguration() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration -type ChangeMergeRequestApprovalConfigurationOptions struct { - ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` -} - -// GetConfiguration shows information about single merge request approvals -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-configuration-1 -func (s *MergeRequestApprovalsService) GetConfiguration(pid interface{}, mr int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", pathEscape(project), mr) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequestApprovals) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// ChangeApprovalConfiguration updates the approval configuration of a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration -func (s *MergeRequestApprovalsService) ChangeApprovalConfiguration(pid interface{}, mergeRequest int, opt *ChangeMergeRequestApprovalConfigurationOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// ChangeMergeRequestAllowedApproversOptions represents the available -// ChangeMergeRequestAllowedApprovers() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers-for-merge-request -type ChangeMergeRequestAllowedApproversOptions struct { - ApproverIDs []int `url:"approver_ids" json:"approver_ids"` - ApproverGroupIDs []int `url:"approver_group_ids" json:"approver_group_ids"` -} - -// ChangeAllowedApprovers updates the approvers for a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers-for-merge-request -func (s *MergeRequestApprovalsService) ChangeAllowedApprovers(pid interface{}, mergeRequest int, opt *ChangeMergeRequestAllowedApproversOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approvers", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetApprovalRules requests information about a merge request’s approval rules -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-merge-request-level-rules -func (s *MergeRequestApprovalsService) GetApprovalRules(pid interface{}, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var par []*MergeRequestApprovalRule - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// GetApprovalState requests information about a merge request’s approval state -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-the-approval-state-of-merge-requests -func (s *MergeRequestApprovalsService) GetApprovalState(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovalState, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_state", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var pas *MergeRequestApprovalState - resp, err := s.client.Do(req, &pas) - if err != nil { - return nil, resp, err - } - - return pas, resp, err -} - -// CreateMergeRequestApprovalRuleOptions represents the available CreateApprovalRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-merge-request-level-rule -type CreateMergeRequestApprovalRuleOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` - ApprovalProjectRuleID *int `url:"approval_project_rule_id,omitempty" json:"approval_project_rule_id,omitempty"` - UserIDs []int `url:"user_ids,omitempty" json:"user_ids,omitempty"` - GroupIDs []int `url:"group_ids,omitempty" json:"group_ids,omitempty"` -} - -// CreateApprovalRule creates a new MR level approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-merge-request-level-rule -func (s *MergeRequestApprovalsService) CreateApprovalRule(pid interface{}, mergeRequest int, opt *CreateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - par := new(MergeRequestApprovalRule) - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// UpdateMergeRequestApprovalRuleOptions represents the available UpdateApprovalRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#update-merge-request-level-rule -type UpdateMergeRequestApprovalRuleOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` - UserIDs []int `url:"user_ids,omitempty" json:"user_ids,omitempty"` - GroupIDs []int `url:"group_ids,omitempty" json:"group_ids,omitempty"` -} - -// UpdateApprovalRule updates an existing approval rule with new options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#update-merge-request-level-rule -func (s *MergeRequestApprovalsService) UpdateApprovalRule(pid interface{}, mergeRequest int, approvalRule int, opt *UpdateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules/%d", pathEscape(project), mergeRequest, approvalRule) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - par := new(MergeRequestApprovalRule) - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// DeleteApprovalRule deletes a mr level approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#delete-merge-request-level-rule -func (s *MergeRequestApprovalsService) DeleteApprovalRule(pid interface{}, mergeRequest int, approvalRule int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules/%d", pathEscape(project), mergeRequest, approvalRule) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/merge_requests.go b/vendor/github.com/xanzy/go-gitlab/merge_requests.go deleted file mode 100644 index c8f70c99c..000000000 --- a/vendor/github.com/xanzy/go-gitlab/merge_requests.go +++ /dev/null @@ -1,902 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// MergeRequestsService handles communication with the merge requests related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html -type MergeRequestsService struct { - client *Client - timeStats *timeStatsService -} - -// MergeRequest represents a GitLab merge request. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html -type MergeRequest struct { - ID int `json:"id"` - IID int `json:"iid"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - ProjectID int `json:"project_id"` - Title string `json:"title"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - Upvotes int `json:"upvotes"` - Downvotes int `json:"downvotes"` - Author *BasicUser `json:"author"` - Assignee *BasicUser `json:"assignee"` - Assignees []*BasicUser `json:"assignees"` - SourceProjectID int `json:"source_project_id"` - TargetProjectID int `json:"target_project_id"` - Labels Labels `json:"labels"` - Description string `json:"description"` - WorkInProgress bool `json:"work_in_progress"` - Milestone *Milestone `json:"milestone"` - MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` - MergeStatus string `json:"merge_status"` - MergeError string `json:"merge_error"` - MergedBy *BasicUser `json:"merged_by"` - MergedAt *time.Time `json:"merged_at"` - ClosedBy *BasicUser `json:"closed_by"` - ClosedAt *time.Time `json:"closed_at"` - Subscribed bool `json:"subscribed"` - SHA string `json:"sha"` - MergeCommitSHA string `json:"merge_commit_sha"` - SquashCommitSHA string `json:"squash_commit_sha"` - UserNotesCount int `json:"user_notes_count"` - ChangesCount string `json:"changes_count"` - ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"` - ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` - WebURL string `json:"web_url"` - DiscussionLocked bool `json:"discussion_locked"` - Changes []struct { - OldPath string `json:"old_path"` - NewPath string `json:"new_path"` - AMode string `json:"a_mode"` - BMode string `json:"b_mode"` - Diff string `json:"diff"` - NewFile bool `json:"new_file"` - RenamedFile bool `json:"renamed_file"` - DeletedFile bool `json:"deleted_file"` - } `json:"changes"` - User struct { - CanMerge bool `json:"can_merge"` - } `json:"user"` - TimeStats *TimeStats `json:"time_stats"` - Squash bool `json:"squash"` - Pipeline *PipelineInfo `json:"pipeline"` - HeadPipeline *Pipeline `json:"head_pipeline"` - DiffRefs struct { - BaseSha string `json:"base_sha"` - HeadSha string `json:"head_sha"` - StartSha string `json:"start_sha"` - } `json:"diff_refs"` - DivergedCommitsCount int `json:"diverged_commits_count"` - RebaseInProgress bool `json:"rebase_in_progress"` - ApprovalsBeforeMerge int `json:"approvals_before_merge"` - Reference string `json:"reference"` - TaskCompletionStatus struct { - Count int `json:"count"` - CompletedCount int `json:"completed_count"` - } `json:"task_completion_status"` - HasConflicts bool `json:"has_conflicts"` -} - -func (m MergeRequest) String() string { - return Stringify(m) -} - -// MergeRequestDiffVersion represents Gitlab merge request version. -// -// Gitlab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-a-single-mr-diff-version -type MergeRequestDiffVersion struct { - ID int `json:"id"` - HeadCommitSHA string `json:"head_commit_sha,omitempty"` - BaseCommitSHA string `json:"base_commit_sha,omitempty"` - StartCommitSHA string `json:"start_commit_sha,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - MergeRequestID int `json:"merge_request_id,omitempty"` - State string `json:"state,omitempty"` - RealSize string `json:"real_size,omitempty"` - Commits []*Commit `json:"commits,omitempty"` - Diffs []*Diff `json:"diffs,omitempty"` -} - -func (m MergeRequestDiffVersion) String() string { - return Stringify(m) -} - -// ListMergeRequestsOptions represents the available ListMergeRequests() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests -type ListMergeRequestsOptions struct { - ListOptions - State *string `url:"state,omitempty" json:"state,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - View *string `url:"view,omitempty" json:"view,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` - TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - In *string `url:"in,omitempty" json:"in,omitempty"` - WIP *string `url:"wip,omitempty" json:"wip,omitempty"` -} - -// ListMergeRequests gets all merge requests. The state parameter can be used -// to get only merge requests with a given state (opened, closed, or merged) -// or all of them (all). The pagination parameters page and per_page can be -// used to restrict the list of merge requests. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests -func (s *MergeRequestsService) ListMergeRequests(opt *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - req, err := s.client.NewRequest("GET", "merge_requests", opt, options) - if err != nil { - return nil, nil, err - } - - var m []*MergeRequest - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// ListGroupMergeRequestsOptions represents the available ListGroupMergeRequests() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-group-merge-requests -type ListGroupMergeRequestsOptions struct { - ListOptions - State *string `url:"state,omitempty" json:"state,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - View *string `url:"view,omitempty" json:"view,omitempty"` - Labels Labels `url:"labels,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` - TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` -} - -// ListGroupMergeRequests gets all merge requests for this group. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-group-merge-requests -func (s *MergeRequestsService) ListGroupMergeRequests(gid interface{}, opt *ListGroupMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/merge_requests", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*MergeRequest - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// ListProjectMergeRequestsOptions represents the available ListMergeRequests() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-project-merge-requests -type ListProjectMergeRequestsOptions struct { - ListOptions - IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` - View *string `url:"view,omitempty" json:"view,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - NotLabels Labels `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` - WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` - WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` - SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` - TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - WIP *string `url:"wip,omitempty" json:"wip,omitempty"` -} - -// ListProjectMergeRequests gets all merge requests for this project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-project-merge-requests -func (s *MergeRequestsService) ListProjectMergeRequests(pid interface{}, opt *ListProjectMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*MergeRequest - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetMergeRequestsOptions represents the available GetMergeRequests() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr -type GetMergeRequestsOptions struct { - RenderHTML *bool `url:"render_html,omitempty" json:"render_html,omitempty"` - IncludeDivergedCommitsCount *bool `url:"include_diverged_commits_count,omitempty" json:"include_diverged_commits_count,omitempty"` - IncludeRebaseInProgress *bool `url:"include_rebase_in_progress,omitempty" json:"include_rebase_in_progress,omitempty"` -} - -// GetMergeRequest shows information about a single merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr -func (s *MergeRequestsService) GetMergeRequest(pid interface{}, mergeRequest int, opt *GetMergeRequestsOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetMergeRequestApprovals gets information about a merge requests approvals -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals -func (s *MergeRequestsService) GetMergeRequestApprovals(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - a := new(MergeRequestApprovals) - resp, err := s.client.Do(req, a) - if err != nil { - return nil, resp, err - } - - return a, resp, err -} - -// GetMergeRequestCommitsOptions represents the available GetMergeRequestCommits() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits -type GetMergeRequestCommitsOptions ListOptions - -// GetMergeRequestCommits gets a list of merge request commits. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits -func (s *MergeRequestsService) GetMergeRequestCommits(pid interface{}, mergeRequest int, opt *GetMergeRequestCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/commits", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var c []*Commit - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// GetMergeRequestChanges shows information about the merge request including -// its files and changes. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-changes -func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/changes", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetMergeRequestParticipants gets a list of merge request participants. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_requests.html#get-single-mr-participants -func (s *MergeRequestsService) GetMergeRequestParticipants(pid interface{}, mergeRequest int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/participants", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var ps []*BasicUser - resp, err := s.client.Do(req, &ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// ListMergeRequestPipelines gets all pipelines for the provided merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-mr-pipelines -func (s *MergeRequestsService) ListMergeRequestPipelines(pid interface{}, mergeRequest int, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/pipelines", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var p []*PipelineInfo - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CreateMergeRequestPipeline creates a new pipeline for a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr-pipeline -func (s *MergeRequestsService) CreateMergeRequestPipeline(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*PipelineInfo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/pipelines", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineInfo) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetIssuesClosedOnMergeOptions represents the available GetIssuesClosedOnMerge() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-issues-that-will-close-on-merge -type GetIssuesClosedOnMergeOptions ListOptions - -// GetIssuesClosedOnMerge gets all the issues that would be closed by merging the -// provided merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#list-issues-that-will-close-on-merge -func (s *MergeRequestsService) GetIssuesClosedOnMerge(pid interface{}, mergeRequest int, opt *GetIssuesClosedOnMergeOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/closes_issues", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// CreateMergeRequestOptions represents the available CreateMergeRequest() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr -type CreateMergeRequestOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` - TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` - TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - RemoveSourceBranch *bool `url:"remove_source_branch,omitempty" json:"remove_source_branch,omitempty"` - Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` - AllowCollaboration *bool `url:"allow_collaboration,omitempty" json:"allow_collaboration,omitempty"` -} - -// CreateMergeRequest creates a new merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr -func (s *MergeRequestsService) CreateMergeRequest(pid interface{}, opt *CreateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// UpdateMergeRequestOptions represents the available UpdateMergeRequest() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr -type UpdateMergeRequestOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` - AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` - AssigneeIDs []int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` - Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"` - AddLabels Labels `url:"add_labels,comma,omitempty" json:"add_labels,omitempty"` - RemoveLabels Labels `url:"remove_labels,comma,omitempty" json:"remove_labels,omitempty"` - MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` - StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` - RemoveSourceBranch *bool `url:"remove_source_branch,omitempty" json:"remove_source_branch,omitempty"` - Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` - DiscussionLocked *bool `url:"discussion_locked,omitempty" json:"discussion_locked,omitempty"` - AllowCollaboration *bool `url:"allow_collaboration,omitempty" json:"allow_collaboration,omitempty"` -} - -// UpdateMergeRequest updates an existing project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr -func (s *MergeRequestsService) UpdateMergeRequest(pid interface{}, mergeRequest int, opt *UpdateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// DeleteMergeRequest deletes a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#delete-a-merge-request -func (s *MergeRequestsService) DeleteMergeRequest(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// AcceptMergeRequestOptions represents the available AcceptMergeRequest() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr -type AcceptMergeRequestOptions struct { - MergeCommitMessage *string `url:"merge_commit_message,omitempty" json:"merge_commit_message,omitempty"` - SquashCommitMessage *string `url:"squash_commit_message,omitempty" json:"squash_commit_message,omitempty"` - Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` - ShouldRemoveSourceBranch *bool `url:"should_remove_source_branch,omitempty" json:"should_remove_source_branch,omitempty"` - MergeWhenPipelineSucceeds *bool `url:"merge_when_pipeline_succeeds,omitempty" json:"merge_when_pipeline_succeeds,omitempty"` - SHA *string `url:"sha,omitempty" json:"sha,omitempty"` -} - -// AcceptMergeRequest merges changes submitted with MR using this API. If merge -// success you get 200 OK. If it has some conflicts and can not be merged - you -// get 405 and error message 'Branch cannot be merged'. If merge request is -// already merged or closed - you get 405 and error message 'Method Not Allowed' -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr -func (s *MergeRequestsService) AcceptMergeRequest(pid interface{}, mergeRequest int, opt *AcceptMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/merge", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// CancelMergeWhenPipelineSucceeds cancels a merge when pipeline succeeds. If -// you don't have permissions to accept this merge request - you'll get a 401. -// If the merge request is already merged or closed - you get 405 and error -// message 'Method Not Allowed'. In case the merge request is not set to be -// merged when the pipeline succeeds, you'll also get a 406 error. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#cancel-merge-when-pipeline-succeeds -func (s *MergeRequestsService) CancelMergeWhenPipelineSucceeds(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/cancel_merge_when_pipeline_succeeds", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("PUT", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// RebaseMergeRequest automatically rebases the source_branch of the merge -// request against its target_branch. If you don’t have permissions to push -// to the merge request’s source branch, you’ll get a 403 Forbidden response. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#rebase-a-merge-request -func (s *MergeRequestsService) RebaseMergeRequest(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/rebase", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("PUT", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// GetMergeRequestDiffVersionsOptions represents the available -// GetMergeRequestDiffVersions() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-mr-diff-versions -type GetMergeRequestDiffVersionsOptions ListOptions - -// GetMergeRequestDiffVersions get a list of merge request diff versions. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-mr-diff-versions -func (s *MergeRequestsService) GetMergeRequestDiffVersions(pid interface{}, mergeRequest int, opt *GetMergeRequestDiffVersionsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiffVersion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/versions", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var v []*MergeRequestDiffVersion - resp, err := s.client.Do(req, &v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// GetSingleMergeRequestDiffVersion get a single MR diff version -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-a-single-mr-diff-version -func (s *MergeRequestsService) GetSingleMergeRequestDiffVersion(pid interface{}, mergeRequest, version int, options ...RequestOptionFunc) (*MergeRequestDiffVersion, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/versions/%d", pathEscape(project), mergeRequest, version) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var v = new(MergeRequestDiffVersion) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// SubscribeToMergeRequest subscribes the authenticated user to the given merge -// request to receive notifications. If the user is already subscribed to the -// merge request, the status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#subscribe-to-a-merge-request -func (s *MergeRequestsService) SubscribeToMergeRequest(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/subscribe", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// UnsubscribeFromMergeRequest unsubscribes the authenticated user from the -// given merge request to not receive notifications from that merge request. -// If the user is not subscribed to the merge request, status code 304 is -// returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#unsubscribe-from-a-merge-request -func (s *MergeRequestsService) UnsubscribeFromMergeRequest(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/unsubscribe", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(MergeRequest) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// CreateTodo manually creates a todo for the current user on a merge request. -// If there already exists a todo for the user on that merge request, -// status code 304 is returned. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#create-a-todo -func (s *MergeRequestsService) CreateTodo(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*Todo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/todo", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - t := new(Todo) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// SetTimeEstimate sets the time estimate for a single project merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#set-a-time-estimate-for-a-merge-request -func (s *MergeRequestsService) SetTimeEstimate(pid interface{}, mergeRequest int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.setTimeEstimate(pid, "merge_requests", mergeRequest, opt, options...) -} - -// ResetTimeEstimate resets the time estimate for a single project merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#reset-the-time-estimate-for-a-merge-request -func (s *MergeRequestsService) ResetTimeEstimate(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.resetTimeEstimate(pid, "merge_requests", mergeRequest, options...) -} - -// AddSpentTime adds spent time for a single project merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#add-spent-time-for-a-merge-request -func (s *MergeRequestsService) AddSpentTime(pid interface{}, mergeRequest int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.addSpentTime(pid, "merge_requests", mergeRequest, opt, options...) -} - -// ResetSpentTime resets the spent time for a single project merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#reset-spent-time-for-a-merge-request -func (s *MergeRequestsService) ResetSpentTime(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.resetSpentTime(pid, "merge_requests", mergeRequest, options...) -} - -// GetTimeSpent gets the spent time for a single project merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/merge_requests.html#get-time-tracking-stats -func (s *MergeRequestsService) GetTimeSpent(pid interface{}, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - return s.timeStats.getTimeSpent(pid, "merge_requests", mergeRequest, options...) -} diff --git a/vendor/github.com/xanzy/go-gitlab/milestones.go b/vendor/github.com/xanzy/go-gitlab/milestones.go deleted file mode 100644 index 3d881d51a..000000000 --- a/vendor/github.com/xanzy/go-gitlab/milestones.go +++ /dev/null @@ -1,269 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// MilestonesService handles communication with the milestone related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html -type MilestonesService struct { - client *Client -} - -// Milestone represents a GitLab milestone. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html -type Milestone struct { - ID int `json:"id"` - IID int `json:"iid"` - ProjectID int `json:"project_id"` - Title string `json:"title"` - Description string `json:"description"` - StartDate *ISOTime `json:"start_date"` - DueDate *ISOTime `json:"due_date"` - State string `json:"state"` - WebURL string `json:"web_url"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` - Expired *bool `json:"expired"` -} - -func (m Milestone) String() string { - return Stringify(m) -} - -// ListMilestonesOptions represents the available ListMilestones() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones -type ListMilestonesOptions struct { - ListOptions - IIDs []int `url:"iids,omitempty" json:"iids,omitempty"` - Title *string `url:"title,omitempty" json:"title,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` -} - -// ListMilestones returns a list of project milestones. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones -func (s *MilestonesService) ListMilestones(pid interface{}, opt *ListMilestonesOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*Milestone - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// GetMilestone gets a single project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#get-single-milestone -func (s *MilestonesService) GetMilestone(pid interface{}, milestone int, options ...RequestOptionFunc) (*Milestone, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones/%d", pathEscape(project), milestone) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - m := new(Milestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// CreateMilestoneOptions represents the available CreateMilestone() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone -type CreateMilestoneOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` -} - -// CreateMilestone creates a new project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone -func (s *MilestonesService) CreateMilestone(pid interface{}, opt *CreateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(Milestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// UpdateMilestoneOptions represents the available UpdateMilestone() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone -type UpdateMilestoneOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` - DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` - StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` -} - -// UpdateMilestone updates an existing project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone -func (s *MilestonesService) UpdateMilestone(pid interface{}, milestone int, opt *UpdateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones/%d", pathEscape(project), milestone) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - m := new(Milestone) - resp, err := s.client.Do(req, m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} - -// DeleteMilestone deletes a specified project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#delete-project-milestone -func (s *MilestonesService) DeleteMilestone(pid interface{}, milestone int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/milestones/%d", pathEscape(project), milestone) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - return s.client.Do(req, nil) -} - -// GetMilestoneIssuesOptions represents the available GetMilestoneIssues() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone -type GetMilestoneIssuesOptions ListOptions - -// GetMilestoneIssues gets all issues assigned to a single project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone -func (s *MilestonesService) GetMilestoneIssues(pid interface{}, milestone int, opt *GetMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones/%d/issues", pathEscape(project), milestone) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var i []*Issue - resp, err := s.client.Do(req, &i) - if err != nil { - return nil, resp, err - } - - return i, resp, err -} - -// GetMilestoneMergeRequestsOptions represents the available -// GetMilestoneMergeRequests() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#get-all-merge-requests-assigned-to-a-single-milestone -type GetMilestoneMergeRequestsOptions ListOptions - -// GetMilestoneMergeRequests gets all merge requests assigned to a single -// project milestone. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/milestones.html#get-all-merge-requests-assigned-to-a-single-milestone -func (s *MilestonesService) GetMilestoneMergeRequests(pid interface{}, milestone int, opt *GetMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/milestones/%d/merge_requests", pathEscape(project), milestone) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var mr []*MergeRequest - resp, err := s.client.Do(req, &mr) - if err != nil { - return nil, resp, err - } - - return mr, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/namespaces.go b/vendor/github.com/xanzy/go-gitlab/namespaces.go deleted file mode 100644 index 4e928804d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/namespaces.go +++ /dev/null @@ -1,122 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// NamespacesService handles communication with the namespace related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html -type NamespacesService struct { - client *Client -} - -// Namespace represents a GitLab namespace. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html -type Namespace struct { - ID int `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Kind string `json:"kind"` - FullPath string `json:"full_path"` - ParentID int `json:"parent_id"` - MembersCountWithDescendants int `json:"members_count_with_descendants"` -} - -func (n Namespace) String() string { - return Stringify(n) -} - -// ListNamespacesOptions represents the available ListNamespaces() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces -type ListNamespacesOptions struct { - ListOptions - Search *string `url:"search,omitempty" json:"search,omitempty"` -} - -// ListNamespaces gets a list of projects accessible by the authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces -func (s *NamespacesService) ListNamespaces(opt *ListNamespacesOptions, options ...RequestOptionFunc) ([]*Namespace, *Response, error) { - req, err := s.client.NewRequest("GET", "namespaces", opt, options) - if err != nil { - return nil, nil, err - } - - var n []*Namespace - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// SearchNamespace gets all namespaces that match your string in their name -// or path. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/namespaces.html#search-for-namespace -func (s *NamespacesService) SearchNamespace(query string, options ...RequestOptionFunc) ([]*Namespace, *Response, error) { - var q struct { - Search string `url:"search,omitempty" json:"search,omitempty"` - } - q.Search = query - - req, err := s.client.NewRequest("GET", "namespaces", &q, options) - if err != nil { - return nil, nil, err - } - - var n []*Namespace - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// GetNamespace gets a namespace by id. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/namespaces.html#get-namespace-by-id -func (s *NamespacesService) GetNamespace(id interface{}, options ...RequestOptionFunc) (*Namespace, *Response, error) { - namespace, err := parseID(id) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("namespaces/%s", namespace) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - n := new(Namespace) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/notes.go b/vendor/github.com/xanzy/go-gitlab/notes.go deleted file mode 100644 index b8d599e4c..000000000 --- a/vendor/github.com/xanzy/go-gitlab/notes.go +++ /dev/null @@ -1,678 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// NotesService handles communication with the notes related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html -type NotesService struct { - client *Client -} - -// Note represents a GitLab note. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html -type Note struct { - ID int `json:"id"` - Body string `json:"body"` - Attachment string `json:"attachment"` - Title string `json:"title"` - FileName string `json:"file_name"` - Author struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"author"` - System bool `json:"system"` - ExpiresAt *time.Time `json:"expires_at"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` - NoteableID int `json:"noteable_id"` - NoteableType string `json:"noteable_type"` - Position *NotePosition `json:"position"` - Resolvable bool `json:"resolvable"` - Resolved bool `json:"resolved"` - ResolvedBy struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"resolved_by"` - NoteableIID int `json:"noteable_iid"` -} - -// NotePosition represents the position attributes of a note. -type NotePosition struct { - BaseSHA string `json:"base_sha"` - StartSHA string `json:"start_sha"` - HeadSHA string `json:"head_sha"` - PositionType string `json:"position_type"` - NewPath string `json:"new_path,omitempty"` - NewLine int `json:"new_line,omitempty"` - OldPath string `json:"old_path,omitempty"` - OldLine int `json:"old_line,omitempty"` - Width int `json:"width,omitempty"` - Height int `json:"height,omitempty"` - X int `json:"x,omitempty"` - Y int `json:"y,omitempty"` -} - -func (n Note) String() string { - return Stringify(n) -} - -// ListIssueNotesOptions represents the available ListIssueNotes() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes -type ListIssueNotesOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListIssueNotes gets a list of all notes for a single issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes -func (s *NotesService) ListIssueNotes(pid interface{}, issue int, opt *ListIssueNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/notes", pathEscape(project), issue) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var n []*Note - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// GetIssueNote returns a single note for a specific project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#get-single-issue-note -func (s *NotesService) GetIssueNote(pid interface{}, issue, note int, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", pathEscape(project), issue, note) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// CreateIssueNoteOptions represents the available CreateIssueNote() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note -type CreateIssueNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` - CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` -} - -// CreateIssueNote creates a new note to a single project issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note -func (s *NotesService) CreateIssueNote(pid interface{}, issue int, opt *CreateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/notes", pathEscape(project), issue) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateIssueNoteOptions represents the available UpdateIssueNote() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note -type UpdateIssueNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// UpdateIssueNote modifies existing note of an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note -func (s *NotesService) UpdateIssueNote(pid interface{}, issue, note int, opt *UpdateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", pathEscape(project), issue, note) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteIssueNote deletes an existing note of an issue. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#delete-an-issue-note -func (s *NotesService) DeleteIssueNote(pid interface{}, issue, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", pathEscape(project), issue, note) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListSnippetNotesOptions represents the available ListSnippetNotes() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes -type ListSnippetNotesOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListSnippetNotes gets a list of all notes for a single snippet. Snippet -// notes are comments users can post to a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes -func (s *NotesService) ListSnippetNotes(pid interface{}, snippet int, opt *ListSnippetNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/notes", pathEscape(project), snippet) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var n []*Note - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// GetSnippetNote returns a single note for a given snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#get-single-snippet-note -func (s *NotesService) GetSnippetNote(pid interface{}, snippet, note int, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", pathEscape(project), snippet, note) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// CreateSnippetNoteOptions represents the available CreateSnippetNote() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note -type CreateSnippetNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// CreateSnippetNote creates a new note for a single snippet. Snippet notes are -// comments users can post to a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note -func (s *NotesService) CreateSnippetNote(pid interface{}, snippet int, opt *CreateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/notes", pathEscape(project), snippet) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateSnippetNoteOptions represents the available UpdateSnippetNote() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note -type UpdateSnippetNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// UpdateSnippetNote modifies existing note of a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note -func (s *NotesService) UpdateSnippetNote(pid interface{}, snippet, note int, opt *UpdateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", pathEscape(project), snippet, note) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteSnippetNote deletes an existing note of a snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#delete-a-snippet-note -func (s *NotesService) DeleteSnippetNote(pid interface{}, snippet, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", pathEscape(project), snippet, note) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListMergeRequestNotesOptions represents the available ListMergeRequestNotes() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes -type ListMergeRequestNotesOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListMergeRequestNotes gets a list of all notes for a single merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes -func (s *NotesService) ListMergeRequestNotes(pid interface{}, mergeRequest int, opt *ListMergeRequestNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var n []*Note - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// GetMergeRequestNote returns a single note for a given merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#get-single-merge-request-note -func (s *NotesService) GetMergeRequestNote(pid interface{}, mergeRequest, note int, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/notes/%d", pathEscape(project), mergeRequest, note) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// CreateMergeRequestNoteOptions represents the available -// CreateMergeRequestNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note -type CreateMergeRequestNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// CreateMergeRequestNote creates a new note for a single merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note -func (s *NotesService) CreateMergeRequestNote(pid interface{}, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", pathEscape(project), mergeRequest) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateMergeRequestNoteOptions represents the available -// UpdateMergeRequestNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note -type UpdateMergeRequestNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// UpdateMergeRequestNote modifies existing note of a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note -func (s *NotesService) UpdateMergeRequestNote(pid interface{}, mergeRequest, note int, opt *UpdateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/merge_requests/%d/notes/%d", pathEscape(project), mergeRequest, note) - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteMergeRequestNote deletes an existing note of a merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notes.html#delete-a-merge-request-note -func (s *NotesService) DeleteMergeRequestNote(pid interface{}, mergeRequest, note int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf( - "projects/%s/merge_requests/%d/notes/%d", pathEscape(project), mergeRequest, note) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListEpicNotesOptions represents the available ListEpicNotes() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#list-all-epic-notes -type ListEpicNotesOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListEpicNotes gets a list of all notes for a single epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#list-all-epic-notes -func (s *NotesService) ListEpicNotes(gid interface{}, epic int, opt *ListEpicNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/notes", pathEscape(group), epic) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var n []*Note - resp, err := s.client.Do(req, &n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// GetEpicNote returns a single note for an epic. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#get-single-epic-note -func (s *NotesService) GetEpicNote(gid interface{}, epic, note int, options ...RequestOptionFunc) (*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", pathEscape(group), epic, note) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// CreateEpicNoteOptions represents the available CreateEpicNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#create-new-epic-note -type CreateEpicNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// CreateEpicNote creates a new note for a single merge request. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#create-new-epic-note -func (s *NotesService) CreateEpicNote(gid interface{}, epic int, opt *CreateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/notes", pathEscape(group), epic) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// UpdateEpicNoteOptions represents the available UpdateEpicNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/notes.html#modify-existing-epic-note -type UpdateEpicNoteOptions struct { - Body *string `url:"body,omitempty" json:"body,omitempty"` -} - -// UpdateEpicNote modifies existing note of an epic. -// -// https://docs.gitlab.com/ee/api/notes.html#modify-existing-epic-note -func (s *NotesService) UpdateEpicNote(gid interface{}, epic, note int, opt *UpdateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", pathEscape(group), epic, note) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - n := new(Note) - resp, err := s.client.Do(req, n) - if err != nil { - return nil, resp, err - } - - return n, resp, err -} - -// DeleteEpicNote deletes an existing note of a merge request. -// -// https://docs.gitlab.com/ee/api/notes.html#delete-an-epic-note -func (s *NotesService) DeleteEpicNote(gid interface{}, epic, note int, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", pathEscape(group), epic, note) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/notifications.go b/vendor/github.com/xanzy/go-gitlab/notifications.go deleted file mode 100644 index 70c8cb75b..000000000 --- a/vendor/github.com/xanzy/go-gitlab/notifications.go +++ /dev/null @@ -1,213 +0,0 @@ -package gitlab - -import ( - "errors" - "fmt" -) - -// NotificationSettingsService handles communication with the notification settings -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/notification_settings.html -type NotificationSettingsService struct { - client *Client -} - -// NotificationSettings represents the Gitlab notification setting. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings -type NotificationSettings struct { - Level NotificationLevelValue `json:"level"` - NotificationEmail string `json:"notification_email"` - Events *NotificationEvents `json:"events"` -} - -// NotificationEvents represents the available notification setting events. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings -type NotificationEvents struct { - CloseIssue bool `json:"close_issue"` - CloseMergeRequest bool `json:"close_merge_request"` - FailedPipeline bool `json:"failed_pipeline"` - MergeMergeRequest bool `json:"merge_merge_request"` - NewIssue bool `json:"new_issue"` - NewMergeRequest bool `json:"new_merge_request"` - NewNote bool `json:"new_note"` - ReassignIssue bool `json:"reassign_issue"` - ReassignMergeRequest bool `json:"reassign_merge_request"` - ReopenIssue bool `json:"reopen_issue"` - ReopenMergeRequest bool `json:"reopen_merge_request"` - SuccessPipeline bool `json:"success_pipeline"` -} - -func (ns NotificationSettings) String() string { - return Stringify(ns) -} - -// GetGlobalSettings returns current notification settings and email address. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#global-notification-settings -func (s *NotificationSettingsService) GetGlobalSettings(options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - u := "notification_settings" - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} - -// NotificationSettingsOptions represents the available options that can be passed -// to the API when updating the notification settings. -type NotificationSettingsOptions struct { - Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"` - NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"` - CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"` - CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"` - FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"` - MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"` - NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"` - NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"` - NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"` - ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"` - ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"` - ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"` - ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"` - SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"` -} - -// UpdateGlobalSettings updates current notification settings and email address. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#update-global-notification-settings -func (s *NotificationSettingsService) UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - if opt.Level != nil && *opt.Level == GlobalNotificationLevel { - return nil, nil, errors.New( - "notification level 'global' is not valid for global notification settings") - } - - u := "notification_settings" - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} - -// GetSettingsForGroup returns current group notification settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings -func (s *NotificationSettingsService) GetSettingsForGroup(gid interface{}, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/notification_settings", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} - -// GetSettingsForProject returns current project notification settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings -func (s *NotificationSettingsService) GetSettingsForProject(pid interface{}, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/notification_settings", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} - -// UpdateSettingsForGroup updates current group notification settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings -func (s *NotificationSettingsService) UpdateSettingsForGroup(gid interface{}, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/notification_settings", pathEscape(group)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} - -// UpdateSettingsForProject updates current project notification settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings -func (s *NotificationSettingsService) UpdateSettingsForProject(pid interface{}, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/notification_settings", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ns := new(NotificationSettings) - resp, err := s.client.Do(req, ns) - if err != nil { - return nil, resp, err - } - - return ns, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/pages_domains.go b/vendor/github.com/xanzy/go-gitlab/pages_domains.go deleted file mode 100644 index fea9910c8..000000000 --- a/vendor/github.com/xanzy/go-gitlab/pages_domains.go +++ /dev/null @@ -1,196 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// PagesDomainsService handles communication with the pages domains -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pages_domains.html -type PagesDomainsService struct { - client *Client -} - -// PagesDomain represents a pages domain. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pages_domains.html -type PagesDomain struct { - Domain string `json:"domain"` - AutoSslEnabled bool `json:"auto_ssl_enabled"` - URL string `json:"url"` - ProjectID int `json:"project_id"` - Verified bool `json:"verified"` - VerificationCode string `json:"verification_code"` - EnabledUntil *time.Time `json:"enabled_until"` - Certificate struct { - Expired bool `json:"expired"` - Expiration *time.Time `json:"expiration"` - } `json:"certificate"` -} - -// ListPagesDomainsOptions represents the available ListPagesDomains() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#list-pages-domains -type ListPagesDomainsOptions ListOptions - -// ListPagesDomains gets a list of project pages domains. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#list-pages-domains -func (s *PagesDomainsService) ListPagesDomains(pid interface{}, opt *ListPagesDomainsOptions, options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pages/domains", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pd []*PagesDomain - resp, err := s.client.Do(req, &pd) - if err != nil { - return nil, resp, err - } - - return pd, resp, err -} - -// ListAllPagesDomains gets a list of all pages domains. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#list-all-pages-domains -func (s *PagesDomainsService) ListAllPagesDomains(options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) { - req, err := s.client.NewRequest("GET", "pages/domains", nil, options) - if err != nil { - return nil, nil, err - } - - var pd []*PagesDomain - resp, err := s.client.Do(req, &pd) - if err != nil { - return nil, resp, err - } - - return pd, resp, err -} - -// GetPagesDomain get a specific pages domain for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#single-pages-domain -func (s *PagesDomainsService) GetPagesDomain(pid interface{}, domain string, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pages/domains/%s", pathEscape(project), domain) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pd := new(PagesDomain) - resp, err := s.client.Do(req, pd) - if err != nil { - return nil, resp, err - } - - return pd, resp, err -} - -// CreatePagesDomainOptions represents the available CreatePagesDomain() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#create-new-pages-domain -type CreatePagesDomainOptions struct { - Domain *string `url:"domain,omitempty" json:"domain,omitempty"` - AutoSslEnabled *bool `url:"auto_ssl_enabled,omitempty" json:"auto_ssl_enabled,omitempty"` - Certificate *string `url:"certifiate,omitempty" json:"certifiate,omitempty"` - Key *string `url:"key,omitempty" json:"key,omitempty"` -} - -// CreatePagesDomain creates a new project pages domain. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#create-new-pages-domain -func (s *PagesDomainsService) CreatePagesDomain(pid interface{}, opt *CreatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pages/domains", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pd := new(PagesDomain) - resp, err := s.client.Do(req, pd) - if err != nil { - return nil, resp, err - } - - return pd, resp, err -} - -// UpdatePagesDomainOptions represents the available UpdatePagesDomain() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#update-pages-domain -type UpdatePagesDomainOptions struct { - AutoSslEnabled *bool `url:"auto_ssl_enabled,omitempty" json:"auto_ssl_enabled,omitempty"` - Certificate *string `url:"certifiate,omitempty" json:"certifiate,omitempty"` - Key *string `url:"key,omitempty" json:"key,omitempty"` -} - -// UpdatePagesDomain updates an existing project pages domain. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#update-pages-domain -func (s *PagesDomainsService) UpdatePagesDomain(pid interface{}, domain string, opt *UpdatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pages/domains/%s", pathEscape(project), domain) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pd := new(PagesDomain) - resp, err := s.client.Do(req, pd) - if err != nil { - return nil, resp, err - } - - return pd, resp, err -} - -// DeletePagesDomain deletes an existing prject pages domain. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pages_domains.html#delete-pages-domain -func (s *PagesDomainsService) DeletePagesDomain(pid interface{}, domain string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/pages/domains/%s", pathEscape(project), domain) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go b/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go deleted file mode 100644 index b57adcff3..000000000 --- a/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go +++ /dev/null @@ -1,346 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// PipelineSchedulesService handles communication with the pipeline -// schedules related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipeline_schedules.html -type PipelineSchedulesService struct { - client *Client -} - -// PipelineSchedule represents a pipeline schedule. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html -type PipelineSchedule struct { - ID int `json:"id"` - Description string `json:"description"` - Ref string `json:"ref"` - Cron string `json:"cron"` - CronTimezone string `json:"cron_timezone"` - NextRunAt *time.Time `json:"next_run_at"` - Active bool `json:"active"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - Owner *User `json:"owner"` - LastPipeline struct { - ID int `json:"id"` - SHA string `json:"sha"` - Ref string `json:"ref"` - Status string `json:"status"` - } `json:"last_pipeline"` - Variables []*PipelineVariable `json:"variables"` -} - -// ListPipelineSchedulesOptions represents the available ListPipelineTriggers() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers -type ListPipelineSchedulesOptions ListOptions - -// ListPipelineSchedules gets a list of project triggers. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html -func (s *PipelineSchedulesService) ListPipelineSchedules(pid interface{}, opt *ListPipelineSchedulesOptions, options ...RequestOptionFunc) ([]*PipelineSchedule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ps []*PipelineSchedule - resp, err := s.client.Do(req, &ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// GetPipelineSchedule gets a pipeline schedule. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html -func (s *PipelineSchedulesService) GetPipelineSchedule(pid interface{}, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", pathEscape(project), schedule) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineSchedule) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CreatePipelineScheduleOptions represents the available -// CreatePipelineSchedule() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule -type CreatePipelineScheduleOptions struct { - Description *string `url:"description" json:"description"` - Ref *string `url:"ref" json:"ref"` - Cron *string `url:"cron" json:"cron"` - CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` - Active *bool `url:"active,omitempty" json:"active,omitempty"` -} - -// CreatePipelineSchedule creates a pipeline schedule. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule -func (s *PipelineSchedulesService) CreatePipelineSchedule(pid interface{}, opt *CreatePipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineSchedule) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// EditPipelineScheduleOptions represents the available -// EditPipelineSchedule() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule -type EditPipelineScheduleOptions struct { - Description *string `url:"description,omitempty" json:"description,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Cron *string `url:"cron,omitempty" json:"cron,omitempty"` - CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` - Active *bool `url:"active,omitempty" json:"active,omitempty"` -} - -// EditPipelineSchedule edits a pipeline schedule. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule -func (s *PipelineSchedulesService) EditPipelineSchedule(pid interface{}, schedule int, opt *EditPipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", pathEscape(project), schedule) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineSchedule) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// TakeOwnershipOfPipelineSchedule sets the owner of the specified -// pipeline schedule to the user issuing the request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#take-ownership-of-a-pipeline-schedule -func (s *PipelineSchedulesService) TakeOwnershipOfPipelineSchedule(pid interface{}, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/take_ownership", pathEscape(project), schedule) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineSchedule) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// DeletePipelineSchedule deletes a pipeline schedule. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#delete-a-pipeline-schedule -func (s *PipelineSchedulesService) DeletePipelineSchedule(pid interface{}, schedule int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", pathEscape(project), schedule) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// RunPipelineSchedule triggers a new scheduled pipeline to run immediately. -// -// Gitlab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#run-a-scheduled-pipeline-immediately -func (s *PipelineSchedulesService) RunPipelineSchedule(pid interface{}, schedule int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/play", pathEscape(project), schedule) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// CreatePipelineScheduleVariableOptions represents the available -// CreatePipelineScheduleVariable() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule -type CreatePipelineScheduleVariableOptions struct { - Key *string `url:"key" json:"key"` - Value *string `url:"value" json:"value"` - VariableType *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` -} - -// CreatePipelineScheduleVariable creates a pipeline schedule variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#create-a-new-pipeline-schedule -func (s *PipelineSchedulesService) CreatePipelineScheduleVariable(pid interface{}, schedule int, opt *CreatePipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables", pathEscape(project), schedule) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineVariable) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// EditPipelineScheduleVariableOptions represents the available -// EditPipelineScheduleVariable() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule-variable -type EditPipelineScheduleVariableOptions struct { - Value *string `url:"value" json:"value"` - VariableType *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` -} - -// EditPipelineScheduleVariable creates a pipeline schedule variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#edit-a-pipeline-schedule-variable -func (s *PipelineSchedulesService) EditPipelineScheduleVariable(pid interface{}, schedule int, key string, opt *EditPipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", pathEscape(project), schedule, key) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineVariable) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// DeletePipelineScheduleVariable creates a pipeline schedule variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_schedules.html#delete-a-pipeline-schedule-variable -func (s *PipelineSchedulesService) DeletePipelineScheduleVariable(pid interface{}, schedule int, key string, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", pathEscape(project), schedule, key) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(PipelineVariable) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go b/vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go deleted file mode 100644 index 999025aa2..000000000 --- a/vendor/github.com/xanzy/go-gitlab/pipeline_triggers.go +++ /dev/null @@ -1,231 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// PipelineTriggersService handles Project pipeline triggers. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html -type PipelineTriggersService struct { - client *Client -} - -// PipelineTrigger represents a project pipeline trigger. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#pipeline-triggers -type PipelineTrigger struct { - ID int `json:"id"` - Description string `json:"description"` - CreatedAt *time.Time `json:"created_at"` - DeletedAt *time.Time `json:"deleted_at"` - LastUsed *time.Time `json:"last_used"` - Token string `json:"token"` - UpdatedAt *time.Time `json:"updated_at"` - Owner *User `json:"owner"` -} - -// ListPipelineTriggersOptions represents the available ListPipelineTriggers() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers -type ListPipelineTriggersOptions ListOptions - -// ListPipelineTriggers gets a list of project triggers. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#list-project-triggers -func (s *PipelineTriggersService) ListPipelineTriggers(pid interface{}, opt *ListPipelineTriggersOptions, options ...RequestOptionFunc) ([]*PipelineTrigger, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/triggers", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pt []*PipelineTrigger - resp, err := s.client.Do(req, &pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// GetPipelineTrigger gets a specific pipeline trigger for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#get-trigger-details -func (s *PipelineTriggersService) GetPipelineTrigger(pid interface{}, trigger int, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/triggers/%d", pathEscape(project), trigger) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pt := new(PipelineTrigger) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// AddPipelineTriggerOptions represents the available AddPipelineTrigger() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#create-a-project-trigger -type AddPipelineTriggerOptions struct { - Description *string `url:"description,omitempty" json:"description,omitempty"` -} - -// AddPipelineTrigger adds a pipeline trigger to a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#create-a-project-trigger -func (s *PipelineTriggersService) AddPipelineTrigger(pid interface{}, opt *AddPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/triggers", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pt := new(PipelineTrigger) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// EditPipelineTriggerOptions represents the available EditPipelineTrigger() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#update-a-project-trigger -type EditPipelineTriggerOptions struct { - Description *string `url:"description,omitempty" json:"description,omitempty"` -} - -// EditPipelineTrigger edits a trigger for a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#update-a-project-trigger -func (s *PipelineTriggersService) EditPipelineTrigger(pid interface{}, trigger int, opt *EditPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/triggers/%d", pathEscape(project), trigger) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pt := new(PipelineTrigger) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// TakeOwnershipOfPipelineTrigger sets the owner of the specified -// pipeline trigger to the user issuing the request. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#take-ownership-of-a-project-trigger -func (s *PipelineTriggersService) TakeOwnershipOfPipelineTrigger(pid interface{}, trigger int, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/triggers/%d/take_ownership", pathEscape(project), trigger) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - pt := new(PipelineTrigger) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// DeletePipelineTrigger removes a trigger from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipeline_triggers.html#remove-a-project-trigger -func (s *PipelineTriggersService) DeletePipelineTrigger(pid interface{}, trigger int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/triggers/%d", pathEscape(project), trigger) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// RunPipelineTriggerOptions represents the available RunPipelineTrigger() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/ci/triggers/README.html#triggering-a-pipeline -type RunPipelineTriggerOptions struct { - Ref *string `url:"ref" json:"ref"` - Token *string `url:"token" json:"token"` - Variables map[string]string `url:"variables,omitempty" json:"variables,omitempty"` -} - -// RunPipelineTrigger starts a trigger from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/ci/triggers/README.html#triggering-a-pipeline -func (s *PipelineTriggersService) RunPipelineTrigger(pid interface{}, opt *RunPipelineTriggerOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/trigger/pipeline", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pt := new(Pipeline) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/pipelines.go b/vendor/github.com/xanzy/go-gitlab/pipelines.go deleted file mode 100644 index 5b893486f..000000000 --- a/vendor/github.com/xanzy/go-gitlab/pipelines.go +++ /dev/null @@ -1,347 +0,0 @@ -// -// Copyright 2017, Igor Varavko -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// PipelinesService handles communication with the repositories related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html -type PipelinesService struct { - client *Client -} - -// PipelineVariable represents a pipeline variable. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html -type PipelineVariable struct { - Key string `json:"key"` - Value string `json:"value"` - VariableType string `json:"variable_type"` -} - -// Pipeline represents a GitLab pipeline. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html -type Pipeline struct { - ID int `json:"id"` - Status string `json:"status"` - Ref string `json:"ref"` - SHA string `json:"sha"` - BeforeSHA string `json:"before_sha"` - Tag bool `json:"tag"` - YamlErrors string `json:"yaml_errors"` - User *BasicUser `json:"user"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` - StartedAt *time.Time `json:"started_at"` - FinishedAt *time.Time `json:"finished_at"` - CommittedAt *time.Time `json:"committed_at"` - Duration int `json:"duration"` - Coverage string `json:"coverage"` - WebURL string `json:"web_url"` - DetailedStatus *DetailedStatus `json:"detailed_status"` -} - -// DetailedStatus contains detailed information about the status of a pipeline. -type DetailedStatus struct { - Icon string `json:"icon"` - Text string `json:"text"` - Label string `json:"label"` - Group string `json:"group"` - Tooltip string `json:"tooltip"` - HasDetails bool `json:"has_details"` - DetailsPath string `json:"details_path"` - Illustration struct { - Image string `json:"image"` - } `json:"illustration"` - Favicon string `json:"favicon"` -} - -func (p Pipeline) String() string { - return Stringify(p) -} - -// PipelineTestReport contains a detailed report of a test run. -type PipelineTestReport struct { - TotalTime float64 `json:"total_time"` - TotalCount int `json:"total_count"` - SuccessCount int `json:"success_count"` - FailedCount int `json:"failed_count"` - SkippedCount int `json:"skipped_count"` - ErrorCount int `json:"error_count"` - TestSuites []PipelineTestSuites `json:"test_suites"` -} - -// PipelineTestSuites contains test suites results. -type PipelineTestSuites struct { - Name string `json:"name"` - TotalTime float64 `json:"total_time"` - TotalCount int `json:"total_count"` - SuccessCount int `json:"success_count"` - FailedCount int `json:"failed_count"` - SkippedCount int `json:"skipped_count"` - ErrorCount int `json:"error_count"` - TestCases []PipelineTestCases `json:"test_cases"` -} - -// PipelineTestCases contains test cases details. -type PipelineTestCases struct { - Status string `json:"status"` - Name string `json:"name"` - Classname string `json:"classname"` - ExecutionTime float64 `json:"execution_time"` -} - -func (p PipelineTestReport) String() string { - return Stringify(p) -} - -// PipelineInfo shows the basic entities of a pipeline, mostly used as fields -// on other assets, like Commit. -type PipelineInfo struct { - ID int `json:"id"` - Status string `json:"status"` - Ref string `json:"ref"` - SHA string `json:"sha"` - WebURL string `json:"web_url"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` -} - -func (p PipelineInfo) String() string { - return Stringify(p) -} - -// ListProjectPipelinesOptions represents the available ListProjectPipelines() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines -type ListProjectPipelinesOptions struct { - ListOptions - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - Status *BuildStateValue `url:"status,omitempty" json:"status,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - SHA *string `url:"sha,omitempty" json:"sha,omitempty"` - YamlErrors *bool `url:"yaml_errors,omitempty" json:"yaml_errors,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` - UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListProjectPipelines gets a list of project piplines. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines -func (s *PipelinesService) ListProjectPipelines(pid interface{}, opt *ListProjectPipelinesOptions, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*PipelineInfo - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetPipeline gets a single project pipeline. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#get-a-single-pipeline -func (s *PipelinesService) GetPipeline(pid interface{}, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Pipeline) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetPipelineVariables gets the variables of a single project pipeline. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#get-variables-of-a-pipeline -func (s *PipelinesService) GetPipelineVariables(pid interface{}, pipeline int, options ...RequestOptionFunc) ([]*PipelineVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d/variables", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var p []*PipelineVariable - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetPipelineTestReport gets the test report of a single project pipeline. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/pipelines.html#get-a-pipelines-test-report -func (s *PipelinesService) GetPipelineTestReport(pid interface{}, pipeline int) (*PipelineTestReport, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d/test_report", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("GET", u, nil, nil) - if err != nil { - return nil, nil, err - } - - p := new(PipelineTestReport) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CreatePipelineOptions represents the available CreatePipeline() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline -type CreatePipelineOptions struct { - Ref *string `url:"ref" json:"ref"` - Variables []*PipelineVariable `url:"variables,omitempty" json:"variables,omitempty"` -} - -// CreatePipeline creates a new project pipeline. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline -func (s *PipelinesService) CreatePipeline(pid interface{}, opt *CreatePipelineOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipeline", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Pipeline) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// RetryPipelineBuild retries failed builds in a pipeline -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipelines.html#retry-failed-builds-in-a-pipeline -func (s *PipelinesService) RetryPipelineBuild(pid interface{}, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d/retry", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Pipeline) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CancelPipelineBuild cancels a pipeline builds -// -// GitLab API docs: -//https://docs.gitlab.com/ce/api/pipelines.html#cancel-a-pipelines-builds -func (s *PipelinesService) CancelPipelineBuild(pid interface{}, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d/cancel", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Pipeline) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// DeletePipeline deletes an existing pipeline. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/pipelines.html#delete-a-pipeline -func (s *PipelinesService) DeletePipeline(pid interface{}, pipeline int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/pipelines/%d", pathEscape(project), pipeline) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_badges.go b/vendor/github.com/xanzy/go-gitlab/project_badges.go deleted file mode 100644 index 1490d3694..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_badges.go +++ /dev/null @@ -1,207 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// ProjectBadge represents a project badge. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#list-all-badges-of-a-project -type ProjectBadge struct { - ID int `json:"id"` - LinkURL string `json:"link_url"` - ImageURL string `json:"image_url"` - RenderedLinkURL string `json:"rendered_link_url"` - RenderedImageURL string `json:"rendered_image_url"` - // Kind represents a project badge kind. Can be empty, when used PreviewProjectBadge(). - Kind string `json:"kind"` -} - -// ProjectBadgesService handles communication with the project badges -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/project_badges.html -type ProjectBadgesService struct { - client *Client -} - -// ListProjectBadgesOptions represents the available ListProjectBadges() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#list-all-badges-of-a-project -type ListProjectBadgesOptions ListOptions - -// ListProjectBadges gets a list of a project's badges and its group badges. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#list-all-badges-of-a-project -func (s *ProjectBadgesService) ListProjectBadges(pid interface{}, opt *ListProjectBadgesOptions, options ...RequestOptionFunc) ([]*ProjectBadge, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/badges", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pb []*ProjectBadge - resp, err := s.client.Do(req, &pb) - if err != nil { - return nil, resp, err - } - - return pb, resp, err -} - -// GetProjectBadge gets a project badge. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#get-a-badge-of-a-project -func (s *ProjectBadgesService) GetProjectBadge(pid interface{}, badge int, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/badges/%d", pathEscape(project), badge) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pb := new(ProjectBadge) - resp, err := s.client.Do(req, pb) - if err != nil { - return nil, resp, err - } - - return pb, resp, err -} - -// AddProjectBadgeOptions represents the available AddProjectBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#add-a-badge-to-a-project -type AddProjectBadgeOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// AddProjectBadge adds a badge to a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#add-a-badge-to-a-project -func (s *ProjectBadgesService) AddProjectBadge(pid interface{}, opt *AddProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/badges", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pb := new(ProjectBadge) - resp, err := s.client.Do(req, pb) - if err != nil { - return nil, resp, err - } - - return pb, resp, err -} - -// EditProjectBadgeOptions represents the available EditProjectBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#edit-a-badge-of-a-project -type EditProjectBadgeOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// EditProjectBadge updates a badge of a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#edit-a-badge-of-a-project -func (s *ProjectBadgesService) EditProjectBadge(pid interface{}, badge int, opt *EditProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/badges/%d", pathEscape(project), badge) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pb := new(ProjectBadge) - resp, err := s.client.Do(req, pb) - if err != nil { - return nil, resp, err - } - - return pb, resp, err -} - -// DeleteProjectBadge removes a badge from a project. Only project's -// badges will be removed by using this endpoint. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#remove-a-badge-from-a-project -func (s *ProjectBadgesService) DeleteProjectBadge(pid interface{}, badge int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/badges/%d", pathEscape(project), badge) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ProjectBadgePreviewOptions represents the available PreviewProjectBadge() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#preview-a-badge-from-a-project -type ProjectBadgePreviewOptions struct { - LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` - ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` -} - -// PreviewProjectBadge returns how the link_url and image_url final URLs would be after -// resolving the placeholder interpolation. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_badges.html#preview-a-badge-from-a-project -func (s *ProjectBadgesService) PreviewProjectBadge(pid interface{}, opt *ProjectBadgePreviewOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/badges/render", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - pb := new(ProjectBadge) - resp, err := s.client.Do(req, &pb) - if err != nil { - return nil, resp, err - } - - return pb, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_import_export.go b/vendor/github.com/xanzy/go-gitlab/project_import_export.go deleted file mode 100644 index f052159c8..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_import_export.go +++ /dev/null @@ -1,196 +0,0 @@ -package gitlab - -import ( - "bytes" - "fmt" - "time" -) - -// ProjectImportExportService handles communication with the project -// import/export related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/user/project/settings/import_export.html -type ProjectImportExportService struct { - client *Client -} - -// ImportStatus represents a project import status. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#import-status -type ImportStatus struct { - ID int `json:"id"` - Description string `json:"description"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - CreateAt *time.Time `json:"create_at"` - ImportStatus string `json:"import_status"` -} - -func (s ImportStatus) String() string { - return Stringify(s) -} - -// ExportStatus represents a project export status. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#export-status -type ExportStatus struct { - ID int `json:"id"` - Description string `json:"description"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - CreatedAt *time.Time `json:"created_at"` - ExportStatus string `json:"export_status"` - Message string `json:"message"` - Links struct { - APIURL string `json:"api_url"` - WebURL string `json:"web_url"` - } `json:"_links"` -} - -func (s ExportStatus) String() string { - return Stringify(s) -} - -// ScheduleExportOptions represents the available ScheduleExport() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#schedule-an-export -type ScheduleExportOptions struct { - Description *string `url:"description,omitempty" json:"description,omitempty"` - Upload struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - HTTPMethod *string `url:"http_method,omitempty" json:"http_method,omitempty"` - } `url:"upload,omitempty" json:"upload,omitempty"` -} - -// ScheduleExport schedules a project export. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#schedule-an-export -func (s *ProjectImportExportService) ScheduleExport(pid interface{}, opt *ScheduleExportOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/export", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ExportStatus get the status of export. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#export-status -func (s *ProjectImportExportService) ExportStatus(pid interface{}, options ...RequestOptionFunc) (*ExportStatus, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/export", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - es := new(ExportStatus) - resp, err := s.client.Do(req, es) - if err != nil { - return nil, resp, err - } - - return es, resp, err -} - -// ExportDownload download the finished export. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#export-download -func (s *ProjectImportExportService) ExportDownload(pid interface{}, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/export/download", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} - -// ImportFileOptions represents the available ImportFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#import-a-file -type ImportFileOptions struct { - Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` - File *string `url:"file,omitempty" json:"file,omitempty"` - Path *string `url:"path,omitempty" json:"path,omitempty"` - Overwrite *bool `url:"overwrite,omitempty" json:"overwrite,omitempty"` - OverrideParams *CreateProjectOptions `url:"override_params,omitempty" json:"override_params,omitempty"` -} - -// ImportFile import a file. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#import-a-file -func (s *ProjectImportExportService) ImportFile(opt *ImportFileOptions, options ...RequestOptionFunc) (*ImportStatus, *Response, error) { - req, err := s.client.NewRequest("POST", "projects/import", opt, options) - if err != nil { - return nil, nil, err - } - - is := new(ImportStatus) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} - -// ImportStatus get the status of an import. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_import_export.html#import-status -func (s *ProjectImportExportService) ImportStatus(pid interface{}, options ...RequestOptionFunc) (*ImportStatus, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/import", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - is := new(ImportStatus) - resp, err := s.client.Do(req, is) - if err != nil { - return nil, resp, err - } - - return is, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_members.go b/vendor/github.com/xanzy/go-gitlab/project_members.go deleted file mode 100644 index 0a1b57f76..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_members.go +++ /dev/null @@ -1,234 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// ProjectMembersService handles communication with the project members -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/members.html -type ProjectMembersService struct { - client *Client -} - -// ListProjectMembersOptions represents the available ListProjectMembers() and -// ListAllProjectMembers() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project -type ListProjectMembersOptions struct { - ListOptions - Query *string `url:"query,omitempty" json:"query,omitempty"` -} - -// ListProjectMembers gets a list of a project's team members viewable by the -// authenticated user. Returns only direct members and not inherited members -// through ancestors groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project -func (s *ProjectMembersService) ListProjectMembers(pid interface{}, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pm []*ProjectMember - resp, err := s.client.Do(req, &pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// ListAllProjectMembers gets a list of a project's team members viewable by the -// authenticated user. Returns a list including inherited members through -// ancestor groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project-including-inherited-members -func (s *ProjectMembersService) ListAllProjectMembers(pid interface{}, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members/all", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pm []*ProjectMember - resp, err := s.client.Do(req, &pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// GetProjectMember gets a project team member. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project -func (s *ProjectMembersService) GetProjectMember(pid interface{}, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members/%d", pathEscape(project), user) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMember) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// GetInheritedProjectMember gets a project team member, including inherited -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project-including-inherited-members -func (s *ProjectMembersService) GetInheritedProjectMember(pid interface{}, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members/all/%d", pathEscape(project), user) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMember) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// AddProjectMemberOptions represents the available AddProjectMember() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project -type AddProjectMemberOptions struct { - UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` - ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` -} - -// AddProjectMember adds a user to a project team. This is an idempotent -// method and can be called multiple times with the same parameters. Adding -// team membership to a user that is already a member does not affect the -// existing membership. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project -func (s *ProjectMembersService) AddProjectMember(pid interface{}, opt *AddProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMember) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// EditProjectMemberOptions represents the available EditProjectMember() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project -type EditProjectMemberOptions struct { - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` - ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` -} - -// EditProjectMember updates a project team member to a specified access level.. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project -func (s *ProjectMembersService) EditProjectMember(pid interface{}, user int, opt *EditProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/members/%d", pathEscape(project), user) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMember) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// DeleteProjectMember removes a user from a project team. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/members.html#remove-a-member-from-a-group-or-project -func (s *ProjectMembersService) DeleteProjectMember(pid interface{}, user int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/members/%d", pathEscape(project), user) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_mirror.go b/vendor/github.com/xanzy/go-gitlab/project_mirror.go deleted file mode 100644 index aa7a1aa5d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_mirror.go +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// ProjectMirrorService handles communication with the project mirror -// related methods of the GitLab API. -// -// GitLAb API docs: https://docs.gitlab.com/ce/api/remote_mirrors.html -type ProjectMirrorService struct { - client *Client -} - -// ProjectMirror represents a project mirror configuration. -// -// GitLAb API docs: https://docs.gitlab.com/ce/api/remote_mirrors.html -type ProjectMirror struct { - Enabled bool `json:"enabled"` - ID int `json:"id"` - LastError string `json:"last_error"` - LastSuccessfulUpdateAt *time.Time `json:"last_successful_update_at"` - LastUpdateAt *time.Time `json:"last_update_at"` - LastUpdateStartedAt *time.Time `json:"last_update_started_at"` - OnlyProtectedBranches bool `json:"only_protected_branches"` - KeepDivergentRefs bool `json:"keep_divergent_refs"` - UpdateStatus string `json:"update_status"` - URL string `json:"url"` -} - -// ListProjectMirror gets a list of mirrors configured on the project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/remote_mirrors.html#list-a-projects-remote-mirrors -func (s *ProjectMirrorService) ListProjectMirror(pid interface{}, options ...RequestOptionFunc) ([]*ProjectMirror, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/remote_mirrors", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var pm []*ProjectMirror - resp, err := s.client.Do(req, &pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err - -} - -// AddProjectMirrorOptions contains the properties requires to create -// a new project mirror. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/remote_mirrors.html#create-a-remote-mirror -type AddProjectMirrorOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` - OnlyProtectedBranches *bool `url:"only_protected_branches,omitempty" json:"only_protected_branches,omitempty"` - KeepDivergentRefs *bool `url:"keep_divergent_refs,omitempty" json:"keep_divergent_refs,omitempty"` -} - -// AddProjectMirror creates a new mirror on the project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/remote_mirrors.html#create-a-remote-mirror -func (s *ProjectMirrorService) AddProjectMirror(pid interface{}, opt *AddProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/remote_mirrors", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMirror) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} - -// EditProjectMirrorOptions contains the properties requires to edit -// an existing project mirror. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/remote_mirrors.html#update-a-remote-mirrors-attributes -type EditProjectMirrorOptions struct { - Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` - OnlyProtectedBranches *bool `url:"only_protected_branches,omitempty" json:"only_protected_branches,omitempty"` - KeepDivergentRefs *bool `url:"keep_divergent_refs,omitempty" json:"keep_divergent_refs,omitempty"` -} - -// EditProjectMirror updates a project team member to a specified access level.. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/remote_mirrors.html#update-a-remote-mirrors-attributes -func (s *ProjectMirrorService) EditProjectMirror(pid interface{}, mirror int, opt *EditProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/remote_mirrors/%d", pathEscape(project), mirror) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pm := new(ProjectMirror) - resp, err := s.client.Do(req, pm) - if err != nil { - return nil, resp, err - } - - return pm, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_snippets.go b/vendor/github.com/xanzy/go-gitlab/project_snippets.go deleted file mode 100644 index 8789db707..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_snippets.go +++ /dev/null @@ -1,206 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" -) - -// ProjectSnippetsService handles communication with the project snippets -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html -type ProjectSnippetsService struct { - client *Client -} - -// ListProjectSnippetsOptions represents the available ListSnippets() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets -type ListProjectSnippetsOptions ListOptions - -// ListSnippets gets a list of project snippets. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets -func (s *ProjectSnippetsService) ListSnippets(pid interface{}, opt *ListProjectSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ps []*Snippet - resp, err := s.client.Do(req, &ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// GetSnippet gets a single project snippet -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#single-snippet -func (s *ProjectSnippetsService) GetSnippet(pid interface{}, snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d", pathEscape(project), snippet) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// CreateProjectSnippetOptions represents the available CreateSnippet() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet -type CreateProjectSnippetOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` -} - -// CreateSnippet creates a new project snippet. The user must have permission -// to create new snippets. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet -func (s *ProjectSnippetsService) CreateSnippet(pid interface{}, opt *CreateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// UpdateProjectSnippetOptions represents the available UpdateSnippet() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet -type UpdateProjectSnippetOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` -} - -// UpdateSnippet updates an existing project snippet. The user must have -// permission to change an existing snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet -func (s *ProjectSnippetsService) UpdateSnippet(pid interface{}, snippet int, opt *UpdateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d", pathEscape(project), snippet) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// DeleteSnippet deletes an existing project snippet. This is an idempotent -// function and deleting a non-existent snippet still returns a 200 OK status -// code. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#delete-snippet -func (s *ProjectSnippetsService) DeleteSnippet(pid interface{}, snippet int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d", pathEscape(project), snippet) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SnippetContent returns the raw project snippet as plain text. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/project_snippets.html#snippet-content -func (s *ProjectSnippetsService) SnippetContent(pid interface{}, snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/snippets/%d/raw", pathEscape(project), snippet) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/project_variables.go b/vendor/github.com/xanzy/go-gitlab/project_variables.go deleted file mode 100644 index 86f9d0b8c..000000000 --- a/vendor/github.com/xanzy/go-gitlab/project_variables.go +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright 2018, Patrick Webster -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" -) - -// ProjectVariablesService handles communication with the -// project variables related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html -type ProjectVariablesService struct { - client *Client -} - -// ProjectVariable represents a GitLab Project Variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html -type ProjectVariable struct { - Key string `json:"key"` - Value string `json:"value"` - VariableType VariableTypeValue `json:"variable_type"` - Protected bool `json:"protected"` - Masked bool `json:"masked"` - EnvironmentScope string `json:"environment_scope"` -} - -func (v ProjectVariable) String() string { - return Stringify(v) -} - -// ListProjectVariablesOptions represents the available options for listing variables -// in a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#list-project-variables -type ListProjectVariablesOptions ListOptions - -// ListVariables gets a list of all variables in a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#list-project-variables -func (s *ProjectVariablesService) ListVariables(pid interface{}, opt *ListProjectVariablesOptions, options ...RequestOptionFunc) ([]*ProjectVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/variables", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var vs []*ProjectVariable - resp, err := s.client.Do(req, &vs) - if err != nil { - return nil, resp, err - } - - return vs, resp, err -} - -// GetVariable gets a variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#show-variable-details -func (s *ProjectVariablesService) GetVariable(pid interface{}, key string, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/variables/%s", pathEscape(project), url.PathEscape(key)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - v := new(ProjectVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// CreateProjectVariableOptions represents the available CreateVariable() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#create-variable -type CreateProjectVariableOptions struct { - Key *string `url:"key,omitempty" json:"key,omitempty"` - Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` - Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` - EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` -} - -// CreateVariable creates a new project variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#create-variable -func (s *ProjectVariablesService) CreateVariable(pid interface{}, opt *CreateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/variables", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - v := new(ProjectVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// UpdateProjectVariableOptions represents the available UpdateVariable() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#update-variable -type UpdateProjectVariableOptions struct { - Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` - Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` - EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` -} - -// UpdateVariable updates a project's variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#update-variable -func (s *ProjectVariablesService) UpdateVariable(pid interface{}, key string, opt *UpdateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/variables/%s", pathEscape(project), url.PathEscape(key)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - v := new(ProjectVariable) - resp, err := s.client.Do(req, v) - if err != nil { - return nil, resp, err - } - - return v, resp, err -} - -// RemoveVariable removes a project's variable. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_level_variables.html#remove-variable -func (s *ProjectVariablesService) RemoveVariable(pid interface{}, key string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/variables/%s", pathEscape(project), url.PathEscape(key)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/projects.go b/vendor/github.com/xanzy/go-gitlab/projects.go deleted file mode 100644 index 5d5ca8c38..000000000 --- a/vendor/github.com/xanzy/go-gitlab/projects.go +++ /dev/null @@ -1,1632 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "os" - "time" -) - -// ProjectsService handles communication with the repositories related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html -type ProjectsService struct { - client *Client -} - -// Project represents a GitLab project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html -type Project struct { - ID int `json:"id"` - Description string `json:"description"` - DefaultBranch string `json:"default_branch"` - Public bool `json:"public"` - Visibility VisibilityValue `json:"visibility"` - SSHURLToRepo string `json:"ssh_url_to_repo"` - HTTPURLToRepo string `json:"http_url_to_repo"` - WebURL string `json:"web_url"` - ReadmeURL string `json:"readme_url"` - TagList []string `json:"tag_list"` - Owner *User `json:"owner"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - IssuesEnabled bool `json:"issues_enabled"` - OpenIssuesCount int `json:"open_issues_count"` - MergeRequestsEnabled bool `json:"merge_requests_enabled"` - ApprovalsBeforeMerge int `json:"approvals_before_merge"` - JobsEnabled bool `json:"jobs_enabled"` - WikiEnabled bool `json:"wiki_enabled"` - SnippetsEnabled bool `json:"snippets_enabled"` - ResolveOutdatedDiffDiscussions bool `json:"resolve_outdated_diff_discussions"` - ContainerRegistryEnabled bool `json:"container_registry_enabled"` - CreatedAt *time.Time `json:"created_at,omitempty"` - LastActivityAt *time.Time `json:"last_activity_at,omitempty"` - CreatorID int `json:"creator_id"` - Namespace *ProjectNamespace `json:"namespace"` - ImportStatus string `json:"import_status"` - ImportError string `json:"import_error"` - Permissions *Permissions `json:"permissions"` - MarkedForDeletionAt *ISOTime `json:"marked_for_deletion_at"` - Archived bool `json:"archived"` - AvatarURL string `json:"avatar_url"` - SharedRunnersEnabled bool `json:"shared_runners_enabled"` - ForksCount int `json:"forks_count"` - StarCount int `json:"star_count"` - RunnersToken string `json:"runners_token"` - PublicBuilds bool `json:"public_builds"` - OnlyAllowMergeIfPipelineSucceeds bool `json:"only_allow_merge_if_pipeline_succeeds"` - OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved"` - RemoveSourceBranchAfterMerge bool `json:"remove_source_branch_after_merge"` - LFSEnabled bool `json:"lfs_enabled"` - RequestAccessEnabled bool `json:"request_access_enabled"` - MergeMethod MergeMethodValue `json:"merge_method"` - ForkedFromProject *ForkParent `json:"forked_from_project"` - Mirror bool `json:"mirror"` - MirrorUserID int `json:"mirror_user_id"` - MirrorTriggerBuilds bool `json:"mirror_trigger_builds"` - OnlyMirrorProtectedBranches bool `json:"only_mirror_protected_branches"` - MirrorOverwritesDivergedBranches bool `json:"mirror_overwrites_diverged_branches"` - PackagesEnabled bool `json:"packages_enabled"` - ServiceDeskEnabled bool `json:"service_desk_enabled"` - ServiceDeskAddress string `json:"service_desk_address"` - IssuesAccessLevel AccessControlValue `json:"issues_access_level"` - RepositoryAccessLevel AccessControlValue `json:"repository_access_level"` - MergeRequestsAccessLevel AccessControlValue `json:"merge_requests_access_level"` - ForkingAccessLevel AccessControlValue `json:"forking_access_level"` - WikiAccessLevel AccessControlValue `json:"wiki_access_level"` - BuildsAccessLevel AccessControlValue `json:"builds_access_level"` - SnippetsAccessLevel AccessControlValue `json:"snippets_access_level"` - PagesAccessLevel AccessControlValue `json:"pages_access_level"` - AutocloseReferencedIssues bool `json:"autoclose_referenced_issues"` - SharedWithGroups []struct { - GroupID int `json:"group_id"` - GroupName string `json:"group_name"` - GroupAccessLevel int `json:"group_access_level"` - } `json:"shared_with_groups"` - Statistics *ProjectStatistics `json:"statistics"` - Links *Links `json:"_links,omitempty"` - CIConfigPath string `json:"ci_config_path"` - CIDefaultGitDepth int `json:"ci_default_git_depth"` - CustomAttributes []*CustomAttribute `json:"custom_attributes"` - ComplianceFrameworks []string `json:"compliance_frameworks"` -} - -// Repository represents a repository. -type Repository struct { - Name string `json:"name"` - Description string `json:"description"` - WebURL string `json:"web_url"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - Visibility VisibilityValue `json:"visibility"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` -} - -// ProjectNamespace represents a project namespace. -type ProjectNamespace struct { - ID int `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Kind string `json:"kind"` - FullPath string `json:"full_path"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` -} - -// StorageStatistics represents a statistics record for a group or project. -type StorageStatistics struct { - StorageSize int64 `json:"storage_size"` - RepositorySize int64 `json:"repository_size"` - LfsObjectsSize int64 `json:"lfs_objects_size"` - JobArtifactsSize int64 `json:"job_artifacts_size"` -} - -// ProjectStatistics represents a statistics record for a project. -type ProjectStatistics struct { - StorageStatistics - CommitCount int `json:"commit_count"` -} - -// Permissions represents permissions. -type Permissions struct { - ProjectAccess *ProjectAccess `json:"project_access"` - GroupAccess *GroupAccess `json:"group_access"` -} - -// ProjectAccess represents project access. -type ProjectAccess struct { - AccessLevel AccessLevelValue `json:"access_level"` - NotificationLevel NotificationLevelValue `json:"notification_level"` -} - -// GroupAccess represents group access. -type GroupAccess struct { - AccessLevel AccessLevelValue `json:"access_level"` - NotificationLevel NotificationLevelValue `json:"notification_level"` -} - -// ForkParent represents the parent project when this is a fork. -type ForkParent struct { - HTTPURLToRepo string `json:"http_url_to_repo"` - ID int `json:"id"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - WebURL string `json:"web_url"` -} - -// Links represents a project web links for self, issues, merge_requests, -// repo_branches, labels, events, members. -type Links struct { - Self string `json:"self"` - Issues string `json:"issues"` - MergeRequests string `json:"merge_requests"` - RepoBranches string `json:"repo_branches"` - Labels string `json:"labels"` - Events string `json:"events"` - Members string `json:"members"` -} - -func (s Project) String() string { - return Stringify(s) -} - -// ProjectApprovalRule represents a GitLab project approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-project-level-rules -type ProjectApprovalRule struct { - ID int `json:"id"` - Name string `json:"name"` - RuleType string `json:"rule_type"` - EligibleApprovers []*BasicUser `json:"eligible_approvers"` - ApprovalsRequired int `json:"approvals_required"` - Users []*BasicUser `json:"users"` - Groups []*Group `json:"groups"` - ContainsHiddenGroups bool `json:"contains_hidden_groups"` - ProtectedBranches []*ProtectedBranch `json:"protected_branches"` -} - -func (s ProjectApprovalRule) String() string { - return Stringify(s) -} - -// ListProjectsOptions represents the available ListProjects() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects -type ListProjectsOptions struct { - ListOptions - Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - SearchNamespaces *bool `url:"search_namespaces,omitempty" json:"search_namespaces,omitempty"` - Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` - Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` - Membership *bool `url:"membership,omitempty" json:"membership,omitempty"` - Starred *bool `url:"starred,omitempty" json:"starred,omitempty"` - Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` - WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` - WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"` - WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"` - WithProgrammingLanguage *string `url:"with_programming_language,omitempty" json:"with_programming_language,omitempty"` - WikiChecksumFailed *bool `url:"wiki_checksum_failed,omitempty" json:"wiki_checksum_failed,omitempty"` - RepositoryChecksumFailed *bool `url:"repository_checksum_failed,omitempty" json:"repository_checksum_failed,omitempty"` - MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` - IDAfter *int `url:"id_after,omitempty" json:"id_after,omitempty"` - IDBefore *int `url:"id_before,omitempty" json:"id_before,omitempty"` - LastActivityAfter *time.Time `url:"last_activity_after,omitempty" json:"last_activity_after,omitempty"` - LastActivityBefore *time.Time `url:"last_activity_before,omitempty" json:"last_activity_before,omitempty"` -} - -// ListProjects gets a list of projects accessible by the authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects -func (s *ProjectsService) ListProjects(opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - req, err := s.client.NewRequest("GET", "projects", opt, options) - if err != nil { - return nil, nil, err - } - - var p []*Project - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ListUserProjects gets a list of projects for the given user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#list-user-projects -func (s *ProjectsService) ListUserProjects(uid interface{}, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - user, err := parseID(uid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("users/%s/projects", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*Project - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ProjectUser represents a GitLab project user. -type ProjectUser struct { - ID int `json:"id"` - Name string `json:"name"` - Username string `json:"username"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` -} - -// ListProjectUserOptions represents the available ListProjectsUsers() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#get-project-users -type ListProjectUserOptions struct { - ListOptions - Search *string `url:"search,omitempty" json:"search,omitempty"` -} - -// ListProjectsUsers gets a list of users for the given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-project-users -func (s *ProjectsService) ListProjectsUsers(pid interface{}, opt *ListProjectUserOptions, options ...RequestOptionFunc) ([]*ProjectUser, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/users", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*ProjectUser - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ProjectLanguages is a map of strings because the response is arbitrary -// -// Gitlab API docs: https://docs.gitlab.com/ce/api/projects.html#languages -type ProjectLanguages map[string]float32 - -// GetProjectLanguages gets a list of languages used by the project -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#languages -func (s *ProjectsService) GetProjectLanguages(pid interface{}, options ...RequestOptionFunc) (*ProjectLanguages, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/languages", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(ProjectLanguages) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetProjectOptions represents the available GetProject() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#get-single-project -type GetProjectOptions struct { - Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` - License *bool `url:"license,omitempty" json:"license,omitempty"` - WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` -} - -// GetProject gets a specific project, identified by project ID or -// NAMESPACE/PROJECT_NAME, which is owned by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-single-project -func (s *ProjectsService) GetProject(pid interface{}, opt *GetProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ProjectEvent represents a GitLab project event. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-project-events -type ProjectEvent struct { - Title interface{} `json:"title"` - ProjectID int `json:"project_id"` - ActionName string `json:"action_name"` - TargetID interface{} `json:"target_id"` - TargetType interface{} `json:"target_type"` - AuthorID int `json:"author_id"` - AuthorUsername string `json:"author_username"` - Data struct { - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - UserID int `json:"user_id"` - UserName string `json:"user_name"` - Repository *Repository `json:"repository"` - Commits []*Commit `json:"commits"` - TotalCommitsCount int `json:"total_commits_count"` - } `json:"data"` - TargetTitle interface{} `json:"target_title"` -} - -func (s ProjectEvent) String() string { - return Stringify(s) -} - -// GetProjectEventsOptions represents the available GetProjectEvents() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-project-events -type GetProjectEventsOptions ListOptions - -// GetProjectEvents gets the events for the specified project. Sorted from -// newest to latest. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-project-events -func (s *ProjectsService) GetProjectEvents(pid interface{}, opt *GetProjectEventsOptions, options ...RequestOptionFunc) ([]*ProjectEvent, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/events", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*ProjectEvent - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CreateProjectOptions represents the available CreateProject() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#create-project -type CreateProjectOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - Path *string `url:"path,omitempty" json:"path,omitempty"` - NamespaceID *int `url:"namespace_id,omitempty" json:"namespace_id,omitempty"` - DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - IssuesAccessLevel *AccessControlValue `url:"issues_access_level,omitempty" json:"issues_access_level,omitempty"` - RepositoryAccessLevel *AccessControlValue `url:"repository_access_level,omitempty" json:"repository_access_level,omitempty"` - MergeRequestsAccessLevel *AccessControlValue `url:"merge_requests_access_level,omitempty" json:"merge_requests_access_level,omitempty"` - ForkingAccessLevel *AccessControlValue `url:"forking_access_level,omitempty" json:"forking_access_level,omitempty"` - BuildsAccessLevel *AccessControlValue `url:"builds_access_level,omitempty" json:"builds_access_level,omitempty"` - WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` - SnippetsAccessLevel *AccessControlValue `url:"snippets_access_level,omitempty" json:"snippets_access_level,omitempty"` - PagesAccessLevel *AccessControlValue `url:"pages_access_level,omitempty" json:"pages_access_level,omitempty"` - EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` - ResolveOutdatedDiffDiscussions *bool `url:"resolve_outdated_diff_discussions,omitempty" json:"resolve_outdated_diff_discussions,omitempty"` - ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` - SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` - ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` - PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` - OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` - OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` - MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` - RemoveSourceBranchAfterMerge *bool `url:"remove_source_branch_after_merge,omitempty" json:"remove_source_branch_after_merge,omitempty"` - LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` - RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` - TagList *[]string `url:"tag_list,omitempty" json:"tag_list,omitempty"` - PrintingMergeRequestLinkEnabled *bool `url:"printing_merge_request_link_enabled,omitempty" json:"printing_merge_request_link_enabled,omitempty"` - BuildGitStrategy *string `url:"build_git_strategy,omitempty" json:"build_git_strategy,omitempty"` - BuildTimeout *int `url:"build_timeout,omitempty" json:"build_timeout,omitempty"` - AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` - BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` - CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` - AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` - AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` - ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` - ExternalAuthorizationClassificationLabel *string `url:"external_authorization_classification_label,omitempty" json:"external_authorization_classification_label,omitempty"` - Mirror *bool `url:"mirror,omitempty" json:"mirror,omitempty"` - MirrorTriggerBuilds *bool `url:"mirror_trigger_builds,omitempty" json:"mirror_trigger_builds,omitempty"` - InitializeWithReadme *bool `url:"initialize_with_readme,omitempty" json:"initialize_with_readme,omitempty"` - TemplateName *string `url:"template_name,omitempty" json:"template_name,omitempty"` - TemplateProjectID *int `url:"template_project_id,omitempty" json:"template_project_id,omitempty"` - UseCustomTemplate *bool `url:"use_custom_template,omitempty" json:"use_custom_template,omitempty"` - GroupWithProjectTemplatesID *int `url:"group_with_project_templates_id,omitempty" json:"group_with_project_templates_id,omitempty"` - PackagesEnabled *bool `url:"packages_enabled,omitempty" json:"packages_enabled,omitempty"` - ServiceDeskEnabled *bool `url:"service_desk_enabled,omitempty" json:"service_desk_enabled,omitempty"` - AutocloseReferencedIssues *bool `url:"autoclose_referenced_issues,omitempty" json:"autoclose_referenced_issues,omitempty"` - - // Deprecated members - IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` - MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` - JobsEnabled *bool `url:"jobs_enabled,omitempty" json:"jobs_enabled,omitempty"` - WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` - SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` -} - -// CreateProject creates a new project owned by the authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#create-project -func (s *ProjectsService) CreateProject(opt *CreateProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - req, err := s.client.NewRequest("POST", "projects", opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// CreateProjectForUserOptions represents the available CreateProjectForUser() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user -type CreateProjectForUserOptions CreateProjectOptions - -// CreateProjectForUser creates a new project owned by the specified user. -// Available only for admins. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user -func (s *ProjectsService) CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - u := fmt.Sprintf("projects/user/%d", user) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// EditProjectOptions represents the available EditProject() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project -type EditProjectOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - Path *string `url:"path,omitempty" json:"path,omitempty"` - DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - IssuesAccessLevel *AccessControlValue `url:"issues_access_level,omitempty" json:"issues_access_level,omitempty"` - RepositoryAccessLevel *AccessControlValue `url:"repository_access_level,omitempty" json:"repository_access_level,omitempty"` - MergeRequestsAccessLevel *AccessControlValue `url:"merge_requests_access_level,omitempty" json:"merge_requests_access_level,omitempty"` - ForkingAccessLevel *AccessControlValue `url:"forking_access_level,omitempty" json:"forking_access_level,omitempty"` - BuildsAccessLevel *AccessControlValue `url:"builds_access_level,omitempty" json:"builds_access_level,omitempty"` - WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` - SnippetsAccessLevel *AccessControlValue `url:"snippets_access_level,omitempty" json:"snippets_access_level,omitempty"` - PagesAccessLevel *AccessControlValue `url:"pages_access_level,omitempty" json:"pages_access_level,omitempty"` - EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` - ResolveOutdatedDiffDiscussions *bool `url:"resolve_outdated_diff_discussions,omitempty" json:"resolve_outdated_diff_discussions,omitempty"` - ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` - SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` - ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` - PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` - OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` - OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` - MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` - RemoveSourceBranchAfterMerge *bool `url:"remove_source_branch_after_merge,omitempty" json:"remove_source_branch_after_merge,omitempty"` - LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` - RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` - TagList *[]string `url:"tag_list,omitempty" json:"tag_list,omitempty"` - BuildGitStrategy *string `url:"build_git_strategy,omitempty" json:"build_git_strategy,omitempty"` - BuildTimeout *int `url:"build_timeout,omitempty" json:"build_timeout,omitempty"` - AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` - BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` - CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` - CIDefaultGitDepth *int `url:"ci_default_git_depth,omitempty" json:"ci_default_git_depth,omitempty"` - AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` - AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` - ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` - ExternalAuthorizationClassificationLabel *string `url:"external_authorization_classification_label,omitempty" json:"external_authorization_classification_label,omitempty"` - Mirror *bool `url:"mirror,omitempty" json:"mirror,omitempty"` - MirrorUserID *int `url:"mirror_user_id,omitempty" json:"mirror_user_id,omitempty"` - MirrorTriggerBuilds *bool `url:"mirror_trigger_builds,omitempty" json:"mirror_trigger_builds,omitempty"` - OnlyMirrorProtectedBranches *bool `url:"only_mirror_protected_branches,omitempty" json:"only_mirror_protected_branches,omitempty"` - MirrorOverwritesDivergedBranches *bool `url:"mirror_overwrites_diverged_branches,omitempty" json:"mirror_overwrites_diverged_branches,omitempty"` - PackagesEnabled *bool `url:"packages_enabled,omitempty" json:"packages_enabled,omitempty"` - ServiceDeskEnabled *bool `url:"service_desk_enabled,omitempty" json:"service_desk_enabled,omitempty"` - AutocloseReferencedIssues *bool `url:"autoclose_referenced_issues,omitempty" json:"autoclose_referenced_issues,omitempty"` - - // Deprecated members - IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` - MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` - JobsEnabled *bool `url:"jobs_enabled,omitempty" json:"jobs_enabled,omitempty"` - WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` - SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` -} - -// EditProject updates an existing project. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project -func (s *ProjectsService) EditProject(pid interface{}, opt *EditProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ForkProjectOptions represents the available ForkProject() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#fork-project -type ForkProjectOptions struct { - Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty" ` - Path *string `url:"path,omitempty" json:"path,omitempty"` -} - -// ForkProject forks a project into the user namespace of the authenticated -// user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#fork-project -func (s *ProjectsService) ForkProject(pid interface{}, opt *ForkProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/fork", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// StarProject stars a given the project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#star-a-project -func (s *ProjectsService) StarProject(pid interface{}, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/star", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// UnstarProject unstars a given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#unstar-a-project -func (s *ProjectsService) UnstarProject(pid interface{}, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/unstar", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ArchiveProject archives the project if the user is either admin or the -// project owner of this project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#archive-a-project -func (s *ProjectsService) ArchiveProject(pid interface{}, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/archive", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// UnarchiveProject unarchives the project if the user is either admin or -// the project owner of this project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#unarchive-a-project -func (s *ProjectsService) UnarchiveProject(pid interface{}, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/unarchive", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// DeleteProject removes a project including all associated resources -// (issues, merge requests etc.) -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#remove-project -func (s *ProjectsService) DeleteProject(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ShareWithGroupOptions represents options to share project with groups -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#share-project-with-group -type ShareWithGroupOptions struct { - GroupID *int `url:"group_id" json:"group_id"` - GroupAccess *AccessLevelValue `url:"group_access" json:"group_access"` - ExpiresAt *string `url:"expires_at" json:"expires_at"` -} - -// ShareProjectWithGroup allows to share a project with a group. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#share-project-with-group -func (s *ProjectsService) ShareProjectWithGroup(pid interface{}, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/share", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteSharedProjectFromGroup allows to unshare a project from a group. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#delete-a-shared-project-link-within-a-group -func (s *ProjectsService) DeleteSharedProjectFromGroup(pid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/share/%d", pathEscape(project), groupID) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ProjectMember represents a project member. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members -type ProjectMember struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - ExpiresAt *ISOTime `json:"expires_at"` - AccessLevel AccessLevelValue `json:"access_level"` - WebURL string `json:"web_url"` - AvatarURL string `json:"avatar_url"` -} - -// ProjectHook represents a project hook. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks -type ProjectHook struct { - ID int `json:"id"` - URL string `json:"url"` - ConfidentialNoteEvents bool `json:"confidential_note_events"` - ProjectID int `json:"project_id"` - PushEvents bool `json:"push_events"` - PushEventsBranchFilter string `json:"push_events_branch_filter"` - IssuesEvents bool `json:"issues_events"` - ConfidentialIssuesEvents bool `json:"confidential_issues_events"` - MergeRequestsEvents bool `json:"merge_requests_events"` - TagPushEvents bool `json:"tag_push_events"` - NoteEvents bool `json:"note_events"` - JobEvents bool `json:"job_events"` - PipelineEvents bool `json:"pipeline_events"` - WikiPageEvents bool `json:"wiki_page_events"` - EnableSSLVerification bool `json:"enable_ssl_verification"` - CreatedAt *time.Time `json:"created_at"` -} - -// ListProjectHooksOptions represents the available ListProjectHooks() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-project-hooks -type ListProjectHooksOptions ListOptions - -// ListProjectHooks gets a list of project hooks. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks -func (s *ProjectsService) ListProjectHooks(pid interface{}, opt *ListProjectHooksOptions, options ...RequestOptionFunc) ([]*ProjectHook, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/hooks", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ph []*ProjectHook - resp, err := s.client.Do(req, &ph) - if err != nil { - return nil, resp, err - } - - return ph, resp, err -} - -// GetProjectHook gets a specific hook for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#get-project-hook -func (s *ProjectsService) GetProjectHook(pid interface{}, hook int, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/hooks/%d", pathEscape(project), hook) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ph := new(ProjectHook) - resp, err := s.client.Do(req, ph) - if err != nil { - return nil, resp, err - } - - return ph, resp, err -} - -// AddProjectHookOptions represents the available AddProjectHook() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#add-project-hook -type AddProjectHookOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` - EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` - Token *string `url:"token,omitempty" json:"token,omitempty"` -} - -// AddProjectHook adds a hook to a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#add-project-hook -func (s *ProjectsService) AddProjectHook(pid interface{}, opt *AddProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/hooks", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - ph := new(ProjectHook) - resp, err := s.client.Do(req, ph) - if err != nil { - return nil, resp, err - } - - return ph, resp, err -} - -// EditProjectHookOptions represents the available EditProjectHook() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook -type EditProjectHookOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` - EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` - Token *string `url:"token,omitempty" json:"token,omitempty"` -} - -// EditProjectHook edits a hook for a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook -func (s *ProjectsService) EditProjectHook(pid interface{}, hook int, opt *EditProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/hooks/%d", pathEscape(project), hook) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ph := new(ProjectHook) - resp, err := s.client.Do(req, ph) - if err != nil { - return nil, resp, err - } - - return ph, resp, err -} - -// DeleteProjectHook removes a hook from a project. This is an idempotent -// method and can be called multiple times. Either the hook is available or not. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#delete-project-hook -func (s *ProjectsService) DeleteProjectHook(pid interface{}, hook int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/hooks/%d", pathEscape(project), hook) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ProjectForkRelation represents a project fork relationship. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#admin-fork-relation -type ProjectForkRelation struct { - ID int `json:"id"` - ForkedToProjectID int `json:"forked_to_project_id"` - ForkedFromProjectID int `json:"forked_from_project_id"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` -} - -// CreateProjectForkRelation creates a forked from/to relation between -// existing projects. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#create-a-forked-fromto-relation-between-existing-projects. -func (s *ProjectsService) CreateProjectForkRelation(pid int, fork int, options ...RequestOptionFunc) (*ProjectForkRelation, *Response, error) { - u := fmt.Sprintf("projects/%d/fork/%d", pid, fork) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - pfr := new(ProjectForkRelation) - resp, err := s.client.Do(req, pfr) - if err != nil { - return nil, resp, err - } - - return pfr, resp, err -} - -// DeleteProjectForkRelation deletes an existing forked from relationship. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#delete-an-existing-forked-from-relationship -func (s *ProjectsService) DeleteProjectForkRelation(pid int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("projects/%d/fork", pid) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ProjectFile represents an uploaded project file -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#upload-a-file -type ProjectFile struct { - Alt string `json:"alt"` - URL string `json:"url"` - Markdown string `json:"markdown"` -} - -// UploadFile upload a file from disk -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#upload-a-file -func (s *ProjectsService) UploadFile(pid interface{}, file string, options ...RequestOptionFunc) (*ProjectFile, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/uploads", pathEscape(project)) - - f, err := os.Open(file) - if err != nil { - return nil, nil, err - } - defer f.Close() - - b := &bytes.Buffer{} - w := multipart.NewWriter(b) - - fw, err := w.CreateFormFile("file", file) - if err != nil { - return nil, nil, err - } - - _, err = io.Copy(fw, f) - if err != nil { - return nil, nil, err - } - w.Close() - - req, err := s.client.NewRequest("", u, nil, options) - if err != nil { - return nil, nil, err - } - - req.Body = ioutil.NopCloser(b) - req.ContentLength = int64(b.Len()) - req.Header.Set("Content-Type", w.FormDataContentType()) - req.Method = "POST" - - uf := &ProjectFile{} - resp, err := s.client.Do(req, uf) - if err != nil { - return nil, resp, err - } - - return uf, resp, nil -} - -// ListProjectForks gets a list of project forks. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/projects.html#list-forks-of-a-project -func (s *ProjectsService) ListProjectForks(pid interface{}, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/forks", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var forks []*Project - resp, err := s.client.Do(req, &forks) - if err != nil { - return nil, resp, err - } - - return forks, resp, err -} - -// ProjectPushRules represents a project push rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#push-rules -type ProjectPushRules struct { - ID int `json:"id"` - ProjectID int `json:"project_id"` - CommitMessageRegex string `json:"commit_message_regex"` - CommitMessageNegativeRegex string `json:"commit_message_negative_regex"` - BranchNameRegex string `json:"branch_name_regex"` - DenyDeleteTag bool `json:"deny_delete_tag"` - CreatedAt *time.Time `json:"created_at"` - MemberCheck bool `json:"member_check"` - PreventSecrets bool `json:"prevent_secrets"` - AuthorEmailRegex string `json:"author_email_regex"` - FileNameRegex string `json:"file_name_regex"` - MaxFileSize int `json:"max_file_size"` - CommitCommitterCheck bool `json:"commit_committer_check"` - RejectUnsignedCommits bool `json:"reject_unsigned_commits"` -} - -// GetProjectPushRules gets the push rules of a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#get-project-push-rules -func (s *ProjectsService) GetProjectPushRules(pid interface{}, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/push_rule", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ppr := new(ProjectPushRules) - resp, err := s.client.Do(req, ppr) - if err != nil { - return nil, resp, err - } - - return ppr, resp, err -} - -// AddProjectPushRuleOptions represents the available AddProjectPushRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#add-project-push-rule -type AddProjectPushRuleOptions struct { - DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` - MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` - PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` - CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` - CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` - BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` - AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` - FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` - MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` - CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` - RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` -} - -// AddProjectPushRule adds a push rule to a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#add-project-push-rule -func (s *ProjectsService) AddProjectPushRule(pid interface{}, opt *AddProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/push_rule", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - ppr := new(ProjectPushRules) - resp, err := s.client.Do(req, ppr) - if err != nil { - return nil, resp, err - } - - return ppr, resp, err -} - -// EditProjectPushRuleOptions represents the available EditProjectPushRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#edit-project-push-rule -type EditProjectPushRuleOptions struct { - AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` - BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` - CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` - CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` - FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` - DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` - MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` - PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` - MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` - CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` - RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` -} - -// EditProjectPushRule edits a push rule for a specified project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#edit-project-push-rule -func (s *ProjectsService) EditProjectPushRule(pid interface{}, opt *EditProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/push_rule", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ppr := new(ProjectPushRules) - resp, err := s.client.Do(req, ppr) - if err != nil { - return nil, resp, err - } - - return ppr, resp, err -} - -// DeleteProjectPushRule removes a push rule from a project. This is an -// idempotent method and can be called multiple times. Either the push rule is -// available or not. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#delete-project-push-rule -func (s *ProjectsService) DeleteProjectPushRule(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/push_rule", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ProjectApprovals represents GitLab project level merge request approvals. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals -type ProjectApprovals struct { - Approvers []*MergeRequestApproverUser `json:"approvers"` - ApproverGroups []*MergeRequestApproverGroup `json:"approver_groups"` - ApprovalsBeforeMerge int `json:"approvals_before_merge"` - ResetApprovalsOnPush bool `json:"reset_approvals_on_push"` - DisableOverridingApproversPerMergeRequest bool `json:"disable_overriding_approvers_per_merge_request"` - MergeRequestsAuthorApproval bool `json:"merge_requests_author_approval"` - MergeRequestsDisableCommittersApproval bool `json:"merge_requests_disable_committers_approval"` -} - -// GetApprovalConfiguration get the approval configuration for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-configuration -func (s *ProjectsService) GetApprovalConfiguration(pid interface{}, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approvals", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pa := new(ProjectApprovals) - resp, err := s.client.Do(req, pa) - if err != nil { - return nil, resp, err - } - - return pa, resp, err -} - -// ChangeApprovalConfigurationOptions represents the available -// ApprovalConfiguration() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-configuration -type ChangeApprovalConfigurationOptions struct { - ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` - ResetApprovalsOnPush *bool `url:"reset_approvals_on_push,omitempty" json:"reset_approvals_on_push,omitempty"` - DisableOverridingApproversPerMergeRequest *bool `url:"disable_overriding_approvers_per_merge_request,omitempty" json:"disable_overriding_approvers_per_merge_request,omitempty"` - MergeRequestsAuthorApproval *bool `url:"merge_requests_author_approval,omitempty" json:"merge_requests_author_approval,omitempty"` - MergeRequestsDisableCommittersApproval *bool `url:"merge_requests_disable_committers_approval,omitempty" json:"merge_requests_disable_committers_approval,omitempty"` -} - -// ChangeApprovalConfiguration updates the approval configuration for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-configuration -func (s *ProjectsService) ChangeApprovalConfiguration(pid interface{}, opt *ChangeApprovalConfigurationOptions, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approvals", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pa := new(ProjectApprovals) - resp, err := s.client.Do(req, pa) - if err != nil { - return nil, resp, err - } - - return pa, resp, err -} - -// GetProjectApprovalRules looks up the list of project level approvers. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-project-level-rules -func (s *ProjectsService) GetProjectApprovalRules(pid interface{}, options ...RequestOptionFunc) ([]*ProjectApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approval_rules", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var par []*ProjectApprovalRule - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// CreateProjectLevelRuleOptions represents the available CreateProjectApprovalRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-project-level-rules -type CreateProjectLevelRuleOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` - UserIDs []int `url:"user_ids,omitempty" json:"user_ids,omitempty"` - GroupIDs []int `url:"group_ids,omitempty" json:"group_ids,omitempty"` - ProtectedBranchIDs []int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` -} - -// CreateProjectApprovalRule creates a new project-level approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-project-level-rules -func (s *ProjectsService) CreateProjectApprovalRule(pid interface{}, opt *CreateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approval_rules", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - par := new(ProjectApprovalRule) - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// UpdateProjectLevelRuleOptions represents the available UpdateProjectApprovalRule() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#update-project-level-rules -type UpdateProjectLevelRuleOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` - UserIDs []int `url:"user_ids,omitempty" json:"user_ids,omitempty"` - GroupIDs []int `url:"group_ids,omitempty" json:"group_ids,omitempty"` - ProtectedBranchIDs []int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` -} - -// UpdateProjectApprovalRule updates an existing approval rule with new options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#update-project-level-rules -func (s *ProjectsService) UpdateProjectApprovalRule(pid interface{}, approvalRule int, opt *UpdateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approval_rules/%d", pathEscape(project), approvalRule) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - par := new(ProjectApprovalRule) - resp, err := s.client.Do(req, &par) - if err != nil { - return nil, resp, err - } - - return par, resp, err -} - -// DeleteProjectApprovalRule deletes a project-level approval rule. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#delete-project-level-rules -func (s *ProjectsService) DeleteProjectApprovalRule(pid interface{}, approvalRule int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/approval_rules/%d", pathEscape(project), approvalRule) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ChangeAllowedApproversOptions represents the available ChangeAllowedApprovers() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers -type ChangeAllowedApproversOptions struct { - ApproverIDs []int `url:"approver_ids,omitempty" json:"approver_ids,omitempty"` - ApproverGroupIDs []int `url:"approver_group_ids,omitempty" json:"approver_group_ids,omitempty"` -} - -// ChangeAllowedApprovers updates the list of approvers and approver groups. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers -func (s *ProjectsService) ChangeAllowedApprovers(pid interface{}, opt *ChangeAllowedApproversOptions, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/approvers", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - pa := new(ProjectApprovals) - resp, err := s.client.Do(req, pa) - if err != nil { - return nil, resp, err - } - - return pa, resp, err -} - -// StartMirroringProject start the pull mirroring process for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/projects.html#start-the-pull-mirroring-process-for-a-project-starter -func (s *ProjectsService) StartMirroringProject(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/mirror/pull", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - resp, err := s.client.Do(req, nil) - if err != nil { - return resp, err - } - - return resp, err -} - -// TransferProjectOptions represents the available TransferProject() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#transfer-a-project-to-a-new-namespace -type TransferProjectOptions struct { - Namespace interface{} `url:"namespace,omitempty" json:"namespace,omitempty"` -} - -// TransferProject transfer a project into the specified namespace -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#transfer-a-project-to-a-new-namespace -func (s *ProjectsService) TransferProject(pid interface{}, opt *TransferProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/transfer", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(Project) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/protected_branches.go b/vendor/github.com/xanzy/go-gitlab/protected_branches.go deleted file mode 100644 index 8c1fcff1f..000000000 --- a/vendor/github.com/xanzy/go-gitlab/protected_branches.go +++ /dev/null @@ -1,213 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen, Michael Lihs -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" -) - -// ProtectedBranchesService handles communication with the protected branch -// related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#protected-branches-api -type ProtectedBranchesService struct { - client *Client -} - -// BranchAccessDescription represents the access description for a protected -// branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#protected-branches-api -type BranchAccessDescription struct { - AccessLevel AccessLevelValue `json:"access_level"` - UserID int `json:"user_id"` - GroupID int `json:"group_id"` - AccessLevelDescription string `json:"access_level_description"` -} - -// ProtectedBranch represents a protected branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#list-protected-branches -type ProtectedBranch struct { - ID int `json:"id"` - Name string `json:"name"` - PushAccessLevels []*BranchAccessDescription `json:"push_access_levels"` - MergeAccessLevels []*BranchAccessDescription `json:"merge_access_levels"` - UnprotectAccessLevels []*BranchAccessDescription `json:"unprotect_access_levels"` - CodeOwnerApprovalRequired bool `json:"code_owner_approval_required"` -} - -// ListProtectedBranchesOptions represents the available ListProtectedBranches() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#list-protected-branches -type ListProtectedBranchesOptions ListOptions - -// ListProtectedBranches gets a list of protected branches from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#list-protected-branches -func (s *ProtectedBranchesService) ListProtectedBranches(pid interface{}, opt *ListProtectedBranchesOptions, options ...RequestOptionFunc) ([]*ProtectedBranch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_branches", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var p []*ProtectedBranch - resp, err := s.client.Do(req, &p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// GetProtectedBranch gets a single protected branch or wildcard protected branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#get-a-single-protected-branch-or-wildcard-protected-branch -func (s *ProtectedBranchesService) GetProtectedBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_branches/%s", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - p := new(ProtectedBranch) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// ProtectRepositoryBranchesOptions represents the available -// ProtectRepositoryBranches() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#protect-repository-branches -type ProtectRepositoryBranchesOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - PushAccessLevel *AccessLevelValue `url:"push_access_level,omitempty" json:"push_access_level,omitempty"` - MergeAccessLevel *AccessLevelValue `url:"merge_access_level,omitempty" json:"merge_access_level,omitempty"` - UnprotectAccessLevel *AccessLevelValue `url:"unprotect_access_level,omitempty" json:"unprotect_access_level,omitempty"` - AllowedToPush []*ProtectBranchPermissionOptions `url:"allowed_to_push,omitempty" json:"allowed_to_push,omitempty"` - AllowedToMerge []*ProtectBranchPermissionOptions `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` - AllowedToUnprotect []*ProtectBranchPermissionOptions `url:"allowed_to_unprotect,omitempty" json:"allowed_to_unprotect,omitempty"` - CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` -} - -// ProtectBranchPermissionOptions represents a branch permission option. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#protect-repository-branches -type ProtectBranchPermissionOptions struct { - UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` - GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` - AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` -} - -// ProtectRepositoryBranches protects a single repository branch or several -// project repository branches using a wildcard protected branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#protect-repository-branches -func (s *ProtectedBranchesService) ProtectRepositoryBranches(pid interface{}, opt *ProtectRepositoryBranchesOptions, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_branches", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - p := new(ProtectedBranch) - resp, err := s.client.Do(req, p) - if err != nil { - return nil, resp, err - } - - return p, resp, err -} - -// UnprotectRepositoryBranches unprotects the given protected branch or wildcard -// protected branch. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/protected_branches.html#unprotect-repository-branches -func (s *ProtectedBranchesService) UnprotectRepositoryBranches(pid interface{}, branch string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/protected_branches/%s", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// RequireCodeOwnerApprovalsOptions represents the available -// RequireCodeOwnerApprovals() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_branches.html#require-code-owner-approvals-for-a-single-branch -type RequireCodeOwnerApprovalsOptions struct { - CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` -} - -// RequireCodeOwnerApprovals updates the code owner approval. -// -// Gitlab API docs: -// https://docs.gitlab.com/ee/api/protected_branches.html#require-code-owner-approvals-for-a-single-branch -func (s *ProtectedBranchesService) RequireCodeOwnerApprovals(pid interface{}, branch string, opt *RequireCodeOwnerApprovalsOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/protected_branches/%s", pathEscape(project), url.PathEscape(branch)) - - req, err := s.client.NewRequest("PATCH", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/protected_tags.go b/vendor/github.com/xanzy/go-gitlab/protected_tags.go deleted file mode 100644 index 10957af53..000000000 --- a/vendor/github.com/xanzy/go-gitlab/protected_tags.go +++ /dev/null @@ -1,145 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// ProtectedTagsService handles communication with the protected tag methods -// of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html -type ProtectedTagsService struct { - client *Client -} - -// ProtectedTag represents a protected tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html -type ProtectedTag struct { - Name string `json:"name"` - CreateAccessLevels []*TagAccessDescription `json:"create_access_levels"` -} - -// TagAccessDescription reperesents the access decription for a protected tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html -type TagAccessDescription struct { - AccessLevel AccessLevelValue `json:"access_level"` - AccessLevelDescription string `json:"access_level_description"` -} - -// ListProtectedTagsOptions represents the available ListProtectedTags() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#list-protected-tags -type ListProtectedTagsOptions ListOptions - -// ListProtectedTags returns a list of protected tags from a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#list-protected-tags -func (s *ProtectedTagsService) ListProtectedTags(pid interface{}, opt *ListProtectedTagsOptions, options ...RequestOptionFunc) ([]*ProtectedTag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_tags", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var pts []*ProtectedTag - resp, err := s.client.Do(req, &pts) - if err != nil { - return nil, resp, err - } - - return pts, resp, err -} - -// GetProtectedTag returns a single protected tag or wildcard protected tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#get-a-single-protected-tag-or-wildcard-protected-tag -func (s *ProtectedTagsService) GetProtectedTag(pid interface{}, tag string, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_tags/%s", pathEscape(project), pathEscape(tag)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - pt := new(ProtectedTag) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// ProtectRepositoryTagsOptions represents the available ProtectRepositoryTags() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#protect-repository-tags -type ProtectRepositoryTagsOptions struct { - Name *string `url:"name" json:"name"` - CreateAccessLevel *AccessLevelValue `url:"create_access_level,omitempty" json:"create_access_level,omitempty"` -} - -// ProtectRepositoryTags protects a single repository tag or several project -// repository tags using a wildcard protected tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#protect-repository-tags -func (s *ProtectedTagsService) ProtectRepositoryTags(pid interface{}, opt *ProtectRepositoryTagsOptions, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/protected_tags", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - pt := new(ProtectedTag) - resp, err := s.client.Do(req, pt) - if err != nil { - return nil, resp, err - } - - return pt, resp, err -} - -// UnprotectRepositoryTags unprotects the given protected tag or wildcard -// protected tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/protected_tags.html#unprotect-repository-tags -func (s *ProtectedTagsService) UnprotectRepositoryTags(pid interface{}, tag string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/protected_tags/%s", pathEscape(project), pathEscape(tag)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/registry.go b/vendor/github.com/xanzy/go-gitlab/registry.go deleted file mode 100644 index 8694cf94a..000000000 --- a/vendor/github.com/xanzy/go-gitlab/registry.go +++ /dev/null @@ -1,223 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// ContainerRegistryService handles communication with the container registry -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html -type ContainerRegistryService struct { - client *Client -} - -// RegistryRepository represents a GitLab content registry repository. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html -type RegistryRepository struct { - ID int `json:"id"` - Name string `json:"name"` - Path string `json:"path"` - Location string `json:"location"` - CreatedAt *time.Time `json:"created_at"` -} - -func (s RegistryRepository) String() string { - return Stringify(s) -} - -// RegistryRepositoryTag represents a GitLab registry image tag. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html -type RegistryRepositoryTag struct { - Name string `json:"name"` - Path string `json:"path"` - Location string `json:"location"` - Revision string `json:"revision"` - ShortRevision string `json:"short_revision"` - Digest string `json:"digest"` - CreatedAt *time.Time `json:"created_at"` - TotalSize int `json:"total_size"` -} - -func (s RegistryRepositoryTag) String() string { - return Stringify(s) -} - -// ListRegistryRepositoriesOptions represents the available -// ListRegistryRepositories() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repositories -type ListRegistryRepositoriesOptions ListOptions - -// ListRegistryRepositories gets a list of registry repositories in a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repositories -func (s *ContainerRegistryService) ListRegistryRepositories(pid interface{}, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var repos []*RegistryRepository - resp, err := s.client.Do(req, &repos) - if err != nil { - return nil, resp, err - } - - return repos, resp, err -} - -// DeleteRegistryRepository deletes a repository in a registry. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#delete-registry-repository -func (s *ContainerRegistryService) DeleteRegistryRepository(pid interface{}, repository int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories/%d", pathEscape(project), repository) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListRegistryRepositoryTagsOptions represents the available -// ListRegistryRepositoryTags() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#list-repository-tags -type ListRegistryRepositoryTagsOptions ListOptions - -// ListRegistryRepositoryTags gets a list of tags for given registry repository. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#list-repository-tags -func (s *ContainerRegistryService) ListRegistryRepositoryTags(pid interface{}, repository int, opt *ListRegistryRepositoryTagsOptions, options ...RequestOptionFunc) ([]*RegistryRepositoryTag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags", - pathEscape(project), - repository, - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var tags []*RegistryRepositoryTag - resp, err := s.client.Do(req, &tags) - if err != nil { - return nil, resp, err - } - - return tags, resp, err -} - -// GetRegistryRepositoryTagDetail get details of a registry repository tag -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#get-details-of-a-repository-tag -func (s *ContainerRegistryService) GetRegistryRepositoryTagDetail(pid interface{}, repository int, tagName string, options ...RequestOptionFunc) (*RegistryRepositoryTag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s", - pathEscape(project), - repository, - tagName, - ) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - tag := new(RegistryRepositoryTag) - resp, err := s.client.Do(req, &tag) - if err != nil { - return nil, resp, err - } - - return tag, resp, err -} - -// DeleteRegistryRepositoryTag deletes a registry repository tag. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#delete-a-repository-tag -func (s *ContainerRegistryService) DeleteRegistryRepositoryTag(pid interface{}, repository int, tagName string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s", - pathEscape(project), - repository, - tagName, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteRegistryRepositoryTagsOptions represents the available -// DeleteRegistryRepositoryTags() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#delete-repository-tags-in-bulk -type DeleteRegistryRepositoryTagsOptions struct { - NameRegexpDelete *string `url:"name_regex_delete,omitempty" json:"name_regex_delete,omitempty"` - NameRegexpKeep *string `url:"name_regex_keep,omitempty" json:"name_regex_keep,omitempty"` - KeepN *int `url:"keep_n,omitempty" json:"keep_n,omitempty"` - OlderThan *string `url:"older_than,omitempty" json:"older_than,omitempty"` - - // Deprecated members - NameRegexp *string `url:"name_regex,omitempty" json:"name_regex,omitempty"` -} - -// DeleteRegistryRepositoryTags deletes repository tags in bulk based on -// given criteria. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/container_registry.html#delete-repository-tags-in-bulk -func (s *ContainerRegistryService) DeleteRegistryRepositoryTags(pid interface{}, repository int, opt *DeleteRegistryRepositoryTagsOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags", - pathEscape(project), - repository, - ) - - req, err := s.client.NewRequest("DELETE", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/releaselinks.go b/vendor/github.com/xanzy/go-gitlab/releaselinks.go deleted file mode 100644 index 04daaa868..000000000 --- a/vendor/github.com/xanzy/go-gitlab/releaselinks.go +++ /dev/null @@ -1,176 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// ReleaseLinksService handles communication with the release link methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html -type ReleaseLinksService struct { - client *Client -} - -// ReleaseLink represents a release link. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html -type ReleaseLink struct { - ID int `json:"id"` - Name string `json:"name"` - URL string `json:"url"` - External bool `json:"external"` -} - -// ListReleaseLinksOptions represents ListReleaseLinks() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-links -type ListReleaseLinksOptions ListOptions - -// ListReleaseLinks gets assets as links from a Release. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-links -func (s *ReleaseLinksService) ListReleaseLinks(pid interface{}, tagName string, opt *ListReleaseLinksOptions, options ...RequestOptionFunc) ([]*ReleaseLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s/assets/links", pathEscape(project), tagName) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rls []*ReleaseLink - resp, err := s.client.Do(req, &rls) - if err != nil { - return nil, resp, err - } - - return rls, resp, err -} - -// GetReleaseLink returns a link from release assets. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#get-a-link -func (s *ReleaseLinksService) GetReleaseLink(pid interface{}, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", - pathEscape(project), - tagName, - link) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - rl := new(ReleaseLink) - resp, err := s.client.Do(req, rl) - if err != nil { - return nil, resp, err - } - - return rl, resp, err -} - -// CreateReleaseLinkOptions represents CreateReleaseLink() options. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#create-a-link -type CreateReleaseLinkOptions struct { - Name *string `url:"name" json:"name"` - URL *string `url:"url" json:"url"` -} - -// CreateReleaseLink creates a link. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#create-a-link -func (s *ReleaseLinksService) CreateReleaseLink(pid interface{}, tagName string, opt *CreateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s/assets/links", pathEscape(project), tagName) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - rl := new(ReleaseLink) - resp, err := s.client.Do(req, rl) - if err != nil { - return nil, resp, err - } - - return rl, resp, err -} - -// UpdateReleaseLinkOptions represents UpdateReleaseLink() options. -// -// You have to specify at least one of Name of URL. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#update-a-link -type UpdateReleaseLinkOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - URL *string `url:"url,omitempty" json:"url,omitempty"` -} - -// UpdateReleaseLink updates an asset link. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#update-a-link -func (s *ReleaseLinksService) UpdateReleaseLink(pid interface{}, tagName string, link int, opt *UpdateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", - pathEscape(project), - tagName, - link) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - rl := new(ReleaseLink) - resp, err := s.client.Do(req, rl) - if err != nil { - return nil, resp, err - } - - return rl, resp, err -} - -// DeleteReleaseLink deletes a link from release. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#delete-a-link -func (s *ReleaseLinksService) DeleteReleaseLink(pid interface{}, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", - pathEscape(project), - tagName, - link, - ) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - rl := new(ReleaseLink) - resp, err := s.client.Do(req, rl) - if err != nil { - return nil, resp, err - } - - return rl, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/releases.go b/vendor/github.com/xanzy/go-gitlab/releases.go deleted file mode 100644 index 39df844c8..000000000 --- a/vendor/github.com/xanzy/go-gitlab/releases.go +++ /dev/null @@ -1,212 +0,0 @@ -package gitlab - -import ( - "fmt" - "time" -) - -// ReleasesService handles communication with the releases methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/releases/index.html -type ReleasesService struct { - client *Client -} - -// Release represents a project release. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#list-releases -type Release struct { - TagName string `json:"tag_name"` - Name string `json:"name"` - Description string `json:"description,omitempty"` - DescriptionHTML string `json:"description_html,omitempty"` - CreatedAt *time.Time `json:"created_at,omitempty"` - Author struct { - ID int `json:"id"` - Name string `json:"name"` - Username string `json:"username"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"author"` - Commit Commit `json:"commit"` - Assets struct { - Count int `json:"count"` - Sources []struct { - Format string `json:"format"` - URL string `json:"url"` - } `json:"sources"` - Links []*ReleaseLink `json:"links"` - } `json:"assets"` -} - -// ListReleasesOptions represents ListReleases() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#list-releases -type ListReleasesOptions ListOptions - -// ListReleases gets a pagenated of releases accessible by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#list-releases -func (s *ReleasesService) ListReleases(pid interface{}, opt *ListReleasesOptions, options ...RequestOptionFunc) ([]*Release, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Release - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// GetRelease returns a single release, identified by a tag name. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#get-a-release-by-a-tag-name -func (s *ReleasesService) GetRelease(pid interface{}, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s", pathEscape(project), tagName) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - r := new(Release) - resp, err := s.client.Do(req, r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// ReleaseAssets represents release assets in CreateRelease() options -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release -type ReleaseAssets struct { - Links []*ReleaseAssetLink `url:"links" json:"links"` -} - -// ReleaseAssetLink represents release asset link in CreateRelease() options -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release -type ReleaseAssetLink struct { - Name string `url:"name" json:"name"` - URL string `url:"url" json:"url"` -} - -// CreateReleaseOptions represents CreateRelease() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release -type CreateReleaseOptions struct { - Name *string `url:"name" json:"name"` - TagName *string `url:"tag_name" json:"tag_name"` - Description *string `url:"description" json:"description"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Assets *ReleaseAssets `url:"assets,omitempty" json:"assets,omitempty"` -} - -// CreateRelease creates a release. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#create-a-release -func (s *ReleasesService) CreateRelease(pid interface{}, opts *CreateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opts, options) - if err != nil { - return nil, nil, err - } - - r := new(Release) - resp, err := s.client.Do(req, r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// UpdateReleaseOptions represents UpdateRelease() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#update-a-release -type UpdateReleaseOptions struct { - Name *string `url:"name" json:"name"` - Description *string `url:"description" json:"description"` -} - -// UpdateRelease updates a release. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#update-a-release -func (s *ReleasesService) UpdateRelease(pid interface{}, tagName string, opts *UpdateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s", pathEscape(project), tagName) - - req, err := s.client.NewRequest("PUT", u, opts, options) - if err != nil { - return nil, nil, err - } - - r := new(Release) - resp, err := s.client.Do(req, &r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// DeleteRelease deletes a release. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/releases/index.html#delete-a-release -func (s *ReleasesService) DeleteRelease(pid interface{}, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/releases/%s", pathEscape(project), tagName) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, nil, err - } - - r := new(Release) - resp, err := s.client.Do(req, r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/repositories.go b/vendor/github.com/xanzy/go-gitlab/repositories.go deleted file mode 100644 index 1c37d118e..000000000 --- a/vendor/github.com/xanzy/go-gitlab/repositories.go +++ /dev/null @@ -1,331 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" - "io" - "net/url" -) - -// RepositoriesService handles communication with the repositories related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html -type RepositoriesService struct { - client *Client -} - -// TreeNode represents a GitLab repository file or directory. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html -type TreeNode struct { - ID string `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - Path string `json:"path"` - Mode string `json:"mode"` -} - -func (t TreeNode) String() string { - return Stringify(t) -} - -// ListTreeOptions represents the available ListTree() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree -type ListTreeOptions struct { - ListOptions - Path *string `url:"path,omitempty" json:"path,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Recursive *bool `url:"recursive,omitempty" json:"recursive,omitempty"` -} - -// ListTree gets a list of repository files and directories in a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree -func (s *RepositoriesService) ListTree(pid interface{}, opt *ListTreeOptions, options ...RequestOptionFunc) ([]*TreeNode, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tree", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var t []*TreeNode - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// Blob gets information about blob in repository like size and content. Note -// that blob content is Base64 encoded. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#get-a-blob-from-repository -func (s *RepositoriesService) Blob(pid interface{}, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/blobs/%s", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} - -// RawBlobContent gets the raw file contents for a blob by blob SHA. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#raw-blob-content -func (s *RepositoriesService) RawBlobContent(pid interface{}, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/blobs/%s/raw", pathEscape(project), url.PathEscape(sha)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} - -// ArchiveOptions represents the available Archive() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive -type ArchiveOptions struct { - Format *string `url:"-" json:"-"` - SHA *string `url:"sha,omitempty" json:"sha,omitempty"` -} - -// Archive gets an archive of the repository. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive -func (s *RepositoriesService) Archive(pid interface{}, opt *ArchiveOptions, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/archive", pathEscape(project)) - - // Set an optional format for the archive. - if opt != nil && opt.Format != nil { - u = fmt.Sprintf("%s.%s", u, *opt.Format) - } - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} - -// StreamArchive streams an archive of the repository to the provided -// io.Writer. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive -func (s *RepositoriesService) StreamArchive(pid interface{}, w io.Writer, opt *ArchiveOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/repository/archive", pathEscape(project)) - - // Set an optional format for the archive. - if opt != nil && opt.Format != nil { - u = fmt.Sprintf("%s.%s", u, *opt.Format) - } - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, w) -} - -// Compare represents the result of a comparison of branches, tags or commits. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits -type Compare struct { - Commit *Commit `json:"commit"` - Commits []*Commit `json:"commits"` - Diffs []*Diff `json:"diffs"` - CompareTimeout bool `json:"compare_timeout"` - CompareSameRef bool `json:"compare_same_ref"` -} - -func (c Compare) String() string { - return Stringify(c) -} - -// CompareOptions represents the available Compare() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits -type CompareOptions struct { - From *string `url:"from,omitempty" json:"from,omitempty"` - To *string `url:"to,omitempty" json:"to,omitempty"` - Straight *bool `url:"straight,omitempty" json:"straight,omitempty"` -} - -// Compare compares branches, tags or commits. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits -func (s *RepositoriesService) Compare(pid interface{}, opt *CompareOptions, options ...RequestOptionFunc) (*Compare, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/compare", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(Compare) - resp, err := s.client.Do(req, c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// Contributor represents a GitLap contributor. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributors -type Contributor struct { - Name string `json:"name"` - Email string `json:"email"` - Commits int `json:"commits"` - Additions int `json:"additions"` - Deletions int `json:"deletions"` -} - -func (c Contributor) String() string { - return Stringify(c) -} - -// ListContributorsOptions represents the available ListContributors() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributors -type ListContributorsOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// Contributors gets the repository contributors list. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributors -func (s *RepositoriesService) Contributors(pid interface{}, opt *ListContributorsOptions, options ...RequestOptionFunc) ([]*Contributor, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/contributors", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var c []*Contributor - resp, err := s.client.Do(req, &c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} - -// MergeBaseOptions represents the available MergeBase() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#merge-base -type MergeBaseOptions struct { - Ref []string `url:"refs[],omitempty" json:"refs,omitempty"` -} - -// MergeBase gets the common ancestor for 2 refs (commit SHAs, branch -// names or tags). -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repositories.html#merge-base -func (s *RepositoriesService) MergeBase(pid interface{}, opt *MergeBaseOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/merge_base", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - c := new(Commit) - resp, err := s.client.Do(req, c) - if err != nil { - return nil, resp, err - } - - return c, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/repository_files.go b/vendor/github.com/xanzy/go-gitlab/repository_files.go deleted file mode 100644 index cc954c27d..000000000 --- a/vendor/github.com/xanzy/go-gitlab/repository_files.go +++ /dev/null @@ -1,376 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" - "net/url" - "strconv" - "time" -) - -// RepositoryFilesService handles communication with the repository files -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html -type RepositoryFilesService struct { - client *Client -} - -// File represents a GitLab repository file. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html -type File struct { - FileName string `json:"file_name"` - FilePath string `json:"file_path"` - Size int `json:"size"` - Encoding string `json:"encoding"` - Content string `json:"content"` - Ref string `json:"ref"` - BlobID string `json:"blob_id"` - CommitID string `json:"commit_id"` - SHA256 string `json:"content_sha256"` - LastCommitID string `json:"last_commit_id"` -} - -func (r File) String() string { - return Stringify(r) -} - -// GetFileOptions represents the available GetFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository -type GetFileOptions struct { - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` -} - -// GetFile allows you to receive information about a file in repository like -// name, size, content. Note that file content is Base64 encoded. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository -func (s *RepositoryFilesService) GetFile(pid interface{}, fileName string, opt *GetFileOptions, options ...RequestOptionFunc) (*File, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - f := new(File) - resp, err := s.client.Do(req, f) - if err != nil { - return nil, resp, err - } - - return f, resp, err -} - -// GetFileMetaDataOptions represents the available GetFileMetaData() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository -type GetFileMetaDataOptions struct { - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` -} - -// GetFileMetaData allows you to receive meta information about a file in -// repository like name, size. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository -func (s *RepositoryFilesService) GetFileMetaData(pid interface{}, fileName string, opt *GetFileMetaDataOptions, options ...RequestOptionFunc) (*File, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("HEAD", u, opt, options) - if err != nil { - return nil, nil, err - } - - resp, err := s.client.Do(req, nil) - if err != nil { - return nil, resp, err - } - - f := &File{ - BlobID: resp.Header.Get("X-Gitlab-Blob-Id"), - CommitID: resp.Header.Get("X-Gitlab-Last-Commit-Id"), - Encoding: resp.Header.Get("X-Gitlab-Encoding"), - FileName: resp.Header.Get("X-Gitlab-File-Name"), - FilePath: resp.Header.Get("X-Gitlab-File-Path"), - Ref: resp.Header.Get("X-Gitlab-Ref"), - SHA256: resp.Header.Get("X-Gitlab-Content-Sha256"), - LastCommitID: resp.Header.Get("X-Gitlab-Last-Commit-Id"), - } - - if sizeString := resp.Header.Get("X-Gitlab-Size"); sizeString != "" { - f.Size, err = strconv.Atoi(sizeString) - if err != nil { - return nil, resp, err - } - } - - return f, resp, err -} - -// FileBlameRange represents one item of blame information. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html -type FileBlameRange struct { - Commit struct { - ID string `json:"id"` - ParentIDs []string `json:"parent_ids"` - Message string `json:"message"` - AuthoredDate *time.Time `json:"authored_date"` - AuthorName string `json:"author_name"` - AuthorEmail string `json:"author_email"` - CommittedDate *time.Time `json:"committed_date"` - CommitterName string `json:"committer_name"` - CommitterEmail string `json:"committer_email"` - } `json:"commit"` - Lines []string `json:"lines"` -} - -func (b FileBlameRange) String() string { - return Stringify(b) -} - -// GetFileBlameOptions represents the available GetFileBlame() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-blame-from-repository -type GetFileBlameOptions struct { - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` -} - -// GetFileBlame allows you to receive blame information. Each blame range -// contains lines and corresponding commit info. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-file-blame-from-repository -func (s *RepositoryFilesService) GetFileBlame(pid interface{}, file string, opt *GetFileBlameOptions, options ...RequestOptionFunc) ([]*FileBlameRange, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s/blame", - pathEscape(project), - url.PathEscape(file), - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var br []*FileBlameRange - resp, err := s.client.Do(req, &br) - if err != nil { - return nil, resp, err - } - - return br, resp, err -} - -// GetRawFileOptions represents the available GetRawFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-raw-file-from-repository -type GetRawFileOptions struct { - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` -} - -// GetRawFile allows you to receive the raw file in repository. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#get-raw-file-from-repository -func (s *RepositoryFilesService) GetRawFile(pid interface{}, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) ([]byte, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s/raw", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var f bytes.Buffer - resp, err := s.client.Do(req, &f) - if err != nil { - return nil, resp, err - } - - return f.Bytes(), resp, err -} - -// FileInfo represents file details of a GitLab repository file. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html -type FileInfo struct { - FilePath string `json:"file_path"` - Branch string `json:"branch"` -} - -func (r FileInfo) String() string { - return Stringify(r) -} - -// CreateFileOptions represents the available CreateFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository -type CreateFileOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` - Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` - AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` - AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` -} - -// CreateFile creates a new file in a repository. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository -func (s *RepositoryFilesService) CreateFile(pid interface{}, fileName string, opt *CreateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - f := new(FileInfo) - resp, err := s.client.Do(req, f) - if err != nil { - return nil, resp, err - } - - return f, resp, err -} - -// UpdateFileOptions represents the available UpdateFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository -type UpdateFileOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` - Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` - AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` - AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` - LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` -} - -// UpdateFile updates an existing file in a repository -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository -func (s *RepositoryFilesService) UpdateFile(pid interface{}, fileName string, opt *UpdateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - f := new(FileInfo) - resp, err := s.client.Do(req, f) - if err != nil { - return nil, resp, err - } - - return f, resp, err -} - -// DeleteFileOptions represents the available DeleteFile() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository -type DeleteFileOptions struct { - Branch *string `url:"branch,omitempty" json:"branch,omitempty"` - StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` - AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` - AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` - CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` - LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` -} - -// DeleteFile deletes an existing file in a repository -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository -func (s *RepositoryFilesService) DeleteFile(pid interface{}, fileName string, opt *DeleteFileOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf( - "projects/%s/repository/files/%s", - pathEscape(project), - url.PathEscape(fileName), - ) - - req, err := s.client.NewRequest("DELETE", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/request_options.go b/vendor/github.com/xanzy/go-gitlab/request_options.go deleted file mode 100644 index 9485aed0e..000000000 --- a/vendor/github.com/xanzy/go-gitlab/request_options.go +++ /dev/null @@ -1,30 +0,0 @@ -package gitlab - -import ( - "context" - - retryablehttp "github.com/hashicorp/go-retryablehttp" -) - -// RequestOptionFunc can be passed to all API requests to customize the API request. -type RequestOptionFunc func(*retryablehttp.Request) error - -// WithSudo takes either a username or user ID and sets the SUDO request header -func WithSudo(uid interface{}) RequestOptionFunc { - return func(req *retryablehttp.Request) error { - user, err := parseID(uid) - if err != nil { - return err - } - req.Header.Set("SUDO", user) - return nil - } -} - -// WithContext runs the request with the provided context -func WithContext(ctx context.Context) RequestOptionFunc { - return func(req *retryablehttp.Request) error { - *req = *req.WithContext(ctx) - return nil - } -} diff --git a/vendor/github.com/xanzy/go-gitlab/runners.go b/vendor/github.com/xanzy/go-gitlab/runners.go deleted file mode 100644 index 96c23467b..000000000 --- a/vendor/github.com/xanzy/go-gitlab/runners.go +++ /dev/null @@ -1,454 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "time" -) - -// RunnersService handles communication with the runner related methods of the -// GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html -type RunnersService struct { - client *Client -} - -// Runner represents a GitLab CI Runner. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html -type Runner struct { - ID int `json:"id"` - Description string `json:"description"` - Active bool `json:"active"` - IsShared bool `json:"is_shared"` - IPAddress string `json:"ip_address"` - Name string `json:"name"` - Online bool `json:"online"` - Status string `json:"status"` - Token string `json:"token"` -} - -// RunnerDetails represents the GitLab CI runner details. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html -type RunnerDetails struct { - Active bool `json:"active"` - Architecture string `json:"architecture"` - Description string `json:"description"` - ID int `json:"id"` - IPAddress string `json:"ip_address"` - IsShared bool `json:"is_shared"` - ContactedAt *time.Time `json:"contacted_at"` - Name string `json:"name"` - Online bool `json:"online"` - Status string `json:"status"` - Platform string `json:"platform"` - Projects []struct { - ID int `json:"id"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - } `json:"projects"` - Token string `json:"token"` - Revision string `json:"revision"` - TagList []string `json:"tag_list"` - Version string `json:"version"` - Locked bool `json:"locked"` - AccessLevel string `json:"access_level"` - MaximumTimeout int `json:"maximum_timeout"` - Groups []struct { - ID int `json:"id"` - Name string `json:"name"` - WebURL string `json:"web_url"` - } `json:"groups"` -} - -// ListRunnersOptions represents the available ListRunners() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-owned-runners -type ListRunnersOptions struct { - ListOptions - Scope *string `url:"scope,omitempty" json:"scope,omitempty"` - Type *string `url:"type,omitempty" json:"type,omitempty"` - Status *string `url:"status,omitempty" json:"status,omitempty"` - TagList []string `url:"tag_list,comma,omitempty" json:"tag_list,omitempty"` -} - -// ListRunners gets a list of runners accessible by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-owned-runners -func (s *RunnersService) ListRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { - req, err := s.client.NewRequest("GET", "runners", opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Runner - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// ListAllRunners gets a list of all runners in the GitLab instance. Access is -// restricted to users with admin privileges. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-all-runners -func (s *RunnersService) ListAllRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { - req, err := s.client.NewRequest("GET", "runners/all", opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Runner - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// GetRunnerDetails returns details for given runner. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#get-runner-39-s-details -func (s *RunnersService) GetRunnerDetails(rid interface{}, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) { - runner, err := parseID(rid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("runners/%s", runner) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var rs *RunnerDetails - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// UpdateRunnerDetailsOptions represents the available UpdateRunnerDetails() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#update-runner-39-s-details -type UpdateRunnerDetailsOptions struct { - Description *string `url:"description,omitempty" json:"description,omitempty"` - Active *bool `url:"active,omitempty" json:"active,omitempty"` - TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` - RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` - Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` - AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"` - MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` -} - -// UpdateRunnerDetails updates details for a given runner. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#update-runner-39-s-details -func (s *RunnersService) UpdateRunnerDetails(rid interface{}, opt *UpdateRunnerDetailsOptions, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) { - runner, err := parseID(rid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("runners/%s", runner) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rs *RunnerDetails - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// RemoveRunner removes a runner. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#remove-a-runner -func (s *RunnersService) RemoveRunner(rid interface{}, options ...RequestOptionFunc) (*Response, error) { - runner, err := parseID(rid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("runners/%s", runner) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListRunnerJobsOptions represents the available ListRunnerJobs() -// options. Status can be one of: running, success, failed, canceled. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-runners-jobs -type ListRunnerJobsOptions struct { - ListOptions - Status *string `url:"status,omitempty" json:"status,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListRunnerJobs gets a list of jobs that are being processed or were processed by specified Runner. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-runner-39-s-jobs -func (s *RunnersService) ListRunnerJobs(rid interface{}, opt *ListRunnerJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { - runner, err := parseID(rid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("runners/%s/jobs", runner) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Job - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// ListProjectRunnersOptions represents the available ListProjectRunners() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-project-s-runners -type ListProjectRunnersOptions ListRunnersOptions - -// ListProjectRunners gets a list of runners accessible by the authenticated user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#list-project-s-runners -func (s *RunnersService) ListProjectRunners(pid interface{}, opt *ListProjectRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/runners", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Runner - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// EnableProjectRunnerOptions represents the available EnableProjectRunner() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#enable-a-runner-in-project -type EnableProjectRunnerOptions struct { - RunnerID int `json:"runner_id"` -} - -// EnableProjectRunner enables an available specific runner in the project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#enable-a-runner-in-project -func (s *RunnersService) EnableProjectRunner(pid interface{}, opt *EnableProjectRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/runners", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - var r *Runner - resp, err := s.client.Do(req, &r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// DisableProjectRunner disables a specific runner from project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#disable-a-runner-from-project -func (s *RunnersService) DisableProjectRunner(pid interface{}, runner int, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/runners/%d", pathEscape(project), runner) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ListGroupsRunnersOptions represents the available ListGroupsRunners() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/runners.html#list-groups-runners -type ListGroupsRunnersOptions struct { - ListOptions - Type *string `url:"type,omitempty" json:"type,omitempty"` - Status *string `url:"status,omitempty" json:"status,omitempty"` - TagList []string `url:"tag_list,comma,omitempty" json:"tag_list,omitempty"` -} - -// ListGroupsRunners lists all runners (specific and shared) available in the -// group as well it’s ancestor groups. Shared runners are listed if at least one -// shared runner is defined. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/runners.html#list-groups-runners -func (s *RunnersService) ListGroupsRunners(gid interface{}, opt *ListGroupsRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("groups/%s/runners", pathEscape(group)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var rs []*Runner - resp, err := s.client.Do(req, &rs) - if err != nil { - return nil, resp, err - } - - return rs, resp, err -} - -// RegisterNewRunnerOptions represents the available RegisterNewRunner() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner -type RegisterNewRunnerOptions struct { - Token *string `url:"token" json:"token"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Info *string `url:"info,omitempty" json:"info,omitempty"` - Active *bool `url:"active,omitempty" json:"active,omitempty"` - Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` - RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` - TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` - MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` -} - -// RegisterNewRunner registers a new Runner for the instance. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner -func (s *RunnersService) RegisterNewRunner(opt *RegisterNewRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) { - req, err := s.client.NewRequest("POST", "runners", opt, options) - if err != nil { - return nil, nil, err - } - - var r *Runner - resp, err := s.client.Do(req, &r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// DeleteRegisteredRunnerOptions represents the available -// DeleteRegisteredRunner() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#delete-a-registered-runner -type DeleteRegisteredRunnerOptions struct { - Token *string `url:"token" json:"token"` -} - -// DeleteRegisteredRunner registers a new Runner for the instance. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#delete-a-registered-runner -func (s *RunnersService) DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) { - req, err := s.client.NewRequest("DELETE", "runners", opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// VerifyRegisteredRunnerOptions represents the available -// VerifyRegisteredRunner() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#verify-authentication-for-a-registered-runner -type VerifyRegisteredRunnerOptions struct { - Token *string `url:"token" json:"token"` -} - -// VerifyRegisteredRunner registers a new Runner for the instance. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/runners.html#verify-authentication-for-a-registered-runner -func (s *RunnersService) VerifyRegisteredRunner(opt *VerifyRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) { - req, err := s.client.NewRequest("POST", "runners/verify", opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/search.go b/vendor/github.com/xanzy/go-gitlab/search.go deleted file mode 100644 index 7ea1bf089..000000000 --- a/vendor/github.com/xanzy/go-gitlab/search.go +++ /dev/null @@ -1,354 +0,0 @@ -// -// Copyright 2018, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" -) - -// SearchService handles communication with the search related methods of the -// GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html -type SearchService struct { - client *Client -} - -// SearchOptions represents the available options for all search methods. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html -type SearchOptions ListOptions - -type searchOptions struct { - SearchOptions - Scope string `url:"scope" json:"scope"` - Search string `url:"search" json:"search"` -} - -// Projects searches the expression within projects -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-projects -func (s *SearchService) Projects(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - var ps []*Project - resp, err := s.search("projects", query, &ps, opt, options...) - return ps, resp, err -} - -// ProjectsByGroup searches the expression within projects for -// the specified group -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#group-search-api -func (s *SearchService) ProjectsByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { - var ps []*Project - resp, err := s.searchByGroup(gid, "projects", query, &ps, opt, options...) - return ps, resp, err -} - -// Issues searches the expression within issues -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues -func (s *SearchService) Issues(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - var is []*Issue - resp, err := s.search("issues", query, &is, opt, options...) - return is, resp, err -} - -// IssuesByGroup searches the expression within issues for -// the specified group -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues -func (s *SearchService) IssuesByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - var is []*Issue - resp, err := s.searchByGroup(gid, "issues", query, &is, opt, options...) - return is, resp, err -} - -// IssuesByProject searches the expression within issues for -// the specified project -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-issues -func (s *SearchService) IssuesByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { - var is []*Issue - resp, err := s.searchByProject(pid, "issues", query, &is, opt, options...) - return is, resp, err -} - -// MergeRequests searches the expression within merge requests -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests -func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - var ms []*MergeRequest - resp, err := s.search("merge_requests", query, &ms, opt, options...) - return ms, resp, err -} - -// MergeRequestsByGroup searches the expression within merge requests for -// the specified group -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests -func (s *SearchService) MergeRequestsByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - var ms []*MergeRequest - resp, err := s.searchByGroup(gid, "merge_requests", query, &ms, opt, options...) - return ms, resp, err -} - -// MergeRequestsByProject searches the expression within merge requests for -// the specified project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-merge_requests -func (s *SearchService) MergeRequestsByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { - var ms []*MergeRequest - resp, err := s.searchByProject(pid, "merge_requests", query, &ms, opt, options...) - return ms, resp, err -} - -// Milestones searches the expression within milestones -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones -func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { - var ms []*Milestone - resp, err := s.search("milestones", query, &ms, opt, options...) - return ms, resp, err -} - -// MilestonesByGroup searches the expression within milestones for -// the specified group -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones -func (s *SearchService) MilestonesByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { - var ms []*Milestone - resp, err := s.searchByGroup(gid, "milestones", query, &ms, opt, options...) - return ms, resp, err -} - -// MilestonesByProject searches the expression within milestones for -// the specified project -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-milestones -func (s *SearchService) MilestonesByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { - var ms []*Milestone - resp, err := s.searchByProject(pid, "milestones", query, &ms, opt, options...) - return ms, resp, err -} - -// SnippetTitles searches the expression within snippet titles -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-snippet_titles -func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { - var ss []*Snippet - resp, err := s.search("snippet_titles", query, &ss, opt, options...) - return ss, resp, err -} - -// SnippetBlobs searches the expression within snippet blobs -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-snippet_blobs -func (s *SearchService) SnippetBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { - var ss []*Snippet - resp, err := s.search("snippet_blobs", query, &ss, opt, options...) - return ss, resp, err -} - -// NotesByProject searches the expression within notes for the specified -// project -// -// GitLab API docs: // https://docs.gitlab.com/ce/api/search.html#scope-notes -func (s *SearchService) NotesByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { - var ns []*Note - resp, err := s.searchByProject(pid, "notes", query, &ns, opt, options...) - return ns, resp, err -} - -// WikiBlobs searches the expression within all wiki blobs -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs -func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { - var ws []*Wiki - resp, err := s.search("wiki_blobs", query, &ws, opt, options...) - return ws, resp, err -} - -// WikiBlobsByGroup searches the expression within wiki blobs for -// specified group -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs -func (s *SearchService) WikiBlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { - var ws []*Wiki - resp, err := s.searchByGroup(gid, "wiki_blobs", query, &ws, opt, options...) - return ws, resp, err -} - -// WikiBlobsByProject searches the expression within wiki blobs for -// the specified project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/search.html#scope-wiki_blobs -func (s *SearchService) WikiBlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { - var ws []*Wiki - resp, err := s.searchByProject(pid, "wiki_blobs", query, &ws, opt, options...) - return ws, resp, err -} - -// Commits searches the expression within all commits -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits -func (s *SearchService) Commits(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { - var cs []*Commit - resp, err := s.search("commits", query, &cs, opt, options...) - return cs, resp, err -} - -// CommitsByGroup searches the expression within commits for the specified -// group -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits -func (s *SearchService) CommitsByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { - var cs []*Commit - resp, err := s.searchByGroup(gid, "commits", query, &cs, opt, options...) - return cs, resp, err -} - -// CommitsByProject searches the expression within commits for the -// specified project -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-commits -func (s *SearchService) CommitsByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { - var cs []*Commit - resp, err := s.searchByProject(pid, "commits", query, &cs, opt, options...) - return cs, resp, err -} - -// Blob represents a single blob. -type Blob struct { - Basename string `json:"basename"` - Data string `json:"data"` - Filename string `json:"filename"` - ID int `json:"id"` - Ref string `json:"ref"` - Startline int `json:"startline"` - ProjectID int `json:"project_id"` -} - -// Blobs searches the expression within all blobs -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs -func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { - var bs []*Blob - resp, err := s.search("blobs", query, &bs, opt, options...) - return bs, resp, err -} - -// BlobsByGroup searches the expression within blobs for the specified -// group -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs -func (s *SearchService) BlobsByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { - var bs []*Blob - resp, err := s.searchByGroup(gid, "blobs", query, &bs, opt, options...) - return bs, resp, err -} - -// BlobsByProject searches the expression within blobs for the specified -// project -// -// GitLab API docs: https://docs.gitlab.com/ce/api/search.html#scope-blobs -func (s *SearchService) BlobsByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { - var bs []*Blob - resp, err := s.searchByProject(pid, "blobs", query, &bs, opt, options...) - return bs, resp, err -} - -// Users searches the expression within all users -// -// GitLab API docs: https://docs.gitlab.com/ee/api/search.html#scope-users -func (s *SearchService) Users(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { - var ret []*User - resp, err := s.search("users", query, &ret, opt, options...) - return ret, resp, err -} - -// UsersByGroup searches the expression within users for the specified -// group -// -// GitLab API docs: https://docs.gitlab.com/ee/api/search.html#scope-users-1 -func (s *SearchService) UsersByGroup(gid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { - var ret []*User - resp, err := s.searchByGroup(gid, "users", query, &ret, opt, options...) - return ret, resp, err -} - -// UsersByProject searches the expression within users for the -// specified project -// -// GitLab API docs: https://docs.gitlab.com/ee/api/search.html#scope-users-2 -func (s *SearchService) UsersByProject(pid interface{}, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { - var ret []*User - resp, err := s.searchByProject(pid, "users", query, &ret, opt, options...) - return ret, resp, err -} - -func (s *SearchService) search(scope, query string, result interface{}, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { - opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} - - req, err := s.client.NewRequest("GET", "search", opts, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, result) -} - -func (s *SearchService) searchByGroup(gid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { - group, err := parseID(gid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("groups/%s/-/search", pathEscape(group)) - - opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, result) -} - -func (s *SearchService) searchByProject(pid interface{}, scope, query string, result interface{}, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/-/search", pathEscape(project)) - - opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} - - req, err := s.client.NewRequest("GET", u, opts, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, result) -} diff --git a/vendor/github.com/xanzy/go-gitlab/services.go b/vendor/github.com/xanzy/go-gitlab/services.go deleted file mode 100644 index 0f36c4eb9..000000000 --- a/vendor/github.com/xanzy/go-gitlab/services.go +++ /dev/null @@ -1,1110 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "encoding/json" - "fmt" - "strconv" - "time" -) - -// ServicesService handles communication with the services related methods of -// the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/services.html -type ServicesService struct { - client *Client -} - -// Service represents a GitLab service. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/services.html -type Service struct { - ID int `json:"id"` - Title string `json:"title"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - Active bool `json:"active"` - PushEvents bool `json:"push_events"` - IssuesEvents bool `json:"issues_events"` - ConfidentialIssuesEvents bool `json:"confidential_issues_events"` - CommitEvents bool `json:"commit_events"` - MergeRequestsEvents bool `json:"merge_requests_events"` - CommentOnEventEnabled bool `json:"comment_on_event_enabled"` - TagPushEvents bool `json:"tag_push_events"` - NoteEvents bool `json:"note_events"` - ConfidentialNoteEvents bool `json:"confidential_note_events"` - PipelineEvents bool `json:"pipeline_events"` - JobEvents bool `json:"job_events"` - WikiPageEvents bool `json:"wiki_page_events"` -} - -// ListServices gets a list of all active services. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/services.html#list-all-active-services -func (s *ServicesService) ListServices(pid interface{}, options ...RequestOptionFunc) ([]*Service, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var svcs []*Service - resp, err := s.client.Do(req, &svcs) - if err != nil { - return nil, resp, err - } - - return svcs, resp, err -} - -// DroneCIService represents Drone CI service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#drone-ci -type DroneCIService struct { - Service - Properties *DroneCIServiceProperties `json:"properties"` -} - -// DroneCIServiceProperties represents Drone CI specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#drone-ci -type DroneCIServiceProperties struct { - Token string `json:"token"` - DroneURL string `json:"drone_url"` - EnableSSLVerification bool `json:"enable_ssl_verification"` -} - -// GetDroneCIService gets Drone CI service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings -func (s *ServicesService) GetDroneCIService(pid interface{}, options ...RequestOptionFunc) (*DroneCIService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(DroneCIService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetDroneCIServiceOptions represents the available SetDroneCIService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service -type SetDroneCIServiceOptions struct { - Token *string `url:"token" json:"token" ` - DroneURL *string `url:"drone_url" json:"drone_url"` - EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` -} - -// SetDroneCIService sets Drone CI service for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service -func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteDroneCIService deletes Drone CI service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service -func (s *ServicesService) DeleteDroneCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ExternalWikiService represents External Wiki service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#external-wiki -type ExternalWikiService struct { - Service - Properties *ExternalWikiServiceProperties `json:"properties"` -} - -// ExternalWikiServiceProperties represents External Wiki specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#external-wiki -type ExternalWikiServiceProperties struct { - ExternalWikiURL string `json:"external_wiki_url"` -} - -// GetExternalWikiService gets External Wiki service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-external-wiki-service-settings -func (s *ServicesService) GetExternalWikiService(pid interface{}, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(ExternalWikiService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetExternalWikiServiceOptions represents the available SetExternalWikiService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service -type SetExternalWikiServiceOptions struct { - ExternalWikiURL *string `url:"external_wiki_url,omitempty" json:"external_wiki_url,omitempty"` -} - -// SetExternalWikiService sets External Wiki service for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service -func (s *ServicesService) SetExternalWikiService(pid interface{}, opt *SetExternalWikiServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteExternalWikiService deletes External Wiki service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-external-wiki-service -func (s *ServicesService) DeleteExternalWikiService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// GithubService represents Github service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#github-premium -type GithubService struct { - Service - Properties *GithubServiceProperties `json:"properties"` -} - -// GithubServiceProperties represents Github specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#github-premium -type GithubServiceProperties struct { - RepositoryURL string `json:"repository_url,omitempty"` - StaticContext bool `json:"static_context,omitempty"` -} - -// GetGithubService gets Github service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-github-service-settings -func (s *ServicesService) GetGithubService(pid interface{}, options ...RequestOptionFunc) (*GithubService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/github", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(GithubService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetGithubServiceOptions represents the available SetGithubService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-github-service -type SetGithubServiceOptions struct { - Token *string `url:"token,omitempty" json:"token,omitempty"` - RepositoryURL *string `url:"repository_url,omitempty" json:"repository_url,omitempty"` - StaticContext *bool `url:"static_context,omitempty" json:"static_context,omitempty"` -} - -// SetGithubService sets Github service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-github-service -func (s *ServicesService) SetGithubService(pid interface{}, opt *SetGithubServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/github", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteGithubService deletes Github service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-github-service -func (s *ServicesService) DeleteGithubService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/github", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SetGitLabCIServiceOptions represents the available SetGitLabCIService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service -type SetGitLabCIServiceOptions struct { - Token *string `url:"token,omitempty" json:"token,omitempty"` - ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` -} - -// SetGitLabCIService sets GitLab CI service for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service -func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/gitlab-ci", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteGitLabCIService deletes GitLab CI service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service -func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/gitlab-ci", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SetHipChatServiceOptions represents the available SetHipChatService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service -type SetHipChatServiceOptions struct { - Token *string `url:"token,omitempty" json:"token,omitempty" ` - Room *string `url:"room,omitempty" json:"room,omitempty"` -} - -// SetHipChatService sets HipChat service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service -func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/hipchat", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteHipChatService deletes HipChat service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service -func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/hipchat", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// JenkinsCIService represents Jenkins CI service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#jenkins-ci -type JenkinsCIService struct { - Service - Properties *JenkinsCIServiceProperties `json:"properties"` -} - -// JenkinsCIServiceProperties represents Jenkins CI specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#jenkins-ci -type JenkinsCIServiceProperties struct { - URL string `json:"jenkins_url,omitempty"` - ProjectName string `json:"project_name,omitempty"` - Username string `json:"username,omitempty"` -} - -// GetJenkinsCIService gets Jenkins CI service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#get-jenkins-ci-service-settings -func (s *ServicesService) GetJenkinsCIService(pid interface{}, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(JenkinsCIService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetJenkinsCIServiceOptions represents the available SetJenkinsCIService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#jenkins-ci -type SetJenkinsCIServiceOptions struct { - URL *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"` - ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Password *string `url:"password,omitempty" json:"password,omitempty"` -} - -// SetJenkinsCIService sets Jenkins service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#create-edit-jenkins-ci-service -func (s *ServicesService) SetJenkinsCIService(pid interface{}, opt *SetJenkinsCIServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteJenkinsCIService deletes Jenkins CI service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-jira-service -func (s *ServicesService) DeleteJenkinsCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// JiraService represents Jira service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#jira -type JiraService struct { - Service - Properties *JiraServiceProperties `json:"properties"` -} - -// JiraServiceProperties represents Jira specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#jira -type JiraServiceProperties struct { - URL string `json:"url,omitempty"` - APIURL string `json:"api_url,omitempty"` - ProjectKey string `json:"project_key,omitempty" ` - Username string `json:"username,omitempty" ` - Password string `json:"password,omitempty" ` - JiraIssueTransitionID string `json:"jira_issue_transition_id,omitempty"` -} - -// UnmarshalJSON decodes the Jira Service Properties. -// -// This allows support of JiraIssueTransitionID for both type string (>11.9) and float64 (<11.9) -func (p *JiraServiceProperties) UnmarshalJSON(b []byte) error { - type Alias JiraServiceProperties - raw := struct { - *Alias - JiraIssueTransitionID interface{} `json:"jira_issue_transition_id"` - }{ - Alias: (*Alias)(p), - } - - if err := json.Unmarshal(b, &raw); err != nil { - return err - } - - switch id := raw.JiraIssueTransitionID.(type) { - case nil: - // No action needed. - case string: - p.JiraIssueTransitionID = id - case float64: - p.JiraIssueTransitionID = strconv.Itoa(int(id)) - default: - return fmt.Errorf("failed to unmarshal JiraTransitionID of type: %T", id) - } - - return nil -} - -// GetJiraService gets Jira service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-jira-service-settings -func (s *ServicesService) GetJiraService(pid interface{}, options ...RequestOptionFunc) (*JiraService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(JiraService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetJiraServiceOptions represents the available SetJiraService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-jira-service -type SetJiraServiceOptions struct { - URL *string `url:"url,omitempty" json:"url,omitempty"` - APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` - ProjectKey *string `url:"project_key,omitempty" json:"project_key,omitempty" ` - Username *string `url:"username,omitempty" json:"username,omitempty" ` - Password *string `url:"password,omitempty" json:"password,omitempty" ` - Active *bool `url:"active,omitempty" json:"active,omitempty"` - JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"` - CommitEvents *bool `url:"commit_events,omitempty" json:"commit_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - CommentOnEventEnabled *bool `url:"comment_on_event_enabled,omitempty" json:"comment_on_event_enabled,omitempty"` -} - -// SetJiraService sets Jira service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-jira-service -func (s *ServicesService) SetJiraService(pid interface{}, opt *SetJiraServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteJiraService deletes Jira service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-jira-service -func (s *ServicesService) DeleteJiraService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// MicrosoftTeamsService represents Microsoft Teams service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#microsoft-teams -type MicrosoftTeamsService struct { - Service - Properties *MicrosoftTeamsServiceProperties `json:"properties"` -} - -// MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#microsoft-teams -type MicrosoftTeamsServiceProperties struct { - WebHook string `json:"webhook"` - NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"` - BranchesToBeNotified string `json:"branches_to_be_notified"` - IssuesEvents BoolValue `json:"issues_events"` - ConfidentialIssuesEvents BoolValue `json:"confidential_issues_events"` - MergeRequestsEvents BoolValue `json:"merge_requests_events"` - TagPushEvents BoolValue `json:"tag_push_events"` - NoteEvents BoolValue `json:"note_events"` - ConfidentialNoteEvents BoolValue `json:"confidential_note_events"` - PipelineEvents BoolValue `json:"pipeline_events"` - WikiPageEvents BoolValue `json:"wiki_page_events"` -} - -// GetMicrosoftTeamsService gets MicrosoftTeams service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-microsoft-teams-service-settings -func (s *ServicesService) GetMicrosoftTeamsService(pid interface{}, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(MicrosoftTeamsService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetMicrosoftTeamsServiceOptions represents the available SetMicrosoftTeamsService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service -type SetMicrosoftTeamsServiceOptions struct { - WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` - NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines" json:"notify_only_broken_pipelines"` - BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` -} - -// SetMicrosoftTeamsService sets Microsoft Teams service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service -func (s *ServicesService) SetMicrosoftTeamsService(pid interface{}, opt *SetMicrosoftTeamsServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - return s.client.Do(req, nil) -} - -// DeleteMicrosoftTeamsService deletes Microsoft Teams service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-microsoft-teams-service -func (s *ServicesService) DeleteMicrosoftTeamsService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// PipelinesEmailService represents Pipelines Email service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#pipeline-emails -type PipelinesEmailService struct { - Service - Properties *PipelinesEmailProperties `json:"properties"` -} - -// PipelinesEmailProperties represents PipelinesEmail specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#pipeline-emails -type PipelinesEmailProperties struct { - Recipients string `json:"recipients,omitempty"` - NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines,omitempty"` - NotifyOnlyDefaultBranch BoolValue `json:"notify_only_default_branch,omitempty"` - BranchesToBeNotified string `json:"branches_to_be_notified,omitempty"` -} - -// GetPipelinesEmailService gets Pipelines Email service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#get-pipeline-emails-service-settings -func (s *ServicesService) GetPipelinesEmailService(pid interface{}, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/pipelines-email", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(PipelinesEmailService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetPipelinesEmailServiceOptions represents the available SetPipelinesEmailService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#pipeline-emails -type SetPipelinesEmailServiceOptions struct { - Recipients *string `url:"recipients,omitempty" json:"recipients,omitempty"` - NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` - NotifyOnlyDefaultBranch *bool `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"` - AddPusher *bool `url:"add_pusher,omitempty" json:"add_pusher,omitempty"` - BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` -} - -// SetPipelinesEmailService sets Pipelines Email service for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#pipeline-emails -func (s *ServicesService) SetPipelinesEmailService(pid interface{}, opt *SetPipelinesEmailServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/pipelines-email", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeletePipelinesEmailService deletes Pipelines Email service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/services.html#delete-pipeline-emails-service -func (s *ServicesService) DeletePipelinesEmailService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/pipelines-email", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SlackService represents Slack service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#slack -type SlackService struct { - Service - Properties *SlackServiceProperties `json:"properties"` -} - -// SlackServiceProperties represents Slack specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#slack -type SlackServiceProperties struct { - WebHook string `json:"webhook,omitempty"` - Username string `json:"username,omitempty"` - Channel string `json:"channel,omitempty"` - NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines,omitempty"` - NotifyOnlyDefaultBranch BoolValue `json:"notify_only_default_branch,omitempty"` - BranchesToBeNotified string `json:"branches_to_be_notified,omitempty"` - ConfidentialIssueChannel string `json:"confidential_issue_channel,omitempty"` - ConfidentialNoteChannel string `json:"confidential_note_channel,omitempty"` - DeploymentChannel string `json:"deployment_channel,omitempty"` - IssueChannel string `json:"issue_channel,omitempty"` - MergeRequestChannel string `json:"merge_request_channel,omitempty"` - NoteChannel string `json:"note_channel,omitempty"` - TagPushChannel string `json:"tag_push_channel,omitempty"` - PipelineChannel string `json:"pipeline_channel,omitempty"` - PushChannel string `json:"push_channel,omitempty"` - WikiPageChannel string `json:"wiki_page_channel,omitempty"` -} - -// GetSlackService gets Slack service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-slack-service-settings -func (s *ServicesService) GetSlackService(pid interface{}, options ...RequestOptionFunc) (*SlackService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(SlackService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetSlackServiceOptions represents the available SetSlackService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-slack-service -type SetSlackServiceOptions struct { - WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Channel *string `url:"channel,omitempty" json:"channel,omitempty"` - NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` - NotifyOnlyDefaultBranch *bool `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"` - BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` - ConfidentialIssueChannel *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"` - ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` - // TODO: Currently, GitLab ignores this option (not implemented yet?), so - // there is no way to set it. Uncomment when this is fixed. - // See: https://gitlab.com/gitlab-org/gitlab-ce/issues/49730 - //ConfidentialNoteChannel *string `json:"confidential_note_channel,omitempty"` - ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` - DeploymentChannel *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"` - DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` - IssueChannel *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"` - IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` - MergeRequestChannel *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - TagPushChannel *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"` - TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` - NoteChannel *string `url:"note_channel,omitempty" json:"note_channel,omitempty"` - NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` - PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"` - PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` - PushChannel *string `url:"push_channel,omitempty" json:"push_channel,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` - WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"` - WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` -} - -// SetSlackService sets Slack service for a project -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#edit-slack-service -func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteSlackService deletes Slack service for project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-slack-service -func (s *ServicesService) DeleteSlackService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// CustomIssueTrackerService represents Custom Issue Tracker service settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#custom-issue-tracker -type CustomIssueTrackerService struct { - Service - Properties *CustomIssueTrackerServiceProperties `json:"properties"` -} - -// CustomIssueTrackerServiceProperties represents Custom Issue Tracker specific properties. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#custom-issue-tracker -type CustomIssueTrackerServiceProperties struct { - ProjectURL string `json:"project_url,omitempty"` - IssuesURL string `json:"issues_url,omitempty"` - NewIssueURL string `json:"new_issue_url,omitempty"` -} - -// GetCustomIssueTrackerService gets Custom Issue Tracker service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#get-custom-issue-tracker-service-settings -func (s *ServicesService) GetCustomIssueTrackerService(pid interface{}, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - svc := new(CustomIssueTrackerService) - resp, err := s.client.Do(req, svc) - if err != nil { - return nil, resp, err - } - - return svc, resp, err -} - -// SetCustomIssueTrackerServiceOptions represents the available SetCustomIssueTrackerService() -// options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-custom-issue-tracker-service -type SetCustomIssueTrackerServiceOptions struct { - NewIssueURL *string `url:"new_issue_url,omitempty" json:"new_issue_url,omitempty"` - IssuesURL *string `url:"issues_url,omitempty" json:"issues_url,omitempty"` - ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Title *string `url:"title,omitempty" json:"title,omitempty"` - PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` -} - -// SetCustomIssueTrackerService sets Custom Issue Tracker service for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#createedit-custom-issue-tracker-service -func (s *ServicesService) SetCustomIssueTrackerService(pid interface{}, opt *SetCustomIssueTrackerServiceOptions, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", pathEscape(project)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteCustomIssueTrackerService deletes Custom Issue Tracker service settings for a project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/services.html#delete-custom-issue-tracker-service -func (s *ServicesService) DeleteCustomIssueTrackerService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", pathEscape(project)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/settings.go b/vendor/github.com/xanzy/go-gitlab/settings.go deleted file mode 100644 index 8811c8c20..000000000 --- a/vendor/github.com/xanzy/go-gitlab/settings.go +++ /dev/null @@ -1,409 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import "time" - -// SettingsService handles communication with the application SettingsService -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html -type SettingsService struct { - client *Client -} - -// Settings represents the GitLab application settings. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html -type Settings struct { - ID int `json:"id"` - CreatedAt *time.Time `json:"created_at"` - UpdatedAt *time.Time `json:"updated_at"` - AdminNotificationEmail string `json:"admin_notification_email"` - AfterSignOutPath string `json:"after_sign_out_path"` - AfterSignUpText string `json:"after_sign_up_text"` - AkismetAPIKey string `json:"akismet_api_key"` - AkismetEnabled bool `json:"akismet_enabled"` - AllowGroupOwnersToManageLDAP bool `json:"allow_group_owners_to_manage_ldap"` - AllowLocalRequestsFromHooksAndServices bool `json:"allow_local_requests_from_hooks_and_services"` - AllowLocalRequestsFromSystemHooks bool `json:"allow_local_requests_from_system_hooks"` - AllowLocalRequestsFromWebHooksAndServices bool `json:"allow_local_requests_from_web_hooks_and_services"` - ArchiveBuildsInHumanReadable string `json:"archive_builds_in_human_readable"` - AssetProxyEnabled bool `json:"asset_proxy_enabled"` - AssetProxySecretKey string `json:"asset_proxy_secret_key"` - AssetProxyURL string `json:"asset_proxy_url"` - AssetProxyWhitelist []string `json:"asset_proxy_whitelist"` - AuthorizedKeysEnabled bool `json:"authorized_keys_enabled_enabled"` - AutoDevOpsDomain string `json:"auto_devops_domain"` - AutoDevOpsEnabled bool `json:"auto_devops_enabled"` - CheckNamespacePlan bool `json:"check_namespace_plan"` - CommitEmailHostname string `json:"commit_email_hostname"` - ContainerRegistryTokenExpireDelay int `json:"container_registry_token_expire_delay"` - DefaultArtifactsExpireIn string `json:"default_artifacts_expire_in"` - DefaultBranchProtection int `json:"default_branch_protection"` - DefaultGroupVisibility VisibilityValue `json:"default_group_visibility"` - DefaultProjectCreation int `json:"default_project_creation"` - DefaultProjectsLimit int `json:"default_projects_limit"` - DefaultProjectVisibility VisibilityValue `json:"default_project_visibility"` - DefaultSnippetVisibility VisibilityValue `json:"default_snippet_visibility"` - DiffMaxPatchBytes int `json:"diff_max_patch_bytes"` - DisabledOauthSignInSources []string `json:"disabled_oauth_sign_in_sources"` - DNSRebindingProtectionEnabled bool `json:"dns_rebinding_protection_enabled"` - DomainBlacklist []string `json:"domain_blacklist"` - DomainBlacklistEnabled bool `json:"domain_blacklist_enabled"` - DomainWhitelist []string `json:"domain_whitelist"` - DSAKeyRestriction int `json:"dsa_key_restriction"` - ECDSAKeyRestriction int `json:"ecdsa_key_restriction"` - Ed25519KeyRestriction int `json:"ed25519_key_restriction"` - ElasticsearchAWSAccessKey string `json:"elasticsearch_aws_access_key"` - ElasticsearchAWS bool `json:"elasticsearch_aws"` - ElasticsearchAWSRegion string `json:"elasticsearch_aws_region"` - ElasticsearchAWSSecretAccessKey string `json:"elasticsearch_aws_secret_access_key"` - ElasticsearchIndexing bool `json:"elasticsearch_indexing"` - ElasticsearchLimitIndexing bool `json:"elasticsearch_limit_indexing"` - ElasticsearchNamespaceIDs []int `json:"elasticsearch_namespace_ids"` - ElasticsearchProjectIDs []int `json:"elasticsearch_project_ids"` - ElasticsearchSearch bool `json:"elasticsearch_search"` - ElasticsearchURL []string `json:"elasticsearch_url"` - EmailAdditionalText string `json:"email_additional_text"` - EmailAuthorInBody bool `json:"email_author_in_body"` - EnabledGitAccessProtocol string `json:"enabled_git_access_protocol"` - EnforceTerms bool `json:"enforce_terms"` - ExternalAuthClientCert string `json:"external_auth_client_cert"` - ExternalAuthClientKeyPass string `json:"external_auth_client_key_pass"` - ExternalAuthClientKey string `json:"external_auth_client_key"` - ExternalAuthorizationServiceDefaultLabel string `json:"external_authorization_service_default_label"` - ExternalAuthorizationServiceEnabled bool `json:"external_authorization_service_enabled"` - ExternalAuthorizationServiceTimeout float64 `json:"external_authorization_service_timeout"` - ExternalAuthorizationServiceURL string `json:"external_authorization_service_url"` - FileTemplateProjectID int `json:"file_template_project_id"` - FirstDayOfWeek int `json:"first_day_of_week"` - GeoNodeAllowedIPs string `json:"geo_node_allowed_ips"` - GeoStatusTimeout int `json:"geo_status_timeout"` - GitalyTimeoutDefault int `json:"gitaly_timeout_default"` - GitalyTimeoutFast int `json:"gitaly_timeout_fast"` - GitalyTimeoutMedium int `json:"gitaly_timeout_medium"` - GrafanaEnabled bool `json:"grafana_enabled"` - GrafanaURL string `json:"grafana_url"` - GravatarEnabled bool `json:"gravatar_enabled"` - HashedStorageEnabled bool `json:"hashed_storage_enabled"` - HelpPageHideCommercialContent bool `json:"help_page_hide_commercial_content"` - HelpPageSupportURL string `json:"help_page_support_url"` - HelpPageText string `json:"help_page_text"` - HelpText string `json:"help_text"` - HideThirdPartyOffers bool `json:"hide_third_party_offers"` - HomePageURL string `json:"home_page_url"` - HousekeepingBitmapsEnabled bool `json:"housekeeping_bitmaps_enabled"` - HousekeepingEnabled bool `json:"housekeeping_enabled"` - HousekeepingFullRepackPeriod int `json:"housekeeping_full_repack_period"` - HousekeepingGcPeriod int `json:"housekeeping_gc_period"` - HousekeepingIncrementalRepackPeriod int `json:"housekeeping_incremental_repack_period"` - HTMLEmailsEnabled bool `json:"html_emails_enabled"` - ImportSources []string `json:"import_sources"` - InstanceStatisticsVisibilityPrivate bool `json:"instance_statistics_visibility_private"` - LocalMarkdownVersion int `json:"local_markdown_version"` - MaxArtifactsSize int `json:"max_artifacts_size"` - MaxAttachmentSize int `json:"max_attachment_size"` - MaxPagesSize int `json:"max_pages_size"` - MetricsEnabled bool `json:"metrics_enabled"` - MetricsHost string `json:"metrics_host"` - MetricsMethodCallThreshold int `json:"metrics_method_call_threshold"` - MetricsPacketSize int `json:"metrics_packet_size"` - MetricsPoolSize int `json:"metrics_pool_size"` - MetricsPort int `json:"metrics_port"` - MetricsSampleInterval int `json:"metrics_sample_interval"` - MetricsTimeout int `json:"metrics_timeout"` - MirrorAvailable bool `json:"mirror_available"` - MirrorCapacityThreshold int `json:"mirror_capacity_threshold"` - MirrorMaxCapacity int `json:"mirror_max_capacity"` - MirrorMaxDelay int `json:"mirror_max_delay"` - OutboundLocalRequestsWhitelist []string `json:"outbound_local_requests_whitelist"` - PagesDomainVerificationEnabled bool `json:"pages_domain_verification_enabled"` - PasswordAuthenticationEnabledForGit bool `json:"password_authentication_enabled_for_git"` - PasswordAuthenticationEnabledForWeb bool `json:"password_authentication_enabled_for_web"` - PerformanceBarAllowedGroupID string `json:"performance_bar_allowed_group_id"` - PerformanceBarAllowedGroupPath string `json:"performance_bar_allowed_group_path"` - PerformanceBarEnabled bool `json:"performance_bar_enabled"` - PlantumlEnabled bool `json:"plantuml_enabled"` - PlantumlURL string `json:"plantuml_url"` - PollingIntervalMultiplier float64 `json:"polling_interval_multiplier,string"` - ProjectExportEnabled bool `json:"project_export_enabled"` - PrometheusMetricsEnabled bool `json:"prometheus_metrics_enabled"` - ProtectedCIVariables bool `json:"protected_ci_variables"` - PseudonymizerEnabled bool `json:"psedonymizer_enabled"` - PushEventHooksLimit int `json:"push_event_hooks_limit"` - PushEventActivitiesLimit int `json:"push_event_activities_limit"` - RecaptchaEnabled bool `json:"recaptcha_enabled"` - RecaptchaPrivateKey string `json:"recaptcha_private_key"` - RecaptchaSiteKey string `json:"recaptcha_site_key"` - ReceiveMaxInputSize int `json:"receive_max_input_size"` - RepositoryChecksEnabled bool `json:"repository_checks_enabled"` - RepositorySizeLimit int `json:"repository_size_limit"` - RepositoryStorages []string `json:"repository_storages"` - RequireTwoFactorAuthentication bool `json:"require_two_factor_authentication"` - RestrictedVisibilityLevels []VisibilityValue `json:"restricted_visibility_levels"` - RsaKeyRestriction int `json:"rsa_key_restriction"` - SendUserConfirmationEmail bool `json:"send_user_confirmation_email"` - SessionExpireDelay int `json:"session_expire_delay"` - SharedRunnersEnabled bool `json:"shared_runners_enabled"` - SharedRunnersMinutes int `json:"shared_runners_minutes"` - SharedRunnersText string `json:"shared_runners_text"` - SignInText string `json:"sign_in_text"` - SignupEnabled bool `json:"signup_enabled"` - SlackAppEnabled bool `json:"slack_app_enabled"` - SlackAppID string `json:"slack_app_id"` - SlackAppSecret string `json:"slack_app_secret"` - SlackAppVerificationToken string `json:"slack_app_verification_token"` - SnowplowCollectorHostname string `json:"snowplow_collector_hostname"` - SnowplowCookieDomain string `json:"snowplow_cookie_domain"` - SnowplowEnabled bool `json:"snowplow_enabled"` - SnowplowSiteID string `json:"snowplow_site_id"` - TerminalMaxSessionTime int `json:"terminal_max_session_time"` - Terms string `json:"terms"` - ThrottleAuthenticatedAPIEnabled bool `json:"throttle_authenticated_api_enabled"` - ThrottleAuthenticatedAPIPeriodInSeconds int `json:"throttle_authenticated_api_period_in_seconds"` - ThrottleAuthenticatedAPIRequestsPerPeriod int `json:"throttle_authenticated_api_requests_per_period"` - ThrottleAuthenticatedWebEnabled bool `json:"throttle_authenticated_web_enabled"` - ThrottleAuthenticatedWebPeriodInSeconds int `json:"throttle_authenticated_web_period_in_seconds"` - ThrottleAuthenticatedWebRequestsPerPeriod int `json:"throttle_authenticated_web_requests_per_period"` - ThrottleUnauthenticatedEnabled bool `json:"throttle_unauthenticated_enabled"` - ThrottleUnauthenticatedPeriodInSeconds int `json:"throttle_unauthenticated_period_in_seconds"` - ThrottleUnauthenticatedRequestsPerPeriod int `json:"throttle_unauthenticated_requests_per_period"` - TimeTrackingLimitToHours bool `json:"time_tracking_limit_to_hours"` - TwoFactorGracePeriod int `json:"two_factor_grace_period"` - UniqueIPsLimitEnabled bool `json:"unique_ips_limit_enabled"` - UniqueIPsLimitPerUser int `json:"unique_ips_limit_per_user"` - UniqueIPsLimitTimeWindow int `json:"unique_ips_limit_time_window"` - UsagePingEnabled bool `json:"usage_ping_enabled"` - UserDefaultExternal bool `json:"user_default_external"` - UserDefaultInternalRegex string `json:"user_default_internal_regex"` - UserOauthApplications bool `json:"user_oauth_applications"` - UserShowAddSSHKeyMessage bool `json:"user_show_add_ssh_key_message"` - VersionCheckEnabled bool `json:"version_check_enabled"` - WebIDEClientsidePreviewEnabled bool `json:"web_ide_clientside_preview_enabled"` -} - -func (s Settings) String() string { - return Stringify(s) -} - -// GetSettings gets the current application settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/settings.html#get-current-application.settings -func (s *SettingsService) GetSettings(options ...RequestOptionFunc) (*Settings, *Response, error) { - req, err := s.client.NewRequest("GET", "application/settings", nil, options) - if err != nil { - return nil, nil, err - } - - as := new(Settings) - resp, err := s.client.Do(req, as) - if err != nil { - return nil, resp, err - } - - return as, resp, err -} - -// UpdateSettingsOptions represents the available UpdateSettings() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/settings.html#change-application.settings -type UpdateSettingsOptions struct { - AdminNotificationEmail *string `url:"admin_notification_email,omitempty" json:"admin_notification_email,omitempty"` - AfterSignOutPath *string `url:"after_sign_out_path,omitempty" json:"after_sign_out_path,omitempty"` - AfterSignUpText *string `url:"after_sign_up_text,omitempty" json:"after_sign_up_text,omitempty"` - AkismetAPIKey *string `url:"akismet_api_key,omitempty" json:"akismet_api_key,omitempty"` - AkismetEnabled *bool `url:"akismet_enabled,omitempty" json:"akismet_enabled,omitempty"` - AllowGroupOwnersToManageLDAP *bool `url:"allow_group_owners_to_manage_ldap,omitempty" json:"allow_group_owners_to_manage_ldap,omitempty"` - AllowLocalRequestsFromHooksAndServices *bool `url:"allow_local_requests_from_hooks_and_services,omitempty" json:"allow_local_requests_from_hooks_and_services,omitempty"` - AllowLocalRequestsFromSystemHooks *bool `url:"allow_local_requests_from_system_hooks,omitempty" json:"allow_local_requests_from_system_hooks,omitempty"` - AllowLocalRequestsFromWebHooksAndServices *bool `url:"allow_local_requests_from_web_hooks_and_services,omitempty" json:"allow_local_requests_from_web_hooks_and_services,omitempty"` - ArchiveBuildsInHumanReadable *string `url:"archive_builds_in_human_readable,omitempty" json:"archive_builds_in_human_readable,omitempty"` - AssetProxyEnabled *bool `url:"asset_proxy_enabled,omitempty" json:"asset_proxy_enabled,omitempty"` - AssetProxySecretKey *string `url:"asset_proxy_secret_key,omitempty" json:"asset_proxy_secret_key,omitempty"` - AssetProxyURL *string `url:"asset_proxy_url,omitempty" json:"asset_proxy_url,omitempty"` - AssetProxyWhitelist []string `url:"asset_proxy_whitelist,omitempty" json:"asset_proxy_whitelist,omitempty"` - AuthorizedKeysEnabled *bool `url:"authorized_keys_enabled,omitempty" json:"authorized_keys_enabled,omitempty"` - AutoDevOpsDomain *string `url:"auto_devops_domain,omitempty" json:"auto_devops_domain,omitempty"` - AutoDevOpsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` - CheckNamespacePlan *bool `url:"check_namespace_plan,omitempty" json:"check_namespace_plan,omitempty"` - CommitEmailHostname *string `url:"commit_email_hostname,omitempty" json:"commit_email_hostname,omitempty"` - ContainerRegistryTokenExpireDelay *int `url:"container_registry_token_expire_delay,omitempty" json:"container_registry_token_expire_delay,omitempty"` - DefaultArtifactsExpireIn *string `url:"default_artifacts_expire_in,omitempty" json:"default_artifacts_expire_in,omitempty"` - DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"` - DefaultGroupVisibility *VisibilityValue `url:"default_group_visibility,omitempty" json:"default_group_visibility,omitempty"` - DefaultProjectCreation *int `url:"default_project_creation,omitempty" json:"default_project_creation,omitempty"` - DefaultProjectsLimit *int `url:"default_projects_limit,omitempty" json:"default_projects_limit,omitempty"` - DefaultProjectVisibility *VisibilityValue `url:"default_project_visibility,omitempty" json:"default_project_visibility,omitempty"` - DefaultSnippetVisibility *VisibilityValue `url:"default_snippet_visibility,omitempty" json:"default_snippet_visibility,omitempty"` - DiffMaxPatchBytes *int `url:"diff_max_patch_bytes,omitempty" json:"diff_max_patch_bytes,omitempty"` - DisabledOauthSignInSources []string `url:"disabled_oauth_sign_in_sources,omitempty" json:"disabled_oauth_sign_in_sources,omitempty"` - DNSRebindingProtectionEnabled *bool `url:"dns_rebinding_protection_enabled,omitempty" json:"dns_rebinding_protection_enabled,omitempty"` - DomainBlacklist []string `url:"domain_blacklist,omitempty" json:"domain_blacklist,omitempty"` - DomainBlacklistEnabled *bool `url:"domain_blacklist_enabled,omitempty" json:"domain_blacklist_enabled,omitempty"` - DomainWhitelist []string `url:"domain_whitelist,omitempty" json:"domain_whitelist,omitempty"` - DSAKeyRestriction *int `url:"dsa_key_restriction,omitempty" json:"dsa_key_restriction,omitempty"` - ECDSAKeyRestriction *int `url:"ecdsa_key_restriction,omitempty" json:"ecdsa_key_restriction,omitempty"` - Ed25519KeyRestriction *int `url:"ed25519_key_restriction,omitempty" json:"ed25519_key_restriction,omitempty"` - ElasticsearchAWSAccessKey *string `url:"elasticsearch_aws_access_key,omitempty" json:"elasticsearch_aws_access_key,omitempty"` - ElasticsearchAWS *bool `url:"elasticsearch_aws,omitempty" json:"elasticsearch_aws,omitempty"` - ElasticsearchAWSRegion *string `url:"elasticsearch_aws_region,omitempty" json:"elasticsearch_aws_region,omitempty"` - ElasticsearchAWSSecretAccessKey *string `url:"elasticsearch_aws_secret_access_key,omitempty" json:"elasticsearch_aws_secret_access_key,omitempty"` - ElasticsearchIndexing *bool `url:"elasticsearch_indexing,omitempty" json:"elasticsearch_indexing,omitempty"` - ElasticsearchLimitIndexing *bool `url:"elasticsearch_limit_indexing,omitempty" json:"elasticsearch_limit_indexing,omitempty"` - ElasticsearchNamespaceIDs []int `url:"elasticsearch_namespace_ids,omitempty" json:"elasticsearch_namespace_ids,omitempty"` - ElasticsearchProjectIDs []int `url:"elasticsearch_project_ids,omitempty" json:"elasticsearch_project_ids,omitempty"` - ElasticsearchSearch *bool `url:"elasticsearch_search,omitempty" json:"elasticsearch_search,omitempty"` - ElasticsearchURL *string `url:"elasticsearch_url,omitempty" json:"elasticsearch_url,omitempty"` - EmailAdditionalText *string `url:"email_additional_text,omitempty" json:"email_additional_text,omitempty"` - EmailAuthorInBody *bool `url:"email_author_in_body,omitempty" json:"email_author_in_body,omitempty"` - EnabledGitAccessProtocol *string `url:"enabled_git_access_protocol,omitempty" json:"enabled_git_access_protocol,omitempty"` - EnforceTerms *bool `url:"enforce_terms,omitempty" json:"enforce_terms,omitempty"` - ExternalAuthClientCert *string `url:"external_auth_client_cert,omitempty" json:"external_auth_client_cert,omitempty"` - ExternalAuthClientKeyPass *string `url:"external_auth_client_key_pass,omitempty" json:"external_auth_client_key_pass,omitempty"` - ExternalAuthClientKey *string `url:"external_auth_client_key,omitempty" json:"external_auth_client_key,omitempty"` - ExternalAuthorizationServiceDefaultLabel *string `url:"external_authorization_service_default_label,omitempty" json:"external_authorization_service_default_label,omitempty"` - ExternalAuthorizationServiceEnabled *bool `url:"external_authorization_service_enabled,omitempty" json:"external_authorization_service_enabled,omitempty"` - ExternalAuthorizationServiceTimeout *float64 `url:"external_authorization_service_timeout,omitempty" json:"external_authorization_service_timeout,omitempty"` - ExternalAuthorizationServiceURL *string `url:"external_authorization_service_url,omitempty" json:"external_authorization_service_url,omitempty"` - FileTemplateProjectID *int `url:"file_template_project_id,omitempty" json:"file_template_project_id,omitempty"` - FirstDayOfWeek *int `url:"first_day_of_week,omitempty" json:"first_day_of_week,omitempty"` - GeoNodeAllowedIPs *string `url:"geo_node_allowed_ips,omitempty" json:"geo_node_allowed_ips,omitempty"` - GeoStatusTimeout *int `url:"geo_status_timeout,omitempty" json:"geo_status_timeout,omitempty"` - GitalyTimeoutDefault *int `url:"gitaly_timeout_default,omitempty" json:"gitaly_timeout_default,omitempty"` - GitalyTimeoutFast *int `url:"gitaly_timeout_fast,omitempty" json:"gitaly_timeout_fast,omitempty"` - GitalyTimeoutMedium *int `url:"gitaly_timeout_medium,omitempty" json:"gitaly_timeout_medium,omitempty"` - GrafanaEnabled *bool `url:"grafana_enabled,omitempty" json:"grafana_enabled,omitempty"` - GrafanaURL *string `url:"grafana_url,omitempty" json:"grafana_url,omitempty"` - GravatarEnabled *bool `url:"gravatar_enabled,omitempty" json:"gravatar_enabled,omitempty"` - HashedStorageEnabled *bool `url:"hashed_storage_enabled,omitempty" json:"hashed_storage_enabled,omitempty"` - HelpPageHideCommercialContent *bool `url:"help_page_hide_commercial_content,omitempty" json:"help_page_hide_commercial_content,omitempty"` - HelpPageSupportURL *string `url:"help_page_support_url,omitempty" json:"help_page_support_url,omitempty"` - HelpPageText *string `url:"help_page_text,omitempty" json:"help_page_text,omitempty"` - HelpText *string `url:"help_text,omitempty" json:"help_text,omitempty"` - HideThirdPartyOffers *bool `url:"hide_third_party_offers,omitempty" json:"hide_third_party_offers,omitempty"` - HomePageURL *string `url:"home_page_url,omitempty" json:"home_page_url,omitempty"` - HousekeepingBitmapsEnabled *bool `url:"housekeeping_bitmaps_enabled,omitempty" json:"housekeeping_bitmaps_enabled,omitempty"` - HousekeepingEnabled *bool `url:"housekeeping_enabled,omitempty" json:"housekeeping_enabled,omitempty"` - HousekeepingFullRepackPeriod *int `url:"housekeeping_full_repack_period,omitempty" json:"housekeeping_full_repack_period,omitempty"` - HousekeepingGcPeriod *int `url:"housekeeping_gc_period,omitempty" json:"housekeeping_gc_period,omitempty"` - HousekeepingIncrementalRepackPeriod *int `url:"housekeeping_incremental_repack_period,omitempty" json:"housekeeping_incremental_repack_period,omitempty"` - HTMLEmailsEnabled *bool `url:"html_emails_enabled,omitempty" json:"html_emails_enabled,omitempty"` - ImportSources []string `url:"import_sources,omitempty" json:"import_sources,omitempty"` - InstanceStatisticsVisibilityPrivate *bool `url:"instance_statistics_visibility_private,omitempty" json:"instance_statistics_visibility_private,omitempty"` - LocalMarkdownVersion *int `url:"local_markdown_version,omitempty" json:"local_markdown_version,omitempty"` - MaxArtifactsSize *int `url:"max_artifacts_size,omitempty" json:"max_artifacts_size,omitempty"` - MaxAttachmentSize *int `url:"max_attachment_size,omitempty" json:"max_attachment_size,omitempty"` - MaxPagesSize *int `url:"max_pages_size,omitempty" json:"max_pages_size,omitempty"` - MetricsEnabled *bool `url:"metrics_enabled,omitempty" json:"metrics_enabled,omitempty"` - MetricsHost *string `url:"metrics_host,omitempty" json:"metrics_host,omitempty"` - MetricsMethodCallThreshold *int `url:"metrics_method_call_threshold,omitempty" json:"metrics_method_call_threshold,omitempty"` - MetricsPacketSize *int `url:"metrics_packet_size,omitempty" json:"metrics_packet_size,omitempty"` - MetricsPoolSize *int `url:"metrics_pool_size,omitempty" json:"metrics_pool_size,omitempty"` - MetricsPort *int `url:"metrics_port,omitempty" json:"metrics_port,omitempty"` - MetricsSampleInterval *int `url:"metrics_sample_interval,omitempty" json:"metrics_sample_interval,omitempty"` - MetricsTimeout *int `url:"metrics_timeout,omitempty" json:"metrics_timeout,omitempty"` - MirrorAvailable *bool `url:"mirror_available,omitempty" json:"mirror_available,omitempty"` - MirrorCapacityThreshold *int `url:"mirror_capacity_threshold,omitempty" json:"mirror_capacity_threshold,omitempty"` - MirrorMaxCapacity *int `url:"mirror_max_capacity,omitempty" json:"mirror_max_capacity,omitempty"` - MirrorMaxDelay *int `url:"mirror_max_delay,omitempty" json:"mirror_max_delay,omitempty"` - OutboundLocalRequestsWhitelist []string `url:"outbound_local_requests_whitelist,omitempty" json:"outbound_local_requests_whitelist,omitempty"` - PagesDomainVerificationEnabled *bool `url:"pages_domain_verification_enabled,omitempty" json:"pages_domain_verification_enabled,omitempty"` - PasswordAuthenticationEnabledForGit *bool `url:"password_authentication_enabled_for_git,omitempty" json:"password_authentication_enabled_for_git,omitempty"` - PasswordAuthenticationEnabledForWeb *bool `url:"password_authentication_enabled_for_web,omitempty" json:"password_authentication_enabled_for_web,omitempty"` - PerformanceBarAllowedGroupID *string `url:"performance_bar_allowed_group_id,omitempty" json:"performance_bar_allowed_group_id,omitempty"` - PerformanceBarAllowedGroupPath *string `url:"performance_bar_allowed_group_path,omitempty" json:"performance_bar_allowed_group_path,omitempty"` - PerformanceBarEnabled *bool `url:"performance_bar_enabled,omitempty" json:"performance_bar_enabled,omitempty"` - PlantumlEnabled *bool `url:"plantuml_enabled,omitempty" json:"plantuml_enabled,omitempty"` - PlantumlURL *string `url:"plantuml_url,omitempty" json:"plantuml_url,omitempty"` - PollingIntervalMultiplier *float64 `url:"polling_interval_multiplier,omitempty" json:"polling_interval_multiplier,omitempty"` - ProjectExportEnabled *bool `url:"project_export_enabled,omitempty" json:"project_export_enabled,omitempty"` - PrometheusMetricsEnabled *bool `url:"prometheus_metrics_enabled,omitempty" json:"prometheus_metrics_enabled,omitempty"` - ProtectedCIVariables *bool `url:"protected_ci_variables,omitempty" json:"protected_ci_variables,omitempty"` - PseudonymizerEnabled *bool `url:"psedonymizer_enabled,omitempty" json:"psedonymizer_enabled,omitempty"` - PushEventHooksLimit *int `url:"push_event_hooks_limit,omitempty" json:"push_event_hooks_limit,omitempty"` - PushEventActivitiesLimit *int `url:"push_event_activities_limit,omitempty" json:"push_event_activities_limit,omitempty"` - RecaptchaEnabled *bool `url:"recaptcha_enabled,omitempty" json:"recaptcha_enabled,omitempty"` - RecaptchaPrivateKey *string `url:"recaptcha_private_key,omitempty" json:"recaptcha_private_key,omitempty"` - RecaptchaSiteKey *string `url:"recaptcha_site_key,omitempty" json:"recaptcha_site_key,omitempty"` - ReceiveMaxInputSize *int `url:"receive_max_input_size,omitempty" json:"receive_max_input_size,omitempty"` - RepositoryChecksEnabled *bool `url:"repository_checks_enabled,omitempty" json:"repository_checks_enabled,omitempty"` - RepositorySizeLimit *int `url:"repository_size_limit,omitempty" json:"repository_size_limit,omitempty"` - RepositoryStorages []string `url:"repository_storages,omitempty" json:"repository_storages,omitempty"` - RequireTwoFactorAuthentication *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"` - RestrictedVisibilityLevels []VisibilityValue `url:"restricted_visibility_levels,omitempty" json:"restricted_visibility_levels,omitempty"` - RsaKeyRestriction *int `url:"rsa_key_restriction,omitempty" json:"rsa_key_restriction,omitempty"` - SendUserConfirmationEmail *bool `url:"send_user_confirmation_email,omitempty" json:"send_user_confirmation_email,omitempty"` - SessionExpireDelay *int `url:"session_expire_delay,omitempty" json:"session_expire_delay,omitempty"` - SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` - SharedRunnersMinutes *int `url:"shared_runners_minutes,omitempty" json:"shared_runners_minutes,omitempty"` - SharedRunnersText *string `url:"shared_runners_text,omitempty" json:"shared_runners_text,omitempty"` - SignInText *string `url:"sign_in_text,omitempty" json:"sign_in_text,omitempty"` - SignupEnabled *bool `url:"signup_enabled,omitempty" json:"signup_enabled,omitempty"` - SlackAppEnabled *bool `url:"slack_app_enabled,omitempty" json:"slack_app_enabled,omitempty"` - SlackAppID *string `url:"slack_app_id,omitempty" json:"slack_app_id,omitempty"` - SlackAppSecret *string `url:"slack_app_secret,omitempty" json:"slack_app_secret,omitempty"` - SlackAppVerificationToken *string `url:"slack_app_verification_token,omitempty" json:"slack_app_verification_token,omitempty"` - SnowplowCollectorHostname *string `url:"snowplow_collector_hostname,omitempty" json:"snowplow_collector_hostname,omitempty"` - SnowplowCookieDomain *string `url:"snowplow_cookie_domain,omitempty" json:"snowplow_cookie_domain,omitempty"` - SnowplowEnabled *bool `url:"snowplow_enabled,omitempty" json:"snowplow_enabled,omitempty"` - SnowplowSiteID *string `url:"snowplow_site_id,omitempty" json:"snowplow_site_id,omitempty"` - TerminalMaxSessionTime *int `url:"terminal_max_session_time,omitempty" json:"terminal_max_session_time,omitempty"` - Terms *string `url:"terms,omitempty" json:"terms,omitempty"` - ThrottleAuthenticatedAPIEnabled *bool `url:"throttle_authenticated_api_enabled,omitempty" json:"throttle_authenticated_api_enabled,omitempty"` - ThrottleAuthenticatedAPIPeriodInSeconds *int `url:"throttle_authenticated_api_period_in_seconds,omitempty" json:"throttle_authenticated_api_period_in_seconds,omitempty"` - ThrottleAuthenticatedAPIRequestsPerPeriod *int `url:"throttle_authenticated_api_requests_per_period,omitempty" json:"throttle_authenticated_api_requests_per_period,omitempty"` - ThrottleAuthenticatedWebEnabled *bool `url:"throttle_authenticated_web_enabled,omitempty" json:"throttle_authenticated_web_enabled,omitempty"` - ThrottleAuthenticatedWebPeriodInSeconds *int `url:"throttle_authenticated_web_period_in_seconds,omitempty" json:"throttle_authenticated_web_period_in_seconds,omitempty"` - ThrottleAuthenticatedWebRequestsPerPeriod *int `url:"throttle_authenticated_web_requests_per_period,omitempty" json:"throttle_authenticated_web_requests_per_period,omitempty"` - ThrottleUnauthenticatedEnabled *bool `url:"throttle_unauthenticated_enabled,omitempty" json:"throttle_unauthenticated_enabled,omitempty"` - ThrottleUnauthenticatedPeriodInSeconds *int `url:"throttle_unauthenticated_period_in_seconds,omitempty" json:"throttle_unauthenticated_period_in_seconds,omitempty"` - ThrottleUnauthenticatedRequestsPerPeriod *int `url:"throttle_unauthenticated_requests_per_period,omitempty" json:"throttle_unauthenticated_requests_per_period,omitempty"` - TimeTrackingLimitToHours *bool `url:"time_tracking_limit_to_hours,omitempty" json:"time_tracking_limit_to_hours,omitempty"` - TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"` - UniqueIPsLimitEnabled *bool `url:"unique_ips_limit_enabled,omitempty" json:"unique_ips_limit_enabled,omitempty"` - UniqueIPsLimitPerUser *int `url:"unique_ips_limit_per_user,omitempty" json:"unique_ips_limit_per_user,omitempty"` - UniqueIPsLimitTimeWindow *int `url:"unique_ips_limit_time_window,omitempty" json:"unique_ips_limit_time_window,omitempty"` - UsagePingEnabled *bool `url:"usage_ping_enabled,omitempty" json:"usage_ping_enabled,omitempty"` - UserDefaultExternal *bool `url:"user_default_external,omitempty" json:"user_default_external,omitempty"` - UserDefaultInternalRegex *string `url:"user_default_internal_regex,omitempty" json:"user_default_internal_regex,omitempty"` - UserOauthApplications *bool `url:"user_oauth_applications,omitempty" json:"user_oauth_applications,omitempty"` - UserShowAddSSHKeyMessage *bool `url:"user_show_add_ssh_key_message,omitempty" json:"user_show_add_ssh_key_message,omitempty"` - VersionCheckEnabled *bool `url:"version_check_enabled,omitempty" json:"version_check_enabled,omitempty"` - WebIDEClientsidePreviewEnabled *bool `url:"web_ide_clientside_preview_enabled,omitempty" json:"web_ide_clientside_preview_enabled,omitempty"` -} - -// UpdateSettings updates the application settings. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/settings.html#change-application.settings -func (s *SettingsService) UpdateSettings(opt *UpdateSettingsOptions, options ...RequestOptionFunc) (*Settings, *Response, error) { - req, err := s.client.NewRequest("PUT", "application/settings", opt, options) - if err != nil { - return nil, nil, err - } - - as := new(Settings) - resp, err := s.client.Do(req, as) - if err != nil { - return nil, resp, err - } - - return as, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/snippets.go b/vendor/github.com/xanzy/go-gitlab/snippets.go deleted file mode 100644 index a8025de48..000000000 --- a/vendor/github.com/xanzy/go-gitlab/snippets.go +++ /dev/null @@ -1,230 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "bytes" - "fmt" - "time" -) - -// SnippetsService handles communication with the snippets -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/snippets.html -type SnippetsService struct { - client *Client -} - -// Snippet represents a GitLab snippet. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/snippets.html -type Snippet struct { - ID int `json:"id"` - Title string `json:"title"` - FileName string `json:"file_name"` - Description string `json:"description"` - Author struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - } `json:"author"` - UpdatedAt *time.Time `json:"updated_at"` - CreatedAt *time.Time `json:"created_at"` - WebURL string `json:"web_url"` - RawURL string `json:"raw_url"` -} - -func (s Snippet) String() string { - return Stringify(s) -} - -// ListSnippetsOptions represents the available ListSnippets() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/snippets.html#list-snippets -type ListSnippetsOptions ListOptions - -// ListSnippets gets a list of snippets. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/snippets.html#list-snippets -func (s *SnippetsService) ListSnippets(opt *ListSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { - req, err := s.client.NewRequest("GET", "snippets", opt, options) - if err != nil { - return nil, nil, err - } - - var ps []*Snippet - resp, err := s.client.Do(req, &ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// GetSnippet gets a single snippet -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#single-snippet -func (s *SnippetsService) GetSnippet(snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) { - u := fmt.Sprintf("snippets/%d", snippet) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// CreateSnippetOptions represents the available CreateSnippet() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#create-new-snippet -type CreateSnippetOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` -} - -// CreateSnippet creates a new snippet. The user must have permission -// to create new snippets. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#create-new-snippet -func (s *SnippetsService) CreateSnippet(opt *CreateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { - req, err := s.client.NewRequest("POST", "snippets", opt, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// UpdateSnippetOptions represents the available UpdateSnippet() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#update-snippet -type UpdateSnippetOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` - Description *string `url:"description,omitempty" json:"description,omitempty"` - Content *string `url:"content,omitempty" json:"content,omitempty"` - Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` -} - -// UpdateSnippet updates an existing snippet. The user must have -// permission to change an existing snippet. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#update-snippet -func (s *SnippetsService) UpdateSnippet(snippet int, opt *UpdateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { - u := fmt.Sprintf("snippets/%d", snippet) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - ps := new(Snippet) - resp, err := s.client.Do(req, ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} - -// DeleteSnippet deletes an existing snippet. This is an idempotent -// function and deleting a non-existent snippet still returns a 200 OK status -// code. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#delete-snippet -func (s *SnippetsService) DeleteSnippet(snippet int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("snippets/%d", snippet) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// SnippetContent returns the raw snippet as plain text. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#snippet-content -func (s *SnippetsService) SnippetContent(snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) { - u := fmt.Sprintf("snippets/%d/raw", snippet) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var b bytes.Buffer - resp, err := s.client.Do(req, &b) - if err != nil { - return nil, resp, err - } - - return b.Bytes(), resp, err -} - -// ExploreSnippetsOptions represents the available ExploreSnippets() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#explore-all-public-snippets -type ExploreSnippetsOptions ListOptions - -// ExploreSnippets gets the list of public snippets. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/snippets.html#explore-all-public-snippets -func (s *SnippetsService) ExploreSnippets(opt *ExploreSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { - req, err := s.client.NewRequest("GET", "snippets/public", nil, options) - if err != nil { - return nil, nil, err - } - - var ps []*Snippet - resp, err := s.client.Do(req, &ps) - if err != nil { - return nil, resp, err - } - - return ps, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/tags.go b/vendor/github.com/xanzy/go-gitlab/tags.go deleted file mode 100644 index 32fdeb4af..000000000 --- a/vendor/github.com/xanzy/go-gitlab/tags.go +++ /dev/null @@ -1,244 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "fmt" - "net/url" -) - -// TagsService handles communication with the tags related methods -// of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html -type TagsService struct { - client *Client -} - -// Tag represents a GitLab tag. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html -type Tag struct { - Commit *Commit `json:"commit"` - Release *ReleaseNote `json:"release"` - Name string `json:"name"` - Message string `json:"message"` -} - -// ReleaseNote represents a GitLab version release. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html -type ReleaseNote struct { - TagName string `json:"tag_name"` - Description string `json:"description"` -} - -func (t Tag) String() string { - return Stringify(t) -} - -// ListTagsOptions represents the available ListTags() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#list-project-repository-tags -type ListTagsOptions struct { - ListOptions - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Search *string `url:"search,omitempty" json:"search,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` -} - -// ListTags gets a list of tags from a project, sorted by name in reverse -// alphabetical order. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#list-project-repository-tags -func (s *TagsService) ListTags(pid interface{}, opt *ListTagsOptions, options ...RequestOptionFunc) ([]*Tag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var t []*Tag - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// GetTag a specific repository tag determined by its name. It returns 200 together -// with the tag information if the tag exists. It returns 404 if the tag does not exist. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#get-a-single-repository-tag -func (s *TagsService) GetTag(pid interface{}, tag string, options ...RequestOptionFunc) (*Tag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags/%s", pathEscape(project), url.PathEscape(tag)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var t *Tag - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// CreateTagOptions represents the available CreateTag() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag -type CreateTagOptions struct { - TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"` - Ref *string `url:"ref,omitempty" json:"ref,omitempty"` - Message *string `url:"message,omitempty" json:"message,omitempty"` - // ReleaseDescription parameter was deprecated in GitLab 11.7 - ReleaseDescription *string `url:"release_description:omitempty" json:"release_description,omitempty"` -} - -// CreateTag creates a new tag in the repository that points to the supplied ref. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag -func (s *TagsService) CreateTag(pid interface{}, opt *CreateTagOptions, options ...RequestOptionFunc) (*Tag, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(Tag) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// DeleteTag deletes a tag of a repository with given name. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#delete-a-tag -func (s *TagsService) DeleteTag(pid interface{}, tag string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags/%s", pathEscape(project), url.PathEscape(tag)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// CreateReleaseNoteOptions represents the available CreateReleaseNote() options. -// -// Deprecated: This feature was deprecated in GitLab 11.7. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#create-a-new-release -type CreateReleaseNoteOptions struct { - Description *string `url:"description:omitempty" json:"description,omitempty"` -} - -// CreateReleaseNote Add release notes to the existing git tag. -// If there already exists a release for the given tag, status code 409 is returned. -// -// Deprecated: This feature was deprecated in GitLab 11.7. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#create-a-new-release -func (s *TagsService) CreateReleaseNote(pid interface{}, tag string, opt *CreateReleaseNoteOptions, options ...RequestOptionFunc) (*ReleaseNote, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags/%s/release", pathEscape(project), url.PathEscape(tag)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - r := new(ReleaseNote) - resp, err := s.client.Do(req, r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} - -// UpdateReleaseNoteOptions represents the available UpdateReleaseNote() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#update-a-release -type UpdateReleaseNoteOptions struct { - Description *string `url:"description:omitempty" json:"description,omitempty"` -} - -// UpdateReleaseNote Updates the release notes of a given release. -// -// Deprecated: This feature was deprecated in GitLab 11.7. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/tags.html#update-a-release -func (s *TagsService) UpdateReleaseNote(pid interface{}, tag string, opt *UpdateReleaseNoteOptions, options ...RequestOptionFunc) (*ReleaseNote, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/repository/tags/%s/release", pathEscape(project), url.PathEscape(tag)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - r := new(ReleaseNote) - resp, err := s.client.Do(req, r) - if err != nil { - return nil, resp, err - } - - return r, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/time_stats.go b/vendor/github.com/xanzy/go-gitlab/time_stats.go deleted file mode 100644 index dd1f550a4..000000000 --- a/vendor/github.com/xanzy/go-gitlab/time_stats.go +++ /dev/null @@ -1,162 +0,0 @@ -package gitlab - -import ( - "fmt" -) - -// timeStatsService handles communication with the time tracking related -// methods of the GitLab API. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -type timeStatsService struct { - client *Client -} - -// TimeStats represents the time estimates and time spent for an issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -type TimeStats struct { - HumanTimeEstimate string `json:"human_time_estimate"` - HumanTotalTimeSpent string `json:"human_total_time_spent"` - TimeEstimate int `json:"time_estimate"` - TotalTimeSpent int `json:"total_time_spent"` -} - -func (t TimeStats) String() string { - return Stringify(t) -} - -// SetTimeEstimateOptions represents the available SetTimeEstimate() -// options. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -type SetTimeEstimateOptions struct { - Duration *string `url:"duration,omitempty" json:"duration,omitempty"` -} - -// setTimeEstimate sets the time estimate for a single project issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -func (s *timeStatsService) setTimeEstimate(pid interface{}, entity string, issue int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/time_estimate", pathEscape(project), entity, issue) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(TimeStats) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// resetTimeEstimate resets the time estimate for a single project issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -func (s *timeStatsService) resetTimeEstimate(pid interface{}, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/reset_time_estimate", pathEscape(project), entity, issue) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - t := new(TimeStats) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// AddSpentTimeOptions represents the available AddSpentTime() options. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -type AddSpentTimeOptions struct { - Duration *string `url:"duration,omitempty" json:"duration,omitempty"` -} - -// addSpentTime adds spent time for a single project issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -func (s *timeStatsService) addSpentTime(pid interface{}, entity string, issue int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/add_spent_time", pathEscape(project), entity, issue) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(TimeStats) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// resetSpentTime resets the spent time for a single project issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -func (s *timeStatsService) resetSpentTime(pid interface{}, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/reset_spent_time", pathEscape(project), entity, issue) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, nil, err - } - - t := new(TimeStats) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// getTimeSpent gets the spent time for a single project issue. -// -// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html -func (s *timeStatsService) getTimeSpent(pid interface{}, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/%s/%d/time_stats", pathEscape(project), entity, issue) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - t := new(TimeStats) - resp, err := s.client.Do(req, t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/todos.go b/vendor/github.com/xanzy/go-gitlab/todos.go deleted file mode 100644 index dc8ebb0fe..000000000 --- a/vendor/github.com/xanzy/go-gitlab/todos.go +++ /dev/null @@ -1,176 +0,0 @@ -package gitlab - -import "time" -import "fmt" - -// TodosService handles communication with the todos related methods of -// the Gitlab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html -type TodosService struct { - client *Client -} - -// TodoAction represents the available actions that can be performed on a todo. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html -type TodoAction string - -// The available todo actions. -const ( - TodoAssigned TodoAction = "assigned" - TodoMentioned TodoAction = "mentioned" - TodoBuildFailed TodoAction = "build_failed" - TodoMarked TodoAction = "marked" - TodoApprovalRequired TodoAction = "approval_required" - TodoDirectlyAddressed TodoAction = "directly_addressed" -) - -// TodoTarget represents a todo target of type Issue or MergeRequest -type TodoTarget struct { - // TODO: replace both Assignee and Author structs with v4 User struct - Assignee struct { - Name string `json:"name"` - Username string `json:"username"` - ID int `json:"id"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"assignee"` - Author struct { - Name string `json:"name"` - Username string `json:"username"` - ID int `json:"id"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"author"` - CreatedAt *time.Time `json:"created_at"` - Description string `json:"description"` - Downvotes int `json:"downvotes"` - ID int `json:"id"` - IID int `json:"iid"` - Labels []string `json:"labels"` - Milestone Milestone `json:"milestone"` - ProjectID int `json:"project_id"` - State string `json:"state"` - Subscribed bool `json:"subscribed"` - Title string `json:"title"` - UpdatedAt *time.Time `json:"updated_at"` - Upvotes int `json:"upvotes"` - UserNotesCount int `json:"user_notes_count"` - WebURL string `json:"web_url"` - - // Only available for type Issue - Confidential bool `json:"confidential"` - DueDate string `json:"due_date"` - Weight int `json:"weight"` - - // Only available for type MergeRequest - ApprovalsBeforeMerge int `json:"approvals_before_merge"` - ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` - MergeCommitSHA string `json:"merge_commit_sha"` - MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` - MergeStatus string `json:"merge_status"` - SHA string `json:"sha"` - ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int `json:"source_project_id"` - Squash bool `json:"squash"` - TargetBranch string `json:"target_branch"` - TargetProjectID int `json:"target_project_id"` - WorkInProgress bool `json:"work_in_progress"` -} - -// Todo represents a GitLab todo. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html -type Todo struct { - ID int `json:"id"` - Project struct { - ID int `json:"id"` - HTTPURLToRepo string `json:"http_url_to_repo"` - WebURL string `json:"web_url"` - Name string `json:"name"` - NameWithNamespace string `json:"name_with_namespace"` - Path string `json:"path"` - PathWithNamespace string `json:"path_with_namespace"` - } `json:"project"` - Author struct { - ID int `json:"id"` - Name string `json:"name"` - Username string `json:"username"` - State string `json:"state"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` - } `json:"author"` - ActionName TodoAction `json:"action_name"` - TargetType string `json:"target_type"` - Target TodoTarget `json:"target"` - TargetURL string `json:"target_url"` - Body string `json:"body"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` -} - -func (t Todo) String() string { - return Stringify(t) -} - -// ListTodosOptions represents the available ListTodos() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html#get-a-list-of-todos -type ListTodosOptions struct { - ListOptions - Action *TodoAction `url:"action,omitempty" json:"action,omitempty"` - AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` - ProjectID *int `url:"project_id,omitempty" json:"project_id,omitempty"` - State *string `url:"state,omitempty" json:"state,omitempty"` - Type *string `url:"type,omitempty" json:"type,omitempty"` -} - -// ListTodos lists all todos created by authenticated user. -// When no filter is applied, it returns all pending todos for the current user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/todos.html#get-a-list-of-todos -func (s *TodosService) ListTodos(opt *ListTodosOptions, options ...RequestOptionFunc) ([]*Todo, *Response, error) { - req, err := s.client.NewRequest("GET", "todos", opt, options) - if err != nil { - return nil, nil, err - } - - var t []*Todo - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// MarkTodoAsDone marks a single pending todo given by its ID for the current user as done. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html#mark-a-todo-as-done -func (s *TodosService) MarkTodoAsDone(id int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("todos/%d/mark_as_done", id) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// MarkAllTodosAsDone marks all pending todos for the current user as done. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/todos.html#mark-all-todos-as-done -func (s *TodosService) MarkAllTodosAsDone(options ...RequestOptionFunc) (*Response, error) { - req, err := s.client.NewRequest("POST", "todos/mark_as_done", nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/types.go b/vendor/github.com/xanzy/go-gitlab/types.go deleted file mode 100644 index 2a7de69e5..000000000 --- a/vendor/github.com/xanzy/go-gitlab/types.go +++ /dev/null @@ -1,444 +0,0 @@ -package gitlab - -import ( - "encoding/json" - "errors" - "fmt" - "net/url" - "time" -) - -// AccessControlValue represents an access control value within GitLab, -// used for managing access to certain project features. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html -type AccessControlValue string - -// List of available access control values. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html -const ( - DisabledAccessControl AccessControlValue = "disabled" - EnabledAccessControl AccessControlValue = "enabled" - PrivateAccessControl AccessControlValue = "private" - PublicAccessControl AccessControlValue = "public" -) - -// AccessControl is a helper routine that allocates a new AccessControlValue -// to store v and returns a pointer to it. -func AccessControl(v AccessControlValue) *AccessControlValue { - p := new(AccessControlValue) - *p = v - return p -} - -// AccessLevelValue represents a permission level within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html -type AccessLevelValue int - -// List of available access levels -// -// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html -const ( - NoPermissions AccessLevelValue = 0 - MinimalAccessPermissions AccessLevelValue = 5 - GuestPermissions AccessLevelValue = 10 - ReporterPermissions AccessLevelValue = 20 - DeveloperPermissions AccessLevelValue = 30 - MaintainerPermissions AccessLevelValue = 40 - OwnerPermissions AccessLevelValue = 50 - - // These are deprecated and should be removed in a future version - MasterPermissions AccessLevelValue = 40 - OwnerPermission AccessLevelValue = 50 -) - -// AccessLevel is a helper routine that allocates a new AccessLevelValue -// to store v and returns a pointer to it. -func AccessLevel(v AccessLevelValue) *AccessLevelValue { - p := new(AccessLevelValue) - *p = v - return p -} - -// BuildStateValue represents a GitLab build state. -type BuildStateValue string - -// These constants represent all valid build states. -const ( - Pending BuildStateValue = "pending" - Created BuildStateValue = "created" - Running BuildStateValue = "running" - Success BuildStateValue = "success" - Failed BuildStateValue = "failed" - Canceled BuildStateValue = "canceled" - Skipped BuildStateValue = "skipped" - Manual BuildStateValue = "manual" -) - -// BuildState is a helper routine that allocates a new BuildStateValue -// to store v and returns a pointer to it. -func BuildState(v BuildStateValue) *BuildStateValue { - p := new(BuildStateValue) - *p = v - return p -} - -// DeploymentStatusValue represents a Gitlab deployment status. -type DeploymentStatusValue string - -// These constants represent all valid deployment statuses. -const ( - DeploymentStatusCreated DeploymentStatusValue = "created" - DeploymentStatusRunning DeploymentStatusValue = "running" - DeploymentStatusSuccess DeploymentStatusValue = "success" - DeploymentStatusFailed DeploymentStatusValue = "failed" - DeploymentStatusCanceled DeploymentStatusValue = "canceled" -) - -// DeploymentStatus is a helper routine that allocates a new -// DeploymentStatusValue to store v and returns a pointer to it. -func DeploymentStatus(v DeploymentStatusValue) *DeploymentStatusValue { - p := new(DeploymentStatusValue) - *p = v - return p -} - -// FileAction represents the available actions that can be performed on a file. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions -type FileAction string - -// The available file actions. -const ( - FileCreate FileAction = "create" - FileDelete FileAction = "delete" - FileMove FileAction = "move" - FileUpdate FileAction = "update" -) - -// ISOTime represents an ISO 8601 formatted date -type ISOTime time.Time - -// ISO 8601 date format -const iso8601 = "2006-01-02" - -// MarshalJSON implements the json.Marshaler interface -func (t ISOTime) MarshalJSON() ([]byte, error) { - if y := time.Time(t).Year(); y < 0 || y >= 10000 { - // ISO 8901 uses 4 digits for the years - return nil, errors.New("json: ISOTime year outside of range [0,9999]") - } - - b := make([]byte, 0, len(iso8601)+2) - b = append(b, '"') - b = time.Time(t).AppendFormat(b, iso8601) - b = append(b, '"') - - return b, nil -} - -// UnmarshalJSON implements the json.Unmarshaler interface -func (t *ISOTime) UnmarshalJSON(data []byte) error { - // Ignore null, like in the main JSON package - if string(data) == "null" { - return nil - } - - isotime, err := time.Parse(`"`+iso8601+`"`, string(data)) - *t = ISOTime(isotime) - - return err -} - -// EncodeValues implements the query.Encoder interface -func (t *ISOTime) EncodeValues(key string, v *url.Values) error { - if t == nil || (time.Time(*t)).IsZero() { - return nil - } - v.Add(key, t.String()) - return nil -} - -// String implements the Stringer interface -func (t ISOTime) String() string { - return time.Time(t).Format(iso8601) -} - -// NotificationLevelValue represents a notification level. -type NotificationLevelValue int - -// String implements the fmt.Stringer interface. -func (l NotificationLevelValue) String() string { - return notificationLevelNames[l] -} - -// MarshalJSON implements the json.Marshaler interface. -func (l NotificationLevelValue) MarshalJSON() ([]byte, error) { - return json.Marshal(l.String()) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (l *NotificationLevelValue) UnmarshalJSON(data []byte) error { - var raw interface{} - if err := json.Unmarshal(data, &raw); err != nil { - return err - } - - switch raw := raw.(type) { - case float64: - *l = NotificationLevelValue(raw) - case string: - *l = notificationLevelTypes[raw] - case nil: - // No action needed. - default: - return fmt.Errorf("json: cannot unmarshal %T into Go value of type %T", raw, *l) - } - - return nil -} - -// List of valid notification levels. -const ( - DisabledNotificationLevel NotificationLevelValue = iota - ParticipatingNotificationLevel - WatchNotificationLevel - GlobalNotificationLevel - MentionNotificationLevel - CustomNotificationLevel -) - -var notificationLevelNames = [...]string{ - "disabled", - "participating", - "watch", - "global", - "mention", - "custom", -} - -var notificationLevelTypes = map[string]NotificationLevelValue{ - "disabled": DisabledNotificationLevel, - "participating": ParticipatingNotificationLevel, - "watch": WatchNotificationLevel, - "global": GlobalNotificationLevel, - "mention": MentionNotificationLevel, - "custom": CustomNotificationLevel, -} - -// NotificationLevel is a helper routine that allocates a new NotificationLevelValue -// to store v and returns a pointer to it. -func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue { - p := new(NotificationLevelValue) - *p = v - return p -} - -// VisibilityValue represents a visibility level within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -type VisibilityValue string - -// List of available visibility levels. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -const ( - PrivateVisibility VisibilityValue = "private" - InternalVisibility VisibilityValue = "internal" - PublicVisibility VisibilityValue = "public" -) - -// Visibility is a helper routine that allocates a new VisibilityValue -// to store v and returns a pointer to it. -func Visibility(v VisibilityValue) *VisibilityValue { - p := new(VisibilityValue) - *p = v - return p -} - -// ProjectCreationLevelValue represents a project creation level within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -type ProjectCreationLevelValue string - -// List of available project creation levels. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -const ( - NoOneProjectCreation ProjectCreationLevelValue = "noone" - MaintainerProjectCreation ProjectCreationLevelValue = "maintainer" - DeveloperProjectCreation ProjectCreationLevelValue = "developer" -) - -// ProjectCreationLevel is a helper routine that allocates a new ProjectCreationLevelValue -// to store v and returns a pointer to it. -func ProjectCreationLevel(v ProjectCreationLevelValue) *ProjectCreationLevelValue { - p := new(ProjectCreationLevelValue) - *p = v - return p -} - -// SubGroupCreationLevelValue represents a sub group creation level within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -type SubGroupCreationLevelValue string - -// List of available sub group creation levels. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -const ( - OwnerSubGroupCreationLevelValue SubGroupCreationLevelValue = "owner" - MaintainerSubGroupCreationLevelValue SubGroupCreationLevelValue = "maintainer" -) - -// SubGroupCreationLevel is a helper routine that allocates a new SubGroupCreationLevelValue -// to store v and returns a pointer to it. -func SubGroupCreationLevel(v SubGroupCreationLevelValue) *SubGroupCreationLevelValue { - p := new(SubGroupCreationLevelValue) - *p = v - return p -} - -// VariableTypeValue represents a variable type within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -type VariableTypeValue string - -// List of available variable types. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/ -const ( - EnvVariableType VariableTypeValue = "env_var" - FileVariableType VariableTypeValue = "file" -) - -// VariableType is a helper routine that allocates a new VariableTypeValue -// to store v and returns a pointer to it. -func VariableType(v VariableTypeValue) *VariableTypeValue { - p := new(VariableTypeValue) - *p = v - return p -} - -// MergeMethodValue represents a project merge type within GitLab. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#project-merge-method -type MergeMethodValue string - -// List of available merge type -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#project-merge-method -const ( - NoFastForwardMerge MergeMethodValue = "merge" - FastForwardMerge MergeMethodValue = "ff" - RebaseMerge MergeMethodValue = "rebase_merge" -) - -// MergeMethod is a helper routine that allocates a new MergeMethod -// to sotre v and returns a pointer to it. -func MergeMethod(v MergeMethodValue) *MergeMethodValue { - p := new(MergeMethodValue) - *p = v - return p -} - -// EventTypeValue represents actions type for contribution events -type EventTypeValue string - -// List of available action type -// -// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#action-types -const ( - CreatedEventType EventTypeValue = "created" - UpdatedEventType EventTypeValue = "updated" - ClosedEventType EventTypeValue = "closed" - ReopenedEventType EventTypeValue = "reopened" - PushedEventType EventTypeValue = "pushed" - CommentedEventType EventTypeValue = "commented" - MergedEventType EventTypeValue = "merged" - JoinedEventType EventTypeValue = "joined" - LeftEventType EventTypeValue = "left" - DestroyedEventType EventTypeValue = "destroyed" - ExpiredEventType EventTypeValue = "expired" -) - -// EventTargetTypeValue represents actions type value for contribution events -type EventTargetTypeValue string - -// List of available action type -// -// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#target-types -const ( - IssueEventTargetType EventTargetTypeValue = "issue" - MilestoneEventTargetType EventTargetTypeValue = "milestone" - MergeRequestEventTargetType EventTargetTypeValue = "merge_request" - NoteEventTargetType EventTargetTypeValue = "note" - ProjectEventTargetType EventTargetTypeValue = "project" - SnippetEventTargetType EventTargetTypeValue = "snippet" - UserEventTargetType EventTargetTypeValue = "user" -) - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - p := new(bool) - *p = v - return p -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int { - p := new(int) - *p = v - return p -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - p := new(string) - *p = v - return p -} - -// Time is a helper routine that allocates a new time.Time value -// to store v and returns a pointer to it. -func Time(v time.Time) *time.Time { - p := new(time.Time) - *p = v - return p -} - -// BoolValue is a boolean value with advanced json unmarshaling features. -type BoolValue bool - -// UnmarshalJSON allows 1, 0, "true", and "false" to be considered as boolean values -// Needed for: -// https://gitlab.com/gitlab-org/gitlab-ce/issues/50122 -// https://gitlab.com/gitlab-org/gitlab/-/issues/233941 -// https://github.com/gitlabhq/terraform-provider-gitlab/issues/348 -func (t *BoolValue) UnmarshalJSON(b []byte) error { - switch string(b) { - case `"1"`: - *t = true - return nil - case `"0"`: - *t = false - return nil - case `"true"`: - *t = true - return nil - case `"false"`: - *t = false - return nil - default: - var v bool - err := json.Unmarshal(b, &v) - *t = BoolValue(v) - return err - } -} diff --git a/vendor/github.com/xanzy/go-gitlab/users.go b/vendor/github.com/xanzy/go-gitlab/users.go deleted file mode 100644 index 2dbed926c..000000000 --- a/vendor/github.com/xanzy/go-gitlab/users.go +++ /dev/null @@ -1,974 +0,0 @@ -// -// Copyright 2017, Sander van Harmelen -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package gitlab - -import ( - "errors" - "fmt" - "time" -) - -// List a couple of standard errors. -var ( - ErrUserActivatePrevented = errors.New("Cannot activate a user that is blocked by admin or by LDAP synchronization") - ErrUserBlockPrevented = errors.New("Cannot block a user that is already blocked by LDAP synchronization") - ErrUserDeactivatePrevented = errors.New("Cannot deactivate a user that is blocked by admin or by LDAP synchronization, or that has any activity in past 180 days") - ErrUserNotFound = errors.New("User does not exist") - ErrUserUnblockPrevented = errors.New("Cannot unblock a user that is blocked by LDAP synchronization") -) - -// UsersService handles communication with the user related methods of -// the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html -type UsersService struct { - client *Client -} - -// BasicUser included in other service responses (such as merge requests, pipelines, etc). -type BasicUser struct { - ID int `json:"id"` - Username string `json:"username"` - Name string `json:"name"` - State string `json:"state"` - CreatedAt *time.Time `json:"created_at"` - AvatarURL string `json:"avatar_url"` - WebURL string `json:"web_url"` -} - -// User represents a GitLab user. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/users.html -type User struct { - ID int `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - Name string `json:"name"` - State string `json:"state"` - WebURL string `json:"web_url"` - CreatedAt *time.Time `json:"created_at"` - Bio string `json:"bio"` - Location string `json:"location"` - PublicEmail string `json:"public_email"` - Skype string `json:"skype"` - Linkedin string `json:"linkedin"` - Twitter string `json:"twitter"` - WebsiteURL string `json:"website_url"` - Organization string `json:"organization"` - ExternUID string `json:"extern_uid"` - Provider string `json:"provider"` - ThemeID int `json:"theme_id"` - LastActivityOn *ISOTime `json:"last_activity_on"` - ColorSchemeID int `json:"color_scheme_id"` - IsAdmin bool `json:"is_admin"` - AvatarURL string `json:"avatar_url"` - CanCreateGroup bool `json:"can_create_group"` - CanCreateProject bool `json:"can_create_project"` - ProjectsLimit int `json:"projects_limit"` - CurrentSignInAt *time.Time `json:"current_sign_in_at"` - LastSignInAt *time.Time `json:"last_sign_in_at"` - ConfirmedAt *time.Time `json:"confirmed_at"` - TwoFactorEnabled bool `json:"two_factor_enabled"` - Identities []*UserIdentity `json:"identities"` - External bool `json:"external"` - PrivateProfile bool `json:"private_profile"` - SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` - CustomAttributes []*CustomAttribute `json:"custom_attributes"` -} - -// UserIdentity represents a user identity. -type UserIdentity struct { - Provider string `json:"provider"` - ExternUID string `json:"extern_uid"` -} - -// ListUsersOptions represents the available ListUsers() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users -type ListUsersOptions struct { - ListOptions - Active *bool `url:"active,omitempty" json:"active,omitempty"` - Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"` - - // The options below are only available for admins. - Search *string `url:"search,omitempty" json:"search,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - ExternalUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` - CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` - CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` - OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` - Sort *string `url:"sort,omitempty" json:"sort,omitempty"` - External *bool `url:"external,omitempty" json:"external,omitempty"` - WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` -} - -// ListUsers gets a list of users. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users -func (s *UsersService) ListUsers(opt *ListUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { - req, err := s.client.NewRequest("GET", "users", opt, options) - if err != nil { - return nil, nil, err - } - - var usr []*User - resp, err := s.client.Do(req, &usr) - if err != nil { - return nil, resp, err - } - - return usr, resp, err -} - -// GetUser gets a single user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-user -func (s *UsersService) GetUser(user int, options ...RequestOptionFunc) (*User, *Response, error) { - u := fmt.Sprintf("users/%d", user) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - usr := new(User) - resp, err := s.client.Do(req, usr) - if err != nil { - return nil, resp, err - } - - return usr, resp, err -} - -// CreateUserOptions represents the available CreateUser() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation -type CreateUserOptions struct { - Email *string `url:"email,omitempty" json:"email,omitempty"` - Password *string `url:"password,omitempty" json:"password,omitempty"` - ResetPassword *bool `url:"reset_password,omitempty" json:"reset_password,omitempty"` - ForceRandomPassword *bool `url:"force_random_password,omitempty" json:"force_random_password,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Skype *string `url:"skype,omitempty" json:"skype,omitempty"` - Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` - Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` - WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` - Organization *string `url:"organization,omitempty" json:"organization,omitempty"` - ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` - ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` - Bio *string `url:"bio,omitempty" json:"bio,omitempty"` - Location *string `url:"location,omitempty" json:"location,omitempty"` - Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` - CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` - SkipConfirmation *bool `url:"skip_confirmation,omitempty" json:"skip_confirmation,omitempty"` - External *bool `url:"external,omitempty" json:"external,omitempty"` - PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` -} - -// CreateUser creates a new user. Note only administrators can create new users. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation -func (s *UsersService) CreateUser(opt *CreateUserOptions, options ...RequestOptionFunc) (*User, *Response, error) { - req, err := s.client.NewRequest("POST", "users", opt, options) - if err != nil { - return nil, nil, err - } - - usr := new(User) - resp, err := s.client.Do(req, usr) - if err != nil { - return nil, resp, err - } - - return usr, resp, err -} - -// ModifyUserOptions represents the available ModifyUser() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification -type ModifyUserOptions struct { - Email *string `url:"email,omitempty" json:"email,omitempty"` - Password *string `url:"password,omitempty" json:"password,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Skype *string `url:"skype,omitempty" json:"skype,omitempty"` - Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` - Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` - WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` - Organization *string `url:"organization,omitempty" json:"organization,omitempty"` - ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` - ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` - Bio *string `url:"bio,omitempty" json:"bio,omitempty"` - Location *string `url:"location,omitempty" json:"location,omitempty"` - Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` - CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` - SkipReconfirmation *bool `url:"skip_reconfirmation,omitempty" json:"skip_reconfirmation,omitempty"` - External *bool `url:"external,omitempty" json:"external,omitempty"` - PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` -} - -// ModifyUser modifies an existing user. Only administrators can change attributes -// of a user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification -func (s *UsersService) ModifyUser(user int, opt *ModifyUserOptions, options ...RequestOptionFunc) (*User, *Response, error) { - u := fmt.Sprintf("users/%d", user) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - usr := new(User) - resp, err := s.client.Do(req, usr) - if err != nil { - return nil, resp, err - } - - return usr, resp, err -} - -// DeleteUser deletes a user. Available only for administrators. This is an -// idempotent function, calling this function for a non-existent user id still -// returns a status code 200 OK. The JSON response differs if the user was -// actually deleted or not. In the former the user is returned and in the -// latter not. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-deletion -func (s *UsersService) DeleteUser(user int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("users/%d", user) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// CurrentUser gets currently authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#current-user -func (s *UsersService) CurrentUser(options ...RequestOptionFunc) (*User, *Response, error) { - req, err := s.client.NewRequest("GET", "user", nil, options) - if err != nil { - return nil, nil, err - } - - usr := new(User) - resp, err := s.client.Do(req, usr) - if err != nil { - return nil, resp, err - } - - return usr, resp, err -} - -// SSHKey represents a SSH key. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys -type SSHKey struct { - ID int `json:"id"` - Title string `json:"title"` - Key string `json:"key"` - CreatedAt *time.Time `json:"created_at"` -} - -// ListSSHKeys gets a list of currently authenticated user's SSH keys. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys -func (s *UsersService) ListSSHKeys(options ...RequestOptionFunc) ([]*SSHKey, *Response, error) { - req, err := s.client.NewRequest("GET", "user/keys", nil, options) - if err != nil { - return nil, nil, err - } - - var k []*SSHKey - resp, err := s.client.Do(req, &k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// ListSSHKeysForUserOptions represents the available ListSSHKeysForUser() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#list-ssh-keys-for-user -type ListSSHKeysForUserOptions ListOptions - -// ListSSHKeysForUser gets a list of a specified user's SSH keys. Available -// only for admin -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#list-ssh-keys-for-user -func (s *UsersService) ListSSHKeysForUser(user int, opt *ListSSHKeysForUserOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) { - u := fmt.Sprintf("users/%d/keys", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var k []*SSHKey - resp, err := s.client.Do(req, &k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// GetSSHKey gets a single key. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-ssh-key -func (s *UsersService) GetSSHKey(key int, options ...RequestOptionFunc) (*SSHKey, *Response, error) { - u := fmt.Sprintf("user/keys/%d", key) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - k := new(SSHKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// AddSSHKeyOptions represents the available AddSSHKey() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-ssh-key -type AddSSHKeyOptions struct { - Title *string `url:"title,omitempty" json:"title,omitempty"` - Key *string `url:"key,omitempty" json:"key,omitempty"` -} - -// AddSSHKey creates a new key owned by the currently authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key -func (s *UsersService) AddSSHKey(opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) { - req, err := s.client.NewRequest("POST", "user/keys", opt, options) - if err != nil { - return nil, nil, err - } - - k := new(SSHKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// AddSSHKeyForUser creates new key owned by specified user. Available only for -// admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key-for-user -func (s *UsersService) AddSSHKeyForUser(user int, opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) { - u := fmt.Sprintf("users/%d/keys", user) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - k := new(SSHKey) - resp, err := s.client.Do(req, k) - if err != nil { - return nil, resp, err - } - - return k, resp, err -} - -// DeleteSSHKey deletes key owned by currently authenticated user. This is an -// idempotent function and calling it on a key that is already deleted or not -// available results in 200 OK. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-current-owner -func (s *UsersService) DeleteSSHKey(key int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("user/keys/%d", key) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteSSHKeyForUser deletes key owned by a specified user. Available only -// for admin. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-given-user -func (s *UsersService) DeleteSSHKeyForUser(user, key int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("users/%d/keys/%d", user, key) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// BlockUser blocks the specified user. Available only for admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#block-user -func (s *UsersService) BlockUser(user int, options ...RequestOptionFunc) error { - u := fmt.Sprintf("users/%d/block", user) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return err - } - - resp, err := s.client.Do(req, nil) - if err != nil && resp == nil { - return err - } - - switch resp.StatusCode { - case 201: - return nil - case 403: - return ErrUserBlockPrevented - case 404: - return ErrUserNotFound - default: - return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) - } -} - -// UnblockUser unblocks the specified user. Available only for admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#unblock-user -func (s *UsersService) UnblockUser(user int, options ...RequestOptionFunc) error { - u := fmt.Sprintf("users/%d/unblock", user) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return err - } - - resp, err := s.client.Do(req, nil) - if err != nil && resp == nil { - return err - } - - switch resp.StatusCode { - case 201: - return nil - case 403: - return ErrUserUnblockPrevented - case 404: - return ErrUserNotFound - default: - return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) - } -} - -// DeactivateUser deactivate the specified user. Available only for admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#deactivate-user -func (s *UsersService) DeactivateUser(user int, options ...RequestOptionFunc) error { - u := fmt.Sprintf("users/%d/deactivate", user) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return err - } - - resp, err := s.client.Do(req, nil) - if err != nil && resp == nil { - return err - } - - switch resp.StatusCode { - case 201: - return nil - case 403: - return ErrUserDeactivatePrevented - case 404: - return ErrUserNotFound - default: - return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) - } -} - -// ActivateUser activate the specified user. Available only for admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#activate-user -func (s *UsersService) ActivateUser(user int, options ...RequestOptionFunc) error { - u := fmt.Sprintf("users/%d/activate", user) - - req, err := s.client.NewRequest("POST", u, nil, options) - if err != nil { - return err - } - - resp, err := s.client.Do(req, nil) - if err != nil && resp == nil { - return err - } - - switch resp.StatusCode { - case 201: - return nil - case 403: - return ErrUserActivatePrevented - case 404: - return ErrUserNotFound - default: - return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode) - } -} - -// Email represents an Email. -// -// GitLab API docs: https://doc.gitlab.com/ce/api/users.html#list-emails -type Email struct { - ID int `json:"id"` - Email string `json:"email"` -} - -// ListEmails gets a list of currently authenticated user's Emails. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-emails -func (s *UsersService) ListEmails(options ...RequestOptionFunc) ([]*Email, *Response, error) { - req, err := s.client.NewRequest("GET", "user/emails", nil, options) - if err != nil { - return nil, nil, err - } - - var e []*Email - resp, err := s.client.Do(req, &e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// ListEmailsForUserOptions represents the available ListEmailsForUser() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#list-emails-for-user -type ListEmailsForUserOptions ListOptions - -// ListEmailsForUser gets a list of a specified user's Emails. Available -// only for admin -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#list-emails-for-user -func (s *UsersService) ListEmailsForUser(user int, opt *ListEmailsForUserOptions, options ...RequestOptionFunc) ([]*Email, *Response, error) { - u := fmt.Sprintf("users/%d/emails", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var e []*Email - resp, err := s.client.Do(req, &e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// GetEmail gets a single email. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-email -func (s *UsersService) GetEmail(email int, options ...RequestOptionFunc) (*Email, *Response, error) { - u := fmt.Sprintf("user/emails/%d", email) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - e := new(Email) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// AddEmailOptions represents the available AddEmail() options. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-email -type AddEmailOptions struct { - Email *string `url:"email,omitempty" json:"email,omitempty"` -} - -// AddEmail creates a new email owned by the currently authenticated user. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email -func (s *UsersService) AddEmail(opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) { - req, err := s.client.NewRequest("POST", "user/emails", opt, options) - if err != nil { - return nil, nil, err - } - - e := new(Email) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// AddEmailForUser creates new email owned by specified user. Available only for -// admin. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email-for-user -func (s *UsersService) AddEmailForUser(user int, opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) { - u := fmt.Sprintf("users/%d/emails", user) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - e := new(Email) - resp, err := s.client.Do(req, e) - if err != nil { - return nil, resp, err - } - - return e, resp, err -} - -// DeleteEmail deletes email owned by currently authenticated user. This is an -// idempotent function and calling it on a key that is already deleted or not -// available results in 200 OK. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#delete-email-for-current-owner -func (s *UsersService) DeleteEmail(email int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("user/emails/%d", email) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// DeleteEmailForUser deletes email owned by a specified user. Available only -// for admin. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#delete-email-for-given-user -func (s *UsersService) DeleteEmailForUser(user, email int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("users/%d/emails/%d", user, email) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// ImpersonationToken represents an impersonation token. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-all-impersonation-tokens-of-a-user -type ImpersonationToken struct { - ID int `json:"id"` - Name string `json:"name"` - Active bool `json:"active"` - Token string `json:"token"` - Scopes []string `json:"scopes"` - Revoked bool `json:"revoked"` - CreatedAt *time.Time `json:"created_at"` - ExpiresAt *ISOTime `json:"expires_at"` -} - -// GetAllImpersonationTokensOptions represents the available -// GetAllImpersonationTokens() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-all-impersonation-tokens-of-a-user -type GetAllImpersonationTokensOptions struct { - ListOptions - State *string `url:"state,omitempty" json:"state,omitempty"` -} - -// GetAllImpersonationTokens retrieves all impersonation tokens of a user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-all-impersonation-tokens-of-a-user -func (s *UsersService) GetAllImpersonationTokens(user int, opt *GetAllImpersonationTokensOptions, options ...RequestOptionFunc) ([]*ImpersonationToken, *Response, error) { - u := fmt.Sprintf("users/%d/impersonation_tokens", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var ts []*ImpersonationToken - resp, err := s.client.Do(req, &ts) - if err != nil { - return nil, resp, err - } - - return ts, resp, err -} - -// GetImpersonationToken retrieves an impersonation token of a user. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-an-impersonation-token-of-a-user -func (s *UsersService) GetImpersonationToken(user, token int, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) { - u := fmt.Sprintf("users/%d/impersonation_tokens/%d", user, token) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - t := new(ImpersonationToken) - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// CreateImpersonationTokenOptions represents the available -// CreateImpersonationToken() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#create-an-impersonation-token -type CreateImpersonationTokenOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` - ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` -} - -// CreateImpersonationToken creates an impersonation token. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#create-an-impersonation-token -func (s *UsersService) CreateImpersonationToken(user int, opt *CreateImpersonationTokenOptions, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) { - u := fmt.Sprintf("users/%d/impersonation_tokens", user) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - t := new(ImpersonationToken) - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// RevokeImpersonationToken revokes an impersonation token. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#revoke-an-impersonation-token -func (s *UsersService) RevokeImpersonationToken(user, token int, options ...RequestOptionFunc) (*Response, error) { - u := fmt.Sprintf("users/%d/impersonation_tokens/%d", user, token) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} - -// UserActivity represents an entry in the user/activities response -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-user-activities-admin-only -type UserActivity struct { - Username string `json:"username"` - LastActivityOn *ISOTime `json:"last_activity_on"` -} - -// GetUserActivitiesOptions represents the options for GetUserActivities -// -// GitLap API docs: -// https://docs.gitlab.com/ce/api/users.html#get-user-activities-admin-only -type GetUserActivitiesOptions struct { - ListOptions - From *ISOTime `url:"from,omitempty" json:"from,omitempty"` -} - -// GetUserActivities retrieves user activities (admin only) -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-user-activities-admin-only -func (s *UsersService) GetUserActivities(opt *GetUserActivitiesOptions, options ...RequestOptionFunc) ([]*UserActivity, *Response, error) { - req, err := s.client.NewRequest("GET", "user/activities", opt, options) - if err != nil { - return nil, nil, err - } - - var t []*UserActivity - resp, err := s.client.Do(req, &t) - if err != nil { - return nil, resp, err - } - - return t, resp, err -} - -// UserStatus represents the current status of a user -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#user-status -type UserStatus struct { - Emoji string `json:"emoji"` - Message string `json:"message"` - MessageHTML string `json:"message_html"` -} - -// CurrentUserStatus retrieves the user status -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#user-status -func (s *UsersService) CurrentUserStatus(options ...RequestOptionFunc) (*UserStatus, *Response, error) { - req, err := s.client.NewRequest("GET", "user/status", nil, options) - if err != nil { - return nil, nil, err - } - - status := new(UserStatus) - resp, err := s.client.Do(req, status) - if err != nil { - return nil, resp, err - } - - return status, resp, err -} - -// GetUserStatus retrieves a user's status -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#get-the-status-of-a-user -func (s *UsersService) GetUserStatus(user int, options ...RequestOptionFunc) (*UserStatus, *Response, error) { - u := fmt.Sprintf("users/%d/status", user) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - status := new(UserStatus) - resp, err := s.client.Do(req, status) - if err != nil { - return nil, resp, err - } - - return status, resp, err -} - -// UserStatusOptions represents the options required to set the status -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#set-user-status -type UserStatusOptions struct { - Emoji *string `url:"emoji,omitempty" json:"emoji,omitempty"` - Message *string `url:"message,omitempty" json:"message,omitempty"` -} - -// SetUserStatus sets the user's status -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/users.html#set-user-status -func (s *UsersService) SetUserStatus(opt *UserStatusOptions, options ...RequestOptionFunc) (*UserStatus, *Response, error) { - req, err := s.client.NewRequest("PUT", "user/status", opt, options) - if err != nil { - return nil, nil, err - } - - status := new(UserStatus) - resp, err := s.client.Do(req, status) - if err != nil { - return nil, resp, err - } - - return status, resp, err -} - -// UserMembership represents a membership of the user in a namespace or project. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/users.html#user-memberships-admin-only -type UserMembership struct { - SourceID int `json:"source_id"` - SourceName string `json:"source_name"` - SourceType string `json:"source_type"` - AccessLevel string `json:"access_level"` -} - -// GetUserMembershipOptions represents the options available to query user memberships. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/users.html#user-memberships-admin-only -type GetUserMembershipOptions struct { - ListOptions - Type *string `url:"type,omitempty" json:"type,omitempty"` -} - -// GetUserMemberships retrieves a list of the user's memberships. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/users.html#user-memberships-admin-only -func (s *UsersService) GetUserMemberships(user int, opt *GetUserMembershipOptions, options ...RequestOptionFunc) ([]*UserMembership, *Response, error) { - u := fmt.Sprintf("users/%d/memberships", user) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var m []*UserMembership - resp, err := s.client.Do(req, &m) - if err != nil { - return nil, resp, err - } - - return m, resp, err -} diff --git a/vendor/github.com/xanzy/go-gitlab/validate.go b/vendor/github.com/xanzy/go-gitlab/validate.go deleted file mode 100644 index 099484ef1..000000000 --- a/vendor/github.com/xanzy/go-gitlab/validate.go +++ /dev/null @@ -1,40 +0,0 @@ -package gitlab - -// ValidateService handles communication with the validation related methods of -// the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/lint.html -type ValidateService struct { - client *Client -} - -// LintResult represents the linting results. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/lint.html -type LintResult struct { - Status string `json:"status"` - Errors []string `json:"errors"` -} - -// Lint validates .gitlab-ci.yml content. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/lint.html -func (s *ValidateService) Lint(content string, options ...RequestOptionFunc) (*LintResult, *Response, error) { - var opts struct { - Content string `url:"content,omitempty" json:"content,omitempty"` - } - opts.Content = content - - req, err := s.client.NewRequest("POST", "ci/lint", &opts, options) - if err != nil { - return nil, nil, err - } - - l := new(LintResult) - resp, err := s.client.Do(req, l) - if err != nil { - return nil, resp, err - } - - return l, resp, nil -} diff --git a/vendor/github.com/xanzy/go-gitlab/wikis.go b/vendor/github.com/xanzy/go-gitlab/wikis.go deleted file mode 100644 index ffabef845..000000000 --- a/vendor/github.com/xanzy/go-gitlab/wikis.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2017, Stany MARCEL -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gitlab - -import ( - "fmt" - "net/url" -) - -// WikisService handles communication with the wikis related methods of -// the Gitlab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/wikis.html -type WikisService struct { - client *Client -} - -// WikiFormat represents the available wiki formats. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/wikis.html -type WikiFormat string - -// The available wiki formats. -const ( - WikiFormatMarkdown WikiFormat = "markdown" - WikiFormatRFoc WikiFormat = "rdoc" - WikiFormatASCIIDoc WikiFormat = "asciidoc" -) - -// Wiki represents a GitLab wiki. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/wikis.html -type Wiki struct { - Content string `json:"content"` - Format WikiFormat `json:"format"` - Slug string `json:"slug"` - Title string `json:"title"` -} - -func (w Wiki) String() string { - return Stringify(w) -} - -// ListWikisOptions represents the available ListWikis options. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#list-wiki-pages -type ListWikisOptions struct { - WithContent *bool `url:"with_content,omitempty" json:"with_content,omitempty"` -} - -// ListWikis lists all pages of the wiki of the given project id. -// When with_content is set, it also returns the content of the pages. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#list-wiki-pages -func (s *WikisService) ListWikis(pid interface{}, opt *ListWikisOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/wikis", pathEscape(project)) - - req, err := s.client.NewRequest("GET", u, opt, options) - if err != nil { - return nil, nil, err - } - - var w []*Wiki - resp, err := s.client.Do(req, &w) - if err != nil { - return nil, resp, err - } - - return w, resp, err -} - -// GetWikiPage gets a wiki page for a given project. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#get-a-wiki-page -func (s *WikisService) GetWikiPage(pid interface{}, slug string, options ...RequestOptionFunc) (*Wiki, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/wikis/%s", pathEscape(project), url.PathEscape(slug)) - - req, err := s.client.NewRequest("GET", u, nil, options) - if err != nil { - return nil, nil, err - } - - var w *Wiki - resp, err := s.client.Do(req, &w) - if err != nil { - return nil, resp, err - } - - return w, resp, err -} - -// CreateWikiPageOptions represents options to CreateWikiPage. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#create-a-new-wiki-page -type CreateWikiPageOptions struct { - Content *string `url:"content" json:"content"` - Title *string `url:"title" json:"title"` - Format *string `url:"format,omitempty" json:"format,omitempty"` -} - -// CreateWikiPage creates a new wiki page for the given repository with -// the given title, slug, and content. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#create-a-new-wiki-page -func (s *WikisService) CreateWikiPage(pid interface{}, opt *CreateWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/wikis", pathEscape(project)) - - req, err := s.client.NewRequest("POST", u, opt, options) - if err != nil { - return nil, nil, err - } - - w := new(Wiki) - resp, err := s.client.Do(req, w) - if err != nil { - return nil, resp, err - } - - return w, resp, err -} - -// EditWikiPageOptions represents options to EditWikiPage. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#edit-an-existing-wiki-page -type EditWikiPageOptions struct { - Content *string `url:"content" json:"content"` - Title *string `url:"title" json:"title"` - Format *string `url:"format,omitempty" json:"format,omitempty"` -} - -// EditWikiPage Updates an existing wiki page. At least one parameter is -// required to update the wiki page. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#edit-an-existing-wiki-page -func (s *WikisService) EditWikiPage(pid interface{}, slug string, opt *EditWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, nil, err - } - u := fmt.Sprintf("projects/%s/wikis/%s", pathEscape(project), url.PathEscape(slug)) - - req, err := s.client.NewRequest("PUT", u, opt, options) - if err != nil { - return nil, nil, err - } - - w := new(Wiki) - resp, err := s.client.Do(req, w) - if err != nil { - return nil, resp, err - } - - return w, resp, err -} - -// DeleteWikiPage deletes a wiki page with a given slug. -// -// GitLab API docs: -// https://docs.gitlab.com/ce/api/wikis.html#delete-a-wiki-page -func (s *WikisService) DeleteWikiPage(pid interface{}, slug string, options ...RequestOptionFunc) (*Response, error) { - project, err := parseID(pid) - if err != nil { - return nil, err - } - u := fmt.Sprintf("projects/%s/wikis/%s", pathEscape(project), url.PathEscape(slug)) - - req, err := s.client.NewRequest("DELETE", u, nil, options) - if err != nil { - return nil, err - } - - return s.client.Do(req, nil) -} diff --git a/vendor/github.com/xanzy/go-gitlab/.gitignore b/vendor/gitlab.com/gitlab-org/api/client-go/.gitignore similarity index 78% rename from vendor/github.com/xanzy/go-gitlab/.gitignore rename to vendor/gitlab.com/gitlab-org/api/client-go/.gitignore index 19b0dcfbd..d28ad4186 100644 --- a/vendor/github.com/xanzy/go-gitlab/.gitignore +++ b/vendor/gitlab.com/gitlab-org/api/client-go/.gitignore @@ -26,3 +26,13 @@ _testmain.go # IDE specific files and folders .idea *.iml +*.swp +*.swo + +# vendor +vendor +.go/ +.golangci-lint/ + +# reports +gl-code-quality-report.json \ No newline at end of file diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/.gitlab-ci.yml b/vendor/gitlab.com/gitlab-org/api/client-go/.gitlab-ci.yml new file mode 100644 index 000000000..55fd2efce --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/.gitlab-ci.yml @@ -0,0 +1,205 @@ +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_PIPELINE_SOURCE == "schedule" + - if: $CI_COMMIT_TAG + - if: $CI_COMMIT_REF_PROTECTED == "true" + +include: + - template: Jobs/SAST.gitlab-ci.yml + - component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@2.0.0 + inputs: + job_stage: lint + job_allow_failure: true + + # NOTE: the two includes below are a hack to conditionally set the tags node + # on our Go jobs. We want to use the large Ultimate runners if possible, + # which is what we have available in the gitlab-org and gitlab-community (Community Forks) + # groups. However, there is no easy way to conditionally set tags or even variables without + # jeopardizing existing (complex) workflow:rules or job:rules. Thus, we resort to + # this nasty conditionally include hack. + - local: '.gitlab/ci/gitlab-go-runner-tags.gitlab-ci.yml' + rules: + - if: $CI_PROJECT_ROOT_NAMESPACE == 'gitlab-org' || $CI_PROJECT_ROOT_NAMESPACE == 'gitlab-community' + - local: '.gitlab/ci/community-go-runner-tags.gitlab-ci.yml' + rules: + - if: $CI_PROJECT_ROOT_NAMESPACE != 'gitlab-org' && $CI_PROJECT_ROOT_NAMESPACE != 'gitlab-community' + +stages: + - lint + - test + - deploy + +.go:versions: + parallel: + matrix: + - GOLANG_IMAGE_VERSION: + - '1.23' + - '1.24' + +.go:base: + extends: + - .go:runner-tags + # From: https://docs.gitlab.com/ci/caching/#cache-go-dependencies + variables: + GOPATH: $CI_PROJECT_DIR/.go + GOLANGCI_LINT_CACHE: $CI_PROJECT_DIR/.golangci-lint + before_script: + - mkdir -p "${GOPATH}" "${GOLANGCI_LINT_CACHE}" + - export PATH="${GOPATH}/bin:$PATH" + cache: + paths: + - $GOPATH/pkg/mod/ + - $GOLANGCI_LINT_CACHE/ + key: + files: + - go.sum + # We only need to run Go-related jobs when actual Go files changed + # or when running either on the default branch or for a tag. + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - if: $CI_COMMIT_TAG + - changes: + - '**/*.go' + - testdata/** + - go.mod + - go.sum + - .gitlab-ci.yml + - .gitlab/ci/*.yml + +golangci-lint: + extends: + - .go:base + stage: lint + needs: [] + variables: + REPORT_FILENAME: 'gl-code-quality-report.json' + image: golangci/golangci-lint:v2.1.6 + script: + - golangci-lint run + artifacts: + reports: + codequality: $REPORT_FILENAME + paths: [$REPORT_FILENAME] + when: always + +verify-generated-code: + extends: + - .go:base + stage: lint + needs: [] + image: golang:1.24-bookworm + script: + - make generate + - | + echo "Checking git status" + [ -z "$(git status --short)" ] || { + echo "Error: Files should have been generated:"; + git status --short; echo "Diff:"; + git --no-pager diff HEAD; + echo "Run \"make generate\" and try again"; + exit 1; + } + +tests:unit: + extends: + - .go:base + - .go:versions + stage: test + needs: [] + image: golang:$GOLANG_IMAGE_VERSION + variables: + # configure tooling versions + GOTESTSUM_VERSION: 'v1.12.0' + GOCOVER_COBERTURA_VERSION: 'v1.2.1-0.20240107185409-0818f3538137' + + # configure artifact files + JUNIT_FILENAME: tests.xml + COVERPROFILE_FILENAME: coverage.out + COVERPROFILE_XML_FILENAME: coverage.xml + script: + - go run gotest.tools/gotestsum@${GOTESTSUM_VERSION} --format=standard-quiet --junitfile=$JUNIT_FILENAME -- -race -coverprofile=$COVERPROFILE_FILENAME -covermode=atomic ./... + - grep -v '_generated.go' "$COVERPROFILE_FILENAME" | grep -v '_mock.go' > "${COVERPROFILE_FILENAME}.tmp" + - mv "${COVERPROFILE_FILENAME}.tmp" "$COVERPROFILE_FILENAME" + - go run github.com/boumenot/gocover-cobertura@${GOCOVER_COBERTURA_VERSION} < $COVERPROFILE_FILENAME > $COVERPROFILE_XML_FILENAME + - go tool cover -func $COVERPROFILE_FILENAME + coverage: '/total:.+\(statements\).+\d+\.\d+/' + artifacts: + paths: + - $JUNIT_FILENAME + - $COVERPROFILE_XML_FILENAME + reports: + junit: $JUNIT_FILENAME + coverage_report: + path: $COVERPROFILE_XML_FILENAME + coverage_format: cobertura + when: always + +generate-release-notes: + stage: deploy + needs: [] + image: alpine:3.21.3 + before_script: + - apk add --update jq curl git + variables: + GIT_DEPTH: 400 + GIT_FETCH_EXTRA_FLAGS: '--tags' + script: + - | + # Download upstream tags if running from a fork + if [ "${CI_MERGE_REQUEST_SOURCE_PROJECT_ID}" != "${CI_MERGE_REQUEST_PROJECT_ID}" ]; then + echo "This merge request has been created from a fork." + if [ "${CI_MERGE_REQUEST_SOURCE_PROJECT_ID}" = "${CI_PROJECT_ID}" ]; then + echo "The merge request pipeline runs in the source project. Downloading tags." + git fetch --depth="${GIT_DEPTH}" --tags "${CI_MERGE_REQUEST_PROJECT_URL}" + else + echo "The merge request pipeline runs in the target project. Not downloading tags." + fi + fi + - | + # Determine version. + if [ -z "$CI_COMMIT_TAG" ]; then + version="$(git describe --tags --match 'v*')" + else + version="$CI_COMMIT_TAG" + fi + urlencoded_version="$(jq -rn --arg x "${version}" '$x|@uri')" + echo "Generating release notes for ${version} (urlencoded=${urlencoded_version}) ..." + - | + # If running in a merge request pipeline, generate the release notes using the target project. + PROJECT_ID="${CI_PROJECT_ID}" + if [ -n "${CI_MERGE_REQUEST_PROJECT_ID}" ]; then + PROJECT_ID="${CI_MERGE_REQUEST_PROJECT_ID}" + fi + - url="https://gitlab.com/api/v4/projects/${PROJECT_ID}/repository/changelog?version=${urlencoded_version}"; echo "url=\"${url}\"" + - curl --fail-with-body "${url}" | jq -r .notes >release-notes.md + - cat release-notes.md + artifacts: + paths: + - release-notes.md + +release: + stage: deploy + rules: + - if: $CI_COMMIT_TAG + needs: + - golangci-lint + - tests:unit + - job: generate-release-notes + artifacts: true + image: registry.gitlab.com/gitlab-org/release-cli:latest + script: + - echo "Create release for $CI_COMMIT_TAG" + release: + tag_name: '$CI_COMMIT_TAG' + tag_message: 'Version $CI_COMMIT_TAG' + name: '$CI_COMMIT_TAG' + description: release-notes.md + +# Update rules on SAST to ensure the jobs show up in the pipeline +# this prevents forks that don't have `ultimate` from skipping SAST scans +# since gitlab-advaced-sast replaces semgrep. +semgrep-sast: + needs: [] + rules: + - when: always diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/.golangci.yml b/vendor/gitlab.com/gitlab-org/api/client-go/.golangci.yml new file mode 100644 index 000000000..c2eb5c9b0 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/.golangci.yml @@ -0,0 +1,70 @@ +version: "2" + +# Options for analysis running +run: + concurrency: 4 + issues-exit-code: 1 + tests: true + +# Output configuration options +output: + formats: + text: + path: stdout + colors: false + print-issued-lines: false + code-climate: + path: gl-code-quality-report.json +linters: + enable: + - asciicheck + - dogsled + - errorlint + - goconst + - misspell + - nakedret + - nolintlint + - revive + - unconvert + - whitespace + disable: + - errcheck + settings: + misspell: + locale: US + ignore-rules: + - noteable + revive: + enable-all-rules: false + rules: + - name: deep-exit + + # List of regexps of issue texts to exclude. + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - path: (.+)\.go$ + text: ^.*, make it a constant$ + paths: + - third_party$ + - builtin$ + - examples/* +issues: + # Maximum issues count per one linter (set to 0 to disable) + max-issues-per-linter: 0 + # Maximum count of issues with the same text (set to 0 to disable) + max-same-issues: 0 +formatters: + enable: + - gofumpt + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/.tool-versions b/vendor/gitlab.com/gitlab-org/api/client-go/.tool-versions new file mode 100644 index 000000000..3a8d95737 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/.tool-versions @@ -0,0 +1 @@ +golang 1.23 diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/CONTRIBUTING.md b/vendor/gitlab.com/gitlab-org/api/client-go/CONTRIBUTING.md new file mode 100644 index 000000000..fb7d5c273 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# How to Contribute + +We want to make contributing to this project as easy as possible. + +## Reporting Issues + +If you have an issue, please report it on the +[issue tracker](https://gitlab.com/gitlab-org/api/client-go/-/issues). + +When you are up for writing a MR to solve the issue you encountered, it's not +needed to first open a separate issue. In that case only opening a MR with a +description of the issue you are trying to solve is just fine. + +## Contributing Code + +Merge requests are always welcome. When in doubt if your contribution fits within +the rest of the project, feel free to first open an issue to discuss your idea. + +This is not needed when fixing a bug or adding an enhancement, as long as the +enhancement you are trying to add can be found in the public GitLab API docs as +this project only supports what is in the public API docs. + +### Use community fork to contribute + +To contribute to this project we recommend that you use the +[community fork](https://gitlab.com/gitlab-community/api/client-go). +Have a look at the +[community fork README](https://gitlab.com/gitlab-community#gitlab-community-forks) +to learn more about what it is and why you should prefer it over +creating your own fork to contribute. + +## Coding style + +We try to follow the Go best practices, where it makes sense, and use +[`gofumpt`](https://github.com/mvdan/gofumpt) to format code in this project. +As a general rule of thumb we prefer to keep line width for comments below 80 +chars and for code (where possible and sensible) below 100 chars. + +Before making a MR, please look at the rest this package and try to make sure +your contribution is consistent with the rest of the coding style. + +New `struct` fields or methods should be placed (as much as possible) in the same +order as the ordering used in the public API docs. The idea is that this makes it +easier to find things. + +### Setting up your local development environment to contribute + +1. Install dependencies: + ```sh + make setup + ``` +1. Make your changes on your feature branch in the community fork or your personal fork +1. Run the reviewable command, which tests, lints and formats the code: + ```sh + make reviewable + ``` +1. Push your feature branch upstream +1. Open up your merge request diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/Dangerfile b/vendor/gitlab.com/gitlab-org/api/client-go/Dangerfile new file mode 100644 index 000000000..51504b3e7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/Dangerfile @@ -0,0 +1,11 @@ +require 'gitlab-dangerfiles' + +# see https://docs.gitlab.com/development/dangerbot/#enable-danger-on-a-project +# see https://gitlab.com/gitlab-org/ruby/gems/gitlab-dangerfiles +Gitlab::Dangerfiles.for_project(self, 'gitlab-api-client-go') do |dangerfiles| + # Import all plugins from the gem + dangerfiles.import_plugins + + # Import a defined set of danger rules + dangerfiles.import_dangerfiles(only: %w[simple_roulette changelog metadata type_label z_add_labels z_retry_link]) +end diff --git a/vendor/github.com/xanzy/go-gitlab/LICENSE b/vendor/gitlab.com/gitlab-org/api/client-go/LICENSE similarity index 99% rename from vendor/github.com/xanzy/go-gitlab/LICENSE rename to vendor/gitlab.com/gitlab-org/api/client-go/LICENSE index 261eeb9e9..8dada3eda 100644 --- a/vendor/github.com/xanzy/go-gitlab/LICENSE +++ b/vendor/gitlab.com/gitlab-org/api/client-go/LICENSE @@ -178,7 +178,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/Makefile b/vendor/gitlab.com/gitlab-org/api/client-go/Makefile new file mode 100644 index 000000000..510bcbf63 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/Makefile @@ -0,0 +1,41 @@ +##@ General + +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +reviewable: setup generate fmt lint test ## Run before committing. + +fmt: install-gofumpt ## Format code + @gofumpt -l -w *.go testing/*.go examples/*.go + +lint: install-golangci-lint ## Run linter + @golangci-lint run + +.PHONY: setup +setup: install-golangci-lint install-gofumpt ## Setup your local environment + go mod tidy + +install-golangci-lint: + @go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest + +install-gofumpt: + @go install mvdan.cc/gofumpt@latest + +.PHONY: generate +generate: install-gofumpt ## Generate files + ./scripts/generate_testing_client.sh + ./scripts/generate_service_interface_map.sh + ./scripts/generate_mock_api.sh + +.PHONY: clean +clean: ## Remove generated files + rm -f \ + testing/*_mock.go \ + testing/*_generated.go \ + *_generated_test.go + +test: ## Run tests + go test ./... -race diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/README.md b/vendor/gitlab.com/gitlab-org/api/client-go/README.md new file mode 100644 index 000000000..21416b1b1 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/README.md @@ -0,0 +1,181 @@ +# GitLab client-go (former `github.com/xanzy/go-gitlab`) + +A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way. + + +## Table of Contents + +[[_TOC_]] + +## Usage + +```go +import "gitlab.com/gitlab-org/api/client-go" +``` + +Construct a new GitLab client, then use the various services on the client to +access different parts of the GitLab API. For example, to list all +users: + +```go +git, err := gitlab.NewClient("yourtokengoeshere") +if err != nil { + log.Fatalf("Failed to create client: %v", err) +} +users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{}) +``` + +There are a few `With...` option functions that can be used to customize +the API client. For example, to set a custom base URL: + +```go +git, err := gitlab.NewClient("yourtokengoeshere", gitlab.WithBaseURL("https://git.mydomain.com/api/v4")) +if err != nil { + log.Fatalf("Failed to create client: %v", err) +} +users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{}) +``` + +Some API methods have optional parameters that can be passed. For example, +to list all projects for user "svanharmelen": + +```go +git := gitlab.NewClient("yourtokengoeshere") +opt := &gitlab.ListProjectsOptions{Search: gitlab.Ptr("svanharmelen")} +projects, _, err := git.Projects.ListProjects(opt) +``` + +### Examples + +The [examples](/examples) directory +contains a couple for clear examples, of which one is partially listed here as well: + +```go +package main + +import ( + "log" + + "gitlab.com/gitlab-org/api/client-go" +) + +func main() { + git, err := gitlab.NewClient("yourtokengoeshere") + if err != nil { + log.Fatalf("Failed to create client: %v", err) + } + + // Create new project + p := &gitlab.CreateProjectOptions{ + Name: gitlab.Ptr("My Project"), + Description: gitlab.Ptr("Just a test project to play with"), + MergeRequestsAccessLevel: gitlab.Ptr(gitlab.EnabledAccessControl), + SnippetsAccessLevel: gitlab.Ptr(gitlab.EnabledAccessControl), + Visibility: gitlab.Ptr(gitlab.PublicVisibility), + } + project, _, err := git.Projects.CreateProject(p) + if err != nil { + log.Fatal(err) + } + + // Add a new snippet + s := &gitlab.CreateProjectSnippetOptions{ + Title: gitlab.Ptr("Dummy Snippet"), + FileName: gitlab.Ptr("snippet.go"), + Content: gitlab.Ptr("package main...."), + Visibility: gitlab.Ptr(gitlab.PublicVisibility), + } + _, _, err = git.ProjectSnippets.CreateSnippet(project.ID, s) + if err != nil { + log.Fatal(err) + } +} +``` + +For complete usage of go-gitlab, see the full [package docs](https://godoc.org/gitlab.com/gitlab-org/api/client-go). + +## Installation + +To install the library, use the following command: + +```go +go get gitlab.com/gitlab-org/api/client-go +``` + +## Testing + +The `client-go` project comes with a `testing` package at `gitlab.com/gitlab-org/api/client-go/testing` +which contains a `TestClient` with [gomock](https://github.com/uber-go/mock) mocks for the individual services. + +You can use them like this: + +```go +func Test_MyApp(t *testing.T) { + client := testing.NewTestClient(t) + + // Setup expectations + client.MockClusterAgents.EXPECT(). + List(gomock.Any(), 123, nil). + Return([]*gitlab.ClusterAgent{{ID: 1}}, nil) + + // Use the client in your test + // You'd probably call your own code here that gets the client injected. + // You can also retrieve a `gitlab.Client` object from `client.Client`. + agents, err := client.ClusterAgents.List(ctx, 123, nil) + assert.NoError(t, err) + assert.Len(t, agents, 1) +} +``` + +### I want to generate my own mocks + +You can! You can set up your own `TestClient` with mocks pretty easily: + +```go +func NewTestClient(t *testing.T) { + // generate your mocks or instantiate a fake or whatever you like + mockClusterAgentsService := newMockClusterAgentsService(t) + client := &gitlab.Client{ + ClusterAgents: mockClusterAgentsService + } + + return tc +} +``` + +The `newMockClusterAgentsService` must return a type that implements `gitlab.ClusterAgentsInterface`. + +You can have a look at [`testing/client.go`](/testing.client.go) how it's implemented for `gomock`. + +## Compatibility + +The `client-go` package will maintain compatibility with the officially supported Go releases +at the time the package is released. According to the [Go Release Policy](https://go.dev/doc/devel/release#policy), +that's currently the two last major Go releases. +This compatibility is reflected in the `go` directive of the [`go.mod`](/go.mod) file +and the unit test matrix in [`.gitlab-ci.yml`](/.gitlab-ci.yml). + +You may also use https://endoflife.date/go to quickly discover the supported Go versions. + +## Contributing + +Contributions are always welcome. For more information, check out the +[contributing guide](/CONTRIBUTING.md). + +## Maintenance + +This is a community maintained project. If you have a paid GitLab subscription, +please note that this project is not packaged as a part of GitLab, and falls outside +of the scope of support. + +For more information, see GitLab's +[Statement of Support](https://about.gitlab.com/support/statement-of-support.html). +Please fill out an issue in this projects issue tracker and someone from the community +will respond as soon as they are available to help you. + +### Known GitLab Projects using this package + +- [GitLab Terraform Provider](https://gitlab.com/gitlab-org/terraform-provider-gitlab) + maintained by the community with support from ~"group::environments" +- [GitLab CLI (`glab`)](https://gitlab.com/gitlab-org/cli) + maintained by ~"group::code review" diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/access_requests.go b/vendor/gitlab.com/gitlab-org/api/client-go/access_requests.go new file mode 100644 index 000000000..1c2ef31c7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/access_requests.go @@ -0,0 +1,268 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + AccessRequestsServiceInterface interface { + ListProjectAccessRequests(pid any, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) + ListGroupAccessRequests(gid any, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) + RequestProjectAccess(pid any, options ...RequestOptionFunc) (*AccessRequest, *Response, error) + RequestGroupAccess(gid any, options ...RequestOptionFunc) (*AccessRequest, *Response, error) + ApproveProjectAccessRequest(pid any, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) + ApproveGroupAccessRequest(gid any, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) + DenyProjectAccessRequest(pid any, user int, options ...RequestOptionFunc) (*Response, error) + DenyGroupAccessRequest(gid any, user int, options ...RequestOptionFunc) (*Response, error) + } + + // AccessRequestsService handles communication with the project/group + // access requests related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/access_requests/ + AccessRequestsService struct { + client *Client + } +) + +var _ AccessRequestsServiceInterface = (*AccessRequestsService)(nil) + +// AccessRequest represents a access request for a group or project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/ +type AccessRequest struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + RequestedAt *time.Time `json:"requested_at"` + AccessLevel AccessLevelValue `json:"access_level"` +} + +// ListAccessRequestsOptions represents the available +// ListProjectAccessRequests() or ListGroupAccessRequests() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#list-access-requests-for-a-group-or-project +type ListAccessRequestsOptions ListOptions + +// ListProjectAccessRequests gets a list of access requests +// viewable by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#list-access-requests-for-a-group-or-project +func (s *AccessRequestsService) ListProjectAccessRequests(pid any, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_requests", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ars []*AccessRequest + resp, err := s.client.Do(req, &ars) + if err != nil { + return nil, resp, err + } + + return ars, resp, nil +} + +// ListGroupAccessRequests gets a list of access requests +// viewable by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#list-access-requests-for-a-group-or-project +func (s *AccessRequestsService) ListGroupAccessRequests(gid any, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_requests", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ars []*AccessRequest + resp, err := s.client.Do(req, &ars) + if err != nil { + return nil, resp, err + } + + return ars, resp, nil +} + +// RequestProjectAccess requests access for the authenticated user +// to a group or project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#request-access-to-a-group-or-project +func (s *AccessRequestsService) RequestProjectAccess(pid any, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_requests", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + ar := new(AccessRequest) + resp, err := s.client.Do(req, ar) + if err != nil { + return nil, resp, err + } + + return ar, resp, nil +} + +// RequestGroupAccess requests access for the authenticated user +// to a group or project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#request-access-to-a-group-or-project +func (s *AccessRequestsService) RequestGroupAccess(gid any, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_requests", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + ar := new(AccessRequest) + resp, err := s.client.Do(req, ar) + if err != nil { + return nil, resp, err + } + + return ar, resp, nil +} + +// ApproveAccessRequestOptions represents the available +// ApproveProjectAccessRequest() and ApproveGroupAccessRequest() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#approve-an-access-request +type ApproveAccessRequestOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// ApproveProjectAccessRequest approves an access request for the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#approve-an-access-request +func (s *AccessRequestsService) ApproveProjectAccessRequest(pid any, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_requests/%d/approve", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ar := new(AccessRequest) + resp, err := s.client.Do(req, ar) + if err != nil { + return nil, resp, err + } + + return ar, resp, nil +} + +// ApproveGroupAccessRequest approves an access request for the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#approve-an-access-request +func (s *AccessRequestsService) ApproveGroupAccessRequest(gid any, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_requests/%d/approve", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ar := new(AccessRequest) + resp, err := s.client.Do(req, ar) + if err != nil { + return nil, resp, err + } + + return ar, resp, nil +} + +// DenyProjectAccessRequest denies an access request for the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#deny-an-access-request +func (s *AccessRequestsService) DenyProjectAccessRequest(pid any, user int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/access_requests/%d", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DenyGroupAccessRequest denies an access request for the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/access_requests/#deny-an-access-request +func (s *AccessRequestsService) DenyGroupAccessRequest(gid any, user int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/access_requests/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/alert_management.go b/vendor/gitlab.com/gitlab-org/api/client-go/alert_management.go new file mode 100644 index 000000000..b87f15c55 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/alert_management.go @@ -0,0 +1,175 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "io" + "net/http" + "time" +) + +type ( + AlertManagementServiceInterface interface { + UploadMetricImage(pid any, alertIID int, content io.Reader, filename string, opt *UploadMetricImageOptions, options ...RequestOptionFunc) (*MetricImage, *Response, error) + ListMetricImages(pid any, alertIID int, opt *ListMetricImagesOptions, options ...RequestOptionFunc) ([]*MetricImage, *Response, error) + UpdateMetricImage(pid any, alertIID int, id int, opt *UpdateMetricImageOptions, options ...RequestOptionFunc) (*MetricImage, *Response, error) + DeleteMetricImage(pid any, alertIID int, id int, options ...RequestOptionFunc) (*Response, error) + } + + // AlertManagementService handles communication with the alert management + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/alert_management_alerts/ + AlertManagementService struct { + client *Client + } +) + +var _ AlertManagementServiceInterface = (*AlertManagementService)(nil) + +// MetricImage represents a single metric image file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/ +type MetricImage struct { + ID int `json:"id"` + CreatedAt *time.Time `json:"created_at"` + Filename string `json:"filename"` + FilePath string `json:"file_path"` + URL string `json:"url"` + URLText string `json:"url_text"` +} + +// UploadMetricImageOptions represents the available UploadMetricImage() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#upload-metric-image +type UploadMetricImageOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + URLText *string `url:"url_text,omitempty" json:"url_text,omitempty"` +} + +// UploadMetricImageOptions uploads a metric image to a project alert. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#upload-metric-image +func (s *AlertManagementService) UploadMetricImage(pid any, alertIID int, content io.Reader, filename string, opt *UploadMetricImageOptions, options ...RequestOptionFunc) (*MetricImage, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/alert_management_alerts/%d/metric_images", PathEscape(project), alertIID) + + req, err := s.client.UploadRequest(http.MethodPost, u, content, filename, UploadFile, opt, options) + if err != nil { + return nil, nil, err + } + + mi := new(MetricImage) + resp, err := s.client.Do(req, mi) + if err != nil { + return nil, resp, err + } + + return mi, resp, nil +} + +// ListMetricImagesOptions represents the available ListMetricImages() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#list-metric-images +type ListMetricImagesOptions struct { + ListOptions +} + +// ListMetricImages lists all the metric images for a project alert. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#list-metric-images +func (s *AlertManagementService) ListMetricImages(pid any, alertIID int, opt *ListMetricImagesOptions, options ...RequestOptionFunc) ([]*MetricImage, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/alert_management_alerts/%d/metric_images", PathEscape(project), alertIID) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mis []*MetricImage + resp, err := s.client.Do(req, &mis) + if err != nil { + return nil, resp, err + } + + return mis, resp, nil +} + +// UpdateMetricImageOptions represents the available UpdateMetricImage() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#update-metric-image +type UpdateMetricImageOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + URLText *string `url:"url_text,omitempty" json:"url_text,omitempty"` +} + +// UpdateMetricImage updates a metric image for a project alert. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#update-metric-image +func (s *AlertManagementService) UpdateMetricImage(pid any, alertIID int, id int, opt *UpdateMetricImageOptions, options ...RequestOptionFunc) (*MetricImage, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/alert_management_alerts/%d/metric_images/%d", PathEscape(project), alertIID, id) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + mi := new(MetricImage) + resp, err := s.client.Do(req, mi) + if err != nil { + return nil, resp, err + } + + return mi, resp, nil +} + +// DeleteMetricImage deletes a metric image for a project alert. +// +// GitLab API docs: +// https://docs.gitlab.com/api/alert_management_alerts/#delete-metric-image +func (s *AlertManagementService) DeleteMetricImage(pid any, alertIID int, id int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/alert_management_alerts/%d/metric_images/%d", PathEscape(project), alertIID, id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/appearance.go b/vendor/gitlab.com/gitlab-org/api/client-go/appearance.go new file mode 100644 index 000000000..6b4724e50 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/appearance.go @@ -0,0 +1,121 @@ +// +// Copyright 2023, 徐晓伟 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "net/http" + +type ( + AppearanceServiceInterface interface { + GetAppearance(options ...RequestOptionFunc) (*Appearance, *Response, error) + ChangeAppearance(opt *ChangeAppearanceOptions, options ...RequestOptionFunc) (*Appearance, *Response, error) + } + + // AppearanceService handles communication with appearance of the Gitlab API. + // + // Gitlab API docs: https://docs.gitlab.com/api/appearance/ + AppearanceService struct { + client *Client + } +) + +var _ AppearanceServiceInterface = (*AppearanceService)(nil) + +// Appearance represents a GitLab appearance. +// +// Gitlab API docs: https://docs.gitlab.com/api/appearance/ +type Appearance struct { + Title string `json:"title"` + Description string `json:"description"` + PWAName string `json:"pwa_name"` + PWAShortName string `json:"pwa_short_name"` + PWADescription string `json:"pwa_description"` + PWAIcon string `json:"pwa_icon"` + Logo string `json:"logo"` + HeaderLogo string `json:"header_logo"` + Favicon string `json:"favicon"` + MemberGuidelines string `json:"member_guidelines"` + NewProjectGuidelines string `json:"new_project_guidelines"` + ProfileImageGuidelines string `json:"profile_image_guidelines"` + HeaderMessage string `json:"header_message"` + FooterMessage string `json:"footer_message"` + MessageBackgroundColor string `json:"message_background_color"` + MessageFontColor string `json:"message_font_color"` + EmailHeaderAndFooterEnabled bool `json:"email_header_and_footer_enabled"` +} + +// GetAppearance gets the current appearance configuration of the GitLab instance. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/appearance/#get-details-on-current-application-appearance +func (s *AppearanceService) GetAppearance(options ...RequestOptionFunc) (*Appearance, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "application/appearance", nil, options) + if err != nil { + return nil, nil, err + } + + as := new(Appearance) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} + +// ChangeAppearanceOptions represents the available ChangeAppearance() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/appearance/#update-application-appearance +type ChangeAppearanceOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + PWAName *string `url:"pwa_name,omitempty" json:"pwa_name,omitempty"` + PWAShortName *string `url:"pwa_short_name,omitempty" json:"pwa_short_name,omitempty"` + PWADescription *string `url:"pwa_description,omitempty" json:"pwa_description,omitempty"` + PWAIcon *string `url:"pwa_icon,omitempty" json:"pwa_icon,omitempty"` + Logo *string `url:"logo,omitempty" json:"logo,omitempty"` + HeaderLogo *string `url:"header_logo,omitempty" json:"header_logo,omitempty"` + Favicon *string `url:"favicon,omitempty" json:"favicon,omitempty"` + MemberGuidelines *string `url:"member_guidelines,omitempty" json:"member_guidelines,omitempty"` + NewProjectGuidelines *string `url:"new_project_guidelines,omitempty" json:"new_project_guidelines,omitempty"` + ProfileImageGuidelines *string `url:"profile_image_guidelines,omitempty" json:"profile_image_guidelines,omitempty"` + HeaderMessage *string `url:"header_message,omitempty" json:"header_message,omitempty"` + FooterMessage *string `url:"footer_message,omitempty" json:"footer_message,omitempty"` + MessageBackgroundColor *string `url:"message_background_color,omitempty" json:"message_background_color,omitempty"` + MessageFontColor *string `url:"message_font_color,omitempty" json:"message_font_color,omitempty"` + EmailHeaderAndFooterEnabled *bool `url:"email_header_and_footer_enabled,omitempty" json:"email_header_and_footer_enabled,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` +} + +// ChangeAppearance changes the appearance configuration. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/appearance/#update-application-appearance +func (s *AppearanceService) ChangeAppearance(opt *ChangeAppearanceOptions, options ...RequestOptionFunc) (*Appearance, *Response, error) { + req, err := s.client.NewRequest(http.MethodPut, "application/appearance", opt, options) + if err != nil { + return nil, nil, err + } + + as := new(Appearance) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/application_statistics.go b/vendor/gitlab.com/gitlab-org/api/client-go/application_statistics.go new file mode 100644 index 000000000..5442852c5 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/application_statistics.go @@ -0,0 +1,68 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "net/http" + +type ( + ApplicationStatisticsServiceInterface interface { + GetApplicationStatistics(options ...RequestOptionFunc) (*ApplicationStatistics, *Response, error) + } + + // ApplicationStatisticsService handles communication with the application + // statistics related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/statistics/ + ApplicationStatisticsService struct { + client *Client + } +) + +var _ ApplicationStatisticsServiceInterface = (*ApplicationStatisticsService)(nil) + +// ApplicationStatistics represents application statistics. +// +// GitLab API docs: https://docs.gitlab.com/api/statistics/ +type ApplicationStatistics struct { + Forks int `url:"forks" json:"forks"` + Issues int `url:"issues" json:"issues"` + MergeRequests int `url:"merge_requests" json:"merge_requests"` + Notes int `url:"notes" json:"notes"` + Snippets int `url:"snippets" json:"snippets"` + SSHKeys int `url:"ssh_keys" json:"ssh_keys"` + Milestones int `url:"milestones" json:"milestones"` + Users int `url:"users" json:"users"` + Groups int `url:"groups" json:"groups"` + Projects int `url:"projects" json:"projects"` + ActiveUsers int `url:"active_users" json:"active_users"` +} + +// GetApplicationStatistics gets details on the current application statistics. +// +// GitLab API docs: +// https://docs.gitlab.com/api/statistics/#get-details-on-current-application-statistics +func (s *ApplicationStatisticsService) GetApplicationStatistics(options ...RequestOptionFunc) (*ApplicationStatistics, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "application/statistics", nil, options) + if err != nil { + return nil, nil, err + } + + statistics := new(ApplicationStatistics) + resp, err := s.client.Do(req, statistics) + if err != nil { + return nil, resp, err + } + return statistics, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/applications.go b/vendor/gitlab.com/gitlab-org/api/client-go/applications.go similarity index 63% rename from vendor/github.com/xanzy/go-gitlab/applications.go rename to vendor/gitlab.com/gitlab-org/api/client-go/applications.go index 1436ed011..06dae54cb 100644 --- a/vendor/github.com/xanzy/go-gitlab/applications.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/applications.go @@ -1,5 +1,5 @@ // -// Copyright 2017, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,16 +16,30 @@ package gitlab -import "fmt" +import ( + "fmt" + "net/http" +) -// ApplicationsService handles communication with administrables applications -// of the Gitlab API. -// -// Gitlab API docs : https://docs.gitlab.com/ee/api/applications.html -type ApplicationsService struct { - client *Client -} +type ( + ApplicationsServiceInterface interface { + CreateApplication(opt *CreateApplicationOptions, options ...RequestOptionFunc) (*Application, *Response, error) + ListApplications(opt *ListApplicationsOptions, options ...RequestOptionFunc) ([]*Application, *Response, error) + DeleteApplication(application int, options ...RequestOptionFunc) (*Response, error) + } + + // ApplicationsService handles communication with administrables applications + // of the Gitlab API. + // + // Gitlab API docs: https://docs.gitlab.com/api/applications/ + ApplicationsService struct { + client *Client + } +) + +var _ ApplicationsServiceInterface = (*ApplicationsService)(nil) +// Application represents a GitLab application type Application struct { ID int `json:"id"` ApplicationID string `json:"application_id"` @@ -38,7 +52,7 @@ type Application struct { // CreateApplicationOptions represents the available CreateApplication() options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/applications.html#create-an-application +// https://docs.gitlab.com/api/applications/#create-an-application type CreateApplicationOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` RedirectURI *string `url:"redirect_uri,omitempty" json:"redirect_uri,omitempty"` @@ -48,9 +62,9 @@ type CreateApplicationOptions struct { // CreateApplication creates a new application owned by the authenticated user. // -// Gitlab API docs : https://docs.gitlab.com/ce/api/applications.html#create-an-application +// Gitlab API docs: https://docs.gitlab.com/api/applications/#create-an-application func (s *ApplicationsService) CreateApplication(opt *CreateApplicationOptions, options ...RequestOptionFunc) (*Application, *Response, error) { - req, err := s.client.NewRequest("POST", "applications", opt, options) + req, err := s.client.NewRequest(http.MethodPost, "applications", opt, options) if err != nil { return nil, nil, err } @@ -61,16 +75,18 @@ func (s *ApplicationsService) CreateApplication(opt *CreateApplicationOptions, o return nil, resp, err } - return a, resp, err + return a, resp, nil } +// ListApplicationsOptions represents the available +// ListApplications() options. type ListApplicationsOptions ListOptions // ListApplications get a list of administrables applications by the authenticated user // -// Gitlab API docs : https://docs.gitlab.com/ce/api/applications.html#list-all-applications +// Gitlab API docs : https://docs.gitlab.com/api/applications/#list-all-applications func (s *ApplicationsService) ListApplications(opt *ListApplicationsOptions, options ...RequestOptionFunc) ([]*Application, *Response, error) { - req, err := s.client.NewRequest("GET", "applications", opt, options) + req, err := s.client.NewRequest(http.MethodGet, "applications", opt, options) if err != nil { return nil, nil, err } @@ -81,17 +97,17 @@ func (s *ApplicationsService) ListApplications(opt *ListApplicationsOptions, opt return nil, resp, err } - return as, resp, err + return as, resp, nil } // DeleteApplication removes a specific application. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/applications.html#delete-an-application +// https://docs.gitlab.com/api/applications/#delete-an-application func (s *ApplicationsService) DeleteApplication(application int, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("applications/%d", application) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/audit_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/audit_events.go new file mode 100644 index 000000000..3a61d8a4f --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/audit_events.go @@ -0,0 +1,217 @@ +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + AuditEventsServiceInterface interface { + ListInstanceAuditEvents(opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) + GetInstanceAuditEvent(event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) + ListGroupAuditEvents(gid any, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) + GetGroupAuditEvent(gid any, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) + ListProjectAuditEvents(pid any, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) + GetProjectAuditEvent(pid any, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) + } + + // AuditEventsService handles communication with the project/group/instance + // audit event related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/audit_events/ + AuditEventsService struct { + client *Client + } +) + +var _ AuditEventsServiceInterface = (*AuditEventsService)(nil) + +// AuditEvent represents an audit event for a group, a project or the instance. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/ +type AuditEvent struct { + ID int `json:"id"` + AuthorID int `json:"author_id"` + EntityID int `json:"entity_id"` + EntityType string `json:"entity_type"` + EventName string `json:"event_name"` + Details AuditEventDetails `json:"details"` + CreatedAt *time.Time `json:"created_at"` + EventType string `json:"event_type"` +} + +// AuditEventDetails represents the details portion of an audit event for +// a group, a project or the instance. The exact fields that are returned +// for an audit event depend on the action being recorded. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/ +type AuditEventDetails struct { + With string `json:"with"` + Add string `json:"add"` + As string `json:"as"` + Change string `json:"change"` + From string `json:"from"` + To string `json:"to"` + Remove string `json:"remove"` + CustomMessage string `json:"custom_message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthorClass string `json:"author_class"` + TargetID any `json:"target_id"` + TargetType string `json:"target_type"` + TargetDetails string `json:"target_details"` + IPAddress string `json:"ip_address"` + EntityPath string `json:"entity_path"` + FailedLogin string `json:"failed_login"` + EventName string `json:"event_name"` +} + +// ListAuditEventsOptions represents the available ListProjectAuditEvents(), +// ListGroupAuditEvents() or ListInstanceAuditEvents() options. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/ +type ListAuditEventsOptions struct { + ListOptions + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` +} + +// ListInstanceAuditEvents gets a list of audit events for instance. +// Authentication as Administrator is required. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/#retrieve-all-instance-audit-events +func (s *AuditEventsService) ListInstanceAuditEvents(opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "audit_events", opt, options) + if err != nil { + return nil, nil, err + } + + var aes []*AuditEvent + resp, err := s.client.Do(req, &aes) + if err != nil { + return nil, resp, err + } + + return aes, resp, nil +} + +// GetInstanceAuditEvent gets a specific instance audit event. +// Authentication as Administrator is required. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/#retrieve-single-instance-audit-event +func (s *AuditEventsService) GetInstanceAuditEvent(event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) { + u := fmt.Sprintf("audit_events/%d", event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ae := new(AuditEvent) + resp, err := s.client.Do(req, ae) + if err != nil { + return nil, resp, err + } + + return ae, resp, nil +} + +// ListGroupAuditEvents gets a list of audit events for the specified group +// viewable by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/#retrieve-all-group-audit-events +func (s *AuditEventsService) ListGroupAuditEvents(gid any, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/audit_events", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var aes []*AuditEvent + resp, err := s.client.Do(req, &aes) + if err != nil { + return nil, resp, err + } + + return aes, resp, nil +} + +// GetGroupAuditEvent gets a specific group audit event. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/#retrieve-a-specific-group-audit-event +func (s *AuditEventsService) GetGroupAuditEvent(gid any, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/audit_events/%d", PathEscape(group), event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ae := new(AuditEvent) + resp, err := s.client.Do(req, ae) + if err != nil { + return nil, resp, err + } + + return ae, resp, nil +} + +// ListProjectAuditEvents gets a list of audit events for the specified project +// viewable by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/audit_events/#retrieve-all-project-audit-events +func (s *AuditEventsService) ListProjectAuditEvents(pid any, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/audit_events", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var aes []*AuditEvent + resp, err := s.client.Do(req, &aes) + if err != nil { + return nil, resp, err + } + + return aes, resp, nil +} + +// GetProjectAuditEvent gets a specific project audit event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/audit_events/#retrieve-a-specific-project-audit-event +func (s *AuditEventsService) GetProjectAuditEvent(pid any, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/audit_events/%d", PathEscape(project), event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ae := new(AuditEvent) + resp, err := s.client.Do(req, ae) + if err != nil { + return nil, resp, err + } + + return ae, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/avatar.go b/vendor/gitlab.com/gitlab-org/api/client-go/avatar.go new file mode 100644 index 000000000..e0bf2d6f7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/avatar.go @@ -0,0 +1,72 @@ +// +// Copyright 2021, Pavel Kostohrys +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "net/http" +) + +type ( + AvatarRequestsServiceInterface interface { + GetAvatar(opt *GetAvatarOptions, options ...RequestOptionFunc) (*Avatar, *Response, error) + } + + // AvatarRequestsService handles communication with the avatar related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/avatar/ + AvatarRequestsService struct { + client *Client + } +) + +var _ AvatarRequestsServiceInterface = (*AvatarRequestsService)(nil) + +// Avatar represents a GitLab avatar. +// +// GitLab API docs: https://docs.gitlab.com/api/avatar/ +type Avatar struct { + AvatarURL string `json:"avatar_url"` +} + +// GetAvatarOptions represents the available GetAvatar() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/avatar/#get-details-on-an-account-avatar +type GetAvatarOptions struct { + Email *string `url:"email,omitempty" json:"email,omitempty"` + Size *int `url:"size,omitempty" json:"size,omitempty"` +} + +// GetAvatar gets the avatar URL for a user with the given email address. +// +// GitLab API docs: +// https://docs.gitlab.com/api/avatar/#get-details-on-an-account-avatar +func (s *AvatarRequestsService) GetAvatar(opt *GetAvatarOptions, options ...RequestOptionFunc) (*Avatar, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "avatar", opt, options) + if err != nil { + return nil, nil, err + } + + avatar := new(Avatar) + response, err := s.client.Do(req, avatar) + if err != nil { + return nil, response, err + } + + return avatar, response, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/award_emojis.go b/vendor/gitlab.com/gitlab-org/api/client-go/award_emojis.go new file mode 100644 index 000000000..525ec4475 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/award_emojis.go @@ -0,0 +1,499 @@ +// +// Copyright 2021, Arkbriar +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + AwardEmojiServiceInterface interface { + ListMergeRequestAwardEmoji(pid any, mergeRequestIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + ListIssueAwardEmoji(pid any, issueIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + ListSnippetAwardEmoji(pid any, snippetID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + GetMergeRequestAwardEmoji(pid any, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + GetIssueAwardEmoji(pid any, issueIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + GetSnippetAwardEmoji(pid any, snippetID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateMergeRequestAwardEmoji(pid any, mergeRequestIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateIssueAwardEmoji(pid any, issueIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateSnippetAwardEmoji(pid any, snippetID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + DeleteIssueAwardEmoji(pid any, issueIID, awardID int, options ...RequestOptionFunc) (*Response, error) + DeleteMergeRequestAwardEmoji(pid any, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*Response, error) + DeleteSnippetAwardEmoji(pid any, snippetID, awardID int, options ...RequestOptionFunc) (*Response, error) + ListIssuesAwardEmojiOnNote(pid any, issueID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + ListMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + ListSnippetAwardEmojiOnNote(pid any, snippetIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) + GetIssuesAwardEmojiOnNote(pid any, issueID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + GetMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + GetSnippetAwardEmojiOnNote(pid any, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateIssuesAwardEmojiOnNote(pid any, issueID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + CreateSnippetAwardEmojiOnNote(pid any, snippetIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) + DeleteIssuesAwardEmojiOnNote(pid any, issueID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) + DeleteMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) + DeleteSnippetAwardEmojiOnNote(pid any, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) + } + + // AwardEmojiService handles communication with the emoji awards related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/emoji_reactions/ + AwardEmojiService struct { + client *Client + } +) + +var _ AwardEmojiServiceInterface = (*AwardEmojiService)(nil) + +// AwardEmoji represents a GitLab Award Emoji. +// +// GitLab API docs: https://docs.gitlab.com/api/emoji_reactions/ +type AwardEmoji struct { + ID int `json:"id"` + Name string `json:"name"` + User struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"user"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + AwardableID int `json:"awardable_id"` + AwardableType string `json:"awardable_type"` +} + +const ( + awardMergeRequest = "merge_requests" + awardIssue = "issues" + awardSnippets = "snippets" +) + +// ListAwardEmojiOptions represents the available options for listing emoji +// for each resource +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/ +type ListAwardEmojiOptions ListOptions + +// ListMergeRequestAwardEmoji gets a list of all award emoji on the merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-an-awardables-emoji-reactions +func (s *AwardEmojiService) ListMergeRequestAwardEmoji(pid any, mergeRequestIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...) +} + +// ListIssueAwardEmoji gets a list of all award emoji on the issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-an-awardables-emoji-reactions +func (s *AwardEmojiService) ListIssueAwardEmoji(pid any, issueIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmoji(pid, awardIssue, issueIID, opt, options...) +} + +// ListSnippetAwardEmoji gets a list of all award emoji on the snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-an-awardables-emoji-reactions +func (s *AwardEmojiService) ListSnippetAwardEmoji(pid any, snippetID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmoji(pid, awardSnippets, snippetID, opt, options...) +} + +func (s *AwardEmojiService) listAwardEmoji(pid any, resource string, resourceID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/award_emoji", + PathEscape(project), + resource, + resourceID, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var as []*AwardEmoji + resp, err := s.client.Do(req, &as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} + +// GetMergeRequestAwardEmoji get an award emoji from merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-single-emoji-reaction +func (s *AwardEmojiService) GetMergeRequestAwardEmoji(pid any, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...) +} + +// GetIssueAwardEmoji get an award emoji from issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-single-emoji-reaction +func (s *AwardEmojiService) GetIssueAwardEmoji(pid any, issueIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getAwardEmoji(pid, awardIssue, issueIID, awardID, options...) +} + +// GetSnippetAwardEmoji get an award emoji from snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-single-emoji-reaction +func (s *AwardEmojiService) GetSnippetAwardEmoji(pid any, snippetID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getAwardEmoji(pid, awardSnippets, snippetID, awardID, options...) +} + +func (s *AwardEmojiService) getAwardEmoji(pid any, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", + PathEscape(project), + resource, + resourceID, + awardID, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(AwardEmoji) + resp, err := s.client.Do(req, &a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// CreateAwardEmojiOptions represents the available options for awarding emoji +// for a resource +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction +type CreateAwardEmojiOptions struct { + Name string `json:"name"` +} + +// CreateMergeRequestAwardEmoji get an award emoji from merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction +func (s *AwardEmojiService) CreateMergeRequestAwardEmoji(pid any, mergeRequestIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...) +} + +// CreateIssueAwardEmoji get an award emoji from issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction +func (s *AwardEmojiService) CreateIssueAwardEmoji(pid any, issueIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmoji(pid, awardIssue, issueIID, opt, options...) +} + +// CreateSnippetAwardEmoji get an award emoji from snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction +func (s *AwardEmojiService) CreateSnippetAwardEmoji(pid any, snippetID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmoji(pid, awardSnippets, snippetID, opt, options...) +} + +func (s *AwardEmojiService) createAwardEmoji(pid any, resource string, resourceID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/award_emoji", + PathEscape(project), + resource, + resourceID, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + a := new(AwardEmoji) + resp, err := s.client.Do(req, &a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// DeleteIssueAwardEmoji delete award emoji on an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction +func (s *AwardEmojiService) DeleteIssueAwardEmoji(pid any, issueIID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmoji(pid, awardIssue, issueIID, awardID, options...) +} + +// DeleteMergeRequestAwardEmoji delete award emoji on a merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction +func (s *AwardEmojiService) DeleteMergeRequestAwardEmoji(pid any, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...) +} + +// DeleteSnippetAwardEmoji delete award emoji on a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction +func (s *AwardEmojiService) DeleteSnippetAwardEmoji(pid any, snippetID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmoji(pid, awardSnippets, snippetID, awardID, options...) +} + +// DeleteAwardEmoji Delete an award emoji on the specified resource. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction +func (s *AwardEmojiService) deleteAwardEmoji(pid any, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", PathEscape(project), resource, + resourceID, awardID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + return s.client.Do(req, nil) +} + +// ListIssuesAwardEmojiOnNote gets a list of all award emoji on a note from the +// issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-a-comments-emoji-reactions +func (s *AwardEmojiService) ListIssuesAwardEmojiOnNote(pid any, issueID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...) +} + +// ListMergeRequestAwardEmojiOnNote gets a list of all award emoji on a note +// from the merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-a-comments-emoji-reactions +func (s *AwardEmojiService) ListMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...) +} + +// ListSnippetAwardEmojiOnNote gets a list of all award emoji on a note from the +// snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#list-a-comments-emoji-reactions +func (s *AwardEmojiService) ListSnippetAwardEmojiOnNote(pid any, snippetIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + return s.listAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...) +} + +func (s *AwardEmojiService) listAwardEmojiOnNote(pid any, resources string, ressourceID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", PathEscape(project), resources, + ressourceID, noteID) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var as []*AwardEmoji + resp, err := s.client.Do(req, &as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} + +// GetIssuesAwardEmojiOnNote gets an award emoji on a note from an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-an-emoji-reaction-for-a-comment +func (s *AwardEmojiService) GetIssuesAwardEmojiOnNote(pid any, issueID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getSingleNoteAwardEmoji(pid, awardIssue, issueID, noteID, awardID, options...) +} + +// GetMergeRequestAwardEmojiOnNote gets an award emoji on a note from a +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-an-emoji-reaction-for-a-comment +func (s *AwardEmojiService) GetMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getSingleNoteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, noteID, awardID, + options...) +} + +// GetSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#get-an-emoji-reaction-for-a-comment +func (s *AwardEmojiService) GetSnippetAwardEmojiOnNote(pid any, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.getSingleNoteAwardEmoji(pid, awardSnippets, snippetIID, noteID, awardID, options...) +} + +func (s *AwardEmojiService) getSingleNoteAwardEmoji(pid any, ressource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d", + PathEscape(project), + ressource, + resourceID, + noteID, + awardID, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(AwardEmoji) + resp, err := s.client.Do(req, &a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// CreateIssuesAwardEmojiOnNote gets an award emoji on a note from an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction-to-a-comment +func (s *AwardEmojiService) CreateIssuesAwardEmojiOnNote(pid any, issueID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...) +} + +// CreateMergeRequestAwardEmojiOnNote gets an award emoji on a note from a +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction-to-a-comment +func (s *AwardEmojiService) CreateMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...) +} + +// CreateSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction-to-a-comment +func (s *AwardEmojiService) CreateSnippetAwardEmojiOnNote(pid any, snippetIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + return s.createAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...) +} + +// CreateAwardEmojiOnNote award emoji on a note. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#add-a-new-emoji-reaction-to-a-comment +func (s *AwardEmojiService) createAwardEmojiOnNote(pid any, resource string, resourceID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", + PathEscape(project), + resource, + resourceID, + noteID, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + a := new(AwardEmoji) + resp, err := s.client.Do(req, &a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// DeleteIssuesAwardEmojiOnNote deletes an award emoji on a note from an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction-from-a-comment +func (s *AwardEmojiService) DeleteIssuesAwardEmojiOnNote(pid any, issueID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmojiOnNote(pid, awardIssue, issueID, noteID, awardID, options...) +} + +// DeleteMergeRequestAwardEmojiOnNote deletes an award emoji on a note from a +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction-from-a-comment +func (s *AwardEmojiService) DeleteMergeRequestAwardEmojiOnNote(pid any, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, awardID, + options...) +} + +// DeleteSnippetAwardEmojiOnNote deletes an award emoji on a note from a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/emoji_reactions/#delete-an-emoji-reaction-from-a-comment +func (s *AwardEmojiService) DeleteSnippetAwardEmojiOnNote(pid any, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { + return s.deleteAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, awardID, options...) +} + +func (s *AwardEmojiService) deleteAwardEmojiOnNote(pid any, resource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d", + PathEscape(project), + resource, + resourceID, + noteID, + awardID, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/boards.go b/vendor/gitlab.com/gitlab-org/api/client-go/boards.go new file mode 100644 index 000000000..1d1558d02 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/boards.go @@ -0,0 +1,384 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + IssueBoardsServiceInterface interface { + CreateIssueBoard(pid any, opt *CreateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) + UpdateIssueBoard(pid any, board int, opt *UpdateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) + DeleteIssueBoard(pid any, board int, options ...RequestOptionFunc) (*Response, error) + ListIssueBoards(pid any, opt *ListIssueBoardsOptions, options ...RequestOptionFunc) ([]*IssueBoard, *Response, error) + GetIssueBoard(pid any, board int, options ...RequestOptionFunc) (*IssueBoard, *Response, error) + GetIssueBoardLists(pid any, board int, opt *GetIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) + GetIssueBoardList(pid any, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) + CreateIssueBoardList(pid any, board int, opt *CreateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) + UpdateIssueBoardList(pid any, board, list int, opt *UpdateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) + DeleteIssueBoardList(pid any, board, list int, options ...RequestOptionFunc) (*Response, error) + } + + // IssueBoardsService handles communication with the issue board related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/boards/ + IssueBoardsService struct { + client *Client + } +) + +var _ IssueBoardsServiceInterface = (*IssueBoardsService)(nil) + +// IssueBoard represents a GitLab issue board. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/ +type IssueBoard struct { + ID int `json:"id"` + Name string `json:"name"` + Project *Project `json:"project"` + Milestone *Milestone `json:"milestone"` + Assignee *struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"assignee"` + Lists []*BoardList `json:"lists"` + Weight int `json:"weight"` + Labels []*LabelDetails `json:"labels"` +} + +func (b IssueBoard) String() string { + return Stringify(b) +} + +// BoardList represents a GitLab board list. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/ +type BoardList struct { + ID int `json:"id"` + Assignee *struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + } `json:"assignee"` + Iteration *ProjectIteration `json:"iteration"` + Label *Label `json:"label"` + MaxIssueCount int `json:"max_issue_count"` + MaxIssueWeight int `json:"max_issue_weight"` + Milestone *Milestone `json:"milestone"` + Position int `json:"position"` +} + +func (b BoardList) String() string { + return Stringify(b) +} + +// CreateIssueBoardOptions represents the available CreateIssueBoard() options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#create-an-issue-board +type CreateIssueBoardOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// CreateIssueBoard creates a new issue board. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#create-an-issue-board +func (s *IssueBoardsService) CreateIssueBoard(pid any, opt *CreateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + board := new(IssueBoard) + resp, err := s.client.Do(req, board) + if err != nil { + return nil, resp, err + } + + return board, resp, nil +} + +// UpdateIssueBoardOptions represents the available UpdateIssueBoard() options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#update-an-issue-board +type UpdateIssueBoardOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels *LabelOptions `url:"labels,omitempty" json:"labels,omitempty"` + Weight *int `url:"weight,omitempty" json:"weight,omitempty"` +} + +// UpdateIssueBoard update an issue board. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#update-an-issue-board +func (s *IssueBoardsService) UpdateIssueBoard(pid any, board int, opt *UpdateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d", PathEscape(project), board) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + is := new(IssueBoard) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// DeleteIssueBoard deletes an issue board. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#delete-an-issue-board +func (s *IssueBoardsService) DeleteIssueBoard(pid any, board int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d", PathEscape(project), board) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListIssueBoardsOptions represents the available ListIssueBoards() options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#list-project-issue-boards +type ListIssueBoardsOptions ListOptions + +// ListIssueBoards gets a list of all issue boards in a project. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#list-project-issue-boards +func (s *IssueBoardsService) ListIssueBoards(pid any, opt *ListIssueBoardsOptions, options ...RequestOptionFunc) ([]*IssueBoard, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var is []*IssueBoard + resp, err := s.client.Do(req, &is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// GetIssueBoard gets a single issue board of a project. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#show-a-single-issue-board +func (s *IssueBoardsService) GetIssueBoard(pid any, board int, options ...RequestOptionFunc) (*IssueBoard, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d", PathEscape(project), board) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ib := new(IssueBoard) + resp, err := s.client.Do(req, ib) + if err != nil { + return nil, resp, err + } + + return ib, resp, nil +} + +// GetIssueBoardListsOptions represents the available GetIssueBoardLists() options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#list-board-lists-in-a-project-issue-board +type GetIssueBoardListsOptions ListOptions + +// GetIssueBoardLists gets a list of the issue board's lists. Does not include +// backlog and closed lists. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#list-board-lists-in-a-project-issue-board +func (s *IssueBoardsService) GetIssueBoardLists(pid any, board int, opt *GetIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d/lists", PathEscape(project), board) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var bl []*BoardList + resp, err := s.client.Do(req, &bl) + if err != nil { + return nil, resp, err + } + + return bl, resp, nil +} + +// GetIssueBoardList gets a single issue board list. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#show-a-single-board-list +func (s *IssueBoardsService) GetIssueBoardList(pid any, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", + PathEscape(project), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + bl := new(BoardList) + resp, err := s.client.Do(req, bl) + if err != nil { + return nil, resp, err + } + + return bl, resp, nil +} + +// CreateIssueBoardListOptions represents the available CreateIssueBoardList() +// options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#create-a-board-list +type CreateIssueBoardListOptions struct { + LabelID *int `url:"label_id,omitempty" json:"label_id,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + IterationID *int `url:"iteration_id,omitempty" json:"iteration_id,omitempty"` +} + +// CreateIssueBoardList creates a new issue board list. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#create-a-board-list +func (s *IssueBoardsService) CreateIssueBoardList(pid any, board int, opt *CreateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d/lists", PathEscape(project), board) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + bl := new(BoardList) + resp, err := s.client.Do(req, bl) + if err != nil { + return nil, resp, err + } + + return bl, resp, nil +} + +// UpdateIssueBoardListOptions represents the available UpdateIssueBoardList() +// options. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#reorder-a-list-in-a-board +type UpdateIssueBoardListOptions struct { + Position *int `url:"position" json:"position"` +} + +// UpdateIssueBoardList updates the position of an existing issue board list. +// +// GitLab API docs: https://docs.gitlab.com/api/boards/#reorder-a-list-in-a-board +func (s *IssueBoardsService) UpdateIssueBoardList(pid any, board, list int, opt *UpdateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", + PathEscape(project), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + bl := new(BoardList) + resp, err := s.client.Do(req, bl) + if err != nil { + return nil, resp, err + } + + return bl, resp, nil +} + +// DeleteIssueBoardList soft deletes an issue board list. Only for admins and +// project owners. +// +// GitLab API docs: +// https://docs.gitlab.com/api/boards/#delete-a-board-list-from-a-board +func (s *IssueBoardsService) DeleteIssueBoardList(pid any, board, list int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/boards/%d/lists/%d", + PathEscape(project), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/branches.go b/vendor/gitlab.com/gitlab-org/api/client-go/branches.go new file mode 100644 index 000000000..1c753b17f --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/branches.go @@ -0,0 +1,195 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + BranchesServiceInterface interface { + ListBranches(pid any, opts *ListBranchesOptions, options ...RequestOptionFunc) ([]*Branch, *Response, error) + GetBranch(pid any, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) + CreateBranch(pid any, opt *CreateBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) + DeleteBranch(pid any, branch string, options ...RequestOptionFunc) (*Response, error) + DeleteMergedBranches(pid any, options ...RequestOptionFunc) (*Response, error) + } + + // BranchesService handles communication with the branch related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/branches/ + BranchesService struct { + client *Client + } +) + +var _ BranchesServiceInterface = (*BranchesService)(nil) + +// Branch represents a GitLab branch. +// +// GitLab API docs: https://docs.gitlab.com/api/branches/ +type Branch struct { + Commit *Commit `json:"commit"` + Name string `json:"name"` + Protected bool `json:"protected"` + Merged bool `json:"merged"` + Default bool `json:"default"` + CanPush bool `json:"can_push"` + DevelopersCanPush bool `json:"developers_can_push"` + DevelopersCanMerge bool `json:"developers_can_merge"` + WebURL string `json:"web_url"` +} + +func (b Branch) String() string { + return Stringify(b) +} + +// ListBranchesOptions represents the available ListBranches() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#list-repository-branches +type ListBranchesOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + Regex *string `url:"regex,omitempty" json:"regex,omitempty"` +} + +// ListBranches gets a list of repository branches from a project, sorted by +// name alphabetically. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#list-repository-branches +func (s *BranchesService) ListBranches(pid any, opts *ListBranchesOptions, options ...RequestOptionFunc) ([]*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var b []*Branch + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// GetBranch gets a single project repository branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#get-single-repository-branch +func (s *BranchesService) GetBranch(pid any, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s", PathEscape(project), url.PathEscape(branch)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// CreateBranchOptions represents the available CreateBranch() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#create-repository-branch +type CreateBranchOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// CreateBranch creates branch from commit SHA or existing branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#create-repository-branch +func (s *BranchesService) CreateBranch(pid any, opt *CreateBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + b := new(Branch) + resp, err := s.client.Do(req, b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// DeleteBranch deletes an existing branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#delete-repository-branch +func (s *BranchesService) DeleteBranch(pid any, branch string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/branches/%s", PathEscape(project), url.PathEscape(branch)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteMergedBranches deletes all branches that are merged into the project's default branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/branches/#delete-merged-branches +func (s *BranchesService) DeleteMergedBranches(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/merged_branches", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/broadcast_messages.go b/vendor/gitlab.com/gitlab-org/api/client-go/broadcast_messages.go new file mode 100644 index 000000000..2e4220086 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/broadcast_messages.go @@ -0,0 +1,197 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + BroadcastMessagesServiceInterface interface { + ListBroadcastMessages(opt *ListBroadcastMessagesOptions, options ...RequestOptionFunc) ([]*BroadcastMessage, *Response, error) + GetBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) + CreateBroadcastMessage(opt *CreateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) + UpdateBroadcastMessage(broadcast int, opt *UpdateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) + DeleteBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*Response, error) + } + + // BroadcastMessagesService handles communication with the broadcast + // messages methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/broadcast_messages/ + BroadcastMessagesService struct { + client *Client + } +) + +var _ BroadcastMessagesServiceInterface = (*BroadcastMessagesService)(nil) + +// BroadcastMessage represents a GitLab broadcast message. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#get-all-broadcast-messages +type BroadcastMessage struct { + Message string `json:"message"` + StartsAt *time.Time `json:"starts_at"` + EndsAt *time.Time `json:"ends_at"` + Font string `json:"font"` + ID int `json:"id"` + Active bool `json:"active"` + TargetAccessLevels []AccessLevelValue `json:"target_access_levels"` + TargetPath string `json:"target_path"` + BroadcastType string `json:"broadcast_type"` + Dismissable bool `json:"dismissable"` + Theme string `json:"theme"` +} + +// ListBroadcastMessagesOptions represents the available ListBroadcastMessages() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#get-all-broadcast-messages +type ListBroadcastMessagesOptions ListOptions + +// ListBroadcastMessages gets a list of all broadcasted messages. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#get-all-broadcast-messages +func (s *BroadcastMessagesService) ListBroadcastMessages(opt *ListBroadcastMessagesOptions, options ...RequestOptionFunc) ([]*BroadcastMessage, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "broadcast_messages", opt, options) + if err != nil { + return nil, nil, err + } + + var bs []*BroadcastMessage + resp, err := s.client.Do(req, &bs) + if err != nil { + return nil, resp, err + } + + return bs, resp, nil +} + +// GetBroadcastMessage gets a single broadcast message. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#get-a-specific-broadcast-message +func (s *BroadcastMessagesService) GetBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { + u := fmt.Sprintf("broadcast_messages/%d", broadcast) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + b := new(BroadcastMessage) + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// CreateBroadcastMessageOptions represents the available CreateBroadcastMessage() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#create-a-broadcast-message +type CreateBroadcastMessageOptions struct { + Message *string `url:"message" json:"message"` + StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"` + EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"` + Font *string `url:"font,omitempty" json:"font,omitempty"` + TargetAccessLevels []AccessLevelValue `url:"target_access_levels,omitempty" json:"target_access_levels,omitempty"` + TargetPath *string `url:"target_path,omitempty" json:"target_path,omitempty"` + BroadcastType *string `url:"broadcast_type,omitempty" json:"broadcast_type,omitempty"` + Dismissable *bool `url:"dismissable,omitempty" json:"dismissable,omitempty"` + Theme *string `url:"theme,omitempty" json:"theme,omitempty"` +} + +// CreateBroadcastMessage creates a message to broadcast. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#create-a-broadcast-message +func (s *BroadcastMessagesService) CreateBroadcastMessage(opt *CreateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "broadcast_messages", opt, options) + if err != nil { + return nil, nil, err + } + + b := new(BroadcastMessage) + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// UpdateBroadcastMessageOptions represents the available CreateBroadcastMessage() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#update-a-broadcast-message +type UpdateBroadcastMessageOptions struct { + Message *string `url:"message,omitempty" json:"message,omitempty"` + StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"` + EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"` + Font *string `url:"font,omitempty" json:"font,omitempty"` + TargetAccessLevels []AccessLevelValue `url:"target_access_levels,omitempty" json:"target_access_levels,omitempty"` + TargetPath *string `url:"target_path,omitempty" json:"target_path,omitempty"` + BroadcastType *string `url:"broadcast_type,omitempty" json:"broadcast_type,omitempty"` + Dismissable *bool `url:"dismissable,omitempty" json:"dismissable,omitempty"` + Theme *string `url:"theme,omitempty" json:"theme,omitempty"` +} + +// UpdateBroadcastMessage update a broadcasted message. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#update-a-broadcast-message +func (s *BroadcastMessagesService) UpdateBroadcastMessage(broadcast int, opt *UpdateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) { + u := fmt.Sprintf("broadcast_messages/%d", broadcast) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + b := new(BroadcastMessage) + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b, resp, nil +} + +// DeleteBroadcastMessage deletes a broadcasted message. +// +// GitLab API docs: +// https://docs.gitlab.com/api/broadcast_messages/#delete-a-broadcast-message +func (s *BroadcastMessagesService) DeleteBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("broadcast_messages/%d", broadcast) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/bulk_imports.go b/vendor/gitlab.com/gitlab-org/api/client-go/bulk_imports.go new file mode 100644 index 000000000..70464498e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/bulk_imports.go @@ -0,0 +1,80 @@ +package gitlab + +import ( + "net/http" + "time" +) + +type ( + BulkImportsServiceInterface interface { + StartMigration(startMigrationOptions *BulkImportStartMigrationOptions, options ...RequestOptionFunc) (*BulkImportStartMigrationResponse, *Response, error) + } + + // BulkImportsService handles communication with GitLab's direct transfer API. + // + // GitLab API docs: https://docs.gitlab.com/api/bulk_imports/ + BulkImportsService struct { + client *Client + } +) + +var _ BulkImportsServiceInterface = (*BulkImportsService)(nil) + +// BulkImportStartMigrationConfiguration represents the available configuration options to start a migration. +// +// GitLab API docs: https://docs.gitlab.com/api/bulk_imports/#start-a-new-group-or-project-migration +type BulkImportStartMigrationConfiguration struct { + URL *string `json:"url,omitempty"` + AccessToken *string `json:"access_token,omitempty"` +} + +// BulkImportStartMigrationEntity represents the available entity options to start a migration. +// +// GitLab API docs: https://docs.gitlab.com/api/bulk_imports/#start-a-new-group-or-project-migration +type BulkImportStartMigrationEntity struct { + SourceType *string `json:"source_type,omitempty"` + SourceFullPath *string `json:"source_full_path,omitempty"` + DestinationSlug *string `json:"destination_slug,omitempty"` + DestinationNamespace *string `json:"destination_namespace,omitempty"` + MigrateProjects *bool `json:"migrate_projects,omitempty"` + MigrateMemberships *bool `json:"migrate_memberships,omitempty"` +} + +// BulkImportStartMigrationOptions represents the available start migration options. +// +// GitLab API docs: https://docs.gitlab.com/api/bulk_imports/#start-a-new-group-or-project-migration +type BulkImportStartMigrationOptions struct { + Configuration *BulkImportStartMigrationConfiguration `json:"configuration,omitempty"` + Entities []BulkImportStartMigrationEntity `json:"entities,omitempty"` +} + +// BulkImportStartMigrationResponse represents the start migration response. +// +// GitLab API docs: https://docs.gitlab.com/api/bulk_imports/#start-a-new-group-or-project-migration +type BulkImportStartMigrationResponse struct { + ID int `json:"id"` + Status string `json:"status"` + SourceType string `json:"source_type"` + SourceURL string `json:"source_url"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + HasFailures bool `json:"has_failures"` +} + +// StartMigration starts a migration. +// +// GitLab API docs: https://docs.gitlab.com/api/bulk_imports/#start-a-new-group-or-project-migration +func (b *BulkImportsService) StartMigration(startMigrationOptions *BulkImportStartMigrationOptions, options ...RequestOptionFunc) (*BulkImportStartMigrationResponse, *Response, error) { + request, err := b.client.NewRequest(http.MethodPost, "bulk_imports", startMigrationOptions, options) + if err != nil { + return nil, nil, err + } + + startMigrationResponse := new(BulkImportStartMigrationResponse) + response, err := b.client.Do(request, startMigrationResponse) + if err != nil { + return nil, response, err + } + + return startMigrationResponse, response, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/ci_yml_templates.go b/vendor/gitlab.com/gitlab-org/api/client-go/ci_yml_templates.go new file mode 100644 index 000000000..168ca1fc4 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/ci_yml_templates.go @@ -0,0 +1,104 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + CIYMLTemplatesServiceInterface interface { + ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplateListItem, *Response, error) + GetTemplate(key string, options ...RequestOptionFunc) (*CIYMLTemplate, *Response, error) + } + + // CIYMLTemplatesService handles communication with the gitlab + // CI YML templates related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/templates/gitlab_ci_ymls/ + CIYMLTemplatesService struct { + client *Client + } +) + +var _ CIYMLTemplatesServiceInterface = (*CIYMLTemplatesService)(nil) + +// CIYMLTemplate represents a GitLab CI YML template. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/gitlab_ci_ymls/ +type CIYMLTemplate struct { + Name string `json:"name"` + Content string `json:"content"` +} + +// CIYMLTemplateListItem represents a GitLab CI YML template from the list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/gitlab_ci_ymls/ +type CIYMLTemplateListItem struct { + Key string `json:"key"` + Name string `json:"name"` +} + +// ListCIYMLTemplatesOptions represents the available ListAllTemplates() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/gitlab_ci_ymls/#list-gitlab-ci-yaml-templates +type ListCIYMLTemplatesOptions ListOptions + +// ListAllTemplates get all GitLab CI YML templates. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/gitlab_ci_ymls/#list-gitlab-ci-yaml-templates +func (s *CIYMLTemplatesService) ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplateListItem, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "templates/gitlab_ci_ymls", opt, options) + if err != nil { + return nil, nil, err + } + + var cts []*CIYMLTemplateListItem + resp, err := s.client.Do(req, &cts) + if err != nil { + return nil, resp, err + } + + return cts, resp, nil +} + +// GetTemplate get a single GitLab CI YML template. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/gitlab_ci_ymls/#single-gitlab-ci-yaml-template +func (s *CIYMLTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*CIYMLTemplate, *Response, error) { + u := fmt.Sprintf("templates/gitlab_ci_ymls/%s", PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ct := new(CIYMLTemplate) + resp, err := s.client.Do(req, ct) + if err != nil { + return nil, resp, err + } + + return ct, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/client_options.go b/vendor/gitlab.com/gitlab-org/api/client-go/client_options.go new file mode 100644 index 000000000..2ff7bab9b --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/client_options.go @@ -0,0 +1,142 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "net/http" + "time" + + retryablehttp "github.com/hashicorp/go-retryablehttp" +) + +// ClientOptionFunc can be used to customize a new GitLab API client. +type ClientOptionFunc func(*Client) error + +// WithBaseURL sets the base URL for API requests to a custom endpoint. +func WithBaseURL(urlStr string) ClientOptionFunc { + return func(c *Client) error { + return c.setBaseURL(urlStr) + } +} + +// WithCustomBackoff can be used to configure a custom backoff policy. +func WithCustomBackoff(backoff retryablehttp.Backoff) ClientOptionFunc { + return func(c *Client) error { + c.client.Backoff = backoff + return nil + } +} + +// WithCustomLeveledLogger can be used to configure a custom retryablehttp +// leveled logger. +func WithCustomLeveledLogger(leveledLogger retryablehttp.LeveledLogger) ClientOptionFunc { + return func(c *Client) error { + c.client.Logger = leveledLogger + return nil + } +} + +// WithCustomLimiter injects a custom rate limiter to the client. +func WithCustomLimiter(limiter RateLimiter) ClientOptionFunc { + return func(c *Client) error { + c.configureLimiterOnce.Do(func() {}) + c.limiter = limiter + return nil + } +} + +// WithCustomLogger can be used to configure a custom retryablehttp logger. +func WithCustomLogger(logger retryablehttp.Logger) ClientOptionFunc { + return func(c *Client) error { + c.client.Logger = logger + return nil + } +} + +// WithCustomRetry can be used to configure a custom retry policy. +func WithCustomRetry(checkRetry retryablehttp.CheckRetry) ClientOptionFunc { + return func(c *Client) error { + c.client.CheckRetry = checkRetry + return nil + } +} + +// WithCustomRetryMax can be used to configure a custom maximum number of retries. +func WithCustomRetryMax(retryMax int) ClientOptionFunc { + return func(c *Client) error { + c.client.RetryMax = retryMax + return nil + } +} + +// WithCustomRetryWaitMinMax can be used to configure a custom minimum and +// maximum time to wait between retries. +func WithCustomRetryWaitMinMax(waitMin, waitMax time.Duration) ClientOptionFunc { + return func(c *Client) error { + c.client.RetryWaitMin = waitMin + c.client.RetryWaitMax = waitMax + return nil + } +} + +// WithErrorHandler can be used to configure a custom error handler. +func WithErrorHandler(handler retryablehttp.ErrorHandler) ClientOptionFunc { + return func(c *Client) error { + c.client.ErrorHandler = handler + return nil + } +} + +// WithHTTPClient can be used to configure a custom HTTP client. +func WithHTTPClient(httpClient *http.Client) ClientOptionFunc { + return func(c *Client) error { + c.client.HTTPClient = httpClient + return nil + } +} + +// WithRequestLogHook can be used to configure a custom request log hook. +func WithRequestLogHook(hook retryablehttp.RequestLogHook) ClientOptionFunc { + return func(c *Client) error { + c.client.RequestLogHook = hook + return nil + } +} + +// WithResponseLogHook can be used to configure a custom response log hook. +func WithResponseLogHook(hook retryablehttp.ResponseLogHook) ClientOptionFunc { + return func(c *Client) error { + c.client.ResponseLogHook = hook + return nil + } +} + +// WithoutRetries disables the default retry logic. +func WithoutRetries() ClientOptionFunc { + return func(c *Client) error { + c.disableRetries = true + return nil + } +} + +// WithRequestOptions can be used to configure default request options applied to every request. +func WithRequestOptions(options ...RequestOptionFunc) ClientOptionFunc { + return func(c *Client) error { + c.defaultRequestOptions = append(c.defaultRequestOptions, options...) + return nil + } +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/cluster_agents.go b/vendor/gitlab.com/gitlab-org/api/client-go/cluster_agents.go new file mode 100644 index 000000000..88855174d --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/cluster_agents.go @@ -0,0 +1,309 @@ +// +// Copyright 2022, Timo Furrer +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ClusterAgentsServiceInterface interface { + ListAgents(pid any, opt *ListAgentsOptions, options ...RequestOptionFunc) ([]*Agent, *Response, error) + GetAgent(pid any, id int, options ...RequestOptionFunc) (*Agent, *Response, error) + RegisterAgent(pid any, opt *RegisterAgentOptions, options ...RequestOptionFunc) (*Agent, *Response, error) + DeleteAgent(pid any, id int, options ...RequestOptionFunc) (*Response, error) + ListAgentTokens(pid any, aid int, opt *ListAgentTokensOptions, options ...RequestOptionFunc) ([]*AgentToken, *Response, error) + GetAgentToken(pid any, aid int, id int, options ...RequestOptionFunc) (*AgentToken, *Response, error) + CreateAgentToken(pid any, aid int, opt *CreateAgentTokenOptions, options ...RequestOptionFunc) (*AgentToken, *Response, error) + RevokeAgentToken(pid any, aid int, id int, options ...RequestOptionFunc) (*Response, error) + } + + // ClusterAgentsService handles communication with the cluster agents related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/cluster_agents/ + ClusterAgentsService struct { + client *Client + } +) + +var _ ClusterAgentsServiceInterface = (*ClusterAgentsService)(nil) + +// Agent represents a GitLab agent for Kubernetes. +// +// GitLab API docs: https://docs.gitlab.com/api/cluster_agents/ +type Agent struct { + ID int `json:"id"` + Name string `json:"name"` + CreatedAt *time.Time `json:"created_at"` + CreatedByUserID int `json:"created_by_user_id"` + ConfigProject ConfigProject `json:"config_project"` +} + +type ConfigProject struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreatedAt *time.Time `json:"created_at"` +} + +func (a Agent) String() string { + return Stringify(a) +} + +// AgentToken represents a GitLab agent token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#list-tokens-for-an-agent +type AgentToken struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AgentID int `json:"agent_id"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + CreatedByUserID int `json:"created_by_user_id"` + LastUsedAt *time.Time `json:"last_used_at"` + Token string `json:"token"` +} + +func (a AgentToken) String() string { + return Stringify(a) +} + +// ListAgentsOptions represents the available ListAgents() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#list-the-agents-for-a-project +type ListAgentsOptions ListOptions + +// ListAgents returns a list of agents registered for the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#list-the-agents-for-a-project +func (s *ClusterAgentsService) ListAgents(pid any, opt *ListAgentsOptions, options ...RequestOptionFunc) ([]*Agent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, uri, opt, options) + if err != nil { + return nil, nil, err + } + + var as []*Agent + resp, err := s.client.Do(req, &as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} + +// GetAgent gets a single agent details. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#get-details-about-an-agent +func (s *ClusterAgentsService) GetAgent(pid any, id int, options ...RequestOptionFunc) (*Agent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodGet, uri, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(Agent) + resp, err := s.client.Do(req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// RegisterAgentOptions represents the available RegisterAgent() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#register-an-agent-with-a-project +type RegisterAgentOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// RegisterAgent registers an agent to the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#register-an-agent-with-a-project +func (s *ClusterAgentsService) RegisterAgent(pid any, opt *RegisterAgentOptions, options ...RequestOptionFunc) (*Agent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, uri, opt, options) + if err != nil { + return nil, nil, err + } + + a := new(Agent) + resp, err := s.client.Do(req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// DeleteAgent deletes an existing agent registration. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#delete-a-registered-agent +func (s *ClusterAgentsService) DeleteAgent(pid any, id int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodDelete, uri, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListAgentTokensOptions represents the available ListAgentTokens() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#list-tokens-for-an-agent +type ListAgentTokensOptions ListOptions + +// ListAgentTokens returns a list of tokens for an agent. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#list-tokens-for-an-agent +func (s *ClusterAgentsService) ListAgentTokens(pid any, aid int, opt *ListAgentTokensOptions, options ...RequestOptionFunc) ([]*AgentToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d/tokens", PathEscape(project), aid) + + req, err := s.client.NewRequest(http.MethodGet, uri, opt, options) + if err != nil { + return nil, nil, err + } + + var ats []*AgentToken + resp, err := s.client.Do(req, &ats) + if err != nil { + return nil, resp, err + } + + return ats, resp, nil +} + +// GetAgentToken gets a single agent token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#get-a-single-agent-token +func (s *ClusterAgentsService) GetAgentToken(pid any, aid int, id int, options ...RequestOptionFunc) (*AgentToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d/tokens/%d", PathEscape(project), aid, id) + + req, err := s.client.NewRequest(http.MethodGet, uri, nil, options) + if err != nil { + return nil, nil, err + } + + at := new(AgentToken) + resp, err := s.client.Do(req, at) + if err != nil { + return nil, resp, err + } + + return at, resp, nil +} + +// CreateAgentTokenOptions represents the available CreateAgentToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#create-an-agent-token +type CreateAgentTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// CreateAgentToken creates a new token for an agent. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#create-an-agent-token +func (s *ClusterAgentsService) CreateAgentToken(pid any, aid int, opt *CreateAgentTokenOptions, options ...RequestOptionFunc) (*AgentToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d/tokens", PathEscape(project), aid) + + req, err := s.client.NewRequest(http.MethodPost, uri, opt, options) + if err != nil { + return nil, nil, err + } + + at := new(AgentToken) + resp, err := s.client.Do(req, at) + if err != nil { + return nil, resp, err + } + + return at, resp, nil +} + +// RevokeAgentToken revokes an agent token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/cluster_agents/#revoke-an-agent-token +func (s *ClusterAgentsService) RevokeAgentToken(pid any, aid int, id int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + uri := fmt.Sprintf("projects/%s/cluster_agents/%d/tokens/%d", PathEscape(project), aid, id) + + req, err := s.client.NewRequest(http.MethodDelete, uri, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/commits.go b/vendor/gitlab.com/gitlab-org/api/client-go/commits.go new file mode 100644 index 000000000..d73031f05 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/commits.go @@ -0,0 +1,634 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" + "time" +) + +// CommitsService handles communication with the commit related methods +// of the GitLab API. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/ +type ( + CommitsServiceInterface interface { + ListCommits(pid any, opt *ListCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) + GetCommitRefs(pid any, sha string, opt *GetCommitRefsOptions, options ...RequestOptionFunc) ([]*CommitRef, *Response, error) + GetCommit(pid any, sha string, opt *GetCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) + CreateCommit(pid any, opt *CreateCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) + GetCommitDiff(pid any, sha string, opt *GetCommitDiffOptions, options ...RequestOptionFunc) ([]*Diff, *Response, error) + GetCommitComments(pid any, sha string, opt *GetCommitCommentsOptions, options ...RequestOptionFunc) ([]*CommitComment, *Response, error) + PostCommitComment(pid any, sha string, opt *PostCommitCommentOptions, options ...RequestOptionFunc) (*CommitComment, *Response, error) + GetCommitStatuses(pid any, sha string, opt *GetCommitStatusesOptions, options ...RequestOptionFunc) ([]*CommitStatus, *Response, error) + SetCommitStatus(pid any, sha string, opt *SetCommitStatusOptions, options ...RequestOptionFunc) (*CommitStatus, *Response, error) + ListMergeRequestsByCommit(pid any, sha string, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + CherryPickCommit(pid any, sha string, opt *CherryPickCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) + RevertCommit(pid any, sha string, opt *RevertCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) + GetGPGSignature(pid any, sha string, options ...RequestOptionFunc) (*GPGSignature, *Response, error) + } + + // CommitsService handles communication with the commit related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/commits/ + CommitsService struct { + client *Client + } +) + +var _ CommitsServiceInterface = (*CommitsService)(nil) + +// Commit represents a GitLab commit. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/ +type Commit struct { + ID string `json:"id"` + ShortID string `json:"short_id"` + Title string `json:"title"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthoredDate *time.Time `json:"authored_date"` + CommitterName string `json:"committer_name"` + CommitterEmail string `json:"committer_email"` + CommittedDate *time.Time `json:"committed_date"` + CreatedAt *time.Time `json:"created_at"` + Message string `json:"message"` + ParentIDs []string `json:"parent_ids"` + Stats *CommitStats `json:"stats"` + Status *BuildStateValue `json:"status"` + LastPipeline *PipelineInfo `json:"last_pipeline"` + ProjectID int `json:"project_id"` + Trailers map[string]string `json:"trailers"` + ExtendedTrailers map[string]string `json:"extended_trailers"` + WebURL string `json:"web_url"` +} + +// CommitStats represents the number of added and deleted files in a commit. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/ +type CommitStats struct { + Additions int `json:"additions"` + Deletions int `json:"deletions"` + Total int `json:"total"` +} + +func (c Commit) String() string { + return Stringify(c) +} + +// ListCommitsOptions represents the available ListCommits() options. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#list-repository-commits +type ListCommitsOptions struct { + ListOptions + RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"` + Since *time.Time `url:"since,omitempty" json:"since,omitempty"` + Until *time.Time `url:"until,omitempty" json:"until,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Author *string `url:"author,omitempty" json:"author,omitempty"` + All *bool `url:"all,omitempty" json:"all,omitempty"` + WithStats *bool `url:"with_stats,omitempty" json:"with_stats,omitempty"` + FirstParent *bool `url:"first_parent,omitempty" json:"first_parent,omitempty"` + Trailers *bool `url:"trailers,omitempty" json:"trailers,omitempty"` +} + +// ListCommits gets a list of repository commits in a project. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#list-repository-commits +func (s *CommitsService) ListCommits(pid any, opt *ListCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var c []*Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// CommitRef represents the reference of branches/tags in a commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-references-a-commit-is-pushed-to +type CommitRef struct { + Type string `json:"type"` + Name string `json:"name"` +} + +// GetCommitRefsOptions represents the available GetCommitRefs() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-references-a-commit-is-pushed-to +type GetCommitRefsOptions struct { + ListOptions + Type *string `url:"type,omitempty" json:"type,omitempty"` +} + +// GetCommitRefs gets all references (from branches or tags) a commit is pushed to +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-references-a-commit-is-pushed-to +func (s *CommitsService) GetCommitRefs(pid any, sha string, opt *GetCommitRefsOptions, options ...RequestOptionFunc) ([]*CommitRef, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/refs", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var cs []*CommitRef + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// GetCommitOptions represents the available GetCommit() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-a-single-commit +type GetCommitOptions struct { + Stats *bool `url:"stats,omitempty" json:"stats,omitempty"` +} + +// GetCommit gets a specific commit identified by the commit hash or name of a +// branch or tag. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#get-a-single-commit +func (s *CommitsService) GetCommit(pid any, sha string, opt *GetCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + if sha == "" { + return nil, nil, fmt.Errorf("SHA must be a non-empty string") + } + u := fmt.Sprintf("projects/%s/repository/commits/%s", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// CreateCommitOptions represents the available options for a new commit. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#create-a-commit-with-multiple-files-and-actions +type CreateCommitOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` + StartSHA *string `url:"start_sha,omitempty" json:"start_sha,omitempty"` + StartProject *string `url:"start_project,omitempty" json:"start_project,omitempty"` + Actions []*CommitActionOptions `url:"actions" json:"actions"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + Stats *bool `url:"stats,omitempty" json:"stats,omitempty"` + Force *bool `url:"force,omitempty" json:"force,omitempty"` +} + +// CommitActionOptions represents the available options for a new single +// file action. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#create-a-commit-with-multiple-files-and-actions +type CommitActionOptions struct { + Action *FileActionValue `url:"action,omitempty" json:"action,omitempty"` + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + PreviousPath *string `url:"previous_path,omitempty" json:"previous_path,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` + LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` + ExecuteFilemode *bool `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"` +} + +// CreateCommit creates a commit with multiple files and actions. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#create-a-commit-with-multiple-files-and-actions +func (s *CommitsService) CreateCommit(pid any, opt *CreateCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// Diff represents a GitLab diff. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/ +type Diff struct { + Diff string `json:"diff"` + NewPath string `json:"new_path"` + OldPath string `json:"old_path"` + AMode string `json:"a_mode"` + BMode string `json:"b_mode"` + NewFile bool `json:"new_file"` + RenamedFile bool `json:"renamed_file"` + DeletedFile bool `json:"deleted_file"` +} + +func (d Diff) String() string { + return Stringify(d) +} + +// GetCommitDiffOptions represents the available GetCommitDiff() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-the-diff-of-a-commit +type GetCommitDiffOptions struct { + ListOptions + Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` +} + +// GetCommitDiff gets the diff of a commit in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-the-diff-of-a-commit +func (s *CommitsService) GetCommitDiff(pid any, sha string, opt *GetCommitDiffOptions, options ...RequestOptionFunc) ([]*Diff, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var d []*Diff + resp, err := s.client.Do(req, &d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CommitComment represents a GitLab commit comment. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/ +type CommitComment struct { + Note string `json:"note"` + Path string `json:"path"` + Line int `json:"line"` + LineType string `json:"line_type"` + Author Author `json:"author"` +} + +// Author represents a GitLab commit author +type Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + Blocked bool `json:"blocked"` + CreatedAt *time.Time `json:"created_at"` +} + +func (c CommitComment) String() string { + return Stringify(c) +} + +// GetCommitCommentsOptions represents the available GetCommitComments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-the-comments-of-a-commit +type GetCommitCommentsOptions ListOptions + +// GetCommitComments gets the comments of a commit in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-the-comments-of-a-commit +func (s *CommitsService) GetCommitComments(pid any, sha string, opt *GetCommitCommentsOptions, options ...RequestOptionFunc) ([]*CommitComment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var c []*CommitComment + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// PostCommitCommentOptions represents the available PostCommitComment() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#post-comment-to-commit +type PostCommitCommentOptions struct { + Note *string `url:"note,omitempty" json:"note,omitempty"` + Path *string `url:"path" json:"path"` + Line *int `url:"line" json:"line"` + LineType *string `url:"line_type" json:"line_type"` +} + +// PostCommitComment adds a comment to a commit. Optionally you can post +// comments on a specific line of a commit. Therefor both path, line_new and +// line_old are required. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#post-comment-to-commit +func (s *CommitsService) PostCommitComment(pid any, sha string, opt *PostCommitCommentOptions, options ...RequestOptionFunc) (*CommitComment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(CommitComment) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// GetCommitStatusesOptions represents the available GetCommitStatuses() options. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#list-the-statuses-of-a-commit +type GetCommitStatusesOptions struct { + ListOptions + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Stage *string `url:"stage,omitempty" json:"stage,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + All *bool `url:"all,omitempty" json:"all,omitempty"` +} + +// CommitStatus represents a GitLab commit status. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#commit-status +type CommitStatus struct { + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + Name string `json:"name"` + AllowFailure bool `json:"allow_failure"` + Coverage float64 `json:"coverage"` + PipelineId int `json:"pipeline_id"` + Author Author `json:"author"` + Description string `json:"description"` + TargetURL string `json:"target_url"` +} + +// GetCommitStatuses gets the statuses of a commit in a project. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#list-the-statuses-of-a-commit +func (s *CommitsService) GetCommitStatuses(pid any, sha string, opt *GetCommitStatusesOptions, options ...RequestOptionFunc) ([]*CommitStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var cs []*CommitStatus + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// SetCommitStatusOptions represents the available SetCommitStatus() options. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#set-the-pipeline-status-of-a-commit +type SetCommitStatusOptions struct { + State BuildStateValue `url:"state" json:"state"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Context *string `url:"context,omitempty" json:"context,omitempty"` + TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Coverage *float64 `url:"coverage,omitempty" json:"coverage,omitempty"` + PipelineID *int `url:"pipeline_id,omitempty" json:"pipeline_id,omitempty"` +} + +// SetCommitStatus sets the status of a commit in a project. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#set-the-pipeline-status-of-a-commit +func (s *CommitsService) SetCommitStatus(pid any, sha string, opt *SetCommitStatusOptions, options ...RequestOptionFunc) (*CommitStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/statuses/%s", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + cs := new(CommitStatus) + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// ListMergeRequestsByCommit gets merge request associated with a commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#list-merge-requests-associated-with-a-commit +func (s *CommitsService) ListMergeRequestsByCommit(pid any, sha string, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/merge_requests", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var mrs []*BasicMergeRequest + resp, err := s.client.Do(req, &mrs) + if err != nil { + return nil, resp, err + } + + return mrs, resp, nil +} + +// CherryPickCommitOptions represents the available CherryPickCommit() options. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#cherry-pick-a-commit +type CherryPickCommitOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"` + Message *string `url:"message,omitempty" json:"message,omitempty"` +} + +// CherryPickCommit cherry picks a commit to a given branch. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#cherry-pick-a-commit +func (s *CommitsService) CherryPickCommit(pid any, sha string, opt *CherryPickCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// RevertCommitOptions represents the available RevertCommit() options. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#revert-a-commit +type RevertCommitOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` +} + +// RevertCommit reverts a commit in a given branch. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#revert-a-commit +func (s *CommitsService) RevertCommit(pid any, sha string, opt *RevertCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/revert", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// GPGSignature represents a Gitlab commit's GPG Signature. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#get-signature-of-a-commit +type GPGSignature struct { + KeyID int `json:"gpg_key_id"` + KeyPrimaryKeyID string `json:"gpg_key_primary_keyid"` + KeyUserName string `json:"gpg_key_user_name"` + KeyUserEmail string `json:"gpg_key_user_email"` + VerificationStatus string `json:"verification_status"` + KeySubkeyID int `json:"gpg_key_subkey_id"` +} + +// GetGPGSignature gets a GPG signature of a commit. +// +// GitLab API docs: https://docs.gitlab.com/api/commits/#get-signature-of-a-commit +func (s *CommitsService) GetGPGSignature(pid any, sha string, options ...RequestOptionFunc) (*GPGSignature, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/signature", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + sig := new(GPGSignature) + resp, err := s.client.Do(req, &sig) + if err != nil { + return nil, resp, err + } + + return sig, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/container_registry.go b/vendor/gitlab.com/gitlab-org/api/client-go/container_registry.go new file mode 100644 index 000000000..4e473ee0e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/container_registry.go @@ -0,0 +1,326 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ContainerRegistryServiceInterface interface { + ListProjectRegistryRepositories(pid any, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) + ListGroupRegistryRepositories(gid any, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) + GetSingleRegistryRepository(pid any, opt *GetSingleRegistryRepositoryOptions, options ...RequestOptionFunc) (*RegistryRepository, *Response, error) + DeleteRegistryRepository(pid any, repository int, options ...RequestOptionFunc) (*Response, error) + ListRegistryRepositoryTags(pid any, repository int, opt *ListRegistryRepositoryTagsOptions, options ...RequestOptionFunc) ([]*RegistryRepositoryTag, *Response, error) + GetRegistryRepositoryTagDetail(pid any, repository int, tagName string, options ...RequestOptionFunc) (*RegistryRepositoryTag, *Response, error) + DeleteRegistryRepositoryTag(pid any, repository int, tagName string, options ...RequestOptionFunc) (*Response, error) + DeleteRegistryRepositoryTags(pid any, repository int, opt *DeleteRegistryRepositoryTagsOptions, options ...RequestOptionFunc) (*Response, error) + } + + // ContainerRegistryService handles communication with the container registry + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/container_registry/ + ContainerRegistryService struct { + client *Client + } +) + +var _ ContainerRegistryServiceInterface = (*ContainerRegistryService)(nil) + +// RegistryRepository represents a GitLab content registry repository. +// +// GitLab API docs: https://docs.gitlab.com/api/container_registry/ +type RegistryRepository struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + ProjectID int `json:"project_id"` + Location string `json:"location"` + CreatedAt *time.Time `json:"created_at"` + CleanupPolicyStartedAt *time.Time `json:"cleanup_policy_started_at"` + Status *ContainerRegistryStatus `json:"status"` + TagsCount int `json:"tags_count"` + Tags []*RegistryRepositoryTag `json:"tags"` +} + +func (s RegistryRepository) String() string { + return Stringify(s) +} + +// RegistryRepositoryTag represents a GitLab registry image tag. +// +// GitLab API docs: https://docs.gitlab.com/api/container_registry/ +type RegistryRepositoryTag struct { + Name string `json:"name"` + Path string `json:"path"` + Location string `json:"location"` + Revision string `json:"revision"` + ShortRevision string `json:"short_revision"` + Digest string `json:"digest"` + CreatedAt *time.Time `json:"created_at"` + TotalSize int `json:"total_size"` +} + +func (s RegistryRepositoryTag) String() string { + return Stringify(s) +} + +// ListRegistryRepositoriesOptions represents the available +// ListRegistryRepositories() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#list-registry-repositories +type ListRegistryRepositoriesOptions struct { + ListOptions + + // Deprecated: These options are deprecated for ListGroupRegistryRepositories calls. (Removed in GitLab 15.0) + Tags *bool `url:"tags,omitempty" json:"tags,omitempty"` + TagsCount *bool `url:"tags_count,omitempty" json:"tags_count,omitempty"` +} + +// ListProjectRegistryRepositories gets a list of registry repositories in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#within-a-project +func (s *ContainerRegistryService) ListProjectRegistryRepositories(pid any, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var repos []*RegistryRepository + resp, err := s.client.Do(req, &repos) + if err != nil { + return nil, resp, err + } + + return repos, resp, nil +} + +// ListGroupRegistryRepositories gets a list of registry repositories in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#within-a-group +func (s *ContainerRegistryService) ListGroupRegistryRepositories(gid any, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/registry/repositories", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var repos []*RegistryRepository + resp, err := s.client.Do(req, &repos) + if err != nil { + return nil, resp, err + } + + return repos, resp, nil +} + +// GetSingleRegistryRepositoryOptions represents the available +// GetSingleRegistryRepository() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#get-details-of-a-single-repository +type GetSingleRegistryRepositoryOptions struct { + Tags *bool `url:"tags,omitempty" json:"tags,omitempty"` + TagsCount *bool `url:"tags_count,omitempty" json:"tags_count,omitempty"` +} + +// GetSingleRegistryRepository gets the details of single registry repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#get-details-of-a-single-repository +func (s *ContainerRegistryService) GetSingleRegistryRepository(pid any, opt *GetSingleRegistryRepositoryOptions, options ...RequestOptionFunc) (*RegistryRepository, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("registry/repositories/%s", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + repo := new(RegistryRepository) + resp, err := s.client.Do(req, repo) + if err != nil { + return nil, resp, err + } + + return repo, resp, nil +} + +// DeleteRegistryRepository deletes a repository in a registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#delete-registry-repository +func (s *ContainerRegistryService) DeleteRegistryRepository(pid any, repository int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories/%d", PathEscape(project), repository) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListRegistryRepositoryTagsOptions represents the available +// ListRegistryRepositoryTags() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#list-registry-repository-tags +type ListRegistryRepositoryTagsOptions ListOptions + +// ListRegistryRepositoryTags gets a list of tags for given registry repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#list-registry-repository-tags +func (s *ContainerRegistryService) ListRegistryRepositoryTags(pid any, repository int, opt *ListRegistryRepositoryTagsOptions, options ...RequestOptionFunc) ([]*RegistryRepositoryTag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags", + PathEscape(project), + repository, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var tags []*RegistryRepositoryTag + resp, err := s.client.Do(req, &tags) + if err != nil { + return nil, resp, err + } + + return tags, resp, nil +} + +// GetRegistryRepositoryTagDetail get details of a registry repository tag +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#get-details-of-a-registry-repository-tag +func (s *ContainerRegistryService) GetRegistryRepositoryTagDetail(pid any, repository int, tagName string, options ...RequestOptionFunc) (*RegistryRepositoryTag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s", + PathEscape(project), + repository, + tagName, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + tag := new(RegistryRepositoryTag) + resp, err := s.client.Do(req, &tag) + if err != nil { + return nil, resp, err + } + + return tag, resp, nil +} + +// DeleteRegistryRepositoryTag deletes a registry repository tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#delete-a-registry-repository-tag +func (s *ContainerRegistryService) DeleteRegistryRepositoryTag(pid any, repository int, tagName string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s", + PathEscape(project), + repository, + tagName, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteRegistryRepositoryTagsOptions represents the available +// DeleteRegistryRepositoryTags() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#delete-registry-repository-tags-in-bulk +type DeleteRegistryRepositoryTagsOptions struct { + NameRegexpDelete *string `url:"name_regex_delete,omitempty" json:"name_regex_delete,omitempty"` + NameRegexpKeep *string `url:"name_regex_keep,omitempty" json:"name_regex_keep,omitempty"` + KeepN *int `url:"keep_n,omitempty" json:"keep_n,omitempty"` + OlderThan *string `url:"older_than,omitempty" json:"older_than,omitempty"` + + // Deprecated: NameRegexp is deprecated in favor of NameRegexpDelete. + NameRegexp *string `url:"name_regex,omitempty" json:"name_regex,omitempty"` +} + +// DeleteRegistryRepositoryTags deletes repository tags in bulk based on +// given criteria. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#delete-registry-repository-tags-in-bulk +func (s *ContainerRegistryService) DeleteRegistryRepositoryTags(pid any, repository int, opt *DeleteRegistryRepositoryTagsOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags", + PathEscape(project), + repository, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/container_registry_protection_rules.go b/vendor/gitlab.com/gitlab-org/api/client-go/container_registry_protection_rules.go new file mode 100644 index 000000000..5871f3983 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/container_registry_protection_rules.go @@ -0,0 +1,178 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ContainerRegistryProtectionRulesServiceInterface interface { + ListContainerRegistryProtectionRules(pid any, options ...RequestOptionFunc) ([]*ContainerRegistryProtectionRule, *Response, error) + CreateContainerRegistryProtectionRule(pid any, opt *CreateContainerRegistryProtectionRuleOptions, options ...RequestOptionFunc) (*ContainerRegistryProtectionRule, *Response, error) + UpdateContainerRegistryProtectionRule(pid any, ruleID int, opt *UpdateContainerRegistryProtectionRuleOptions, options ...RequestOptionFunc) (*ContainerRegistryProtectionRule, *Response, error) + DeleteContainerRegistryProtectionRule(pid any, ruleID int, options ...RequestOptionFunc) (*Response, error) + } + + // ContainerRegistryProtectionRulesService handles communication with + // the container registry protection rules related methods of the + // GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/container_repository_protection_rules/ + ContainerRegistryProtectionRulesService struct { + client *Client + } +) + +var _ ContainerRegistryProtectionRulesServiceInterface = (*ContainerRegistryProtectionRulesService)(nil) + +// ContainerRegistryProtectionRule represents a GitLab container registry +// protection rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/ +type ContainerRegistryProtectionRule struct { + ID int `json:"id"` + ProjectID int `json:"project_id"` + RepositoryPathPattern string `json:"repository_path_pattern"` + MinimumAccessLevelForPush ProtectionRuleAccessLevel `json:"minimum_access_level_for_push"` + MinimumAccessLevelForDelete ProtectionRuleAccessLevel `json:"minimum_access_level_for_delete"` +} + +func (s ContainerRegistryProtectionRule) String() string { + return Stringify(s) +} + +// ListContainerRegistryProtectionRules gets a list of container repository +// protection rules from a project’s container registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#list-container-repository-protection-rules +func (s *ContainerRegistryProtectionRulesService) ListContainerRegistryProtectionRules(pid any, options ...RequestOptionFunc) ([]*ContainerRegistryProtectionRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/protection/repository/rules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var rules []*ContainerRegistryProtectionRule + resp, err := s.client.Do(req, &rules) + if err != nil { + return nil, resp, err + } + + return rules, resp, nil +} + +// CreateContainerRegistryProtectionRuleOptions represents the available +// CreateContainerRegistryProtectionRule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#create-a-container-repository-protection-rule +type CreateContainerRegistryProtectionRuleOptions struct { + RepositoryPathPattern *string `url:"repository_path_pattern,omitempty" json:"repository_path_pattern,omitempty"` + MinimumAccessLevelForPush *ProtectionRuleAccessLevel `url:"minimum_access_level_for_push,omitempty" json:"minimum_access_level_for_push,omitempty"` + MinimumAccessLevelForDelete *ProtectionRuleAccessLevel `url:"minimum_access_level_for_delete,omitempty" json:"minimum_access_level_for_delete,omitempty"` +} + +// CreateContainerRegistryProtectionRule creates a container repository +// protection rule for a project’s container registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#create-a-container-repository-protection-rule +func (s *ContainerRegistryProtectionRulesService) CreateContainerRegistryProtectionRule(pid any, opt *CreateContainerRegistryProtectionRuleOptions, options ...RequestOptionFunc) (*ContainerRegistryProtectionRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/protection/repository/rules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + rule := new(ContainerRegistryProtectionRule) + resp, err := s.client.Do(req, rule) + if err != nil { + return nil, resp, err + } + + return rule, resp, nil +} + +// UpdateContainerRegistryProtectionRuleOptions represents the available +// UpdateContainerRegistryProtectionRule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#update-a-container-repository-protection-rule +type UpdateContainerRegistryProtectionRuleOptions struct { + RepositoryPathPattern *string `url:"repository_path_pattern,omitempty" json:"repository_path_pattern,omitempty"` + MinimumAccessLevelForPush *ProtectionRuleAccessLevel `url:"minimum_access_level_for_push,omitempty" json:"minimum_access_level_for_push,omitempty"` + MinimumAccessLevelForDelete *ProtectionRuleAccessLevel `url:"minimum_access_level_for_delete,omitempty" json:"minimum_access_level_for_delete,omitempty"` +} + +// UpdateContainerRegistryProtectionRule updates a container repository protection +// rule for a project’s container registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#update-a-container-repository-protection-rule +func (s *ContainerRegistryProtectionRulesService) UpdateContainerRegistryProtectionRule(pid any, ruleID int, opt *UpdateContainerRegistryProtectionRuleOptions, options ...RequestOptionFunc) (*ContainerRegistryProtectionRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/registry/protection/repository/rules/%d", PathEscape(project), ruleID) + + req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, nil, err + } + + rule := new(ContainerRegistryProtectionRule) + resp, err := s.client.Do(req, rule) + if err != nil { + return nil, resp, err + } + + return rule, resp, nil +} + +// DeleteContainerRegistryProtectionRule deletes a container repository protection +// rule from a project’s container registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/#delete-a-container-repository-protection-rule +func (s *ContainerRegistryProtectionRulesService) DeleteContainerRegistryProtectionRule(pid any, ruleID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/registry/protection/repository/rules/%d", PathEscape(project), ruleID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/context.go b/vendor/gitlab.com/gitlab-org/api/client-go/context.go new file mode 100644 index 000000000..25c2319c7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/context.go @@ -0,0 +1,33 @@ +package gitlab + +import ( + "context" + + retryablehttp "github.com/hashicorp/go-retryablehttp" +) + +// contextKey is key of context used internal client-go +type contextKey struct{} + +// checkRetryKey is context key of requestRetry. +// Value type of this key must be `retryablehttp.CheckRetry` +// This is used in [WithRequestRetry]. +var checkRetryKey = &contextKey{} + +// checkRetryFromContext returns checkRetry from Context. +// If checkRetry doesn't exist in context, return nil +func checkRetryFromContext(ctx context.Context) retryablehttp.CheckRetry { + val := ctx.Value(checkRetryKey) + + // There is no checkRetry in context + if val == nil { + return nil + } + + return val.(retryablehttp.CheckRetry) +} + +// contextWithCheckRetry create and return new context with checkRetry +func contextWithCheckRetry(ctx context.Context, checkRetry retryablehttp.CheckRetry) context.Context { + return context.WithValue(ctx, checkRetryKey, checkRetry) +} diff --git a/vendor/github.com/xanzy/go-gitlab/custom_attributes.go b/vendor/gitlab.com/gitlab-org/api/client-go/custom_attributes.go similarity index 59% rename from vendor/github.com/xanzy/go-gitlab/custom_attributes.go rename to vendor/gitlab.com/gitlab-org/api/client-go/custom_attributes.go index 02e9e5ca0..92e3babce 100644 --- a/vendor/github.com/xanzy/go-gitlab/custom_attributes.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/custom_attributes.go @@ -1,20 +1,56 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + package gitlab import ( "fmt" + "net/http" ) -// CustomAttributesService handles communication with the group, project and -// user custom attributes related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/custom_attributes.html -type CustomAttributesService struct { - client *Client -} +type ( + CustomAttributesServiceInterface interface { + ListCustomUserAttributes(user int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) + ListCustomGroupAttributes(group int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) + ListCustomProjectAttributes(project int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) + GetCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + GetCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + GetCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + SetCustomUserAttribute(user int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + SetCustomGroupAttribute(group int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + SetCustomProjectAttribute(project int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) + DeleteCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*Response, error) + DeleteCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*Response, error) + DeleteCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*Response, error) + } + + // CustomAttributesService handles communication with the group, project and + // user custom attributes related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/custom_attributes/ + CustomAttributesService struct { + client *Client + } +) + +var _ CustomAttributesServiceInterface = (*CustomAttributesService)(nil) // CustomAttribute struct is used to unmarshal response to api calls. // -// GitLab API docs: https://docs.gitlab.com/ce/api/custom_attributes.html +// GitLab API docs: https://docs.gitlab.com/api/custom_attributes/ type CustomAttribute struct { Key string `json:"key"` Value string `json:"value"` @@ -23,7 +59,7 @@ type CustomAttribute struct { // ListCustomUserAttributes lists the custom attributes of the specified user. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes +// https://docs.gitlab.com/api/custom_attributes/#list-custom-attributes func (s *CustomAttributesService) ListCustomUserAttributes(user int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { return s.listCustomAttributes("users", user, options...) } @@ -31,7 +67,7 @@ func (s *CustomAttributesService) ListCustomUserAttributes(user int, options ... // ListCustomGroupAttributes lists the custom attributes of the specified group. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes +// https://docs.gitlab.com/api/custom_attributes/#list-custom-attributes func (s *CustomAttributesService) ListCustomGroupAttributes(group int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { return s.listCustomAttributes("groups", group, options...) } @@ -39,14 +75,14 @@ func (s *CustomAttributesService) ListCustomGroupAttributes(group int, options . // ListCustomProjectAttributes lists the custom attributes of the specified project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes +// https://docs.gitlab.com/api/custom_attributes/#list-custom-attributes func (s *CustomAttributesService) ListCustomProjectAttributes(project int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { return s.listCustomAttributes("projects", project, options...) } func (s *CustomAttributesService) listCustomAttributes(resource string, id int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { u := fmt.Sprintf("%s/%d/custom_attributes", resource, id) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -56,36 +92,36 @@ func (s *CustomAttributesService) listCustomAttributes(resource string, id int, if err != nil { return nil, resp, err } - return cas, resp, err + return cas, resp, nil } -// GetCustomUserAttribute returns the user attribute with a speciifc key. +// GetCustomUserAttribute returns the user attribute with a specific key. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#single-custom-attribute func (s *CustomAttributesService) GetCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.getCustomAttribute("users", user, key, options...) } -// GetCustomGroupAttribute returns the group attribute with a speciifc key. +// GetCustomGroupAttribute returns the group attribute with a specific key. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#single-custom-attribute func (s *CustomAttributesService) GetCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.getCustomAttribute("groups", group, key, options...) } -// GetCustomProjectAttribute returns the project attribute with a speciifc key. +// GetCustomProjectAttribute returns the project attribute with a specific key. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#single-custom-attribute func (s *CustomAttributesService) GetCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.getCustomAttribute("projects", project, key, options...) } func (s *CustomAttributesService) getCustomAttribute(resource string, id int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -95,13 +131,13 @@ func (s *CustomAttributesService) getCustomAttribute(resource string, id int, ke if err != nil { return nil, resp, err } - return ca, resp, err + return ca, resp, nil } // SetCustomUserAttribute sets the custom attributes of the specified user. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#set-custom-attribute func (s *CustomAttributesService) SetCustomUserAttribute(user int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.setCustomAttribute("users", user, c, options...) } @@ -109,7 +145,7 @@ func (s *CustomAttributesService) SetCustomUserAttribute(user int, c CustomAttri // SetCustomGroupAttribute sets the custom attributes of the specified group. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#set-custom-attribute func (s *CustomAttributesService) SetCustomGroupAttribute(group int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.setCustomAttribute("groups", group, c, options...) } @@ -117,14 +153,14 @@ func (s *CustomAttributesService) SetCustomGroupAttribute(group int, c CustomAtt // SetCustomProjectAttribute sets the custom attributes of the specified project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#set-custom-attribute func (s *CustomAttributesService) SetCustomProjectAttribute(project int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.setCustomAttribute("projects", project, c, options...) } func (s *CustomAttributesService) setCustomAttribute(resource string, id int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, c.Key) - req, err := s.client.NewRequest("PUT", u, c, options) + req, err := s.client.NewRequest(http.MethodPut, u, c, options) if err != nil { return nil, nil, err } @@ -134,13 +170,13 @@ func (s *CustomAttributesService) setCustomAttribute(resource string, id int, c if err != nil { return nil, resp, err } - return ca, resp, err + return ca, resp, nil } // DeleteCustomUserAttribute removes the custom attribute of the specified user. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#delete-custom-attribute func (s *CustomAttributesService) DeleteCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*Response, error) { return s.deleteCustomAttribute("users", user, key, options...) } @@ -148,7 +184,7 @@ func (s *CustomAttributesService) DeleteCustomUserAttribute(user int, key string // DeleteCustomGroupAttribute removes the custom attribute of the specified group. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#delete-custom-attribute func (s *CustomAttributesService) DeleteCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*Response, error) { return s.deleteCustomAttribute("groups", group, key, options...) } @@ -156,14 +192,14 @@ func (s *CustomAttributesService) DeleteCustomGroupAttribute(group int, key stri // DeleteCustomProjectAttribute removes the custom attribute of the specified project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute +// https://docs.gitlab.com/api/custom_attributes/#delete-custom-attribute func (s *CustomAttributesService) DeleteCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*Response, error) { return s.deleteCustomAttribute("projects", project, key, options...) } func (s *CustomAttributesService) deleteCustomAttribute(resource string, id int, key string, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/database_migrations.go b/vendor/gitlab.com/gitlab-org/api/client-go/database_migrations.go new file mode 100644 index 000000000..007b1b401 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/database_migrations.go @@ -0,0 +1,62 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + DatabaseMigrationsServiceInterface interface { + MarkMigrationAsSuccessful(version int, opt *MarkMigrationAsSuccessfulOptions, options ...RequestOptionFunc) (*Response, error) + } + + // DatabaseMigrationsService handles communication with the database + // migrations related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/database_migrations/ + DatabaseMigrationsService struct { + client *Client + } +) + +var _ DatabaseMigrationsServiceInterface = (*DatabaseMigrationsService)(nil) + +// MarkMigrationAsSuccessfulOptions represents the options to mark a migration +// as successful. +// +// GitLab API docs: +// https://docs.gitlab.com/api/database_migrations/#mark-a-migration-as-successful +type MarkMigrationAsSuccessfulOptions struct { + Database string `url:"database,omitempty" json:"database,omitempty"` +} + +// MarkMigrationAsSuccessful markd pending migrations as successfully executed +// to prevent them from being executed by the db:migrate tasks. Use this API to +// skip failing migrations after they are determined to be safe to skip. +// +// GitLab API docs: +// https://docs.gitlab.com/api/database_migrations/#mark-a-migration-as-successful +func (s *DatabaseMigrationsService) MarkMigrationAsSuccessful(version int, opt *MarkMigrationAsSuccessfulOptions, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("admin/migrations/%d/mark", version) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/dependencies.go b/vendor/gitlab.com/gitlab-org/api/client-go/dependencies.go new file mode 100644 index 000000000..e4b85381e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/dependencies.go @@ -0,0 +1,103 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + DependenciesServiceInterface interface { + ListProjectDependencies(pid any, opt *ListProjectDependenciesOptions, options ...RequestOptionFunc) ([]*Dependency, *Response, error) + } + + // DependenciesService handles communication with the dependencies related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/dependencies/ + DependenciesService struct { + client *Client + } +) + +var _ DependenciesServiceInterface = (*DependenciesService)(nil) + +// Dependency represents a project dependency. +// +// GitLab API docs: https://docs.gitlab.com/api/dependencies/ +type Dependency struct { + Name string `url:"name" json:"name"` + Version string `url:"version" json:"version"` + PackageManager DependencyPackageManagerValue `url:"package_manager" json:"package_manager"` + DependencyFilePath string `url:"dependency_file_path" json:"dependency_file_path"` + Vulnerabilities []*DependencyVulnerability `url:"vulnerabilities" json:"vulnerabilities"` + Licenses []*DependencyLicense `url:"licenses" json:"licenses"` +} + +// DependencyVulnerability represents a project dependency vulnerability. +// +// GitLab API docs: https://docs.gitlab.com/api/dependencies/ +type DependencyVulnerability struct { + Name string `url:"name" json:"name"` + Severity string `url:"severity" json:"severity"` + ID int `url:"id" json:"id"` + URL string `url:"url" json:"url"` +} + +// DependencyLicense represents a project dependency license. +// +// GitLab API docs: https://docs.gitlab.com/api/dependencies/ +type DependencyLicense struct { + Name string `url:"name" json:"name"` + URL string `url:"url" json:"url"` +} + +// ListProjectDependenciesOptions represents the options for listing project +// dependencies. +// +// GitLab API docs: +// https://docs.gitlab.com/api/dependencies/#list-project-dependencies +type ListProjectDependenciesOptions struct { + ListOptions + PackageManager []*DependencyPackageManagerValue `url:"package_manager,omitempty" json:"package_manager,omitempty"` +} + +// ListProjectDependencies Get a list of project dependencies. This API partially +// mirroring Dependency List feature. This list can be generated only for languages +// and package managers supported by Gemnasium. +// +// GitLab API docs: +// https://docs.gitlab.com/api/dependencies/#list-project-dependencies +func (s *DependenciesService) ListProjectDependencies(pid any, opt *ListProjectDependenciesOptions, options ...RequestOptionFunc) ([]*Dependency, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/dependencies", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var dependencies []*Dependency + resp, err := s.client.Do(req, &dependencies) + if err != nil { + return nil, resp, err + } + + return dependencies, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/dependency_list_export.go b/vendor/gitlab.com/gitlab-org/api/client-go/dependency_list_export.go new file mode 100644 index 000000000..ed475fd46 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/dependency_list_export.go @@ -0,0 +1,136 @@ +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/http" +) + +type ( + DependencyListExportServiceInterface interface { + CreateDependencyListExport(pipelineID int, opt *CreateDependencyListExportOptions, options ...RequestOptionFunc) (*DependencyListExport, *Response, error) + GetDependencyListExport(id int, options ...RequestOptionFunc) (*DependencyListExport, *Response, error) + DownloadDependencyListExport(id int, options ...RequestOptionFunc) (io.Reader, *Response, error) + } + + // DependencyListExportService handles communication with the dependency list export + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/dependency_list_export/ + DependencyListExportService struct { + client *Client + } +) + +var _ DependencyListExportServiceInterface = (*DependencyListExportService)(nil) + +// CreateDependencyListExportOptions represents the available CreateDependencyListExport() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/dependency_list_export/#create-a-dependency-list-export +type CreateDependencyListExportOptions struct { + ExportType *string `url:"export_type" json:"export_type"` +} + +// DependencyListExport represents a request for a GitLab project's dependency list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/dependency_list_export/#create-a-dependency-list-export +type DependencyListExport struct { + ID int `json:"id"` + HasFinished bool `json:"has_finished"` + Self string `json:"self"` + Download string `json:"download"` +} + +const defaultExportType = "sbom" + +// CreateDependencyListExport creates a new CycloneDX JSON export for all the project dependencies +// detected in a pipeline. +// +// If an authenticated user does not have permission to read_dependency, this request returns a 403 +// Forbidden status code. +// +// SBOM exports can be only accessed by the export’s author. +// +// GitLab docs: +// https://docs.gitlab.com/api/dependency_list_export/#create-a-dependency-list-export +func (s *DependencyListExportService) CreateDependencyListExport(pipelineID int, opt *CreateDependencyListExportOptions, options ...RequestOptionFunc) (*DependencyListExport, *Response, error) { + // POST /pipelines/:id/dependency_list_exports + createExportPath := fmt.Sprintf("pipelines/%d/dependency_list_exports", pipelineID) + + if opt == nil { + opt = &CreateDependencyListExportOptions{} + } + if opt.ExportType == nil { + opt.ExportType = Ptr(defaultExportType) + } + + req, err := s.client.NewRequest(http.MethodPost, createExportPath, opt, options) + if err != nil { + return nil, nil, err + } + + export := new(DependencyListExport) + resp, err := s.client.Do(req, &export) + if err != nil { + return nil, resp, err + } + + return export, resp, nil +} + +// GetDependencyListExport gets metadata about a single dependency list export. +// +// GitLab docs: +// https://docs.gitlab.com/api/dependency_list_export/#get-single-dependency-list-export +func (s *DependencyListExportService) GetDependencyListExport(id int, options ...RequestOptionFunc) (*DependencyListExport, *Response, error) { + // GET /dependency_list_exports/:id + getExportPath := fmt.Sprintf("dependency_list_exports/%d", id) + + req, err := s.client.NewRequest(http.MethodGet, getExportPath, nil, options) + if err != nil { + return nil, nil, err + } + + export := new(DependencyListExport) + resp, err := s.client.Do(req, &export) + if err != nil { + return nil, resp, err + } + + return export, resp, nil +} + +// DownloadDependencyListExport downloads a single dependency list export. +// +// The github.com/CycloneDX/cyclonedx-go package can be used to parse the data from the returned io.Reader. +// +// sbom := new(cdx.BOM) +// decoder := cdx.NewBOMDecoder(reader, cdx.BOMFileFormatJSON) +// +// if err = decoder.Decode(sbom); err != nil { +// panic(err) +// } +// +// GitLab docs: +// https://docs.gitlab.com/api/dependency_list_export/#download-dependency-list-export +func (s *DependencyListExportService) DownloadDependencyListExport(id int, options ...RequestOptionFunc) (io.Reader, *Response, error) { + // GET /dependency_list_exports/:id/download + downloadExportPath := fmt.Sprintf("dependency_list_exports/%d/download", id) + + req, err := s.client.NewRequest(http.MethodGet, downloadExportPath, nil, options) + if err != nil { + return nil, nil, err + } + + var sbomBuffer bytes.Buffer + resp, err := s.client.Do(req, &sbomBuffer) + if err != nil { + return nil, resp, err + } + + return &sbomBuffer, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/dependency_proxy.go b/vendor/gitlab.com/gitlab-org/api/client-go/dependency_proxy.go new file mode 100644 index 000000000..a475cb5fd --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/dependency_proxy.go @@ -0,0 +1,56 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + DependencyProxyServiceInterface interface { + PurgeGroupDependencyProxy(gid any, options ...RequestOptionFunc) (*Response, error) + } + + // DependencyProxyService handles communication with the dependency proxy + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/dependency_proxy/ + DependencyProxyService struct { + client *Client + } +) + +var _ DependencyProxyServiceInterface = (*DependencyProxyService)(nil) + +// PurgeGroupDependencyProxy schedules for deletion the cached manifests and blobs +// for a group. This endpoint requires the Owner role for the group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/dependency_proxy/#purge-the-dependency-proxy-for-a-group +func (s *DependencyProxyService) PurgeGroupDependencyProxy(gid any, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/dependency_proxy/cache", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/deploy_keys.go b/vendor/gitlab.com/gitlab-org/api/client-go/deploy_keys.go new file mode 100644 index 000000000..6c0cf47f1 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/deploy_keys.go @@ -0,0 +1,293 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + DeployKeysServiceInterface interface { + ListAllDeployKeys(opt *ListInstanceDeployKeysOptions, options ...RequestOptionFunc) ([]*InstanceDeployKey, *Response, error) + ListProjectDeployKeys(pid any, opt *ListProjectDeployKeysOptions, options ...RequestOptionFunc) ([]*ProjectDeployKey, *Response, error) + GetDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) + AddDeployKey(pid any, opt *AddDeployKeyOptions, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) + DeleteDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*Response, error) + EnableDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) + UpdateDeployKey(pid any, deployKey int, opt *UpdateDeployKeyOptions, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) + } + + // DeployKeysService handles communication with the keys related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/deploy_keys/ + DeployKeysService struct { + client *Client + } +) + +var _ DeployKeysServiceInterface = (*DeployKeysService)(nil) + +// InstanceDeployKey represents a GitLab deploy key with the associated +// projects it has write access to. +type InstanceDeployKey struct { + ID int `json:"id"` + Title string `json:"title"` + CreatedAt *time.Time `json:"created_at"` + Key string `json:"key"` + Fingerprint string `json:"fingerprint"` + ProjectsWithWriteAccess []*DeployKeyProject `json:"projects_with_write_access"` +} + +func (k InstanceDeployKey) String() string { + return Stringify(k) +} + +// DeployKeyProject refers to a project an InstanceDeployKey has write access to. +type DeployKeyProject struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreatedAt *time.Time `json:"created_at"` +} + +func (k DeployKeyProject) String() string { + return Stringify(k) +} + +// ProjectDeployKey represents a GitLab project deploy key. +type ProjectDeployKey struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + Fingerprint string `json:"fingerprint"` + FingerprintSHA256 string `json:"fingerprint_sha256"` + CreatedAt *time.Time `json:"created_at"` + CanPush bool `json:"can_push"` + ExpiresAt *time.Time `json:"expires_at"` +} + +func (k ProjectDeployKey) String() string { + return Stringify(k) +} + +// ListProjectDeployKeysOptions represents the available ListAllDeployKeys() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#list-all-deploy-keys +type ListInstanceDeployKeysOptions struct { + ListOptions + Public *bool `url:"public,omitempty" json:"public,omitempty"` +} + +// ListAllDeployKeys gets a list of all deploy keys +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#list-all-deploy-keys +func (s *DeployKeysService) ListAllDeployKeys(opt *ListInstanceDeployKeysOptions, options ...RequestOptionFunc) ([]*InstanceDeployKey, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "deploy_keys", opt, options) + if err != nil { + return nil, nil, err + } + + var ks []*InstanceDeployKey + resp, err := s.client.Do(req, &ks) + if err != nil { + return nil, resp, err + } + + return ks, resp, nil +} + +// ListProjectDeployKeysOptions represents the available ListProjectDeployKeys() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#list-deploy-keys-for-project +type ListProjectDeployKeysOptions ListOptions + +// ListProjectDeployKeys gets a list of a project's deploy keys +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#list-deploy-keys-for-project +func (s *DeployKeysService) ListProjectDeployKeys(pid any, opt *ListProjectDeployKeysOptions, options ...RequestOptionFunc) ([]*ProjectDeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ks []*ProjectDeployKey + resp, err := s.client.Do(req, &ks) + if err != nil { + return nil, resp, err + } + + return ks, resp, nil +} + +// GetDeployKey gets a single deploy key. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#get-a-single-deploy-key +func (s *DeployKeysService) GetDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys/%d", PathEscape(project), deployKey) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(ProjectDeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// AddDeployKeyOptions represents the available ADDDeployKey() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#add-deploy-key-for-a-project +type AddDeployKeyOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"` + ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// AddDeployKey creates a new deploy key for a project. If deploy key already +// exists in another project - it will be joined to project but only if +// original one is accessible by the same user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#add-deploy-key-for-a-project +func (s *DeployKeysService) AddDeployKey(pid any, opt *AddDeployKeyOptions, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(ProjectDeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// DeleteDeployKey deletes a deploy key from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#delete-deploy-key +func (s *DeployKeysService) DeleteDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys/%d", PathEscape(project), deployKey) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// EnableDeployKey enables a deploy key. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#enable-a-deploy-key +func (s *DeployKeysService) EnableDeployKey(pid any, deployKey int, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys/%d/enable", PathEscape(project), deployKey) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(ProjectDeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// UpdateDeployKeyOptions represents the available UpdateDeployKey() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#update-deploy-key +type UpdateDeployKeyOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"` +} + +// UpdateDeployKey updates a deploy key for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_keys/#update-deploy-key +func (s *DeployKeysService) UpdateDeployKey(pid any, deployKey int, opt *UpdateDeployKeyOptions, options ...RequestOptionFunc) (*ProjectDeployKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_keys/%d", PathEscape(project), deployKey) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(ProjectDeployKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/deploy_tokens.go b/vendor/gitlab.com/gitlab-org/api/client-go/deploy_tokens.go new file mode 100644 index 000000000..f7128a69f --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/deploy_tokens.go @@ -0,0 +1,304 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + DeployTokensServiceInterface interface { + ListAllDeployTokens(options ...RequestOptionFunc) ([]*DeployToken, *Response, error) + ListProjectDeployTokens(pid any, opt *ListProjectDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) + GetProjectDeployToken(pid any, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) + CreateProjectDeployToken(pid any, opt *CreateProjectDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) + DeleteProjectDeployToken(pid any, deployToken int, options ...RequestOptionFunc) (*Response, error) + ListGroupDeployTokens(gid any, opt *ListGroupDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) + GetGroupDeployToken(gid any, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) + CreateGroupDeployToken(gid any, opt *CreateGroupDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) + DeleteGroupDeployToken(gid any, deployToken int, options ...RequestOptionFunc) (*Response, error) + } + + // DeployTokensService handles communication with the deploy tokens related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/deploy_tokens/ + DeployTokensService struct { + client *Client + } +) + +// DeployToken represents a GitLab deploy token. +type DeployToken struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + ExpiresAt *time.Time `json:"expires_at"` + Revoked bool `json:"revoked"` + Expired bool `json:"expired"` + Token string `json:"token,omitempty"` + Scopes []string `json:"scopes"` +} + +func (k DeployToken) String() string { + return Stringify(k) +} + +// ListAllDeployTokens gets a list of all deploy tokens. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#list-all-deploy-tokens +func (s *DeployTokensService) ListAllDeployTokens(options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "deploy_tokens", nil, options) + if err != nil { + return nil, nil, err + } + + var ts []*DeployToken + resp, err := s.client.Do(req, &ts) + if err != nil { + return nil, resp, err + } + + return ts, resp, nil +} + +// ListProjectDeployTokensOptions represents the available ListProjectDeployTokens() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#list-project-deploy-tokens +type ListProjectDeployTokensOptions ListOptions + +// ListProjectDeployTokens gets a list of a project's deploy tokens. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#list-project-deploy-tokens +func (s *DeployTokensService) ListProjectDeployTokens(pid any, opt *ListProjectDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_tokens", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ts []*DeployToken + resp, err := s.client.Do(req, &ts) + if err != nil { + return nil, resp, err + } + + return ts, resp, nil +} + +// GetProjectDeployToken gets a single deploy token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#get-a-project-deploy-token +func (s *DeployTokensService) GetProjectDeployToken(pid any, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_tokens/%d", PathEscape(project), deployToken) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(DeployToken) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// CreateProjectDeployTokenOptions represents the available CreateProjectDeployToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#create-a-project-deploy-token +type CreateProjectDeployTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` +} + +// CreateProjectDeployToken creates a new deploy token for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#create-a-project-deploy-token +func (s *DeployTokensService) CreateProjectDeployToken(pid any, opt *CreateProjectDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deploy_tokens", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(DeployToken) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// DeleteProjectDeployToken removes a deploy token from the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#delete-a-project-deploy-token +func (s *DeployTokensService) DeleteProjectDeployToken(pid any, deployToken int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/deploy_tokens/%d", PathEscape(project), deployToken) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGroupDeployTokensOptions represents the available ListGroupDeployTokens() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#list-group-deploy-tokens +type ListGroupDeployTokensOptions ListOptions + +// ListGroupDeployTokens gets a list of a group’s deploy tokens. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#list-group-deploy-tokens +func (s *DeployTokensService) ListGroupDeployTokens(gid any, opt *ListGroupDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/deploy_tokens", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ts []*DeployToken + resp, err := s.client.Do(req, &ts) + if err != nil { + return nil, resp, err + } + + return ts, resp, nil +} + +// GetGroupDeployToken gets a single deploy token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#get-a-group-deploy-token +func (s *DeployTokensService) GetGroupDeployToken(gid any, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/deploy_tokens/%d", PathEscape(group), deployToken) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(DeployToken) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// CreateGroupDeployTokenOptions represents the available CreateGroupDeployToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#create-a-group-deploy-token +type CreateGroupDeployTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` +} + +// CreateGroupDeployToken creates a new deploy token for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#create-a-group-deploy-token +func (s *DeployTokensService) CreateGroupDeployToken(gid any, opt *CreateGroupDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/deploy_tokens", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(DeployToken) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// DeleteGroupDeployToken removes a deploy token from the group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deploy_tokens/#delete-a-group-deploy-token +func (s *DeployTokensService) DeleteGroupDeployToken(gid any, deployToken int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/deploy_tokens/%d", PathEscape(group), deployToken) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/deployments.go b/vendor/gitlab.com/gitlab-org/api/client-go/deployments.go new file mode 100644 index 000000000..7368477c9 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/deployments.go @@ -0,0 +1,274 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // DeploymentsServiceInterface defines all the API methods for the DeploymentsService + DeploymentsServiceInterface interface { + ListProjectDeployments(pid any, opts *ListProjectDeploymentsOptions, options ...RequestOptionFunc) ([]*Deployment, *Response, error) + GetProjectDeployment(pid any, deployment int, options ...RequestOptionFunc) (*Deployment, *Response, error) + CreateProjectDeployment(pid any, opt *CreateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) + UpdateProjectDeployment(pid any, deployment int, opt *UpdateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) + ApproveOrRejectProjectDeployment(pid any, deployment int, opt *ApproveOrRejectProjectDeploymentOptions, options ...RequestOptionFunc) (*Response, error) + DeleteProjectDeployment(pid any, deployment int, options ...RequestOptionFunc) (*Response, error) + } + + // DeploymentsService handles communication with the deployment related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/deployments/ + DeploymentsService struct { + client *Client + } +) + +var _ DeploymentsServiceInterface = (*DeploymentsService)(nil) + +// Deployment represents the Gitlab deployment +type Deployment struct { + ID int `json:"id"` + IID int `json:"iid"` + Ref string `json:"ref"` + SHA string `json:"sha"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + User *ProjectUser `json:"user"` + Environment *Environment `json:"environment"` + Deployable struct { + ID int `json:"id"` + Status string `json:"status"` + Stage string `json:"stage"` + Name string `json:"name"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + Coverage float64 `json:"coverage"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + Duration float64 `json:"duration"` + User *User `json:"user"` + Commit *Commit `json:"commit"` + Pipeline struct { + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + } `json:"pipeline"` + Runner *Runner `json:"runner"` + } `json:"deployable"` +} + +// ListProjectDeploymentsOptions represents the available ListProjectDeployments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#list-project-deployments +type ListProjectDeploymentsOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Environment *string `url:"environment,omitempty" json:"environment,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` + + // Only for Gitlab versions less than 14 + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + + // Only for Gitlab 14 or higher + FinishedAfter *time.Time `url:"finished_after,omitempty" json:"finished_after,omitempty"` + FinishedBefore *time.Time `url:"finished_before,omitempty" json:"finished_before,omitempty"` +} + +// ListProjectDeployments gets a list of deployments in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#list-project-deployments +func (s *DeploymentsService) ListProjectDeployments(pid any, opts *ListProjectDeploymentsOptions, options ...RequestOptionFunc) ([]*Deployment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deployments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var ds []*Deployment + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetProjectDeployment get a deployment for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#get-a-specific-deployment +func (s *DeploymentsService) GetProjectDeployment(pid any, deployment int, options ...RequestOptionFunc) (*Deployment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deployments/%d", PathEscape(project), deployment) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Deployment) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateProjectDeploymentOptions represents the available +// CreateProjectDeployment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#create-a-deployment +type CreateProjectDeploymentOptions struct { + Environment *string `url:"environment,omitempty" json:"environment,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` + Tag *bool `url:"tag,omitempty" json:"tag,omitempty"` + Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"` +} + +// CreateProjectDeployment creates a project deployment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#create-a-deployment +func (s *DeploymentsService) CreateProjectDeployment(pid any, opt *CreateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deployments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Deployment) + resp, err := s.client.Do(req, &d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// UpdateProjectDeploymentOptions represents the available +// UpdateProjectDeployment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#update-a-deployment +type UpdateProjectDeploymentOptions struct { + Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"` +} + +// UpdateProjectDeployment updates a project deployment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#update-a-deployment +func (s *DeploymentsService) UpdateProjectDeployment(pid any, deployment int, opt *UpdateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deployments/%d", PathEscape(project), deployment) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Deployment) + resp, err := s.client.Do(req, &d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// ApproveOrRejectProjectDeploymentOptions represents the available +// ApproveOrRejectProjectDeployment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#approve-or-reject-a-blocked-deployment +type ApproveOrRejectProjectDeploymentOptions struct { + Status *DeploymentApprovalStatus `url:"status,omitempty" json:"status,omitempty"` + Comment *string `url:"comment,omitempty" json:"comment,omitempty"` + RepresentedAs *string `url:"represented_as,omitempty" json:"represented_as,omitempty"` +} + +// ApproveOrRejectProjectDeployment approve or reject a blocked deployment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#approve-or-reject-a-blocked-deployment +func (s *DeploymentsService) ApproveOrRejectProjectDeployment(pid any, deployment int, + opt *ApproveOrRejectProjectDeploymentOptions, options ...RequestOptionFunc, +) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/deployments/%d/approval", PathEscape(project), deployment) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteProjectDeployment delete a project deployment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#delete-a-specific-deployment +func (s *DeploymentsService) DeleteProjectDeployment(pid any, deployment int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/deployments/%d", PathEscape(project), deployment) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/deployments_merge_requests.go b/vendor/gitlab.com/gitlab-org/api/client-go/deployments_merge_requests.go new file mode 100644 index 000000000..a2b0e717c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/deployments_merge_requests.go @@ -0,0 +1,62 @@ +// Copyright 2022, Daniela Filipe Bento +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // DeploymentMergeRequestsServiceInterface defines all the API methods for the DeploymentMergeRequestsService + DeploymentMergeRequestsServiceInterface interface { + ListDeploymentMergeRequests(pid any, deployment int, opts *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) + } + + // DeploymentMergeRequestsService handles communication with the deployment's + // merge requests related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/deployments/#list-of-merge-requests-associated-with-a-deployment + DeploymentMergeRequestsService struct { + client *Client + } +) + +var _ DeploymentMergeRequestsServiceInterface = (*DeploymentMergeRequestsService)(nil) + +// ListDeploymentMergeRequests get the merge requests associated with deployment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/deployments/#list-of-merge-requests-associated-with-a-deployment +func (s *DeploymentMergeRequestsService) ListDeploymentMergeRequests(pid any, deployment int, opts *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/deployments/%d/merge_requests", PathEscape(project), deployment) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var mrs []*MergeRequest + resp, err := s.client.Do(req, &mrs) + if err != nil { + return nil, resp, err + } + + return mrs, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/discussions.go b/vendor/gitlab.com/gitlab-org/api/client-go/discussions.go new file mode 100644 index 000000000..f73a865ad --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/discussions.go @@ -0,0 +1,1184 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // DiscussionsServiceInterface defines all the API methods for the DiscussionsService + DiscussionsServiceInterface interface { + ListIssueDiscussions(pid any, issue int, opt *ListIssueDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) + GetIssueDiscussion(pid any, issue int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) + CreateIssueDiscussion(pid any, issue int, opt *CreateIssueDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + AddIssueDiscussionNote(pid any, issue int, discussion string, opt *AddIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateIssueDiscussionNote(pid any, issue int, discussion string, note int, opt *UpdateIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteIssueDiscussionNote(pid any, issue int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) + ListSnippetDiscussions(pid any, snippet int, opt *ListSnippetDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) + GetSnippetDiscussion(pid any, snippet int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) + CreateSnippetDiscussion(pid any, snippet int, opt *CreateSnippetDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + AddSnippetDiscussionNote(pid any, snippet int, discussion string, opt *AddSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateSnippetDiscussionNote(pid any, snippet int, discussion string, note int, opt *UpdateSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteSnippetDiscussionNote(pid any, snippet int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) + ListGroupEpicDiscussions(gid any, epic int, opt *ListGroupEpicDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) + GetEpicDiscussion(gid any, epic int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) + CreateEpicDiscussion(gid any, epic int, opt *CreateEpicDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + AddEpicDiscussionNote(gid any, epic int, discussion string, opt *AddEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateEpicDiscussionNote(gid any, epic int, discussion string, note int, opt *UpdateEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteEpicDiscussionNote(gid any, epic int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) + ListMergeRequestDiscussions(pid any, mergeRequest int, opt *ListMergeRequestDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) + GetMergeRequestDiscussion(pid any, mergeRequest int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) + CreateMergeRequestDiscussion(pid any, mergeRequest int, opt *CreateMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + ResolveMergeRequestDiscussion(pid any, mergeRequest int, discussion string, opt *ResolveMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + AddMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, opt *AddMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, note int, opt *UpdateMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) + ListCommitDiscussions(pid any, commit string, opt *ListCommitDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) + GetCommitDiscussion(pid any, commit string, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) + CreateCommitDiscussion(pid any, commit string, opt *CreateCommitDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) + AddCommitDiscussionNote(pid any, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateCommitDiscussionNote(pid any, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteCommitDiscussionNote(pid any, commit string, discussion string, note int, options ...RequestOptionFunc) (*Response, error) + } + + // DiscussionsService handles communication with the discussions related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/discussions/ + DiscussionsService struct { + client *Client + } +) + +var _ DiscussionsServiceInterface = (*DiscussionsService)(nil) + +// Discussion represents a GitLab discussion. +// +// GitLab API docs: https://docs.gitlab.com/api/discussions/ +type Discussion struct { + ID string `json:"id"` + IndividualNote bool `json:"individual_note"` + Notes []*Note `json:"notes"` +} + +func (d Discussion) String() string { + return Stringify(d) +} + +// ListIssueDiscussionsOptions represents the available ListIssueDiscussions() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-issue-discussion-items +type ListIssueDiscussionsOptions ListOptions + +// ListIssueDiscussions gets a list of all discussions for a single +// issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-issue-discussion-items +func (s *DiscussionsService) ListIssueDiscussions(pid any, issue int, opt *ListIssueDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ds []*Discussion + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetIssueDiscussion returns a single discussion for a specific project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#get-single-issue-discussion-item +func (s *DiscussionsService) GetIssueDiscussion(pid any, issue int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s", + PathEscape(project), + issue, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateIssueDiscussionOptions represents the available CreateIssueDiscussion() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-issue-thread +type CreateIssueDiscussionOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// CreateIssueDiscussion creates a new discussion to a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-issue-thread +func (s *DiscussionsService) CreateIssueDiscussion(pid any, issue int, opt *CreateIssueDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// AddIssueDiscussionNoteOptions represents the available AddIssueDiscussionNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-issue-thread +type AddIssueDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// AddIssueDiscussionNote creates a new discussion to a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-issue-thread +func (s *DiscussionsService) AddIssueDiscussionNote(pid any, issue int, discussion string, opt *AddIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes", + PathEscape(project), + issue, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateIssueDiscussionNoteOptions represents the available +// UpdateIssueDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-issue-thread-note +type UpdateIssueDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// UpdateIssueDiscussionNote modifies existing discussion of an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-issue-thread-note +func (s *DiscussionsService) UpdateIssueDiscussionNote(pid any, issue int, discussion string, note int, opt *UpdateIssueDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d", + PathEscape(project), + issue, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteIssueDiscussionNote deletes an existing discussion of an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#delete-an-issue-thread-note +func (s *DiscussionsService) DeleteIssueDiscussionNote(pid any, issue int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/discussions/%s/notes/%d", + PathEscape(project), + issue, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListSnippetDiscussionsOptions represents the available ListSnippetDiscussions() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-snippet-discussion-items +type ListSnippetDiscussionsOptions ListOptions + +// ListSnippetDiscussions gets a list of all discussions for a single +// snippet. Snippet discussions are comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-snippet-discussion-items +func (s *DiscussionsService) ListSnippetDiscussions(pid any, snippet int, opt *ListSnippetDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ds []*Discussion + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetSnippetDiscussion returns a single discussion for a given snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#get-single-snippet-discussion-item +func (s *DiscussionsService) GetSnippetDiscussion(pid any, snippet int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s", + PathEscape(project), + snippet, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateSnippetDiscussionOptions represents the available +// CreateSnippetDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-snippet-thread +type CreateSnippetDiscussionOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// CreateSnippetDiscussion creates a new discussion for a single snippet. +// Snippet discussions are comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-snippet-thread +func (s *DiscussionsService) CreateSnippetDiscussion(pid any, snippet int, opt *CreateSnippetDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// AddSnippetDiscussionNoteOptions represents the available +// AddSnippetDiscussionNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-snippet-thread +type AddSnippetDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// AddSnippetDiscussionNote creates a new discussion to a single project +// snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-snippet-thread +func (s *DiscussionsService) AddSnippetDiscussionNote(pid any, snippet int, discussion string, opt *AddSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes", + PathEscape(project), + snippet, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateSnippetDiscussionNoteOptions represents the available +// UpdateSnippetDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-snippet-thread-note +type UpdateSnippetDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// UpdateSnippetDiscussionNote modifies existing discussion of a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-snippet-thread-note +func (s *DiscussionsService) UpdateSnippetDiscussionNote(pid any, snippet int, discussion string, note int, opt *UpdateSnippetDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d", + PathEscape(project), + snippet, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteSnippetDiscussionNote deletes an existing discussion of a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#delete-a-snippet-thread-note +func (s *DiscussionsService) DeleteSnippetDiscussionNote(pid any, snippet int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/discussions/%s/notes/%d", + PathEscape(project), + snippet, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGroupEpicDiscussionsOptions represents the available +// ListEpicDiscussions() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-group-epic-discussion-items +type ListGroupEpicDiscussionsOptions ListOptions + +// ListGroupEpicDiscussions gets a list of all discussions for a single +// epic. Epic discussions are comments users can post to a epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-group-epic-discussion-items +func (s *DiscussionsService) ListGroupEpicDiscussions(gid any, epic int, opt *ListGroupEpicDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions", + PathEscape(group), + epic, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ds []*Discussion + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetEpicDiscussion returns a single discussion for a given epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#get-single-epic-discussion-item +func (s *DiscussionsService) GetEpicDiscussion(gid any, epic int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s", + PathEscape(group), + epic, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateEpicDiscussionOptions represents the available CreateEpicDiscussion() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-epic-thread +type CreateEpicDiscussionOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// CreateEpicDiscussion creates a new discussion for a single epic. Epic +// discussions are comments users can post to a epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-epic-thread +func (s *DiscussionsService) CreateEpicDiscussion(gid any, epic int, opt *CreateEpicDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions", + PathEscape(group), + epic, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// AddEpicDiscussionNoteOptions represents the available +// AddEpicDiscussionNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-epic-thread +type AddEpicDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// AddEpicDiscussionNote creates a new discussion to a single project epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-epic-thread +func (s *DiscussionsService) AddEpicDiscussionNote(gid any, epic int, discussion string, opt *AddEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes", + PathEscape(group), + epic, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateEpicDiscussionNoteOptions represents the available UpdateEpicDiscussion() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-epic-thread-note +type UpdateEpicDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// UpdateEpicDiscussionNote modifies existing discussion of an epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-existing-epic-thread-note +func (s *DiscussionsService) UpdateEpicDiscussionNote(gid any, epic int, discussion string, note int, opt *UpdateEpicDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d", + PathEscape(group), + epic, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteEpicDiscussionNote deletes an existing discussion of a epic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#delete-an-epic-thread-note +func (s *DiscussionsService) DeleteEpicDiscussionNote(gid any, epic int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/discussions/%s/notes/%d", + PathEscape(group), + epic, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListMergeRequestDiscussionsOptions represents the available +// ListMergeRequestDiscussions() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-merge-request-discussion-items +type ListMergeRequestDiscussionsOptions ListOptions + +// ListMergeRequestDiscussions gets a list of all discussions for a single +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-merge-request-discussion-items +func (s *DiscussionsService) ListMergeRequestDiscussions(pid any, mergeRequest int, opt *ListMergeRequestDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions", + PathEscape(project), + mergeRequest, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ds []*Discussion + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetMergeRequestDiscussion returns a single discussion for a given merge +// request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#get-single-merge-request-discussion-item +func (s *DiscussionsService) GetMergeRequestDiscussion(pid any, mergeRequest int, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s", + PathEscape(project), + mergeRequest, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateMergeRequestDiscussionOptions represents the available +// CreateMergeRequestDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-merge-request-thread +type CreateMergeRequestDiscussionOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CommitID *string `url:"commit_id,omitempty" json:"commit_id,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + Position *PositionOptions `url:"position,omitempty" json:"position,omitempty"` +} + +// PositionOptions represents the position option of a discussion. +type PositionOptions struct { + BaseSHA *string `url:"base_sha,omitempty" json:"base_sha,omitempty"` + HeadSHA *string `url:"head_sha,omitempty" json:"head_sha,omitempty"` + StartSHA *string `url:"start_sha,omitempty" json:"start_sha,omitempty"` + NewPath *string `url:"new_path,omitempty" json:"new_path,omitempty"` + OldPath *string `url:"old_path,omitempty" json:"old_path,omitempty"` + PositionType *string `url:"position_type,omitempty" json:"position_type"` + NewLine *int `url:"new_line,omitempty" json:"new_line,omitempty"` + OldLine *int `url:"old_line,omitempty" json:"old_line,omitempty"` + LineRange *LineRangeOptions `url:"line_range,omitempty" json:"line_range,omitempty"` + Width *int `url:"width,omitempty" json:"width,omitempty"` + Height *int `url:"height,omitempty" json:"height,omitempty"` + X *float64 `url:"x,omitempty" json:"x,omitempty"` + Y *float64 `url:"y,omitempty" json:"y,omitempty"` +} + +// LineRangeOptions represents the line range option of a discussion. +type LineRangeOptions struct { + Start *LinePositionOptions `url:"start,omitempty" json:"start,omitempty"` + End *LinePositionOptions `url:"end,omitempty" json:"end,omitempty"` +} + +// LinePositionOptions represents the line position option of a discussion. +type LinePositionOptions struct { + LineCode *string `url:"line_code,omitempty" json:"line_code,omitempty"` + Type *string `url:"type,omitempty" json:"type,omitempty"` + OldLine *int `url:"old_line,omitempty" json:"old_line,omitempty"` + NewLine *int `url:"new_line,omitempty" json:"new_line,omitempty"` +} + +// CreateMergeRequestDiscussion creates a new discussion for a single merge +// request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-merge-request-thread +func (s *DiscussionsService) CreateMergeRequestDiscussion(pid any, mergeRequest int, opt *CreateMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions", + PathEscape(project), + mergeRequest, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// ResolveMergeRequestDiscussionOptions represents the available +// ResolveMergeRequestDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#resolve-a-merge-request-thread +type ResolveMergeRequestDiscussionOptions struct { + Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"` +} + +// ResolveMergeRequestDiscussion resolves/unresolves whole discussion of a merge +// request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#resolve-a-merge-request-thread +func (s *DiscussionsService) ResolveMergeRequestDiscussion(pid any, mergeRequest int, discussion string, opt *ResolveMergeRequestDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s", + PathEscape(project), + mergeRequest, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// AddMergeRequestDiscussionNoteOptions represents the available +// AddMergeRequestDiscussionNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-merge-request-thread +type AddMergeRequestDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// AddMergeRequestDiscussionNote creates a new discussion to a single project +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-merge-request-thread +func (s *DiscussionsService) AddMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, opt *AddMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes", + PathEscape(project), + mergeRequest, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateMergeRequestDiscussionNoteOptions represents the available +// UpdateMergeRequestDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-an-existing-merge-request-thread-note +type UpdateMergeRequestDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + Resolved *bool `url:"resolved,omitempty" json:"resolved,omitempty"` +} + +// UpdateMergeRequestDiscussionNote modifies existing discussion of a merge +// request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-an-existing-merge-request-thread-note +func (s *DiscussionsService) UpdateMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, note int, opt *UpdateMergeRequestDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d", + PathEscape(project), + mergeRequest, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteMergeRequestDiscussionNote deletes an existing discussion of a merge +// request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#delete-a-merge-request-thread-note +func (s *DiscussionsService) DeleteMergeRequestDiscussionNote(pid any, mergeRequest int, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/discussions/%s/notes/%d", + PathEscape(project), + mergeRequest, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListCommitDiscussionsOptions represents the available +// ListCommitDiscussions() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-commit-discussion-items +type ListCommitDiscussionsOptions ListOptions + +// ListCommitDiscussions gets a list of all discussions for a single +// commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#list-project-commit-discussion-items +func (s *DiscussionsService) ListCommitDiscussions(pid any, commit string, opt *ListCommitDiscussionsOptions, options ...RequestOptionFunc) ([]*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions", + PathEscape(project), + commit, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ds []*Discussion + resp, err := s.client.Do(req, &ds) + if err != nil { + return nil, resp, err + } + + return ds, resp, nil +} + +// GetCommitDiscussion returns a single discussion for a specific project +// commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#get-single-commit-discussion-item +func (s *DiscussionsService) GetCommitDiscussion(pid any, commit string, discussion string, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s", + PathEscape(project), + commit, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// CreateCommitDiscussionOptions represents the available +// CreateCommitDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-commit-thread +type CreateCommitDiscussionOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + Position *NotePosition `url:"position,omitempty" json:"position,omitempty"` +} + +// CreateCommitDiscussion creates a new discussion to a single project commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#create-new-commit-thread +func (s *DiscussionsService) CreateCommitDiscussion(pid any, commit string, opt *CreateCommitDiscussionOptions, options ...RequestOptionFunc) (*Discussion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions", + PathEscape(project), + commit, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + d := new(Discussion) + resp, err := s.client.Do(req, d) + if err != nil { + return nil, resp, err + } + + return d, resp, nil +} + +// AddCommitDiscussionNoteOptions represents the available +// AddCommitDiscussionNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-commit-thread +type AddCommitDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// AddCommitDiscussionNote creates a new discussion to a single project commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#add-note-to-existing-commit-thread +func (s *DiscussionsService) AddCommitDiscussionNote(pid any, commit string, discussion string, opt *AddCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes", + PathEscape(project), + commit, + discussion, + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateCommitDiscussionNoteOptions represents the available +// UpdateCommitDiscussion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-an-existing-commit-thread-note +type UpdateCommitDiscussionNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// UpdateCommitDiscussionNote modifies existing discussion of a commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#modify-an-existing-commit-thread-note +func (s *DiscussionsService) UpdateCommitDiscussionNote(pid any, commit string, discussion string, note int, opt *UpdateCommitDiscussionNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d", + PathEscape(project), + commit, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteCommitDiscussionNote deletes an existing discussion of an commit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/discussions/#delete-a-commit-thread-note +func (s *DiscussionsService) DeleteCommitDiscussionNote(pid any, commit string, discussion string, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/commits/%s/discussions/%s/notes/%d", + PathEscape(project), + commit, + discussion, + note, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/dockerfile_templates.go b/vendor/gitlab.com/gitlab-org/api/client-go/dockerfile_templates.go new file mode 100644 index 000000000..0885b3b88 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/dockerfile_templates.go @@ -0,0 +1,103 @@ +// +// Copyright 2022, FantasyTeddy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + // DockerfileTemplatesServiceInterface defines all the API methods for the DockerfileTemplatesService + DockerfileTemplatesServiceInterface interface { + ListTemplates(opt *ListDockerfileTemplatesOptions, options ...RequestOptionFunc) ([]*DockerfileTemplateListItem, *Response, error) + GetTemplate(key string, options ...RequestOptionFunc) (*DockerfileTemplate, *Response, error) + } + + // DockerfileTemplatesService handles communication with the Dockerfile + // templates related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/templates/dockerfiles/ + DockerfileTemplatesService struct { + client *Client + } +) + +var _ DockerfileTemplatesServiceInterface = (*DockerfileTemplatesService)(nil) + +// DockerfileTemplate represents a GitLab Dockerfile template. +// +// GitLab API docs: https://docs.gitlab.com/api/templates/dockerfiles/ +type DockerfileTemplate struct { + Name string `json:"name"` + Content string `json:"content"` +} + +// DockerfileTemplateListItem represents a GitLab Dockerfile template from the list. +// +// GitLab API docs: https://docs.gitlab.com/api/templates/dockerfiles/ +type DockerfileTemplateListItem struct { + Key string `json:"key"` + Name string `json:"name"` +} + +// ListDockerfileTemplatesOptions represents the available ListAllTemplates() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/dockerfiles/#list-dockerfile-templates +type ListDockerfileTemplatesOptions ListOptions + +// ListTemplates get a list of available Dockerfile templates. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/dockerfiles/#list-dockerfile-templates +func (s *DockerfileTemplatesService) ListTemplates(opt *ListDockerfileTemplatesOptions, options ...RequestOptionFunc) ([]*DockerfileTemplateListItem, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "templates/dockerfiles", opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*DockerfileTemplateListItem + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// GetTemplate get a single Dockerfile template. +// +// GitLab API docs: +// https://docs.gitlab.com/api/templates/dockerfiles/#single-dockerfile-template +func (s *DockerfileTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*DockerfileTemplate, *Response, error) { + u := fmt.Sprintf("templates/dockerfiles/%s", url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(DockerfileTemplate) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/dora_metrics.go b/vendor/gitlab.com/gitlab-org/api/client-go/dora_metrics.go new file mode 100644 index 000000000..21b4d0eba --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/dora_metrics.go @@ -0,0 +1,117 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // DORAMetricsServiceInterface defines all the API methods for the DORAMetricsService + DORAMetricsServiceInterface interface { + GetProjectDORAMetrics(pid any, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) + GetGroupDORAMetrics(gid any, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) + } + + // DORAMetricsService handles communication with the DORA metrics related methods + // of the GitLab API. + // + // Gitlab API docs: https://docs.gitlab.com/api/dora/metrics/ + DORAMetricsService struct { + client *Client + } +) + +var _ DORAMetricsServiceInterface = (*DORAMetricsService)(nil) + +// DORAMetric represents a single DORA metric data point. +// +// Gitlab API docs: https://docs.gitlab.com/api/dora/metrics/ +type DORAMetric struct { + Date string `json:"date"` + Value float64 `json:"value"` +} + +// Gets a string representation of a DORAMetric data point +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +func (m DORAMetric) String() string { + return Stringify(m) +} + +// GetDORAMetricsOptions represent the request body options for getting +// DORA metrics +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +type GetDORAMetricsOptions struct { + Metric *DORAMetricType `url:"metric,omitempty" json:"metric,omitempty"` + EndDate *ISOTime `url:"end_date,omitempty" json:"end_date,omitempty"` + EnvironmentTiers *[]string `url:"environment_tiers,comma,omitempty" json:"environment_tiers,omitempty"` + Interval *DORAMetricInterval `url:"interval,omitempty" json:"interval,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` +} + +// GetProjectDORAMetrics gets the DORA metrics for a project. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/dora/metrics/#get-project-level-dora-metrics +func (s *DORAMetricsService) GetProjectDORAMetrics(pid any, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/dora/metrics", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var metrics []DORAMetric + resp, err := s.client.Do(req, &metrics) + if err != nil { + return nil, resp, err + } + + return metrics, resp, err +} + +// GetGroupDORAMetrics gets the DORA metrics for a group. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/dora/metrics/#get-group-level-dora-metrics +func (s *DORAMetricsService) GetGroupDORAMetrics(gid any, opt GetDORAMetricsOptions, options ...RequestOptionFunc) ([]DORAMetric, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/dora/metrics", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var metrics []DORAMetric + resp, err := s.client.Do(req, &metrics) + if err != nil { + return nil, resp, err + } + + return metrics, resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/draft_notes.go b/vendor/gitlab.com/gitlab-org/api/client-go/draft_notes.go new file mode 100644 index 000000000..452096562 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/draft_notes.go @@ -0,0 +1,248 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // DraftNotesServiceInterface defines all the API methods for the DraftNotesService + DraftNotesServiceInterface interface { + ListDraftNotes(pid any, mergeRequest int, opt *ListDraftNotesOptions, options ...RequestOptionFunc) ([]*DraftNote, *Response, error) + GetDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*DraftNote, *Response, error) + CreateDraftNote(pid any, mergeRequest int, opt *CreateDraftNoteOptions, options ...RequestOptionFunc) (*DraftNote, *Response, error) + UpdateDraftNote(pid any, mergeRequest int, note int, opt *UpdateDraftNoteOptions, options ...RequestOptionFunc) (*DraftNote, *Response, error) + DeleteDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*Response, error) + PublishDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*Response, error) + PublishAllDraftNotes(pid any, mergeRequest int, options ...RequestOptionFunc) (*Response, error) + } + + // DraftNotesService handles communication with the draft notes related methods + // of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/draft_notes/#list-all-merge-request-draft-notes + DraftNotesService struct { + client *Client + } +) + +var _ DraftNotesServiceInterface = (*DraftNotesService)(nil) + +type DraftNote struct { + ID int `json:"id"` + AuthorID int `json:"author_id"` + MergeRequestID int `json:"merge_request_id"` + ResolveDiscussion bool `json:"resolve_discussion"` + DiscussionID string `json:"discussion_id"` + Note string `json:"note"` + CommitID string `json:"commit_id"` + LineCode string `json:"line_code"` + Position *NotePosition `json:"position"` +} + +// ListDraftNotesOptions represents the available ListDraftNotes() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/draft_notes/#list-all-merge-request-draft-notes +type ListDraftNotesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListDraftNotes gets a list of all draft notes for a merge request. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#list-all-merge-request-draft-notes +func (s *DraftNotesService) ListDraftNotes(pid any, mergeRequest int, opt *ListDraftNotesOptions, options ...RequestOptionFunc) ([]*DraftNote, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*DraftNote + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetDraftNote gets a single draft note for a merge request. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#get-a-single-draft-note +func (s *DraftNotesService) GetDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*DraftNote, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes/%d", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(DraftNote) + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// CreateDraftNoteOptions represents the available CreateDraftNote() +// options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#create-a-draft-note +type CreateDraftNoteOptions struct { + Note *string `url:"note" json:"note"` + CommitID *string `url:"commit_id,omitempty" json:"commit_id,omitempty"` + InReplyToDiscussionID *string `url:"in_reply_to_discussion_id,omitempty" json:"in_reply_to_discussion_id,omitempty"` + ResolveDiscussion *bool `url:"resolve_discussion,omitempty" json:"resolve_discussion,omitempty"` + Position *PositionOptions `url:"position,omitempty" json:"position,omitempty"` +} + +// CreateDraftNote creates a draft note for a merge request. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#create-a-draft-note +func (s *DraftNotesService) CreateDraftNote(pid any, mergeRequest int, opt *CreateDraftNoteOptions, options ...RequestOptionFunc) (*DraftNote, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(DraftNote) + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateDraftNoteOptions represents the available UpdateDraftNote() +// options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#create-a-draft-note +type UpdateDraftNoteOptions struct { + Note *string `url:"note,omitempty" json:"note,omitempty"` + Position *PositionOptions `url:"position,omitempty" json:"position,omitempty"` +} + +// UpdateDraftNote updates a draft note for a merge request. +// +// Gitlab API docs: https://docs.gitlab.com/api/draft_notes/#create-a-draft-note +func (s *DraftNotesService) UpdateDraftNote(pid any, mergeRequest int, note int, opt *UpdateDraftNoteOptions, options ...RequestOptionFunc) (*DraftNote, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes/%d", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(DraftNote) + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteDraftNote deletes a single draft note for a merge request. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#delete-a-draft-note +func (s *DraftNotesService) DeleteDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes/%d", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// PublishDraftNote publishes a single draft note for a merge request. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#publish-a-draft-note +func (s *DraftNotesService) PublishDraftNote(pid any, mergeRequest int, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes/%d/publish", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodPut, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// PublishAllDraftNotes publishes all draft notes for a merge request that belong to the user. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/draft_notes/#publish-a-draft-note +func (s *DraftNotesService) PublishAllDraftNotes(pid any, mergeRequest int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/draft_notes/bulk_publish", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/enterprise_users.go b/vendor/gitlab.com/gitlab-org/api/client-go/enterprise_users.go new file mode 100644 index 000000000..e50b5c511 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/enterprise_users.go @@ -0,0 +1,125 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + EnterpriseUsersServiceInterface interface { + ListEnterpriseUsers(gid any, opt *ListEnterpriseUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + GetEnterpriseUser(gid any, uid int, options ...RequestOptionFunc) (*User, *Response, error) + Disable2FAForEnterpriseUser(gid any, uid int, options ...RequestOptionFunc) (*Response, error) + } + + // EnterpriseUsersService handles communication with the enterprise users + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_enterprise_users/ + EnterpriseUsersService struct { + client *Client + } +) + +var _ EnterpriseUsersServiceInterface = (*EnterpriseUsersService)(nil) + +// ListEnterpriseUsersOptions represents the available +// ListEnterpriseUsers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_enterprise_users/#list-all-enterprise-users +type ListEnterpriseUsersOptions struct { + ListOptions + Username string `url:"username,omitempty" json:"username,omitempty"` + Search string `url:"search,omitempty" json:"search,omitempty"` + Active bool `url:"active,omitempty" json:"active,omitempty"` + Blocked bool `url:"blocked,omitempty" json:"blocked,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + TwoFactor string `url:"two_factor,omitempty" json:"two_factor,omitempty"` +} + +// ListEnterpriseUsers lists all enterprise users for a given top-level group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_enterprise_users/#list-all-enterprise-users +func (s *EnterpriseUsersService) ListEnterpriseUsers(gid any, opt *ListEnterpriseUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/enterprise_users", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var users []*User + resp, err := s.client.Do(req, &users) + if err != nil { + return nil, resp, err + } + + return users, resp, nil +} + +// GetEnterpriseUser gets details on a specified enterprise user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_enterprise_users/#get-details-on-an-enterprise-user +func (s *EnterpriseUsersService) GetEnterpriseUser(gid any, uid int, options ...RequestOptionFunc) (*User, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/enterprise_users/%d", PathEscape(group), uid) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + user := new(User) + resp, err := s.client.Do(req, &user) + if err != nil { + return nil, resp, err + } + + return user, resp, nil +} + +// Disable2FAForEnterpriseUser disables two-factor authentication (2FA) for a +// specified enterprise user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_enterprise_users/#disable-two-factor-authentication-for-an-enterprise-user +func (s *EnterpriseUsersService) Disable2FAForEnterpriseUser(gid any, uid int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/enterprise_users/%d/disable_two_factor", PathEscape(group), uid) + + req, err := s.client.NewRequest(http.MethodPatch, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/environments.go b/vendor/gitlab.com/gitlab-org/api/client-go/environments.go new file mode 100644 index 000000000..9d8f9fedc --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/environments.go @@ -0,0 +1,267 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // EnvironmentsServiceInterface defines all the API methods for the EnvironmentsService + EnvironmentsServiceInterface interface { + ListEnvironments(pid any, opts *ListEnvironmentsOptions, options ...RequestOptionFunc) ([]*Environment, *Response, error) + GetEnvironment(pid any, environment int, options ...RequestOptionFunc) (*Environment, *Response, error) + CreateEnvironment(pid any, opt *CreateEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) + EditEnvironment(pid any, environment int, opt *EditEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) + DeleteEnvironment(pid any, environment int, options ...RequestOptionFunc) (*Response, error) + StopEnvironment(pid any, environmentID int, opt *StopEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) + } + + // EnvironmentsService handles communication with the environment related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/environments/ + EnvironmentsService struct { + client *Client + } +) + +var _ EnvironmentsServiceInterface = (*EnvironmentsService)(nil) + +// Environment represents a GitLab environment. +// +// GitLab API docs: https://docs.gitlab.com/api/environments/ +type Environment struct { + ID int `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Description string `json:"description"` + State string `json:"state"` + Tier string `json:"tier"` + ExternalURL string `json:"external_url"` + Project *Project `json:"project"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + LastDeployment *Deployment `json:"last_deployment"` + ClusterAgent *Agent `json:"cluster_agent"` + KubernetesNamespace string `json:"kubernetes_namespace"` + FluxResourcePath string `json:"flux_resource_path"` + AutoStopAt *time.Time `json:"auto_stop_at"` + AutoStopSetting string `json:"auto_stop_setting"` +} + +func (env Environment) String() string { + return Stringify(env) +} + +// ListEnvironmentsOptions represents the available ListEnvironments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#list-environments +type ListEnvironmentsOptions struct { + ListOptions + Name *string `url:"name,omitempty" json:"name,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + States *string `url:"states,omitempty" json:"states,omitempty"` +} + +// ListEnvironments gets a list of environments from a project, sorted by name +// alphabetically. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#list-environments +func (s *EnvironmentsService) ListEnvironments(pid any, opts *ListEnvironmentsOptions, options ...RequestOptionFunc) ([]*Environment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/environments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var envs []*Environment + resp, err := s.client.Do(req, &envs) + if err != nil { + return nil, resp, err + } + + return envs, resp, nil +} + +// GetEnvironment gets a specific environment from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#get-a-specific-environment +func (s *EnvironmentsService) GetEnvironment(pid any, environment int, options ...RequestOptionFunc) (*Environment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/environments/%d", PathEscape(project), environment) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + env := new(Environment) + resp, err := s.client.Do(req, env) + if err != nil { + return nil, resp, err + } + + return env, resp, nil +} + +// CreateEnvironmentOptions represents the available CreateEnvironment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#create-a-new-environment +type CreateEnvironmentOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` + Tier *string `url:"tier,omitempty" json:"tier,omitempty"` + ClusterAgentID *int `url:"cluster_agent_id,omitempty" json:"cluster_agent_id,omitempty"` + KubernetesNamespace *string `url:"kubernetes_namespace,omitempty" json:"kubernetes_namespace,omitempty"` + FluxResourcePath *string `url:"flux_resource_path,omitempty" json:"flux_resource_path,omitempty"` + AutoStopSetting *string `url:"auto_stop_setting,omitempty" json:"auto_stop_setting,omitempty"` +} + +// CreateEnvironment adds an environment to a project. This method is idempotent +// and can be called multiple times with the same parameters. Creating an environment +// that already exists does not affect the existing association. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#create-a-new-environment +func (s *EnvironmentsService) CreateEnvironment(pid any, opt *CreateEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/environments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + env := new(Environment) + resp, err := s.client.Do(req, env) + if err != nil { + return nil, resp, err + } + + return env, resp, nil +} + +// EditEnvironmentOptions represents the available EditEnvironment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#update-an-existing-environment +type EditEnvironmentOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` + Tier *string `url:"tier,omitempty" json:"tier,omitempty"` + ClusterAgentID *int `url:"cluster_agent_id,omitempty" json:"cluster_agent_id,omitempty"` + KubernetesNamespace *string `url:"kubernetes_namespace,omitempty" json:"kubernetes_namespace,omitempty"` + FluxResourcePath *string `url:"flux_resource_path,omitempty" json:"flux_resource_path,omitempty"` + AutoStopSetting *string `url:"auto_stop_setting,omitempty" json:"auto_stop_setting,omitempty"` +} + +// EditEnvironment updates a project team environment to a specified access level.. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#update-an-existing-environment +func (s *EnvironmentsService) EditEnvironment(pid any, environment int, opt *EditEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/environments/%d", PathEscape(project), environment) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + env := new(Environment) + resp, err := s.client.Do(req, env) + if err != nil { + return nil, resp, err + } + + return env, resp, nil +} + +// DeleteEnvironment removes an environment from a project team. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#delete-an-environment +func (s *EnvironmentsService) DeleteEnvironment(pid any, environment int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/environments/%d", PathEscape(project), environment) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// StopEnvironmentOptions represents the available StopEnvironment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#stop-an-environment +type StopEnvironmentOptions struct { + Force *bool `url:"force,omitempty" json:"force,omitempty"` +} + +// StopEnvironment stops an environment within a specific project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/environments/#stop-an-environment +func (s *EnvironmentsService) StopEnvironment(pid any, environmentID int, opt *StopEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/environments/%d/stop", PathEscape(project), environmentID) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + env := new(Environment) + resp, err := s.client.Do(req, env) + if err != nil { + return nil, resp, err + } + + return env, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/epic_issues.go b/vendor/gitlab.com/gitlab-org/api/client-go/epic_issues.go new file mode 100644 index 000000000..625d86c11 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/epic_issues.go @@ -0,0 +1,181 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // EpicIssuesServiceInterface defines all the API methods for the EpicIssuesService + // Will be removed in v5 of the API, use Work Items API instead + EpicIssuesServiceInterface interface { + // Will be removed in v5 of the API, use Work Items API instead + ListEpicIssues(gid any, epic int, opt *ListOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + AssignEpicIssue(gid any, epic, issue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + RemoveEpicIssue(gid any, epic, epicIssue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + UpdateEpicIssueAssignment(gid any, epic, epicIssue int, opt *UpdateEpicIssueAssignmentOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + } + + // EpicIssuesService handles communication with the epic issue related methods + // of the GitLab API. + // Will be removed in v5 of the API, use Work Items API instead + // + // GitLab API docs: https://docs.gitlab.com/api/epic_issues/ + EpicIssuesService struct { + client *Client + } +) + +// Will be removed in v5 of the API, use Work Items API instead +var _ EpicIssuesServiceInterface = (*EpicIssuesService)(nil) + +// EpicIssueAssignment contains both the epic and issue objects returned from +// Gitlab with the assignment ID. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epic_issues/ +type EpicIssueAssignment struct { + ID int `json:"id"` + Epic *Epic `json:"epic"` + Issue *Issue `json:"issue"` +} + +// ListEpicIssues get a list of epic issues. +// Will be removed in v5 of the API, use Work Items API instead +// +// Gitlab API docs: +// https://docs.gitlab.com/api/epic_issues/#list-issues-for-an-epic +func (s *EpicIssuesService) ListEpicIssues(gid any, epic int, opt *ListOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/issues", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var is []*Issue + resp, err := s.client.Do(req, &is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// AssignEpicIssue assigns an existing issue to an epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// Gitlab API Docs: +// https://docs.gitlab.com/api/epic_issues/#assign-an-issue-to-the-epic +func (s *EpicIssuesService) AssignEpicIssue(gid any, epic, issue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", PathEscape(group), epic, issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(EpicIssueAssignment) + resp, err := s.client.Do(req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// RemoveEpicIssue removes an issue from an epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// Gitlab API Docs: +// https://docs.gitlab.com/api/epic_issues/#remove-an-issue-from-the-epic +func (s *EpicIssuesService) RemoveEpicIssue(gid any, epic, epicIssue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", PathEscape(group), epic, epicIssue) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(EpicIssueAssignment) + resp, err := s.client.Do(req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// UpdateEpicIssueAssignmentOptions describes the UpdateEpicIssueAssignment() +// options. +// Will be removed in v5 of the API, use Work Items API instead +// +// Gitlab API Docs: +// https://docs.gitlab.com/api/epic_issues/#update-epic---issue-association +type UpdateEpicIssueAssignmentOptions struct { + *ListOptions + MoveBeforeID *int `url:"move_before_id,omitempty" json:"move_before_id,omitempty"` + MoveAfterID *int `url:"move_after_id,omitempty" json:"move_after_id,omitempty"` +} + +// UpdateEpicIsssueAssignmentOptions is kept for backwards compatibility. +// Deprecated: use UpdateEpicIssueAssignmentOptions instead. +type UpdateEpicIsssueAssignmentOptions = UpdateEpicIssueAssignmentOptions + +// UpdateEpicIssueAssignment moves an issue before or after another issue in an +// epic issue list. +// Will be removed in v5 of the API, use Work Items API instead +// +// Gitlab API Docs: +// https://docs.gitlab.com/api/epic_issues/#update-epic---issue-association +func (s *EpicIssuesService) UpdateEpicIssueAssignment(gid any, epic, epicIssue int, opt *UpdateEpicIssueAssignmentOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", PathEscape(group), epic, epicIssue) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + var is []*Issue + resp, err := s.client.Do(req, &is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/epics.go b/vendor/gitlab.com/gitlab-org/api/client-go/epics.go new file mode 100644 index 000000000..df28cc032 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/epics.go @@ -0,0 +1,310 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // EpicsServiceInterface defines all the API methods for the EpicsService + // Will be removed in v5 of the API, use Work Items API instead + EpicsServiceInterface interface { + // Will be removed in v5 of the API, use Work Items API instead + ListGroupEpics(gid any, opt *ListGroupEpicsOptions, options ...RequestOptionFunc) ([]*Epic, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + GetEpic(gid any, epic int, options ...RequestOptionFunc) (*Epic, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + GetEpicLinks(gid any, epic int, options ...RequestOptionFunc) ([]*Epic, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + CreateEpic(gid any, opt *CreateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + UpdateEpic(gid any, epic int, opt *UpdateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) + // Will be removed in v5 of the API, use Work Items API instead + DeleteEpic(gid any, epic int, options ...RequestOptionFunc) (*Response, error) + } + + // EpicsService handles communication with the epic related methods + // of the GitLab API. + // Will be removed in v5 of the API, use Work Items API instead + // + // GitLab API docs: https://docs.gitlab.com/api/epics/ + EpicsService struct { + client *Client + } +) + +// Will be removed in v5 of the API, use Work Items API instead +var _ EpicsServiceInterface = (*EpicsService)(nil) + +// EpicAuthor represents a author of the epic. +// Will be removed in v5 of the API, use Work Items API instead +type EpicAuthor struct { + ID int `json:"id"` + State string `json:"state"` + WebURL string `json:"web_url"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + Username string `json:"username"` +} + +// Epic represents a GitLab epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/ +type Epic struct { + ID int `json:"id"` + IID int `json:"iid"` + GroupID int `json:"group_id"` + ParentID int `json:"parent_id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + Confidential bool `json:"confidential"` + WebURL string `json:"web_url"` + Author *EpicAuthor `json:"author"` + StartDate *ISOTime `json:"start_date"` + StartDateIsFixed bool `json:"start_date_is_fixed"` + StartDateFixed *ISOTime `json:"start_date_fixed"` + StartDateFromMilestones *ISOTime `json:"start_date_from_milestones"` + DueDate *ISOTime `json:"due_date"` + DueDateIsFixed bool `json:"due_date_is_fixed"` + DueDateFixed *ISOTime `json:"due_date_fixed"` + DueDateFromMilestones *ISOTime `json:"due_date_from_milestones"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + ClosedAt *time.Time `json:"closed_at"` + Labels []string `json:"labels"` + Upvotes int `json:"upvotes"` + Downvotes int `json:"downvotes"` + UserNotesCount int `json:"user_notes_count"` + URL string `json:"url"` +} + +// Will be removed in v5 of the API, use Work Items API instead +func (e Epic) String() string { + return Stringify(e) +} + +// ListGroupEpicsOptions represents the available ListGroupEpics() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#list-epics-for-a-group +type ListGroupEpicsOptions struct { + ListOptions + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"` + IncludeDescendantGroups *bool `url:"include_descendant_groups,omitempty" json:"include_descendant_groups,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` +} + +// ListGroupEpics gets a list of group epics. This function accepts pagination +// parameters page and per_page to return the list of group epics. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#list-epics-for-a-group +func (s *EpicsService) ListGroupEpics(gid any, opt *ListGroupEpicsOptions, options ...RequestOptionFunc) ([]*Epic, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var es []*Epic + resp, err := s.client.Do(req, &es) + if err != nil { + return nil, resp, err + } + + return es, resp, nil +} + +// GetEpic gets a single group epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#single-epic +func (s *EpicsService) GetEpic(gid any, epic int, options ...RequestOptionFunc) (*Epic, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + e := new(Epic) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// GetEpicLinks gets all child epics of an epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epic_links/ +func (s *EpicsService) GetEpicLinks(gid any, epic int, options ...RequestOptionFunc) ([]*Epic, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/epics", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var e []*Epic + resp, err := s.client.Do(req, &e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// CreateEpicOptions represents the available CreateEpic() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#new-epic +type CreateEpicOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"` + StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"` + DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"` + DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"` + ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` +} + +// CreateEpic creates a new group epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#new-epic +func (s *EpicsService) CreateEpic(gid any, opt *CreateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Epic) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// UpdateEpicOptions represents the available UpdateEpic() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#update-epic +type UpdateEpicOptions struct { + AddLabels *LabelOptions `url:"add_labels,omitempty" json:"add_labels,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"` + DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` + RemoveLabels *LabelOptions `url:"remove_labels,omitempty" json:"remove_labels,omitempty"` + StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"` + StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + UpdatedAt *time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` +} + +// UpdateEpic updates an existing group epic. This function is also used +// to mark an epic as closed. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#update-epic +func (s *EpicsService) UpdateEpic(gid any, epic int, opt *UpdateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Epic) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// DeleteEpic deletes a single group epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: https://docs.gitlab.com/api/epics/#delete-epic +func (s *EpicsService) DeleteEpic(gid any, epic int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/error_tracking.go b/vendor/gitlab.com/gitlab-org/api/client-go/error_tracking.go new file mode 100644 index 000000000..14de8ea88 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/error_tracking.go @@ -0,0 +1,209 @@ +// +// Copyright 2022, Ryan Glab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // ErrorTrackingServiceInterface defines all the API methods for the ErrorTrackingService + ErrorTrackingServiceInterface interface { + GetErrorTrackingSettings(pid any, options ...RequestOptionFunc) (*ErrorTrackingSettings, *Response, error) + EnableDisableErrorTracking(pid any, opt *EnableDisableErrorTrackingOptions, options ...RequestOptionFunc) (*ErrorTrackingSettings, *Response, error) + ListClientKeys(pid any, opt *ListClientKeysOptions, options ...RequestOptionFunc) ([]*ErrorTrackingClientKey, *Response, error) + CreateClientKey(pid any, options ...RequestOptionFunc) (*ErrorTrackingClientKey, *Response, error) + DeleteClientKey(pid any, keyID int, options ...RequestOptionFunc) (*Response, error) + } + + // ErrorTrackingService handles communication with the error tracking + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/error_tracking/ + ErrorTrackingService struct { + client *Client + } +) + +var _ ErrorTrackingServiceInterface = (*ErrorTrackingService)(nil) + +// ErrorTrackingClientKey represents an error tracking client key. +// +// GitLab docs: +// https://docs.gitlab.com/api/error_tracking/#error-tracking-client-keys +type ErrorTrackingClientKey struct { + ID int `json:"id"` + Active bool `json:"active"` + PublicKey string `json:"public_key"` + SentryDsn string `json:"sentry_dsn"` +} + +func (p ErrorTrackingClientKey) String() string { + return Stringify(p) +} + +// ErrorTrackingSettings represents error tracking settings for a GitLab project. +// +// GitLab API docs: https://docs.gitlab.com/api/error_tracking/#error-tracking-project-settings +type ErrorTrackingSettings struct { + Active bool `json:"active"` + ProjectName string `json:"project_name"` + SentryExternalURL string `json:"sentry_external_url"` + APIURL string `json:"api_url"` + Integrated bool `json:"integrated"` +} + +func (p ErrorTrackingSettings) String() string { + return Stringify(p) +} + +// GetErrorTrackingSettings gets error tracking settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#get-error-tracking-settings +func (s *ErrorTrackingService) GetErrorTrackingSettings(pid any, options ...RequestOptionFunc) (*ErrorTrackingSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/error_tracking/settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ets := new(ErrorTrackingSettings) + resp, err := s.client.Do(req, ets) + if err != nil { + return nil, resp, err + } + + return ets, resp, nil +} + +// EnableDisableErrorTrackingOptions represents the available +// EnableDisableErrorTracking() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#enable-or-disable-the-error-tracking-project-settings +type EnableDisableErrorTrackingOptions struct { + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Integrated *bool `url:"integrated,omitempty" json:"integrated,omitempty"` +} + +// EnableDisableErrorTracking allows you to enable or disable the error tracking +// settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#enable-or-disable-the-error-tracking-project-settings +func (s *ErrorTrackingService) EnableDisableErrorTracking(pid any, opt *EnableDisableErrorTrackingOptions, options ...RequestOptionFunc) (*ErrorTrackingSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/error_tracking/settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, nil, err + } + + ets := new(ErrorTrackingSettings) + resp, err := s.client.Do(req, &ets) + if err != nil { + return nil, resp, err + } + + return ets, resp, nil +} + +// ListClientKeysOptions represents the available ListClientKeys() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#list-project-client-keys +type ListClientKeysOptions ListOptions + +// ListClientKeys lists error tracking project client keys. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#list-project-client-keys +func (s *ErrorTrackingService) ListClientKeys(pid any, opt *ListClientKeysOptions, options ...RequestOptionFunc) ([]*ErrorTrackingClientKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/error_tracking/client_keys", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var cks []*ErrorTrackingClientKey + resp, err := s.client.Do(req, &cks) + if err != nil { + return nil, resp, err + } + + return cks, resp, nil +} + +// CreateClientKey creates a new client key for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#create-a-client-key +func (s *ErrorTrackingService) CreateClientKey(pid any, options ...RequestOptionFunc) (*ErrorTrackingClientKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/error_tracking/client_keys", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + ck := new(ErrorTrackingClientKey) + resp, err := s.client.Do(req, ck) + if err != nil { + return nil, resp, err + } + + return ck, resp, nil +} + +// DeleteClientKey removes a client key from the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/error_tracking/#delete-a-client-key +func (s *ErrorTrackingService) DeleteClientKey(pid any, keyID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/error_tracking/client_keys/%d", PathEscape(project), keyID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/event_parsing.go b/vendor/gitlab.com/gitlab-org/api/client-go/event_parsing.go new file mode 100644 index 000000000..cae15b4bc --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/event_parsing.go @@ -0,0 +1,312 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// EventType represents a Gitlab event type. +type EventType string + +// List of available event types. +const ( + EventConfidentialIssue EventType = "Confidential Issue Hook" + EventConfidentialNote EventType = "Confidential Note Hook" + EventTypeBuild EventType = "Build Hook" + EventTypeDeployment EventType = "Deployment Hook" + EventTypeFeatureFlag EventType = "Feature Flag Hook" + EventTypeIssue EventType = "Issue Hook" + EventTypeJob EventType = "Job Hook" + EventTypeMember EventType = "Member Hook" + EventTypeMergeRequest EventType = "Merge Request Hook" + EventTypeNote EventType = "Note Hook" + EventTypePipeline EventType = "Pipeline Hook" + EventTypePush EventType = "Push Hook" + EventTypeRelease EventType = "Release Hook" + EventTypeResourceAccessToken EventType = "Resource Access Token Hook" + EventTypeServiceHook EventType = "Service Hook" + EventTypeSubGroup EventType = "Subgroup Hook" + EventTypeSystemHook EventType = "System Hook" + EventTypeTagPush EventType = "Tag Push Hook" + EventTypeWikiPage EventType = "Wiki Page Hook" +) + +const ( + eventObjectKindPush = "push" + eventObjectKindTagPush = "tag_push" + eventObjectKindMergeRequest = "merge_request" +) + +const ( + noteableTypeCommit = "Commit" + noteableTypeIssue = "Issue" + noteableTypeMergeRequest = "MergeRequest" + noteableTypeSnippet = "Snippet" +) + +type noteEvent struct { + ObjectKind string `json:"object_kind"` + ObjectAttributes struct { + NoteableType string `json:"noteable_type"` + } `json:"object_attributes"` +} + +type serviceEvent struct { + ObjectKind string `json:"object_kind"` +} + +const eventTokenHeader = "X-Gitlab-Token" + +// HookEventToken returns the token for the given request. +func HookEventToken(r *http.Request) string { + return r.Header.Get(eventTokenHeader) +} + +const eventTypeHeader = "X-Gitlab-Event" + +// HookEventType returns the event type for the given request. +func HookEventType(r *http.Request) EventType { + return EventType(r.Header.Get(eventTypeHeader)) +} + +// ParseHook tries to parse both web- and system hooks. +// +// Example usage: +// +// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// payload, err := io.ReadAll(r.Body) +// if err != nil { ... } +// event, err := gitlab.ParseHook(gitlab.HookEventType(r), payload) +// if err != nil { ... } +// switch event := event.(type) { +// case *gitlab.PushEvent: +// processPushEvent(event) +// case *gitlab.MergeEvent: +// processMergeEvent(event) +// ... +// } +// } +func ParseHook(eventType EventType, payload []byte) (event any, err error) { + switch eventType { + case EventTypeSystemHook: + return ParseSystemhook(payload) + default: + return ParseWebhook(eventType, payload) + } +} + +// ParseSystemhook parses the event payload. For recognized event types, a +// value of the corresponding struct type will be returned. An error will be +// returned for unrecognized event types. +// +// Example usage: +// +// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// payload, err := io.ReadAll(r.Body) +// if err != nil { ... } +// event, err := gitlab.ParseSystemhook(payload) +// if err != nil { ... } +// switch event := event.(type) { +// case *gitlab.PushSystemEvent: +// processPushSystemEvent(event) +// case *gitlab.MergeSystemEvent: +// processMergeSystemEvent(event) +// ... +// } +// } +func ParseSystemhook(payload []byte) (event any, err error) { + e := &systemHookEvent{} + err = json.Unmarshal(payload, e) + if err != nil { + return nil, err + } + + switch e.EventName { + case eventObjectKindPush: + event = &PushSystemEvent{} + case eventObjectKindTagPush: + event = &TagPushSystemEvent{} + case "repository_update": + event = &RepositoryUpdateSystemEvent{} + case + "project_create", + "project_update", + "project_destroy", + "project_transfer", + "project_rename": + event = &ProjectSystemEvent{} + case + "group_create", + "group_destroy", + "group_rename": + event = &GroupSystemEvent{} + case "key_create", "key_destroy": + event = &KeySystemEvent{} + case + "user_create", + "user_destroy", + "user_rename", + "user_failed_login": + event = &UserSystemEvent{} + case + "user_add_to_group", + "user_remove_from_group", + "user_update_for_group": + event = &UserGroupSystemEvent{} + case + "user_add_to_team", + "user_remove_from_team", + "user_update_for_team": + event = &UserTeamSystemEvent{} + default: + switch e.ObjectKind { + case string(MergeRequestEventTargetType): + event = &MergeEvent{} + default: + return nil, fmt.Errorf("unexpected system hook type %s", e.EventName) + } + } + + if err := json.Unmarshal(payload, event); err != nil { + return nil, err + } + + return event, nil +} + +// WebhookEventType returns the event type for the given request. +func WebhookEventType(r *http.Request) EventType { + return EventType(r.Header.Get(eventTypeHeader)) +} + +// ParseWebhook parses the event payload. For recognized event types, a +// value of the corresponding struct type will be returned. An error will +// be returned for unrecognized event types. +// +// Example usage: +// +// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// payload, err := io.ReadAll(r.Body) +// if err != nil { ... } +// event, err := gitlab.ParseWebhook(gitlab.HookEventType(r), payload) +// if err != nil { ... } +// switch event := event.(type) { +// case *gitlab.PushEvent: +// processPushEvent(event) +// case *gitlab.MergeEvent: +// processMergeEvent(event) +// ... +// } +// } +func ParseWebhook(eventType EventType, payload []byte) (event any, err error) { + switch eventType { + case EventTypeBuild: + event = &BuildEvent{} + case EventTypeDeployment: + event = &DeploymentEvent{} + case EventTypeFeatureFlag: + event = &FeatureFlagEvent{} + case EventTypeIssue, EventConfidentialIssue: + event = &IssueEvent{} + case EventTypeJob: + event = &JobEvent{} + case EventTypeMember: + event = &MemberEvent{} + case EventTypeMergeRequest: + event = &MergeEvent{} + case EventTypeNote, EventConfidentialNote: + note := ¬eEvent{} + err := json.Unmarshal(payload, note) + if err != nil { + return nil, err + } + + if note.ObjectKind != string(NoteEventTargetType) { + return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind) + } + + switch note.ObjectAttributes.NoteableType { + case noteableTypeCommit: + event = &CommitCommentEvent{} + case noteableTypeMergeRequest: + event = &MergeCommentEvent{} + case noteableTypeIssue: + event = &IssueCommentEvent{} + case noteableTypeSnippet: + event = &SnippetCommentEvent{} + default: + return nil, fmt.Errorf("unexpected noteable type %s", note.ObjectAttributes.NoteableType) + } + case EventTypePipeline: + event = &PipelineEvent{} + case EventTypePush: + event = &PushEvent{} + case EventTypeRelease: + event = &ReleaseEvent{} + case EventTypeResourceAccessToken: + data := map[string]any{} + err := json.Unmarshal(payload, &data) + if err != nil { + return nil, err + } + + _, groupEvent := data["group"] + _, projectEvent := data["project"] + + switch { + case groupEvent: + event = &GroupResourceAccessTokenEvent{} + case projectEvent: + event = &ProjectResourceAccessTokenEvent{} + default: + return nil, fmt.Errorf("unexpected resource access token payload") + } + case EventTypeServiceHook: + service := &serviceEvent{} + err := json.Unmarshal(payload, service) + if err != nil { + return nil, err + } + switch service.ObjectKind { + case eventObjectKindPush: + event = &PushEvent{} + case eventObjectKindTagPush: + event = &TagEvent{} + case eventObjectKindMergeRequest: + event = &MergeEvent{} + default: + return nil, fmt.Errorf("unexpected service type %s", service.ObjectKind) + } + case EventTypeSubGroup: + event = &SubGroupEvent{} + case EventTypeTagPush: + event = &TagEvent{} + case EventTypeWikiPage: + event = &WikiPageEvent{} + default: + return nil, fmt.Errorf("unexpected event type: %s", eventType) + } + + if err := json.Unmarshal(payload, event); err != nil { + return nil, err + } + + return event, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/event_systemhook_types.go b/vendor/gitlab.com/gitlab-org/api/client-go/event_systemhook_types.go new file mode 100644 index 000000000..50940e832 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/event_systemhook_types.go @@ -0,0 +1,249 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "time" + +// systemHookEvent is used to pre-process events to determine the +// system hook event type. +type systemHookEvent struct { + BaseSystemEvent + ObjectKind string `json:"object_kind"` +} + +// BaseSystemEvent contains system hook's common properties. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type BaseSystemEvent struct { + EventName string `json:"event_name"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// ProjectSystemEvent represents a project system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type ProjectSystemEvent struct { + BaseSystemEvent + Name string `json:"name"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + ProjectID int `json:"project_id"` + OwnerName string `json:"owner_name"` + OwnerEmail string `json:"owner_email"` + ProjectVisibility string `json:"project_visibility"` + OldPathWithNamespace string `json:"old_path_with_namespace,omitempty"` +} + +// GroupSystemEvent represents a group system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type GroupSystemEvent struct { + BaseSystemEvent + Name string `json:"name"` + Path string `json:"path"` + PathWithNamespace string `json:"full_path"` + GroupID int `json:"group_id"` + OwnerName string `json:"owner_name"` + OwnerEmail string `json:"owner_email"` + ProjectVisibility string `json:"project_visibility"` + OldPath string `json:"old_path,omitempty"` + OldPathWithNamespace string `json:"old_full_path,omitempty"` +} + +// KeySystemEvent represents a key system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type KeySystemEvent struct { + BaseSystemEvent + ID int `json:"id"` + Username string `json:"username"` + Key string `json:"key"` +} + +// UserSystemEvent represents a user system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type UserSystemEvent struct { + BaseSystemEvent + ID int `json:"user_id"` + Name string `json:"name"` + Username string `json:"username"` + OldUsername string `json:"old_username,omitempty"` + Email string `json:"email"` + State string `json:"state,omitempty"` +} + +// UserGroupSystemEvent represents a user group system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type UserGroupSystemEvent struct { + BaseSystemEvent + ID int `json:"user_id"` + Name string `json:"user_name"` + Username string `json:"user_username"` + Email string `json:"user_email"` + GroupID int `json:"group_id"` + GroupName string `json:"group_name"` + GroupPath string `json:"group_path"` + GroupAccess string `json:"group_access"` +} + +// UserTeamSystemEvent represents a user team system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/ +type UserTeamSystemEvent struct { + BaseSystemEvent + ID int `json:"user_id"` + Name string `json:"user_name"` + Username string `json:"user_username"` + Email string `json:"user_email"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + ProjectPath string `json:"project_path"` + ProjectPathWithNamespace string `json:"project_path_with_namespace"` + ProjectVisibility string `json:"project_visibility"` + AccessLevel string `json:"access_level"` +} + +// PushSystemEvent represents a push system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/#push-events +type PushSystemEvent struct { + BaseSystemEvent + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitHTTPURL string `json:"git_http_url"` + GitSSHURL string `json:"git_ssh_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + } `json:"project"` + Commits []struct { + ID string `json:"id"` + Message string `json:"message"` + Timestamp time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// TagPushSystemEvent represents a tag push system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/#tag-events +type TagPushSystemEvent struct { + BaseSystemEvent + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitHTTPURL string `json:"git_http_url"` + GitSSHURL string `json:"git_ssh_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + } `json:"project"` + Commits []struct { + ID string `json:"id"` + Message string `json:"message"` + Timestamp time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// RepositoryUpdateSystemEvent represents a repository updated system event. +// +// GitLab API docs: +// https://docs.gitlab.com/administration/system_hooks/#repository-update-events +type RepositoryUpdateSystemEvent struct { + BaseSystemEvent + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitHTTPURL string `json:"git_http_url"` + GitSSHURL string `json:"git_ssh_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CiConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + } `json:"project"` + Changes []struct { + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + } `json:"changes"` + Refs []string `json:"refs"` +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/event_webhook_types.go b/vendor/gitlab.com/gitlab-org/api/client-go/event_webhook_types.go new file mode 100644 index 000000000..f1580cd65 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/event_webhook_types.go @@ -0,0 +1,1279 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "strconv" + "time" +) + +// StateID identifies the state of an issue or merge request. +// +// There are no GitLab API docs on the subject, but the mappings can be found in +// GitLab's codebase: +// https://gitlab.com/gitlab-org/gitlab-foss/-/blob/ba5be4989e/app/models/concerns/issuable.rb#L39-42 +type StateID int + +const ( + StateIDNone StateID = 0 + StateIDOpen StateID = 1 + StateIDClosed StateID = 2 + StateIDMerged StateID = 3 + StateIDLocked StateID = 4 +) + +// BuildEvent represents a build event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#job-events +type BuildEvent struct { + ObjectKind string `json:"object_kind"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + BeforeSHA string `json:"before_sha"` + SHA string `json:"sha"` + BuildID int `json:"build_id"` + BuildName string `json:"build_name"` + BuildStage string `json:"build_stage"` + BuildStatus string `json:"build_status"` + BuildCreatedAt string `json:"build_created_at"` + BuildStartedAt string `json:"build_started_at"` + BuildFinishedAt string `json:"build_finished_at"` + BuildDuration float64 `json:"build_duration"` + BuildAllowFailure bool `json:"build_allow_failure"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + User *EventUser `json:"user"` + Commit struct { + ID int `json:"id"` + SHA string `json:"sha"` + Message string `json:"message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + Status string `json:"status"` + Duration int `json:"duration"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` + } `json:"commit"` + Repository *Repository `json:"repository"` +} + +// CommitCommentEvent represents a comment on a commit event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#comment-on-a-commit +type CommitCommentEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff *Diff `json:"st_diff"` + Description string `json:"description"` + Action CommentEventAction `json:"action"` + URL string `json:"url"` + } `json:"object_attributes"` + Commit *struct { + ID string `json:"id"` + Title string `json:"title"` + Message string `json:"message"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commit"` +} + +// DeploymentEvent represents a deployment event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#deployment-events +type DeploymentEvent struct { + ObjectKind string `json:"object_kind"` + Status string `json:"status"` + StatusChangedAt string `json:"status_changed_at"` + DeploymentID int `json:"deployment_id"` + DeployableID int `json:"deployable_id"` + DeployableURL string `json:"deployable_url"` + Environment string `json:"environment"` + EnvironmentSlug string `json:"environment_slug"` + EnvironmentExternalURL string `json:"environment_external_url"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL *string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + } `json:"project"` + Ref string `json:"ref"` + ShortSHA string `json:"short_sha"` + User *EventUser `json:"user"` + UserURL string `json:"user_url"` + CommitURL string `json:"commit_url"` + CommitTitle string `json:"commit_title"` +} + +// FeatureFlagEvent represents a feature flag event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#feature-flag-events +type FeatureFlagEvent struct { + ObjectKind string `json:"object_kind"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL *string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + } `json:"project"` + User *EventUser `json:"user"` + UserURL string `json:"user_url"` + ObjectAttributes struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Active bool `json:"active"` + } `json:"object_attributes"` +} + +// GroupResourceAccessTokenEvent represents a resource access token event for a +// group. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#project-and-group-access-token-events +type GroupResourceAccessTokenEvent struct { + EventName string `json:"event_name"` + ObjectKind string `json:"object_kind"` + Group struct { + GroupID int `json:"group_id"` + GroupName string `json:"group_name"` + GroupPath string `json:"group_path"` + } `json:"group"` + ObjectAttributes struct { + ID int `json:"id"` + UserID int `json:"user_id"` + Name string `json:"name"` + CreatedAt string `json:"created_at"` + ExpiresAt *ISOTime `json:"expires_at"` + } `json:"object_attributes"` +} + +// IssueCommentEvent represents a comment on an issue event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#comment-on-an-issue +type IssueCommentEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *User `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + DiscussionID string `json:"discussion_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff []*Diff `json:"st_diff"` + Description string `json:"description"` + Action CommentEventAction `json:"action"` + URL string `json:"url"` + } `json:"object_attributes"` + Issue struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + MilestoneID int `json:"milestone_id"` + AuthorID int `json:"author_id"` + Position int `json:"position"` + BranchName string `json:"branch_name"` + Description string `json:"description"` + State string `json:"state"` + Title string `json:"title"` + Labels []*EventLabel `json:"labels"` + LastEditedAt string `json:"last_edit_at"` + LastEditedByID int `json:"last_edited_by_id"` + UpdatedAt string `json:"updated_at"` + UpdatedByID int `json:"updated_by_id"` + CreatedAt string `json:"created_at"` + ClosedAt string `json:"closed_at"` + DueDate *ISOTime `json:"due_date"` + URL string `json:"url"` + TimeEstimate int `json:"time_estimate"` + Confidential bool `json:"confidential"` + TotalTimeSpent int `json:"total_time_spent"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + HumanTimeEstimate string `json:"human_time_estimate"` + AssigneeIDs []int `json:"assignee_ids"` + AssigneeID int `json:"assignee_id"` + } `json:"issue"` +} + +// IssueEvent represents a issue event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#work-item-events +type IssueEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *EventUser `json:"user"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Title string `json:"title"` + AssigneeIDs []int `json:"assignee_ids"` + AssigneeID int `json:"assignee_id"` + AuthorID int `json:"author_id"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedByID int `json:"updated_by_id"` + LastEditedAt string `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + RelativePosition int `json:"relative_position"` + BranchName string `json:"branch_name"` + Description string `json:"description"` + MilestoneID int `json:"milestone_id"` + StateID StateID `json:"state_id"` + Confidential bool `json:"confidential"` + DiscussionLocked bool `json:"discussion_locked"` + DueDate *ISOTime `json:"due_date"` + MovedToID int `json:"moved_to_id"` + DuplicatedToID int `json:"duplicated_to_id"` + TimeEstimate int `json:"time_estimate"` + TotalTimeSpent int `json:"total_time_spent"` + TimeChange int `json:"time_change"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + HumanTimeEstimate string `json:"human_time_estimate"` + HumanTimeChange string `json:"human_time_change"` + Weight int `json:"weight"` + IID int `json:"iid"` + URL string `json:"url"` + State string `json:"state"` + Action string `json:"action"` + Severity string `json:"severity"` + EscalationStatus string `json:"escalation_status"` + EscalationPolicy struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"escalation_policy"` + Labels []*EventLabel `json:"labels"` + } `json:"object_attributes"` + Assignee *EventUser `json:"assignee"` + Assignees *[]EventUser `json:"assignees"` + Labels []*EventLabel `json:"labels"` + Changes struct { + Assignees struct { + Previous []*EventUser `json:"previous"` + Current []*EventUser `json:"current"` + } `json:"assignees"` + Description struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"description"` + Labels struct { + Previous []*EventLabel `json:"previous"` + Current []*EventLabel `json:"current"` + } `json:"labels"` + Title struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"title"` + ClosedAt struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"closed_at"` + StateID struct { + Previous StateID `json:"previous"` + Current StateID `json:"current"` + } `json:"state_id"` + UpdatedAt struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"updated_at"` + UpdatedByID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"updated_by_id"` + TotalTimeSpent struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"total_time_spent"` + } `json:"changes"` +} + +// JobEvent represents a job event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#job-events +type JobEvent struct { + ObjectKind string `json:"object_kind"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + BeforeSHA string `json:"before_sha"` + SHA string `json:"sha"` + BuildID int `json:"build_id"` + BuildName string `json:"build_name"` + BuildStage string `json:"build_stage"` + BuildStatus string `json:"build_status"` + BuildCreatedAt string `json:"build_created_at"` + BuildStartedAt string `json:"build_started_at"` + BuildFinishedAt string `json:"build_finished_at"` + BuildDuration float64 `json:"build_duration"` + BuildQueuedDuration float64 `json:"build_queued_duration"` + BuildAllowFailure bool `json:"build_allow_failure"` + BuildFailureReason string `json:"build_failure_reason"` + RetriesCount int `json:"retries_count"` + PipelineID int `json:"pipeline_id"` + ProjectID int `json:"project_id"` + ProjectName string `json:"project_name"` + User *EventUser `json:"user"` + Commit struct { + ID int `json:"id"` + Name string `json:"name"` + SHA string `json:"sha"` + Message string `json:"message"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthorURL string `json:"author_url"` + Status string `json:"status"` + Duration int `json:"duration"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` + } `json:"commit"` + Repository *Repository `json:"repository"` + Runner struct { + ID int `json:"id"` + Active bool `json:"active"` + RunnerType string `json:"runner_type"` + IsShared bool `json:"is_shared"` + Description string `json:"description"` + Tags []string `json:"tags"` + } `json:"runner"` + Environment struct { + Name string `json:"name"` + Action string `json:"action"` + DeploymentTier string `json:"deployment_tier"` + } `json:"environment"` + SourcePipeline struct { + Project struct { + ID int `json:"id"` + WebURL string `json:"web_url"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"project"` + PipelineID int `json:"pipeline_id"` + JobID int `json:"job_id"` + } `json:"source_pipeline"` +} + +// MemberEvent represents a member event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#group-member-events +type MemberEvent struct { + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + GroupName string `json:"group_name"` + GroupPath string `json:"group_path"` + GroupID int `json:"group_id"` + UserUsername string `json:"user_username"` + UserName string `json:"user_name"` + UserEmail string `json:"user_email"` + UserID int `json:"user_id"` + GroupAccess string `json:"group_access"` + GroupPlan string `json:"group_plan"` + ExpiresAt *time.Time `json:"expires_at"` + EventName string `json:"event_name"` +} + +// MergeCommentEvent represents a comment on a merge event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#comment-on-a-merge-request +type MergeCommentEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *EventUser `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + ObjectAttributes struct { + Attachment string `json:"attachment"` + AuthorID int `json:"author_id"` + ChangePosition *NotePosition `json:"change_position"` + CommitID string `json:"commit_id"` + CreatedAt string `json:"created_at"` + DiscussionID string `json:"discussion_id"` + ID int `json:"id"` + LineCode string `json:"line_code"` + Note string `json:"note"` + NoteableID int `json:"noteable_id"` + NoteableType string `json:"noteable_type"` + OriginalPosition *NotePosition `json:"original_position"` + Position *NotePosition `json:"position"` + ProjectID int `json:"project_id"` + ResolvedAt string `json:"resolved_at"` + ResolvedByID int `json:"resolved_by_id"` + ResolvedByPush bool `json:"resolved_by_push"` + StDiff *Diff `json:"st_diff"` + System bool `json:"system"` + Type string `json:"type"` + UpdatedAt string `json:"updated_at"` + UpdatedByID int `json:"updated_by_id"` + Description string `json:"description"` + Action CommentEventAction `json:"action"` + URL string `json:"url"` + } `json:"object_attributes"` + Repository *Repository `json:"repository"` + MergeRequest struct { + ID int `json:"id"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + AuthorID int `json:"author_id"` + AssigneeID int `json:"assignee_id"` + AssigneeIDs []int `json:"assignee_ids"` + ReviewerIDs []int `json:"reviewer_ids"` + Title string `json:"title"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + MilestoneID int `json:"milestone_id"` + State string `json:"state"` + MergeStatus string `json:"merge_status"` + TargetProjectID int `json:"target_project_id"` + IID int `json:"iid"` + Description string `json:"description"` + Position int `json:"position"` + Labels []*EventLabel `json:"labels"` + LockedAt string `json:"locked_at"` + UpdatedByID int `json:"updated_by_id"` + MergeError string `json:"merge_error"` + MergeParams *MergeParams `json:"merge_params"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + MergeUserID int `json:"merge_user_id"` + MergeCommitSHA string `json:"merge_commit_sha"` + DeletedAt string `json:"deleted_at"` + InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` + LockVersion int `json:"lock_version"` + ApprovalsBeforeMerge string `json:"approvals_before_merge"` + RebaseCommitSHA string `json:"rebase_commit_sha"` + TimeEstimate int `json:"time_estimate"` + Squash bool `json:"squash"` + LastEditedAt string `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + Source *Repository `json:"source"` + Target *Repository `json:"target"` + LastCommit struct { + ID string `json:"id"` + Title string `json:"title"` + Message string `json:"message"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"last_commit"` + WorkInProgress bool `json:"work_in_progress"` + TotalTimeSpent int `json:"total_time_spent"` + HeadPipelineID int `json:"head_pipeline_id"` + Assignee *EventUser `json:"assignee"` + DetailedMergeStatus string `json:"detailed_merge_status"` + } `json:"merge_request"` +} + +// MergeEvent represents a merge event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#merge-request-events +type MergeEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *EventUser `json:"user"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + ObjectAttributes struct { + ID int `json:"id"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + AuthorID int `json:"author_id"` + AssigneeID int `json:"assignee_id"` + AssigneeIDs []int `json:"assignee_ids"` + ReviewerIDs []int `json:"reviewer_ids"` + Title string `json:"title"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468) + StCommits []*Commit `json:"st_commits"` + StDiffs []*Diff `json:"st_diffs"` + LastEditedAt string `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + MilestoneID int `json:"milestone_id"` + StateID StateID `json:"state_id"` + State string `json:"state"` + MergeStatus string `json:"merge_status"` + TargetProjectID int `json:"target_project_id"` + IID int `json:"iid"` + Description string `json:"description"` + Position int `json:"position"` + LockedAt string `json:"locked_at"` + UpdatedByID int `json:"updated_by_id"` + MergeError string `json:"merge_error"` + MergeParams *MergeParams `json:"merge_params"` + MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"` + MergeUserID int `json:"merge_user_id"` + MergeCommitSHA string `json:"merge_commit_sha"` + DeletedAt string `json:"deleted_at"` + ApprovalsBeforeMerge string `json:"approvals_before_merge"` + RebaseCommitSHA string `json:"rebase_commit_sha"` + InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"` + LockVersion int `json:"lock_version"` + TimeEstimate int `json:"time_estimate"` + Source *Repository `json:"source"` + Target *Repository `json:"target"` + HeadPipelineID *int `json:"head_pipeline_id"` + LastCommit struct { + ID string `json:"id"` + Message string `json:"message"` + Title string `json:"title"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"last_commit"` + BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` + WorkInProgress bool `json:"work_in_progress"` + Draft bool `json:"draft"` + TotalTimeSpent int `json:"total_time_spent"` + TimeChange int `json:"time_change"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + HumanTimeChange string `json:"human_time_change"` + HumanTimeEstimate string `json:"human_time_estimate"` + FirstContribution bool `json:"first_contribution"` + URL string `json:"url"` + Labels []*EventLabel `json:"labels"` + Action string `json:"action"` + DetailedMergeStatus string `json:"detailed_merge_status"` + OldRev string `json:"oldrev"` + } `json:"object_attributes"` + Repository *Repository `json:"repository"` + Labels []*EventLabel `json:"labels"` + Changes struct { + Assignees struct { + Previous []*EventUser `json:"previous"` + Current []*EventUser `json:"current"` + } `json:"assignees"` + Reviewers struct { + Previous []*EventUser `json:"previous"` + Current []*EventUser `json:"current"` + } `json:"reviewers"` + Description struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"description"` + Draft struct { + Previous bool `json:"previous"` + Current bool `json:"current"` + } `json:"draft"` + Labels struct { + Previous []*EventLabel `json:"previous"` + Current []*EventLabel `json:"current"` + } `json:"labels"` + LastEditedAt struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"last_edited_at"` + LastEditedByID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"last_edited_by_id"` + MergeStatus struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"merge_status"` + MilestoneID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"milestone_id"` + SourceBranch struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"source_branch"` + SourceProjectID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"source_project_id"` + StateID struct { + Previous StateID `json:"previous"` + Current StateID `json:"current"` + } `json:"state_id"` + TargetBranch struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"target_branch"` + TargetProjectID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"target_project_id"` + Title struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"title"` + UpdatedAt struct { + Previous string `json:"previous"` + Current string `json:"current"` + } `json:"updated_at"` + UpdatedByID struct { + Previous int `json:"previous"` + Current int `json:"current"` + } `json:"updated_by_id"` + } `json:"changes"` + Assignees []*EventUser `json:"assignees"` + Reviewers []*EventUser `json:"reviewers"` +} + +// EventUser represents a user record in an event and is used as an even +// initiator or a merge assignee. +type EventUser struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + AvatarURL string `json:"avatar_url"` + Email string `json:"email"` +} + +// MergeParams represents the merge params. +type MergeParams struct { + ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` +} + +// UnmarshalJSON decodes the merge parameters +// +// This allows support of ForceRemoveSourceBranch for both type +// bool (>11.9) and string (<11.9) +func (p *MergeParams) UnmarshalJSON(b []byte) error { + type Alias MergeParams + raw := struct { + *Alias + ForceRemoveSourceBranch any `json:"force_remove_source_branch"` + }{ + Alias: (*Alias)(p), + } + + err := json.Unmarshal(b, &raw) + if err != nil { + return err + } + + switch v := raw.ForceRemoveSourceBranch.(type) { + case nil: + // No action needed. + case bool: + p.ForceRemoveSourceBranch = v + case string: + p.ForceRemoveSourceBranch, err = strconv.ParseBool(v) + if err != nil { + return err + } + default: + return fmt.Errorf("failed to unmarshal ForceRemoveSourceBranch of type: %T", v) + } + + return nil +} + +// PipelineEvent represents a pipeline event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#pipeline-events +type PipelineEvent struct { + ObjectKind string `json:"object_kind"` + ObjectAttributes struct { + ID int `json:"id"` + IID int `json:"iid"` + Name string `json:"name"` + Ref string `json:"ref"` + Tag bool `json:"tag"` + SHA string `json:"sha"` + BeforeSHA string `json:"before_sha"` + Source string `json:"source"` + Status string `json:"status"` + DetailedStatus string `json:"detailed_status"` + Stages []string `json:"stages"` + CreatedAt string `json:"created_at"` + FinishedAt string `json:"finished_at"` + Duration int `json:"duration"` + QueuedDuration int `json:"queued_duration"` + URL string `json:"url"` + Variables []struct { + Key string `json:"key"` + Value string `json:"value"` + } `json:"variables"` + } `json:"object_attributes"` + MergeRequest struct { + ID int `json:"id"` + IID int `json:"iid"` + Title string `json:"title"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + TargetBranch string `json:"target_branch"` + TargetProjectID int `json:"target_project_id"` + State string `json:"state"` + MergeRequestStatus string `json:"merge_status"` + DetailedMergeStatus string `json:"detailed_merge_status"` + URL string `json:"url"` + } `json:"merge_request"` + User *EventUser `json:"user"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Commit struct { + ID string `json:"id"` + Message string `json:"message"` + Title string `json:"title"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commit"` + SourcePipeline struct { + Project struct { + ID int `json:"id"` + WebURL string `json:"web_url"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"project"` + PipelineID int `json:"pipeline_id"` + JobID int `json:"job_id"` + } `json:"source_pipeline"` + Builds []struct { + ID int `json:"id"` + Stage string `json:"stage"` + Name string `json:"name"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` + StartedAt string `json:"started_at"` + FinishedAt string `json:"finished_at"` + Duration float64 `json:"duration"` + QueuedDuration float64 `json:"queued_duration"` + FailureReason string `json:"failure_reason"` + When string `json:"when"` + Manual bool `json:"manual"` + AllowFailure bool `json:"allow_failure"` + User *EventUser `json:"user"` + Runner struct { + ID int `json:"id"` + Description string `json:"description"` + Active bool `json:"active"` + IsShared bool `json:"is_shared"` + RunnerType string `json:"runner_type"` + Tags []string `json:"tags"` + } `json:"runner"` + ArtifactsFile struct { + Filename string `json:"filename"` + Size int `json:"size"` + } `json:"artifacts_file"` + Environment struct { + Name string `json:"name"` + Action string `json:"action"` + DeploymentTier string `json:"deployment_tier"` + } `json:"environment"` + } `json:"builds"` +} + +// ProjectResourceAccessTokenEvent represents a resource access token event for +// a project. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#project-and-group-access-token-events +type ProjectResourceAccessTokenEvent struct { + EventName string `json:"event_name"` + ObjectKind string `json:"object_kind"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + } `json:"project"` + ObjectAttributes struct { + ID int `json:"id"` + UserID int `json:"user_id"` + Name string `json:"name"` + CreatedAt string `json:"created_at"` + ExpiresAt *ISOTime `json:"expires_at"` + } `json:"object_attributes"` +} + +// PushEvent represents a push event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#push-events +type PushEvent struct { + ObjectKind string `json:"object_kind"` + EventName string `json:"event_name"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserEmail string `json:"user_email"` + UserAvatar string `json:"user_avatar"` + ProjectID int `json:"project_id"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + Commits []*struct { + ID string `json:"id"` + Message string `json:"message"` + Title string `json:"title"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + Added []string `json:"added"` + Modified []string `json:"modified"` + Removed []string `json:"removed"` + } `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// ReleaseEvent represents a release event +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#release-events +type ReleaseEvent struct { + ID int `json:"id"` + CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468) + Description string `json:"description"` + Name string `json:"name"` + Tag string `json:"tag"` + ReleasedAt string `json:"released_at"` // Should be *time.Time (see Gitlab issue #21468) + ObjectKind string `json:"object_kind"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL *string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + VisibilityLevel int `json:"visibility_level"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + CIConfigPath string `json:"ci_config_path"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + } `json:"project"` + URL string `json:"url"` + Action string `json:"action"` + Assets struct { + Count int `json:"count"` + Links []struct { + ID int `json:"id"` + External bool `json:"external"` + LinkType string `json:"link_type"` + Name string `json:"name"` + URL string `json:"url"` + } `json:"links"` + Sources []struct { + Format string `json:"format"` + URL string `json:"url"` + } `json:"sources"` + } `json:"assets"` + Commit struct { + ID string `json:"id"` + Message string `json:"message"` + Title string `json:"title"` + Timestamp string `json:"timestamp"` // Should be *time.Time (see Gitlab issue #21468) + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + } `json:"commit"` +} + +// SnippetCommentEvent represents a comment on a snippet event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#comment-on-a-code-snippet +type SnippetCommentEvent struct { + ObjectKind string `json:"object_kind"` + EventType string `json:"event_type"` + User *EventUser `json:"user"` + ProjectID int `json:"project_id"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + ObjectAttributes struct { + ID int `json:"id"` + Note string `json:"note"` + NoteableType string `json:"noteable_type"` + AuthorID int `json:"author_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + ProjectID int `json:"project_id"` + Attachment string `json:"attachment"` + LineCode string `json:"line_code"` + CommitID string `json:"commit_id"` + NoteableID int `json:"noteable_id"` + System bool `json:"system"` + StDiff *Diff `json:"st_diff"` + Description string `json:"description"` + Action CommentEventAction `json:"action"` + URL string `json:"url"` + } `json:"object_attributes"` + Snippet *struct { + ID int `json:"id"` + Title string `json:"title"` + Content string `json:"content"` + AuthorID int `json:"author_id"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + Filename string `json:"file_name"` + ExpiresAt string `json:"expires_at"` + Type string `json:"type"` + VisibilityLevel int `json:"visibility_level"` + Description string `json:"description"` + Secret bool `json:"secret"` + RepositoryReadOnly bool `json:"repository_read_only"` + } `json:"snippet"` +} + +// SubGroupEvent represents a subgroup event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#subgroup-events +type SubGroupEvent struct { + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + EventName string `json:"event_name"` + Name string `json:"name"` + Path string `json:"path"` + FullPath string `json:"full_path"` + GroupID int `json:"group_id"` + ParentGroupID int `json:"parent_group_id"` + ParentName string `json:"parent_name"` + ParentPath string `json:"parent_path"` + ParentFullPath string `json:"parent_full_path"` +} + +// TagEvent represents a tag event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#tag-events +type TagEvent struct { + ObjectKind string `json:"object_kind"` + EventName string `json:"event_name"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + CheckoutSHA string `json:"checkout_sha"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + UserUsername string `json:"user_username"` + UserAvatar string `json:"user_avatar"` + UserEmail string `json:"user_email"` + ProjectID int `json:"project_id"` + Message string `json:"message"` + Project struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Repository *Repository `json:"repository"` + Commits []*struct { + ID string `json:"id"` + Message string `json:"message"` + Title string `json:"title"` + Timestamp *time.Time `json:"timestamp"` + URL string `json:"url"` + Author struct { + Name string `json:"name"` + Email string `json:"email"` + } `json:"author"` + Added []string `json:"added"` + Modified []string `json:"modified"` + Removed []string `json:"removed"` + } `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` +} + +// WikiPageEvent represents a wiki page event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#wiki-page-events +type WikiPageEvent struct { + ObjectKind string `json:"object_kind"` + User *EventUser `json:"user"` + Project struct { + Name string `json:"name"` + Description string `json:"description"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` + WebURL string `json:"web_url"` + Visibility VisibilityValue `json:"visibility"` + } `json:"project"` + Wiki struct { + WebURL string `json:"web_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + } `json:"wiki"` + ObjectAttributes struct { + Title string `json:"title"` + Content string `json:"content"` + Format string `json:"format"` + Message string `json:"message"` + Slug string `json:"slug"` + URL string `json:"url"` + Action string `json:"action"` + DiffURL string `json:"diff_url"` + } `json:"object_attributes"` +} + +// EventLabel represents a label inside a webhook event. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#work-item-events +type EventLabel struct { + ID int `json:"id"` + Title string `json:"title"` + Color string `json:"color"` + ProjectID int `json:"project_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + Template bool `json:"template"` + Description string `json:"description"` + Type string `json:"type"` + GroupID int `json:"group_id"` +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/events.go b/vendor/gitlab.com/gitlab-org/api/client-go/events.go new file mode 100644 index 000000000..a11d77cb2 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/events.go @@ -0,0 +1,241 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // EventsServiceInterface defines all the API methods for the EventsService + EventsServiceInterface interface { + ListCurrentUserContributionEvents(opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) + ListProjectVisibleEvents(pid any, opt *ListProjectVisibleEventsOptions, options ...RequestOptionFunc) ([]*ProjectEvent, *Response, error) + } + + // EventsService handles communication with the event related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/events/ + EventsService struct { + client *Client + } +) + +var _ EventsServiceInterface = (*EventsService)(nil) + +// ContributionEvent represents a user's contribution +// +// GitLab API docs: +// https://docs.gitlab.com/api/events/#get-user-contribution-events +type ContributionEvent struct { + ID int `json:"id"` + Title string `json:"title"` + ProjectID int `json:"project_id"` + ActionName string `json:"action_name"` + TargetID int `json:"target_id"` + TargetIID int `json:"target_iid"` + TargetType string `json:"target_type"` + AuthorID int `json:"author_id"` + TargetTitle string `json:"target_title"` + CreatedAt *time.Time `json:"created_at"` + PushData struct { + CommitCount int `json:"commit_count"` + Action string `json:"action"` + RefType string `json:"ref_type"` + CommitFrom string `json:"commit_from"` + CommitTo string `json:"commit_to"` + Ref string `json:"ref"` + CommitTitle string `json:"commit_title"` + } `json:"push_data"` + Note *Note `json:"note"` + Author struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"author"` + AuthorUsername string `json:"author_username"` +} + +// ListContributionEventsOptions represents the options for GetUserContributionEvents +// +// GitLap API docs: +// https://docs.gitlab.com/api/events/#get-user-contribution-events +type ListContributionEventsOptions struct { + ListOptions + Action *EventTypeValue `url:"action,omitempty" json:"action,omitempty"` + TargetType *EventTargetTypeValue `url:"target_type,omitempty" json:"target_type,omitempty"` + Before *ISOTime `url:"before,omitempty" json:"before,omitempty"` + After *ISOTime `url:"after,omitempty" json:"after,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListUserContributionEvents retrieves user contribution events +// for the specified user, sorted from newest to oldest. +// +// GitLab API docs: +// https://docs.gitlab.com/api/events/#get-user-contribution-events +func (s *UsersService) ListUserContributionEvents(uid any, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("users/%s/events", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var cs []*ContributionEvent + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// ListCurrentUserContributionEvents gets a list currently authenticated user's events +// +// GitLab API docs: https://docs.gitlab.com/api/events/#list-currently-authenticated-users-events +func (s *EventsService) ListCurrentUserContributionEvents(opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "events", opt, options) + if err != nil { + return nil, nil, err + } + + var cs []*ContributionEvent + resp, err := s.client.Do(req, &cs) + if err != nil { + return nil, resp, err + } + + return cs, resp, nil +} + +// ProjectEvent represents a GitLab project event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/events/#list-a-projects-visible-events +type ProjectEvent struct { + ID int `json:"id"` + Title string `json:"title"` + ProjectID int `json:"project_id"` + ActionName string `json:"action_name"` + TargetID int `json:"target_id"` + TargetIID int `json:"target_iid"` + TargetType string `json:"target_type"` + AuthorID int `json:"author_id"` + TargetTitle string `json:"target_title"` + CreatedAt string `json:"created_at"` + Author struct { + Name string `json:"name"` + Username string `json:"username"` + ID int `json:"id"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"author"` + AuthorUsername string `json:"author_username"` + Data struct { + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + UserID int `json:"user_id"` + UserName string `json:"user_name"` + Repository *Repository `json:"repository"` + Commits []*Commit `json:"commits"` + TotalCommitsCount int `json:"total_commits_count"` + } `json:"data"` + Note struct { + ID int `json:"id"` + Body string `json:"body"` + Attachment string `json:"attachment"` + Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"author"` + CreatedAt *time.Time `json:"created_at"` + System bool `json:"system"` + NoteableID int `json:"noteable_id"` + NoteableType string `json:"noteable_type"` + NoteableIID int `json:"noteable_iid"` + } `json:"note"` + PushData struct { + CommitCount int `json:"commit_count"` + Action string `json:"action"` + RefType string `json:"ref_type"` + CommitFrom string `json:"commit_from"` + CommitTo string `json:"commit_to"` + Ref string `json:"ref"` + CommitTitle string `json:"commit_title"` + } `json:"push_data"` +} + +func (s ProjectEvent) String() string { + return Stringify(s) +} + +// ListProjectVisibleEventsOptions represents the available +// ListProjectVisibleEvents() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/events/#list-a-projects-visible-events +type ListProjectVisibleEventsOptions struct { + ListOptions + Action *EventTypeValue `url:"action,omitempty" json:"action,omitempty"` + TargetType *EventTargetTypeValue `url:"target_type,omitempty" json:"target_type,omitempty"` + Before *ISOTime `url:"before,omitempty" json:"before,omitempty"` + After *ISOTime `url:"after,omitempty" json:"after,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListProjectVisibleEvents gets the events for the specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/events/#list-a-projects-visible-events +func (s *EventsService) ListProjectVisibleEvents(pid any, opt *ListProjectVisibleEventsOptions, options ...RequestOptionFunc) ([]*ProjectEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/events", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProjectEvent + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/external_status_checks.go b/vendor/gitlab.com/gitlab-org/api/client-go/external_status_checks.go new file mode 100644 index 000000000..caddb0815 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/external_status_checks.go @@ -0,0 +1,233 @@ +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // ExternalStatusChecksServiceInterface defines all the API methods for the ExternalStatusChecksService + ExternalStatusChecksServiceInterface interface { + ListMergeStatusChecks(pid any, mr int, opt *ListOptions, options ...RequestOptionFunc) ([]*MergeStatusCheck, *Response, error) + SetExternalStatusCheckStatus(pid any, mergeRequest int, opt *SetExternalStatusCheckStatusOptions, options ...RequestOptionFunc) (*Response, error) + ListProjectStatusChecks(pid any, opt *ListOptions, options ...RequestOptionFunc) ([]*ProjectStatusCheck, *Response, error) + CreateExternalStatusCheck(pid any, opt *CreateExternalStatusCheckOptions, options ...RequestOptionFunc) (*Response, error) + DeleteExternalStatusCheck(pid any, check int, options ...RequestOptionFunc) (*Response, error) + UpdateExternalStatusCheck(pid any, check int, opt *UpdateExternalStatusCheckOptions, options ...RequestOptionFunc) (*Response, error) + RetryFailedStatusCheckForAMergeRequest(pid any, mergeRequest int, externalStatusCheck int, options ...RequestOptionFunc) (*Response, error) + } + + // ExternalStatusChecksService handles communication with the external + // status check related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/status_checks/ + ExternalStatusChecksService struct { + client *Client + } +) + +var _ ExternalStatusChecksServiceInterface = (*ExternalStatusChecksService)(nil) + +type MergeStatusCheck struct { + ID int `json:"id"` + Name string `json:"name"` + ExternalURL string `json:"external_url"` + Status string `json:"status"` +} + +type ProjectStatusCheck struct { + ID int `json:"id"` + Name string `json:"name"` + ProjectID int `json:"project_id"` + ExternalURL string `json:"external_url"` + ProtectedBranches []StatusCheckProtectedBranch `json:"protected_branches"` +} + +type StatusCheckProtectedBranch struct { + ID int `json:"id"` + ProjectID int `json:"project_id"` + Name string `json:"name"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + CodeOwnerApprovalRequired bool `json:"code_owner_approval_required"` +} + +// ListMergeStatusChecks lists the external status checks that apply to it +// and their status for a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/status_checks/#list-status-checks-for-a-merge-request +func (s *ExternalStatusChecksService) ListMergeStatusChecks(pid any, mr int, opt *ListOptions, options ...RequestOptionFunc) ([]*MergeStatusCheck, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/status_checks", PathEscape(project), mr) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mscs []*MergeStatusCheck + resp, err := s.client.Do(req, &mscs) + if err != nil { + return nil, resp, err + } + + return mscs, resp, nil +} + +// SetExternalStatusCheckStatusOptions represents the available +// SetExternalStatusCheckStatus() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/status_checks/#set-status-of-an-external-status-check +type SetExternalStatusCheckStatusOptions struct { + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` + ExternalStatusCheckID *int `url:"external_status_check_id,omitempty" json:"external_status_check_id,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` +} + +// SetExternalStatusCheckStatus sets the status of an external status check. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/status_checks/#set-status-of-an-external-status-check +func (s *ExternalStatusChecksService) SetExternalStatusCheckStatus(pid any, mergeRequest int, opt *SetExternalStatusCheckStatusOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/status_check_responses", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListProjectStatusChecks lists the project external status checks. +// +// GitLab API docs: +// https://docs.gitlab.com/api/status_checks/#get-project-external-status-check-services +func (s *ExternalStatusChecksService) ListProjectStatusChecks(pid any, opt *ListOptions, options ...RequestOptionFunc) ([]*ProjectStatusCheck, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/external_status_checks", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pscs []*ProjectStatusCheck + resp, err := s.client.Do(req, &pscs) + if err != nil { + return nil, resp, err + } + + return pscs, resp, nil +} + +// CreateExternalStatusCheckOptions represents the available +// CreateExternalStatusCheck() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/status_checks/#create-external-status-check-service +type CreateExternalStatusCheckOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` + ProtectedBranchIDs *[]int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` +} + +// CreateExternalStatusCheck creates an external status check. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/status_checks/#create-external-status-check-service +func (s *ExternalStatusChecksService) CreateExternalStatusCheck(pid any, opt *CreateExternalStatusCheckOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/external_status_checks", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteExternalStatusCheck deletes an external status check. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/status_checks/#delete-external-status-check-service +func (s *ExternalStatusChecksService) DeleteExternalStatusCheck(pid any, check int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/external_status_checks/%d", PathEscape(project), check) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateExternalStatusCheckOptions represents the available +// UpdateExternalStatusCheck() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/status_checks/#update-external-status-check-service +type UpdateExternalStatusCheckOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` + ProtectedBranchIDs *[]int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` +} + +// UpdateExternalStatusCheck updates an external status check. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/status_checks/#update-external-status-check-service +func (s *ExternalStatusChecksService) UpdateExternalStatusCheck(pid any, check int, opt *UpdateExternalStatusCheckOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/external_status_checks/%d", PathEscape(project), check) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateExternalStatusCheck updates an external status check. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/status_checks/#retry-failed-status-check-for-a-merge-request +func (s *ExternalStatusChecksService) RetryFailedStatusCheckForAMergeRequest(pid any, mergeRequest int, externalStatusCheck int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/status_checks/%d/retry", PathEscape(project), mergeRequest, externalStatusCheck) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/feature_flag_user_lists.go b/vendor/gitlab.com/gitlab-org/api/client-go/feature_flag_user_lists.go new file mode 100644 index 000000000..5555a2831 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/feature_flag_user_lists.go @@ -0,0 +1,204 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + FeatureFlagUserListsServiceInterface interface { + ListFeatureFlagUserLists(pid any, opt *ListFeatureFlagUserListsOptions, options ...RequestOptionFunc) ([]*FeatureFlagUserList, *Response, error) + CreateFeatureFlagUserList(pid any, opt *CreateFeatureFlagUserListOptions, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) + GetFeatureFlagUserList(pid any, iid int, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) + UpdateFeatureFlagUserList(pid any, iid int, opt *UpdateFeatureFlagUserListOptions, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) + DeleteFeatureFlagUserList(pid any, iid int, options ...RequestOptionFunc) (*Response, error) + } + + // FeatureFlagUserListService handles communication with the feature flag + // user list related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/feature_flag_user_lists/ + FeatureFlagUserListsService struct { + client *Client + } +) + +var _ FeatureFlagUserListsServiceInterface = (*FeatureFlagUserListsService)(nil) + +// FeatureFlagUserList represents a project feature flag user list. +// +// GitLab API docs: https://docs.gitlab.com/api/feature_flag_user_lists/ +type FeatureFlagUserList struct { + Name string `url:"name" json:"name"` + UserXIDs string `url:"user_xids" json:"user_xids"` + ID int `url:"id" json:"id"` + IID int `url:"iid" json:"iid"` + ProjectID int `url:"project_id" json:"project_id"` + CreatedAt *time.Time `url:"created_at" json:"created_at"` + UpdatedAt *time.Time `url:"updated_at" json:"updated_at"` +} + +// ListFeatureFlagUserListsOptions represents the available +// ListFeatureFlagUserLists() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#list-all-feature-flag-user-lists-for-a-project +type ListFeatureFlagUserListsOptions struct { + ListOptions + Search string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListFeatureFlagUserLists gets all feature flag user lists for the requested +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#list-all-feature-flag-user-lists-for-a-project +func (s *FeatureFlagUserListsService) ListFeatureFlagUserLists(pid any, opt *ListFeatureFlagUserListsOptions, options ...RequestOptionFunc) ([]*FeatureFlagUserList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags_user_lists", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var lists []*FeatureFlagUserList + resp, err := s.client.Do(req, &lists) + if err != nil { + return nil, resp, err + } + + return lists, resp, nil +} + +// CreateFeatureFlagUserListOptions represents the available +// CreateFeatureFlagUserList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#create-a-feature-flag-user-list +type CreateFeatureFlagUserListOptions struct { + Name string `url:"name,omitempty" json:"name,omitempty"` + UserXIDs string `url:"user_xids,omitempty" json:"user_xids,omitempty"` +} + +// CreateFeatureFlagUserList creates a feature flag user list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#create-a-feature-flag-user-list +func (s *FeatureFlagUserListsService) CreateFeatureFlagUserList(pid any, opt *CreateFeatureFlagUserListOptions, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags_user_lists", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + list := new(FeatureFlagUserList) + resp, err := s.client.Do(req, list) + if err != nil { + return nil, resp, err + } + + return list, resp, nil +} + +// GetFeatureFlagUserList gets a feature flag user list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#get-a-feature-flag-user-list +func (s *FeatureFlagUserListsService) GetFeatureFlagUserList(pid any, iid int, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags_user_lists/%d", PathEscape(project), iid) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + list := new(FeatureFlagUserList) + resp, err := s.client.Do(req, list) + if err != nil { + return nil, resp, err + } + + return list, resp, nil +} + +// UpdateFeatureFlagUserListOptions represents the available +// UpdateFeatureFlagUserList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#update-a-feature-flag-user-list +type UpdateFeatureFlagUserListOptions struct { + Name string `url:"name,omitempty" json:"name,omitempty"` + UserXIDs string `url:"user_xids,omitempty" json:"user_xids,omitempty"` +} + +// UpdateFeatureFlagUserList updates a feature flag user list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#update-a-feature-flag-user-list +func (s *FeatureFlagUserListsService) UpdateFeatureFlagUserList(pid any, iid int, opt *UpdateFeatureFlagUserListOptions, options ...RequestOptionFunc) (*FeatureFlagUserList, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags_user_lists/%d", PathEscape(project), iid) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + list := new(FeatureFlagUserList) + resp, err := s.client.Do(req, list) + if err != nil { + return nil, resp, err + } + + return list, resp, nil +} + +// DeleteFeatureFlagUserList deletes a feature flag user list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flag_user_lists/#delete-feature-flag-user-list +func (s *FeatureFlagUserListsService) DeleteFeatureFlagUserList(pid any, iid int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags_user_lists/%d", PathEscape(project), iid) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/feature_flags.go b/vendor/gitlab.com/gitlab-org/api/client-go/feature_flags.go new file mode 100644 index 000000000..d0a5d84d7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/feature_flags.go @@ -0,0 +1,172 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + // FeaturesServiceInterface defines all the API methods for the FeaturesService + FeaturesServiceInterface interface { + ListFeatures(options ...RequestOptionFunc) ([]*Feature, *Response, error) + ListFeatureDefinitions(options ...RequestOptionFunc) ([]*FeatureDefinition, *Response, error) + SetFeatureFlag(name string, opt *SetFeatureFlagOptions, options ...RequestOptionFunc) (*Feature, *Response, error) + DeleteFeatureFlag(name string, options ...RequestOptionFunc) (*Response, error) + } + + // FeaturesService handles the communication with the application FeaturesService + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/features/ + FeaturesService struct { + client *Client + } +) + +var _ FeaturesServiceInterface = (*FeaturesService)(nil) + +// Feature represents a GitLab feature flag. +// +// GitLab API docs: https://docs.gitlab.com/api/features/ +type Feature struct { + Name string `json:"name"` + State string `json:"state"` + Gates []Gate + Definition *FeatureDefinition `json:"definition"` +} + +// Gate represents a gate of a GitLab feature flag. +// +// GitLab API docs: https://docs.gitlab.com/api/features/ +type Gate struct { + Key string `json:"key"` + Value any `json:"value"` +} + +func (f Feature) String() string { + return Stringify(f) +} + +// ListFeatures gets a list of feature flags +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#list-all-features +func (s *FeaturesService) ListFeatures(options ...RequestOptionFunc) ([]*Feature, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "features", nil, options) + if err != nil { + return nil, nil, err + } + + var f []*Feature + resp, err := s.client.Do(req, &f) + if err != nil { + return nil, resp, err + } + return f, resp, nil +} + +// FeatureDefinition represents a Feature Definition. +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#list-all-feature-definitions +type FeatureDefinition struct { + Name string `json:"name"` + IntroducedByURL string `json:"introduced_by_url"` + RolloutIssueURL string `json:"rollout_issue_url"` + Milestone string `json:"milestone"` + LogStateChanges bool `json:"log_state_changes"` + Type string `json:"type"` + Group string `json:"group"` + DefaultEnabled bool `json:"default_enabled"` +} + +func (fd FeatureDefinition) String() string { + return Stringify(fd) +} + +// ListFeatureDefinitions gets a lists of all feature definitions. +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#list-all-feature-definitions +func (s *FeaturesService) ListFeatureDefinitions(options ...RequestOptionFunc) ([]*FeatureDefinition, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "features/definitions", nil, options) + if err != nil { + return nil, nil, err + } + + var fd []*FeatureDefinition + resp, err := s.client.Do(req, &fd) + if err != nil { + return nil, resp, err + } + return fd, resp, nil +} + +// SetFeatureFlagOptions represents the available options for +// SetFeatureFlag(). +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#set-or-create-a-feature +type SetFeatureFlagOptions struct { + Value any `url:"value" json:"value"` + Key string `url:"key" json:"key"` + FeatureGroup string `url:"feature_group" json:"feature_group"` + User string `url:"user" json:"user"` + Group string `url:"group" json:"group"` + Namespace string `url:"namespace" json:"namespace"` + Project string `url:"project" json:"project"` + Repository string `url:"repository" json:"repository"` + Force bool `url:"force" json:"force"` +} + +// SetFeatureFlag sets or creates a feature flag gate +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#set-or-create-a-feature +func (s *FeaturesService) SetFeatureFlag(name string, opt *SetFeatureFlagOptions, options ...RequestOptionFunc) (*Feature, *Response, error) { + u := fmt.Sprintf("features/%s", url.PathEscape(name)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + f := &Feature{} + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + return f, resp, nil +} + +// DeleteFeatureFlag deletes a feature flag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/features/#delete-a-feature +func (s *FeaturesService) DeleteFeatureFlag(name string, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("features/%s", url.PathEscape(name)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/freeze_periods.go b/vendor/gitlab.com/gitlab-org/api/client-go/freeze_periods.go similarity index 53% rename from vendor/github.com/xanzy/go-gitlab/freeze_periods.go rename to vendor/gitlab.com/gitlab-org/api/client-go/freeze_periods.go index f7483f326..cf6d3f854 100644 --- a/vendor/github.com/xanzy/go-gitlab/freeze_periods.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/freeze_periods.go @@ -1,5 +1,5 @@ // -// Copyright 2020 Paul Cioanca +// Copyright 2021 Paul Cioanca // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,21 +18,39 @@ package gitlab import ( "fmt" + "net/http" "time" ) // FreezePeriodsService handles the communication with the freeze periods // related methods of the GitLab API. // -// https://docs.gitlab.com/ce/api/freeze_periods.html -type FreezePeriodsService struct { - client *Client -} +// https://docs.gitlab.com/api/freeze_periods/ +type ( + // FreezePeriodsServiceInterface defines all the API methods for the FreezePeriodsService + FreezePeriodsServiceInterface interface { + ListFreezePeriods(pid any, opt *ListFreezePeriodsOptions, options ...RequestOptionFunc) ([]*FreezePeriod, *Response, error) + GetFreezePeriod(pid any, freezePeriod int, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) + CreateFreezePeriodOptions(pid any, opt *CreateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) + UpdateFreezePeriodOptions(pid any, freezePeriod int, opt *UpdateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) + DeleteFreezePeriod(pid any, freezePeriod int, options ...RequestOptionFunc) (*Response, error) + } + + // FreezePeriodsService handles the communication with the freeze periods + // related methods of the GitLab API. + // + // https://docs.gitlab.com/api/freeze_periods/ + FreezePeriodsService struct { + client *Client + } +) + +var _ FreezePeriodsServiceInterface = (*FreezePeriodsService)(nil) // FreezePeriod represents a freeze period object. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods +// https://docs.gitlab.com/api/freeze_periods/#list-freeze-periods type FreezePeriod struct { ID int `json:"id"` FreezeStart string `json:"freeze_start"` @@ -46,21 +64,21 @@ type FreezePeriod struct { // options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods +// https://docs.gitlab.com/api/freeze_periods/#list-freeze-periods type ListFreezePeriodsOptions ListOptions // ListFreezePeriods gets a list of project project freeze periods. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods -func (s *FreezePeriodsService) ListFreezePeriods(pid interface{}, opt *ListFreezePeriodsOptions, options ...RequestOptionFunc) ([]*FreezePeriod, *Response, error) { +// https://docs.gitlab.com/api/freeze_periods/#list-freeze-periods +func (s *FreezePeriodsService) ListFreezePeriods(pid any, opt *ListFreezePeriodsOptions, options ...RequestOptionFunc) ([]*FreezePeriod, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/freeze_periods", pathEscape(project)) + u := fmt.Sprintf("projects/%s/freeze_periods", PathEscape(project)) - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -71,21 +89,21 @@ func (s *FreezePeriodsService) ListFreezePeriods(pid interface{}, opt *ListFreez return nil, resp, err } - return fp, resp, err + return fp, resp, nil } // GetFreezePeriod gets a specific freeze period for a project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#get-a-freeze-period-by-a-freeze_period_id -func (s *FreezePeriodsService) GetFreezePeriod(pid interface{}, freezePeriod int, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { +// https://docs.gitlab.com/api/freeze_periods/#get-a-freeze-period-by-a-freeze_period_id +func (s *FreezePeriodsService) GetFreezePeriod(pid any, freezePeriod int, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod) + u := fmt.Sprintf("projects/%s/freeze_periods/%d", PathEscape(project), freezePeriod) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -96,14 +114,14 @@ func (s *FreezePeriodsService) GetFreezePeriod(pid interface{}, freezePeriod int return nil, resp, err } - return fp, resp, err + return fp, resp, nil } // CreateFreezePeriodOptions represents the available CreateFreezePeriodOptions() // options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#create-a-freeze-period +// https://docs.gitlab.com/api/freeze_periods/#create-a-freeze-period type CreateFreezePeriodOptions struct { FreezeStart *string `url:"freeze_start,omitempty" json:"freeze_start,omitempty"` FreezeEnd *string `url:"freeze_end,omitempty" json:"freeze_end,omitempty"` @@ -113,15 +131,15 @@ type CreateFreezePeriodOptions struct { // CreateFreezePeriodOptions adds a freeze period to a specified project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#create-a-freeze-period -func (s *FreezePeriodsService) CreateFreezePeriodOptions(pid interface{}, opt *CreateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { +// https://docs.gitlab.com/api/freeze_periods/#create-a-freeze-period +func (s *FreezePeriodsService) CreateFreezePeriodOptions(pid any, opt *CreateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/freeze_periods", pathEscape(project)) + u := fmt.Sprintf("projects/%s/freeze_periods", PathEscape(project)) - req, err := s.client.NewRequest("POST", u, opt, options) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } @@ -132,14 +150,14 @@ func (s *FreezePeriodsService) CreateFreezePeriodOptions(pid interface{}, opt *C return nil, resp, err } - return fp, resp, err + return fp, resp, nil } // UpdateFreezePeriodOptions represents the available UpdateFreezePeriodOptions() // options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#update-a-freeze-period +// https://docs.gitlab.com/api/freeze_periods/#update-a-freeze-period type UpdateFreezePeriodOptions struct { FreezeStart *string `url:"freeze_start,omitempty" json:"freeze_start,omitempty"` FreezeEnd *string `url:"freeze_end,omitempty" json:"freeze_end,omitempty"` @@ -149,15 +167,15 @@ type UpdateFreezePeriodOptions struct { // UpdateFreezePeriodOptions edits a freeze period for a specified project. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#update-a-freeze-period -func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid interface{}, freezePeriod int, opt *UpdateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { +// https://docs.gitlab.com/api/freeze_periods/#update-a-freeze-period +func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid any, freezePeriod int, opt *UpdateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod) + u := fmt.Sprintf("projects/%s/freeze_periods/%d", PathEscape(project), freezePeriod) - req, err := s.client.NewRequest("PUT", u, opt, options) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } @@ -168,7 +186,7 @@ func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid interface{}, freeze return nil, resp, err } - return fp, resp, err + return fp, resp, nil } // DeleteFreezePeriod removes a freeze period from a project. This is an @@ -176,15 +194,15 @@ func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid interface{}, freeze // available or not. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/freeze_periods.html#delete-a-freeze-period -func (s *FreezePeriodsService) DeleteFreezePeriod(pid interface{}, freezePeriod int, options ...RequestOptionFunc) (*Response, error) { +// https://docs.gitlab.com/api/freeze_periods/#delete-a-freeze-period +func (s *FreezePeriodsService) DeleteFreezePeriod(pid any, freezePeriod int, options ...RequestOptionFunc) (*Response, error) { project, err := parseID(pid) if err != nil { return nil, err } - u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod) + u := fmt.Sprintf("projects/%s/freeze_periods/%d", PathEscape(project), freezePeriod) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/generic_packages.go b/vendor/gitlab.com/gitlab-org/api/client-go/generic_packages.go new file mode 100644 index 000000000..e80fb5bbd --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/generic_packages.go @@ -0,0 +1,169 @@ +// +// Copyright 2021, Sune Keller +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/http" + "time" +) + +type ( + // GenericPackagesServiceInterface defines all the API methods for the GenericPackagesService + GenericPackagesServiceInterface interface { + FormatPackageURL(pid any, packageName, packageVersion, fileName string) (string, error) + PublishPackageFile(pid any, packageName, packageVersion, fileName string, content io.Reader, opt *PublishPackageFileOptions, options ...RequestOptionFunc) (*GenericPackagesFile, *Response, error) + DownloadPackageFile(pid any, packageName, packageVersion, fileName string, options ...RequestOptionFunc) ([]byte, *Response, error) + } + + // GenericPackagesService handles communication with the packages related + // methods of the GitLab API. + // + // GitLab docs: + // https://docs.gitlab.com/user/packages/generic_packages/ + GenericPackagesService struct { + client *Client + } +) + +var _ GenericPackagesServiceInterface = (*GenericPackagesService)(nil) + +// GenericPackagesFile represents a GitLab generic package file. +// +// GitLab API docs: +// https://docs.gitlab.com/user/packages/generic_packages/#publish-a-single-file +type GenericPackagesFile struct { + ID int `json:"id"` + PackageID int `json:"package_id"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Size int `json:"size"` + FileStore int `json:"file_store"` + FileMD5 string `json:"file_md5"` + FileSHA1 string `json:"file_sha1"` + FileName string `json:"file_name"` + File struct { + URL string `json:"url"` + } `json:"file"` + FileSHA256 string `json:"file_sha256"` + VerificationRetryAt *time.Time `json:"verification_retry_at"` + VerifiedAt *time.Time `json:"verified_at"` + VerificationFailure bool `json:"verification_failure"` + VerificationRetryCount int `json:"verification_retry_count"` + VerificationChecksum string `json:"verification_checksum"` + VerificationState int `json:"verification_state"` + VerificationStartedAt *time.Time `json:"verification_started_at"` + NewFilePath string `json:"new_file_path"` +} + +// FormatPackageURL returns the GitLab Package Registry URL for the given artifact metadata, without the BaseURL. +// This does not make a GitLab API request, but rather computes it based on their documentation. +func (s *GenericPackagesService) FormatPackageURL(pid any, packageName, packageVersion, fileName string) (string, error) { + project, err := parseID(pid) + if err != nil { + return "", err + } + u := fmt.Sprintf( + "projects/%s/packages/generic/%s/%s/%s", + PathEscape(project), + PathEscape(packageName), + PathEscape(packageVersion), + PathEscape(fileName), + ) + return u, nil +} + +// PublishPackageFileOptions represents the available PublishPackageFile() +// options. +// +// GitLab docs: +// https://docs.gitlab.com/user/packages/generic_packages/#publish-a-single-file +type PublishPackageFileOptions struct { + Status *GenericPackageStatusValue `url:"status,omitempty" json:"status,omitempty"` + Select *GenericPackageSelectValue `url:"select,omitempty" json:"select,omitempty"` +} + +// PublishPackageFile uploads a file to a project's package registry. +// +// GitLab docs: +// https://docs.gitlab.com/user/packages/generic_packages/#publish-a-single-file +func (s *GenericPackagesService) PublishPackageFile(pid any, packageName, packageVersion, fileName string, content io.Reader, opt *PublishPackageFileOptions, options ...RequestOptionFunc) (*GenericPackagesFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/packages/generic/%s/%s/%s", + PathEscape(project), + PathEscape(packageName), + PathEscape(packageVersion), + PathEscape(fileName), + ) + + // We need to create the request as a GET request to make sure the options + // are set correctly. After the request is created we will overwrite both + // the method and the body. + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + // Overwrite the method and body. + req.Method = http.MethodPut + req.SetBody(content) + + f := new(GenericPackagesFile) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, nil +} + +// DownloadPackageFile allows you to download the package file. +// +// GitLab docs: +// https://docs.gitlab.com/user/packages/generic_packages/#download-a-single-file +func (s *GenericPackagesService) DownloadPackageFile(pid any, packageName, packageVersion, fileName string, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/packages/generic/%s/%s/%s", + PathEscape(project), + PathEscape(packageName), + PathEscape(packageVersion), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var f bytes.Buffer + resp, err := s.client.Do(req, &f) + if err != nil { + return nil, resp, err + } + + return f.Bytes(), resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/geo_nodes.go b/vendor/gitlab.com/gitlab-org/api/client-go/geo_nodes.go new file mode 100644 index 000000000..124cc8312 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/geo_nodes.go @@ -0,0 +1,473 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + GeoNodesServiceInterface interface { + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + CreateGeoNode(*CreateGeoNodesOptions, ...RequestOptionFunc) (*GeoNode, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + ListGeoNodes(*ListGeoNodesOptions, ...RequestOptionFunc) ([]*GeoNode, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + GetGeoNode(int, ...RequestOptionFunc) (*GeoNode, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + EditGeoNode(int, *UpdateGeoNodesOptions, ...RequestOptionFunc) (*GeoNode, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + DeleteGeoNode(int, ...RequestOptionFunc) (*Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + RepairGeoNode(int, ...RequestOptionFunc) (*GeoNode, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + RetrieveStatusOfAllGeoNodes(...RequestOptionFunc) ([]*GeoNodeStatus, *Response, error) + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + RetrieveStatusOfGeoNode(int, ...RequestOptionFunc) (*GeoNodeStatus, *Response, error) + } + + // GeoNodesService handles communication with Geo Nodes related methods + // of GitLab API. + // Deprecated: will be removed in v5 of the API, use Geo Sites API instead + // + // GitLab API docs: https://docs.gitlab.com/api/geo_nodes/ + GeoNodesService struct { + client *Client + } +) + +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +var _ GeoNodesServiceInterface = (*GeoNodesService)(nil) + +// GeoNode represents a GitLab Geo Node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: https://docs.gitlab.com/api/geo_nodes/ +type GeoNode struct { + ID int `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + InternalURL string `json:"internal_url"` + Primary bool `json:"primary"` + Enabled bool `json:"enabled"` + Current bool `json:"current"` + FilesMaxCapacity int `json:"files_max_capacity"` + ReposMaxCapacity int `json:"repos_max_capacity"` + VerificationMaxCapacity int `json:"verification_max_capacity"` + SelectiveSyncType string `json:"selective_sync_type"` + SelectiveSyncShards []string `json:"selective_sync_shards"` + SelectiveSyncNamespaceIds []int `json:"selective_sync_namespace_ids"` + MinimumReverificationInterval int `json:"minimum_reverification_interval"` + ContainerRepositoriesMaxCapacity int `json:"container_repositories_max_capacity"` + SyncObjectStorage bool `json:"sync_object_storage"` + CloneProtocol string `json:"clone_protocol"` + WebEditURL string `json:"web_edit_url"` + WebGeoProjectsURL string `json:"web_geo_projects_url"` + Links GeoNodeLinks `json:"_links"` +} + +// GeoNodeLinks represents links for GitLab GeoNode. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: https://docs.gitlab.com/api/geo_nodes/ +type GeoNodeLinks struct { + Self string `json:"self"` + Status string `json:"status"` + Repair string `json:"repair"` +} + +// CreateGeoNodesOptions represents the available CreateGeoNode() options. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#create-a-new-geo-node +type CreateGeoNodesOptions struct { + Primary *bool `url:"primary,omitempty" json:"primary,omitempty"` + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + InternalURL *string `url:"internal_url,omitempty" json:"internal_url,omitempty"` + FilesMaxCapacity *int `url:"files_max_capacity,omitempty" json:"files_max_capacity,omitempty"` + ReposMaxCapacity *int `url:"repos_max_capacity,omitempty" json:"repos_max_capacity,omitempty"` + VerificationMaxCapacity *int `url:"verification_max_capacity,omitempty" json:"verification_max_capacity,omitempty"` + ContainerRepositoriesMaxCapacity *int `url:"container_repositories_max_capacity,omitempty" json:"container_repositories_max_capacity,omitempty"` + SyncObjectStorage *bool `url:"sync_object_storage,omitempty" json:"sync_object_storage,omitempty"` + SelectiveSyncType *string `url:"selective_sync_type,omitempty" json:"selective_sync_type,omitempty"` + SelectiveSyncShards *[]string `url:"selective_sync_shards,omitempty" json:"selective_sync_shards,omitempty"` + SelectiveSyncNamespaceIds *[]int `url:"selective_sync_namespace_ids,omitempty" json:"selective_sync_namespace_ids,omitempty"` + MinimumReverificationInterval *int `url:"minimum_reverification_interval,omitempty" json:"minimum_reverification_interval,omitempty"` +} + +// CreateGeoNode creates a new Geo Node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#create-a-new-geo-node +func (s *GeoNodesService) CreateGeoNode(opt *CreateGeoNodesOptions, options ...RequestOptionFunc) (*GeoNode, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "geo_nodes", opt, options) + if err != nil { + return nil, nil, err + } + + g := new(GeoNode) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// ListGeoNodesOptions represents the available ListGeoNodes() options. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-configuration-about-all-geo-nodes +type ListGeoNodesOptions ListOptions + +// ListGeoNodes gets a list of geo nodes. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-configuration-about-all-geo-nodes +func (s *GeoNodesService) ListGeoNodes(opt *ListGeoNodesOptions, options ...RequestOptionFunc) ([]*GeoNode, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "geo_nodes", opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*GeoNode + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// GetGeoNode gets a specific geo node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-configuration-about-a-specific-geo-node +func (s *GeoNodesService) GetGeoNode(id int, options ...RequestOptionFunc) (*GeoNode, *Response, error) { + u := fmt.Sprintf("geo_nodes/%d", id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(GeoNode) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// UpdateGeoNodesOptions represents the available EditGeoNode() options. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#edit-a-geo-node +type UpdateGeoNodesOptions struct { + ID *int `url:"primary,omitempty" json:"primary,omitempty"` + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + InternalURL *string `url:"internal_url,omitempty" json:"internal_url,omitempty"` + FilesMaxCapacity *int `url:"files_max_capacity,omitempty" json:"files_max_capacity,omitempty"` + ReposMaxCapacity *int `url:"repos_max_capacity,omitempty" json:"repos_max_capacity,omitempty"` + VerificationMaxCapacity *int `url:"verification_max_capacity,omitempty" json:"verification_max_capacity,omitempty"` + ContainerRepositoriesMaxCapacity *int `url:"container_repositories_max_capacity,omitempty" json:"container_repositories_max_capacity,omitempty"` + SyncObjectStorage *bool `url:"sync_object_storage,omitempty" json:"sync_object_storage,omitempty"` + SelectiveSyncType *string `url:"selective_sync_type,omitempty" json:"selective_sync_type,omitempty"` + SelectiveSyncShards *[]string `url:"selective_sync_shards,omitempty" json:"selective_sync_shards,omitempty"` + SelectiveSyncNamespaceIds *[]int `url:"selective_sync_namespace_ids,omitempty" json:"selective_sync_namespace_ids,omitempty"` + MinimumReverificationInterval *int `url:"minimum_reverification_interval,omitempty" json:"minimum_reverification_interval,omitempty"` +} + +// EditGeoNode updates settings of an existing Geo node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#edit-a-geo-node +func (s *GeoNodesService) EditGeoNode(id int, opt *UpdateGeoNodesOptions, options ...RequestOptionFunc) (*GeoNode, *Response, error) { + u := fmt.Sprintf("geo_nodes/%d", id) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(GeoNode) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// DeleteGeoNode removes the Geo node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#delete-a-geo-node +func (s *GeoNodesService) DeleteGeoNode(id int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("geo_nodes/%d", id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RepairGeoNode to repair the OAuth authentication of a Geo node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#repair-a-geo-node +func (s *GeoNodesService) RepairGeoNode(id int, options ...RequestOptionFunc) (*GeoNode, *Response, error) { + u := fmt.Sprintf("geo_nodes/%d/repair", id) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(GeoNode) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// GeoNodeStatus represents the status of Geo Node. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-status-about-all-geo-nodes +type GeoNodeStatus struct { + GeoNodeID int `json:"geo_node_id"` + Healthy bool `json:"healthy"` + Health string `json:"health"` + HealthStatus string `json:"health_status"` + MissingOauthApplication bool `json:"missing_oauth_application"` + AttachmentsCount int `json:"attachments_count"` + AttachmentsSyncedCount int `json:"attachments_synced_count"` + AttachmentsFailedCount int `json:"attachments_failed_count"` + AttachmentsSyncedMissingOnPrimaryCount int `json:"attachments_synced_missing_on_primary_count"` + AttachmentsSyncedInPercentage string `json:"attachments_synced_in_percentage"` + DbReplicationLagSeconds int `json:"db_replication_lag_seconds"` + LfsObjectsCount int `json:"lfs_objects_count"` + LfsObjectsSyncedCount int `json:"lfs_objects_synced_count"` + LfsObjectsFailedCount int `json:"lfs_objects_failed_count"` + LfsObjectsSyncedMissingOnPrimaryCount int `json:"lfs_objects_synced_missing_on_primary_count"` + LfsObjectsSyncedInPercentage string `json:"lfs_objects_synced_in_percentage"` + JobArtifactsCount int `json:"job_artifacts_count"` + JobArtifactsSyncedCount int `json:"job_artifacts_synced_count"` + JobArtifactsFailedCount int `json:"job_artifacts_failed_count"` + JobArtifactsSyncedMissingOnPrimaryCount int `json:"job_artifacts_synced_missing_on_primary_count"` + JobArtifactsSyncedInPercentage string `json:"job_artifacts_synced_in_percentage"` + ContainerRepositoriesCount int `json:"container_repositories_count"` + ContainerRepositoriesSyncedCount int `json:"container_repositories_synced_count"` + ContainerRepositoriesFailedCount int `json:"container_repositories_failed_count"` + ContainerRepositoriesSyncedInPercentage string `json:"container_repositories_synced_in_percentage"` + DesignRepositoriesCount int `json:"design_repositories_count"` + DesignRepositoriesSyncedCount int `json:"design_repositories_synced_count"` + DesignRepositoriesFailedCount int `json:"design_repositories_failed_count"` + DesignRepositoriesSyncedInPercentage string `json:"design_repositories_synced_in_percentage"` + ProjectsCount int `json:"projects_count"` + RepositoriesCount int `json:"repositories_count"` + RepositoriesFailedCount int `json:"repositories_failed_count"` + RepositoriesSyncedCount int `json:"repositories_synced_count"` + RepositoriesSyncedInPercentage string `json:"repositories_synced_in_percentage"` + WikisCount int `json:"wikis_count"` + WikisFailedCount int `json:"wikis_failed_count"` + WikisSyncedCount int `json:"wikis_synced_count"` + WikisSyncedInPercentage string `json:"wikis_synced_in_percentage"` + ReplicationSlotsCount int `json:"replication_slots_count"` + ReplicationSlotsUsedCount int `json:"replication_slots_used_count"` + ReplicationSlotsUsedInPercentage string `json:"replication_slots_used_in_percentage"` + ReplicationSlotsMaxRetainedWalBytes int `json:"replication_slots_max_retained_wal_bytes"` + RepositoriesCheckedCount int `json:"repositories_checked_count"` + RepositoriesCheckedFailedCount int `json:"repositories_checked_failed_count"` + RepositoriesCheckedInPercentage string `json:"repositories_checked_in_percentage"` + RepositoriesChecksummedCount int `json:"repositories_checksummed_count"` + RepositoriesChecksumFailedCount int `json:"repositories_checksum_failed_count"` + RepositoriesChecksummedInPercentage string `json:"repositories_checksummed_in_percentage"` + WikisChecksummedCount int `json:"wikis_checksummed_count"` + WikisChecksumFailedCount int `json:"wikis_checksum_failed_count"` + WikisChecksummedInPercentage string `json:"wikis_checksummed_in_percentage"` + RepositoriesVerifiedCount int `json:"repositories_verified_count"` + RepositoriesVerificationFailedCount int `json:"repositories_verification_failed_count"` + RepositoriesVerifiedInPercentage string `json:"repositories_verified_in_percentage"` + RepositoriesChecksumMismatchCount int `json:"repositories_checksum_mismatch_count"` + WikisVerifiedCount int `json:"wikis_verified_count"` + WikisVerificationFailedCount int `json:"wikis_verification_failed_count"` + WikisVerifiedInPercentage string `json:"wikis_verified_in_percentage"` + WikisChecksumMismatchCount int `json:"wikis_checksum_mismatch_count"` + RepositoriesRetryingVerificationCount int `json:"repositories_retrying_verification_count"` + WikisRetryingVerificationCount int `json:"wikis_retrying_verification_count"` + LastEventID int `json:"last_event_id"` + LastEventTimestamp int `json:"last_event_timestamp"` + CursorLastEventID int `json:"cursor_last_event_id"` + CursorLastEventTimestamp int `json:"cursor_last_event_timestamp"` + LastSuccessfulStatusCheckTimestamp int `json:"last_successful_status_check_timestamp"` + Version string `json:"version"` + Revision string `json:"revision"` + MergeRequestDiffsCount int `json:"merge_request_diffs_count"` + MergeRequestDiffsChecksumTotalCount int `json:"merge_request_diffs_checksum_total_count"` + MergeRequestDiffsChecksummedCount int `json:"merge_request_diffs_checksummed_count"` + MergeRequestDiffsChecksumFailedCount int `json:"merge_request_diffs_checksum_failed_count"` + MergeRequestDiffsSyncedCount int `json:"merge_request_diffs_synced_count"` + MergeRequestDiffsFailedCount int `json:"merge_request_diffs_failed_count"` + MergeRequestDiffsRegistryCount int `json:"merge_request_diffs_registry_count"` + MergeRequestDiffsVerificationTotalCount int `json:"merge_request_diffs_verification_total_count"` + MergeRequestDiffsVerifiedCount int `json:"merge_request_diffs_verified_count"` + MergeRequestDiffsVerificationFailedCount int `json:"merge_request_diffs_verification_failed_count"` + MergeRequestDiffsSyncedInPercentage string `json:"merge_request_diffs_synced_in_percentage"` + MergeRequestDiffsVerifiedInPercentage string `json:"merge_request_diffs_verified_in_percentage"` + PackageFilesCount int `json:"package_files_count"` + PackageFilesChecksumTotalCount int `json:"package_files_checksum_total_count"` + PackageFilesChecksummedCount int `json:"package_files_checksummed_count"` + PackageFilesChecksumFailedCount int `json:"package_files_checksum_failed_count"` + PackageFilesSyncedCount int `json:"package_files_synced_count"` + PackageFilesFailedCount int `json:"package_files_failed_count"` + PackageFilesRegistryCount int `json:"package_files_registry_count"` + PackageFilesVerificationTotalCount int `json:"package_files_verification_total_count"` + PackageFilesVerifiedCount int `json:"package_files_verified_count"` + PackageFilesVerificationFailedCount int `json:"package_files_verification_failed_count"` + PackageFilesSyncedInPercentage string `json:"package_files_synced_in_percentage"` + PackageFilesVerifiedInPercentage string `json:"package_files_verified_in_percentage"` + PagesDeploymentsCount int `json:"pages_deployments_count"` + PagesDeploymentsChecksumTotalCount int `json:"pages_deployments_checksum_total_count"` + PagesDeploymentsChecksummedCount int `json:"pages_deployments_checksummed_count"` + PagesDeploymentsChecksumFailedCount int `json:"pages_deployments_checksum_failed_count"` + PagesDeploymentsSyncedCount int `json:"pages_deployments_synced_count"` + PagesDeploymentsFailedCount int `json:"pages_deployments_failed_count"` + PagesDeploymentsRegistryCount int `json:"pages_deployments_registry_count"` + PagesDeploymentsVerificationTotalCount int `json:"pages_deployments_verification_total_count"` + PagesDeploymentsVerifiedCount int `json:"pages_deployments_verified_count"` + PagesDeploymentsVerificationFailedCount int `json:"pages_deployments_verification_failed_count"` + PagesDeploymentsSyncedInPercentage string `json:"pages_deployments_synced_in_percentage"` + PagesDeploymentsVerifiedInPercentage string `json:"pages_deployments_verified_in_percentage"` + TerraformStateVersionsCount int `json:"terraform_state_versions_count"` + TerraformStateVersionsChecksumTotalCount int `json:"terraform_state_versions_checksum_total_count"` + TerraformStateVersionsChecksummedCount int `json:"terraform_state_versions_checksummed_count"` + TerraformStateVersionsChecksumFailedCount int `json:"terraform_state_versions_checksum_failed_count"` + TerraformStateVersionsSyncedCount int `json:"terraform_state_versions_synced_count"` + TerraformStateVersionsFailedCount int `json:"terraform_state_versions_failed_count"` + TerraformStateVersionsRegistryCount int `json:"terraform_state_versions_registry_count"` + TerraformStateVersionsVerificationTotalCount int `json:"terraform_state_versions_verification_total_count"` + TerraformStateVersionsVerifiedCount int `json:"terraform_state_versions_verified_count"` + TerraformStateVersionsVerificationFailedCount int `json:"terraform_state_versions_verification_failed_count"` + TerraformStateVersionsSyncedInPercentage string `json:"terraform_state_versions_synced_in_percentage"` + TerraformStateVersionsVerifiedInPercentage string `json:"terraform_state_versions_verified_in_percentage"` + SnippetRepositoriesCount int `json:"snippet_repositories_count"` + SnippetRepositoriesChecksumTotalCount int `json:"snippet_repositories_checksum_total_count"` + SnippetRepositoriesChecksummedCount int `json:"snippet_repositories_checksummed_count"` + SnippetRepositoriesChecksumFailedCount int `json:"snippet_repositories_checksum_failed_count"` + SnippetRepositoriesSyncedCount int `json:"snippet_repositories_synced_count"` + SnippetRepositoriesFailedCount int `json:"snippet_repositories_failed_count"` + SnippetRepositoriesRegistryCount int `json:"snippet_repositories_registry_count"` + SnippetRepositoriesVerificationTotalCount int `json:"snippet_repositories_verification_total_count"` + SnippetRepositoriesVerifiedCount int `json:"snippet_repositories_verified_count"` + SnippetRepositoriesVerificationFailedCount int `json:"snippet_repositories_verification_failed_count"` + SnippetRepositoriesSyncedInPercentage string `json:"snippet_repositories_synced_in_percentage"` + SnippetRepositoriesVerifiedInPercentage string `json:"snippet_repositories_verified_in_percentage"` + GroupWikiRepositoriesCount int `json:"group_wiki_repositories_count"` + GroupWikiRepositoriesChecksumTotalCount int `json:"group_wiki_repositories_checksum_total_count"` + GroupWikiRepositoriesChecksummedCount int `json:"group_wiki_repositories_checksummed_count"` + GroupWikiRepositoriesChecksumFailedCount int `json:"group_wiki_repositories_checksum_failed_count"` + GroupWikiRepositoriesSyncedCount int `json:"group_wiki_repositories_synced_count"` + GroupWikiRepositoriesFailedCount int `json:"group_wiki_repositories_failed_count"` + GroupWikiRepositoriesRegistryCount int `json:"group_wiki_repositories_registry_count"` + GroupWikiRepositoriesVerificationTotalCount int `json:"group_wiki_repositories_verification_total_count"` + GroupWikiRepositoriesVerifiedCount int `json:"group_wiki_repositories_verified_count"` + GroupWikiRepositoriesVerificationFailedCount int `json:"group_wiki_repositories_verification_failed_count"` + GroupWikiRepositoriesSyncedInPercentage string `json:"group_wiki_repositories_synced_in_percentage"` + GroupWikiRepositoriesVerifiedInPercentage string `json:"group_wiki_repositories_verified_in_percentage"` + PipelineArtifactsCount int `json:"pipeline_artifacts_count"` + PipelineArtifactsChecksumTotalCount int `json:"pipeline_artifacts_checksum_total_count"` + PipelineArtifactsChecksummedCount int `json:"pipeline_artifacts_checksummed_count"` + PipelineArtifactsChecksumFailedCount int `json:"pipeline_artifacts_checksum_failed_count"` + PipelineArtifactsSyncedCount int `json:"pipeline_artifacts_synced_count"` + PipelineArtifactsFailedCount int `json:"pipeline_artifacts_failed_count"` + PipelineArtifactsRegistryCount int `json:"pipeline_artifacts_registry_count"` + PipelineArtifactsVerificationTotalCount int `json:"pipeline_artifacts_verification_total_count"` + PipelineArtifactsVerifiedCount int `json:"pipeline_artifacts_verified_count"` + PipelineArtifactsVerificationFailedCount int `json:"pipeline_artifacts_verification_failed_count"` + PipelineArtifactsSyncedInPercentage string `json:"pipeline_artifacts_synced_in_percentage"` + PipelineArtifactsVerifiedInPercentage string `json:"pipeline_artifacts_verified_in_percentage"` + UploadsCount int `json:"uploads_count"` + UploadsSyncedCount int `json:"uploads_synced_count"` + UploadsFailedCount int `json:"uploads_failed_count"` + UploadsRegistryCount int `json:"uploads_registry_count"` + UploadsSyncedInPercentage string `json:"uploads_synced_in_percentage"` +} + +// RetrieveStatusOfAllGeoNodes get the list of status of all Geo Nodes. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-status-about-all-geo-nodes +func (s *GeoNodesService) RetrieveStatusOfAllGeoNodes(options ...RequestOptionFunc) ([]*GeoNodeStatus, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "geo_nodes/status", nil, options) + if err != nil { + return nil, nil, err + } + + var gnss []*GeoNodeStatus + resp, err := s.client.Do(req, &gnss) + if err != nil { + return nil, resp, err + } + + return gnss, resp, nil +} + +// RetrieveStatusOfGeoNode get the of status of a specific Geo Nodes. +// Deprecated: will be removed in v5 of the API, use Geo Sites API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_nodes/#retrieve-status-about-a-specific-geo-node +func (s *GeoNodesService) RetrieveStatusOfGeoNode(id int, options ...RequestOptionFunc) (*GeoNodeStatus, *Response, error) { + u := fmt.Sprintf("geo_nodes/%d/status", id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gns := new(GeoNodeStatus) + resp, err := s.client.Do(req, gns) + if err != nil { + return nil, resp, err + } + + return gns, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/geo_sites.go b/vendor/gitlab.com/gitlab-org/api/client-go/geo_sites.go new file mode 100644 index 000000000..53cdb895e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/geo_sites.go @@ -0,0 +1,513 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + GeoSitesServiceInterface interface { + CreateGeoSite(*CreateGeoSitesOptions, ...RequestOptionFunc) (*GeoSite, *Response, error) + ListGeoSites(*ListGeoSitesOptions, ...RequestOptionFunc) ([]*GeoSite, *Response, error) + GetGeoSite(int, ...RequestOptionFunc) (*GeoSite, *Response, error) + EditGeoSite(int, *EditGeoSiteOptions, ...RequestOptionFunc) (*GeoSite, *Response, error) + DeleteGeoSite(int, ...RequestOptionFunc) (*Response, error) + RepairGeoSite(int, ...RequestOptionFunc) (*GeoSite, *Response, error) + ListStatusOfAllGeoSites(*ListStatusOfAllGeoSitesOptions, ...RequestOptionFunc) ([]*GeoSiteStatus, *Response, error) + GetStatusOfGeoSite(int, ...RequestOptionFunc) (*GeoSiteStatus, *Response, error) + } + + // GeoSitesService handles communication with Geo Sites related methods + // of GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/geo_sites/ + GeoSitesService struct { + client *Client + } +) + +var _ GeoSitesServiceInterface = (*GeoSitesService)(nil) + +// GeoSite represents a GitLab Geo Site. +// +// GitLab API docs: https://docs.gitlab.com/api/geo_sites/ +type GeoSite struct { + ID int `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + InternalURL string `json:"internal_url"` + Primary bool `json:"primary"` + Enabled bool `json:"enabled"` + Current bool `json:"current"` + FilesMaxCapacity int `json:"files_max_capacity"` + ReposMaxCapacity int `json:"repos_max_capacity"` + VerificationMaxCapacity int `json:"verification_max_capacity"` + ContainerRepositoriesMaxCapacity int `json:"container_repositories_max_capacity"` + SelectiveSyncType string `json:"selective_sync_type"` + SelectiveSyncShards []string `json:"selective_sync_shards"` + SelectiveSyncNamespaceIDs []int `json:"selective_sync_namespace_ids"` + MinimumReverificationInterval int `json:"minimum_reverification_interval"` + SyncObjectStorage bool `json:"sync_object_storage"` + WebEditURL string `json:"web_edit_url"` + WebGeoReplicationDetailsURL string `json:"web_geo_replication_details_url"` + Links GeoSiteLinks `json:"_links"` +} + +// GeoSiteLinks represents links for GitLab GeoSite. +// +// GitLab API docs: https://docs.gitlab.com/api/geo_sites/ +type GeoSiteLinks struct { + Self string `json:"self"` + Status string `json:"status"` + Repair string `json:"repair"` +} + +// CreateGeoSitesOptions represents the available CreateGeoSite() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#create-a-new-geo-site +type CreateGeoSitesOptions struct { + Primary *bool `url:"primary,omitempty" json:"primary,omitempty"` + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + InternalURL *string `url:"internal_url,omitempty" json:"internal_url,omitempty"` + FilesMaxCapacity *int `url:"files_max_capacity,omitempty" json:"files_max_capacity,omitempty"` + ReposMaxCapacity *int `url:"repos_max_capacity,omitempty" json:"repos_max_capacity,omitempty"` + VerificationMaxCapacity *int `url:"verification_max_capacity,omitempty" json:"verification_max_capacity,omitempty"` + ContainerRepositoriesMaxCapacity *int `url:"container_repositories_max_capacity,omitempty" json:"container_repositories_max_capacity,omitempty"` + SyncObjectStorage *bool `url:"sync_object_storage,omitempty" json:"sync_object_storage,omitempty"` + SelectiveSyncType *string `url:"selective_sync_type,omitempty" json:"selective_sync_type,omitempty"` + SelectiveSyncShards *[]string `url:"selective_sync_shards,omitempty" json:"selective_sync_shards,omitempty"` + SelectiveSyncNamespaceIDs *[]int `url:"selective_sync_namespace_ids,omitempty" json:"selective_sync_namespace_ids,omitempty"` + MinimumReverificationInterval *int `url:"minimum_reverification_interval,omitempty" json:"minimum_reverification_interval,omitempty"` +} + +// CreateGeoSite creates a new Geo Site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#create-a-new-geo-site +func (s *GeoSitesService) CreateGeoSite(opt *CreateGeoSitesOptions, options ...RequestOptionFunc) (*GeoSite, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "geo_sites", opt, options) + if err != nil { + return nil, nil, err + } + + site := new(GeoSite) + resp, err := s.client.Do(req, site) + if err != nil { + return nil, resp, err + } + + return site, resp, nil +} + +// ListGeoSitesOptions represents the available ListGeoSites() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-configuration-about-all-geo-sites +type ListGeoSitesOptions ListOptions + +// ListGeoSites gets a list of geo sites. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-configuration-about-all-geo-sites +func (s *GeoSitesService) ListGeoSites(opt *ListGeoSitesOptions, options ...RequestOptionFunc) ([]*GeoSite, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "geo_sites", opt, options) + if err != nil { + return nil, nil, err + } + + var sites []*GeoSite + resp, err := s.client.Do(req, &sites) + if err != nil { + return nil, resp, err + } + + return sites, resp, nil +} + +// GetGeoSite gets a specific geo site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-configuration-about-a-specific-geo-site +func (s *GeoSitesService) GetGeoSite(id int, options ...RequestOptionFunc) (*GeoSite, *Response, error) { + u := fmt.Sprintf("geo_sites/%d", id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + site := new(GeoSite) + resp, err := s.client.Do(req, site) + if err != nil { + return nil, resp, err + } + + return site, resp, nil +} + +// EditGeoSiteOptions represents the available EditGeoSite() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#edit-a-geo-site +type EditGeoSiteOptions struct { + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + InternalURL *string `url:"internal_url,omitempty" json:"internal_url,omitempty"` + FilesMaxCapacity *int `url:"files_max_capacity,omitempty" json:"files_max_capacity,omitempty"` + ReposMaxCapacity *int `url:"repos_max_capacity,omitempty" json:"repos_max_capacity,omitempty"` + VerificationMaxCapacity *int `url:"verification_max_capacity,omitempty" json:"verification_max_capacity,omitempty"` + ContainerRepositoriesMaxCapacity *int `url:"container_repositories_max_capacity,omitempty" json:"container_repositories_max_capacity,omitempty"` + SelectiveSyncType *string `url:"selective_sync_type,omitempty" json:"selective_sync_type,omitempty"` + SelectiveSyncShards *[]string `url:"selective_sync_shards,omitempty" json:"selective_sync_shards,omitempty"` + SelectiveSyncNamespaceIDs *[]int `url:"selective_sync_namespace_ids,omitempty" json:"selective_sync_namespace_ids,omitempty"` + MinimumReverificationInterval *int `url:"minimum_reverification_interval,omitempty" json:"minimum_reverification_interval,omitempty"` +} + +// EditGeoSite updates settings of an existing Geo site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#edit-a-geo-site +func (s *GeoSitesService) EditGeoSite(id int, opt *EditGeoSiteOptions, options ...RequestOptionFunc) (*GeoSite, *Response, error) { + u := fmt.Sprintf("geo_sites/%d", id) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + site := new(GeoSite) + resp, err := s.client.Do(req, site) + if err != nil { + return nil, resp, err + } + + return site, resp, nil +} + +// DeleteGeoSite removes the Geo site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#delete-a-geo-site +func (s *GeoSitesService) DeleteGeoSite(id int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("geo_sites/%d", id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RepairGeoSite to repair the OAuth authentication of a Geo site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#repair-a-geo-site +func (s *GeoSitesService) RepairGeoSite(id int, options ...RequestOptionFunc) (*GeoSite, *Response, error) { + u := fmt.Sprintf("geo_sites/%d/repair", id) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + site := new(GeoSite) + resp, err := s.client.Do(req, site) + if err != nil { + return nil, resp, err + } + + return site, resp, nil +} + +// GeoSiteStatus represents the status of Geo Site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-status-about-all-geo-sites +type GeoSiteStatus struct { + GeoNodeID int `json:"geo_node_id"` + ProjectsCount int `json:"projects_count"` + ContainerRepositoriesReplicationEnabled bool `json:"container_repositories_replication_enabled"` + LFSObjectsCount int `json:"lfs_objects_count"` + LFSObjectsChecksumTotalCount int `json:"lfs_objects_checksum_total_count"` + LFSObjectsChecksummedCount int `json:"lfs_objects_checksummed_count"` + LFSObjectsChecksumFailedCount int `json:"lfs_objects_checksum_failed_count"` + LFSObjectsSyncedCount int `json:"lfs_objects_synced_count"` + LFSObjectsFailedCount int `json:"lfs_objects_failed_count"` + LFSObjectsRegistryCount int `json:"lfs_objects_registry_count"` + LFSObjectsVerificationTotalCount int `json:"lfs_objects_verification_total_count"` + LFSObjectsVerifiedCount int `json:"lfs_objects_verified_count"` + LFSObjectsVerificationFailedCount int `json:"lfs_objects_verification_failed_count"` + MergeRequestDiffsCount int `json:"merge_request_diffs_count"` + MergeRequestDiffsChecksumTotalCount int `json:"merge_request_diffs_checksum_total_count"` + MergeRequestDiffsChecksummedCount int `json:"merge_request_diffs_checksummed_count"` + MergeRequestDiffsChecksumFailedCount int `json:"merge_request_diffs_checksum_failed_count"` + MergeRequestDiffsSyncedCount int `json:"merge_request_diffs_synced_count"` + MergeRequestDiffsFailedCount int `json:"merge_request_diffs_failed_count"` + MergeRequestDiffsRegistryCount int `json:"merge_request_diffs_registry_count"` + MergeRequestDiffsVerificationTotalCount int `json:"merge_request_diffs_verification_total_count"` + MergeRequestDiffsVerifiedCount int `json:"merge_request_diffs_verified_count"` + MergeRequestDiffsVerificationFailedCount int `json:"merge_request_diffs_verification_failed_count"` + PackageFilesCount int `json:"package_files_count"` + PackageFilesChecksumTotalCount int `json:"package_files_checksum_total_count"` + PackageFilesChecksummedCount int `json:"package_files_checksummed_count"` + PackageFilesChecksumFailedCount int `json:"package_files_checksum_failed_count"` + PackageFilesSyncedCount int `json:"package_files_synced_count"` + PackageFilesFailedCount int `json:"package_files_failed_count"` + PackageFilesRegistryCount int `json:"package_files_registry_count"` + PackageFilesVerificationTotalCount int `json:"package_files_verification_total_count"` + PackageFilesVerifiedCount int `json:"package_files_verified_count"` + PackageFilesVerificationFailedCount int `json:"package_files_verification_failed_count"` + TerraformStateVersionsCount int `json:"terraform_state_versions_count"` + TerraformStateVersionsChecksumTotalCount int `json:"terraform_state_versions_checksum_total_count"` + TerraformStateVersionsChecksummedCount int `json:"terraform_state_versions_checksummed_count"` + TerraformStateVersionsChecksumFailedCount int `json:"terraform_state_versions_checksum_failed_count"` + TerraformStateVersionsSyncedCount int `json:"terraform_state_versions_synced_count"` + TerraformStateVersionsFailedCount int `json:"terraform_state_versions_failed_count"` + TerraformStateVersionsRegistryCount int `json:"terraform_state_versions_registry_count"` + TerraformStateVersionsVerificationTotalCount int `json:"terraform_state_versions_verification_total_count"` + TerraformStateVersionsVerifiedCount int `json:"terraform_state_versions_verified_count"` + TerraformStateVersionsVerificationFailedCount int `json:"terraform_state_versions_verification_failed_count"` + SnippetRepositoriesCount int `json:"snippet_repositories_count"` + SnippetRepositoriesChecksumTotalCount int `json:"snippet_repositories_checksum_total_count"` + SnippetRepositoriesChecksummedCount int `json:"snippet_repositories_checksummed_count"` + SnippetRepositoriesChecksumFailedCount int `json:"snippet_repositories_checksum_failed_count"` + SnippetRepositoriesSyncedCount int `json:"snippet_repositories_synced_count"` + SnippetRepositoriesFailedCount int `json:"snippet_repositories_failed_count"` + SnippetRepositoriesRegistryCount int `json:"snippet_repositories_registry_count"` + SnippetRepositoriesVerificationTotalCount int `json:"snippet_repositories_verification_total_count"` + SnippetRepositoriesVerifiedCount int `json:"snippet_repositories_verified_count"` + SnippetRepositoriesVerificationFailedCount int `json:"snippet_repositories_verification_failed_count"` + GroupWikiRepositoriesCount int `json:"group_wiki_repositories_count"` + GroupWikiRepositoriesChecksumTotalCount int `json:"group_wiki_repositories_checksum_total_count"` + GroupWikiRepositoriesChecksummedCount int `json:"group_wiki_repositories_checksummed_count"` + GroupWikiRepositoriesChecksumFailedCount int `json:"group_wiki_repositories_checksum_failed_count"` + GroupWikiRepositoriesSyncedCount int `json:"group_wiki_repositories_synced_count"` + GroupWikiRepositoriesFailedCount int `json:"group_wiki_repositories_failed_count"` + GroupWikiRepositoriesRegistryCount int `json:"group_wiki_repositories_registry_count"` + GrupWikiRepositoriesVerificationTotalCount int `json:"group_wiki_repositories_verification_total_count"` + GroupWikiRepositoriesVerifiedCount int `json:"group_wiki_repositories_verified_count"` + GroupWikiRepositoriesVerificationFailedCount int `json:"group_wiki_repositories_verification_failed_count"` + PipelineArtifactsCount int `json:"pipeline_artifacts_count"` + PipelineArtifactsChecksumTotalCount int `json:"pipeline_artifacts_checksum_total_count"` + PipelineArtifactsChecksummedCount int `json:"pipeline_artifacts_checksummed_count"` + PipelineArtifactsChecksumFailedCount int `json:"pipeline_artifacts_checksum_failed_count"` + PipelineArtifactsSyncedCount int `json:"pipeline_artifacts_synced_count"` + PipelineArtifactsFailedCount int `json:"pipeline_artifacts_failed_count"` + PipelineArtifactsRegistryCount int `json:"pipeline_artifacts_registry_count"` + PipelineArtifactsVerificationTotalCount int `json:"pipeline_artifacts_verification_total_count"` + PipelineArtifactsVerifiedCount int `json:"pipeline_artifacts_verified_count"` + PipelineArtifactsVerificationFailedCount int `json:"pipeline_artifacts_verification_failed_count"` + PagesDeploymentsCount int `json:"pages_deployments_count"` + PagesDeploymentsChecksumTotalCount int `json:"pages_deployments_checksum_total_count"` + PagesDeploymentsChecksummedCount int `json:"pages_deployments_checksummed_count"` + PagesDeploymentsChecksumFailedCount int `json:"pages_deployments_checksum_failed_count"` + PagesDeploymentsSyncedCount int `json:"pages_deployments_synced_count"` + PagesDeploymentsFailedCount int `json:"pages_deployments_failed_count"` + PagesDeploymentsRegistryCount int `json:"pages_deployments_registry_count"` + PagesDeploymentsVerificationTotalCount int `json:"pages_deployments_verification_total_count"` + PagesDeploymentsVerifiedCount int `json:"pages_deployments_verified_count"` + PagesDeploymentsVerificationFailedCount int `json:"pages_deployments_verification_failed_count"` + UploadsCount int `json:"uploads_count"` + UploadsChecksumTotalCount int `json:"uploads_checksum_total_count"` + UploadsChecksummedCount int `json:"uploads_checksummed_count"` + UploadsChecksumFailedCount int `json:"uploads_checksum_failed_count"` + UploadsSyncedCount int `json:"uploads_synced_count"` + UploadsFailedCount int `json:"uploads_failed_count"` + UploadsRegistryCount int `json:"uploads_registry_count"` + UploadsVerificationTotalCount int `json:"uploads_verification_total_count"` + UploadsVerifiedCount int `json:"uploads_verified_count"` + UploadsVerificationFailedCount int `json:"uploads_verification_failed_count"` + JobArtifactsCount int `json:"job_artifacts_count"` + JobArtifactsChecksumTotalCount int `json:"job_artifacts_checksum_total_count"` + JobArtifactsChecksummedCount int `json:"job_artifacts_checksummed_count"` + JobArtifactsChecksumFailedCount int `json:"job_artifacts_checksum_failed_count"` + JobArtifactsSyncedCount int `json:"job_artifacts_synced_count"` + JobArtifactsFailedCount int `json:"job_artifacts_failed_count"` + JobArtifactsRegistryCount int `json:"job_artifacts_registry_count"` + JobArtifactsVerificationTotalCount int `json:"job_artifacts_verification_total_count"` + JobArtifactsVerifiedCount int `json:"job_artifacts_verified_count"` + JobArtifactsVerificationFailedCount int `json:"job_artifacts_verification_failed_count"` + CISecureFilesCount int `json:"ci_secure_files_count"` + CISecureFilesChecksumTotalCount int `json:"ci_secure_files_checksum_total_count"` + CISecureFilesChecksummedCount int `json:"ci_secure_files_checksummed_count"` + CISecureFilesChecksumFailedCount int `json:"ci_secure_files_checksum_failed_count"` + CISecureFilesSyncedCount int `json:"ci_secure_files_synced_count"` + CISecureFilesFailedCount int `json:"ci_secure_files_failed_count"` + CISecureFilesRegistryCount int `json:"ci_secure_files_registry_count"` + CISecureFilesVerificationTotalCount int `json:"ci_secure_files_verification_total_count"` + CISecureFilesVerifiedCount int `json:"ci_secure_files_verified_count"` + CISecureFilesVerificationFailedCount int `json:"ci_secure_files_verification_failed_count"` + ContainerRepositoriesCount int `json:"container_repositories_count"` + ContainerRepositoriesChecksumTotalCount int `json:"container_repositories_checksum_total_count"` + ContainerRepositoriesChecksummedCount int `json:"container_repositories_checksummed_count"` + ContainerRepositoriesChecksumFailedCount int `json:"container_repositories_checksum_failed_count"` + ContainerRepositoriesSyncedCount int `json:"container_repositories_synced_count"` + ContainerRepositoriesFailedCount int `json:"container_repositories_failed_count"` + ContainerRepositoriesRegistryCount int `json:"container_repositories_registry_count"` + ContainerRepositoriesVerificationTotalCount int `json:"container_repositories_verification_total_count"` + ContainerRepositoriesVerifiedCount int `json:"container_repositories_verified_count"` + ContainerRepositoriesVerificationFailedCount int `json:"container_repositories_verification_failed_count"` + DependencyProxyBlobsCount int `json:"dependency_proxy_blobs_count"` + DependencyProxyBlobsChecksumTotalCount int `json:"dependency_proxy_blobs_checksum_total_count"` + DependencyProxyBlobsChecksummedCount int `json:"dependency_proxy_blobs_checksummed_count"` + DependencyProxyBlobsChecksumFailedCount int `json:"dependency_proxy_blobs_checksum_failed_count"` + DependencyProxyBlobsSyncedCount int `json:"dependency_proxy_blobs_synced_count"` + DependencyProxyBlobsFailedCount int `json:"dependency_proxy_blobs_failed_count"` + DependencyProxyBlobsRegistryCount int `json:"dependency_proxy_blobs_registry_count"` + DependencyProxyBlobsVerificationTotalCount int `json:"dependency_proxy_blobs_verification_total_count"` + DependencyProxyBlobsVerifiedCount int `json:"dependency_proxy_blobs_verified_count"` + DependencyProxyBlobsVerificationFailedCount int `json:"dependency_proxy_blobs_verification_failed_count"` + DependencyProxyManifestsCount int `json:"dependency_proxy_manifests_count"` + DependencyProxyManifestsChecksumTotalCount int `json:"dependency_proxy_manifests_checksum_total_count"` + DependencyProxyManifestsChecksummedCount int `json:"dependency_proxy_manifests_checksummed_count"` + DependencyProxyManifestsChecksumFailedCount int `json:"dependency_proxy_manifests_checksum_failed_count"` + DependencyProxyManifestsSyncedCount int `json:"dependency_proxy_manifests_synced_count"` + DependencyProxyManifestsFailedCount int `json:"dependency_proxy_manifests_failed_count"` + DependencyProxyManifestsRegistryCount int `json:"dependency_proxy_manifests_registry_count"` + DependencyProxyManifestsVerificationTotalCount int `json:"dependency_proxy_manifests_verification_total_count"` + DependencyProxyManifestsVerifiedCount int `json:"dependency_proxy_manifests_verified_count"` + DependencyProxyManifestsVerificationFailedCount int `json:"dependency_proxy_manifests_verification_failed_count"` + ProjectWikiRepositoriesCount int `json:"project_wiki_repositories_count"` + ProjectWikiRepositoriesChecksumTotalCount int `json:"project_wiki_repositories_checksum_total_count"` + ProjectWikiRepositoriesChecksummedCount int `json:"project_wiki_repositories_checksummed_count"` + ProjectWikiRepositoriesChecksumFailedCount int `json:"project_wiki_repositories_checksum_failed_count"` + ProjectWikiRepositoriesSyncedCount int `json:"project_wiki_repositories_synced_count"` + ProjectWikiRepositoriesFailedCount int `json:"project_wiki_repositories_failed_count"` + ProjectWikiRepositoriesRegistryCount int `json:"project_wiki_repositories_registry_count"` + ProjectWikiRepositoriesVerificationTotalCount int `json:"project_wiki_repositories_verification_total_count"` + ProjectWikiRepositoriesVerifiedCount int `json:"project_wiki_repositories_verified_count"` + ProjectWikiRepositoriesVerificationFailedCount int `json:"project_wiki_repositories_verification_failed_count"` + GitFetchEventCountWeekly int `json:"git_fetch_event_count_weekly"` + GitPushEventCountWeekly int `json:"git_push_event_count_weekly"` + ProxyRemoteRequestsEventCountWeekly int `json:"proxy_remote_requests_event_count_weekly"` + ProxyLocalRequestsEventCountWeekly int `json:"proxy_local_requests_event_count_weekly"` + RepositoriesCheckedInPercentage string `json:"repositories_checked_in_percentage"` + ReplicationSlotsUsedInPercentage string `json:"replication_slots_used_in_percentage"` + LFSObjectsSyncedInPercentage string `json:"lfs_objects_synced_in_percentage"` + LFSObjectsVerifiedInPercentage string `json:"lfs_objects_verified_in_percentage"` + MergeRequestDiffsSyncedInPercentage string `json:"merge_request_diffs_synced_in_percentage"` + MergeRequestDiffsVerifiedInPercentage string `json:"merge_request_diffs_verified_in_percentage"` + PackageFilesSyncedInPercentage string `json:"package_files_synced_in_percentage"` + PackageFilesVerifiedInPercentage string `json:"package_files_verified_in_percentage"` + TerraformStateVersionsSyncedInPercentage string `json:"terraform_state_versions_synced_in_percentage"` + TerraformStateVersionsVerifiedInPercentage string `json:"terraform_state_versions_verified_in_percentage"` + SnippetRepositoriesSyncedInPercentage string `json:"snippet_repositories_synced_in_percentage"` + SnippetRepositoriesVerifiedInPercentage string `json:"snippet_repositories_verified_in_percentage"` + GroupWikiRepositoriesSyncedInPercentage string `json:"group_wiki_repositories_synced_in_percentage"` + GroupWikiRepositoriesVerifiedInPercentage string `json:"group_wiki_repositories_verified_in_percentage"` + PipelineArtifactsSyncedInPercentage string `json:"pipeline_artifacts_synced_in_percentage"` + PipelineArtifactsVerifiedInPercentage string `json:"pipeline_artifacts_verified_in_percentage"` + PagesDeploymentsSyncedInPercentage string `json:"pages_deployments_synced_in_percentage"` + PagesDeploymentsVerifiedInPercentage string `json:"pages_deployments_verified_in_percentage"` + UploadsSyncedInPercentage string `json:"uploads_synced_in_percentage"` + UploadsVerifiedInPercentage string `json:"uploads_verified_in_percentage"` + JobArtifactsSyncedInPercentage string `json:"job_artifacts_synced_in_percentage"` + JobArtifactsVerifiedInPercentage string `json:"job_artifacts_verified_in_percentage"` + CISecureFilesSyncedInPercentage string `json:"ci_secure_files_synced_in_percentage"` + CISecureFilesVerifiedInPercentage string `json:"ci_secure_files_verified_in_percentage"` + ContainerRepositoriesSyncedInPercentage string `json:"container_repositories_synced_in_percentage"` + ContainerRepositoriesVerifiedInPercentage string `json:"container_repositories_verified_in_percentage"` + DependencyProxyBlobsSyncedInPercentage string `json:"dependency_proxy_blobs_synced_in_percentage"` + DependencyProxyBlobsVerifiedInPercentage string `json:"dependency_proxy_blobs_verified_in_percentage"` + DependencyProxyManifestsSyncedInPercentage string `json:"dependency_proxy_manifests_synced_in_percentage"` + DependencyProxyManifestsVerifiedInPercentage string `json:"dependency_proxy_manifests_verified_in_percentage"` + ProjectWikiRepositoriesSyncedInPercentage string `json:"project_wiki_repositories_synced_in_percentage"` + ProjectWikiRepositoriesVerifiedInPercentage string `json:"project_wiki_repositories_verified_in_percentage"` + ReplicationSlotsCount int `json:"replication_slots_count"` + ReplicationSlotsUsedCount int `json:"replication_slots_used_count"` + Healthy bool `json:"healthy"` + Health string `json:"health"` + HealthStatus string `json:"health_status"` + MissingOAuthApplication bool `json:"missing_oauth_application"` + DBReplicationLagSeconds int `json:"db_replication_lag_seconds"` + ReplicationSlotsMaxRetainedWalBytes int `json:"replication_slots_max_retained_wal_bytes"` + RepositoriesCheckedCount int `json:"repositories_checked_count"` + RepositoriesCheckedFailedCount int `json:"repositories_checked_failed_count"` + LastEventID int `json:"last_event_id"` + LastEventTimestamp int `json:"last_event_timestamp"` + CursorLastEventID int `json:"cursor_last_event_id"` + CursorLastEventTimestamp int `json:"cursor_last_event_timestamp"` + LastSuccessfulStatusCheckTimestamp int `json:"last_successful_status_check_timestamp"` + Version string `json:"version"` + Revision string `json:"revision"` + SelectiveSyncType string `json:"selective_sync_type"` + Namespaces []string `json:"namespaces"` + UpdatedAt time.Time `json:"updated_at"` + StorageShardsMatch bool `json:"storage_shards_match"` + Links GeoSiteStatusLink `json:"_links"` +} + +// GeoSiteStatus represents the status of Geo Site. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-status-about-all-geo-sites +type GeoSiteStatusLink struct { + Self string `json:"self"` + Site string `json:"site"` +} + +// ListStatusOfAllGeoSitesOptions represents the available ListStatusOfAllGeoSites() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-status-about-all-geo-sites +type ListStatusOfAllGeoSitesOptions ListOptions + +// ListStatusOfAllGeoSites get the list of status of all Geo Sites. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-status-about-all-geo-sites +func (s *GeoSitesService) ListStatusOfAllGeoSites(opt *ListStatusOfAllGeoSitesOptions, options ...RequestOptionFunc) ([]*GeoSiteStatus, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "geo_sites/status", nil, options) + if err != nil { + return nil, nil, err + } + + var statuses []*GeoSiteStatus + resp, err := s.client.Do(req, &statuses) + if err != nil { + return nil, resp, err + } + + return statuses, resp, nil +} + +// GetStatusOfGeoSite get the of status of a specific Geo Sites. +// +// GitLab API docs: +// https://docs.gitlab.com/api/geo_sites/#retrieve-status-about-a-specific-geo-site +func (s *GeoSitesService) GetStatusOfGeoSite(id int, options ...RequestOptionFunc) (*GeoSiteStatus, *Response, error) { + u := fmt.Sprintf("geo_sites/%d/status", id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + status := new(GeoSiteStatus) + resp, err := s.client.Do(req, status) + if err != nil { + return nil, resp, err + } + + return status, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/gitignore_templates.go b/vendor/gitlab.com/gitlab-org/api/client-go/gitignore_templates.go similarity index 51% rename from vendor/github.com/xanzy/go-gitlab/gitignore_templates.go rename to vendor/gitlab.com/gitlab-org/api/client-go/gitignore_templates.go index e2dea8364..7ffbede55 100644 --- a/vendor/github.com/xanzy/go-gitlab/gitignore_templates.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/gitignore_templates.go @@ -1,5 +1,5 @@ // -// Copyright 2018, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,58 +18,77 @@ package gitlab import ( "fmt" + "net/http" "net/url" ) -// GitIgnoreTemplatesService handles communication with the gitignore -// templates related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html -type GitIgnoreTemplatesService struct { - client *Client -} +type ( + // GitIgnoreTemplatesServiceInterface defines all the API methods for the GitIgnoreTemplatesService + GitIgnoreTemplatesServiceInterface interface { + ListTemplates(*ListTemplatesOptions, ...RequestOptionFunc) ([]*GitIgnoreTemplateListItem, *Response, error) + GetTemplate(string, ...RequestOptionFunc) (*GitIgnoreTemplate, *Response, error) + } + + // GitIgnoreTemplatesService handles communication with the gitignore + // templates related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/templates/gitignores/ + GitIgnoreTemplatesService struct { + client *Client + } +) + +var _ GitIgnoreTemplatesServiceInterface = (*GitIgnoreTemplatesService)(nil) // GitIgnoreTemplate represents a GitLab gitignore template. // -// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html +// GitLab API docs: https://docs.gitlab.com/api/templates/gitignores/ type GitIgnoreTemplate struct { Name string `json:"name"` Content string `json:"content"` } +// GitIgnoreTemplateListItem represents a GitLab gitignore template from the list. +// +// GitLab API docs: https://docs.gitlab.com/api/templates/gitignores/ +type GitIgnoreTemplateListItem struct { + Key string `json:"key"` + Name string `json:"name"` +} + // ListTemplatesOptions represents the available ListAllTemplates() options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates +// https://docs.gitlab.com/api/templates/gitignores/#get-all-gitignore-templates type ListTemplatesOptions ListOptions // ListTemplates get a list of available git ignore templates // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates -func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...RequestOptionFunc) ([]*GitIgnoreTemplate, *Response, error) { - req, err := s.client.NewRequest("GET", "templates/gitignores", opt, options) +// https://docs.gitlab.com/api/templates/gitignores/#get-all-gitignore-templates +func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...RequestOptionFunc) ([]*GitIgnoreTemplateListItem, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "templates/gitignores", opt, options) if err != nil { return nil, nil, err } - var gs []*GitIgnoreTemplate + var gs []*GitIgnoreTemplateListItem resp, err := s.client.Do(req, &gs) if err != nil { return nil, resp, err } - return gs, resp, err + return gs, resp, nil } // GetTemplate get a git ignore template // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/gitignores.html#single-gitignore-template +// https://docs.gitlab.com/api/templates/gitignores/#get-a-single-gitignore-template func (s *GitIgnoreTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*GitIgnoreTemplate, *Response, error) { u := fmt.Sprintf("templates/gitignores/%s", url.PathEscape(key)) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -80,5 +99,5 @@ func (s *GitIgnoreTemplatesService) GetTemplate(key string, options ...RequestOp return nil, resp, err } - return g, resp, err + return g, resp, nil } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/gitlab.go b/vendor/gitlab.com/gitlab-org/api/client-go/gitlab.go new file mode 100644 index 000000000..98505301a --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/gitlab.go @@ -0,0 +1,1123 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package gitlab implements a GitLab API client. +package gitlab + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "maps" + "math" + "math/rand" + "mime/multipart" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "sync" + "time" + + "github.com/hashicorp/go-cleanhttp" + + "github.com/google/go-querystring/query" + retryablehttp "github.com/hashicorp/go-retryablehttp" + "golang.org/x/oauth2" + "golang.org/x/time/rate" +) + +const ( + defaultBaseURL = "https://gitlab.com/" + apiVersionPath = "api/v4/" + userAgent = "go-gitlab" + + headerRateLimit = "RateLimit-Limit" + headerRateReset = "RateLimit-Reset" +) + +// AuthType represents an authentication type within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/ +type AuthType int + +// List of available authentication types. +// +// GitLab API docs: https://docs.gitlab.com/api/ +const ( + BasicAuth AuthType = iota + JobToken + OAuthToken + PrivateToken +) + +var ErrNotFound = errors.New("404 Not Found") + +// A Client manages communication with the GitLab API. +type Client struct { + // HTTP client used to communicate with the API. + client *retryablehttp.Client + + // Base URL for API requests. Defaults to the public GitLab API, but can be + // set to a domain endpoint to use with a self hosted GitLab server. baseURL + // should always be specified with a trailing slash. + baseURL *url.URL + + // disableRetries is used to disable the default retry logic. + disableRetries bool + + // configureLimiterOnce is used to make sure the limiter is configured exactly + // once and block all other calls until the initial (one) call is done. + configureLimiterOnce sync.Once + + // Limiter is used to limit API calls and prevent 429 responses. + limiter RateLimiter + + // Token type used to make authenticated API calls. + authType AuthType + + // Username and password used for basic authentication. + username, password string + + // Token used to make authenticated API calls. + token string + + // Protects the token field from concurrent read/write accesses. + tokenLock sync.RWMutex + + // Default request options applied to every request. + defaultRequestOptions []RequestOptionFunc + + // User agent used when communicating with the GitLab API. + UserAgent string + + // GraphQL interface + GraphQL GraphQLInterface + + // Services used for talking to different parts of the GitLab API. + AccessRequests AccessRequestsServiceInterface + AlertManagement AlertManagementServiceInterface + Appearance AppearanceServiceInterface + Applications ApplicationsServiceInterface + ApplicationStatistics ApplicationStatisticsServiceInterface + AuditEvents AuditEventsServiceInterface + Avatar AvatarRequestsServiceInterface + AwardEmoji AwardEmojiServiceInterface + Boards IssueBoardsServiceInterface + Branches BranchesServiceInterface + BroadcastMessage BroadcastMessagesServiceInterface + BulkImports BulkImportsServiceInterface + CIYMLTemplate CIYMLTemplatesServiceInterface + ClusterAgents ClusterAgentsServiceInterface + Commits CommitsServiceInterface + ContainerRegistry ContainerRegistryServiceInterface + ContainerRegistryProtectionRules ContainerRegistryProtectionRulesServiceInterface + CustomAttribute CustomAttributesServiceInterface + DatabaseMigrations DatabaseMigrationsServiceInterface + Dependencies DependenciesServiceInterface + DependencyListExport DependencyListExportServiceInterface + DependencyProxy DependencyProxyServiceInterface + DeployKeys DeployKeysServiceInterface + DeployTokens DeployTokensServiceInterface + DeploymentMergeRequests DeploymentMergeRequestsServiceInterface + Deployments DeploymentsServiceInterface + Discussions DiscussionsServiceInterface + DockerfileTemplate DockerfileTemplatesServiceInterface + DORAMetrics DORAMetricsServiceInterface + DraftNotes DraftNotesServiceInterface + EnterpriseUsers EnterpriseUsersServiceInterface + Environments EnvironmentsServiceInterface + EpicIssues EpicIssuesServiceInterface + Epics EpicsServiceInterface + ErrorTracking ErrorTrackingServiceInterface + Events EventsServiceInterface + ExternalStatusChecks ExternalStatusChecksServiceInterface + FeatureFlagUserLists FeatureFlagUserListsServiceInterface + Features FeaturesServiceInterface + FreezePeriods FreezePeriodsServiceInterface + GenericPackages GenericPackagesServiceInterface + GeoNodes GeoNodesServiceInterface + GeoSites GeoSitesServiceInterface + GitIgnoreTemplates GitIgnoreTemplatesServiceInterface + GroupAccessTokens GroupAccessTokensServiceInterface + GroupActivityAnalytics GroupActivityAnalyticsServiceInterface + GroupBadges GroupBadgesServiceInterface + GroupCluster GroupClustersServiceInterface + GroupEpicBoards GroupEpicBoardsServiceInterface + GroupImportExport GroupImportExportServiceInterface + GroupIssueBoards GroupIssueBoardsServiceInterface + GroupIterations GroupIterationsServiceInterface + GroupLabels GroupLabelsServiceInterface + GroupMarkdownUploads GroupMarkdownUploadsServiceInterface + GroupMembers GroupMembersServiceInterface + GroupMilestones GroupMilestonesServiceInterface + GroupProtectedEnvironments GroupProtectedEnvironmentsServiceInterface + GroupReleases GroupReleasesServiceInterface + GroupRepositoryStorageMove GroupRepositoryStorageMoveServiceInterface + GroupSCIM GroupSCIMServiceInterface + GroupSecuritySettings GroupSecuritySettingsServiceInterface + GroupSSHCertificates GroupSSHCertificatesServiceInterface + GroupVariables GroupVariablesServiceInterface + GroupWikis GroupWikisServiceInterface + Groups GroupsServiceInterface + Import ImportServiceInterface + InstanceCluster InstanceClustersServiceInterface + InstanceVariables InstanceVariablesServiceInterface + Invites InvitesServiceInterface + IssueLinks IssueLinksServiceInterface + Issues IssuesServiceInterface + IssuesStatistics IssuesStatisticsServiceInterface + Jobs JobsServiceInterface + JobTokenScope JobTokenScopeServiceInterface + Keys KeysServiceInterface + Labels LabelsServiceInterface + License LicenseServiceInterface + LicenseTemplates LicenseTemplatesServiceInterface + Markdown MarkdownServiceInterface + MemberRolesService MemberRolesServiceInterface + MergeRequestApprovals MergeRequestApprovalsServiceInterface + MergeRequestApprovalSettings MergeRequestApprovalSettingsServiceInterface + MergeRequests MergeRequestsServiceInterface + MergeTrains MergeTrainsServiceInterface + Metadata MetadataServiceInterface + Milestones MilestonesServiceInterface + Namespaces NamespacesServiceInterface + Notes NotesServiceInterface + NotificationSettings NotificationSettingsServiceInterface + Packages PackagesServiceInterface + Pages PagesServiceInterface + PagesDomains PagesDomainsServiceInterface + PersonalAccessTokens PersonalAccessTokensServiceInterface + PipelineSchedules PipelineSchedulesServiceInterface + PipelineTriggers PipelineTriggersServiceInterface + Pipelines PipelinesServiceInterface + PlanLimits PlanLimitsServiceInterface + ProjectAccessTokens ProjectAccessTokensServiceInterface + ProjectBadges ProjectBadgesServiceInterface + ProjectCluster ProjectClustersServiceInterface + ProjectFeatureFlags ProjectFeatureFlagServiceInterface + ProjectImportExport ProjectImportExportServiceInterface + ProjectIterations ProjectIterationsServiceInterface + ProjectMarkdownUploads ProjectMarkdownUploadsServiceInterface + ProjectMembers ProjectMembersServiceInterface + ProjectMirrors ProjectMirrorServiceInterface + ProjectRepositoryStorageMove ProjectRepositoryStorageMoveServiceInterface + ProjectSecuritySettings ProjectSecuritySettingsServiceInterface + ProjectSnippets ProjectSnippetsServiceInterface + ProjectTemplates ProjectTemplatesServiceInterface + ProjectVariables ProjectVariablesServiceInterface + ProjectVulnerabilities ProjectVulnerabilitiesServiceInterface + Projects ProjectsServiceInterface + ProtectedBranches ProtectedBranchesServiceInterface + ProtectedEnvironments ProtectedEnvironmentsServiceInterface + ProtectedTags ProtectedTagsServiceInterface + ReleaseLinks ReleaseLinksServiceInterface + Releases ReleasesServiceInterface + Repositories RepositoriesServiceInterface + RepositoryFiles RepositoryFilesServiceInterface + RepositorySubmodules RepositorySubmodulesServiceInterface + ResourceGroup ResourceGroupServiceInterface + ResourceIterationEvents ResourceIterationEventsServiceInterface + ResourceLabelEvents ResourceLabelEventsServiceInterface + ResourceMilestoneEvents ResourceMilestoneEventsServiceInterface + ResourceStateEvents ResourceStateEventsServiceInterface + ResourceWeightEvents ResourceWeightEventsServiceInterface + Runners RunnersServiceInterface + Search SearchServiceInterface + SecureFiles SecureFilesServiceInterface + Services ServicesServiceInterface + Settings SettingsServiceInterface + Sidekiq SidekiqServiceInterface + SnippetRepositoryStorageMove SnippetRepositoryStorageMoveServiceInterface + Snippets SnippetsServiceInterface + SystemHooks SystemHooksServiceInterface + Tags TagsServiceInterface + Todos TodosServiceInterface + Topics TopicsServiceInterface + UsageData UsageDataServiceInterface + Users UsersServiceInterface + Validate ValidateServiceInterface + Version VersionServiceInterface + Wikis WikisServiceInterface +} + +// ListOptions specifies the optional parameters to various List methods that +// support pagination. +type ListOptions struct { + // For keyset-based paginated result sets, the value must be `"keyset"` + Pagination string `url:"pagination,omitempty" json:"pagination,omitempty"` + // For offset-based and keyset-based paginated result sets, the number of results to include per page. + PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"` + // For offset-based paginated result sets, page of results to retrieve. + Page int `url:"page,omitempty" json:"page,omitempty"` + // For keyset-based paginated result sets, tree record ID at which to fetch the next page. + PageToken string `url:"page_token,omitempty" json:"page_token,omitempty"` + // For keyset-based paginated result sets, name of the column by which to order + OrderBy string `url:"order_by,omitempty" json:"order_by,omitempty"` + // For keyset-based paginated result sets, sort order (`"asc"`` or `"desc"`) + Sort string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// RateLimiter describes the interface that all (custom) rate limiters must implement. +type RateLimiter interface { + Wait(context.Context) error +} + +// NewClient returns a new GitLab API client. To use API methods which require +// authentication, provide a valid private or personal token. +func NewClient(token string, options ...ClientOptionFunc) (*Client, error) { + client, err := newClient(options...) + if err != nil { + return nil, err + } + client.authType = PrivateToken + client.token = token + return client, nil +} + +// NewBasicAuthClient returns a new GitLab API client. To use API methods which +// require authentication, provide a valid username and password. +func NewBasicAuthClient(username, password string, options ...ClientOptionFunc) (*Client, error) { + client, err := newClient(options...) + if err != nil { + return nil, err + } + + client.authType = BasicAuth + client.username = username + client.password = password + + return client, nil +} + +// NewJobClient returns a new GitLab API client. To use API methods which require +// authentication, provide a valid job token. +func NewJobClient(token string, options ...ClientOptionFunc) (*Client, error) { + client, err := newClient(options...) + if err != nil { + return nil, err + } + client.authType = JobToken + client.token = token + return client, nil +} + +// NewOAuthClient returns a new GitLab API client. To use API methods which +// require authentication, provide a valid oauth token. +func NewOAuthClient(token string, options ...ClientOptionFunc) (*Client, error) { + client, err := newClient(options...) + if err != nil { + return nil, err + } + client.authType = OAuthToken + client.token = token + return client, nil +} + +func newClient(options ...ClientOptionFunc) (*Client, error) { + c := &Client{UserAgent: userAgent} + + // Configure the HTTP client. + c.client = &retryablehttp.Client{ + Backoff: c.retryHTTPBackoff, + CheckRetry: c.retryHTTPCheck, + ErrorHandler: retryablehttp.PassthroughErrorHandler, + HTTPClient: cleanhttp.DefaultPooledClient(), + RetryWaitMin: 100 * time.Millisecond, + RetryWaitMax: 400 * time.Millisecond, + RetryMax: 5, + } + + // Set the default base URL. + c.setBaseURL(defaultBaseURL) + + // Apply any given client options. + for _, fn := range options { + if fn == nil { + continue + } + if err := fn(c); err != nil { + return nil, err + } + } + + // If no custom limiter was set using a client option, configure + // the default rate limiter with values that implicitly disable + // rate limiting until an initial HTTP call is done and we can + // use the headers to try and properly configure the limiter. + if c.limiter == nil { + c.limiter = rate.NewLimiter(rate.Inf, 0) + } + + // Create the internal timeStats service. + timeStats := &timeStatsService{client: c} + + // GraphQL interface + c.GraphQL = &GraphQL{client: c} + + // Create all the public services. + c.AccessRequests = &AccessRequestsService{client: c} + c.AlertManagement = &AlertManagementService{client: c} + c.Appearance = &AppearanceService{client: c} + c.Applications = &ApplicationsService{client: c} + c.ApplicationStatistics = &ApplicationStatisticsService{client: c} + c.AuditEvents = &AuditEventsService{client: c} + c.Avatar = &AvatarRequestsService{client: c} + c.AwardEmoji = &AwardEmojiService{client: c} + c.Boards = &IssueBoardsService{client: c} + c.Branches = &BranchesService{client: c} + c.BroadcastMessage = &BroadcastMessagesService{client: c} + c.BulkImports = &BulkImportsService{client: c} + c.CIYMLTemplate = &CIYMLTemplatesService{client: c} + c.ClusterAgents = &ClusterAgentsService{client: c} + c.Commits = &CommitsService{client: c} + c.ContainerRegistry = &ContainerRegistryService{client: c} + c.ContainerRegistryProtectionRules = &ContainerRegistryProtectionRulesService{client: c} + c.CustomAttribute = &CustomAttributesService{client: c} + c.DatabaseMigrations = &DatabaseMigrationsService{client: c} + c.Dependencies = &DependenciesService{client: c} + c.DependencyListExport = &DependencyListExportService{client: c} + c.DependencyProxy = &DependencyProxyService{client: c} + c.DeployKeys = &DeployKeysService{client: c} + c.DeployTokens = &DeployTokensService{client: c} + c.DeploymentMergeRequests = &DeploymentMergeRequestsService{client: c} + c.Deployments = &DeploymentsService{client: c} + c.Discussions = &DiscussionsService{client: c} + c.DockerfileTemplate = &DockerfileTemplatesService{client: c} + c.DORAMetrics = &DORAMetricsService{client: c} + c.DraftNotes = &DraftNotesService{client: c} + c.EnterpriseUsers = &EnterpriseUsersService{client: c} + c.Environments = &EnvironmentsService{client: c} + c.EpicIssues = &EpicIssuesService{client: c} + c.Epics = &EpicsService{client: c} + c.ErrorTracking = &ErrorTrackingService{client: c} + c.Events = &EventsService{client: c} + c.ExternalStatusChecks = &ExternalStatusChecksService{client: c} + c.FeatureFlagUserLists = &FeatureFlagUserListsService{client: c} + c.Features = &FeaturesService{client: c} + c.FreezePeriods = &FreezePeriodsService{client: c} + c.GenericPackages = &GenericPackagesService{client: c} + c.GeoNodes = &GeoNodesService{client: c} + c.GeoSites = &GeoSitesService{client: c} + c.GitIgnoreTemplates = &GitIgnoreTemplatesService{client: c} + c.GroupAccessTokens = &GroupAccessTokensService{client: c} + c.GroupActivityAnalytics = &GroupActivityAnalyticsService{client: c} + c.GroupBadges = &GroupBadgesService{client: c} + c.GroupCluster = &GroupClustersService{client: c} + c.GroupEpicBoards = &GroupEpicBoardsService{client: c} + c.GroupImportExport = &GroupImportExportService{client: c} + c.GroupIssueBoards = &GroupIssueBoardsService{client: c} + c.GroupIterations = &GroupIterationsService{client: c} + c.GroupLabels = &GroupLabelsService{client: c} + c.GroupMarkdownUploads = &GroupMarkdownUploadsService{client: c} + c.GroupMembers = &GroupMembersService{client: c} + c.GroupMilestones = &GroupMilestonesService{client: c} + c.GroupProtectedEnvironments = &GroupProtectedEnvironmentsService{client: c} + c.GroupReleases = &GroupReleasesService{client: c} + c.GroupRepositoryStorageMove = &GroupRepositoryStorageMoveService{client: c} + c.GroupSCIM = &GroupSCIMService{client: c} + c.GroupSecuritySettings = &GroupSecuritySettingsService{client: c} + c.GroupSSHCertificates = &GroupSSHCertificatesService{client: c} + c.GroupVariables = &GroupVariablesService{client: c} + c.GroupWikis = &GroupWikisService{client: c} + c.Groups = &GroupsService{client: c} + c.Import = &ImportService{client: c} + c.InstanceCluster = &InstanceClustersService{client: c} + c.InstanceVariables = &InstanceVariablesService{client: c} + c.Invites = &InvitesService{client: c} + c.IssueLinks = &IssueLinksService{client: c} + c.Issues = &IssuesService{client: c, timeStats: timeStats} + c.IssuesStatistics = &IssuesStatisticsService{client: c} + c.Jobs = &JobsService{client: c} + c.JobTokenScope = &JobTokenScopeService{client: c} + c.Keys = &KeysService{client: c} + c.Labels = &LabelsService{client: c} + c.License = &LicenseService{client: c} + c.LicenseTemplates = &LicenseTemplatesService{client: c} + c.Markdown = &MarkdownService{client: c} + c.MemberRolesService = &MemberRolesService{client: c} + c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c} + c.MergeRequestApprovalSettings = &MergeRequestApprovalSettingsService{client: c} + c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats} + c.MergeTrains = &MergeTrainsService{client: c} + c.Metadata = &MetadataService{client: c} + c.Milestones = &MilestonesService{client: c} + c.Namespaces = &NamespacesService{client: c} + c.Notes = &NotesService{client: c} + c.NotificationSettings = &NotificationSettingsService{client: c} + c.Packages = &PackagesService{client: c} + c.Pages = &PagesService{client: c} + c.PagesDomains = &PagesDomainsService{client: c} + c.PersonalAccessTokens = &PersonalAccessTokensService{client: c} + c.PipelineSchedules = &PipelineSchedulesService{client: c} + c.PipelineTriggers = &PipelineTriggersService{client: c} + c.Pipelines = &PipelinesService{client: c} + c.PlanLimits = &PlanLimitsService{client: c} + c.ProjectAccessTokens = &ProjectAccessTokensService{client: c} + c.ProjectBadges = &ProjectBadgesService{client: c} + c.ProjectCluster = &ProjectClustersService{client: c} + c.ProjectFeatureFlags = &ProjectFeatureFlagService{client: c} + c.ProjectImportExport = &ProjectImportExportService{client: c} + c.ProjectIterations = &ProjectIterationsService{client: c} + c.ProjectMarkdownUploads = &ProjectMarkdownUploadsService{client: c} + c.ProjectMembers = &ProjectMembersService{client: c} + c.ProjectMirrors = &ProjectMirrorService{client: c} + c.ProjectRepositoryStorageMove = &ProjectRepositoryStorageMoveService{client: c} + c.ProjectSecuritySettings = &ProjectSecuritySettingsService{client: c} + c.ProjectSnippets = &ProjectSnippetsService{client: c} + c.ProjectTemplates = &ProjectTemplatesService{client: c} + c.ProjectVariables = &ProjectVariablesService{client: c} + c.ProjectVulnerabilities = &ProjectVulnerabilitiesService{client: c} + c.Projects = &ProjectsService{client: c} + c.ProtectedBranches = &ProtectedBranchesService{client: c} + c.ProtectedEnvironments = &ProtectedEnvironmentsService{client: c} + c.ProtectedTags = &ProtectedTagsService{client: c} + c.ReleaseLinks = &ReleaseLinksService{client: c} + c.Releases = &ReleasesService{client: c} + c.Repositories = &RepositoriesService{client: c} + c.RepositoryFiles = &RepositoryFilesService{client: c} + c.RepositorySubmodules = &RepositorySubmodulesService{client: c} + c.ResourceGroup = &ResourceGroupService{client: c} + c.ResourceIterationEvents = &ResourceIterationEventsService{client: c} + c.ResourceLabelEvents = &ResourceLabelEventsService{client: c} + c.ResourceMilestoneEvents = &ResourceMilestoneEventsService{client: c} + c.ResourceStateEvents = &ResourceStateEventsService{client: c} + c.ResourceWeightEvents = &ResourceWeightEventsService{client: c} + c.Runners = &RunnersService{client: c} + c.Search = &SearchService{client: c} + c.SecureFiles = &SecureFilesService{client: c} + c.Services = &ServicesService{client: c} + c.Settings = &SettingsService{client: c} + c.Sidekiq = &SidekiqService{client: c} + c.Snippets = &SnippetsService{client: c} + c.SnippetRepositoryStorageMove = &SnippetRepositoryStorageMoveService{client: c} + c.SystemHooks = &SystemHooksService{client: c} + c.Tags = &TagsService{client: c} + c.Todos = &TodosService{client: c} + c.Topics = &TopicsService{client: c} + c.UsageData = &UsageDataService{client: c} + c.Users = &UsersService{client: c} + c.Validate = &ValidateService{client: c} + c.Version = &VersionService{client: c} + c.Wikis = &WikisService{client: c} + + return c, nil +} + +// retryHTTPCheck provides a callback for Client.CheckRetry which +// will retry both rate limit (429) and server (>= 500) errors. +func (c *Client) retryHTTPCheck(ctx context.Context, resp *http.Response, err error) (bool, error) { + if ctx.Err() != nil { + return false, ctx.Err() + } + if err != nil { + return false, err + } + if !c.disableRetries && (resp.StatusCode == 429 || resp.StatusCode >= 500) { + return true, nil + } + return false, nil +} + +// retryHTTPBackoff provides a generic callback for Client.Backoff which +// will pass through all calls based on the status code of the response. +func (c *Client) retryHTTPBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { + // Use the rate limit backoff function when we are rate limited. + if resp != nil && resp.StatusCode == 429 { + return rateLimitBackoff(min, max, attemptNum, resp) + } + + // Set custom duration's when we experience a service interruption. + min = 700 * time.Millisecond + max = 900 * time.Millisecond + + return retryablehttp.LinearJitterBackoff(min, max, attemptNum, resp) +} + +// rateLimitBackoff provides a callback for Client.Backoff which will use the +// RateLimit-Reset header to determine the time to wait. We add some jitter +// to prevent a thundering herd. +// +// min and max are mainly used for bounding the jitter that will be added to +// the reset time retrieved from the headers. But if the final wait time is +// less then min, min will be used instead. +func rateLimitBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { + // rnd is used to generate pseudo-random numbers. + rnd := rand.New(rand.NewSource(time.Now().UnixNano())) + + // First create some jitter bounded by the min and max durations. + jitter := time.Duration(rnd.Float64() * float64(max-min)) + + if resp != nil { + if v := resp.Header.Get(headerRateReset); v != "" { + if reset, _ := strconv.ParseInt(v, 10, 64); reset > 0 { + // Only update min if the given time to wait is longer. + if wait := time.Until(time.Unix(reset, 0)); wait > min { + min = wait + } + } + } else { + // In case the RateLimit-Reset header is not set, back off an additional + // 100% exponentially. With the default milliseconds being set to 100 for + // `min`, this makes the 5th retry wait 3.2 seconds (3,200 ms) by default. + min = time.Duration(float64(min) * math.Pow(2, float64(attemptNum))) + } + } + + return min + jitter +} + +// configureLimiter configures the rate limiter. +func (c *Client) configureLimiter(ctx context.Context, headers http.Header) { + if v := headers.Get(headerRateLimit); v != "" { + if rateLimit, _ := strconv.ParseFloat(v, 64); rateLimit > 0 { + // The rate limit is based on requests per minute, so for our limiter to + // work correctly we divide the limit by 60 to get the limit per second. + rateLimit /= 60 + + // Configure the limit and burst using a split of 2/3 for the limit and + // 1/3 for the burst. This enables clients to burst 1/3 of the allowed + // calls before the limiter kicks in. The remaining calls will then be + // spread out evenly using intervals of time.Second / limit which should + // prevent hitting the rate limit. + limit := rate.Limit(rateLimit * 0.66) + burst := int(rateLimit * 0.33) + + // Need at least one allowed to burst or x/time will throw an error + if burst == 0 { + burst = 1 + } + + // Create a new limiter using the calculated values. + c.limiter = rate.NewLimiter(limit, burst) + + // Call the limiter once as we have already made a request + // to get the headers and the limiter is not aware of this. + c.limiter.Wait(ctx) + } + } +} + +// BaseURL return a copy of the baseURL. +func (c *Client) BaseURL() *url.URL { + u := *c.baseURL + return &u +} + +// setBaseURL sets the base URL for API requests to a custom endpoint. +func (c *Client) setBaseURL(urlStr string) error { + // Make sure the given URL end with a slash + if !strings.HasSuffix(urlStr, "/") { + urlStr += "/" + } + + baseURL, err := url.Parse(urlStr) + if err != nil { + return err + } + + if !strings.HasSuffix(baseURL.Path, apiVersionPath) { + baseURL.Path += apiVersionPath + } + + // Update the base URL of the client. + c.baseURL = baseURL + + return nil +} + +// NewRequest creates a new API request. The method expects a relative URL +// path that will be resolved relative to the base URL of the Client. +// Relative URL paths should always be specified without a preceding slash. +// If specified, the value pointed to by body is JSON encoded and included +// as the request body. +func (c *Client) NewRequest(method, path string, opt any, options []RequestOptionFunc) (*retryablehttp.Request, error) { + u := *c.baseURL + unescaped, err := url.PathUnescape(path) + if err != nil { + return nil, err + } + + // Set the encoded path data + u.RawPath = c.baseURL.Path + path + u.Path = c.baseURL.Path + unescaped + + // Create a request specific headers map. + reqHeaders := make(http.Header) + reqHeaders.Set("Accept", "application/json") + + if c.UserAgent != "" { + reqHeaders.Set("User-Agent", c.UserAgent) + } + + var body any + switch { + case method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut: + reqHeaders.Set("Content-Type", "application/json") + + if opt != nil { + body, err = json.Marshal(opt) + if err != nil { + return nil, err + } + } + case opt != nil: + q, err := query.Values(opt) + if err != nil { + return nil, err + } + u.RawQuery = q.Encode() + } + + req, err := retryablehttp.NewRequest(method, u.String(), body) + if err != nil { + return nil, err + } + + for _, fn := range append(c.defaultRequestOptions, options...) { + if fn == nil { + continue + } + if err := fn(req); err != nil { + return nil, err + } + } + + // Set the request specific headers. + maps.Copy(req.Header, reqHeaders) + + return req, nil +} + +// UploadRequest creates an API request for uploading a file. The method +// expects a relative URL path that will be resolved relative to the base +// URL of the Client. Relative URL paths should always be specified without +// a preceding slash. If specified, the value pointed to by body is JSON +// encoded and included as the request body. +func (c *Client) UploadRequest(method, path string, content io.Reader, filename string, uploadType UploadType, opt any, options []RequestOptionFunc) (*retryablehttp.Request, error) { + u := *c.baseURL + unescaped, err := url.PathUnescape(path) + if err != nil { + return nil, err + } + + // Set the encoded path data + u.RawPath = c.baseURL.Path + path + u.Path = c.baseURL.Path + unescaped + + // Create a request specific headers map. + reqHeaders := make(http.Header) + reqHeaders.Set("Accept", "application/json") + + if c.UserAgent != "" { + reqHeaders.Set("User-Agent", c.UserAgent) + } + + b := new(bytes.Buffer) + w := multipart.NewWriter(b) + + fw, err := w.CreateFormFile(string(uploadType), filename) + if err != nil { + return nil, err + } + + if _, err := io.Copy(fw, content); err != nil { + return nil, err + } + + if opt != nil { + fields, err := query.Values(opt) + if err != nil { + return nil, err + } + for name := range fields { + if err = w.WriteField(name, fmt.Sprintf("%v", fields.Get(name))); err != nil { + return nil, err + } + } + } + + if err = w.Close(); err != nil { + return nil, err + } + + reqHeaders.Set("Content-Type", w.FormDataContentType()) + + req, err := retryablehttp.NewRequest(method, u.String(), b) + if err != nil { + return nil, err + } + + for _, fn := range append(c.defaultRequestOptions, options...) { + if fn == nil { + continue + } + if err := fn(req); err != nil { + return nil, err + } + } + + // Set the request specific headers. + maps.Copy(req.Header, reqHeaders) + + return req, nil +} + +// Response is a GitLab API response. This wraps the standard http.Response +// returned from GitLab and provides convenient access to things like +// pagination links. +type Response struct { + *http.Response + + // Fields used for offset-based pagination. + TotalItems int + TotalPages int + ItemsPerPage int + CurrentPage int + NextPage int + PreviousPage int + + // Fields used for keyset-based pagination. + PreviousLink string + NextLink string + FirstLink string + LastLink string +} + +// newResponse creates a new Response for the provided http.Response. +func newResponse(r *http.Response) *Response { + response := &Response{Response: r} + response.populatePageValues() + response.populateLinkValues() + return response +} + +const ( + // Headers used for offset-based pagination. + xTotal = "X-Total" + xTotalPages = "X-Total-Pages" + xPerPage = "X-Per-Page" + xPage = "X-Page" + xNextPage = "X-Next-Page" + xPrevPage = "X-Prev-Page" + + // Headers used for keyset-based pagination. + linkPrev = "prev" + linkNext = "next" + linkFirst = "first" + linkLast = "last" +) + +// populatePageValues parses the HTTP Link response headers and populates the +// various pagination link values in the Response. +func (r *Response) populatePageValues() { + if totalItems := r.Header.Get(xTotal); totalItems != "" { + r.TotalItems, _ = strconv.Atoi(totalItems) + } + if totalPages := r.Header.Get(xTotalPages); totalPages != "" { + r.TotalPages, _ = strconv.Atoi(totalPages) + } + if itemsPerPage := r.Header.Get(xPerPage); itemsPerPage != "" { + r.ItemsPerPage, _ = strconv.Atoi(itemsPerPage) + } + if currentPage := r.Header.Get(xPage); currentPage != "" { + r.CurrentPage, _ = strconv.Atoi(currentPage) + } + if nextPage := r.Header.Get(xNextPage); nextPage != "" { + r.NextPage, _ = strconv.Atoi(nextPage) + } + if previousPage := r.Header.Get(xPrevPage); previousPage != "" { + r.PreviousPage, _ = strconv.Atoi(previousPage) + } +} + +func (r *Response) populateLinkValues() { + if link := r.Header.Get("Link"); link != "" { + for _, link := range strings.Split(link, ",") { + parts := strings.Split(link, ";") + if len(parts) < 2 { + continue + } + + linkType := strings.Trim(strings.Split(parts[1], "=")[1], "\"") + linkValue := strings.Trim(parts[0], "< >") + + switch linkType { + case linkPrev: + r.PreviousLink = linkValue + case linkNext: + r.NextLink = linkValue + case linkFirst: + r.FirstLink = linkValue + case linkLast: + r.LastLink = linkValue + } + } + } +} + +// Do sends an API request and returns the API response. The API response is +// JSON decoded and stored in the value pointed to by v, or returned as an +// error if an API error has occurred. If v implements the io.Writer +// interface, the raw response body will be written to v, without attempting to +// first decode it. +func (c *Client) Do(req *retryablehttp.Request, v any) (*Response, error) { + // Wait will block until the limiter can obtain a new token. + err := c.limiter.Wait(req.Context()) + if err != nil { + return nil, err + } + + // Set the correct authentication header. If using basic auth, then check + // if we already have a token and if not first authenticate and get one. + var basicAuthToken string + switch c.authType { + case BasicAuth: + c.tokenLock.RLock() + basicAuthToken = c.token + c.tokenLock.RUnlock() + if basicAuthToken == "" { + // If we don't have a token yet, we first need to request one. + basicAuthToken, err = c.requestOAuthToken(req.Context(), basicAuthToken) + if err != nil { + return nil, err + } + } + req.Header.Set("Authorization", "Bearer "+basicAuthToken) + case JobToken: + if values := req.Header.Values("JOB-TOKEN"); len(values) == 0 { + req.Header.Set("JOB-TOKEN", c.token) + } + case OAuthToken: + if values := req.Header.Values("Authorization"); len(values) == 0 { + req.Header.Set("Authorization", "Bearer "+c.token) + } + case PrivateToken: + if values := req.Header.Values("PRIVATE-TOKEN"); len(values) == 0 { + req.Header.Set("PRIVATE-TOKEN", c.token) + } + } + + client := c.client + + if cr := checkRetryFromContext(req.Context()); cr != nil { + // for avoid overwriting c.client. Use copy of c.client and apply checkRetry from request context + client = c.newRetryableHTTPClientWithRetryCheck(cr) + } + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode == http.StatusUnauthorized && c.authType == BasicAuth { + resp.Body.Close() + // The token most likely expired, so we need to request a new one and try again. + if _, err := c.requestOAuthToken(req.Context(), basicAuthToken); err != nil { + return nil, err + } + return c.Do(req, v) + } + defer resp.Body.Close() + defer io.Copy(io.Discard, resp.Body) + + // If not yet configured, try to configure the rate limiter + // using the response headers we just received. Fail silently + // so the limiter will remain disabled in case of an error. + c.configureLimiterOnce.Do(func() { c.configureLimiter(req.Context(), resp.Header) }) + + response := newResponse(resp) + + err = CheckResponse(resp) + if err != nil { + // Even though there was an error, we still return the response + // in case the caller wants to inspect it further. + return response, err + } + + if v != nil { + if w, ok := v.(io.Writer); ok { + _, err = io.Copy(w, resp.Body) + } else { + err = json.NewDecoder(resp.Body).Decode(v) + } + } + + return response, err +} + +func (c *Client) requestOAuthToken(ctx context.Context, token string) (string, error) { + c.tokenLock.Lock() + defer c.tokenLock.Unlock() + + // Return early if the token was updated while waiting for the lock. + if c.token != token { + return c.token, nil + } + + config := &oauth2.Config{ + Endpoint: oauth2.Endpoint{ + AuthURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/authorize", + TokenURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/token", + }, + } + + ctx = context.WithValue(ctx, oauth2.HTTPClient, c.client.HTTPClient) + t, err := config.PasswordCredentialsToken(ctx, c.username, c.password) + if err != nil { + return "", err + } + c.token = t.AccessToken + + return c.token, nil +} + +// ErrInvalidIDType is returned when a function expecting an ID as either an integer +// or string receives a different type. This error commonly occurs when working with +// GitLab resources like groups and projects which support both numeric IDs and +// path-based string identifiers. +var ErrInvalidIDType = errors.New("the ID must be an int or a string") + +// Helper function to accept and format both the project ID or name as project +// identifier for all API calls. +func parseID(id any) (string, error) { + switch v := id.(type) { + case int: + return strconv.Itoa(v), nil + case string: + return v, nil + default: + return "", fmt.Errorf("invalid ID type %#v, %w", id, ErrInvalidIDType) + } +} + +// Helper function to escape a project identifier. +func PathEscape(s string) string { + return strings.ReplaceAll(url.PathEscape(s), ".", "%2E") +} + +// An ErrorResponse reports one or more errors caused by an API request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/rest/troubleshooting/ +type ErrorResponse struct { + Body []byte + Response *http.Response + Message string +} + +func (e *ErrorResponse) Error() string { + path := e.Response.Request.URL.RawPath + if path == "" { + path = e.Response.Request.URL.Path + } + url := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, path) + + if e.Message == "" { + return fmt.Sprintf("%s %s: %d", e.Response.Request.Method, url, e.Response.StatusCode) + } else { + return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, url, e.Response.StatusCode, e.Message) + } +} + +// CheckResponse checks the API response for errors, and returns them if present. +func CheckResponse(r *http.Response) error { + switch r.StatusCode { + case 200, 201, 202, 204, 304: + return nil + case 404: + return ErrNotFound + } + + errorResponse := &ErrorResponse{Response: r} + + data, err := io.ReadAll(r.Body) + if err == nil && strings.TrimSpace(string(data)) != "" { + errorResponse.Body = data + + var raw any + if err := json.Unmarshal(data, &raw); err != nil { + errorResponse.Message = fmt.Sprintf("failed to parse unknown error format: %s", data) + } else { + errorResponse.Message = parseError(raw) + } + } + + return errorResponse +} + +// Format: +// +// { +// "message": { +// "": [ +// "", +// "", +// ... +// ], +// "": { +// "": [ +// "", +// "", +// ... +// ], +// } +// }, +// "error": "" +// } +func parseError(raw any) string { + switch raw := raw.(type) { + case string: + return raw + + case []any: + var errs []string + for _, v := range raw { + errs = append(errs, parseError(v)) + } + return fmt.Sprintf("[%s]", strings.Join(errs, ", ")) + + case map[string]any: + var errs []string + for k, v := range raw { + errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v))) + } + sort.Strings(errs) + return strings.Join(errs, ", ") + + default: + return fmt.Sprintf("failed to parse unexpected error type: %T", raw) + } +} + +// newRetryableHTTPClientWithRetryCheck returns a `retryablehttp.Client` clone of itself with the given CheckRetry function +func (c *Client) newRetryableHTTPClientWithRetryCheck(cr retryablehttp.CheckRetry) *retryablehttp.Client { + return &retryablehttp.Client{ + Logger: c.client.Logger, + RetryWaitMin: c.client.RetryWaitMin, + RetryWaitMax: c.client.RetryWaitMax, + RetryMax: c.client.RetryMax, + RequestLogHook: c.client.RequestLogHook, + CheckRetry: cr, + Backoff: c.client.Backoff, + ErrorHandler: c.client.ErrorHandler, + PrepareRetry: c.client.PrepareRetry, + } +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/graphql.go b/vendor/gitlab.com/gitlab-org/api/client-go/graphql.go new file mode 100644 index 000000000..cc8738285 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/graphql.go @@ -0,0 +1,102 @@ +package gitlab + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" +) + +const ( + // GraphQLAPIEndpoint defines the endpoint URI for the GraphQL backend + GraphQLAPIEndpoint = "/api/graphql" +) + +type ( + GraphQLInterface interface { + Do(ctx context.Context, query GraphQLQuery, response any) (*Response, error) + } + + GraphQL struct { + client *Client + } + + GraphQLQuery struct { + Query string `json:"query"` + } + + GenericGraphQLErrors struct { + Errors []struct { + Message string `json:"message"` + } `json:"errors"` + } + + GraphQLResponseError struct { + Err error + Errors GenericGraphQLErrors + } +) + +var _ GraphQLInterface = (*GraphQL)(nil) + +func (e *GraphQLResponseError) Error() string { + if len(e.Errors.Errors) == 0 { + return fmt.Sprintf("%s (no additional error messages)", e.Err) + } + + var sb strings.Builder + sb.WriteString(e.Err.Error()) + sb.WriteString(" (GraphQL errors: ") + + for i, err := range e.Errors.Errors { + if i > 0 { + sb.WriteString(", ") + } + sb.WriteString(err.Message) + } + sb.WriteString(")") + + return sb.String() +} + +// Do sends a GraphQL query and returns the response in the given response argument +// The response must be JSON serializable. The *Response return value is the HTTP response +// and must be used to retrieve additional HTTP information, like status codes and also +// error messages from failed queries. +// +// Example: +// +// var response struct { +// Data struct { +// Project struct { +// ID string `json:"id"` +// } `json:"project"` +// } `json:"data"` +// } +// _, err := client.GraphQL.Do(context.Background(), GraphQLQuery{Query: `query { project(fullPath: "gitlab-org/gitlab") { id } }`}, &response) +// +// Attention: This API is experimental and may be subject to breaking changes to improve the API in the future. +func (g *GraphQL) Do(ctx context.Context, query GraphQLQuery, response any) (*Response, error) { + request, err := g.client.NewRequest(http.MethodPost, "", query, nil) + if err != nil { + return nil, fmt.Errorf("failed to create GraphQL request: %w", err) + } + // Overwrite the path of the existing request, as otherwise client-go appends /api/v4 instead. + request.URL.Path = GraphQLAPIEndpoint + resp, err := g.client.Do(request, response) + if err != nil { + // return error, details can be read from Response + if errResp, ok := err.(*ErrorResponse); ok { //nolint: errorlint + var v GenericGraphQLErrors + if json.Unmarshal(errResp.Body, &v) == nil { + return resp, &GraphQLResponseError{ + Err: err, + Errors: v, + } + } + } + return resp, fmt.Errorf("failed to execute GraphQL query: %w", err) + } + return resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_access_tokens.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_access_tokens.go new file mode 100644 index 000000000..08946643d --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_access_tokens.go @@ -0,0 +1,237 @@ +// +// Copyright 2022, Masahiro Yoshida +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // GroupAccessTokensServiceInterface defines all the API methods for the GroupAccessTokensService + GroupAccessTokensServiceInterface interface { + ListGroupAccessTokens(gid any, opt *ListGroupAccessTokensOptions, options ...RequestOptionFunc) ([]*GroupAccessToken, *Response, error) + GetGroupAccessToken(gid any, id int, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) + CreateGroupAccessToken(gid any, opt *CreateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) + RotateGroupAccessToken(gid any, id int, opt *RotateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) + RotateGroupAccessTokenSelf(gid any, opt *RotateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) + RevokeGroupAccessToken(gid any, id int, options ...RequestOptionFunc) (*Response, error) + } + + // GroupAccessTokensService handles communication with the + // groups access tokens related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_access_tokens/ + GroupAccessTokensService struct { + client *Client + } +) + +var _ GroupAccessTokensServiceInterface = (*GroupAccessTokensService)(nil) + +// GroupAccessToken represents a GitLab group access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/ +type GroupAccessToken resourceAccessToken + +func (v GroupAccessToken) String() string { + return Stringify(v) +} + +// ListGroupAccessTokensOptions represents the available options for +// listing access tokens in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#list-all-group-access-tokens +type ListGroupAccessTokensOptions struct { + ListOptions + CreatedAfter *ISOTime `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *ISOTime `url:"created_before,omitempty" json:"created_before,omitempty"` + LastUsedAfter *ISOTime `url:"last_used_after,omitempty" json:"last_used_after,omitempty"` + LastUsedBefore *ISOTime `url:"last_used_before,omitempty" json:"last_used_before,omitempty"` + Revoked *bool `url:"revoked,omitempty" json:"revoked,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + State *AccessTokenState `url:"state,omitempty" json:"state,omitempty"` +} + +// ListGroupAccessTokens gets a list of all group access tokens in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#list-all-group-access-tokens +func (s *GroupAccessTokensService) ListGroupAccessTokens(gid any, opt *ListGroupAccessTokensOptions, options ...RequestOptionFunc) ([]*GroupAccessToken, *Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens", PathEscape(groups)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gats []*GroupAccessToken + resp, err := s.client.Do(req, &gats) + if err != nil { + return nil, resp, err + } + + return gats, resp, nil +} + +// GetGroupAccessToken gets a single group access tokens in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#get-details-on-a-group-access-token +func (s *GroupAccessTokensService) GetGroupAccessToken(gid any, id int, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens/%d", PathEscape(groups), id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gat := new(GroupAccessToken) + resp, err := s.client.Do(req, &gat) + if err != nil { + return nil, resp, err + } + + return gat, resp, nil +} + +// CreateGroupAccessTokenOptions represents the available CreateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#create-a-group-access-token +type CreateGroupAccessTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// CreateGroupAccessToken creates a new group access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#create-a-group-access-token +func (s *GroupAccessTokensService) CreateGroupAccessToken(gid any, opt *CreateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens", PathEscape(groups)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(GroupAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotateGroupAccessTokenOptions represents the available RotateGroupAccessToken() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#rotate-a-group-access-token +type RotateGroupAccessTokenOptions struct { + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// RotateGroupAccessToken revokes a group access token and returns a new group +// access token that expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#rotate-a-group-access-token +func (s *GroupAccessTokensService) RotateGroupAccessToken(gid any, id int, opt *RotateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens/%d/rotate", PathEscape(groups), id) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gat := new(GroupAccessToken) + resp, err := s.client.Do(req, gat) + if err != nil { + return nil, resp, err + } + + return gat, resp, nil +} + +// RotateGroupAccessTokenSelf revokes the group access token used for the request +// and returns a new group access token that expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#self-rotate +func (s *GroupAccessTokensService) RotateGroupAccessTokenSelf(gid any, opt *RotateGroupAccessTokenOptions, options ...RequestOptionFunc) (*GroupAccessToken, *Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens/self/rotate", PathEscape(groups)) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gat := new(GroupAccessToken) + resp, err := s.client.Do(req, gat) + if err != nil { + return nil, resp, err + } + + return gat, resp, nil +} + +// RevokeGroupAccessToken revokes a group access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#revoke-a-group-access-token +func (s *GroupAccessTokensService) RevokeGroupAccessToken(gid any, id int, options ...RequestOptionFunc) (*Response, error) { + groups, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/access_tokens/%d", PathEscape(groups), id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_activity_analytics.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_activity_analytics.go new file mode 100644 index 000000000..9824f4d63 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_activity_analytics.go @@ -0,0 +1,148 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "net/http" + +type ( + GroupActivityAnalyticsServiceInterface interface { + GetRecentlyCreatedIssuesCount(opt *GetRecentlyCreatedIssuesCountOptions, options ...RequestOptionFunc) (*IssuesCount, *Response, error) + GetRecentlyCreatedMergeRequestsCount(opt *GetRecentlyCreatedMergeRequestsCountOptions, options ...RequestOptionFunc) (*MergeRequestsCount, *Response, error) + GetRecentlyAddedMembersCount(opt *GetRecentlyAddedMembersCountOptions, options ...RequestOptionFunc) (*NewMembersCount, *Response, error) + } + + // GroupActivityAnalyticsService handles communication with the group activity + // analytics related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_activity_analytics/ + GroupActivityAnalyticsService struct { + client *Client + } +) + +var _ GroupActivityAnalyticsServiceInterface = (*GroupActivityAnalyticsService)(nil) + +// IssuesCount represents the total count of recently created issues in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-issues-for-group +type IssuesCount struct { + IssuesCount int `url:"issues_count" json:"issues_count"` +} + +// GetRecentlyCreatedIssuesCountOptions represents the available +// GetRecentlyCreatedIssuesCount() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-issues-for-group +type GetRecentlyCreatedIssuesCountOptions struct { + GroupPath string `url:"group_path" json:"group_path"` +} + +// GetRecentlyCreatedIssuesCount gets the count of recently created issues for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-issues-for-group +func (s *GroupActivityAnalyticsService) GetRecentlyCreatedIssuesCount(opt *GetRecentlyCreatedIssuesCountOptions, options ...RequestOptionFunc) (*IssuesCount, *Response, error) { + u := "analytics/group_activity/issues_count" + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + res := new(IssuesCount) + resp, err := s.client.Do(req, res) + if err != nil { + return nil, resp, err + } + + return res, resp, nil +} + +// MergeRequestsCount represents the total count of recently created merge requests +// in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-merge-requests-for-group +type MergeRequestsCount struct { + MergeRequestsCount int `url:"merge_requests_count" json:"merge_requests_count"` +} + +// GetRecentlyCreatedMergeRequestsCountOptions represents the available +// GetRecentlyCreatedMergeRequestsCount() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-merge-requests-for-group +type GetRecentlyCreatedMergeRequestsCountOptions struct { + GroupPath string `url:"group_path" json:"group_path"` +} + +// GetRecentlyCreatedMergeRequestsCount gets the count of recently created merge +// requests for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-recently-created-merge-requests-for-group +func (s *GroupActivityAnalyticsService) GetRecentlyCreatedMergeRequestsCount(opt *GetRecentlyCreatedMergeRequestsCountOptions, options ...RequestOptionFunc) (*MergeRequestsCount, *Response, error) { + u := "analytics/group_activity/merge_requests_count" + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + res := new(MergeRequestsCount) + resp, err := s.client.Do(req, res) + if err != nil { + return nil, resp, err + } + + return res, resp, nil +} + +// NewMembersCount represents the total count of recently added members to a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-members-recently-added-to-group +type NewMembersCount struct { + NewMembersCount int `url:"new_members_count" json:"new_members_count"` +} + +// GetRecentlyAddedMembersCountOptions represents the available +// GetRecentlyAddedMembersCount() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-members-recently-added-to-group +type GetRecentlyAddedMembersCountOptions struct { + GroupPath string `url:"group_path" json:"group_path"` +} + +// GetRecentlyAddedMembersCount gets the count of recently added members to a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_activity_analytics/#get-count-of-members-recently-added-to-group +func (s *GroupActivityAnalyticsService) GetRecentlyAddedMembersCount(opt *GetRecentlyAddedMembersCountOptions, options ...RequestOptionFunc) (*NewMembersCount, *Response, error) { + u := "analytics/group_activity/new_members_count" + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + res := new(NewMembersCount) + resp, err := s.client.Do(req, res) + if err != nil { + return nil, resp, err + } + + return res, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_badges.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_badges.go new file mode 100644 index 000000000..b56c58264 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_badges.go @@ -0,0 +1,251 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + // GroupBadgesServiceInterface defines all the API methods for the GroupBadgesService + GroupBadgesServiceInterface interface { + ListGroupBadges(gid any, opt *ListGroupBadgesOptions, options ...RequestOptionFunc) ([]*GroupBadge, *Response, error) + GetGroupBadge(gid any, badge int, options ...RequestOptionFunc) (*GroupBadge, *Response, error) + AddGroupBadge(gid any, opt *AddGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) + EditGroupBadge(gid any, badge int, opt *EditGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) + DeleteGroupBadge(gid any, badge int, options ...RequestOptionFunc) (*Response, error) + PreviewGroupBadge(gid any, opt *GroupBadgePreviewOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) + } + + // GroupBadgesService handles communication with the group badges + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_badges/ + GroupBadgesService struct { + client *Client + } +) + +var _ GroupBadgesServiceInterface = (*GroupBadgesService)(nil) + +// BadgeKind represents a GitLab Badge Kind +type BadgeKind string + +// all possible values Badge Kind +const ( + ProjectBadgeKind BadgeKind = "project" + GroupBadgeKind BadgeKind = "group" +) + +// GroupBadge represents a group badge. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/ +type GroupBadge struct { + ID int `json:"id"` + Name string `json:"name"` + LinkURL string `json:"link_url"` + ImageURL string `json:"image_url"` + RenderedLinkURL string `json:"rendered_link_url"` + RenderedImageURL string `json:"rendered_image_url"` + Kind BadgeKind `json:"kind"` +} + +// ListGroupBadgesOptions represents the available ListGroupBadges() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#list-all-badges-of-a-group +type ListGroupBadgesOptions struct { + ListOptions + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// ListGroupBadges gets a list of a group badges. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#list-all-badges-of-a-group +func (s *GroupBadgesService) ListGroupBadges(gid any, opt *ListGroupBadgesOptions, options ...RequestOptionFunc) ([]*GroupBadge, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/badges", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gb []*GroupBadge + resp, err := s.client.Do(req, &gb) + if err != nil { + return nil, resp, err + } + + return gb, resp, nil +} + +// GetGroupBadge gets a group badge. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#get-a-badge-of-a-group +func (s *GroupBadgesService) GetGroupBadge(gid any, badge int, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/badges/%d", PathEscape(group), badge) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gb := new(GroupBadge) + resp, err := s.client.Do(req, gb) + if err != nil { + return nil, resp, err + } + + return gb, resp, nil +} + +// AddGroupBadgeOptions represents the available AddGroupBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#add-a-badge-to-a-group +type AddGroupBadgeOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// AddGroupBadge adds a badge to a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#add-a-badge-to-a-group +func (s *GroupBadgesService) AddGroupBadge(gid any, opt *AddGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/badges", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gb := new(GroupBadge) + resp, err := s.client.Do(req, gb) + if err != nil { + return nil, resp, err + } + + return gb, resp, nil +} + +// EditGroupBadgeOptions represents the available EditGroupBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#edit-a-badge-of-a-group +type EditGroupBadgeOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// EditGroupBadge updates a badge of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#edit-a-badge-of-a-group +func (s *GroupBadgesService) EditGroupBadge(gid any, badge int, opt *EditGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/badges/%d", PathEscape(group), badge) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + gb := new(GroupBadge) + resp, err := s.client.Do(req, gb) + if err != nil { + return nil, resp, err + } + + return gb, resp, nil +} + +// DeleteGroupBadge removes a badge from a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#remove-a-badge-from-a-group +func (s *GroupBadgesService) DeleteGroupBadge(gid any, badge int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/badges/%d", PathEscape(group), badge) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GroupBadgePreviewOptions represents the available PreviewGroupBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#preview-a-badge-from-a-group +type GroupBadgePreviewOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// PreviewGroupBadge returns how the link_url and image_url final URLs would be after +// resolving the placeholder interpolation. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_badges/#preview-a-badge-from-a-group +func (s *GroupBadgesService) PreviewGroupBadge(gid any, opt *GroupBadgePreviewOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/badges/render", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + gb := new(GroupBadge) + resp, err := s.client.Do(req, &gb) + if err != nil { + return nil, resp, err + } + + return gb, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_boards.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_boards.go new file mode 100644 index 000000000..c5d7e77d2 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_boards.go @@ -0,0 +1,370 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupIssueBoardsServiceInterface interface { + ListGroupIssueBoards(gid any, opt *ListGroupIssueBoardsOptions, options ...RequestOptionFunc) ([]*GroupIssueBoard, *Response, error) + CreateGroupIssueBoard(gid any, opt *CreateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) + GetGroupIssueBoard(gid any, board int, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) + UpdateIssueBoard(gid any, board int, opt *UpdateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) + DeleteIssueBoard(gid any, board int, options ...RequestOptionFunc) (*Response, error) + ListGroupIssueBoardLists(gid any, board int, opt *ListGroupIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) + GetGroupIssueBoardList(gid any, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) + CreateGroupIssueBoardList(gid any, board int, opt *CreateGroupIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) + UpdateIssueBoardList(gid any, board, list int, opt *UpdateGroupIssueBoardListOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) + DeleteGroupIssueBoardList(gid any, board, list int, options ...RequestOptionFunc) (*Response, error) + } + + // GroupIssueBoardsService handles communication with the group issue board + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_boards/ + GroupIssueBoardsService struct { + client *Client + } +) + +var _ GroupIssueBoardsServiceInterface = (*GroupIssueBoardsService)(nil) + +// GroupIssueBoard represents a GitLab group issue board. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/ +type GroupIssueBoard struct { + ID int `json:"id"` + Name string `json:"name"` + Group *Group `json:"group"` + Milestone *Milestone `json:"milestone"` + Labels []*GroupLabel `json:"labels"` + Lists []*BoardList `json:"lists"` +} + +func (b GroupIssueBoard) String() string { + return Stringify(b) +} + +// ListGroupIssueBoardsOptions represents the available +// ListGroupIssueBoards() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#list-all-group-issue-boards-in-a-group +type ListGroupIssueBoardsOptions ListOptions + +// ListGroupIssueBoards gets a list of all issue boards in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#list-all-group-issue-boards-in-a-group +func (s *GroupIssueBoardsService) ListGroupIssueBoards(gid any, opt *ListGroupIssueBoardsOptions, options ...RequestOptionFunc) ([]*GroupIssueBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*GroupIssueBoard + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// CreateGroupIssueBoardOptions represents the available +// CreateGroupIssueBoard() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#create-a-group-issue-board +type CreateGroupIssueBoardOptions struct { + Name *string `url:"name" json:"name"` +} + +// CreateGroupIssueBoard creates a new issue board. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#create-a-group-issue-board +func (s *GroupIssueBoardsService) CreateGroupIssueBoard(gid any, opt *CreateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gib := new(GroupIssueBoard) + resp, err := s.client.Do(req, gib) + if err != nil { + return nil, resp, err + } + + return gib, resp, nil +} + +// GetGroupIssueBoard gets a single issue board of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#single-group-issue-board +func (s *GroupIssueBoardsService) GetGroupIssueBoard(gid any, board int, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gib := new(GroupIssueBoard) + resp, err := s.client.Do(req, gib) + if err != nil { + return nil, resp, err + } + + return gib, resp, nil +} + +// UpdateGroupIssueBoardOptions represents a group issue board. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#update-a-group-issue-board +type UpdateGroupIssueBoardOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels *LabelOptions `url:"labels,omitempty" json:"labels,omitempty"` + Weight *int `url:"weight,omitempty" json:"weight,omitempty"` +} + +// UpdateIssueBoard updates a single issue board of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#update-a-group-issue-board +func (s *GroupIssueBoardsService) UpdateIssueBoard(gid any, board int, opt *UpdateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + gib := new(GroupIssueBoard) + resp, err := s.client.Do(req, gib) + if err != nil { + return nil, resp, err + } + + return gib, resp, nil +} + +// DeleteIssueBoard delete a single issue board of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#delete-a-group-issue-board +func (s *GroupIssueBoardsService) DeleteIssueBoard(gid any, board int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGroupIssueBoardListsOptions represents the available +// ListGroupIssueBoardLists() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#list-group-issue-board-lists +type ListGroupIssueBoardListsOptions ListOptions + +// ListGroupIssueBoardLists gets a list of the issue board's lists. Does not include +// backlog and closed lists. +// +// GitLab API docs: https://docs.gitlab.com/api/group_boards/#list-group-issue-board-lists +func (s *GroupIssueBoardsService) ListGroupIssueBoardLists(gid any, board int, opt *ListGroupIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d/lists", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gbl []*BoardList + resp, err := s.client.Do(req, &gbl) + if err != nil { + return nil, resp, err + } + + return gbl, resp, nil +} + +// GetGroupIssueBoardList gets a single issue board list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#single-group-issue-board-list +func (s *GroupIssueBoardsService) GetGroupIssueBoardList(gid any, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", + PathEscape(group), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gbl := new(BoardList) + resp, err := s.client.Do(req, gbl) + if err != nil { + return nil, resp, err + } + + return gbl, resp, nil +} + +// CreateGroupIssueBoardListOptions represents the available +// CreateGroupIssueBoardList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#new-group-issue-board-list +type CreateGroupIssueBoardListOptions struct { + LabelID *int `url:"label_id" json:"label_id"` +} + +// CreateGroupIssueBoardList creates a new issue board list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#new-group-issue-board-list +func (s *GroupIssueBoardsService) CreateGroupIssueBoardList(gid any, board int, opt *CreateGroupIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d/lists", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gbl := new(BoardList) + resp, err := s.client.Do(req, gbl) + if err != nil { + return nil, resp, err + } + + return gbl, resp, nil +} + +// UpdateGroupIssueBoardListOptions represents the available +// UpdateGroupIssueBoardList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#edit-group-issue-board-list +type UpdateGroupIssueBoardListOptions struct { + Position *int `url:"position" json:"position"` +} + +// UpdateIssueBoardList updates the position of an existing +// group issue board list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#edit-group-issue-board-list +func (s *GroupIssueBoardsService) UpdateIssueBoardList(gid any, board, list int, opt *UpdateGroupIssueBoardListOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", + PathEscape(group), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gbl []*BoardList + resp, err := s.client.Do(req, &gbl) + if err != nil { + return nil, resp, err + } + + return gbl, resp, nil +} + +// DeleteGroupIssueBoardList soft deletes a group issue board list. +// Only for admins and group owners. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_boards/#delete-a-group-issue-board-list +func (s *GroupIssueBoardsService) DeleteGroupIssueBoardList(gid any, board, list int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/boards/%d/lists/%d", + PathEscape(group), + board, + list, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/group_clusters.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_clusters.go similarity index 57% rename from vendor/github.com/xanzy/go-gitlab/group_clusters.go rename to vendor/gitlab.com/gitlab-org/api/client-go/group_clusters.go index e91cbd20f..145f56ea4 100644 --- a/vendor/github.com/xanzy/go-gitlab/group_clusters.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_clusters.go @@ -1,5 +1,5 @@ // -// Copyright 2019, Paul Shoemaker +// Copyright 2021, Paul Shoemaker // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,26 +18,50 @@ package gitlab import ( "fmt" + "net/http" "time" ) -// GroupClustersService handles communication with the -// group clusters related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html -type GroupClustersService struct { - client *Client -} +type ( + // Deprecated: in GitLab 14.5, to be removed in 19.0 + GroupClustersServiceInterface interface { + // Deprecated: in GitLab 14.5, to be removed in 19.0 + ListClusters(pid any, options ...RequestOptionFunc) ([]*GroupCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + GetCluster(pid any, cluster int, options ...RequestOptionFunc) (*GroupCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + AddCluster(pid any, opt *AddGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + EditCluster(pid any, cluster int, opt *EditGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + DeleteCluster(pid any, cluster int, options ...RequestOptionFunc) (*Response, error) + } + + // GroupClustersService handles communication with the + // group clusters related methods of the GitLab API. + // Deprecated: in GitLab 14.5, to be removed in 19.0 + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_clusters/ + GroupClustersService struct { + client *Client + } +) + +// Deprecated: in GitLab 14.5, to be removed in 19.0 +var _ GroupClustersServiceInterface = (*GroupClustersService)(nil) // GroupCluster represents a GitLab Group Cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // -// GitLab API docs: https://docs.gitlab.com/ee/api/group_clusters.html +// GitLab API docs: https://docs.gitlab.com/api/group_clusters/ type GroupCluster struct { ID int `json:"id"` Name string `json:"name"` Domain string `json:"domain"` CreatedAt *time.Time `json:"created_at"` + Managed bool `json:"managed"` + Enabled bool `json:"enabled"` ProviderType string `json:"provider_type"` PlatformType string `json:"platform_type"` EnvironmentScope string `json:"environment_scope"` @@ -48,22 +72,24 @@ type GroupCluster struct { Group *Group `json:"group"` } +// Deprecated: in GitLab 14.5, to be removed in 19.0 func (v GroupCluster) String() string { return Stringify(v) } // ListClusters gets a list of all clusters in a group. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#list-group-clusters -func (s *GroupClustersService) ListClusters(pid interface{}, options ...RequestOptionFunc) ([]*GroupCluster, *Response, error) { +// https://docs.gitlab.com/api/group_clusters/#list-group-clusters +func (s *GroupClustersService) ListClusters(pid any, options ...RequestOptionFunc) ([]*GroupCluster, *Response, error) { group, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/clusters", pathEscape(group)) + u := fmt.Sprintf("groups/%s/clusters", PathEscape(group)) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -74,21 +100,22 @@ func (s *GroupClustersService) ListClusters(pid interface{}, options ...RequestO return nil, resp, err } - return pcs, resp, err + return pcs, resp, nil } // GetCluster gets a cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#get-a-single-group-cluster -func (s *GroupClustersService) GetCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { +// https://docs.gitlab.com/api/group_clusters/#get-a-single-group-cluster +func (s *GroupClustersService) GetCluster(pid any, cluster int, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { group, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster) + u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -99,13 +126,14 @@ func (s *GroupClustersService) GetCluster(pid interface{}, cluster int, options return nil, resp, err } - return gc, resp, err + return gc, resp, nil } // AddGroupClusterOptions represents the available AddCluster() options. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#add-existing-cluster-to-group +// https://docs.gitlab.com/api/group_clusters/#add-existing-cluster-to-group type AddGroupClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` @@ -117,6 +145,7 @@ type AddGroupClusterOptions struct { } // AddGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for adding. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type AddGroupPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` @@ -126,17 +155,18 @@ type AddGroupPlatformKubernetesOptions struct { } // AddCluster adds an existing cluster to the group. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#add-existing-cluster-to-group -func (s *GroupClustersService) AddCluster(pid interface{}, opt *AddGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { +// https://docs.gitlab.com/api/group_clusters/#add-existing-cluster-to-group +func (s *GroupClustersService) AddCluster(pid any, opt *AddGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { group, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/clusters/user", pathEscape(group)) + u := fmt.Sprintf("groups/%s/clusters/user", PathEscape(group)) - req, err := s.client.NewRequest("POST", u, opt, options) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } @@ -147,13 +177,14 @@ func (s *GroupClustersService) AddCluster(pid interface{}, opt *AddGroupClusterO return nil, resp, err } - return gc, resp, err + return gc, resp, nil } // EditGroupClusterOptions represents the available EditCluster() options. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#edit-group-cluster +// https://docs.gitlab.com/api/group_clusters/#edit-group-cluster type EditGroupClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` @@ -163,6 +194,7 @@ type EditGroupClusterOptions struct { } // EditGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for editing. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type EditGroupPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` @@ -170,17 +202,18 @@ type EditGroupPlatformKubernetesOptions struct { } // EditCluster updates an existing group cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#edit-group-cluster -func (s *GroupClustersService) EditCluster(pid interface{}, cluster int, opt *EditGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { +// https://docs.gitlab.com/api/group_clusters/#edit-group-cluster +func (s *GroupClustersService) EditCluster(pid any, cluster int, opt *EditGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) { group, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster) + u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) - req, err := s.client.NewRequest("PUT", u, opt, options) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } @@ -191,21 +224,22 @@ func (s *GroupClustersService) EditCluster(pid interface{}, cluster int, opt *Ed return nil, resp, err } - return gc, resp, err + return gc, resp, nil } // DeleteCluster deletes an existing group cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/group_clusters.html#delete-group-cluster -func (s *GroupClustersService) DeleteCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*Response, error) { +// https://docs.gitlab.com/api/group_clusters/#delete-group-cluster +func (s *GroupClustersService) DeleteCluster(pid any, cluster int, options ...RequestOptionFunc) (*Response, error) { group, err := parseID(pid) if err != nil { return nil, err } - u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster) + u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_epic_boards.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_epic_boards.go new file mode 100644 index 000000000..23097312e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_epic_boards.go @@ -0,0 +1,113 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupEpicBoardsServiceInterface interface { + ListGroupEpicBoards(gid any, opt *ListGroupEpicBoardsOptions, options ...RequestOptionFunc) ([]*GroupEpicBoard, *Response, error) + GetGroupEpicBoard(gid any, board int, options ...RequestOptionFunc) (*GroupEpicBoard, *Response, error) + } + + // GroupEpicBoardsService handles communication with the group epic board + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_epic_boards/ + GroupEpicBoardsService struct { + client *Client + } +) + +var _ GroupEpicBoardsServiceInterface = (*GroupEpicBoardsService)(nil) + +// GroupEpicBoard represents a GitLab group epic board. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_epic_boards/ +type GroupEpicBoard struct { + ID int `json:"id"` + Name string `json:"name"` + Group *Group `json:"group"` + Labels []*LabelDetails `json:"labels"` + Lists []*BoardList `json:"lists"` +} + +func (b GroupEpicBoard) String() string { + return Stringify(b) +} + +// ListGroupEpicBoardsOptions represents the available +// ListGroupEpicBoards() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_epic_boards/#list-all-epic-boards-in-a-group +type ListGroupEpicBoardsOptions ListOptions + +// ListGroupEpicBoards gets a list of all epic boards in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_epic_boards/#list-all-epic-boards-in-a-group +func (s *GroupEpicBoardsService) ListGroupEpicBoards(gid any, opt *ListGroupEpicBoardsOptions, options ...RequestOptionFunc) ([]*GroupEpicBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epic_boards", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*GroupEpicBoard + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// GetGroupEpicBoard gets a single epic board of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_epic_boards/#single-group-epic-board +func (s *GroupEpicBoardsService) GetGroupEpicBoard(gid any, board int, options ...RequestOptionFunc) (*GroupEpicBoard, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epic_boards/%d", PathEscape(group), board) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gib := new(GroupEpicBoard) + resp, err := s.client.Do(req, gib) + if err != nil { + return nil, resp, err + } + + return gib, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_hooks.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_hooks.go new file mode 100644 index 000000000..4e5487ce0 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_hooks.go @@ -0,0 +1,373 @@ +// +// Copyright 2021, Eric Stevens +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +// GroupHook represents a GitLab group hook. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/ +type GroupHook struct { + ID int `json:"id"` + URL string `json:"url"` + Name string `json:"name"` + Description string `json:"description"` + CreatedAt *time.Time `json:"created_at"` + PushEvents bool `json:"push_events"` + TagPushEvents bool `json:"tag_push_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + RepositoryUpdateEvents bool `json:"repository_update_events"` + EnableSSLVerification bool `json:"enable_ssl_verification"` + AlertStatus string `json:"alert_status"` + PushEventsBranchFilter string `json:"push_events_branch_filter"` + BranchFilterStrategy string `json:"branch_filter_strategy"` + CustomWebhookTemplate string `json:"custom_webhook_template"` + CustomHeaders []*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` + GroupID int `json:"group_id"` + IssuesEvents bool `json:"issues_events"` + ConfidentialIssuesEvents bool `json:"confidential_issues_events"` + NoteEvents bool `json:"note_events"` + ConfidentialNoteEvents bool `json:"confidential_note_events"` + PipelineEvents bool `json:"pipeline_events"` + WikiPageEvents bool `json:"wiki_page_events"` + JobEvents bool `json:"job_events"` + DeploymentEvents bool `json:"deployment_events"` + FeatureFlagEvents bool `json:"feature_flag_events"` + ReleasesEvents bool `json:"releases_events"` + SubGroupEvents bool `json:"subgroup_events"` + EmojiEvents bool `json:"emoji_events"` + ResourceAccessTokenEvents bool `json:"resource_access_token_events"` + MemberEvents bool `json:"member_events"` +} + +// ListGroupHooksOptions represents the available ListGroupHooks() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#list-group-hooks +type ListGroupHooksOptions ListOptions + +// ListGroupHooks gets a list of group hooks. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#list-group-hooks +func (s *GroupsService) ListGroupHooks(gid any, opt *ListGroupHooksOptions, options ...RequestOptionFunc) ([]*GroupHook, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/hooks", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + var gh []*GroupHook + resp, err := s.client.Do(req, &gh) + if err != nil { + return nil, resp, err + } + + return gh, resp, nil +} + +// GetGroupHook gets a specific hook for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#get-a-group-hook +func (s *GroupsService) GetGroupHook(gid any, hook int, options ...RequestOptionFunc) (*GroupHook, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d", PathEscape(group), hook) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gh := new(GroupHook) + resp, err := s.client.Do(req, gh) + if err != nil { + return nil, resp, err + } + + return gh, resp, nil +} + +// ResendGroupHookEvent resends a specific hook event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#resend-group-hook-event +func (s *GroupsService) ResendGroupHookEvent(gid any, hook int, hookEventID int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/events/%d/resend", PathEscape(group), hook, hookEventID) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// AddGroupHookOptions represents the available AddGroupHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#add-a-group-hook +type AddGroupHookOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` + BranchFilterStrategy *string `url:"branch_filter_strategy,omitempty" json:"branch_filter_strategy,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + FeatureFlagEvents *bool `url:"feature_flag_events,omitempty" json:"feature_flag_events,omitempty"` + ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"` + SubGroupEvents *bool `url:"subgroup_events,omitempty" json:"subgroup_events,omitempty"` + MemberEvents *bool `url:"member_events,omitempty" json:"member_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` + ResourceAccessTokenEvents *bool `url:"resource_access_token_events,omitempty" json:"resource_access_token_events,omitempty"` + CustomWebhookTemplate *string `url:"custom_webhook_template,omitempty" json:"custom_webhook_template,omitempty"` + CustomHeaders *[]*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` +} + +// AddGroupHook creates a new group scoped webhook. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#add-a-group-hook +func (s *GroupsService) AddGroupHook(gid any, opt *AddGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/hooks", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gh := new(GroupHook) + resp, err := s.client.Do(req, gh) + if err != nil { + return nil, resp, err + } + + return gh, resp, nil +} + +// EditGroupHookOptions represents the available EditGroupHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#edit-group-hook +type EditGroupHookOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` + BranchFilterStrategy *string `url:"branch_filter_strategy,omitempty" json:"branch_filter_strategy,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + FeatureFlagEvents *bool `url:"feature_flag_events,omitempty" json:"feature_flag_events,omitempty"` + ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"` + SubGroupEvents *bool `url:"subgroup_events,omitempty" json:"subgroup_events,omitempty"` + MemberEvents *bool `url:"member_events,omitempty" json:"member_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + ServiceAccessTokensExpirationEnforced *bool `url:"service_access_tokens_expiration_enforced,omitempty" json:"service_access_tokens_expiration_enforced,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` + ResourceAccessTokenEvents *bool `url:"resource_access_token_events,omitempty" json:"resource_access_token_events,omitempty"` + CustomWebhookTemplate *string `url:"custom_webhook_template,omitempty" json:"custom_webhook_template,omitempty"` + CustomHeaders *[]*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` +} + +// EditGroupHook edits a hook for a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/group_webhooks/#edit-group-hook +func (s *GroupsService) EditGroupHook(gid any, hook int, opt *EditGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d", PathEscape(group), hook) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + gh := new(GroupHook) + resp, err := s.client.Do(req, gh) + if err != nil { + return nil, resp, err + } + + return gh, resp, nil +} + +// DeleteGroupHook removes a hook from a group. This is an idempotent +// method and can be called multiple times. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#delete-a-group-hook +func (s *GroupsService) DeleteGroupHook(gid any, hook int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d", PathEscape(group), hook) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// TriggerTestGroupHook triggers a test hook for a specified group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#trigger-a-test-group-hook +func (s *GroupsService) TriggerTestGroupHook(pid any, hook int, trigger GroupHookTrigger, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/test/%s", PathEscape(group), hook, trigger) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SetGroupCustomHeader creates or updates a group custom webhook header. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#set-a-custom-header +func (s *GroupsService) SetGroupCustomHeader(gid any, hook int, key string, opt *SetHookCustomHeaderOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/custom_headers/%s", PathEscape(group), hook, key) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteGroupCustomHeader deletes a group custom webhook header. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#delete-a-custom-header +func (s *GroupsService) DeleteGroupCustomHeader(gid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/custom_headers/%s", PathEscape(group), hook, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SetHookURLVariableOptions represents the available SetGroupHookURLVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#set-a-url-variable +type SetHookURLVariableOptions struct { + Value *string `json:"value,omitempty"` +} + +// SetGroupHookURLVariable sets a group hook URL variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#set-a-url-variable +func (s *GroupsService) SetGroupHookURLVariable(gid any, hook int, key string, opt *SetHookURLVariableOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/url_variables/%s", PathEscape(group), hook, key) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteGroupHookURLVariable sets a group hook URL variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_webhooks/#delete-a-url-variable +func (s *GroupsService) DeleteGroupHookURLVariable(gid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/hooks/%d/url_variables/%s", PathEscape(group), hook, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_import_export.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_import_export.go new file mode 100644 index 000000000..406480040 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_import_export.go @@ -0,0 +1,190 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "mime/multipart" + "net/http" + "os" + "path/filepath" + "strconv" +) + +type ( + GroupImportExportServiceInterface interface { + ScheduleExport(gid any, options ...RequestOptionFunc) (*Response, error) + ExportDownload(gid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + ImportFile(opt *GroupImportFileOptions, options ...RequestOptionFunc) (*Response, error) + } + + // GroupImportExportService handles communication with the group import export + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_import_export/ + GroupImportExportService struct { + client *Client + } +) + +var _ GroupImportExportServiceInterface = (*GroupImportExportService)(nil) + +// ScheduleExport starts a new group export. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_import_export/#schedule-new-export +func (s *GroupImportExportService) ScheduleExport(gid any, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/export", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ExportDownload downloads the finished export. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_import_export/#export-download +func (s *GroupImportExportService) ExportDownload(gid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/export/download", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + exportDownload := new(bytes.Buffer) + resp, err := s.client.Do(req, exportDownload) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(exportDownload.Bytes()), resp, err +} + +// GroupImportFileOptions represents the available ImportFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_import_export/#import-a-file +type GroupImportFileOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + File *string `url:"file,omitempty" json:"file,omitempty"` + ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` +} + +// ImportFile imports a file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_import_export/#import-a-file +func (s *GroupImportExportService) ImportFile(opt *GroupImportFileOptions, options ...RequestOptionFunc) (*Response, error) { + // First check if we got all required options. + if opt.Name == nil || *opt.Name == "" { + return nil, fmt.Errorf("missing required option: Name") + } + if opt.Path == nil || *opt.Path == "" { + return nil, fmt.Errorf("missing required option: Path") + } + if opt.File == nil || *opt.File == "" { + return nil, fmt.Errorf("missing required option: File") + } + + f, err := os.Open(*opt.File) + if err != nil { + return nil, err + } + defer f.Close() + + b := &bytes.Buffer{} + w := multipart.NewWriter(b) + + _, filename := filepath.Split(*opt.File) + fw, err := w.CreateFormFile("file", filename) + if err != nil { + return nil, err + } + + _, err = io.Copy(fw, f) + if err != nil { + return nil, err + } + + // Populate the additional fields. + fw, err = w.CreateFormField("name") + if err != nil { + return nil, err + } + + _, err = fw.Write([]byte(*opt.Name)) + if err != nil { + return nil, err + } + + fw, err = w.CreateFormField("path") + if err != nil { + return nil, err + } + + _, err = fw.Write([]byte(*opt.Path)) + if err != nil { + return nil, err + } + + if opt.ParentID != nil { + fw, err = w.CreateFormField("parent_id") + if err != nil { + return nil, err + } + + _, err = fw.Write([]byte(strconv.Itoa(*opt.ParentID))) + if err != nil { + return nil, err + } + } + + if err = w.Close(); err != nil { + return nil, err + } + + req, err := s.client.NewRequest(http.MethodPost, "groups/import", nil, options) + if err != nil { + return nil, err + } + + // Set the buffer as the request body. + if err = req.SetBody(b); err != nil { + return nil, err + } + + // Overwrite the default content type. + req.Header.Set("Content-Type", w.FormDataContentType()) + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_iterations.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_iterations.go new file mode 100644 index 000000000..a0f7e337f --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_iterations.go @@ -0,0 +1,98 @@ +// +// Copyright 2022, Daniel Steinke +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + GroupIterationsServiceInterface interface { + ListGroupIterations(gid any, opt *ListGroupIterationsOptions, options ...RequestOptionFunc) ([]*GroupIteration, *Response, error) + } + + // IterationsAPI handles communication with the iterations related methods + // of the GitLab API + // + // GitLab API docs: https://docs.gitlab.com/api/group_iterations/ + GroupIterationsService struct { + client *Client + } +) + +var _ GroupIterationsServiceInterface = (*GroupIterationsService)(nil) + +// GroupInteration represents a GitLab iteration. +// +// GitLab API docs: https://docs.gitlab.com/api/group_iterations/ +type GroupIteration struct { + ID int `json:"id"` + IID int `json:"iid"` + Sequence int `json:"sequence"` + GroupID int `json:"group_id"` + Title string `json:"title"` + Description string `json:"description"` + State int `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + DueDate *ISOTime `json:"due_date"` + StartDate *ISOTime `json:"start_date"` + WebURL string `json:"web_url"` +} + +func (i GroupIteration) String() string { + return Stringify(i) +} + +// ListGroupIterationsOptions contains the available ListGroupIterations() +// options +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_iterations/#list-group-iterations +type ListGroupIterationsOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"` +} + +// ListGroupIterations returns a list of group iterations. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_iterations/#list-group-iterations +func (s *GroupIterationsService) ListGroupIterations(gid any, opt *ListGroupIterationsOptions, options ...RequestOptionFunc) ([]*GroupIteration, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/iterations", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gis []*GroupIteration + resp, err := s.client.Do(req, &gis) + if err != nil { + return nil, nil, err + } + + return gis, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_labels.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_labels.go new file mode 100644 index 000000000..7bd4d1df8 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_labels.go @@ -0,0 +1,293 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupLabelsServiceInterface interface { + ListGroupLabels(gid any, opt *ListGroupLabelsOptions, options ...RequestOptionFunc) ([]*GroupLabel, *Response, error) + GetGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*GroupLabel, *Response, error) + CreateGroupLabel(gid any, opt *CreateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) + DeleteGroupLabel(gid any, lid any, opt *DeleteGroupLabelOptions, options ...RequestOptionFunc) (*Response, error) + UpdateGroupLabel(gid any, lid any, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) + SubscribeToGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*GroupLabel, *Response, error) + UnsubscribeFromGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*Response, error) + } + + // GroupLabelsService handles communication with the label related methods of the + // GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_labels/ + GroupLabelsService struct { + client *Client + } +) + +var _ GroupLabelsServiceInterface = (*GroupLabelsService)(nil) + +// GroupLabel represents a GitLab group label. +// +// GitLab API docs: https://docs.gitlab.com/api/group_labels/ +type GroupLabel Label + +func (l GroupLabel) String() string { + return Stringify(l) +} + +// ListGroupLabelsOptions represents the available ListGroupLabels() options. +// +// GitLab API docs: https://docs.gitlab.com/api/group_labels/#list-group-labels +type ListGroupLabelsOptions struct { + ListOptions + WithCounts *bool `url:"with_counts,omitempty" json:"with_counts,omitempty"` + IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"` + IncludeDescendantGrouops *bool `url:"include_descendant_groups,omitempty" json:"include_descendant_groups,omitempty"` + OnlyGroupLabels *bool `url:"only_group_labels,omitempty" json:"only_group_labels,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListGroupLabels gets all labels for given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#list-group-labels +func (s *GroupLabelsService) ListGroupLabels(gid any, opt *ListGroupLabelsOptions, options ...RequestOptionFunc) ([]*GroupLabel, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/labels", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var l []*GroupLabel + resp, err := s.client.Do(req, &l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// GetGroupLabel get a single label for a given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#get-a-single-group-label +func (s *GroupLabelsService) GetGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/labels/%s", PathEscape(group), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var l *GroupLabel + resp, err := s.client.Do(req, &l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// CreateGroupLabelOptions represents the available CreateGroupLabel() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#create-a-new-group-label +type CreateGroupLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Priority *int `url:"priority,omitempty" json:"priority,omitempty"` +} + +// CreateGroupLabel creates a new label for given group with given name and +// color. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#create-a-new-group-label +func (s *GroupLabelsService) CreateGroupLabel(gid any, opt *CreateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/labels", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(GroupLabel) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// DeleteGroupLabelOptions represents the available DeleteGroupLabel() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#delete-a-group-label +type DeleteGroupLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// DeleteGroupLabel deletes a group label given by its name or ID. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#delete-a-group-label +func (s *GroupLabelsService) DeleteGroupLabel(gid any, lid any, opt *DeleteGroupLabelOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/labels", PathEscape(group)) + + if lid != nil { + label, err := parseID(lid) + if err != nil { + return nil, err + } + u = fmt.Sprintf("groups/%s/labels/%s", PathEscape(group), PathEscape(label)) + } + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateGroupLabelOptions represents the available UpdateGroupLabel() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#update-a-group-label +type UpdateGroupLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Priority *int `url:"priority,omitempty" json:"priority,omitempty"` +} + +// UpdateGroupLabel updates an existing label with new name or now color. At least +// one parameter is required, to update the label. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#update-a-group-label +func (s *GroupLabelsService) UpdateGroupLabel(gid any, lid any, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/labels", PathEscape(group)) + + if lid != nil { + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u = fmt.Sprintf("groups/%s/labels/%s", PathEscape(group), PathEscape(label)) + } + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(GroupLabel) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// SubscribeToGroupLabel subscribes the authenticated user to a label to receive +// notifications. If the user is already subscribed to the label, the status +// code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#subscribe-to-a-group-label +func (s *GroupLabelsService) SubscribeToGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*GroupLabel, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/labels/%s/subscribe", PathEscape(group), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + l := new(GroupLabel) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// UnsubscribeFromGroupLabel unsubscribes the authenticated user from a label to not +// receive notifications from it. If the user is not subscribed to the label, the +// status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_labels/#unsubscribe-from-a-group-label +func (s *GroupLabelsService) UnsubscribeFromGroupLabel(gid any, lid any, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/labels/%s/unsubscribe", PathEscape(group), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_markdown_uploads.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_markdown_uploads.go new file mode 100644 index 000000000..5c0afc849 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_markdown_uploads.go @@ -0,0 +1,97 @@ +// +// Copyright 2024, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "io" +) + +type ( + GroupMarkdownUploadsServiceInterface interface { + ListGroupMarkdownUploads(gid any, opt *ListMarkdownUploadsOptions, options ...RequestOptionFunc) ([]*GroupMarkdownUpload, *Response, error) + DownloadGroupMarkdownUploadByID(gid any, uploadID int, options ...RequestOptionFunc) (io.Reader, *Response, error) + DownloadGroupMarkdownUploadBySecretAndFilename(gid any, secret string, filename string, options ...RequestOptionFunc) (io.Reader, *Response, error) + DeleteGroupMarkdownUploadByID(gid any, uploadID int, options ...RequestOptionFunc) (*Response, error) + DeleteGroupMarkdownUploadBySecretAndFilename(gid any, secret string, filename string, options ...RequestOptionFunc) (*Response, error) + } + + // GroupMarkdownUploadsService handles communication with the group + // markdown uploads related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_access_tokens/ + GroupMarkdownUploadsService struct { + client *Client + } +) + +var _ GroupMarkdownUploadsServiceInterface = (*GroupMarkdownUploadsService)(nil) + +// Type aliases for backward compatibility +type ( + GroupMarkdownUpload = MarkdownUpload +) + +// ListGroupMarkdownUploads gets all markdown uploads for a group. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_markdown_uploads/#list-uploads +func (s *GroupMarkdownUploadsService) ListGroupMarkdownUploads(gid any, opt *ListMarkdownUploadsOptions, options ...RequestOptionFunc) ([]*GroupMarkdownUpload, *Response, error) { + return listMarkdownUploads[GroupMarkdownUpload](s.client, GroupResource, gid, opt, options) +} + +// DownloadGroupMarkdownUploadByID downloads a specific upload by ID. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_markdown_uploads/#download-an-uploaded-file-by-id +func (s *GroupMarkdownUploadsService) DownloadGroupMarkdownUploadByID(gid any, uploadID int, options ...RequestOptionFunc) (io.Reader, *Response, error) { + buffer, resp, err := downloadMarkdownUploadByID(s.client, GroupResource, gid, uploadID, options) + if err != nil { + return nil, resp, err + } + return buffer, resp, nil +} + +// DownloadGroupMarkdownUploadBySecretAndFilename downloads a specific upload +// by secret and filename. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_markdown_uploads/#download-an-uploaded-file-by-secret-and-filename +func (s *GroupMarkdownUploadsService) DownloadGroupMarkdownUploadBySecretAndFilename(gid any, secret string, filename string, options ...RequestOptionFunc) (io.Reader, *Response, error) { + buffer, resp, err := downloadMarkdownUploadBySecretAndFilename(s.client, GroupResource, gid, secret, filename, options) + if err != nil { + return nil, resp, err + } + return buffer, resp, nil +} + +// DeleteGroupMarkdownUploadByID deletes an upload by ID. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_markdown_uploads/#delete-an-uploaded-file-by-id +func (s *GroupMarkdownUploadsService) DeleteGroupMarkdownUploadByID(gid any, uploadID int, options ...RequestOptionFunc) (*Response, error) { + return deleteMarkdownUploadByID(s.client, GroupResource, gid, uploadID, options) +} + +// DeleteGroupMarkdownUploadBySecretAndFilename deletes an upload +// by secret and filename. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_markdown_uploads/#delete-an-uploaded-file-by-secret-and-filename +func (s *GroupMarkdownUploadsService) DeleteGroupMarkdownUploadBySecretAndFilename(gid any, secret string, filename string, options ...RequestOptionFunc) (*Response, error) { + return deleteMarkdownUploadBySecretAndFilename(s.client, GroupResource, gid, secret, filename, options) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_members.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_members.go new file mode 100644 index 000000000..904507543 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_members.go @@ -0,0 +1,455 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + GroupMembersServiceInterface interface { + GetGroupMember(gid any, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) + GetInheritedGroupMember(gid any, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) + AddGroupMember(gid any, opt *AddGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) + ShareWithGroup(gid any, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + DeleteShareWithGroup(gid any, groupID int, options ...RequestOptionFunc) (*Response, error) + EditGroupMember(gid any, user int, opt *EditGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) + RemoveGroupMember(gid any, user int, opt *RemoveGroupMemberOptions, options ...RequestOptionFunc) (*Response, error) + } + + // GroupMembersService handles communication with the group members + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/members/ + GroupMembersService struct { + client *Client + } +) + +var _ GroupMembersServiceInterface = (*GroupMembersService)(nil) + +// GroupMember represents a GitLab group member. +// +// GitLab API docs: https://docs.gitlab.com/api/members/ +type GroupMember struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *ISOTime `json:"expires_at"` + AccessLevel AccessLevelValue `json:"access_level"` + Email string `json:"email,omitempty"` + GroupSAMLIdentity *GroupMemberSAMLIdentity `json:"group_saml_identity"` + MemberRole *MemberRole `json:"member_role"` +} + +// GroupMemberSAMLIdentity represents the SAML Identity link for the group member. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project +type GroupMemberSAMLIdentity struct { + ExternUID string `json:"extern_uid"` + Provider string `json:"provider"` + SAMLProviderID int `json:"saml_provider_id"` +} + +// BillableGroupMember represents a GitLab billable group member. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-billable-members-of-a-group +type BillableGroupMember struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + Email string `json:"email"` + LastActivityOn *ISOTime `json:"last_activity_on"` + MembershipType string `json:"membership_type"` + Removable bool `json:"removable"` + CreatedAt *time.Time `json:"created_at"` + IsLastOwner bool `json:"is_last_owner"` + LastLoginAt *time.Time `json:"last_login_at"` +} + +// BillableUserMembership represents a Membership of a billable user of a group +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-memberships-for-a-billable-member-of-a-group +type BillableUserMembership struct { + ID int `json:"id"` + SourceID int `json:"source_id"` + SourceFullName string `json:"source_full_name"` + SourceMembersURL string `json:"source_members_url"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *time.Time `json:"expires_at"` + AccessLevel *AccessLevelDetails `json:"access_level"` +} + +// ListGroupMembersOptions represents the available ListGroupMembers() and +// ListAllGroupMembers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project +type ListGroupMembersOptions struct { + ListOptions + Query *string `url:"query,omitempty" json:"query,omitempty"` + UserIDs *[]int `url:"user_ids[],omitempty" json:"user_ids,omitempty"` +} + +// ListGroupMembers get a list of group members viewable by the authenticated +// user. Inherited members through ancestor groups are not included. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project +func (s *GroupsService) ListGroupMembers(gid any, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gm []*GroupMember + resp, err := s.client.Do(req, &gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, nil +} + +// ListAllGroupMembers get a list of group members viewable by the authenticated +// user. Returns a list including inherited members through ancestor groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project-including-inherited-and-invited-members +func (s *GroupsService) ListAllGroupMembers(gid any, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members/all", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gm []*GroupMember + resp, err := s.client.Do(req, &gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, nil +} + +// AddGroupMemberOptions represents the available AddGroupMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#add-a-member-to-a-group-or-project +type AddGroupMemberOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// GetGroupMember gets a member of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#get-a-member-of-a-group-or-project +func (s *GroupMembersService) GetGroupMember(gid any, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gm := new(GroupMember) + resp, err := s.client.Do(req, gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, nil +} + +// GetInheritedGroupMember get a member of a group or project, including +// inherited and invited members +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#get-a-member-of-a-group-or-project-including-inherited-and-invited-members +func (s *GroupMembersService) GetInheritedGroupMember(gid any, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members/all/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gm := new(GroupMember) + resp, err := s.client.Do(req, gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, err +} + +// ListBillableGroupMembersOptions represents the available +// ListBillableGroupMembers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-billable-members-of-a-group +type ListBillableGroupMembersOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListBillableGroupMembers Gets a list of group members that count as billable. +// The list includes members in the subgroup or subproject. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-billable-members-of-a-group +func (s *GroupsService) ListBillableGroupMembers(gid any, opt *ListBillableGroupMembersOptions, options ...RequestOptionFunc) ([]*BillableGroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/billable_members", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var bgm []*BillableGroupMember + resp, err := s.client.Do(req, &bgm) + if err != nil { + return nil, resp, err + } + + return bgm, resp, nil +} + +// ListMembershipsForBillableGroupMemberOptions represents the available +// ListMembershipsForBillableGroupMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-memberships-for-a-billable-member-of-a-group +type ListMembershipsForBillableGroupMemberOptions = ListOptions + +// ListMembershipsForBillableGroupMember gets a list of memberships for a +// billable member of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-memberships-for-a-billable-member-of-a-group +func (s *GroupsService) ListMembershipsForBillableGroupMember(gid any, user int, opt *ListMembershipsForBillableGroupMemberOptions, options ...RequestOptionFunc) ([]*BillableUserMembership, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/billable_members/%d/memberships", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var bum []*BillableUserMembership + resp, err := s.client.Do(req, &bum) + if err != nil { + return nil, resp, err + } + + return bum, resp, nil +} + +// RemoveBillableGroupMember removes a given group members that count as billable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#remove-a-billable-member-from-a-group +func (s *GroupsService) RemoveBillableGroupMember(gid any, user int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/billable_members/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// AddGroupMember adds a user to the list of group members. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#add-a-member-to-a-group-or-project +func (s *GroupMembersService) AddGroupMember(gid any, opt *AddGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gm := new(GroupMember) + resp, err := s.client.Do(req, gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, nil +} + +// ShareWithGroup shares a group with the group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#create-a-link-to-share-a-group-with-another-group +func (s *GroupMembersService) ShareWithGroup(gid any, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/share", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// DeleteShareWithGroup allows to unshare a group from a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#delete-the-link-that-shares-a-group-with-another-group +func (s *GroupMembersService) DeleteShareWithGroup(gid any, groupID int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/share/%d", PathEscape(group), groupID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// EditGroupMemberOptions represents the available EditGroupMember() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#edit-a-member-of-a-group-or-project +type EditGroupMemberOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at,omitempty"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// EditGroupMember updates a member of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#edit-a-member-of-a-group-or-project +func (s *GroupMembersService) EditGroupMember(gid any, user int, opt *EditGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/members/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + gm := new(GroupMember) + resp, err := s.client.Do(req, gm) + if err != nil { + return nil, resp, err + } + + return gm, resp, nil +} + +// RemoveGroupMemberOptions represents the available options to remove a group member. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#remove-a-member-from-a-group-or-project +type RemoveGroupMemberOptions struct { + SkipSubresources *bool `url:"skip_subresources,omitempty" json:"skip_subresources,omitempty"` + UnassignIssuables *bool `url:"unassign_issuables,omitempty" json:"unassign_issuables,omitempty"` +} + +// RemoveGroupMember removes user from user team. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#remove-a-member-from-a-group-or-project +func (s *GroupMembersService) RemoveGroupMember(gid any, user int, opt *RemoveGroupMemberOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/members/%d", PathEscape(group), user) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_milestones.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_milestones.go new file mode 100644 index 000000000..e9fc97aa8 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_milestones.go @@ -0,0 +1,339 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + GroupMilestonesServiceInterface interface { + ListGroupMilestones(gid any, opt *ListGroupMilestonesOptions, options ...RequestOptionFunc) ([]*GroupMilestone, *Response, error) + GetGroupMilestone(gid any, milestone int, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) + CreateGroupMilestone(gid any, opt *CreateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) + UpdateGroupMilestone(gid any, milestone int, opt *UpdateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) + DeleteGroupMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Response, error) + GetGroupMilestoneIssues(gid any, milestone int, opt *GetGroupMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + GetGroupMilestoneMergeRequests(gid any, milestone int, opt *GetGroupMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + GetGroupMilestoneBurndownChartEvents(gid any, milestone int, opt *GetGroupMilestoneBurndownChartEventsOptions, options ...RequestOptionFunc) ([]*BurndownChartEvent, *Response, error) + } + + // GroupMilestonesService handles communication with the milestone related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_milestones/ + GroupMilestonesService struct { + client *Client + } +) + +var _ GroupMilestonesServiceInterface = (*GroupMilestonesService)(nil) + +// GroupMilestone represents a GitLab milestone. +// +// GitLab API docs: https://docs.gitlab.com/api/group_milestones/ +type GroupMilestone struct { + ID int `json:"id"` + IID int `json:"iid"` + GroupID int `json:"group_id"` + Title string `json:"title"` + Description string `json:"description"` + StartDate *ISOTime `json:"start_date"` + DueDate *ISOTime `json:"due_date"` + State string `json:"state"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + Expired *bool `json:"expired"` +} + +func (m GroupMilestone) String() string { + return Stringify(m) +} + +// ListGroupMilestonesOptions represents the available +// ListGroupMilestones() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#list-group-milestones +type ListGroupMilestonesOptions struct { + ListOptions + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + SearchTitle *string `url:"search_title,omitempty" json:"search_title,omitempty"` + IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"` + IncludeDescendents *bool `url:"include_descendents,omitempty" json:"include_descendents,omitempty"` + UpdatedBefore *ISOTime `url:"updated_before,omitempty" json:"updated_before,omitempty"` + UpdatedAfter *ISOTime `url:"updated_after,omitempty" json:"updated_after,omitempty"` + ContainingDate *ISOTime `url:"containing_date,omitempty" json:"containing_date,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` + EndDate *ISOTime `url:"end_date,omitempty" json:"end_date,omitempty"` + + // Deprecated: in GitLab 16.7, use IncludeAncestors instead + IncludeParentMilestones *bool `url:"include_parent_milestones,omitempty" json:"include_parent_milestones,omitempty"` +} + +// ListGroupMilestones returns a list of group milestones. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#list-group-milestones +func (s *GroupMilestonesService) ListGroupMilestones(gid any, opt *ListGroupMilestonesOptions, options ...RequestOptionFunc) ([]*GroupMilestone, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*GroupMilestone + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// GetGroupMilestone gets a single group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-single-milestone +func (s *GroupMilestonesService) GetGroupMilestone(gid any, milestone int, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d", PathEscape(group), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(GroupMilestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateGroupMilestoneOptions represents the available CreateGroupMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#create-new-milestone +type CreateGroupMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` +} + +// CreateGroupMilestone creates a new group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#create-new-milestone +func (s *GroupMilestonesService) CreateGroupMilestone(gid any, opt *CreateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(GroupMilestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// UpdateGroupMilestoneOptions represents the available UpdateGroupMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#edit-milestone +type UpdateGroupMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` +} + +// UpdateGroupMilestone updates an existing group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#edit-milestone +func (s *GroupMilestonesService) UpdateGroupMilestone(gid any, milestone int, opt *UpdateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d", PathEscape(group), milestone) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(GroupMilestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteGroupMilestone deletes a specified group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#delete-group-milestone +func (s *GroupMilestonesService) DeleteGroupMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + return s.client.Do(req, nil) +} + +// GetGroupMilestoneIssuesOptions represents the available GetGroupMilestoneIssues() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-issues-assigned-to-a-single-milestone +type GetGroupMilestoneIssuesOptions ListOptions + +// GetGroupMilestoneIssues gets all issues assigned to a single group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-issues-assigned-to-a-single-milestone +func (s *GroupMilestonesService) GetGroupMilestoneIssues(gid any, milestone int, opt *GetGroupMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d/issues", PathEscape(group), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// GetGroupMilestoneMergeRequestsOptions represents the available +// GetGroupMilestoneMergeRequests() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-merge-requests-assigned-to-a-single-milestone +type GetGroupMilestoneMergeRequestsOptions ListOptions + +// GetGroupMilestoneMergeRequests gets all merge requests assigned to a +// single group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-merge-requests-assigned-to-a-single-milestone +func (s *GroupMilestonesService) GetGroupMilestoneMergeRequests(gid any, milestone int, opt *GetGroupMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d/merge_requests", PathEscape(group), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mr []*BasicMergeRequest + resp, err := s.client.Do(req, &mr) + if err != nil { + return nil, resp, err + } + + return mr, resp, nil +} + +// BurndownChartEvent reprensents a burnout chart event +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-burndown-chart-events-for-a-single-milestone +type BurndownChartEvent struct { + CreatedAt *time.Time `json:"created_at"` + Weight *int `json:"weight"` + Action *string `json:"action"` +} + +// GetGroupMilestoneBurndownChartEventsOptions represents the available +// GetGroupMilestoneBurndownChartEventsOptions() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-burndown-chart-events-for-a-single-milestone +type GetGroupMilestoneBurndownChartEventsOptions ListOptions + +// GetGroupMilestoneBurndownChartEvents gets all merge requests assigned to a +// single group milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_milestones/#get-all-burndown-chart-events-for-a-single-milestone +func (s *GroupMilestonesService) GetGroupMilestoneBurndownChartEvents(gid any, milestone int, opt *GetGroupMilestoneBurndownChartEventsOptions, options ...RequestOptionFunc) ([]*BurndownChartEvent, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/milestones/%d/burndown_events", PathEscape(group), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var be []*BurndownChartEvent + resp, err := s.client.Do(req, &be) + if err != nil { + return nil, resp, err + } + + return be, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_protected_environments.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_protected_environments.go new file mode 100644 index 000000000..aea180371 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_protected_environments.go @@ -0,0 +1,293 @@ +// +// Copyright 2023, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupProtectedEnvironmentsServiceInterface interface { + ListGroupProtectedEnvironments(gid any, opt *ListGroupProtectedEnvironmentsOptions, options ...RequestOptionFunc) ([]*GroupProtectedEnvironment, *Response, error) + GetGroupProtectedEnvironment(gid any, environment string, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) + ProtectGroupEnvironment(gid any, opt *ProtectGroupEnvironmentOptions, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) + UpdateGroupProtectedEnvironment(gid any, environment string, opt *UpdateGroupProtectedEnvironmentOptions, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) + UnprotectGroupEnvironment(gid any, environment string, options ...RequestOptionFunc) (*Response, error) + } + + // GroupProtectedEnvironmentsService handles communication with the group-level + // protected environment methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_protected_environments/ + GroupProtectedEnvironmentsService struct { + client *Client + } +) + +var _ GroupProtectedEnvironmentsServiceInterface = (*GroupProtectedEnvironmentsService)(nil) + +// GroupProtectedEnvironment represents a group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/ +type GroupProtectedEnvironment struct { + Name string `json:"name"` + DeployAccessLevels []*GroupEnvironmentAccessDescription `json:"deploy_access_levels"` + RequiredApprovalCount int `json:"required_approval_count"` + ApprovalRules []*GroupEnvironmentApprovalRule `json:"approval_rules"` +} + +// GroupEnvironmentAccessDescription represents the access decription for a +// group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/ +type GroupEnvironmentAccessDescription struct { + ID int `json:"id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + GroupInheritanceType int `json:"group_inheritance_type"` +} + +// GroupEnvironmentApprovalRule represents the approval rules for a group-level +// protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#protect-a-single-environment +type GroupEnvironmentApprovalRule struct { + ID int `json:"id"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + RequiredApprovalCount int `json:"required_approvals"` + GroupInheritanceType int `json:"group_inheritance_type"` +} + +// ListGroupProtectedEnvironmentsOptions represents the available +// ListGroupProtectedEnvironments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#list-group-level-protected-environments +type ListGroupProtectedEnvironmentsOptions ListOptions + +// ListGroupProtectedEnvironments returns a list of protected environments from +// a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#list-group-level-protected-environments +func (s *GroupProtectedEnvironmentsService) ListGroupProtectedEnvironments(gid any, opt *ListGroupProtectedEnvironmentsOptions, options ...RequestOptionFunc) ([]*GroupProtectedEnvironment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/protected_environments", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pes []*GroupProtectedEnvironment + resp, err := s.client.Do(req, &pes) + if err != nil { + return nil, resp, err + } + + return pes, resp, nil +} + +// GetGroupProtectedEnvironment returns a single group-level protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#get-a-single-protected-environment +func (s *GroupProtectedEnvironmentsService) GetGroupProtectedEnvironment(gid any, environment string, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/protected_environments/%s", PathEscape(group), environment) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pe := new(GroupProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// ProtectGroupEnvironmentOptions represents the available +// ProtectGroupEnvironment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#protect-a-single-environment +type ProtectGroupEnvironmentOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + DeployAccessLevels *[]*GroupEnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` + RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + ApprovalRules *[]*GroupEnvironmentApprovalRuleOptions `url:"approval_rules,omitempty" json:"approval_rules,omitempty"` +} + +// GroupEnvironmentAccessOptions represents the options for an access decription +// for a group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#protect-a-single-environment +type GroupEnvironmentAccessOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` +} + +// GroupEnvironmentApprovalRuleOptions represents the approval rules for a +// group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#protect-a-single-environment +type GroupEnvironmentApprovalRuleOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + AccessLevelDescription *string `url:"access_level_description,omitempty" json:"access_level_description,omitempty"` + RequiredApprovalCount *int `url:"required_approvals,omitempty" json:"required_approvals,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` +} + +// ProtectGroupEnvironment protects a single group-level environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#protect-a-single-environment +func (s *GroupProtectedEnvironmentsService) ProtectGroupEnvironment(gid any, opt *ProtectGroupEnvironmentOptions, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/protected_environments", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pe := new(GroupProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// UpdateGroupProtectedEnvironmentOptions represents the available +// UpdateGroupProtectedEnvironment() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#update-a-protected-environment +type UpdateGroupProtectedEnvironmentOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + DeployAccessLevels *[]*UpdateGroupEnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` + RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + ApprovalRules *[]*UpdateGroupEnvironmentApprovalRuleOptions `url:"approval_rules,omitempty" json:"approval_rules,omitempty"` +} + +// UpdateGroupEnvironmentAccessOptions represents the options for updates to the +// access decription for a group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#update-a-protected-environment +type UpdateGroupEnvironmentAccessOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ID *int `url:"id,omitempty" json:"id,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` + Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` +} + +// UpdateGroupEnvironmentApprovalRuleOptions represents the updates to the +// approval rules for a group-level protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#update-a-protected-environment +type UpdateGroupEnvironmentApprovalRuleOptions struct { + ID *int `url:"id,omitempty" json:"id,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + AccessLevelDescription *string `url:"access_level_description,omitempty" json:"access_level_description,omitempty"` + RequiredApprovalCount *int `url:"required_approvals,omitempty" json:"required_approvals,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` + Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` +} + +// UpdateGroupProtectedEnvironment updates a single group-level protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#update-a-protected-environment +func (s *GroupProtectedEnvironmentsService) UpdateGroupProtectedEnvironment(gid any, environment string, opt *UpdateGroupProtectedEnvironmentOptions, options ...RequestOptionFunc) (*GroupProtectedEnvironment, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/protected_environments/%s", PathEscape(group), environment) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pe := new(GroupProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// UnprotectGroupEnvironment unprotects the given protected group-level +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_protected_environments/#unprotect-a-single-environment +func (s *GroupProtectedEnvironmentsService) UnprotectGroupEnvironment(gid any, environment string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/protected_environments/%s", PathEscape(group), environment) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_releases.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_releases.go new file mode 100644 index 000000000..da52ce9e2 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_releases.go @@ -0,0 +1,69 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupReleasesServiceInterface interface { + ListGroupReleases(gid any, opts *ListGroupReleasesOptions, options ...RequestOptionFunc) ([]*Release, *Response, error) + } + + // GroupReleasesService handles communication with the group + // releases related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_releases.html + GroupReleasesService struct { + client *Client + } +) + +var _ GroupReleasesServiceInterface = (*GroupReleasesService)(nil) + +// ListGroupReleasesOptions represents the available ListGroupReleases() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_releases.html#list-group-releases +type ListGroupReleasesOptions struct { + ListOptions + Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` +} + +// ListGroupReleases gets a list of releases for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_releases.html#list-group-releases +func (s *GroupReleasesService) ListGroupReleases(gid any, opts *ListGroupReleasesOptions, options ...RequestOptionFunc) ([]*Release, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/releases", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var releases []*Release + resp, err := s.client.Do(req, &releases) + if err != nil { + return nil, resp, err + } + return releases, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_repository_storage_move.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_repository_storage_move.go new file mode 100644 index 000000000..01996cd09 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_repository_storage_move.go @@ -0,0 +1,206 @@ +// +// Copyright 2023, Nick Westbury +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + GroupRepositoryStorageMoveServiceInterface interface { + RetrieveAllStorageMoves(opts RetrieveAllGroupStorageMovesOptions, options ...RequestOptionFunc) ([]*GroupRepositoryStorageMove, *Response, error) + RetrieveAllStorageMovesForGroup(group int, opts RetrieveAllGroupStorageMovesOptions, options ...RequestOptionFunc) ([]*GroupRepositoryStorageMove, *Response, error) + GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) + GetStorageMoveForGroup(group int, repositoryStorage int, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) + ScheduleStorageMoveForGroup(group int, opts ScheduleStorageMoveForGroupOptions, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) + ScheduleAllStorageMoves(opts ScheduleAllGroupStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) + } + + // GroupRepositoryStorageMoveService handles communication with the + // group repositories related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_repository_storage_moves/ + GroupRepositoryStorageMoveService struct { + client *Client + } +) + +// GroupRepositoryStorageMove represents the status of a repository move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/ +type GroupRepositoryStorageMove struct { + ID int `json:"id"` + CreatedAt *time.Time `json:"created_at"` + State string `json:"state"` + SourceStorageName string `json:"source_storage_name"` + DestinationStorageName string `json:"destination_storage_name"` + Group *RepositoryGroup `json:"group"` +} + +type RepositoryGroup struct { + ID int `json:"id"` + Name string `json:"name"` + WebURL string `json:"web_url"` +} + +// RetrieveAllGroupStorageMovesOptions represents the available +// RetrieveAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#retrieve-all-group-repository-storage-moves +type RetrieveAllGroupStorageMovesOptions ListOptions + +// RetrieveAllStorageMoves retrieves all group repository storage moves +// accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#retrieve-all-group-repository-storage-moves +func (g GroupRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllGroupStorageMovesOptions, options ...RequestOptionFunc) ([]*GroupRepositoryStorageMove, *Response, error) { + req, err := g.client.NewRequest(http.MethodGet, "group_repository_storage_moves", opts, options) + if err != nil { + return nil, nil, err + } + + var gsms []*GroupRepositoryStorageMove + resp, err := g.client.Do(req, &gsms) + if err != nil { + return nil, resp, err + } + + return gsms, resp, err +} + +// RetrieveAllStorageMovesForGroup retrieves all repository storage moves for +// a single group accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#retrieve-all-repository-storage-moves-for-a-single-group +func (g GroupRepositoryStorageMoveService) RetrieveAllStorageMovesForGroup(group int, opts RetrieveAllGroupStorageMovesOptions, options ...RequestOptionFunc) ([]*GroupRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("groups/%d/repository_storage_moves", group) + + req, err := g.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var gsms []*GroupRepositoryStorageMove + resp, err := g.client.Do(req, &gsms) + if err != nil { + return nil, resp, err + } + + return gsms, resp, err +} + +// GetStorageMove gets a single group repository storage move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#get-a-single-group-repository-storage-move +func (g GroupRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("group_repository_storage_moves/%d", repositoryStorage) + + req, err := g.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gsm := new(GroupRepositoryStorageMove) + resp, err := g.client.Do(req, gsm) + if err != nil { + return nil, resp, err + } + + return gsm, resp, err +} + +// GetStorageMoveForGroup gets a single repository storage move for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#get-a-single-repository-storage-move-for-a-group +func (g GroupRepositoryStorageMoveService) GetStorageMoveForGroup(group int, repositoryStorage int, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("groups/%d/repository_storage_moves/%d", group, repositoryStorage) + + req, err := g.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gsm := new(GroupRepositoryStorageMove) + resp, err := g.client.Do(req, gsm) + if err != nil { + return nil, resp, err + } + + return gsm, resp, err +} + +// ScheduleStorageMoveForGroupOptions represents the available +// ScheduleStorageMoveForGroup() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#schedule-a-repository-storage-move-for-a-group +type ScheduleStorageMoveForGroupOptions struct { + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleStorageMoveForGroup schedule a repository to be moved for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#schedule-a-repository-storage-move-for-a-group +func (g GroupRepositoryStorageMoveService) ScheduleStorageMoveForGroup(group int, opts ScheduleStorageMoveForGroupOptions, options ...RequestOptionFunc) (*GroupRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("groups/%d/repository_storage_moves", group) + + req, err := g.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + gsm := new(GroupRepositoryStorageMove) + resp, err := g.client.Do(req, gsm) + if err != nil { + return nil, resp, err + } + + return gsm, resp, err +} + +// ScheduleAllGroupStorageMovesOptions represents the available +// ScheduleAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#schedule-repository-storage-moves-for-all-groups-on-a-storage-shard +type ScheduleAllGroupStorageMovesOptions struct { + SourceStorageName *string `url:"source_storage_name,omitempty" json:"source_storage_name,omitempty"` + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleAllStorageMoves schedules all group repositories to be moved. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_repository_storage_moves/#schedule-repository-storage-moves-for-all-groups-on-a-storage-shard +func (g GroupRepositoryStorageMoveService) ScheduleAllStorageMoves(opts ScheduleAllGroupStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := g.client.NewRequest(http.MethodPost, "group_repository_storage_moves", opts, options) + if err != nil { + return nil, err + } + + return g.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_scim.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_scim.go new file mode 100644 index 000000000..e99a266e8 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_scim.go @@ -0,0 +1,142 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupSCIMServiceInterface interface { + GetSCIMIdentitiesForGroup(gid any, options ...RequestOptionFunc) ([]*GroupSCIMIdentity, *Response, error) + GetSCIMIdentity(gid any, uid string, options ...RequestOptionFunc) (*GroupSCIMIdentity, *Response, error) + UpdateSCIMIdentity(gid any, uid string, opt *UpdateSCIMIdentityOptions, options ...RequestOptionFunc) (*Response, error) + DeleteSCIMIdentity(gid any, uid string, options ...RequestOptionFunc) (*Response, error) + } + + // GroupSCIMService handles communication with the Group SCIM + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/scim/ + GroupSCIMService struct { + client *Client + } +) + +// GroupSCIMIdentity represents a GitLab Group SCIM identity. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/ +type GroupSCIMIdentity struct { + ExternalUID string `json:"external_uid"` + UserID int64 `json:"user_id"` + Active bool `json:"active"` +} + +// GetSCIMIdentitiesForGroup gets all SCIM identities for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/#get-scim-identities-for-a-group +func (s *GroupSCIMService) GetSCIMIdentitiesForGroup(gid any, options ...RequestOptionFunc) ([]*GroupSCIMIdentity, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/scim/identities", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var identities []*GroupSCIMIdentity + resp, err := s.client.Do(req, &identities) + if err != nil { + return nil, resp, err + } + return identities, resp, nil +} + +// GetSCIMIdentity gets a SCIM identity for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/#get-a-single-scim-identity +func (s *GroupSCIMService) GetSCIMIdentity(gid any, uid string, options ...RequestOptionFunc) (*GroupSCIMIdentity, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/scim/%s", PathEscape(group), uid) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + identity := new(GroupSCIMIdentity) + resp, err := s.client.Do(req, identity) + if err != nil { + return nil, resp, err + } + return identity, resp, nil +} + +// UpdateSCIMIdentityOptions represent the request options for +// updating a SCIM Identity. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/#update-extern_uid-field-for-a-scim-identity +type UpdateSCIMIdentityOptions struct { + ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` +} + +// UpdateSCIMIdentity updates a SCIM identity. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/#update-extern_uid-field-for-a-scim-identity +func (s *GroupSCIMService) UpdateSCIMIdentity(gid any, uid string, opt *UpdateSCIMIdentityOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/scim/%s", PathEscape(group), uid) + + req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteSCIMIdentity deletes a SCIM identity. +// +// GitLab API docs: +// https://docs.gitlab.com/api/scim/#delete-a-single-scim-identity +func (s *GroupSCIMService) DeleteSCIMIdentity(gid any, uid string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/scim/%s", PathEscape(group), uid) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_security_settings.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_security_settings.go new file mode 100644 index 000000000..c93a31157 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_security_settings.go @@ -0,0 +1,90 @@ +// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + GroupSecuritySettingsServiceInterface interface { + UpdateSecretPushProtectionEnabledSetting(gid any, opt UpdateGroupSecuritySettingsOptions, options ...RequestOptionFunc) (*GroupSecuritySettings, *Response, error) + } + + // GroupSecuritySettingsService handles communication with the Group Security Settings + // related methods of the GitLab API. + // + // Gitlab API docs: + // https://docs.gitlab.com/api/group_security_settings/ + GroupSecuritySettingsService struct { + client *Client + } +) + +var _ GroupSecuritySettingsServiceInterface = (*GroupSecuritySettingsService)(nil) + +// GroupSecuritySettings represents the group security settings data. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/group_security_settings/ +type GroupSecuritySettings struct { + SecretPushProtectionEnabled bool `json:"secret_push_protection_enabled"` + Errors []string `json:"errors"` +} + +// Gets a string representation of the GroupSecuritySettings data. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_security_settings/ +func (s GroupSecuritySettings) String() string { + return Stringify(s) +} + +// GetGroupSecuritySettingsOptions represent the request options for updating +// the group security settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_security_settings/#update-secret_push_protection_enabled-setting +type UpdateGroupSecuritySettingsOptions struct { + SecretPushProtectionEnabled *bool `url:"secret_push_protection_enabled,omitempty" json:"secret_push_protection_enabled,omitempty"` + ProjectsToExclude *[]int `url:"projects_to_exclude,omitempty" json:"projects_to_exclude,omitempty"` +} + +// UpdateSecretPushProtectionEnabledSetting updates the secret_push_protection_enabled +// setting for the all projects in a group to the provided value. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/group_security_settings/#update-secret_push_protection_enabled-setting +func (s *GroupSecuritySettingsService) UpdateSecretPushProtectionEnabledSetting(gid any, opt UpdateGroupSecuritySettingsOptions, options ...RequestOptionFunc) (*GroupSecuritySettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/security_settings", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + settings := new(GroupSecuritySettings) + resp, err := s.client.Do(req, &settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_serviceaccounts.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_serviceaccounts.go new file mode 100644 index 000000000..01fba66ac --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_serviceaccounts.go @@ -0,0 +1,204 @@ +// +// Copyright 2023, James Hong +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +// GroupServiceAccount represents a GitLab service account user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#create-a-service-account-user +type GroupServiceAccount struct { + ID int `json:"id"` + Name string `json:"name"` + UserName string `json:"username"` +} + +// ListServiceAccountsOptions represents the available ListServiceAccounts() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#list-all-service-account-users +type ListServiceAccountsOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListServiceAccounts gets a list of service acxcounts. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#list-all-service-account-users +func (s *GroupsService) ListServiceAccounts(gid any, opt *ListServiceAccountsOptions, options ...RequestOptionFunc) ([]*GroupServiceAccount, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/service_accounts", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var sa []*GroupServiceAccount + resp, err := s.client.Do(req, &sa) + if err != nil { + return nil, resp, err + } + + return sa, resp, nil +} + +// CreateServiceAccountOptions represents the available CreateServiceAccount() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#create-a-service-account-user +type CreateServiceAccountOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` +} + +// Creates a service account user. +// +// This API endpoint works on top-level groups only. It does not work on subgroups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#create-a-service-account-user +func (s *GroupsService) CreateServiceAccount(gid any, opt *CreateServiceAccountOptions, options ...RequestOptionFunc) (*GroupServiceAccount, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/service_accounts", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + sa := new(GroupServiceAccount) + resp, err := s.client.Do(req, sa) + if err != nil { + return nil, resp, err + } + + return sa, resp, nil +} + +// DeleteServiceAccountOptions represents the available DeleteServiceAccount() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#delete-a-service-account-user +type DeleteServiceAccountOptions struct { + HardDelete *bool `url:"hard_delete,omitempty" json:"hard_delete,omitempty"` +} + +// DeleteServiceAccount Deletes a service account user. +// +// This API endpoint works on top-level groups only. It does not work on subgroups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#delete-a-service-account-user +func (s *GroupsService) DeleteServiceAccount(gid any, serviceAccount int, opt *DeleteServiceAccountOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/service_accounts/%d", PathEscape(group), serviceAccount) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// CreateServiceAccountPersonalAccessTokenOptions represents the available +// CreateServiceAccountPersonalAccessToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#create-a-personal-access-token-for-a-service-account-user +type CreateServiceAccountPersonalAccessTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// CreateServiceAccountPersonalAccessToken add a new Personal Access Token for a +// service account user for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#create-a-personal-access-token-for-a-service-account-user +func (s *GroupsService) CreateServiceAccountPersonalAccessToken(gid any, serviceAccount int, opt *CreateServiceAccountPersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/service_accounts/%d/personal_access_tokens", PathEscape(group), serviceAccount) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotateServiceAccountPersonalAccessTokenOptions represents the available RotateServiceAccountPersonalAccessToken() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#rotate-a-personal-access-token-for-a-service-account-user +type RotateServiceAccountPersonalAccessTokenOptions struct { + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// RotateServiceAccountPersonalAccessToken rotates a Personal Access Token for a +// service account user for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_service_accounts/#rotate-a-personal-access-token-for-a-service-account-user +func (s *GroupsService) RotateServiceAccountPersonalAccessToken(gid any, serviceAccount, token int, opt *RotateServiceAccountPersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/service_accounts/%d/personal_access_tokens/%d/rotate", PathEscape(group), serviceAccount, token) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_ssh_certificates.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_ssh_certificates.go new file mode 100644 index 000000000..27f9dddbd --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_ssh_certificates.go @@ -0,0 +1,116 @@ +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // GroupSSHCertificatesServiceInterface defines methods for the GroupSSHCertificatesService. + GroupSSHCertificatesServiceInterface interface { + ListGroupSSHCertificates(gid any, options ...RequestOptionFunc) ([]*GroupSSHCertificate, *Response, error) + CreateGroupSSHCertificate(gid any, opt *CreateGroupSSHCertificateOptions, options ...RequestOptionFunc) (*GroupSSHCertificate, *Response, error) + DeleteGroupSSHCertificate(gid any, cert int, options ...RequestOptionFunc) (*Response, error) + } + + // GroupSSHCertificatesService handles communication with the group + // SSH certificate related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_ssh_certificates/ + GroupSSHCertificatesService struct { + client *Client + } +) + +var _ GroupSSHCertificatesServiceInterface = (*GroupSSHCertificatesService)(nil) + +// GroupSSHCertificate represents a GitLab Group SSH certificate. +// +// GitLab API docs: https://docs.gitlab.com/api/group_ssh_certificates/ +type GroupSSHCertificate struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + CreatedAt *time.Time `json:"created_at"` +} + +// ListGroupSSHCertificates gets a list of SSH certificates for a specified +// group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/group_ssh_certificates/#get-all-ssh-certificates-for-a-particular-group +func (s *GroupSSHCertificatesService) ListGroupSSHCertificates(gid any, options ...RequestOptionFunc) ([]*GroupSSHCertificate, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/ssh_certificates", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var certs []*GroupSSHCertificate + resp, err := s.client.Do(req, &certs) + if err != nil { + return nil, resp, err + } + + return certs, resp, nil +} + +// CreateGroupSSHCertificateOptions represents the available +// CreateGroupSSHCertificate() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ssh_certificates/#create-ssh-certificate +type CreateGroupSSHCertificateOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` +} + +// CreateMemberRole creates a new member role for a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/group_ssh_certificates/#create-ssh-certificate +func (s *GroupSSHCertificatesService) CreateGroupSSHCertificate(gid any, opt *CreateGroupSSHCertificateOptions, options ...RequestOptionFunc) (*GroupSSHCertificate, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/ssh_certificates", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + cert := new(GroupSSHCertificate) + resp, err := s.client.Do(req, cert) + if err != nil { + return nil, resp, err + } + + return cert, resp, nil +} + +// DeleteGroupSSHCertificate deletes a SSH certificate from a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/group_ssh_certificates/#delete-group-ssh-certificate +func (s *GroupSSHCertificatesService) DeleteGroupSSHCertificate(gid any, cert int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/ssh_certificates/%d", PathEscape(group), cert) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_variables.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_variables.go new file mode 100644 index 000000000..ae643a264 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_variables.go @@ -0,0 +1,243 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + // GroupVariablesServiceInterface defines methods for the GroupVariablesService. + GroupVariablesServiceInterface interface { + ListVariables(gid any, opt *ListGroupVariablesOptions, options ...RequestOptionFunc) ([]*GroupVariable, *Response, error) + GetVariable(gid any, key string, opt *GetGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) + CreateVariable(gid any, opt *CreateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) + UpdateVariable(gid any, key string, opt *UpdateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) + RemoveVariable(gid any, key string, opt *RemoveGroupVariableOptions, options ...RequestOptionFunc) (*Response, error) + } + + // GroupVariablesService handles communication with the + // group variables related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/group_level_variables/ + GroupVariablesService struct { + client *Client + } +) + +var _ GroupVariablesServiceInterface = (*GroupVariablesService)(nil) + +// GroupVariable represents a GitLab group Variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/ +type GroupVariable struct { + Key string `json:"key"` + Value string `json:"value"` + VariableType VariableTypeValue `json:"variable_type"` + Protected bool `json:"protected"` + Masked bool `json:"masked"` + Hidden bool `json:"hidden"` + Raw bool `json:"raw"` + EnvironmentScope string `json:"environment_scope"` + Description string `json:"description"` +} + +func (v GroupVariable) String() string { + return Stringify(v) +} + +// ListGroupVariablesOptions represents the available options for listing variables +// for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#list-group-variables +type ListGroupVariablesOptions ListOptions + +// ListVariables gets a list of all variables for a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#list-group-variables +func (s *GroupVariablesService) ListVariables(gid any, opt *ListGroupVariablesOptions, options ...RequestOptionFunc) ([]*GroupVariable, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/variables", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var vs []*GroupVariable + resp, err := s.client.Do(req, &vs) + if err != nil { + return nil, resp, err + } + + return vs, resp, nil +} + +// GetGroupVariableOptions represents the available GetVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#show-variable-details +type GetGroupVariableOptions struct { + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` +} + +// GetVariable gets a variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#show-variable-details +func (s *GroupVariablesService) GetVariable(gid any, key string, opt *GetGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/variables/%s", PathEscape(group), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(GroupVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// CreateGroupVariableOptions represents the available CreateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#create-variable +type CreateGroupVariableOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Value *string `url:"value,omitempty" json:"value,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` + Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + MaskedAndHidden *bool `url:"masked_and_hidden,omitempty" json:"masked_and_hidden,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// CreateVariable creates a new group variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#create-variable +func (s *GroupVariablesService) CreateVariable(gid any, opt *CreateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/variables", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(GroupVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// UpdateGroupVariableOptions represents the available UpdateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#update-variable +type UpdateGroupVariableOptions struct { + Value *string `url:"value,omitempty" json:"value,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` + Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// UpdateVariable updates the position of an existing +// group issue board list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#update-variable +func (s *GroupVariablesService) UpdateVariable(gid any, key string, opt *UpdateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/variables/%s", PathEscape(group), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(GroupVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// RemoveGroupVariableOptions represents the available RemoveVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#remove-variable +type RemoveGroupVariableOptions struct { + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` +} + +// RemoveVariable removes a group's variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_level_variables/#remove-variable +func (s *GroupVariablesService) RemoveVariable(gid any, key string, opt *RemoveGroupVariableOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/variables/%s", PathEscape(group), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/group_wikis.go b/vendor/gitlab.com/gitlab-org/api/client-go/group_wikis.go new file mode 100644 index 000000000..b04fd9983 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/group_wikis.go @@ -0,0 +1,217 @@ +// +// Copyright 2021, Markus Lackner +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + // GroupWikisServiceInterface defines methods for the GroupWikisService. + GroupWikisServiceInterface interface { + ListGroupWikis(gid any, opt *ListGroupWikisOptions, options ...RequestOptionFunc) ([]*GroupWiki, *Response, error) + GetGroupWikiPage(gid any, slug string, opt *GetGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) + CreateGroupWikiPage(gid any, opt *CreateGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) + EditGroupWikiPage(gid any, slug string, opt *EditGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) + DeleteGroupWikiPage(gid any, slug string, options ...RequestOptionFunc) (*Response, error) + } + + // GroupWikisService handles communication with the group wikis related methods of + // the Gitlab API. + // + // GitLab API docs: https://docs.gitlab.com/api/group_wikis/ + GroupWikisService struct { + client *Client + } +) + +var _ GroupWikisServiceInterface = (*GroupWikisService)(nil) + +// GroupWiki represents a GitLab groups wiki. +// +// GitLab API docs: https://docs.gitlab.com/api/group_wikis/ +type GroupWiki struct { + Content string `json:"content"` + Encoding string `json:"encoding"` + Format WikiFormatValue `json:"format"` + Slug string `json:"slug"` + Title string `json:"title"` +} + +func (w GroupWiki) String() string { + return Stringify(w) +} + +// ListGroupWikisOptions represents the available ListGroupWikis options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#list-wiki-pages +type ListGroupWikisOptions struct { + WithContent *bool `url:"with_content,omitempty" json:"with_content,omitempty"` +} + +// ListGroupWikis lists all pages of the wiki of the given group id. +// When with_content is set, it also returns the content of the pages. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#list-wiki-pages +func (s *GroupWikisService) ListGroupWikis(gid any, opt *ListGroupWikisOptions, options ...RequestOptionFunc) ([]*GroupWiki, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/wikis", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gws []*GroupWiki + resp, err := s.client.Do(req, &gws) + if err != nil { + return nil, resp, err + } + + return gws, resp, nil +} + +// GetGroupWikiPageOptions represents options to GetGroupWikiPage +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#get-a-wiki-page +type GetGroupWikiPageOptions struct { + RenderHTML *bool `url:"render_html,omitempty" json:"render_html,omitempty"` + Version *string `url:"version,omitempty" json:"version,omitempty"` +} + +// GetGroupWikiPage gets a wiki page for a given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#get-a-wiki-page +func (s *GroupWikisService) GetGroupWikiPage(gid any, slug string, opt *GetGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/wikis/%s", PathEscape(group), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + gw := new(GroupWiki) + resp, err := s.client.Do(req, gw) + if err != nil { + return nil, resp, err + } + + return gw, resp, nil +} + +// CreateGroupWikiPageOptions represents options to CreateGroupWikiPage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#create-a-new-wiki-page +type CreateGroupWikiPageOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"` +} + +// CreateGroupWikiPage creates a new wiki page for the given group with +// the given title, slug, and content. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#create-a-new-wiki-page +func (s *GroupWikisService) CreateGroupWikiPage(gid any, opt *CreateGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/wikis", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + w := new(GroupWiki) + resp, err := s.client.Do(req, w) + if err != nil { + return nil, resp, err + } + + return w, resp, nil +} + +// EditGroupWikiPageOptions represents options to EditGroupWikiPage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#edit-an-existing-wiki-page +type EditGroupWikiPageOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"` +} + +// EditGroupWikiPage Updates an existing wiki page. At least one parameter is +// required to update the wiki page. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#edit-an-existing-wiki-page +func (s *GroupWikisService) EditGroupWikiPage(gid any, slug string, opt *EditGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/wikis/%s", PathEscape(group), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + w := new(GroupWiki) + resp, err := s.client.Do(req, w) + if err != nil { + return nil, resp, err + } + + return w, resp, nil +} + +// DeleteGroupWikiPage deletes a wiki page with a given slug. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_wikis/#delete-a-wiki-page +func (s *GroupWikisService) DeleteGroupWikiPage(gid any, slug string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/wikis/%s", PathEscape(group), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/groups.go b/vendor/gitlab.com/gitlab-org/api/client-go/groups.go new file mode 100644 index 000000000..a6f773e60 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/groups.go @@ -0,0 +1,1313 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + retryablehttp "github.com/hashicorp/go-retryablehttp" +) + +type ( + GroupsServiceInterface interface { + ListGroups(opt *ListGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) + ListSubGroups(gid any, opt *ListSubGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) + ListDescendantGroups(gid any, opt *ListDescendantGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) + ListGroupProjects(gid any, opt *ListGroupProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + GetGroup(gid any, opt *GetGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + DownloadAvatar(gid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + CreateGroup(opt *CreateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + TransferGroup(gid any, pid any, options ...RequestOptionFunc) (*Group, *Response, error) + TransferSubGroup(gid any, opt *TransferSubGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + UpdateGroup(gid any, opt *UpdateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + UploadAvatar(gid any, avatar io.Reader, filename string, options ...RequestOptionFunc) (*Group, *Response, error) + DeleteGroup(gid any, opt *DeleteGroupOptions, options ...RequestOptionFunc) (*Response, error) + RestoreGroup(gid any, options ...RequestOptionFunc) (*Group, *Response, error) + SearchGroup(query string, options ...RequestOptionFunc) ([]*Group, *Response, error) + ListProvisionedUsers(gid any, opt *ListProvisionedUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + ListGroupLDAPLinks(gid any, options ...RequestOptionFunc) ([]*LDAPGroupLink, *Response, error) + AddGroupLDAPLink(gid any, opt *AddGroupLDAPLinkOptions, options ...RequestOptionFunc) (*LDAPGroupLink, *Response, error) + DeleteGroupLDAPLink(gid any, cn string, options ...RequestOptionFunc) (*Response, error) + DeleteGroupLDAPLinkWithCNOrFilter(gid any, opts *DeleteGroupLDAPLinkWithCNOrFilterOptions, options ...RequestOptionFunc) (*Response, error) + DeleteGroupLDAPLinkForProvider(gid any, provider, cn string, options ...RequestOptionFunc) (*Response, error) + ListGroupSAMLLinks(gid any, options ...RequestOptionFunc) ([]*SAMLGroupLink, *Response, error) + ListGroupSharedProjects(gid any, opt *ListGroupSharedProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + GetGroupSAMLLink(gid any, samlGroupName string, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) + AddGroupSAMLLink(gid any, opt *AddGroupSAMLLinkOptions, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) + DeleteGroupSAMLLink(gid any, samlGroupName string, options ...RequestOptionFunc) (*Response, error) + ShareGroupWithGroup(gid any, opt *ShareGroupWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) + UnshareGroupFromGroup(gid any, groupID int, options ...RequestOptionFunc) (*Response, error) + GetGroupPushRules(gid any, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) + AddGroupPushRule(gid any, opt *AddGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) + EditGroupPushRule(gid any, opt *EditGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) + DeleteGroupPushRule(gid any, options ...RequestOptionFunc) (*Response, error) + + // group_hooks.go + ListGroupHooks(gid any, opt *ListGroupHooksOptions, options ...RequestOptionFunc) ([]*GroupHook, *Response, error) + GetGroupHook(gid any, hook int, options ...RequestOptionFunc) (*GroupHook, *Response, error) + ResendGroupHookEvent(gid any, hook int, hookEventID int, options ...RequestOptionFunc) (*Response, error) + AddGroupHook(gid any, opt *AddGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) + EditGroupHook(gid any, hook int, opt *EditGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) + DeleteGroupHook(gid any, hook int, options ...RequestOptionFunc) (*Response, error) + TriggerTestGroupHook(pid any, hook int, trigger GroupHookTrigger, options ...RequestOptionFunc) (*Response, error) + SetGroupCustomHeader(gid any, hook int, key string, opt *SetHookCustomHeaderOptions, options ...RequestOptionFunc) (*Response, error) + DeleteGroupCustomHeader(gid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) + SetGroupHookURLVariable(gid any, hook int, key string, opt *SetHookURLVariableOptions, options ...RequestOptionFunc) (*Response, error) + DeleteGroupHookURLVariable(gid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) + + // group_serviceaccounts.go + ListServiceAccounts(gid any, opt *ListServiceAccountsOptions, options ...RequestOptionFunc) ([]*GroupServiceAccount, *Response, error) + CreateServiceAccount(gid any, opt *CreateServiceAccountOptions, options ...RequestOptionFunc) (*GroupServiceAccount, *Response, error) + DeleteServiceAccount(gid any, serviceAccount int, opt *DeleteServiceAccountOptions, options ...RequestOptionFunc) (*Response, error) + CreateServiceAccountPersonalAccessToken(gid any, serviceAccount int, opt *CreateServiceAccountPersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + RotateServiceAccountPersonalAccessToken(gid any, serviceAccount, token int, opt *RotateServiceAccountPersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + + // group_members.go + ListGroupMembers(gid any, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) + ListAllGroupMembers(gid any, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) + ListBillableGroupMembers(gid any, opt *ListBillableGroupMembersOptions, options ...RequestOptionFunc) ([]*BillableGroupMember, *Response, error) + ListMembershipsForBillableGroupMember(gid any, user int, opt *ListMembershipsForBillableGroupMemberOptions, options ...RequestOptionFunc) ([]*BillableUserMembership, *Response, error) + RemoveBillableGroupMember(gid any, user int, options ...RequestOptionFunc) (*Response, error) + } + + // GroupsService handles communication with the group related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/groups/ + GroupsService struct { + client *Client + } +) + +var _ GroupsServiceInterface = (*GroupsService)(nil) + +// Group represents a GitLab group. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type Group struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Description string `json:"description"` + MembershipLock bool `json:"membership_lock"` + Visibility VisibilityValue `json:"visibility"` + LFSEnabled bool `json:"lfs_enabled"` + DefaultBranch string `json:"default_branch"` + DefaultBranchProtectionDefaults *BranchProtectionDefaults `json:"default_branch_protection_defaults"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + RequestAccessEnabled bool `json:"request_access_enabled"` + RepositoryStorage string `json:"repository_storage"` + FullName string `json:"full_name"` + FullPath string `json:"full_path"` + FileTemplateProjectID int `json:"file_template_project_id"` + ParentID int `json:"parent_id"` + Statistics *Statistics `json:"statistics"` + CustomAttributes []*CustomAttribute `json:"custom_attributes"` + ShareWithGroupLock bool `json:"share_with_group_lock"` + RequireTwoFactorAuth bool `json:"require_two_factor_authentication"` + TwoFactorGracePeriod int `json:"two_factor_grace_period"` + ProjectCreationLevel ProjectCreationLevelValue `json:"project_creation_level"` + AutoDevopsEnabled bool `json:"auto_devops_enabled"` + SubGroupCreationLevel SubGroupCreationLevelValue `json:"subgroup_creation_level"` + EmailsEnabled bool `json:"emails_enabled"` + MentionsDisabled bool `json:"mentions_disabled"` + RunnersToken string `json:"runners_token"` + SharedRunnersSetting SharedRunnersSettingValue `json:"shared_runners_setting"` + SharedWithGroups []SharedWithGroup `json:"shared_with_groups"` + LDAPCN string `json:"ldap_cn"` + LDAPAccess AccessLevelValue `json:"ldap_access"` + LDAPGroupLinks []*LDAPGroupLink `json:"ldap_group_links"` + SAMLGroupLinks []*SAMLGroupLink `json:"saml_group_links"` + SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` + ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"` + PreventForkingOutsideGroup bool `json:"prevent_forking_outside_group"` + MarkedForDeletionOn *ISOTime `json:"marked_for_deletion_on"` + CreatedAt *time.Time `json:"created_at"` + IPRestrictionRanges string `json:"ip_restriction_ranges"` + AllowedEmailDomainsList string `json:"allowed_email_domains_list"` + WikiAccessLevel AccessControlValue `json:"wiki_access_level"` + + // Deprecated: will be removed in v5 of the API, use ListGroupProjects instead + Projects []*Project `json:"projects"` + + // Deprecated: will be removed in v5 of the API, use ListGroupSharedProjects instead + SharedProjects []*Project `json:"shared_projects"` + + // Deprecated: Use EmailsEnabled instead + EmailsDisabled bool `json:"emails_disabled"` + + // Deprecated: Use DefaultBranchProtectionDefaults instead + DefaultBranchProtection int `json:"default_branch_protection"` +} + +// SharedWithGroup represents a GitLab group shared with a group. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type SharedWithGroup struct { + GroupID int `json:"group_id"` + GroupName string `json:"group_name"` + GroupFullPath string `json:"group_full_path"` + GroupAccessLevel int `json:"group_access_level"` + ExpiresAt *ISOTime `json:"expires_at"` + MemberRoleID int `json:"member_role_id"` +} + +// BranchProtectionDefaults represents default Git protected branch permissions. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-default_branch_protection_defaults +type BranchProtectionDefaults struct { + AllowedToPush []*GroupAccessLevel `json:"allowed_to_push,omitempty"` + AllowForcePush bool `json:"allow_force_push,omitempty"` + AllowedToMerge []*GroupAccessLevel `json:"allowed_to_merge,omitempty"` + DeveloperCanInitialPush bool `json:"developer_can_initial_push,omitempty"` +} + +// GroupAccessLevel represents default branch protection defaults access levels. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-default_branch_protection_defaults +type GroupAccessLevel struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// GroupAvatar represents a GitLab group avatar. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type GroupAvatar struct { + Filename string + Image io.Reader +} + +// MarshalJSON implements the json.Marshaler interface. +func (a *GroupAvatar) MarshalJSON() ([]byte, error) { + if a.Filename == "" && a.Image == nil { + return []byte(`""`), nil + } + type alias GroupAvatar + return json.Marshal((*alias)(a)) +} + +// LDAPGroupLink represents a GitLab LDAP group link. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/ +type LDAPGroupLink struct { + CN string `json:"cn"` + Filter string `json:"filter"` + GroupAccess AccessLevelValue `json:"group_access"` + Provider string `json:"provider"` + MemberRoleID int64 `json:"member_role_id"` +} + +// SAMLGroupLink represents a GitLab SAML group link. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#saml-group-links +type SAMLGroupLink struct { + Name string `json:"name"` + AccessLevel AccessLevelValue `json:"access_level"` + MemberRoleID int `json:"member_role_id,omitempty"` +} + +// ListGroupsOptions represents the available ListGroups() options. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#list-groups +type ListGroupsOptions struct { + ListOptions + SkipGroups *[]int `url:"skip_groups,omitempty" del:"," json:"skip_groups,omitempty"` + AllAvailable *bool `url:"all_available,omitempty" json:"all_available,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` + MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` + TopLevelOnly *bool `url:"top_level_only,omitempty" json:"top_level_only,omitempty"` + RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"` +} + +// ListGroups gets a list of groups (as user: my groups, as admin: all groups). +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-groups +func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "groups", opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*Group + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// ListSubGroupsOptions represents the available ListSubGroups() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-subgroups +type ListSubGroupsOptions ListGroupsOptions + +// ListSubGroups gets a list of subgroups for a given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-subgroups +func (s *GroupsService) ListSubGroups(gid any, opt *ListSubGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/subgroups", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*Group + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// ListDescendantGroupsOptions represents the available ListDescendantGroups() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-descendant-groups +type ListDescendantGroupsOptions ListGroupsOptions + +// ListDescendantGroups gets a list of subgroups for a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-descendant-groups +func (s *GroupsService) ListDescendantGroups(gid any, opt *ListDescendantGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/descendant_groups", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var gs []*Group + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// ListGroupProjectsOptions represents the available ListGroup() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-projects +type ListGroupProjectsOptions struct { + ListOptions + Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` + IncludeSubGroups *bool `url:"include_subgroups,omitempty" json:"include_subgroups,omitempty"` + MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Starred *bool `url:"starred,omitempty" json:"starred,omitempty"` + Topic *string `url:"topic,omitempty" json:"topic,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"` + WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"` + WithSecurityReports *bool `url:"with_security_reports,omitempty" json:"with_security_reports,omitempty"` + WithShared *bool `url:"with_shared,omitempty" json:"with_shared,omitempty"` +} + +// ListGroupProjects get a list of group projects +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-projects +func (s *GroupsService) ListGroupProjects(gid any, opt *ListGroupProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/projects", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Project + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// GetGroupOptions represents the available GetGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#get-a-single-group +type GetGroupOptions struct { + ListOptions + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + + // Deprecated: will be removed in v5 of the API, use ListGroupProjects instead + WithProjects *bool `url:"with_projects,omitempty" json:"with_projects,omitempty"` +} + +// GetGroup gets all details of a group. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#get-a-single-group +func (s *GroupsService) GetGroup(gid any, opt *GetGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// DownloadAvatar downloads a group avatar. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#download-a-group-avatar +func (s *GroupsService) DownloadAvatar(gid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/avatar", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + avatar := new(bytes.Buffer) + resp, err := s.client.Do(req, avatar) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(avatar.Bytes()), resp, err +} + +// CreateGroupOptions represents the available CreateGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#create-a-group +type CreateGroupOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Avatar *GroupAvatar `url:"-" json:"-"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"` + RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"` + TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"` + ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"` + AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` + SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"` + EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"` + MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + DefaultBranchProtectionDefaults *DefaultBranchProtectionDefaultsOptions `url:"default_branch_protection_defaults,omitempty" json:"default_branch_protection_defaults,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` + ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` + SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"` + ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"` + WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` + + // Deprecated: Use EmailsEnabled instead + EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` + + // Deprecated: User DefaultBranchProtectionDefaults instead + DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"` +} + +// DefaultBranchProtectionDefaultsOptions represents the available options for +// using default_branch_protection_defaults in CreateGroup() or UpdateGroup() +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-default_branch_protection_defaults +type DefaultBranchProtectionDefaultsOptions struct { + AllowedToPush *[]*GroupAccessLevel `url:"allowed_to_push,omitempty" json:"allowed_to_push,omitempty"` + AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` + AllowedToMerge *[]*GroupAccessLevel `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` + DeveloperCanInitialPush *bool `url:"developer_can_initial_push,omitempty" json:"developer_can_initial_push,omitempty"` +} + +// CreateGroup creates a new project group. Available only for users who can +// create groups. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#create-a-group +func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + var err error + var req *retryablehttp.Request + + if opt.Avatar == nil { + req, err = s.client.NewRequest(http.MethodPost, "groups", opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPost, + "groups", + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// TransferGroup transfers a project to the Group namespace. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#transfer-a-project-to-a-group +func (s *GroupsService) TransferGroup(gid any, pid any, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/projects/%s", PathEscape(group), PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// TransferSubGroupOptions represents the available TransferSubGroup() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#transfer-a-group +type TransferSubGroupOptions struct { + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` +} + +// TransferSubGroup transfers a group to a new parent group or turn a subgroup +// to a top-level group. Available to administrators and users. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#transfer-a-group +func (s *GroupsService) TransferSubGroup(gid any, opt *TransferSubGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/transfer", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// UpdateGroupOptions represents the available UpdateGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#update-group-attributes +type UpdateGroupOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Avatar *GroupAvatar `url:"-" json:"avatar,omitempty"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"` + RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"` + TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"` + ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"` + AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` + SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"` + EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"` + MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` + DefaultBranchProtectionDefaults *DefaultBranchProtectionDefaultsOptions `url:"default_branch_protection_defaults,omitempty" json:"default_branch_protection_defaults,omitempty"` + FileTemplateProjectID *int `url:"file_template_project_id,omitempty" json:"file_template_project_id,omitempty"` + SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"` + ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"` + PreventForkingOutsideGroup *bool `url:"prevent_forking_outside_group,omitempty" json:"prevent_forking_outside_group,omitempty"` + SharedRunnersSetting *SharedRunnersSettingValue `url:"shared_runners_setting,omitempty" json:"shared_runners_setting,omitempty"` + PreventSharingGroupsOutsideHierarchy *bool `url:"prevent_sharing_groups_outside_hierarchy,omitempty" json:"prevent_sharing_groups_outside_hierarchy,omitempty"` + IPRestrictionRanges *string `url:"ip_restriction_ranges,omitempty" json:"ip_restriction_ranges,omitempty"` + AllowedEmailDomainsList *string `url:"allowed_email_domains_list,omitempty" json:"allowed_email_domains_list,omitempty"` + WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` + + // Deprecated: Use EmailsEnabled instead + EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` + + // Deprecated: Use DefaultBranchProtectionDefaults instead + DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"` +} + +// UpdateGroup updates an existing group; only available to group owners and +// administrators. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#update-group-attributes +func (s *GroupsService) UpdateGroup(gid any, opt *UpdateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s", PathEscape(group)) + + var req *retryablehttp.Request + + if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) { + req, err = s.client.NewRequest(http.MethodPut, u, opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPut, + u, + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// UploadAvatar uploads a group avatar. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#upload-a-group-avatar +func (s *GroupsService) UploadAvatar(gid any, avatar io.Reader, filename string, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s", PathEscape(group)) + + req, err := s.client.UploadRequest( + http.MethodPut, + u, + avatar, + filename, + UploadAvatar, + nil, + options, + ) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// DeleteGroupOptions represents the available DeleteGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#delete-a-group +type DeleteGroupOptions struct { + PermanentlyRemove *bool `url:"permanently_remove,omitempty" json:"permanently_remove,omitempty"` + FullPath *string `url:"full_path,omitempty" json:"full_path,omitempty"` +} + +// DeleteGroup removes group with all projects inside. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#delete-a-group +func (s *GroupsService) DeleteGroup(gid any, opt *DeleteGroupOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RestoreGroup restores a previously deleted group +// +// GitLap API docs: +// https://docs.gitlab.com/api/groups/#restore-a-group-marked-for-deletion +func (s *GroupsService) RestoreGroup(gid any, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/restore", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// SearchGroup get all groups that match your string in their name or path. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/#search-for-a-group +func (s *GroupsService) SearchGroup(query string, options ...RequestOptionFunc) ([]*Group, *Response, error) { + var q struct { + Search string `url:"search,omitempty" json:"search,omitempty"` + } + q.Search = query + + req, err := s.client.NewRequest(http.MethodGet, "groups", &q, options) + if err != nil { + return nil, nil, err + } + + var gs []*Group + resp, err := s.client.Do(req, &gs) + if err != nil { + return nil, resp, err + } + + return gs, resp, nil +} + +// ListProvisionedUsersOptions represents the available ListProvisionedUsers() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-provisioned-users +type ListProvisionedUsersOptions struct { + ListOptions + Username *string `url:"username,omitempty" json:"username,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` +} + +// ListProvisionedUsers gets a list of users provisioned by the given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-provisioned-users +func (s *GroupsService) ListProvisionedUsers(gid any, opt *ListProvisionedUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/provisioned_users", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var us []*User + resp, err := s.client.Do(req, &us) + if err != nil { + return nil, resp, err + } + + return us, resp, nil +} + +// ListGroupLDAPLinks lists the group's LDAP links. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#list-ldap-group-links +func (s *GroupsService) ListGroupLDAPLinks(gid any, options ...RequestOptionFunc) ([]*LDAPGroupLink, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var gls []*LDAPGroupLink + resp, err := s.client.Do(req, &gls) + if err != nil { + return nil, resp, err + } + + return gls, resp, nil +} + +// AddGroupLDAPLinkOptions represents the available AddGroupLDAPLink() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#add-an-ldap-group-link-with-cn-or-filter +type AddGroupLDAPLinkOptions struct { + CN *string `url:"cn,omitempty" json:"cn,omitempty"` + Filter *string `url:"filter,omitempty" json:"filter,omitempty"` + GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + MemberRoleID *int64 `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// AddGroupLDAPLink creates a new group LDAP link. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#add-an-ldap-group-link-with-cn-or-filter +func (s *GroupsService) AddGroupLDAPLink(gid any, opt *AddGroupLDAPLinkOptions, options ...RequestOptionFunc) (*LDAPGroupLink, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gl := new(LDAPGroupLink) + resp, err := s.client.Do(req, gl) + if err != nil { + return nil, resp, err + } + + return gl, resp, nil +} + +// DeleteGroupLDAPLink deletes a group LDAP link. Available only for users who +// can edit groups. +// Deprecated as upstream API is deprecated. Use DeleteGroupLDAPLinkWithCNOrFilter() instead. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#delete-an-ldap-group-link-deprecated +func (s *GroupsService) DeleteGroupLDAPLink(gid any, cn string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/ldap_group_links/%s", PathEscape(group), PathEscape(cn)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteGroupLDAPLinkWithCNOrFilterOptions represents the available DeleteGroupLDAPLinkWithCNOrFilter() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#delete-an-ldap-group-link-with-cn-or-filter +type DeleteGroupLDAPLinkWithCNOrFilterOptions struct { + CN *string `url:"cn,omitempty" json:"cn,omitempty"` + Filter *string `url:"filter,omitempty" json:"filter,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` +} + +// DeleteGroupLDAPLinkWithCNOrFilter deletes a group LDAP link. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#delete-an-ldap-group-link-with-cn-or-filter +func (s *GroupsService) DeleteGroupLDAPLinkWithCNOrFilter(gid any, opts *DeleteGroupLDAPLinkWithCNOrFilterOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodDelete, u, opts, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteGroupLDAPLinkForProvider deletes a group LDAP link from a specific +// provider. Available only for users who can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_ldap_links/#delete-an-ldap-group-link-deprecated +func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid any, provider, cn string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf( + "groups/%s/ldap_group_links/%s/%s", + PathEscape(group), + PathEscape(provider), + PathEscape(cn), + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGroupSAMLLinks lists the group's SAML links. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/saml/#list-saml-group-links +func (s *GroupsService) ListGroupSAMLLinks(gid any, options ...RequestOptionFunc) ([]*SAMLGroupLink, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var gl []*SAMLGroupLink + resp, err := s.client.Do(req, &gl) + if err != nil { + return nil, resp, err + } + + return gl, resp, nil +} + +// ListGroupSharedProjectsOptions represents the available ListGroupSharedProjects() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-shared-projects +type ListGroupSharedProjectsOptions struct { + ListOptions + Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` + MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Starred *bool `url:"starred,omitempty" json:"starred,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"` + WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"` +} + +// ListGroupSharedProjects gets a list of projects shared to this group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#list-shared-projects +func (s *GroupsService) ListGroupSharedProjects(gid any, opt *ListGroupSharedProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/projects/shared", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetGroupSAMLLink get a specific group SAML link. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/saml/#get-a-saml-group-link +func (s *GroupsService) GetGroupSAMLLink(gid any, samlGroupName string, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(samlGroupName)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gl := new(SAMLGroupLink) + resp, err := s.client.Do(req, &gl) + if err != nil { + return nil, resp, err + } + + return gl, resp, nil +} + +// AddGroupSAMLLinkOptions represents the available AddGroupSAMLLink() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/saml/#add-a-saml-group-link +type AddGroupSAMLLinkOptions struct { + SAMLGroupName *string `url:"saml_group_name,omitempty" json:"saml_group_name,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// AddGroupSAMLLink creates a new group SAML link. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/saml/#add-a-saml-group-link +func (s *GroupsService) AddGroupSAMLLink(gid any, opt *AddGroupSAMLLinkOptions, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gl := new(SAMLGroupLink) + resp, err := s.client.Do(req, &gl) + if err != nil { + return nil, resp, err + } + + return gl, resp, nil +} + +// DeleteGroupSAMLLink deletes a group SAML link. Available only for users who +// can edit groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/saml/#delete-a-saml-group-link +func (s *GroupsService) DeleteGroupSAMLLink(gid any, samlGroupName string, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(samlGroupName)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ShareGroupWithGroupOptions represents the available ShareGroupWithGroup() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#share-groups-with-groups +type ShareGroupWithGroupOptions struct { + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// ShareGroupWithGroup shares a group with another group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#create-a-link-to-share-a-group-with-another-group +func (s *GroupsService) ShareGroupWithGroup(gid any, opt *ShareGroupWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/share", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + g := new(Group) + resp, err := s.client.Do(req, g) + if err != nil { + return nil, resp, err + } + + return g, resp, nil +} + +// UnshareGroupFromGroup unshares a group from another group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#delete-the-link-that-shares-a-group-with-another-group +func (s *GroupsService) UnshareGroupFromGroup(gid any, groupID int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/share/%d", PathEscape(group), groupID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GroupPushRules represents a group push rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#get-the-push-rules-of-a-group +type GroupPushRules struct { + ID int `json:"id"` + CreatedAt *time.Time `json:"created_at"` + CommitMessageRegex string `json:"commit_message_regex"` + CommitMessageNegativeRegex string `json:"commit_message_negative_regex"` + BranchNameRegex string `json:"branch_name_regex"` + DenyDeleteTag bool `json:"deny_delete_tag"` + MemberCheck bool `json:"member_check"` + PreventSecrets bool `json:"prevent_secrets"` + AuthorEmailRegex string `json:"author_email_regex"` + FileNameRegex string `json:"file_name_regex"` + MaxFileSize int `json:"max_file_size"` + CommitCommitterCheck bool `json:"commit_committer_check"` + CommitCommitterNameCheck bool `json:"commit_committer_name_check"` + RejectUnsignedCommits bool `json:"reject_unsigned_commits"` + RejectNonDCOCommits bool `json:"reject_non_dco_commits"` +} + +// GetGroupPushRules gets the push rules of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#get-the-push-rules-of-a-group +func (s *GroupsService) GetGroupPushRules(gid any, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + gpr := new(GroupPushRules) + resp, err := s.client.Do(req, gpr) + if err != nil { + return nil, resp, err + } + + return gpr, resp, nil +} + +// AddGroupPushRuleOptions represents the available AddGroupPushRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#add-push-rules-to-a-group +type AddGroupPushRuleOptions struct { + AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` + BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` + CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` + CommitCommitterNameCheck *bool `url:"commit_committer_name_check,omitempty" json:"commit_committer_name_check,omitempty"` + CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` + CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` + DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` + FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` + MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` + MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` + PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` + RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` + RejectNonDCOCommits *bool `url:"reject_non_dco_commits,omitempty" json:"reject_non_dco_commits,omitempty"` +} + +// AddGroupPushRule adds push rules to the specified group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#add-push-rules-to-a-group +func (s *GroupsService) AddGroupPushRule(gid any, opt *AddGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + gpr := new(GroupPushRules) + resp, err := s.client.Do(req, gpr) + if err != nil { + return nil, resp, err + } + + return gpr, resp, nil +} + +// EditGroupPushRuleOptions represents the available EditGroupPushRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#edit-the-push-rules-of-a-group +type EditGroupPushRuleOptions struct { + AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` + BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` + CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` + CommitCommitterNameCheck *bool `url:"commit_committer_name_check,omitempty" json:"commit_committer_name_check,omitempty"` + CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` + CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` + DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` + FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` + MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` + MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` + PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` + RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` + RejectNonDCOCommits *bool `url:"reject_non_dco_commits,omitempty" json:"reject_non_dco_commits,omitempty"` +} + +// EditGroupPushRule edits a push rule for a specified group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#edit-the-push-rules-of-a-group +func (s *GroupsService) EditGroupPushRule(gid any, opt *EditGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + gpr := new(GroupPushRules) + resp, err := s.client.Do(req, gpr) + if err != nil { + return nil, resp, err + } + + return gpr, resp, nil +} + +// DeleteGroupPushRule deletes the push rules of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_push_rules/#delete-the-push-rules-of-a-group +func (s *GroupsService) DeleteGroupPushRule(gid any, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/import.go b/vendor/gitlab.com/gitlab-org/api/client-go/import.go new file mode 100644 index 000000000..693fc598c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/import.go @@ -0,0 +1,278 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "net/http" +) + +type ( + ImportServiceInterface interface { + ImportRepositoryFromGitHub(opt *ImportRepositoryFromGitHubOptions, options ...RequestOptionFunc) (*GitHubImport, *Response, error) + CancelGitHubProjectImport(opt *CancelGitHubProjectImportOptions, options ...RequestOptionFunc) (*CancelledGitHubImport, *Response, error) + ImportGitHubGistsIntoGitLabSnippets(opt *ImportGitHubGistsIntoGitLabSnippetsOptions, options ...RequestOptionFunc) (*Response, error) + ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) + ImportRepositoryFromBitbucketCloud(opt *ImportRepositoryFromBitbucketCloudOptions, options ...RequestOptionFunc) (*BitbucketCloudImport, *Response, error) + } + + // ImportService handles communication with the import + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/import/ + ImportService struct { + client *Client + } +) + +var _ ImportServiceInterface = (*ImportService)(nil) + +// GitHubImport represents the response from an import from GitHub. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-github +type GitHubImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` + ImportSource string `json:"import_source"` + ImportStatus string `json:"import_status"` + HumanImportStatusName string `json:"human_import_status_name"` + ProviderLink string `json:"provider_link"` + RelationType string `json:"relation_type"` + ImportWarning string `json:"import_warning"` +} + +func (s GitHubImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromGitHubOptions represents the available +// ImportRepositoryFromGitHub() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-github +type ImportRepositoryFromGitHubOptions struct { + PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` + RepoID *int `url:"repo_id,omitempty" json:"repo_id,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + TargetNamespace *string `url:"target_namespace,omitempty" json:"target_namespace,omitempty"` + GitHubHostname *string `url:"github_hostname,omitempty" json:"github_hostname,omitempty"` + OptionalStages struct { + SingleEndpointNotesImport *bool `url:"single_endpoint_notes_import,omitempty" json:"single_endpoint_notes_import,omitempty"` + AttachmentsImport *bool `url:"attachments_import,omitempty" json:"attachments_import,omitempty"` + CollaboratorsImport *bool `url:"collaborators_import,omitempty" json:"collaborators_import,omitempty"` + } `url:"optional_stages,omitempty" json:"optional_stages,omitempty"` + TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"` +} + +// Import a repository from GitHub. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-github +func (s *ImportService) ImportRepositoryFromGitHub(opt *ImportRepositoryFromGitHubOptions, options ...RequestOptionFunc) (*GitHubImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/github", opt, options) + if err != nil { + return nil, nil, err + } + + gi := new(GitHubImport) + resp, err := s.client.Do(req, gi) + if err != nil { + return nil, resp, err + } + + return gi, resp, nil +} + +// CancelledGitHubImport represents the response when canceling +// an import from GitHub. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#cancel-github-project-import +type CancelledGitHubImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + ImportSource string `json:"import_source"` + ImportStatus string `json:"import_status"` + HumanImportStatusName string `json:"human_import_status_name"` + ProviderLink string `json:"provider_link"` +} + +func (s CancelledGitHubImport) String() string { + return Stringify(s) +} + +// CancelGitHubProjectImportOptions represents the available +// CancelGitHubProjectImport() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#cancel-github-project-import +type CancelGitHubProjectImportOptions struct { + ProjectID *int `url:"project_id,omitempty" json:"project_id,omitempty"` +} + +// Cancel an import of a repository from GitHub. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#cancel-github-project-import +func (s *ImportService) CancelGitHubProjectImport(opt *CancelGitHubProjectImportOptions, options ...RequestOptionFunc) (*CancelledGitHubImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/github/cancel", opt, options) + if err != nil { + return nil, nil, err + } + + cgi := new(CancelledGitHubImport) + resp, err := s.client.Do(req, cgi) + if err != nil { + return nil, resp, err + } + + return cgi, resp, nil +} + +// ImportGitHubGistsIntoGitLabSnippetsOptions represents the available +// ImportGitHubGistsIntoGitLabSnippets() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-github-gists-into-gitlab-snippets +type ImportGitHubGistsIntoGitLabSnippetsOptions struct { + PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` +} + +// Import personal GitHub Gists into personal GitLab Snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-github-gists-into-gitlab-snippets +func (s *ImportService) ImportGitHubGistsIntoGitLabSnippets(opt *ImportGitHubGistsIntoGitLabSnippetsOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/github/gists", opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// BitbucketServerImport represents the response from an import from Bitbucket +// Server. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-server +type BitbucketServerImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` +} + +func (s BitbucketServerImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromBitbucketServerOptions represents the available ImportRepositoryFromBitbucketServer() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-server +type ImportRepositoryFromBitbucketServerOptions struct { + BitbucketServerUrl *string `url:"bitbucket_server_url,omitempty" json:"bitbucket_server_url,omitempty"` + BitbucketServerUsername *string `url:"bitbucket_server_username,omitempty" json:"bitbucket_server_username,omitempty"` + PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` + BitbucketServerProject *string `url:"bitbucket_server_project,omitempty" json:"bitbucket_server_project,omitempty"` + BitbucketServerRepo *string `url:"bitbucket_server_repo,omitempty" json:"bitbucket_server_repo,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + NewNamespace *string `url:"new_namespace,omitempty" json:"new_namespace,omitempty"` + TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"` +} + +// Import a repository from Bitbucket Server. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-server +func (s *ImportService) ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket_server", opt, options) + if err != nil { + return nil, nil, err + } + + bsi := new(BitbucketServerImport) + resp, err := s.client.Do(req, bsi) + if err != nil { + return nil, resp, err + } + + return bsi, resp, nil +} + +// BitbucketCloudImport represents the response from an import from Bitbucket +// Cloud. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-cloud +type BitbucketCloudImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` + ImportSource string `json:"import_source"` + ImportStatus string `json:"import_status"` + HumanImportStatusName string `json:"human_import_status_name"` + ProviderLink string `json:"provider_link"` + RelationType string `json:"relation_type"` + ImportWarning string `json:"import_warning"` +} + +func (s BitbucketCloudImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromBitbucketCloudOptions represents the available +// ImportRepositoryFromBitbucketCloud() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-cloud +type ImportRepositoryFromBitbucketCloudOptions struct { + BitbucketUsername *string `url:"bitbucket_username,omitempty" json:"bitbucket_username,omitempty"` + BitbucketAppPassword *string `url:"bitbucket_app_password,omitempty" json:"bitbucket_app_password,omitempty"` + RepoPath *string `url:"repo_path,omitempty" json:"repo_path,omitempty"` + TargetNamespace *string `url:"target_namespace,omitempty" json:"target_namespace,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` +} + +// Import a repository from Bitbucket Cloud. +// +// GitLab API docs: +// https://docs.gitlab.com/api/import/#import-repository-from-bitbucket-cloud +func (s *ImportService) ImportRepositoryFromBitbucketCloud(opt *ImportRepositoryFromBitbucketCloudOptions, options ...RequestOptionFunc) (*BitbucketCloudImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket", opt, options) + if err != nil { + return nil, nil, err + } + + bci := new(BitbucketCloudImport) + resp, err := s.client.Do(req, bci) + if err != nil { + return nil, resp, err + } + + return bci, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/instance_clusters.go b/vendor/gitlab.com/gitlab-org/api/client-go/instance_clusters.go similarity index 56% rename from vendor/github.com/xanzy/go-gitlab/instance_clusters.go rename to vendor/gitlab.com/gitlab-org/api/client-go/instance_clusters.go index e646cc89a..fd4bce6be 100644 --- a/vendor/github.com/xanzy/go-gitlab/instance_clusters.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/instance_clusters.go @@ -1,5 +1,5 @@ // -// Copyright 2020, Serena Fang +// Copyright 2021, Serena Fang // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,21 +18,43 @@ package gitlab import ( "fmt" + "net/http" "time" ) -// InstanceClustersService handles communication with the -// instance clusters related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html -type InstanceClustersService struct { - client *Client -} +type ( + // Deprecated: in GitLab 14.5, to be removed in 19.0 + InstanceClustersServiceInterface interface { + // Deprecated: in GitLab 14.5, to be removed in 19.0 + ListClusters(options ...RequestOptionFunc) ([]*InstanceCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + GetCluster(cluster int, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + AddCluster(opt *AddClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + EditCluster(cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + DeleteCluster(cluster int, options ...RequestOptionFunc) (*Response, error) + } + + // InstanceClustersService handles communication with the + // instance clusters related methods of the GitLab API. + // Deprecated: in GitLab 14.5, to be removed in 19.0 + // + // GitLab API docs: + // https://docs.gitlab.com/api/instance_clusters/ + InstanceClustersService struct { + client *Client + } +) + +// Deprecated: in GitLab 14.5, to be removed in 19.0 +var _ InstanceClustersServiceInterface = (*InstanceClustersService)(nil) // InstanceCluster represents a GitLab Instance Cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // -// GitLab API docs: https://docs.gitlab.com/ee/api/instance_clusters.html +// GitLab API docs: https://docs.gitlab.com/api/instance_clusters/ type InstanceCluster struct { ID int `json:"id"` Name string `json:"name"` @@ -48,18 +70,20 @@ type InstanceCluster struct { ManagementProject *ManagementProject `json:"management_project"` } +// Deprecated: in GitLab 14.5, to be removed in 19.0 func (v InstanceCluster) String() string { return Stringify(v) } // ListClusters gets a list of all instance clusters. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html#list-instance-clusters +// https://docs.gitlab.com/api/instance_clusters/#list-instance-clusters func (s *InstanceClustersService) ListClusters(options ...RequestOptionFunc) ([]*InstanceCluster, *Response, error) { u := "admin/clusters" - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -70,17 +94,18 @@ func (s *InstanceClustersService) ListClusters(options ...RequestOptionFunc) ([] return nil, resp, err } - return ics, resp, err + return ics, resp, nil } // GetCluster gets an instance cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html#get-a-single-instance-cluster +// https://docs.gitlab.com/api/instance_clusters/#get-a-single-instance-cluster func (s *InstanceClustersService) GetCluster(cluster int, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) { u := fmt.Sprintf("admin/clusters/%d", cluster) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -91,17 +116,18 @@ func (s *InstanceClustersService) GetCluster(cluster int, options ...RequestOpti return nil, resp, err } - return ic, resp, err + return ic, resp, nil } // AddCluster adds an existing cluster to the instance. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html#add-existing-instance-cluster +// https://docs.gitlab.com/api/instance_clusters/#add-existing-instance-cluster func (s *InstanceClustersService) AddCluster(opt *AddClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) { u := "admin/clusters/add" - req, err := s.client.NewRequest("POST", u, opt, options) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } @@ -112,17 +138,18 @@ func (s *InstanceClustersService) AddCluster(opt *AddClusterOptions, options ... return nil, resp, err } - return ic, resp, err + return ic, resp, nil } // EditCluster updates an existing instance cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html#edit-instance-cluster +// https://docs.gitlab.com/api/instance_clusters/#edit-instance-cluster func (s *InstanceClustersService) EditCluster(cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) { u := fmt.Sprintf("admin/clusters/%d", cluster) - req, err := s.client.NewRequest("PUT", u, opt, options) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } @@ -133,17 +160,18 @@ func (s *InstanceClustersService) EditCluster(cluster int, opt *EditClusterOptio return nil, resp, err } - return ic, resp, err + return ic, resp, nil } // DeleteCluster deletes an existing instance cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_clusters.html#delete-instance-cluster +// https://docs.gitlab.com/api/instance_clusters/#delete-instance-cluster func (s *InstanceClustersService) DeleteCluster(cluster int, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("admin/clusters/%d", cluster) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/github.com/xanzy/go-gitlab/instance_variables.go b/vendor/gitlab.com/gitlab-org/api/client-go/instance_variables.go similarity index 63% rename from vendor/github.com/xanzy/go-gitlab/instance_variables.go rename to vendor/gitlab.com/gitlab-org/api/client-go/instance_variables.go index 0d4006b68..235a333e3 100644 --- a/vendor/github.com/xanzy/go-gitlab/instance_variables.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/instance_variables.go @@ -1,5 +1,5 @@ // -// Copyright 2018, Patrick Webster +// Copyright 2021, Patrick Webster // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,28 +18,43 @@ package gitlab import ( "fmt" + "net/http" "net/url" ) -// InstanceVariablesService handles communication with the -// instance level CI variables related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html -type InstanceVariablesService struct { - client *Client -} +type ( + InstanceVariablesServiceInterface interface { + ListVariables(opt *ListInstanceVariablesOptions, options ...RequestOptionFunc) ([]*InstanceVariable, *Response, error) + GetVariable(key string, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) + CreateVariable(opt *CreateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) + UpdateVariable(key string, opt *UpdateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) + RemoveVariable(key string, options ...RequestOptionFunc) (*Response, error) + } + + // InstanceVariablesService handles communication with the + // instance level CI variables related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/instance_level_ci_variables/ + InstanceVariablesService struct { + client *Client + } +) + +var _ InstanceVariablesServiceInterface = (*InstanceVariablesService)(nil) // InstanceVariable represents a GitLab instance level CI Variable. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html +// https://docs.gitlab.com/api/instance_level_ci_variables/ type InstanceVariable struct { Key string `json:"key"` Value string `json:"value"` VariableType VariableTypeValue `json:"variable_type"` Protected bool `json:"protected"` Masked bool `json:"masked"` + Raw bool `json:"raw"` + Description string `json:"description"` } func (v InstanceVariable) String() string { @@ -50,17 +65,17 @@ func (v InstanceVariable) String() string { // for an instance. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#list-all-instance-variables +// https://docs.gitlab.com/api/instance_level_ci_variables/#list-all-instance-variables type ListInstanceVariablesOptions ListOptions // ListVariables gets a list of all variables for an instance. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#list-all-instance-variables +// https://docs.gitlab.com/api/instance_level_ci_variables/#list-all-instance-variables func (s *InstanceVariablesService) ListVariables(opt *ListInstanceVariablesOptions, options ...RequestOptionFunc) ([]*InstanceVariable, *Response, error) { u := "admin/ci/variables" - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -71,17 +86,17 @@ func (s *InstanceVariablesService) ListVariables(opt *ListInstanceVariablesOptio return nil, resp, err } - return vs, resp, err + return vs, resp, nil } // GetVariable gets a variable. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#show-instance-variable-details +// https://docs.gitlab.com/api/instance_level_ci_variables/#show-instance-variable-details func (s *InstanceVariablesService) GetVariable(key string, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) { u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key)) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -92,30 +107,32 @@ func (s *InstanceVariablesService) GetVariable(key string, options ...RequestOpt return nil, resp, err } - return v, resp, err + return v, resp, nil } // CreateInstanceVariableOptions represents the available CreateVariable() // options. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#create-instance-variable +// https://docs.gitlab.com/api/instance_level_ci_variables/#create-instance-variable type CreateInstanceVariableOptions struct { Key *string `url:"key,omitempty" json:"key,omitempty"` Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` } // CreateVariable creates a new instance level CI variable. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#create-instance-variable +// https://docs.gitlab.com/api/instance_level_ci_variables/#create-instance-variable func (s *InstanceVariablesService) CreateVariable(opt *CreateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) { u := "admin/ci/variables" - req, err := s.client.NewRequest("POST", u, opt, options) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } @@ -126,30 +143,32 @@ func (s *InstanceVariablesService) CreateVariable(opt *CreateInstanceVariableOpt return nil, resp, err } - return v, resp, err + return v, resp, nil } // UpdateInstanceVariableOptions represents the available UpdateVariable() // options. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#update-instance-variable +// https://docs.gitlab.com/api/instance_level_ci_variables/#update-instance-variable type UpdateInstanceVariableOptions struct { Value *string `url:"value,omitempty" json:"value,omitempty"` - VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` - Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` } // UpdateVariable updates the position of an existing // instance level CI variable. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#update-instance-variable +// https://docs.gitlab.com/api/instance_level_ci_variables/#update-instance-variable func (s *InstanceVariablesService) UpdateVariable(key string, opt *UpdateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) { u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key)) - req, err := s.client.NewRequest("PUT", u, opt, options) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } @@ -160,17 +179,17 @@ func (s *InstanceVariablesService) UpdateVariable(key string, opt *UpdateInstanc return nil, resp, err } - return v, resp, err + return v, resp, nil } // RemoveVariable removes an instance level CI variable. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#remove-instance-variable +// https://docs.gitlab.com/api/instance_level_ci_variables/#remove-instance-variable func (s *InstanceVariablesService) RemoveVariable(key string, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key)) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/invites.go b/vendor/gitlab.com/gitlab-org/api/client-go/invites.go new file mode 100644 index 000000000..71b64e078 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/invites.go @@ -0,0 +1,187 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + InvitesServiceInterface interface { + ListPendingGroupInvitations(gid any, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) + ListPendingProjectInvitations(pid any, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) + GroupInvites(gid any, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) + ProjectInvites(pid any, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) + } + + // InvitesService handles communication with the invitation related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/invitations/ + InvitesService struct { + client *Client + } +) + +var _ InvitesServiceInterface = (*InvitesService)(nil) + +// PendingInvite represents a pending invite. +// +// GitLab API docs: https://docs.gitlab.com/api/invitations/ +type PendingInvite struct { + ID int `json:"id"` + InviteEmail string `json:"invite_email"` + CreatedAt *time.Time `json:"created_at"` + AccessLevel AccessLevelValue `json:"access_level"` + ExpiresAt *time.Time `json:"expires_at"` + UserName string `json:"user_name"` + CreatedByName string `json:"created_by_name"` +} + +// ListPendingInvitationsOptions represents the available +// ListPendingInvitations() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#list-all-invitations-pending-for-a-group-or-project +type ListPendingInvitationsOptions struct { + ListOptions + Query *string `url:"query,omitempty" json:"query,omitempty"` +} + +// ListPendingGroupInvitations gets a list of invited group members. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#list-all-invitations-pending-for-a-group-or-project +func (s *InvitesService) ListPendingGroupInvitations(gid any, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/invitations", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pis []*PendingInvite + resp, err := s.client.Do(req, &pis) + if err != nil { + return nil, resp, err + } + + return pis, resp, nil +} + +// ListPendingProjectInvitations gets a list of invited project members. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#list-all-invitations-pending-for-a-group-or-project +func (s *InvitesService) ListPendingProjectInvitations(pid any, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/invitations", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pis []*PendingInvite + resp, err := s.client.Do(req, &pis) + if err != nil { + return nil, resp, err + } + + return pis, resp, nil +} + +// InvitesOptions represents the available GroupInvites() and ProjectInvites() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#add-a-member-to-a-group-or-project +type InvitesOptions struct { + ID any `url:"id,omitempty" json:"id,omitempty"` + Email *string `url:"email,omitempty" json:"email,omitempty"` + UserID any `url:"user_id,omitempty" json:"user_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// InvitesResult represents an invitations result. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#add-a-member-to-a-group-or-project +type InvitesResult struct { + Status string `json:"status"` + Message map[string]string `json:"message,omitempty"` +} + +// GroupInvites invites new users by email to join a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#add-a-member-to-a-group-or-project +func (s *InvitesService) GroupInvites(gid any, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/invitations", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + ir := new(InvitesResult) + resp, err := s.client.Do(req, ir) + if err != nil { + return nil, resp, err + } + + return ir, resp, nil +} + +// ProjectInvites invites new users by email to join a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/invitations/#add-a-member-to-a-group-or-project +func (s *InvitesService) ProjectInvites(pid any, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/invitations", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + ir := new(InvitesResult) + resp, err := s.client.Do(req, ir) + if err != nil { + return nil, resp, err + } + + return ir, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/issue_links.go b/vendor/gitlab.com/gitlab-org/api/client-go/issue_links.go new file mode 100644 index 000000000..78b3877ba --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/issue_links.go @@ -0,0 +1,197 @@ +// +// Copyright 2021, Arkbriar +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + IssueLinksServiceInterface interface { + ListIssueRelations(pid any, issue int, options ...RequestOptionFunc) ([]*IssueRelation, *Response, error) + GetIssueLink(pid any, issue, issueLink int, options ...RequestOptionFunc) (*IssueLink, *Response, error) + CreateIssueLink(pid any, issue int, opt *CreateIssueLinkOptions, options ...RequestOptionFunc) (*IssueLink, *Response, error) + DeleteIssueLink(pid any, issue, issueLink int, options ...RequestOptionFunc) (*IssueLink, *Response, error) + } + + // IssueLinksService handles communication with the issue relations related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/issue_links/ + IssueLinksService struct { + client *Client + } +) + +var _ IssueLinksServiceInterface = (*IssueLinksService)(nil) + +// IssueLink represents a two-way relation between two issues. +// +// GitLab API docs: https://docs.gitlab.com/api/issue_links/ +type IssueLink struct { + SourceIssue *Issue `json:"source_issue"` + TargetIssue *Issue `json:"target_issue"` + LinkType string `json:"link_type"` +} + +// IssueRelation gets a relation between two issues. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issue_links/#list-issue-relations +type IssueRelation struct { + ID int `json:"id"` + IID int `json:"iid"` + State string `json:"state"` + Description string `json:"description"` + Confidential bool `json:"confidential"` + Author *IssueAuthor `json:"author"` + Milestone *Milestone `json:"milestone"` + ProjectID int `json:"project_id"` + Assignees []*IssueAssignee `json:"assignees"` + Assignee *IssueAssignee `json:"assignee"` + UpdatedAt *time.Time `json:"updated_at"` + Title string `json:"title"` + CreatedAt *time.Time `json:"created_at"` + Labels Labels `json:"labels"` + DueDate *ISOTime `json:"due_date"` + WebURL string `json:"web_url"` + References *IssueReferences `json:"references"` + Weight int `json:"weight"` + UserNotesCount int `json:"user_notes_count"` + IssueLinkID int `json:"issue_link_id"` + LinkType string `json:"link_type"` + LinkCreatedAt *time.Time `json:"link_created_at"` + LinkUpdatedAt *time.Time `json:"link_updated_at"` +} + +// ListIssueRelations gets a list of related issues of a given issue, +// sorted by the relationship creation datetime (ascending). +// +// Issues will be filtered according to the user authorizations. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issue_links/#list-issue-relations +func (s *IssueLinksService) ListIssueRelations(pid any, issue int, options ...RequestOptionFunc) ([]*IssueRelation, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/links", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var is []*IssueRelation + resp, err := s.client.Do(req, &is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// GetIssueLink gets a specific issue link. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issue_links/#get-an-issue-link +func (s *IssueLinksService) GetIssueLink(pid any, issue, issueLink int, options ...RequestOptionFunc) (*IssueLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/links/%d", PathEscape(project), issue, issueLink) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + il := new(IssueLink) + resp, err := s.client.Do(req, il) + if err != nil { + return nil, resp, err + } + + return il, resp, nil +} + +// CreateIssueLinkOptions represents the available CreateIssueLink() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issue_links/#create-an-issue-link +type CreateIssueLinkOptions struct { + TargetProjectID *string `json:"target_project_id"` + TargetIssueIID *string `json:"target_issue_iid"` + LinkType *string `json:"link_type"` +} + +// CreateIssueLink creates a two-way relation between two issues. +// User must be allowed to update both issues in order to succeed. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issue_links/#create-an-issue-link +func (s *IssueLinksService) CreateIssueLink(pid any, issue int, opt *CreateIssueLinkOptions, options ...RequestOptionFunc) (*IssueLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/links", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(IssueLink) + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// DeleteIssueLink deletes an issue link, thus removes the two-way relationship. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issue_links/#delete-an-issue-link +func (s *IssueLinksService) DeleteIssueLink(pid any, issue, issueLink int, options ...RequestOptionFunc) (*IssueLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/links/%d", + PathEscape(project), + issue, + issueLink) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, nil, err + } + + il := new(IssueLink) + resp, err := s.client.Do(req, &il) + if err != nil { + return nil, resp, err + } + + return il, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/issues.go b/vendor/gitlab.com/gitlab-org/api/client-go/issues.go new file mode 100644 index 000000000..102047053 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/issues.go @@ -0,0 +1,887 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "net/http" + "reflect" + "strings" + "time" +) + +type ( + IssuesServiceInterface interface { + ListIssues(opt *ListIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + ListGroupIssues(pid any, opt *ListGroupIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + ListProjectIssues(pid any, opt *ListProjectIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + GetIssueByID(issue int, options ...RequestOptionFunc) (*Issue, *Response, error) + GetIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) + CreateIssue(pid any, opt *CreateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) + UpdateIssue(pid any, issue int, opt *UpdateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) + DeleteIssue(pid any, issue int, options ...RequestOptionFunc) (*Response, error) + ReorderIssue(pid any, issue int, opt *ReorderIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) + MoveIssue(pid any, issue int, opt *MoveIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) + SubscribeToIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) + UnsubscribeFromIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) + CreateTodo(pid any, issue int, options ...RequestOptionFunc) (*Todo, *Response, error) + ListMergeRequestsClosingIssue(pid any, issue int, opt *ListMergeRequestsClosingIssueOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + ListMergeRequestsRelatedToIssue(pid any, issue int, opt *ListMergeRequestsRelatedToIssueOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + SetTimeEstimate(pid any, issue int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) + ResetTimeEstimate(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + AddSpentTime(pid any, issue int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) + ResetSpentTime(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + GetTimeSpent(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + GetParticipants(pid any, issue int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) + } + + // IssuesService handles communication with the issue related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/issues/ + IssuesService struct { + client *Client + timeStats *timeStatsService + } +) + +var _ IssuesServiceInterface = (*IssuesService)(nil) + +// IssueAuthor represents a author of the issue. +type IssueAuthor struct { + ID int `json:"id"` + State string `json:"state"` + WebURL string `json:"web_url"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + Username string `json:"username"` +} + +// IssueAssignee represents a assignee of the issue. +type IssueAssignee struct { + ID int `json:"id"` + State string `json:"state"` + WebURL string `json:"web_url"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + Username string `json:"username"` +} + +// IssueReferences represents references of the issue. +type IssueReferences struct { + Short string `json:"short"` + Relative string `json:"relative"` + Full string `json:"full"` +} + +// IssueCloser represents a closer of the issue. +type IssueCloser struct { + ID int `json:"id"` + State string `json:"state"` + WebURL string `json:"web_url"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + Username string `json:"username"` +} + +// IssueLinks represents links of the issue. +type IssueLinks struct { + Self string `json:"self"` + Notes string `json:"notes"` + AwardEmoji string `json:"award_emoji"` + Project string `json:"project"` +} + +// Issue represents a GitLab issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/ +type Issue struct { + ID int `json:"id"` + IID int `json:"iid"` + ExternalID string `json:"external_id"` + State string `json:"state"` + Description string `json:"description"` + HealthStatus string `json:"health_status"` + Author *IssueAuthor `json:"author"` + Milestone *Milestone `json:"milestone"` + ProjectID int `json:"project_id"` + Assignees []*IssueAssignee `json:"assignees"` + UpdatedAt *time.Time `json:"updated_at"` + ClosedAt *time.Time `json:"closed_at"` + ClosedBy *IssueCloser `json:"closed_by"` + Title string `json:"title"` + CreatedAt *time.Time `json:"created_at"` + MovedToID int `json:"moved_to_id"` + Labels Labels `json:"labels"` + LabelDetails []*LabelDetails `json:"label_details"` + Upvotes int `json:"upvotes"` + Downvotes int `json:"downvotes"` + DueDate *ISOTime `json:"due_date"` + WebURL string `json:"web_url"` + References *IssueReferences `json:"references"` + TimeStats *TimeStats `json:"time_stats"` + Confidential bool `json:"confidential"` + Weight int `json:"weight"` + DiscussionLocked bool `json:"discussion_locked"` + IssueType *string `json:"issue_type,omitempty"` + Subscribed bool `json:"subscribed"` + UserNotesCount int `json:"user_notes_count"` + Links *IssueLinks `json:"_links"` + IssueLinkID int `json:"issue_link_id"` + MergeRequestCount int `json:"merge_requests_count"` + EpicIssueID int `json:"epic_issue_id"` + Epic *Epic `json:"epic"` + Iteration *GroupIteration `json:"iteration"` + TaskCompletionStatus *TasksCompletionStatus `json:"task_completion_status"` + ServiceDeskReplyTo string `json:"service_desk_reply_to"` + + // Deprecated: use Assignees instead + Assignee *IssueAssignee `json:"assignee"` +} + +func (i Issue) String() string { + return Stringify(i) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (i *Issue) UnmarshalJSON(data []byte) error { + type alias Issue + + raw := make(map[string]any) + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + if reflect.TypeOf(raw["id"]).Kind() == reflect.String { + raw["external_id"] = raw["id"] + delete(raw, "id") + } + + labelDetails, ok := raw["labels"].([]any) + if ok && len(labelDetails) > 0 { + // We only want to change anything if we got label details. + if _, ok := labelDetails[0].(map[string]any); ok { + labels := make([]any, len(labelDetails)) + for i, details := range labelDetails { + labels[i] = details.(map[string]any)["name"] + } + + // Set the correct values + raw["labels"] = labels + raw["label_details"] = labelDetails + } + } + + data, err = json.Marshal(raw) + if err != nil { + return err + } + + return json.Unmarshal(data, (*alias)(i)) +} + +// LabelDetails represents detailed label information. +type LabelDetails struct { + ID int `json:"id"` + Name string `json:"name"` + Color string `json:"color"` + Description string `json:"description"` + DescriptionHTML string `json:"description_html"` + TextColor string `json:"text_color"` +} + +// ListIssuesOptions represents the available ListIssues() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-issues +type ListIssuesOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + NotMilestone *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + NotAuthorID *[]int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` + AssigneeID *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + NotAssigneeID *[]int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` + AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + NotAssigneeUsername *string `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + NotMyReactionEmoji *[]string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + NotIn *string `url:"not[in],omitempty" json:"not[in],omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + NotSearch *string `url:"not[search],omitempty" json:"not[search],omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + IssueType *string `url:"issue_type,omitempty" json:"issue_type,omitempty"` + IterationID *int `url:"iteration_id,omitempty" json:"iteration_id,omitempty"` +} + +// ListIssues gets all issues created by authenticated user. This function +// takes pagination parameters page and per_page to restrict the list of issues. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-issues +func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "issues", opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// ListGroupIssuesOptions represents the available ListGroupIssues() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-group-issues +type ListGroupIssuesOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + NotMilestone *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + NotAuthorID *int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + + // AssigneeID is defined as an int the the documentation, however, the field + // must be able to accept Assignee IDs and the words 'None' and 'Any'. Use + // *AssigneIDValue instead of *int. + AssigneeID *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + NotAssigneeID *int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` + AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + NotAssigneeUsername *string `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + NotMyReactionEmoji *string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + NotSearch *string `url:"not[search],omitempty" json:"not[search],omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + NotIn *string `url:"not[in],omitempty" json:"not[in],omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + IssueType *string `url:"issue_type,omitempty" json:"issue_type,omitempty"` + IterationID *int `url:"iteration_id,omitempty" json:"iteration_id,omitempty"` +} + +// ListGroupIssues gets a list of group issues. This function accepts +// pagination parameters page and per_page to return the list of group issues. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-group-issues +func (s *IssuesService) ListGroupIssues(pid any, opt *ListGroupIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + group, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/issues", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// ListProjectIssuesOptions represents the available ListProjectIssues() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-project-issues +type ListProjectIssuesOptions struct { + ListOptions + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + NotMilestone *string `url:"not[milestone],omitempty" json:"not[milestone],omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + NotAuthorID *int `url:"not[author_id],omitempty" json:"not[author_id],omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + NotAssigneeID *int `url:"not[assignee_id],omitempty" json:"not[assignee_id],omitempty"` + AssigneeUsername *string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + NotAssigneeUsername *string `url:"not[assignee_username],omitempty" json:"not[assignee_username],omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + NotMyReactionEmoji *string `url:"not[my_reaction_emoji],omitempty" json:"not[my_reaction_emoji],omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + NotIn *string `url:"not[in],omitempty" json:"not[in],omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + IssueType *string `url:"issue_type,omitempty" json:"issue_type,omitempty"` + IterationID *int `url:"iteration_id,omitempty" json:"iteration_id,omitempty"` +} + +// ListProjectIssues gets a list of project issues. This function accepts +// pagination parameters page and per_page to return the list of project issues. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#list-project-issues +func (s *IssuesService) ListProjectIssues(pid any, opt *ListProjectIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// GetIssueByID gets a single issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#single-issue +func (s *IssuesService) GetIssueByID(issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { + u := fmt.Sprintf("issues/%d", issue) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// GetIssue gets a single project issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#single-project-issue +func (s *IssuesService) GetIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// CreateIssueOptions represents the available CreateIssue() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#new-issue +type CreateIssueOptions struct { + IID *int `url:"iid,omitempty" json:"iid,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + AssigneeIDs *[]int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` + EpicID *int `url:"epic_id,omitempty" json:"epic_id,omitempty"` + MergeRequestToResolveDiscussionsOf *int `url:"merge_request_to_resolve_discussions_of,omitempty" json:"merge_request_to_resolve_discussions_of,omitempty"` + DiscussionToResolve *string `url:"discussion_to_resolve,omitempty" json:"discussion_to_resolve,omitempty"` + Weight *int `url:"weight,omitempty" json:"weight,omitempty"` + IssueType *string `url:"issue_type,omitempty" json:"issue_type,omitempty"` +} + +// CreateIssue creates a new project issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#new-issue +func (s *IssuesService) CreateIssue(pid any, opt *CreateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// UpdateIssueOptions represents the available UpdateIssue() options. +// +// To reset the due date, epic, milestone, or weight of the issue, set the +// ResetDueDate, ResetEpic, ResetMilestone, or ResetWeight field to true. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#edit-an-issue +type UpdateIssueOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` + AssigneeIDs *[]int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + AddLabels *LabelOptions `url:"add_labels,comma,omitempty" json:"add_labels,omitempty"` + RemoveLabels *LabelOptions `url:"remove_labels,comma,omitempty" json:"remove_labels,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` + UpdatedAt *time.Time `url:"updated_at,omitempty" json:"updated_at,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` + EpicID *int `url:"epic_id,omitempty" json:"epic_id,omitempty"` + Weight *int `url:"weight,omitempty" json:"weight,omitempty"` + DiscussionLocked *bool `url:"discussion_locked,omitempty" json:"discussion_locked,omitempty"` + IssueType *string `url:"issue_type,omitempty" json:"issue_type,omitempty"` + + ResetDueDate bool `url:"-" json:"-"` + ResetEpicID bool `url:"-" json:"-"` + ResetMilestoneID bool `url:"-" json:"-"` + ResetWeight bool `url:"-" json:"-"` +} + +// MarshalJSON implements custom JSON marshaling for UpdateIssueOptions. +// This is needed to support emitting a literal `null` when the field needs to be removed. +func (o UpdateIssueOptions) MarshalJSON() ([]byte, error) { + data := map[string]any{} + + // Use reflection to copy all fields from o to data + val := reflect.ValueOf(o) + typ := val.Type() + + for i := range val.NumField() { + field := val.Field(i) + fieldName := typ.Field(i).Name + + if field.IsZero() { + continue + } + + name := fieldName + + if tag := typ.Field(i).Tag.Get("json"); tag != "" { + tagFields := strings.Split(tag, ",") + name = tagFields[0] + } + + // Skip unexported fields. + if name == "-" { + continue + } + + data[name] = field.Interface() + } + + // Emit a literal `null` when the field needs to be removed + if o.ResetDueDate { + data["due_date"] = nil + } + + if o.ResetEpicID { + data["epic_id"] = nil + } + + if o.ResetMilestoneID { + data["milestone_id"] = nil + } + + if o.ResetWeight { + data["weight"] = nil + } + + return json.Marshal(data) +} + +// UpdateIssue updates an existing project issue. This function is also used +// to mark an issue as closed. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#edit-an-issue +func (s *IssuesService) UpdateIssue(pid any, issue int, opt *UpdateIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// DeleteIssue deletes a single project issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#delete-an-issue +func (s *IssuesService) DeleteIssue(pid any, issue int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ReorderIssueOptions represents the available ReorderIssue() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#reorder-an-issue +type ReorderIssueOptions struct { + MoveAfterID *int `url:"move_after_id,omitempty" json:"move_after_id,omitempty"` + MoveBeforeID *int `url:"move_before_id,omitempty" json:"move_before_id,omitempty"` +} + +// ReorderIssue reorders an issue. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#reorder-an-issue +func (s *IssuesService) ReorderIssue(pid any, issue int, opt *ReorderIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/reorder", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// MoveIssueOptions represents the available MoveIssue() options. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#move-an-issue +type MoveIssueOptions struct { + ToProjectID *int `url:"to_project_id,omitempty" json:"to_project_id,omitempty"` +} + +// MoveIssue updates an existing project issue. This function is also used +// to mark an issue as closed. +// +// GitLab API docs: https://docs.gitlab.com/api/issues/#move-an-issue +func (s *IssuesService) MoveIssue(pid any, issue int, opt *MoveIssueOptions, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/move", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// SubscribeToIssue subscribes the authenticated user to the given issue to +// receive notifications. If the user is already subscribed to the issue, the +// status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#subscribe-to-an-issue +func (s *IssuesService) SubscribeToIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/subscribe", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// UnsubscribeFromIssue unsubscribes the authenticated user from the given +// issue to not receive notifications from that merge request. If the user +// is not subscribed to the issue, status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#unsubscribe-from-an-issue +func (s *IssuesService) UnsubscribeFromIssue(pid any, issue int, options ...RequestOptionFunc) (*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/unsubscribe", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + i := new(Issue) + resp, err := s.client.Do(req, i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// CreateTodo creates a todo for the current user for an issue. +// If there already exists a todo for the user on that issue, status code +// 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#create-a-to-do-item +func (s *IssuesService) CreateTodo(pid any, issue int, options ...RequestOptionFunc) (*Todo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/todo", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(Todo) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// ListMergeRequestsClosingIssueOptions represents the available +// ListMergeRequestsClosingIssue() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#list-merge-requests-that-close-a-particular-issue-on-merge +type ListMergeRequestsClosingIssueOptions ListOptions + +// ListMergeRequestsClosingIssue gets all the merge requests that will close +// issue when merged. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#list-merge-requests-that-close-a-particular-issue-on-merge +func (s *IssuesService) ListMergeRequestsClosingIssue(pid any, issue int, opt *ListMergeRequestsClosingIssueOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/closed_by", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*BasicMergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ListMergeRequestsRelatedToIssueOptions represents the available +// ListMergeRequestsRelatedToIssue() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#list-merge-requests-related-to-issue +type ListMergeRequestsRelatedToIssueOptions ListOptions + +// ListMergeRequestsRelatedToIssue gets all the merge requests that are +// related to the issue +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#list-merge-requests-related-to-issue +func (s *IssuesService) ListMergeRequestsRelatedToIssue(pid any, issue int, opt *ListMergeRequestsRelatedToIssueOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/related_merge_requests", + PathEscape(project), + issue, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*BasicMergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// SetTimeEstimate sets the time estimate for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#set-a-time-estimate-for-an-issue +func (s *IssuesService) SetTimeEstimate(pid any, issue int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.setTimeEstimate(pid, "issues", issue, opt, options...) +} + +// ResetTimeEstimate resets the time estimate for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#reset-the-time-estimate-for-an-issue +func (s *IssuesService) ResetTimeEstimate(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.resetTimeEstimate(pid, "issues", issue, options...) +} + +// AddSpentTime adds spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#add-spent-time-for-an-issue +func (s *IssuesService) AddSpentTime(pid any, issue int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.addSpentTime(pid, "issues", issue, opt, options...) +} + +// ResetSpentTime resets the spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#reset-spent-time-for-an-issue +func (s *IssuesService) ResetSpentTime(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.resetSpentTime(pid, "issues", issue, options...) +} + +// GetTimeSpent gets the spent time for a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#get-time-tracking-stats +func (s *IssuesService) GetTimeSpent(pid any, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.getTimeSpent(pid, "issues", issue, options...) +} + +// GetParticipants gets a list of issue participants. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues/#list-participants-in-an-issue +func (s *IssuesService) GetParticipants(pid any, issue int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/participants", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var bu []*BasicUser + resp, err := s.client.Do(req, &bu) + if err != nil { + return nil, resp, err + } + + return bu, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/issues_statistics.go b/vendor/gitlab.com/gitlab-org/api/client-go/issues_statistics.go new file mode 100644 index 000000000..23f68169a --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/issues_statistics.go @@ -0,0 +1,197 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + IssuesStatisticsServiceInterface interface { + GetIssuesStatistics(opt *GetIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) + GetGroupIssuesStatistics(gid any, opt *GetGroupIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) + GetProjectIssuesStatistics(pid any, opt *GetProjectIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) + } + + // IssuesStatisticsService handles communication with the issues statistics + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/issues_statistics/ + IssuesStatisticsService struct { + client *Client + } +) + +var _ IssuesStatisticsServiceInterface = (*IssuesStatisticsService)(nil) + +// IssuesStatistics represents a GitLab issues statistic. +// +// GitLab API docs: https://docs.gitlab.com/api/issues_statistics/ +type IssuesStatistics struct { + Statistics struct { + Counts struct { + All int `json:"all"` + Closed int `json:"closed"` + Opened int `json:"opened"` + } `json:"counts"` + } `json:"statistics"` +} + +func (n IssuesStatistics) String() string { + return Stringify(n) +} + +// GetIssuesStatisticsOptions represents the available GetIssuesStatistics() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-issues-statistics +type GetIssuesStatisticsOptions struct { + Labels *LabelOptions `url:"labels,omitempty" json:"labels,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + AssigneeUsername *[]string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` +} + +// GetIssuesStatistics gets issues statistics on all issues the authenticated +// user has access to. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-issues-statistics +func (s *IssuesStatisticsService) GetIssuesStatistics(opt *GetIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "issues_statistics", opt, options) + if err != nil { + return nil, nil, err + } + + is := new(IssuesStatistics) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// GetGroupIssuesStatisticsOptions represents the available GetGroupIssuesStatistics() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-group-issues-statistics +type GetGroupIssuesStatisticsOptions struct { + Labels *LabelOptions `url:"labels,omitempty" json:"labels,omitempty"` + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + AssigneeUsername *[]string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` +} + +// GetGroupIssuesStatistics gets issues count statistics for given group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-group-issues-statistics +func (s *IssuesStatisticsService) GetGroupIssuesStatistics(gid any, opt *GetGroupIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/issues_statistics", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + is := new(IssuesStatistics) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// GetProjectIssuesStatisticsOptions represents the available +// GetProjectIssuesStatistics() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-project-issues-statistics +type GetProjectIssuesStatisticsOptions struct { + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + Labels *LabelOptions `url:"labels,omitempty" json:"labels,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + AssigneeUsername *[]string `url:"assignee_username,omitempty" json:"assignee_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` +} + +// GetProjectIssuesStatistics gets issues count statistics for given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/issues_statistics/#get-project-issues-statistics +func (s *IssuesStatisticsService) GetProjectIssuesStatistics(pid any, opt *GetProjectIssuesStatisticsOptions, options ...RequestOptionFunc) (*IssuesStatistics, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues_statistics", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + is := new(IssuesStatistics) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/job_token_scope.go b/vendor/gitlab.com/gitlab-org/api/client-go/job_token_scope.go new file mode 100644 index 000000000..1421f5913 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/job_token_scope.go @@ -0,0 +1,298 @@ +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + JobTokenScopeServiceInterface interface { + GetProjectJobTokenAccessSettings(pid any, options ...RequestOptionFunc) (*JobTokenAccessSettings, *Response, error) + PatchProjectJobTokenAccessSettings(pid any, opt *PatchProjectJobTokenAccessSettingsOptions, options ...RequestOptionFunc) (*Response, error) + GetProjectJobTokenInboundAllowList(pid any, opt *GetJobTokenInboundAllowListOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + AddProjectToJobScopeAllowList(pid any, opt *JobTokenInboundAllowOptions, options ...RequestOptionFunc) (*JobTokenInboundAllowItem, *Response, error) + RemoveProjectFromJobScopeAllowList(pid any, targetProject int, options ...RequestOptionFunc) (*Response, error) + GetJobTokenAllowlistGroups(pid any, opt *GetJobTokenAllowlistGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) + AddGroupToJobTokenAllowlist(pid any, opt *AddGroupToJobTokenAllowlistOptions, options ...RequestOptionFunc) (*JobTokenAllowlistItem, *Response, error) + RemoveGroupFromJobTokenAllowlist(pid any, targetGroup int, options ...RequestOptionFunc) (*Response, error) + } + + // JobTokenScopeService handles communication with project CI settings + // such as token permissions. + // + // GitLab API docs: https://docs.gitlab.com/api/project_job_token_scopes/ + JobTokenScopeService struct { + client *Client + } +) + +var _ JobTokenScopeServiceInterface = (*JobTokenScopeService)(nil) + +// JobTokenAccessSettings represents job token access attributes for this project. +// +// GitLab API docs: https://docs.gitlab.com/api/project_job_token_scopes/ +type JobTokenAccessSettings struct { + InboundEnabled bool `json:"inbound_enabled"` +} + +// GetProjectJobTokenAccessSettings fetch the CI/CD job token access settings (job token scope) of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#get-a-projects-cicd-job-token-access-settings +func (j *JobTokenScopeService) GetProjectJobTokenAccessSettings(pid any, options ...RequestOptionFunc) (*JobTokenAccessSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + jt := new(JobTokenAccessSettings) + resp, err := j.client.Do(req, jt) + if err != nil { + return nil, resp, err + } + + return jt, resp, err +} + +// PatchProjectJobTokenAccessSettingsOptions represents the available +// PatchProjectJobTokenAccessSettings() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#patch-a-projects-cicd-job-token-access-settings +type PatchProjectJobTokenAccessSettingsOptions struct { + Enabled bool `json:"enabled"` +} + +// PatchProjectJobTokenAccessSettings patch the Limit access to this project setting (job token scope) of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#patch-a-projects-cicd-job-token-access-settings +func (j *JobTokenScopeService) PatchProjectJobTokenAccessSettings(pid any, opt *PatchProjectJobTokenAccessSettingsOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, err + } + + return j.client.Do(req, nil) +} + +// JobTokenInboundAllowItem represents a single job token inbound allowlist item. +// +// GitLab API docs: https://docs.gitlab.com/api/project_job_token_scopes/ +type JobTokenInboundAllowItem struct { + SourceProjectID int `json:"source_project_id"` + TargetProjectID int `json:"target_project_id"` +} + +// GetJobTokenInboundAllowListOptions represents the available +// GetJobTokenInboundAllowList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#get-a-projects-cicd-job-token-inbound-allowlist +type GetJobTokenInboundAllowListOptions struct { + ListOptions +} + +// GetProjectJobTokenInboundAllowList fetches the CI/CD job token inbound +// allowlist (job token scope) of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#get-a-projects-cicd-job-token-inbound-allowlist +func (j *JobTokenScopeService) GetProjectJobTokenInboundAllowList(pid any, opt *GetJobTokenInboundAllowListOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/allowlist`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Project + resp, err := j.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// AddProjectToJobScopeAllowListOptions represents the available +// AddProjectToJobScopeAllowList() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#add-a-project-to-a-cicd-job-token-inbound-allowlist +type JobTokenInboundAllowOptions struct { + TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"` +} + +// AddProjectToJobScopeAllowList adds a new project to a project's job token +// inbound allow list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#add-a-project-to-a-cicd-job-token-inbound-allowlist +func (j *JobTokenScopeService) AddProjectToJobScopeAllowList(pid any, opt *JobTokenInboundAllowOptions, options ...RequestOptionFunc) (*JobTokenInboundAllowItem, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/allowlist`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + jt := new(JobTokenInboundAllowItem) + resp, err := j.client.Do(req, jt) + if err != nil { + return nil, resp, err + } + + return jt, resp, nil +} + +// RemoveProjectFromJobScopeAllowList removes a project from a project's job +// token inbound allow list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#remove-a-project-from-a-cicd-job-token-inbound-allowlist +func (j *JobTokenScopeService) RemoveProjectFromJobScopeAllowList(pid any, targetProject int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/allowlist/%d`, PathEscape(project), targetProject) + + req, err := j.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return j.client.Do(req, nil) +} + +// JobTokenAllowlistItem represents a single job token allowlist item. +// +// GitLab API docs: https://docs.gitlab.com/api/project_job_token_scopes/ +type JobTokenAllowlistItem struct { + SourceProjectID int `json:"source_project_id"` + TargetGroupID int `json:"target_group_id"` +} + +// GetJobTokenAllowlistGroupsOptions represents the available +// GetJobTokenAllowlistGroups() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#get-a-projects-cicd-job-token-allowlist-of-groups +type GetJobTokenAllowlistGroupsOptions struct { + ListOptions +} + +// GetJobTokenAllowListGroups fetches the CI/CD job token allowlist groups +// (job token scopes) of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#get-a-projects-cicd-job-token-allowlist-of-groups +func (j *JobTokenScopeService) GetJobTokenAllowlistGroups(pid any, opt *GetJobTokenAllowlistGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Group + resp, err := j.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// AddGroupToJobTokenAllowlistOptions represents the available +// AddGroupToJobTokenAllowlist() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#add-a-group-to-a-cicd-job-token-allowlist +type AddGroupToJobTokenAllowlistOptions struct { + TargetGroupID *int `url:"target_group_id,omitempty" json:"target_group_id,omitempty"` +} + +// AddProjectToJobScopeGroupsAllowList adds a new group to a project's job token +// inbound groups allow list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#add-a-group-to-a-cicd-job-token-allowlist +func (j *JobTokenScopeService) AddGroupToJobTokenAllowlist(pid any, opt *AddGroupToJobTokenAllowlistOptions, options ...RequestOptionFunc) (*JobTokenAllowlistItem, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist`, PathEscape(project)) + + req, err := j.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + jt := new(JobTokenAllowlistItem) + resp, err := j.client.Do(req, jt) + if err != nil { + return nil, resp, err + } + + return jt, resp, nil +} + +// RemoveGroupFromJopTokenAllowlist removes a group from a project's job +// token inbound groups allow list. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_job_token_scopes/#remove-a-group-from-a-cicd-job-token-allowlist +func (j *JobTokenScopeService) RemoveGroupFromJobTokenAllowlist(pid any, targetGroup int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf(`projects/%s/job_token_scope/groups_allowlist/%d`, PathEscape(project), targetGroup) + + req, err := j.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return j.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/jobs.go b/vendor/gitlab.com/gitlab-org/api/client-go/jobs.go new file mode 100644 index 000000000..2b6ba1acc --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/jobs.go @@ -0,0 +1,609 @@ +// +// Copyright 2021, Arkbriar +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/http" + "time" +) + +type ( + JobsServiceInterface interface { + ListProjectJobs(pid any, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) + ListPipelineJobs(pid any, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) + ListPipelineBridges(pid any, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Bridge, *Response, error) + GetJobTokensJob(opts *GetJobTokensJobOptions, options ...RequestOptionFunc) (*Job, *Response, error) + GetJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) + GetJobArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + DownloadArtifactsFile(pid any, refName string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + DownloadSingleArtifactsFile(pid any, jobID int, artifactPath string, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + DownloadSingleArtifactsFileByTagOrBranch(pid any, refName string, artifactPath string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + GetTraceFile(pid any, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + CancelJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) + RetryJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) + EraseJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) + KeepArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) + PlayJob(pid any, jobID int, opt *PlayJobOptions, options ...RequestOptionFunc) (*Job, *Response, error) + DeleteArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*Response, error) + DeleteProjectArtifacts(pid any, options ...RequestOptionFunc) (*Response, error) + } + + // JobsService handles communication with the ci builds related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/jobs/ + JobsService struct { + client *Client + } +) + +var _ JobsServiceInterface = (*JobsService)(nil) + +// Job represents a ci build. +// +// GitLab API docs: https://docs.gitlab.com/api/jobs/ +type Job struct { + Commit *Commit `json:"commit"` + Coverage float64 `json:"coverage"` + AllowFailure bool `json:"allow_failure"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + ErasedAt *time.Time `json:"erased_at"` + Duration float64 `json:"duration"` + QueuedDuration float64 `json:"queued_duration"` + ArtifactsExpireAt *time.Time `json:"artifacts_expire_at"` + TagList []string `json:"tag_list"` + ID int `json:"id"` + Name string `json:"name"` + Pipeline struct { + ID int `json:"id"` + ProjectID int `json:"project_id"` + Ref string `json:"ref"` + Sha string `json:"sha"` + Status string `json:"status"` + } `json:"pipeline"` + Ref string `json:"ref"` + Artifacts []struct { + FileType string `json:"file_type"` + Filename string `json:"filename"` + Size int `json:"size"` + FileFormat string `json:"file_format"` + } `json:"artifacts"` + ArtifactsFile struct { + Filename string `json:"filename"` + Size int `json:"size"` + } `json:"artifacts_file"` + Runner struct { + ID int `json:"id"` + Description string `json:"description"` + Active bool `json:"active"` + IsShared bool `json:"is_shared"` + Name string `json:"name"` + } `json:"runner"` + Stage string `json:"stage"` + Status string `json:"status"` + FailureReason string `json:"failure_reason"` + Tag bool `json:"tag"` + WebURL string `json:"web_url"` + Project *Project `json:"project"` + User *User `json:"user"` +} + +// Bridge represents a pipeline bridge. +// +// GitLab API docs: https://docs.gitlab.com/api/jobs/#list-pipeline-trigger-jobs +type Bridge struct { + Commit *Commit `json:"commit"` + Coverage float64 `json:"coverage"` + AllowFailure bool `json:"allow_failure"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + ErasedAt *time.Time `json:"erased_at"` + Duration float64 `json:"duration"` + QueuedDuration float64 `json:"queued_duration"` + ID int `json:"id"` + Name string `json:"name"` + Pipeline PipelineInfo `json:"pipeline"` + Ref string `json:"ref"` + Stage string `json:"stage"` + Status string `json:"status"` + FailureReason string `json:"failure_reason"` + Tag bool `json:"tag"` + WebURL string `json:"web_url"` + User *User `json:"user"` + DownstreamPipeline *PipelineInfo `json:"downstream_pipeline"` +} + +// ListJobsOptions represents the available ListProjectJobs() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#list-project-jobs +type ListJobsOptions struct { + ListOptions + Scope *[]BuildStateValue `url:"scope[],omitempty" json:"scope,omitempty"` + IncludeRetried *bool `url:"include_retried,omitempty" json:"include_retried,omitempty"` +} + +// ListProjectJobs gets a list of jobs in a project. +// +// The scope of jobs to show, one or array of: created, pending, running, +// failed, success, canceled, skipped; showing all jobs if none provided +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#list-project-jobs +func (s *JobsService) ListProjectJobs(pid any, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var jobs []*Job + resp, err := s.client.Do(req, &jobs) + if err != nil { + return nil, resp, err + } + + return jobs, resp, nil +} + +// ListPipelineJobs gets a list of jobs for specific pipeline in a +// project. If the pipeline ID is not found, it will respond with 404. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#list-pipeline-jobs +func (s *JobsService) ListPipelineJobs(pid any, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/jobs", PathEscape(project), pipelineID) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var jobs []*Job + resp, err := s.client.Do(req, &jobs) + if err != nil { + return nil, resp, err + } + + return jobs, resp, nil +} + +// ListPipelineBridges gets a list of bridges for specific pipeline in a +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#list-pipeline-trigger-jobs +func (s *JobsService) ListPipelineBridges(pid any, pipelineID int, opts *ListJobsOptions, options ...RequestOptionFunc) ([]*Bridge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/bridges", PathEscape(project), pipelineID) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var bridges []*Bridge + resp, err := s.client.Do(req, &bridges) + if err != nil { + return nil, resp, err + } + + return bridges, resp, nil +} + +// GetJobTokensJobOptions represents the available GetJobTokensJob() options. +// +// GitLab API docs: https://docs.gitlab.com/api/jobs/#get-job-tokens-job +type GetJobTokensJobOptions struct { + JobToken *string `url:"job_token,omitempty" json:"job_token,omitempty"` +} + +// GetJobTokensJob retrieves the job that generated a job token. +// +// GitLab API docs: https://docs.gitlab.com/api/jobs/#get-job-tokens-job +func (s *JobsService) GetJobTokensJob(opts *GetJobTokensJobOptions, options ...RequestOptionFunc) (*Job, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "job", opts, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// GetJob gets a single job of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#get-a-single-job +func (s *JobsService) GetJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// GetJobArtifacts get jobs artifacts of a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#get-job-artifacts +func (s *JobsService) GetJobArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/artifacts", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + artifactsBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactsBuf) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(artifactsBuf.Bytes()), resp, err +} + +// DownloadArtifactsFileOptions represents the available DownloadArtifactsFile() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#download-the-artifacts-archive +type DownloadArtifactsFileOptions struct { + Job *string `url:"job" json:"job"` +} + +// DownloadArtifactsFile download the artifacts file from the given +// reference name and job provided the job finished successfully. +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#download-the-artifacts-archive +func (s *JobsService) DownloadArtifactsFile(pid any, refName string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/artifacts/%s/download", PathEscape(project), refName) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + artifactsBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactsBuf) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(artifactsBuf.Bytes()), resp, err +} + +// DownloadSingleArtifactsFile download a file from the artifacts from the +// given reference name and job provided the job finished successfully. +// Only a single file is going to be extracted from the archive and streamed +// to a client. +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#download-a-single-artifact-file-by-job-id +func (s *JobsService) DownloadSingleArtifactsFile(pid any, jobID int, artifactPath string, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + + u := fmt.Sprintf( + "projects/%s/jobs/%d/artifacts/%s", + PathEscape(project), + jobID, + artifactPath, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + artifactBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactBuf) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(artifactBuf.Bytes()), resp, err +} + +// DownloadSingleArtifactsFile download a single artifact file for a specific +// job of the latest successful pipeline for the given reference name from +// inside the job’s artifacts archive. The file is extracted from the archive +// and streamed to the client. +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#download-a-single-artifact-file-from-specific-tag-or-branch +func (s *JobsService) DownloadSingleArtifactsFileByTagOrBranch(pid any, refName string, artifactPath string, opt *DownloadArtifactsFileOptions, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + + u := fmt.Sprintf( + "projects/%s/jobs/artifacts/%s/raw/%s", + PathEscape(project), + PathEscape(refName), + artifactPath, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + artifactBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, artifactBuf) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(artifactBuf.Bytes()), resp, err +} + +// GetTraceFile gets a trace of a specific job of a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#get-a-log-file +func (s *JobsService) GetTraceFile(pid any, jobID int, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/trace", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + traceBuf := new(bytes.Buffer) + resp, err := s.client.Do(req, traceBuf) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(traceBuf.Bytes()), resp, err +} + +// CancelJob cancels a single job of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#cancel-a-job +func (s *JobsService) CancelJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/cancel", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// RetryJob retries a single job of a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#retry-a-job +func (s *JobsService) RetryJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/retry", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// EraseJob erases a single job of a project, removes a job +// artifacts and a job trace. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#erase-a-job +func (s *JobsService) EraseJob(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/erase", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// KeepArtifacts prevents artifacts from being deleted when +// expiration is set. +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#keep-artifacts +func (s *JobsService) KeepArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/artifacts/keep", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// PlayJobOptions represents the available PlayJob() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#run-a-job +type PlayJobOptions struct { + JobVariablesAttributes *[]*JobVariableOptions `url:"job_variables_attributes,omitempty" json:"job_variables_attributes,omitempty"` +} + +// JobVariableOptions represents a single job variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#run-a-job +type JobVariableOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Value *string `url:"value,omitempty" json:"value,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// PlayJob triggers a manual action to start a job. +// +// GitLab API docs: +// https://docs.gitlab.com/api/jobs/#run-a-job +func (s *JobsService) PlayJob(pid any, jobID int, opt *PlayJobOptions, options ...RequestOptionFunc) (*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/play", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + job := new(Job) + resp, err := s.client.Do(req, job) + if err != nil { + return nil, resp, err + } + + return job, resp, nil +} + +// DeleteArtifacts delete artifacts of a job +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#delete-job-artifacts +func (s *JobsService) DeleteArtifacts(pid any, jobID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/jobs/%d/artifacts", PathEscape(project), jobID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteProjectArtifacts delete artifacts eligible for deletion in a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/job_artifacts/#delete-job-artifacts +func (s *JobsService) DeleteProjectArtifacts(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/artifacts", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/keys.go b/vendor/gitlab.com/gitlab-org/api/client-go/keys.go new file mode 100644 index 000000000..3b2187c65 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/keys.go @@ -0,0 +1,106 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + KeysServiceInterface interface { + GetKeyWithUser(key int, options ...RequestOptionFunc) (*Key, *Response, error) + GetKeyByFingerprint(opt *GetKeyByFingerprintOptions, options ...RequestOptionFunc) (*Key, *Response, error) + } + + // KeysService handles communication with the + // keys related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/keys/ + KeysService struct { + client *Client + } +) + +var _ KeysServiceInterface = (*KeysService)(nil) + +// Key represents a GitLab user's SSH key. +// +// GitLab API docs: +// https://docs.gitlab.com/api/keys/ +type Key struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + CreatedAt *time.Time `json:"created_at"` + User User `json:"user"` +} + +// GetKeyWithUser gets a single key by id along with the associated +// user information. +// +// GitLab API docs: +// https://docs.gitlab.com/api/keys/#get-ssh-key-with-user-by-id-of-an-ssh-key +func (s *KeysService) GetKeyWithUser(key int, options ...RequestOptionFunc) (*Key, *Response, error) { + u := fmt.Sprintf("keys/%d", key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(Key) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// GetKeyByFingerprintOptions represents the available GetKeyByFingerprint() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/keys/#get-user-by-fingerprint-of-ssh-key +// https://docs.gitlab.com/api/keys/#get-user-by-deploy-key-fingerprint +type GetKeyByFingerprintOptions struct { + Fingerprint string `url:"fingerprint" json:"fingerprint"` +} + +// GetKeyByFingerprint gets a specific SSH key or deploy key by fingerprint +// along with the associated user information. +// +// GitLab API docs: +// https://docs.gitlab.com/api/keys/#get-user-by-fingerprint-of-ssh-key +// https://docs.gitlab.com/api/keys/#get-user-by-deploy-key-fingerprint +func (s *KeysService) GetKeyByFingerprint(opt *GetKeyByFingerprintOptions, options ...RequestOptionFunc) (*Key, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "keys", opt, options) + if err != nil { + return nil, nil, err + } + + k := new(Key) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/labels.go b/vendor/gitlab.com/gitlab-org/api/client-go/labels.go new file mode 100644 index 000000000..d7eb1e624 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/labels.go @@ -0,0 +1,340 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type ( + LabelsServiceInterface interface { + ListLabels(pid any, opt *ListLabelsOptions, options ...RequestOptionFunc) ([]*Label, *Response, error) + GetLabel(pid any, lid any, options ...RequestOptionFunc) (*Label, *Response, error) + CreateLabel(pid any, opt *CreateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) + DeleteLabel(pid any, lid any, opt *DeleteLabelOptions, options ...RequestOptionFunc) (*Response, error) + UpdateLabel(pid any, lid any, opt *UpdateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) + SubscribeToLabel(pid any, lid any, options ...RequestOptionFunc) (*Label, *Response, error) + UnsubscribeFromLabel(pid any, lid any, options ...RequestOptionFunc) (*Response, error) + PromoteLabel(pid any, lid any, options ...RequestOptionFunc) (*Response, error) + } + + // LabelsService handles communication with the label related methods of the + // GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/labels/ + LabelsService struct { + client *Client + } +) + +var _ LabelsServiceInterface = (*LabelsService)(nil) + +// Label represents a GitLab label. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/ +type Label struct { + ID int `json:"id"` + Name string `json:"name"` + Color string `json:"color"` + TextColor string `json:"text_color"` + Description string `json:"description"` + OpenIssuesCount int `json:"open_issues_count"` + ClosedIssuesCount int `json:"closed_issues_count"` + OpenMergeRequestsCount int `json:"open_merge_requests_count"` + Subscribed bool `json:"subscribed"` + Priority int `json:"priority"` + IsProjectLabel bool `json:"is_project_label"` +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (l *Label) UnmarshalJSON(data []byte) error { + type alias Label + if err := json.Unmarshal(data, (*alias)(l)); err != nil { + return err + } + + if l.Name == "" { + var raw map[string]any + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + if title, ok := raw["title"].(string); ok { + l.Name = title + } + } + + return nil +} + +func (l Label) String() string { + return Stringify(l) +} + +// ListLabelsOptions represents the available ListLabels() options. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#list-labels +type ListLabelsOptions struct { + ListOptions + WithCounts *bool `url:"with_counts,omitempty" json:"with_counts,omitempty"` + IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListLabels gets all labels for given project. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#list-labels +func (s *LabelsService) ListLabels(pid any, opt *ListLabelsOptions, options ...RequestOptionFunc) ([]*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var l []*Label + resp, err := s.client.Do(req, &l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// GetLabel get a single label for a given project. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#get-a-single-project-label +func (s *LabelsService) GetLabel(pid any, lid any, options ...RequestOptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels/%s", PathEscape(project), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var l *Label + resp, err := s.client.Do(req, &l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// CreateLabelOptions represents the available CreateLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#create-a-new-label +type CreateLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Priority *int `url:"priority,omitempty" json:"priority,omitempty"` +} + +// CreateLabel creates a new label for given repository with given name and +// color. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#create-a-new-label +func (s *LabelsService) CreateLabel(pid any, opt *CreateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(Label) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// DeleteLabelOptions represents the available DeleteLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#delete-a-label +type DeleteLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// DeleteLabel deletes a label given by its name or ID. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#delete-a-label +func (s *LabelsService) DeleteLabel(pid any, lid any, opt *DeleteLabelOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/labels", PathEscape(project)) + + if lid != nil { + label, err := parseID(lid) + if err != nil { + return nil, err + } + u = fmt.Sprintf("projects/%s/labels/%s", PathEscape(project), PathEscape(label)) + } + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateLabelOptions represents the available UpdateLabel() options. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#edit-an-existing-label +type UpdateLabelOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + Color *string `url:"color,omitempty" json:"color,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Priority *int `url:"priority,omitempty" json:"priority,omitempty"` +} + +// UpdateLabel updates an existing label with new name or now color. At least +// one parameter is required, to update the label. +// +// GitLab API docs: https://docs.gitlab.com/api/labels/#edit-an-existing-label +func (s *LabelsService) UpdateLabel(pid any, lid any, opt *UpdateLabelOptions, options ...RequestOptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels", PathEscape(project)) + + if lid != nil { + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u = fmt.Sprintf("projects/%s/labels/%s", PathEscape(project), PathEscape(label)) + } + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + l := new(Label) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// SubscribeToLabel subscribes the authenticated user to a label to receive +// notifications. If the user is already subscribed to the label, the status +// code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/labels/#subscribe-to-a-label +func (s *LabelsService) SubscribeToLabel(pid any, lid any, options ...RequestOptionFunc) (*Label, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/labels/%s/subscribe", PathEscape(project), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + l := new(Label) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// UnsubscribeFromLabel unsubscribes the authenticated user from a label to not +// receive notifications from it. If the user is not subscribed to the label, the +// status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/labels/#unsubscribe-from-a-label +func (s *LabelsService) UnsubscribeFromLabel(pid any, lid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/labels/%s/unsubscribe", PathEscape(project), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// PromoteLabel Promotes a project label to a group label. +// +// GitLab API docs: +// https://docs.gitlab.com/api/labels/#promote-a-project-label-to-a-group-label +func (s *LabelsService) PromoteLabel(pid any, lid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + label, err := parseID(lid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/labels/%s/promote", PathEscape(project), PathEscape(label)) + + req, err := s.client.NewRequest(http.MethodPut, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/github.com/xanzy/go-gitlab/license.go b/vendor/gitlab.com/gitlab-org/api/client-go/license.go similarity index 62% rename from vendor/github.com/xanzy/go-gitlab/license.go rename to vendor/gitlab.com/gitlab-org/api/client-go/license.go index c6deb44e3..9e9d2a068 100644 --- a/vendor/github.com/xanzy/go-gitlab/license.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/license.go @@ -1,5 +1,5 @@ // -// Copyright 2018, Patrick Webster +// Copyright 2021, Patrick Webster // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,21 +16,35 @@ package gitlab -import "time" +import ( + "fmt" + "net/http" + "time" +) -// LicenseService handles communication with the license -// related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/license.html -type LicenseService struct { - client *Client -} +type ( + LicenseServiceInterface interface { + GetLicense(options ...RequestOptionFunc) (*License, *Response, error) + AddLicense(opt *AddLicenseOptions, options ...RequestOptionFunc) (*License, *Response, error) + DeleteLicense(licenseID int, options ...RequestOptionFunc) (*Response, error) + } + + // LicenseService handles communication with the license + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/license/ + LicenseService struct { + client *Client + } +) + +var _ LicenseServiceInterface = (*LicenseService)(nil) // License represents a GitLab license. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/license.html +// https://docs.gitlab.com/api/license/ type License struct { ID int `json:"id"` Plan string `json:"plan"` @@ -66,9 +80,9 @@ func (l License) String() string { // GetLicense retrieves information about the current license. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/license.html#retrieve-information-about-the-current-license -func (s *LicenseService) GetLicense() (*License, *Response, error) { - req, err := s.client.NewRequest("GET", "license", nil, nil) +// https://docs.gitlab.com/api/license/#retrieve-information-about-the-current-license +func (s *LicenseService) GetLicense(options ...RequestOptionFunc) (*License, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "license", nil, options) if err != nil { return nil, nil, err } @@ -79,12 +93,12 @@ func (s *LicenseService) GetLicense() (*License, *Response, error) { return nil, resp, err } - return l, resp, err + return l, resp, nil } // AddLicenseOptions represents the available AddLicense() options. // -// https://docs.gitlab.com/ee/api/license.html#add-a-new-license +// https://docs.gitlab.com/api/license/#add-a-new-license type AddLicenseOptions struct { License *string `url:"license" json:"license"` } @@ -92,9 +106,9 @@ type AddLicenseOptions struct { // AddLicense adds a new license. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/license.html#add-a-new-license +// https://docs.gitlab.com/api/license/#add-a-new-license func (s *LicenseService) AddLicense(opt *AddLicenseOptions, options ...RequestOptionFunc) (*License, *Response, error) { - req, err := s.client.NewRequest("POST", "license", opt, options) + req, err := s.client.NewRequest(http.MethodPost, "license", opt, options) if err != nil { return nil, nil, err } @@ -105,5 +119,20 @@ func (s *LicenseService) AddLicense(opt *AddLicenseOptions, options ...RequestOp return nil, resp, err } - return l, resp, err + return l, resp, nil +} + +// DeleteLicense deletes an existing license. +// +// GitLab API docs: +// https://docs.gitlab.com/api/license/#delete-a-license +func (s *LicenseService) DeleteLicense(licenseID int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("license/%d", licenseID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) } diff --git a/vendor/github.com/xanzy/go-gitlab/license_templates.go b/vendor/gitlab.com/gitlab-org/api/client-go/license_templates.go similarity index 53% rename from vendor/github.com/xanzy/go-gitlab/license_templates.go rename to vendor/gitlab.com/gitlab-org/api/client-go/license_templates.go index 41dcdc3b4..8808f56b5 100644 --- a/vendor/github.com/xanzy/go-gitlab/license_templates.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/license_templates.go @@ -1,13 +1,30 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + package gitlab import ( "fmt" + "net/http" ) // LicenseTemplate represents a license template. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/licenses.html +// https://docs.gitlab.com/api/templates/licenses/ type LicenseTemplate struct { Key string `json:"key"` Name string `json:"name"` @@ -22,19 +39,28 @@ type LicenseTemplate struct { Content string `json:"content"` } -// LicenseTemplatesService handles communication with the license templates -// related methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/templates/licenses.html -type LicenseTemplatesService struct { - client *Client -} +type ( + LicenseTemplatesServiceInterface interface { + ListLicenseTemplates(opt *ListLicenseTemplatesOptions, options ...RequestOptionFunc) ([]*LicenseTemplate, *Response, error) + GetLicenseTemplate(template string, opt *GetLicenseTemplateOptions, options ...RequestOptionFunc) (*LicenseTemplate, *Response, error) + } + + // LicenseTemplatesService handles communication with the license templates + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/templates/licenses/ + LicenseTemplatesService struct { + client *Client + } +) + +var _ LicenseTemplatesServiceInterface = (*LicenseTemplatesService)(nil) // ListLicenseTemplatesOptions represents the available // ListLicenseTemplates() options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/licenses.html#list-license-templates +// https://docs.gitlab.com/api/templates/licenses/#list-license-templates type ListLicenseTemplatesOptions struct { ListOptions Popular *bool `url:"popular,omitempty" json:"popular,omitempty"` @@ -43,9 +69,9 @@ type ListLicenseTemplatesOptions struct { // ListLicenseTemplates get all license templates. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/licenses.html#list-license-templates +// https://docs.gitlab.com/api/templates/licenses/#list-license-templates func (s *LicenseTemplatesService) ListLicenseTemplates(opt *ListLicenseTemplatesOptions, options ...RequestOptionFunc) ([]*LicenseTemplate, *Response, error) { - req, err := s.client.NewRequest("GET", "templates/licenses", opt, options) + req, err := s.client.NewRequest(http.MethodGet, "templates/licenses", opt, options) if err != nil { return nil, nil, err } @@ -56,14 +82,14 @@ func (s *LicenseTemplatesService) ListLicenseTemplates(opt *ListLicenseTemplates return nil, resp, err } - return lts, resp, err + return lts, resp, nil } // GetLicenseTemplateOptions represents the available // GetLicenseTemplate() options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/licenses.html#single-license-template +// https://docs.gitlab.com/api/templates/licenses/#single-license-template type GetLicenseTemplateOptions struct { Project *string `url:"project,omitempty" json:"project,omitempty"` Fullname *string `url:"fullname,omitempty" json:"fullname,omitempty"` @@ -73,11 +99,11 @@ type GetLicenseTemplateOptions struct { // to replace the license placeholder. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/templates/licenses.html#single-license-template +// https://docs.gitlab.com/api/templates/licenses/#single-license-template func (s *LicenseTemplatesService) GetLicenseTemplate(template string, opt *GetLicenseTemplateOptions, options ...RequestOptionFunc) (*LicenseTemplate, *Response, error) { u := fmt.Sprintf("templates/licenses/%s", template) - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -88,5 +114,5 @@ func (s *LicenseTemplatesService) GetLicenseTemplate(template string, opt *GetLi return nil, resp, err } - return lt, resp, err + return lt, resp, nil } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/markdown.go b/vendor/gitlab.com/gitlab-org/api/client-go/markdown.go new file mode 100644 index 000000000..8e2e30f65 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/markdown.go @@ -0,0 +1,55 @@ +package gitlab + +import "net/http" + +type ( + MarkdownServiceInterface interface { + Render(opt *RenderOptions, options ...RequestOptionFunc) (*Markdown, *Response, error) + } + + // MarkdownService handles communication with the markdown related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/markdown/ + MarkdownService struct { + client *Client + } +) + +var _ MarkdownServiceInterface = (*MarkdownService)(nil) + +// Markdown represents a markdown document. +// +// Gitlab API docs: https://docs.gitlab.com/api/markdown/ +type Markdown struct { + HTML string `json:"html"` +} + +// RenderOptions represents the available Render() options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/markdown/#render-an-arbitrary-markdown-document +type RenderOptions struct { + Text *string `url:"text,omitempty" json:"text,omitempty"` + GitlabFlavouredMarkdown *bool `url:"gfm,omitempty" json:"gfm,omitempty"` + Project *string `url:"project,omitempty" json:"project,omitempty"` +} + +// Render an arbitrary markdown document. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/markdown/#render-an-arbitrary-markdown-document +func (s *MarkdownService) Render(opt *RenderOptions, options ...RequestOptionFunc) (*Markdown, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "markdown", opt, options) + if err != nil { + return nil, nil, err + } + + md := new(Markdown) + response, err := s.client.Do(req, md) + if err != nil { + return nil, response, err + } + + return md, response, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/markdown_uploads.go b/vendor/gitlab.com/gitlab-org/api/client-go/markdown_uploads.go new file mode 100644 index 000000000..37a6831c5 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/markdown_uploads.go @@ -0,0 +1,168 @@ +// +// Copyright 2024, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/http" + "time" +) + +// MarkdownUpload represents a single markdown upload. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/project_markdown_uploads/ +// https://docs.gitlab.com/api/group_markdown_uploads/ +type MarkdownUpload struct { + ID int `json:"id"` + Size int `json:"size"` + Filename string `json:"filename"` + CreatedAt *time.Time `json:"created_at"` + UploadedBy *User `json:"uploaded_by"` +} + +// Gets a string representation of a MarkdownUpload. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_markdown_uploads/ +// https://docs.gitlab.com/api/group_markdown_uploads/ +func (m MarkdownUpload) String() string { + return Stringify(m) +} + +// MarkdownUploadedFile represents a single markdown uploaded file. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/project_markdown_uploads/ +type MarkdownUploadedFile struct { + ID int `json:"id"` + Alt string `json:"alt"` + URL string `json:"url"` + FullPath string `json:"full_path"` + Markdown string `json:"markdown"` +} + +// ResourceType represents the type of resource (project or group) +type ResourceType string + +const ( + ProjectResource ResourceType = "projects" + GroupResource ResourceType = "groups" +) + +type ListMarkdownUploadsOptions struct { + ListOptions +} + +// listMarkdownUploads gets all markdown uploads for a resource +func listMarkdownUploads[T any](client *Client, resourceType ResourceType, id any, opt *ListMarkdownUploadsOptions, options []RequestOptionFunc) ([]*T, *Response, error) { + resourceID, err := parseID(id) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("%s/%s/uploads", resourceType, PathEscape(resourceID)) + + req, err := client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var uploads []*T + resp, err := client.Do(req, &uploads) + if err != nil { + return nil, resp, err + } + + return uploads, resp, err +} + +// downloadMarkdownUploadByID downloads a specific upload by ID +func downloadMarkdownUploadByID(client *Client, resourceType ResourceType, id any, uploadID int, options []RequestOptionFunc) (*bytes.Buffer, *Response, error) { + resourceID, err := parseID(id) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("%s/%s/uploads/%d", resourceType, PathEscape(resourceID), uploadID) + + req, err := client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var file bytes.Buffer + resp, err := client.Do(req, &file) + if err != nil { + return nil, resp, err + } + + return &file, resp, err +} + +// downloadMarkdownUploadBySecretAndFilename downloads a specific upload by secret and filename +func downloadMarkdownUploadBySecretAndFilename(client *Client, resourceType ResourceType, id any, secret string, filename string, options []RequestOptionFunc) (*bytes.Buffer, *Response, error) { + resourceID, err := parseID(id) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("%s/%s/uploads/%s/%s", resourceType, PathEscape(resourceID), PathEscape(secret), PathEscape(filename)) + + req, err := client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var file bytes.Buffer + resp, err := client.Do(req, &file) + if err != nil { + return nil, resp, err + } + + return &file, resp, err +} + +// deleteMarkdownUploadByID deletes an upload by ID +func deleteMarkdownUploadByID(client *Client, resourceType ResourceType, id any, uploadID int, options []RequestOptionFunc) (*Response, error) { + resourceID, err := parseID(id) + if err != nil { + return nil, err + } + u := fmt.Sprintf("%s/%s/uploads/%d", resourceType, PathEscape(resourceID), uploadID) + + req, err := client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return client.Do(req, nil) +} + +// deleteMarkdownUploadBySecretAndFilename deletes an upload by secret and filename +func deleteMarkdownUploadBySecretAndFilename(client *Client, resourceType ResourceType, id any, secret string, filename string, options []RequestOptionFunc) (*Response, error) { + resourceID, err := parseID(id) + if err != nil { + return nil, err + } + u := fmt.Sprintf("%s/%s/uploads/%s/%s", resourceType, PathEscape(resourceID), PathEscape(secret), PathEscape(filename)) + + req, err := client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/member_roles.go b/vendor/gitlab.com/gitlab-org/api/client-go/member_roles.go new file mode 100644 index 000000000..e9fede214 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/member_roles.go @@ -0,0 +1,215 @@ +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + MemberRolesServiceInterface interface { + ListInstanceMemberRoles(options ...RequestOptionFunc) ([]*MemberRole, *Response, error) + CreateInstanceMemberRole(opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) + DeleteInstanceMemberRole(memberRoleID int, options ...RequestOptionFunc) (*Response, error) + ListMemberRoles(gid any, options ...RequestOptionFunc) ([]*MemberRole, *Response, error) + CreateMemberRole(gid any, opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) + DeleteMemberRole(gid any, memberRole int, options ...RequestOptionFunc) (*Response, error) + } + + // MemberRolesService handles communication with the member roles related + // methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/member_roles/#list-all-member-roles-of-a-group + MemberRolesService struct { + client *Client + } +) + +var _ MemberRolesServiceInterface = (*MemberRolesService)(nil) + +// MemberRole represents a GitLab member role. +// +// GitLab API docs: +// https://docs.gitlab.com/api/member_roles/#list-all-member-roles-of-a-group +type MemberRole struct { + ID int `json:"id"` + Name string `json:"name"` + Description string `json:"description,omitempty"` + GroupID int `json:"group_id"` + BaseAccessLevel AccessLevelValue `json:"base_access_level"` + AdminCICDVariables bool `json:"admin_cicd_variables,omitempty"` + AdminComplianceFramework bool `json:"admin_compliance_framework,omitempty"` + AdminGroupMembers bool `json:"admin_group_member,omitempty"` + AdminMergeRequests bool `json:"admin_merge_request,omitempty"` + AdminPushRules bool `json:"admin_push_rules,omitempty"` + AdminTerraformState bool `json:"admin_terraform_state,omitempty"` + AdminVulnerability bool `json:"admin_vulnerability,omitempty"` + AdminWebHook bool `json:"admin_web_hook,omitempty"` + ArchiveProject bool `json:"archive_project,omitempty"` + ManageDeployTokens bool `json:"manage_deploy_tokens,omitempty"` + ManageGroupAccessTokens bool `json:"manage_group_access_tokens,omitempty"` + ManageMergeRequestSettings bool `json:"manage_merge_request_settings,omitempty"` + ManageProjectAccessTokens bool `json:"manage_project_access_tokens,omitempty"` + ManageSecurityPolicyLink bool `json:"manage_security_policy_link,omitempty"` + ReadCode bool `json:"read_code,omitempty"` + ReadRunners bool `json:"read_runners,omitempty"` + ReadDependency bool `json:"read_dependency,omitempty"` + ReadVulnerability bool `json:"read_vulnerability,omitempty"` + RemoveGroup bool `json:"remove_group,omitempty"` + RemoveProject bool `json:"remove_project,omitempty"` +} + +// ListInstanceMemberRoles gets all member roles in an instance. +// Authentication as Administrator is required. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#get-all-instance-member-roles +func (s *MemberRolesService) ListInstanceMemberRoles(options ...RequestOptionFunc) ([]*MemberRole, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "member_roles", nil, options) + if err != nil { + return nil, nil, err + } + + var mrs []*MemberRole + resp, err := s.client.Do(req, &mrs) + if err != nil { + return nil, resp, err + } + + return mrs, resp, nil +} + +// CreateMemberRoleOptions represents the available CreateInstanceMemberRole() +// and CreateMemberRole() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/member_roles/#create-a-instance-member-role +// https://docs.gitlab.com/api/member_roles/#add-a-member-role-to-a-group +type CreateMemberRoleOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + BaseAccessLevel *AccessLevelValue `url:"base_access_level,omitempty" json:"base_access_level,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + AdminCICDVariables *bool `url:"admin_cicd_variables" json:"admin_cicd_variables,omitempty"` + AdminComplianceFramework *bool `url:"admin_compliance_framework" json:"admin_compliance_framework,omitempty"` + AdminGroupMembers *bool `url:"admin_group_member" json:"admin_group_member,omitempty"` + AdminMergeRequest *bool `url:"admin_merge_request,omitempty" json:"admin_merge_request,omitempty"` + AdminPushRules *bool `url:"admin_push_rules" json:"admin_push_rules,omitempty"` + AdminTerraformState *bool `url:"admin_terraform_state" json:"admin_terraform_state,omitempty"` + AdminVulnerability *bool `url:"admin_vulnerability,omitempty" json:"admin_vulnerability,omitempty"` + AdminWebHook *bool `url:"admin_web_hook" json:"admin_web_hook,omitempty"` + ArchiveProject *bool `url:"archive_project" json:"archive_project,omitempty"` + ManageDeployTokens *bool `url:"manage_deploy_tokens" json:"manage_deploy_tokens,omitempty"` + ManageGroupAccessTokens *bool `url:"manage_group_access_tokens" json:"manage_group_access_tokens,omitempty"` + ManageMergeRequestSettings *bool `url:"manage_merge_request_settings" json:"manage_merge_request_settings,omitempty"` + ManageProjectAccessTokens *bool `url:"manage_project_access_tokens" json:"manage_project_access_tokens,omitempty"` + ManageSecurityPolicyLink *bool `url:"manage_security_policy_link" json:"manage_security_policy_link,omitempty"` + ReadCode *bool `url:"read_code,omitempty" json:"read_code,omitempty"` + ReadRunners *bool `url:"read_runners" json:"read_runners,omitempty"` + ReadDependency *bool `url:"read_dependency,omitempty" json:"read_dependency,omitempty"` + ReadVulnerability *bool `url:"read_vulnerability,omitempty" json:"read_vulnerability,omitempty"` + RemoveGroup *bool `url:"remove_group" json:"remove_group,omitempty"` + RemoveProject *bool `url:"remove_project" json:"remove_project,omitempty"` +} + +// CreateInstanceMemberRole creates an instance-wide member role. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#create-a-instance-member-role +func (s *MemberRolesService) CreateInstanceMemberRole(opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "member_roles", opt, options) + if err != nil { + return nil, nil, err + } + + mr := new(MemberRole) + resp, err := s.client.Do(req, mr) + if err != nil { + return nil, resp, err + } + + return mr, resp, nil +} + +// DeleteInstanceMemberRole deletes a member role from a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#delete-an-instance-member-role +func (s *MemberRolesService) DeleteInstanceMemberRole(memberRoleID int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("member_roles/%d", memberRoleID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListMemberRoles gets a list of member roles for a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#get-all-group-member-roles +func (s *MemberRolesService) ListMemberRoles(gid any, options ...RequestOptionFunc) ([]*MemberRole, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var mrs []*MemberRole + resp, err := s.client.Do(req, &mrs) + if err != nil { + return nil, resp, err + } + + return mrs, resp, nil +} + +// CreateMemberRole creates a new member role for a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#add-a-member-role-to-a-group +func (s *MemberRolesService) CreateMemberRole(gid any, opt *CreateMemberRoleOptions, options ...RequestOptionFunc) (*MemberRole, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/member_roles", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + mr := new(MemberRole) + resp, err := s.client.Do(req, mr) + if err != nil { + return nil, resp, err + } + + return mr, resp, nil +} + +// DeleteMemberRole deletes a member role from a specified group. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/member_roles/#remove-member-role-of-a-group +func (s *MemberRolesService) DeleteMemberRole(gid any, memberRole int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/member_roles/%d", PathEscape(group), memberRole) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approval_settings.go b/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approval_settings.go new file mode 100644 index 000000000..c1701be22 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approval_settings.go @@ -0,0 +1,185 @@ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + MergeRequestApprovalSettingsServiceInterface interface { + GetGroupMergeRequestApprovalSettings(gid any, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) + UpdateGroupMergeRequestApprovalSettings(gid any, opt *UpdateMergeRequestApprovalSettingsOptions, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) + GetProjectMergeRequestApprovalSettings(pid any, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) + UpdateProjectMergeRequestApprovalSettings(pid any, opt *UpdateMergeRequestApprovalSettingsOptions, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) + } + + // MergeRequestApprovalSettingsService handles communication with the merge + // requests approval settings related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/merge_request_approval_settings/ + MergeRequestApprovalSettingsService struct { + client *Client + } +) + +var _ MergeRequestApprovalSettingsServiceInterface = (*MergeRequestApprovalSettingsService)(nil) + +// MergeRequestApprovalSettings represents the merge request approval settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/ +type MergeRequestApprovalSettings struct { + AllowAuthorApproval MergeRequestApprovalSetting `json:"allow_author_approval"` + AllowCommitterApproval MergeRequestApprovalSetting `json:"allow_committer_approval"` + AllowOverridesToApproverListPerMergeRequest MergeRequestApprovalSetting `json:"allow_overrides_to_approver_list_per_merge_request"` + RetainApprovalsOnPush MergeRequestApprovalSetting `json:"retain_approvals_on_push"` + SelectiveCodeOwnerRemovals MergeRequestApprovalSetting `json:"selective_code_owner_removals"` + RequirePasswordToApprove MergeRequestApprovalSetting `json:"require_password_to_approve"` + RequireReauthenticationToApprove MergeRequestApprovalSetting `json:"require_reauthentication_to_approve"` +} + +// MergeRequestApprovalSetting represents an individual merge request approval +// setting. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/ +type MergeRequestApprovalSetting struct { + Value bool `json:"value"` + Locked bool `json:"locked"` + InheritedFrom string `json:"inherited_from"` +} + +// GetGroupMergeRequestApprovalSettings gets the merge request approval settings +// of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/#get-group-mr-approval-settings +func (s *MergeRequestApprovalSettingsService) GetGroupMergeRequestApprovalSettings(gid any, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/merge_request_approval_setting", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + settings := new(MergeRequestApprovalSettings) + resp, err := s.client.Do(req, settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, nil +} + +// UpdateMergeRequestApprovalSettingsOptions represents the available +// UpdateGroupMergeRequestApprovalSettings() and UpdateProjectMergeRequestApprovalSettings() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/#update-group-mr-approval-settings +// https://docs.gitlab.com/api/merge_request_approval_settings/#update-project-mr-approval-settings +type UpdateMergeRequestApprovalSettingsOptions struct { + AllowAuthorApproval *bool `url:"allow_author_approval,omitempty" json:"allow_author_approval,omitempty"` + AllowCommitterApproval *bool `url:"allow_committer_approval,omitempty" json:"allow_committer_approval,omitempty"` + AllowOverridesToApproverListPerMergeRequest *bool `url:"allow_overrides_to_approver_list_per_merge_request,omitempty" json:"allow_overrides_to_approver_list_per_merge_request,omitempty"` + RetainApprovalsOnPush *bool `url:"retain_approvals_on_push,omitempty" json:"retain_approvals_on_push,omitempty"` + SelectiveCodeOwnerRemovals *bool `url:"selective_code_owner_removals,omitempty" json:"selective_code_owner_removals,omitempty"` + RequireReauthenticationToApprove *bool `url:"require_reauthentication_to_approve,omitempty" json:"require_reauthentication_to_approve,omitempty"` +} + +// UpdateGroupMergeRequestApprovalSettings updates the merge request approval +// settings of a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/#update-group-mr-approval-settings +func (s *MergeRequestApprovalSettingsService) UpdateGroupMergeRequestApprovalSettings(gid any, opt *UpdateMergeRequestApprovalSettingsOptions, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/merge_request_approval_setting", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + settings := new(MergeRequestApprovalSettings) + resp, err := s.client.Do(req, settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, nil +} + +// GetProjectMergeRequestApprovalSettings gets the merge request approval settings +// of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/#get-project-mr-approval-settings +func (s *MergeRequestApprovalSettingsService) GetProjectMergeRequestApprovalSettings(pid any, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_request_approval_setting", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + settings := new(MergeRequestApprovalSettings) + resp, err := s.client.Do(req, settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, nil +} + +// UpdateProjectMergeRequestApprovalSettings updates the merge request approval +// settings of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approval_settings/#update-project-mr-approval-settings +func (s *MergeRequestApprovalSettingsService) UpdateProjectMergeRequestApprovalSettings(pid any, opt *UpdateMergeRequestApprovalSettingsOptions, options ...RequestOptionFunc) (*MergeRequestApprovalSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_request_approval_setting", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + settings := new(MergeRequestApprovalSettings) + resp, err := s.client.Do(req, settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approvals.go b/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approvals.go new file mode 100644 index 000000000..80d16bec6 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/merge_request_approvals.go @@ -0,0 +1,420 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + MergeRequestApprovalsServiceInterface interface { + ApproveMergeRequest(pid any, mr int, opt *ApproveMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) + UnapproveMergeRequest(pid any, mr int, options ...RequestOptionFunc) (*Response, error) + ResetApprovalsOfMergeRequest(pid any, mr int, options ...RequestOptionFunc) (*Response, error) + GetConfiguration(pid any, mr int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) + ChangeApprovalConfiguration(pid any, mergeRequest int, opt *ChangeMergeRequestApprovalConfigurationOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + GetApprovalRules(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestApprovalRule, *Response, error) + GetApprovalState(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovalState, *Response, error) + CreateApprovalRule(pid any, mergeRequest int, opt *CreateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) + UpdateApprovalRule(pid any, mergeRequest int, approvalRule int, opt *UpdateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) + DeleteApprovalRule(pid any, mergeRequest int, approvalRule int, options ...RequestOptionFunc) (*Response, error) + } + + // MergeRequestApprovalsService handles communication with the merge request + // approvals related methods of the GitLab API. This includes reading/updating + // approval settings and approve/unapproving merge requests + // + // GitLab API docs: https://docs.gitlab.com/api/merge_request_approvals/ + MergeRequestApprovalsService struct { + client *Client + } +) + +var _ MergeRequestApprovalsServiceInterface = (*MergeRequestApprovalsService)(nil) + +// MergeRequestApprovals represents GitLab merge request approvals. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#single-merge-request-approval +type MergeRequestApprovals struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + MergeStatus string `json:"merge_status"` + Approved bool `json:"approved"` + ApprovalsBeforeMerge int `json:"approvals_before_merge"` + ApprovalsRequired int `json:"approvals_required"` + ApprovalsLeft int `json:"approvals_left"` + RequirePasswordToApprove bool `json:"require_password_to_approve"` + ApprovedBy []*MergeRequestApproverUser `json:"approved_by"` + SuggestedApprovers []*BasicUser `json:"suggested_approvers"` + Approvers []*MergeRequestApproverUser `json:"approvers"` + ApproverGroups []*MergeRequestApproverGroup `json:"approver_groups"` + UserHasApproved bool `json:"user_has_approved"` + UserCanApprove bool `json:"user_can_approve"` + ApprovalRulesLeft []*MergeRequestApprovalRule `json:"approval_rules_left"` + HasApprovalRules bool `json:"has_approval_rules"` + MergeRequestApproversAvailable bool `json:"merge_request_approvers_available"` + MultipleApprovalRulesAvailable bool `json:"multiple_approval_rules_available"` +} + +func (m MergeRequestApprovals) String() string { + return Stringify(m) +} + +// MergeRequestApproverGroup represents GitLab project level merge request approver group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#project-approval-rules +type MergeRequestApproverGroup struct { + Group struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Description string `json:"description"` + Visibility string `json:"visibility"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + FullName string `json:"full_name"` + FullPath string `json:"full_path"` + LFSEnabled bool `json:"lfs_enabled"` + RequestAccessEnabled bool `json:"request_access_enabled"` + } +} + +// MergeRequestApprovalRule represents a GitLab merge request approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-merge-request-approval-rules +type MergeRequestApprovalRule struct { + ID int `json:"id"` + Name string `json:"name"` + RuleType string `json:"rule_type"` + ReportType string `json:"report_type"` + EligibleApprovers []*BasicUser `json:"eligible_approvers"` + ApprovalsRequired int `json:"approvals_required"` + SourceRule *ProjectApprovalRule `json:"source_rule"` + Users []*BasicUser `json:"users"` + Groups []*Group `json:"groups"` + ContainsHiddenGroups bool `json:"contains_hidden_groups"` + Section string `json:"section"` + ApprovedBy []*BasicUser `json:"approved_by"` + Approved bool `json:"approved"` +} + +// MergeRequestApprovalState represents a GitLab merge request approval state. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-the-approval-state-of-merge-requests +type MergeRequestApprovalState struct { + ApprovalRulesOverwritten bool `json:"approval_rules_overwritten"` + Rules []*MergeRequestApprovalRule `json:"rules"` +} + +// String is a stringify for MergeRequestApprovalRule +func (s MergeRequestApprovalRule) String() string { + return Stringify(s) +} + +// MergeRequestApproverUser represents GitLab project level merge request approver user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#project-approval-rules +type MergeRequestApproverUser struct { + User *BasicUser +} + +// ApproveMergeRequestOptions represents the available ApproveMergeRequest() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#approve-merge-request +type ApproveMergeRequestOptions struct { + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` +} + +// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha +// is provided then it must match the sha at the HEAD of the MR. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#approve-merge-request +func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid any, mr int, opt *ApproveMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", PathEscape(project), mr) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequestApprovals) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// UnapproveMergeRequest unapproves a previously approved merge request on GitLab. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#unapprove-merge-request +func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid any, mr int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", PathEscape(project), mr) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ResetApprovalsOfMergeRequest clear all approvals of merge request on GitLab. +// Available only for bot users based on project or group tokens. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#reset-approvals-of-a-merge-request +func (s *MergeRequestApprovalsService) ResetApprovalsOfMergeRequest(pid any, mr int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/reset_approvals", PathEscape(project), mr) + + req, err := s.client.NewRequest(http.MethodPut, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GetConfiguration shows information about single merge request approvals +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#single-merge-request-approval +func (s *MergeRequestApprovalsService) GetConfiguration(pid any, mr int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", PathEscape(project), mr) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequestApprovals) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ChangeMergeRequestApprovalConfigurationOptions represents the available +// ChangeMergeRequestApprovalConfiguration() options. +// +// Deprecated: in GitLab 16.0 +type ChangeMergeRequestApprovalConfigurationOptions struct { + ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` +} + +// ChangeApprovalConfiguration updates the approval configuration of a merge request. +// +// Deprecated: in GitLab 16.0 +func (s *MergeRequestApprovalsService) ChangeApprovalConfiguration(pid any, mergeRequest int, opt *ChangeMergeRequestApprovalConfigurationOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// GetApprovalRules requests information about a merge request’s approval rules +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-merge-request-approval-rules +func (s *MergeRequestApprovalsService) GetApprovalRules(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var par []*MergeRequestApprovalRule + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// GetApprovalState requests information about a merge request’s approval state +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-the-approval-state-of-merge-requests +func (s *MergeRequestApprovalsService) GetApprovalState(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovalState, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_state", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var pas *MergeRequestApprovalState + resp, err := s.client.Do(req, &pas) + if err != nil { + return nil, resp, err + } + + return pas, resp, nil +} + +// CreateMergeRequestApprovalRuleOptions represents the available CreateApprovalRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#create-merge-request-rule +type CreateMergeRequestApprovalRuleOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` + ApprovalProjectRuleID *int `url:"approval_project_rule_id,omitempty" json:"approval_project_rule_id,omitempty"` + UserIDs *[]int `url:"user_ids,omitempty" json:"user_ids,omitempty"` + GroupIDs *[]int `url:"group_ids,omitempty" json:"group_ids,omitempty"` +} + +// CreateApprovalRule creates a new MR level approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#create-merge-request-rule +func (s *MergeRequestApprovalsService) CreateApprovalRule(pid any, mergeRequest int, opt *CreateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + par := new(MergeRequestApprovalRule) + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// UpdateMergeRequestApprovalRuleOptions represents the available UpdateApprovalRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#update-merge-request-rule +type UpdateMergeRequestApprovalRuleOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` + UserIDs *[]int `url:"user_ids,omitempty" json:"user_ids,omitempty"` + GroupIDs *[]int `url:"group_ids,omitempty" json:"group_ids,omitempty"` +} + +// UpdateApprovalRule updates an existing approval rule with new options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#update-merge-request-rule +func (s *MergeRequestApprovalsService) UpdateApprovalRule(pid any, mergeRequest int, approvalRule int, opt *UpdateMergeRequestApprovalRuleOptions, options ...RequestOptionFunc) (*MergeRequestApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules/%d", PathEscape(project), mergeRequest, approvalRule) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + par := new(MergeRequestApprovalRule) + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// DeleteApprovalRule deletes a mr level approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#delete-merge-request-rule +func (s *MergeRequestApprovalsService) DeleteApprovalRule(pid any, mergeRequest int, approvalRule int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approval_rules/%d", PathEscape(project), mergeRequest, approvalRule) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/merge_requests.go b/vendor/gitlab.com/gitlab-org/api/client-go/merge_requests.go new file mode 100644 index 000000000..8aa69f3ee --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/merge_requests.go @@ -0,0 +1,1373 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "time" +) + +type ( + MergeRequestsServiceInterface interface { + ListMergeRequests(opt *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + ListProjectMergeRequests(pid any, opt *ListProjectMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + ListGroupMergeRequests(gid any, opt *ListGroupMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + GetMergeRequest(pid any, mergeRequest int, opt *GetMergeRequestsOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + GetMergeRequestApprovals(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) + GetMergeRequestCommits(pid any, mergeRequest int, opt *GetMergeRequestCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) + GetMergeRequestChanges(pid any, mergeRequest int, opt *GetMergeRequestChangesOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + ListMergeRequestDiffs(pid any, mergeRequest int, opt *ListMergeRequestDiffsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiff, *Response, error) + ShowMergeRequestRawDiffs(pid any, mergeRequest int, opt *ShowMergeRequestRawDiffsOptions, options ...RequestOptionFunc) ([]byte, *Response, error) + GetMergeRequestParticipants(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) + GetMergeRequestReviewers(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestReviewer, *Response, error) + ListMergeRequestPipelines(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) + CreateMergeRequestPipeline(pid any, mergeRequest int, options ...RequestOptionFunc) (*PipelineInfo, *Response, error) + GetIssuesClosedOnMerge(pid any, mergeRequest int, opt *GetIssuesClosedOnMergeOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + ListRelatedIssues(pid any, mergeRequest int, opt *ListRelatedIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + CreateMergeRequest(pid any, opt *CreateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + UpdateMergeRequest(pid any, mergeRequest int, opt *UpdateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + DeleteMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*Response, error) + AcceptMergeRequest(pid any, mergeRequest int, opt *AcceptMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + CancelMergeWhenPipelineSucceeds(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + RebaseMergeRequest(pid any, mergeRequest int, opt *RebaseMergeRequestOptions, options ...RequestOptionFunc) (*Response, error) + GetMergeRequestDiffVersions(pid any, mergeRequest int, opt *GetMergeRequestDiffVersionsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiffVersion, *Response, error) + GetSingleMergeRequestDiffVersion(pid any, mergeRequest, version int, opt *GetSingleMergeRequestDiffVersionOptions, options ...RequestOptionFunc) (*MergeRequestDiffVersion, *Response, error) + SubscribeToMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + UnsubscribeFromMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) + CreateTodo(pid any, mergeRequest int, options ...RequestOptionFunc) (*Todo, *Response, error) + SetTimeEstimate(pid any, mergeRequest int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) + ResetTimeEstimate(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + AddSpentTime(pid any, mergeRequest int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) + ResetSpentTime(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + GetTimeSpent(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) + CreateMergeRequestDependency(pid any, mergeRequest int, opts CreateMergeRequestDependencyOptions, options ...RequestOptionFunc) (*MergeRequestDependency, *Response, error) + DeleteMergeRequestDependency(pid any, mergeRequest int, blockingMergeRequest int, options ...RequestOptionFunc) (*Response, error) + GetMergeRequestDependencies(pid any, mergeRequest int, options ...RequestOptionFunc) ([]MergeRequestDependency, *Response, error) + } + + // MergeRequestsService handles communication with the merge requests related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/merge_requests/ + MergeRequestsService struct { + client *Client + timeStats *timeStatsService + } +) + +var _ MergeRequestsServiceInterface = (*MergeRequestsService)(nil) + +// BasicMergeRequest represents a basic GitLab merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/ +type BasicMergeRequest struct { + ID int `json:"id"` + IID int `json:"iid"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + State string `json:"state"` + Imported bool `json:"imported"` + ImportedFrom string `json:"imported_from"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Upvotes int `json:"upvotes"` + Downvotes int `json:"downvotes"` + Author *BasicUser `json:"author"` + Assignee *BasicUser `json:"assignee"` + Assignees []*BasicUser `json:"assignees"` + Reviewers []*BasicUser `json:"reviewers"` + SourceProjectID int `json:"source_project_id"` + TargetProjectID int `json:"target_project_id"` + Labels Labels `json:"labels"` + LabelDetails []*LabelDetails `json:"label_details"` + Description string `json:"description"` + Draft bool `json:"draft"` + Milestone *Milestone `json:"milestone"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + DetailedMergeStatus string `json:"detailed_merge_status"` + MergeUser *BasicUser `json:"merge_user"` + MergedAt *time.Time `json:"merged_at"` + MergeAfter *time.Time `json:"merge_after"` + PreparedAt *time.Time `json:"prepared_at"` + ClosedBy *BasicUser `json:"closed_by"` + ClosedAt *time.Time `json:"closed_at"` + SHA string `json:"sha"` + MergeCommitSHA string `json:"merge_commit_sha"` + SquashCommitSHA string `json:"squash_commit_sha"` + UserNotesCount int `json:"user_notes_count"` + ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"` + ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` + AllowCollaboration bool `json:"allow_collaboration"` + AllowMaintainerToPush bool `json:"allow_maintainer_to_push"` + WebURL string `json:"web_url"` + References *IssueReferences `json:"references"` + DiscussionLocked bool `json:"discussion_locked"` + TimeStats *TimeStats `json:"time_stats"` + Squash bool `json:"squash"` + SquashOnMerge bool `json:"squash_on_merge"` + TaskCompletionStatus *TasksCompletionStatus `json:"task_completion_status"` + HasConflicts bool `json:"has_conflicts"` + BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` + + // Deprecated: will be removed in v5 of the API, use MergeUser instead + MergedBy *BasicUser `json:"merged_by"` +} + +func (m BasicMergeRequest) String() string { + return Stringify(m) +} + +// MergeRequest represents a GitLab merge request. +// +// GitLab API docs: https://docs.gitlab.com/api/merge_requests/ +type MergeRequest struct { + BasicMergeRequest + MergeError string `json:"merge_error"` + Subscribed bool `json:"subscribed"` + ChangesCount string `json:"changes_count"` + User struct { + CanMerge bool `json:"can_merge"` + } `json:"user"` + LatestBuildStartedAt *time.Time `json:"latest_build_started_at"` + LatestBuildFinishedAt *time.Time `json:"latest_build_finished_at"` + FirstDeployedToProductionAt *time.Time `json:"first_deployed_to_production_at"` + Pipeline *PipelineInfo `json:"pipeline"` + HeadPipeline *Pipeline `json:"head_pipeline"` + DiffRefs struct { + BaseSha string `json:"base_sha"` + HeadSha string `json:"head_sha"` + StartSha string `json:"start_sha"` + } `json:"diff_refs"` + RebaseInProgress bool `json:"rebase_in_progress"` + DivergedCommitsCount int `json:"diverged_commits_count"` + FirstContribution bool `json:"first_contribution"` + + // Deprecated: use Draft instead + WorkInProgress bool `json:"work_in_progress"` +} + +func (m MergeRequest) String() string { + return Stringify(m) +} + +func (m *MergeRequest) UnmarshalJSON(data []byte) error { + type alias MergeRequest + + raw := make(map[string]any) + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + labelDetails, ok := raw["labels"].([]any) + if ok && len(labelDetails) > 0 { + // We only want to change anything if we got label details. + if _, ok := labelDetails[0].(map[string]any); !ok { + return json.Unmarshal(data, (*alias)(m)) + } + + labels := make([]any, len(labelDetails)) + for i, details := range labelDetails { + labels[i] = details.(map[string]any)["name"] + } + + // Set the correct values + raw["labels"] = labels + raw["label_details"] = labelDetails + + data, err = json.Marshal(raw) + if err != nil { + return err + } + } + + return json.Unmarshal(data, (*alias)(m)) +} + +// MergeRequestDiff represents Gitlab merge request diff. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-request-diffs +type MergeRequestDiff struct { + OldPath string `json:"old_path"` + NewPath string `json:"new_path"` + AMode string `json:"a_mode"` + BMode string `json:"b_mode"` + Diff string `json:"diff"` + NewFile bool `json:"new_file"` + RenamedFile bool `json:"renamed_file"` + DeletedFile bool `json:"deleted_file"` +} + +// MergeRequestDiffVersion represents Gitlab merge request version. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-merge-request-diff-versions +type MergeRequestDiffVersion struct { + ID int `json:"id"` + HeadCommitSHA string `json:"head_commit_sha,omitempty"` + BaseCommitSHA string `json:"base_commit_sha,omitempty"` + StartCommitSHA string `json:"start_commit_sha,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + MergeRequestID int `json:"merge_request_id,omitempty"` + State string `json:"state,omitempty"` + RealSize string `json:"real_size,omitempty"` + Commits []*Commit `json:"commits,omitempty"` + Diffs []*Diff `json:"diffs,omitempty"` +} + +func (m MergeRequestDiffVersion) String() string { + return Stringify(m) +} + +// ListMergeRequestsOptions represents the available ListMergeRequests() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-requests +type ListMergeRequestsOptions struct { + ListOptions + Approved *string `url:"approved,omitempty" json:"approved,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + View *string `url:"view,omitempty" json:"view,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + AssigneeID *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + ApproverIDs *ApproverIDsValue `url:"approver_ids,omitempty" json:"approver_ids,omitempty"` + ApprovedByIDs *ApproverIDsValue `url:"approved_by_ids,omitempty" json:"approved_by_ids,omitempty"` + ReviewerID *ReviewerIDValue `url:"reviewer_id,omitempty" json:"reviewer_id,omitempty"` + ReviewerUsername *string `url:"reviewer_username,omitempty" json:"reviewer_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` + TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + Draft *bool `url:"draft,omitempty" json:"draft,omitempty"` + WIP *string `url:"wip,omitempty" json:"wip,omitempty"` +} + +// ListMergeRequests gets all merge requests. The state parameter can be used +// to get only merge requests with a given state (opened, closed, or merged) +// or all of them (all). The pagination parameters page and per_page can be +// used to restrict the list of merge requests. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-requests +func (s *MergeRequestsService) ListMergeRequests(opt *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "merge_requests", opt, options) + if err != nil { + return nil, nil, err + } + + var m []*BasicMergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ListProjectMergeRequestsOptions represents the available ListMergeRequests() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-project-merge-requests +type ListProjectMergeRequestsOptions struct { + ListOptions + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + View *string `url:"view,omitempty" json:"view,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + AssigneeID *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + ApproverIDs *ApproverIDsValue `url:"approver_ids,omitempty" json:"approver_ids,omitempty"` + ApprovedByIDs *ApproverIDsValue `url:"approved_by_ids,omitempty" json:"approved_by_ids,omitempty"` + ReviewerID *ReviewerIDValue `url:"reviewer_id,omitempty" json:"reviewer_id,omitempty"` + ReviewerUsername *string `url:"reviewer_username,omitempty" json:"reviewer_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` + TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Draft *bool `url:"draft,omitempty" json:"draft,omitempty"` + WIP *string `url:"wip,omitempty" json:"wip,omitempty"` +} + +// ListProjectMergeRequests gets all merge requests for this project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-project-merge-requests +func (s *MergeRequestsService) ListProjectMergeRequests(pid any, opt *ListProjectMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*BasicMergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ListGroupMergeRequestsOptions represents the available ListGroupMergeRequests() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-group-merge-requests +type ListGroupMergeRequestsOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"` + View *string `url:"view,omitempty" json:"view,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + NotLabels *LabelOptions `url:"not[labels],comma,omitempty" json:"not[labels],omitempty"` + WithLabelsDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"` + WithMergeStatusRecheck *bool `url:"with_merge_status_recheck,omitempty" json:"with_merge_status_recheck,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + AuthorUsername *string `url:"author_username,omitempty" json:"author_username,omitempty"` + NotAuthorUsername *string `url:"not[author_username],omitempty" json:"not[author_username],omitempty"` + AssigneeID *AssigneeIDValue `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + ApproverIDs *ApproverIDsValue `url:"approver_ids,omitempty" json:"approver_ids,omitempty"` + ApprovedByIDs *ApproverIDsValue `url:"approved_by_ids,omitempty" json:"approved_by_ids,omitempty"` + ReviewerID *ReviewerIDValue `url:"reviewer_id,omitempty" json:"reviewer_id,omitempty"` + ReviewerUsername *string `url:"reviewer_username,omitempty" json:"reviewer_username,omitempty"` + MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"` + SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` + TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + In *string `url:"in,omitempty" json:"in,omitempty"` + Draft *bool `url:"draft,omitempty" json:"draft,omitempty"` + WIP *string `url:"wip,omitempty" json:"wip,omitempty"` +} + +// ListGroupMergeRequests gets all merge requests for this group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-group-merge-requests +func (s *MergeRequestsService) ListGroupMergeRequests(gid any, opt *ListGroupMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/merge_requests", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*BasicMergeRequest + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// GetMergeRequestsOptions represents the available GetMergeRequests() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-mr +type GetMergeRequestsOptions struct { + RenderHTML *bool `url:"render_html,omitempty" json:"render_html,omitempty"` + IncludeDivergedCommitsCount *bool `url:"include_diverged_commits_count,omitempty" json:"include_diverged_commits_count,omitempty"` + IncludeRebaseInProgress *bool `url:"include_rebase_in_progress,omitempty" json:"include_rebase_in_progress,omitempty"` +} + +// GetMergeRequest shows information about a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-mr +func (s *MergeRequestsService) GetMergeRequest(pid any, mergeRequest int, opt *GetMergeRequestsOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// GetMergeRequestApprovals gets information about a merge requests approvals +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#single-merge-request-approval +func (s *MergeRequestsService) GetMergeRequestApprovals(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequestApprovals, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + a := new(MergeRequestApprovals) + resp, err := s.client.Do(req, a) + if err != nil { + return nil, resp, err + } + + return a, resp, nil +} + +// GetMergeRequestCommitsOptions represents the available GetMergeRequestCommits() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-commits +type GetMergeRequestCommitsOptions ListOptions + +// GetMergeRequestCommits gets a list of merge request commits. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-commits +func (s *MergeRequestsService) GetMergeRequestCommits(pid any, mergeRequest int, opt *GetMergeRequestCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/commits", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var c []*Commit + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// GetMergeRequestChangesOptions represents the available GetMergeRequestChanges() +// options. +// Deprecated: This endpoint has been replaced by +// MergeRequestsService.ListMergeRequestDiffs() +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-changes +type GetMergeRequestChangesOptions struct { + AccessRawDiffs *bool `url:"access_raw_diffs,omitempty" json:"access_raw_diffs,omitempty"` + Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` +} + +// GetMergeRequestChanges shows information about the merge request including +// its files and changes. +// +// Deprecated: This endpoint has been replaced by +// MergeRequestsService.ListMergeRequestDiffs() +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-changes +func (s *MergeRequestsService) GetMergeRequestChanges(pid any, mergeRequest int, opt *GetMergeRequestChangesOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/changes", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ListMergeRequestDiffsOptions represents the available ListMergeRequestDiffs() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-request-diffs +type ListMergeRequestDiffsOptions struct { + ListOptions + Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` +} + +// ListMergeRequestDiffs List diffs of the files changed in a merge request +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-request-diffs +func (s *MergeRequestsService) ListMergeRequestDiffs(pid any, mergeRequest int, opt *ListMergeRequestDiffsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiff, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/diffs", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*MergeRequestDiff + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// ShowMergeRequestRawDiffsOptions represents the available ShowMergeRequestRawDiffs() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#show-merge-request-raw-diffs +type ShowMergeRequestRawDiffsOptions struct{} + +// ShowMergeRequestRawDiffs Show raw diffs of the files changed in a merge request +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#show-merge-request-raw-diffs +func (s *MergeRequestsService) ShowMergeRequestRawDiffs(pid any, mergeRequest int, opt *ShowMergeRequestRawDiffsOptions, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return []byte{}, nil, err + } + u := fmt.Sprintf( + "projects/%s/merge_requests/%d/raw_diffs", + PathEscape(project), + mergeRequest, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return []byte{}, nil, err + } + + var rd bytes.Buffer + resp, err := s.client.Do(req, &rd) + if err != nil { + return []byte{}, resp, err + } + + return rd.Bytes(), resp, nil +} + +// GetMergeRequestParticipants gets a list of merge request participants. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-participants +func (s *MergeRequestsService) GetMergeRequestParticipants(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*BasicUser, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/participants", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var bu []*BasicUser + resp, err := s.client.Do(req, &bu) + if err != nil { + return nil, resp, err + } + + return bu, resp, nil +} + +// MergeRequestReviewer represents a GitLab merge request reviewer. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-reviewers +type MergeRequestReviewer struct { + User *BasicUser `json:"user"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` +} + +// GetMergeRequestReviewers gets a list of merge request reviewers. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-single-merge-request-reviewers +func (s *MergeRequestsService) GetMergeRequestReviewers(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*MergeRequestReviewer, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/reviewers", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var mrr []*MergeRequestReviewer + resp, err := s.client.Do(req, &mrr) + if err != nil { + return nil, resp, err + } + + return mrr, resp, nil +} + +// ListMergeRequestPipelines gets all pipelines for the provided merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-merge-request-pipelines +func (s *MergeRequestsService) ListMergeRequestPipelines(pid any, mergeRequest int, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/pipelines", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var p []*PipelineInfo + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreateMergeRequestPipeline creates a new pipeline for a merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-merge-request-pipeline +func (s *MergeRequestsService) CreateMergeRequestPipeline(pid any, mergeRequest int, options ...RequestOptionFunc) (*PipelineInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/pipelines", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineInfo) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetIssuesClosedOnMergeOptions represents the available GetIssuesClosedOnMerge() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-issues-that-close-on-merge +type GetIssuesClosedOnMergeOptions ListOptions + +// GetIssuesClosedOnMerge gets all the issues that would be closed by merging the +// provided merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-issues-that-close-on-merge +func (s *MergeRequestsService) GetIssuesClosedOnMerge(pid any, mergeRequest int, opt *GetIssuesClosedOnMergeOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/closes_issues", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// ListRelatedIssuesOptions represents the available ListRelatedIssues() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-issues-related-to-the-merge-request +type ListRelatedIssuesOptions ListOptions + +// ListRelatedIssues gets all the issues related to provided merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#list-issues-related-to-the-merge-request +func (s *MergeRequestsService) ListRelatedIssues(pid any, mergeRequest int, opt *ListRelatedIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + + u := fmt.Sprintf("projects/%s/merge_requests/%d/related_issues", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// CreateMergeRequestOptions represents the available CreateMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-mr +type CreateMergeRequestOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"` + TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + AssigneeIDs *[]int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` + ReviewerIDs *[]int `url:"reviewer_ids,omitempty" json:"reviewer_ids,omitempty"` + TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + RemoveSourceBranch *bool `url:"remove_source_branch,omitempty" json:"remove_source_branch,omitempty"` + Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` + AllowCollaboration *bool `url:"allow_collaboration,omitempty" json:"allow_collaboration,omitempty"` + + // Deprecated: will be removed in v5 of the API, use the Merge Request Approvals API instead + ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` +} + +// CreateMergeRequest creates a new merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-mr +func (s *MergeRequestsService) CreateMergeRequest(pid any, opt *CreateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// UpdateMergeRequestOptions represents the available UpdateMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#update-mr +type UpdateMergeRequestOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"` + AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"` + AssigneeIDs *[]int `url:"assignee_ids,omitempty" json:"assignee_ids,omitempty"` + ReviewerIDs *[]int `url:"reviewer_ids,omitempty" json:"reviewer_ids,omitempty"` + Labels *LabelOptions `url:"labels,comma,omitempty" json:"labels,omitempty"` + AddLabels *LabelOptions `url:"add_labels,comma,omitempty" json:"add_labels,omitempty"` + RemoveLabels *LabelOptions `url:"remove_labels,comma,omitempty" json:"remove_labels,omitempty"` + MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` + RemoveSourceBranch *bool `url:"remove_source_branch,omitempty" json:"remove_source_branch,omitempty"` + Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` + DiscussionLocked *bool `url:"discussion_locked,omitempty" json:"discussion_locked,omitempty"` + AllowCollaboration *bool `url:"allow_collaboration,omitempty" json:"allow_collaboration,omitempty"` +} + +// UpdateMergeRequest updates an existing project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#update-mr +func (s *MergeRequestsService) UpdateMergeRequest(pid any, mergeRequest int, opt *UpdateMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteMergeRequest deletes a merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#delete-a-merge-request +func (s *MergeRequestsService) DeleteMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// AcceptMergeRequestOptions represents the available AcceptMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#merge-a-merge-request +type AcceptMergeRequestOptions struct { + MergeCommitMessage *string `url:"merge_commit_message,omitempty" json:"merge_commit_message,omitempty"` + SquashCommitMessage *string `url:"squash_commit_message,omitempty" json:"squash_commit_message,omitempty"` + Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` + ShouldRemoveSourceBranch *bool `url:"should_remove_source_branch,omitempty" json:"should_remove_source_branch,omitempty"` + MergeWhenPipelineSucceeds *bool `url:"merge_when_pipeline_succeeds,omitempty" json:"merge_when_pipeline_succeeds,omitempty"` + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` +} + +// AcceptMergeRequest merges changes submitted with MR using this API. If merge +// success you get 200 OK. If it has some conflicts and can not be merged - you +// get 405 and error message 'Branch cannot be merged'. If merge request is +// already merged or closed - you get 405 and error message 'Method Not Allowed' +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#merge-a-merge-request +func (s *MergeRequestsService) AcceptMergeRequest(pid any, mergeRequest int, opt *AcceptMergeRequestOptions, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/merge", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CancelMergeWhenPipelineSucceeds cancels a merge when pipeline succeeds. If +// you don't have permissions to accept this merge request - you'll get a 401. +// If the merge request is already merged or closed - you get 405 and error +// message 'Method Not Allowed'. In case the merge request is not set to be +// merged when the pipeline succeeds, you'll also get a 406 error. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#cancel-merge-when-pipeline-succeeds +func (s *MergeRequestsService) CancelMergeWhenPipelineSucceeds(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/cancel_merge_when_pipeline_succeeds", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// RebaseMergeRequestOptions represents the available RebaseMergeRequest() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#rebase-a-merge-request +type RebaseMergeRequestOptions struct { + SkipCI *bool `url:"skip_ci,omitempty" json:"skip_ci,omitempty"` +} + +// RebaseMergeRequest automatically rebases the source_branch of the merge +// request against its target_branch. If you don’t have permissions to push +// to the merge request’s source branch, you’ll get a 403 Forbidden response. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#rebase-a-merge-request +func (s *MergeRequestsService) RebaseMergeRequest(pid any, mergeRequest int, opt *RebaseMergeRequestOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/rebase", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GetMergeRequestDiffVersionsOptions represents the available +// GetMergeRequestDiffVersions() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-merge-request-diff-versions +type GetMergeRequestDiffVersionsOptions ListOptions + +// GetMergeRequestDiffVersions get a list of merge request diff versions. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-merge-request-diff-versions +func (s *MergeRequestsService) GetMergeRequestDiffVersions(pid any, mergeRequest int, opt *GetMergeRequestDiffVersionsOptions, options ...RequestOptionFunc) ([]*MergeRequestDiffVersion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/versions", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var v []*MergeRequestDiffVersion + resp, err := s.client.Do(req, &v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// GetSingleMergeRequestDiffVersionOptions represents the available +// GetSingleMergeRequestDiffVersion() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-a-single-merge-request-diff-version +type GetSingleMergeRequestDiffVersionOptions struct { + Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` +} + +// GetSingleMergeRequestDiffVersion get a single MR diff version +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-a-single-merge-request-diff-version +func (s *MergeRequestsService) GetSingleMergeRequestDiffVersion(pid any, mergeRequest, version int, opt *GetSingleMergeRequestDiffVersionOptions, options ...RequestOptionFunc) (*MergeRequestDiffVersion, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/versions/%d", PathEscape(project), mergeRequest, version) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(MergeRequestDiffVersion) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// SubscribeToMergeRequest subscribes the authenticated user to the given merge +// request to receive notifications. If the user is already subscribed to the +// merge request, the status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#subscribe-to-a-merge-request +func (s *MergeRequestsService) SubscribeToMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/subscribe", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// UnsubscribeFromMergeRequest unsubscribes the authenticated user from the +// given merge request to not receive notifications from that merge request. +// If the user is not subscribed to the merge request, status code 304 is +// returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#unsubscribe-from-a-merge-request +func (s *MergeRequestsService) UnsubscribeFromMergeRequest(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/unsubscribe", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(MergeRequest) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateTodo manually creates a todo for the current user on a merge request. +// If there already exists a todo for the user on that merge request, +// status code 304 is returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-a-to-do-item +func (s *MergeRequestsService) CreateTodo(pid any, mergeRequest int, options ...RequestOptionFunc) (*Todo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/todo", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(Todo) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// SetTimeEstimate sets the time estimate for a single project merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#set-a-time-estimate-for-a-merge-request +func (s *MergeRequestsService) SetTimeEstimate(pid any, mergeRequest int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.setTimeEstimate(pid, "merge_requests", mergeRequest, opt, options...) +} + +// ResetTimeEstimate resets the time estimate for a single project merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#reset-the-time-estimate-for-a-merge-request +func (s *MergeRequestsService) ResetTimeEstimate(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.resetTimeEstimate(pid, "merge_requests", mergeRequest, options...) +} + +// AddSpentTime adds spent time for a single project merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#add-spent-time-for-a-merge-request +func (s *MergeRequestsService) AddSpentTime(pid any, mergeRequest int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.addSpentTime(pid, "merge_requests", mergeRequest, opt, options...) +} + +// ResetSpentTime resets the spent time for a single project merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#reset-spent-time-for-a-merge-request +func (s *MergeRequestsService) ResetSpentTime(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.resetSpentTime(pid, "merge_requests", mergeRequest, options...) +} + +// GetTimeSpent gets the spent time for a single project merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-time-tracking-stats +func (s *MergeRequestsService) GetTimeSpent(pid any, mergeRequest int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + return s.timeStats.getTimeSpent(pid, "merge_requests", mergeRequest, options...) +} + +// MergeRequestDependency represents a GitLab merge request dependency. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-a-merge-request-dependency +type MergeRequestDependency struct { + ID int `json:"id"` + BlockingMergeRequest BlockingMergeRequest `json:"blocking_merge_request"` + ProjectID int `json:"project_id"` +} + +// BlockingMergeRequest represents a GitLab merge request dependency. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-a-merge-request-dependency +type BlockingMergeRequest struct { + ID int `json:"id"` + Iid int `json:"iid"` + TargetBranch string `json:"target_branch"` + SourceBranch string `json:"source_branch"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + State string `json:"state"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Upvotes int `json:"upvotes"` + Downvotes int `json:"downvotes"` + Author *BasicUser `json:"author"` + Assignee *BasicUser `json:"assignee"` + Assignees []*BasicUser `json:"assignees"` + Reviewers []*BasicUser `json:"reviewers"` + SourceProjectID int `json:"source_project_id"` + TargetProjectID int `json:"target_project_id"` + Labels *LabelOptions `json:"labels"` + Description string `json:"description"` + Draft bool `json:"draft"` + Milestone *string `json:"milestone"` + AutoMerge bool `json:"auto_merge"` + DetailedMergeStatus string `json:"detailed_merge_status"` + MergedAt *time.Time `json:"merged_at"` + ClosedBy *BasicUser `json:"closed_by"` + ClosedAt *time.Time `json:"closed_at"` + Sha string `json:"sha"` + MergeCommitSha string `json:"merge_commit_sha"` + SquashCommitSha string `json:"squash_commit_sha"` + UserNotesCount int `json:"user_notes_count"` + ShouldRemoveSourceBranch *bool `json:"should_remove_source_branch"` + ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` + WebURL string `json:"web_url"` + References *IssueReferences `json:"references"` + DiscussionLocked *bool `json:"discussion_locked"` + TimeStats *TimeStats `json:"time_stats"` + Squash bool `json:"squash"` + TaskCompletionStatus *TasksCompletionStatus `json:"task_completion_status"` + HasConflicts bool `json:"has_conflicts"` + BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` + MergeUser *BasicUser `json:"merge_user"` + MergeAfter time.Time `json:"merge_after"` + Imported bool `json:"imported"` + ImportedFrom string `json:"imported_from"` + PreparedAt *time.Time `json:"prepared_at"` + SquashOnMerge bool `json:"squash_on_merge"` + + // Deprecated: use Draft instead + WorkInProgress bool `json:"work_in_progress"` + // Deprecated: will be removed in v5 of the API, use AutoMerge instead + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + // Deprecated: will be removed in v5 of the API, use MergeUser instead + MergedBy *BasicUser `json:"merged_by"` + // Deprecated: will be removed in v5 of the API, use the Merge Request Approvals API instead + ApprovalsBeforeMerge *int `json:"approvals_before_merge"` + // Deprecated: will be removed in v5 of the API, use References instead + Reference string `json:"reference"` + // Deprecated: in 15.6, use DetailedMergeStatus instead + MergeStatus string `json:"merge_status"` +} + +func (m MergeRequestDependency) String() string { + return Stringify(m) +} + +// CreateMergeRequestDependencyOptions represents the available CreateMergeRequestDependency() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-a-merge-request-dependency +type CreateMergeRequestDependencyOptions struct { + BlockingMergeRequestID *int `url:"blocking_merge_request_id,omitempty" json:"blocking_merge_request_id,omitempty"` +} + +// CreateMergeRequestDependency creates a new merge request dependency for a given +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#create-a-merge-request-dependency +func (s *MergeRequestsService) CreateMergeRequestDependency(pid any, mergeRequest int, opts CreateMergeRequestDependencyOptions, options ...RequestOptionFunc) (*MergeRequestDependency, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/blocks", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + var mrd MergeRequestDependency + resp, err := s.client.Do(req, &mrd) + if err != nil { + return nil, resp, err + } + + return &mrd, resp, err +} + +// DeleteMergeRequestDependency deletes a merge request dependency for a given +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#delete-a-merge-request-dependency +func (s *MergeRequestsService) DeleteMergeRequestDependency(pid any, mergeRequest int, blockingMergeRequest int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/blocks/%d", PathEscape(project), mergeRequest, blockingMergeRequest) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GetMergeRequestDependencies gets a list of merge request dependencies. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_requests/#get-merge-request-dependencies +func (s *MergeRequestsService) GetMergeRequestDependencies(pid any, mergeRequest int, options ...RequestOptionFunc) ([]MergeRequestDependency, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/blocks", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var mrd []MergeRequestDependency + resp, err := s.client.Do(req, &mrd) + if err != nil { + return nil, resp, err + } + + return mrd, resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/merge_trains.go b/vendor/gitlab.com/gitlab-org/api/client-go/merge_trains.go new file mode 100644 index 000000000..bfeb65801 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/merge_trains.go @@ -0,0 +1,184 @@ +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + MergeTrainsServiceInterface interface { + ListProjectMergeTrains(pid any, opt *ListMergeTrainsOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) + ListMergeRequestInMergeTrain(pid any, targetBranch string, opts *ListMergeTrainsOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) + GetMergeRequestOnAMergeTrain(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeTrain, *Response, error) + AddMergeRequestToMergeTrain(pid any, mergeRequest int, opts *AddMergeRequestToMergeTrainOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) + } + + // MergeTrainsService handles communication with the merge trains related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/merge_trains/ + MergeTrainsService struct { + client *Client + } +) + +var _ MergeTrainsServiceInterface = (*MergeTrainsService)(nil) + +// MergeTrain represents a Gitlab merge train. +// +// GitLab API docs: https://docs.gitlab.com/api/merge_trains/ +type MergeTrain struct { + ID int `json:"id"` + MergeRequest *MergeTrainMergeRequest `json:"merge_request"` + User *BasicUser `json:"user"` + Pipeline *Pipeline `json:"pipeline"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + TargetBranch string `json:"target_branch"` + Status string `json:"status"` + MergedAt *time.Time `json:"merged_at"` + Duration int `json:"duration"` +} + +// MergeTrainMergeRequest represents a Gitlab merge request inside merge train. +// +// GitLab API docs: https://docs.gitlab.com/api/merge_trains/ +type MergeTrainMergeRequest struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + WebURL string `json:"web_url"` +} + +// ListMergeTrainsOptions represents the available ListMergeTrain() options. +// +// Gitab API docs: +// https://docs.gitlab.com/api/merge_trains/#list-merge-trains-for-a-project +type ListMergeTrainsOptions struct { + ListOptions + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListProjectMergeTrains get a list of merge trains in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_trains/#list-merge-trains-for-a-project +func (s *MergeTrainsService) ListProjectMergeTrains(pid any, opt *ListMergeTrainsOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_trains", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mts []*MergeTrain + resp, err := s.client.Do(req, &mts) + if err != nil { + return nil, resp, err + } + + return mts, resp, nil +} + +// ListMergeRequestInMergeTrain gets a list of merge requests added to a merge +// train for the requested target branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_trains/#list-merge-requests-in-a-merge-train +func (s *MergeTrainsService) ListMergeRequestInMergeTrain(pid any, targetBranch string, opts *ListMergeTrainsOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_trains/%s", PathEscape(project), targetBranch) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var mts []*MergeTrain + resp, err := s.client.Do(req, &mts) + if err != nil { + return nil, resp, err + } + + return mts, resp, nil +} + +// GetMergeRequestOnAMergeTrain Get merge train information for the requested +// merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_trains/#get-the-status-of-a-merge-request-on-a-merge-train +func (s *MergeTrainsService) GetMergeRequestOnAMergeTrain(pid any, mergeRequest int, options ...RequestOptionFunc) (*MergeTrain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_trains/merge_requests/%d", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + mt := new(MergeTrain) + resp, err := s.client.Do(req, mt) + if err != nil { + return nil, resp, err + } + + return mt, resp, nil +} + +// AddMergeRequestToMergeTrainOptions represents the available +// AddMergeRequestToMergeTrain() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_trains/#add-a-merge-request-to-a-merge-train +type AddMergeRequestToMergeTrainOptions struct { + AutoMerge *bool `url:"auto_merge,omitempty" json:"auto_merge,omitempty"` + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` + Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` + + // Deprecated: in 17.11, use AutoMerge instead + WhenPipelineSucceeds *bool `url:"when_pipeline_succeeds,omitempty" json:"when_pipeline_succeeds,omitempty"` +} + +// AddMergeRequestToMergeTrain Add a merge request to the merge train targeting +// the merge request’s target branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_trains/#add-a-merge-request-to-a-merge-train +func (s *MergeTrainsService) AddMergeRequestToMergeTrain(pid any, mergeRequest int, opts *AddMergeRequestToMergeTrainOptions, options ...RequestOptionFunc) ([]*MergeTrain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_trains/merge_requests/%d", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + var mts []*MergeTrain + resp, err := s.client.Do(req, &mts) + if err != nil { + return nil, resp, err + } + + return mts, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/metadata.go b/vendor/gitlab.com/gitlab-org/api/client-go/metadata.go new file mode 100644 index 000000000..0a702f8e3 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/metadata.go @@ -0,0 +1,72 @@ +// +// Copyright 2022, Timo Furrer +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "net/http" + +type ( + MetadataServiceInterface interface { + GetMetadata(options ...RequestOptionFunc) (*Metadata, *Response, error) + } + + // MetadataService handles communication with the GitLab server instance to + // retrieve its metadata information via the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/metadata/ + MetadataService struct { + client *Client + } +) + +var _ MetadataServiceInterface = (*MetadataService)(nil) + +// Metadata represents a GitLab instance version. +// +// GitLab API docs: https://docs.gitlab.com/api/metadata/ +type Metadata struct { + Version string `json:"version"` + Revision string `json:"revision"` + KAS struct { + Enabled bool `json:"enabled"` + ExternalURL string `json:"externalUrl"` + ExternalK8SProxyURL string `json:"externalK8sProxyUrl"` + Version string `json:"version"` + } `json:"kas"` + Enterprise bool `json:"enterprise"` +} + +func (s Metadata) String() string { + return Stringify(s) +} + +// GetMetadata gets a GitLab server instance meteadata. +// +// GitLab API docs: https://docs.gitlab.com/api/metadata/ +func (s *MetadataService) GetMetadata(options ...RequestOptionFunc) (*Metadata, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "metadata", nil, options) + if err != nil { + return nil, nil, err + } + + v := new(Metadata) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/milestones.go b/vendor/gitlab.com/gitlab-org/api/client-go/milestones.go new file mode 100644 index 000000000..3bcf0657b --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/milestones.go @@ -0,0 +1,289 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + MilestonesServiceInterface interface { + ListMilestones(pid any, opt *ListMilestonesOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) + GetMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Milestone, *Response, error) + CreateMilestone(pid any, opt *CreateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) + UpdateMilestone(pid any, milestone int, opt *UpdateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) + DeleteMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Response, error) + GetMilestoneIssues(pid any, milestone int, opt *GetMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + GetMilestoneMergeRequests(pid any, milestone int, opt *GetMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) + } + + // MilestonesService handles communication with the milestone related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/milestones/ + MilestonesService struct { + client *Client + } +) + +var _ MilestonesServiceInterface = (*MilestonesService)(nil) + +// Milestone represents a GitLab milestone. +// +// GitLab API docs: https://docs.gitlab.com/api/milestones/ +type Milestone struct { + ID int `json:"id"` + IID int `json:"iid"` + GroupID int `json:"group_id"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + StartDate *ISOTime `json:"start_date"` + DueDate *ISOTime `json:"due_date"` + State string `json:"state"` + WebURL string `json:"web_url"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + Expired *bool `json:"expired"` +} + +func (m Milestone) String() string { + return Stringify(m) +} + +// ListMilestonesOptions represents the available ListMilestones() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#list-project-milestones +type ListMilestonesOptions struct { + ListOptions + IIDs *[]int `url:"iids[],omitempty" json:"iids,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"` + + // Deprecated: in GitLab 16,7, use IncludeAncestors instead + IncludeParentMilestones *bool `url:"include_parent_milestones,omitempty" json:"include_parent_milestones,omitempty"` +} + +// ListMilestones returns a list of project milestones. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#list-project-milestones +func (s *MilestonesService) ListMilestones(pid any, opt *ListMilestonesOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*Milestone + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// GetMilestone gets a single project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#get-single-milestone +func (s *MilestonesService) GetMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// CreateMilestoneOptions represents the available CreateMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#create-new-milestone +type CreateMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` +} + +// CreateMilestone creates a new project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#create-new-milestone +func (s *MilestonesService) CreateMilestone(pid any, opt *CreateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// UpdateMilestoneOptions represents the available UpdateMilestone() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#edit-milestone +type UpdateMilestoneOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"` + DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"` + StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"` +} + +// UpdateMilestone updates an existing project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#edit-milestone +func (s *MilestonesService) UpdateMilestone(pid any, milestone int, opt *UpdateMilestoneOptions, options ...RequestOptionFunc) (*Milestone, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + m := new(Milestone) + resp, err := s.client.Do(req, m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DeleteMilestone deletes a specified project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#delete-project-milestone +func (s *MilestonesService) DeleteMilestone(pid any, milestone int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + return s.client.Do(req, nil) +} + +// GetMilestoneIssuesOptions represents the available GetMilestoneIssues() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#get-all-issues-assigned-to-a-single-milestone +type GetMilestoneIssuesOptions ListOptions + +// GetMilestoneIssues gets all issues assigned to a single project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#get-all-issues-assigned-to-a-single-milestone +func (s *MilestonesService) GetMilestoneIssues(pid any, milestone int, opt *GetMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d/issues", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var i []*Issue + resp, err := s.client.Do(req, &i) + if err != nil { + return nil, resp, err + } + + return i, resp, nil +} + +// GetMilestoneMergeRequestsOptions represents the available +// GetMilestoneMergeRequests() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#get-all-merge-requests-assigned-to-a-single-milestone +type GetMilestoneMergeRequestsOptions ListOptions + +// GetMilestoneMergeRequests gets all merge requests assigned to a single +// project milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/milestones/#get-all-merge-requests-assigned-to-a-single-milestone +func (s *MilestonesService) GetMilestoneMergeRequests(pid any, milestone int, opt *GetMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*BasicMergeRequest, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/milestones/%d/merge_requests", PathEscape(project), milestone) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mr []*BasicMergeRequest + resp, err := s.client.Do(req, &mr) + if err != nil { + return nil, resp, err + } + + return mr, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/namespaces.go b/vendor/gitlab.com/gitlab-org/api/client-go/namespaces.go new file mode 100644 index 000000000..b4768551c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/namespaces.go @@ -0,0 +1,186 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + NamespacesServiceInterface interface { + ListNamespaces(opt *ListNamespacesOptions, options ...RequestOptionFunc) ([]*Namespace, *Response, error) + SearchNamespace(query string, options ...RequestOptionFunc) ([]*Namespace, *Response, error) + GetNamespace(id any, options ...RequestOptionFunc) (*Namespace, *Response, error) + NamespaceExists(id any, opt *NamespaceExistsOptions, options ...RequestOptionFunc) (*NamespaceExistance, *Response, error) + } + + // NamespacesService handles communication with the namespace related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/namespaces/ + NamespacesService struct { + client *Client + } +) + +var _ NamespacesServiceInterface = (*NamespacesService)(nil) + +// Namespace represents a GitLab namespace. +// +// GitLab API docs: https://docs.gitlab.com/api/namespaces/ +type Namespace struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Kind string `json:"kind"` + FullPath string `json:"full_path"` + ParentID int `json:"parent_id"` + AvatarURL *string `json:"avatar_url"` + WebURL string `json:"web_url"` + MembersCountWithDescendants int `json:"members_count_with_descendants"` + BillableMembersCount int `json:"billable_members_count"` + Plan string `json:"plan"` + TrialEndsOn *ISOTime `json:"trial_ends_on"` + Trial bool `json:"trial"` + MaxSeatsUsed *int `json:"max_seats_used"` + SeatsInUse *int `json:"seats_in_use"` +} + +func (n Namespace) String() string { + return Stringify(n) +} + +// ListNamespacesOptions represents the available ListNamespaces() options. +// +// GitLab API docs: https://docs.gitlab.com/api/namespaces/#list-all-namespaces +type ListNamespacesOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + OwnedOnly *bool `url:"owned_only,omitempty" json:"owned_only,omitempty"` + TopLevelOnly *bool `url:"top_level_only,omitempty" json:"top_level_only,omitempty"` +} + +// ListNamespaces gets a list of projects accessible by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/namespaces/#list-all-namespaces +func (s *NamespacesService) ListNamespaces(opt *ListNamespacesOptions, options ...RequestOptionFunc) ([]*Namespace, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "namespaces", opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Namespace + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// SearchNamespace gets all namespaces that match your string in their name +// or path. +// +// GitLab API docs: +// https://docs.gitlab.com/api/namespaces/#list-all-namespaces +func (s *NamespacesService) SearchNamespace(query string, options ...RequestOptionFunc) ([]*Namespace, *Response, error) { + var q struct { + Search string `url:"search,omitempty" json:"search,omitempty"` + } + q.Search = query + + req, err := s.client.NewRequest(http.MethodGet, "namespaces", &q, options) + if err != nil { + return nil, nil, err + } + + var n []*Namespace + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetNamespace gets a namespace by id. +// +// GitLab API docs: +// https://docs.gitlab.com/api/namespaces/#get-details-on-a-namespace +func (s *NamespacesService) GetNamespace(id any, options ...RequestOptionFunc) (*Namespace, *Response, error) { + namespace, err := parseID(id) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("namespaces/%s", PathEscape(namespace)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Namespace) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// NamespaceExistance represents a namespace exists result. +// +// GitLab API docs: +// https://docs.gitlab.com/api/namespaces/#verify-namespace-availability +type NamespaceExistance struct { + Exists bool `json:"exists"` + Suggests []string `json:"suggests"` +} + +// NamespaceExistsOptions represents the available NamespaceExists() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/namespaces/#verify-namespace-availability +type NamespaceExistsOptions struct { + ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"` +} + +// NamespaceExists checks the existence of a namespace. +// +// GitLab API docs: +// https://docs.gitlab.com/api/namespaces/#verify-namespace-availability +func (s *NamespacesService) NamespaceExists(id any, opt *NamespaceExistsOptions, options ...RequestOptionFunc) (*NamespaceExistance, *Response, error) { + namespace, err := parseID(id) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("namespaces/%s/exists", namespace) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(NamespaceExistance) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/notes.go b/vendor/gitlab.com/gitlab-org/api/client-go/notes.go new file mode 100644 index 000000000..b54b95019 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/notes.go @@ -0,0 +1,743 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + NotesServiceInterface interface { + ListIssueNotes(pid any, issue int, opt *ListIssueNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) + GetIssueNote(pid any, issue, note int, options ...RequestOptionFunc) (*Note, *Response, error) + CreateIssueNote(pid any, issue int, opt *CreateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateIssueNote(pid any, issue, note int, opt *UpdateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteIssueNote(pid any, issue, note int, options ...RequestOptionFunc) (*Response, error) + ListSnippetNotes(pid any, snippet int, opt *ListSnippetNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) + GetSnippetNote(pid any, snippet, note int, options ...RequestOptionFunc) (*Note, *Response, error) + CreateSnippetNote(pid any, snippet int, opt *CreateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateSnippetNote(pid any, snippet, note int, opt *UpdateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteSnippetNote(pid any, snippet, note int, options ...RequestOptionFunc) (*Response, error) + ListMergeRequestNotes(pid any, mergeRequest int, opt *ListMergeRequestNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) + GetMergeRequestNote(pid any, mergeRequest, note int, options ...RequestOptionFunc) (*Note, *Response, error) + CreateMergeRequestNote(pid any, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateMergeRequestNote(pid any, mergeRequest, note int, opt *UpdateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteMergeRequestNote(pid any, mergeRequest, note int, options ...RequestOptionFunc) (*Response, error) + ListEpicNotes(gid any, epic int, opt *ListEpicNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) + GetEpicNote(gid any, epic, note int, options ...RequestOptionFunc) (*Note, *Response, error) + CreateEpicNote(gid any, epic int, opt *CreateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + UpdateEpicNote(gid any, epic, note int, opt *UpdateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) + DeleteEpicNote(gid any, epic, note int, options ...RequestOptionFunc) (*Response, error) + } + + // NotesService handles communication with the notes related methods + // of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/notes/ + NotesService struct { + client *Client + } +) + +var _ NotesServiceInterface = (*NotesService)(nil) + +// Note represents a GitLab note. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/ +type Note struct { + ID int `json:"id"` + Type NoteTypeValue `json:"type"` + Body string `json:"body"` + Attachment string `json:"attachment"` + Title string `json:"title"` + FileName string `json:"file_name"` + Author NoteAuthor `json:"author"` + System bool `json:"system"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + ExpiresAt *time.Time `json:"expires_at"` + CommitID string `json:"commit_id"` + Position *NotePosition `json:"position"` + NoteableID int `json:"noteable_id"` + NoteableType string `json:"noteable_type"` + ProjectID int `json:"project_id"` + NoteableIID int `json:"noteable_iid"` + Resolvable bool `json:"resolvable"` + Resolved bool `json:"resolved"` + ResolvedAt *time.Time `json:"resolved_at"` + ResolvedBy struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"resolved_by"` + Internal bool `json:"internal"` + + // Deprecated: use Internal instead + Confidential bool `json:"confidential"` +} + +// NoteAuthor represents the author of a note. +type NoteAuthor struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` +} + +// NotePosition represents the position attributes of a note. +type NotePosition struct { + BaseSHA string `json:"base_sha"` + StartSHA string `json:"start_sha"` + HeadSHA string `json:"head_sha"` + PositionType string `json:"position_type"` + NewPath string `json:"new_path,omitempty"` + NewLine int `json:"new_line,omitempty"` + OldPath string `json:"old_path,omitempty"` + OldLine int `json:"old_line,omitempty"` + LineRange *LineRange `json:"line_range,omitempty"` +} + +// LineRange represents the range of a note. +type LineRange struct { + StartRange *LinePosition `json:"start"` + EndRange *LinePosition `json:"end"` +} + +// LinePosition represents a position in a line range. +type LinePosition struct { + LineCode string `json:"line_code"` + Type string `json:"type"` + OldLine int `json:"old_line"` + NewLine int `json:"new_line"` +} + +func (n Note) String() string { + return Stringify(n) +} + +// ListIssueNotesOptions represents the available ListIssueNotes() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-project-issue-notes +type ListIssueNotesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListIssueNotes gets a list of all notes for a single issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-project-issue-notes +func (s *NotesService) ListIssueNotes(pid any, issue int, opt *ListIssueNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetIssueNote returns a single note for a specific project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#get-single-issue-note +func (s *NotesService) GetIssueNote(pid any, issue, note int, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", PathEscape(project), issue, note) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// CreateIssueNoteOptions represents the available CreateIssueNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-issue-note +type CreateIssueNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + Internal *bool `url:"internal,omitempty" json:"internal,omitempty"` +} + +// CreateIssueNote creates a new note to a single project issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-issue-note +func (s *NotesService) CreateIssueNote(pid any, issue int, opt *CreateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateIssueNoteOptions represents the available UpdateIssueNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-issue-note +type UpdateIssueNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateIssueNote modifies existing note of an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-issue-note +func (s *NotesService) UpdateIssueNote(pid any, issue, note int, opt *UpdateIssueNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", PathEscape(project), issue, note) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteIssueNote deletes an existing note of an issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#delete-an-issue-note +func (s *NotesService) DeleteIssueNote(pid any, issue, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", PathEscape(project), issue, note) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListSnippetNotesOptions represents the available ListSnippetNotes() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-snippet-notes +type ListSnippetNotesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListSnippetNotes gets a list of all notes for a single snippet. Snippet +// notes are comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-snippet-notes +func (s *NotesService) ListSnippetNotes(pid any, snippet int, opt *ListSnippetNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetSnippetNote returns a single note for a given snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#get-single-snippet-note +func (s *NotesService) GetSnippetNote(pid any, snippet, note int, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", PathEscape(project), snippet, note) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// CreateSnippetNoteOptions represents the available CreateSnippetNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-snippet-note +type CreateSnippetNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` +} + +// CreateSnippetNote creates a new note for a single snippet. Snippet notes are +// comments users can post to a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-snippet-note +func (s *NotesService) CreateSnippetNote(pid any, snippet int, opt *CreateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateSnippetNoteOptions represents the available UpdateSnippetNote() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-snippet-note +type UpdateSnippetNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateSnippetNote modifies existing note of a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-snippet-note +func (s *NotesService) UpdateSnippetNote(pid any, snippet, note int, opt *UpdateSnippetNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", PathEscape(project), snippet, note) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteSnippetNote deletes an existing note of a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#delete-a-snippet-note +func (s *NotesService) DeleteSnippetNote(pid any, snippet, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", PathEscape(project), snippet, note) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListMergeRequestNotesOptions represents the available ListMergeRequestNotes() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-merge-request-notes +type ListMergeRequestNotesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListMergeRequestNotes gets a list of all notes for a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-merge-request-notes +func (s *NotesService) ListMergeRequestNotes(pid any, mergeRequest int, opt *ListMergeRequestNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetMergeRequestNote returns a single note for a given merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#get-single-merge-request-note +func (s *NotesService) GetMergeRequestNote(pid any, mergeRequest, note int, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes/%d", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// CreateMergeRequestNoteOptions represents the available +// CreateMergeRequestNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-merge-request-note +type CreateMergeRequestNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` + CreatedAt *time.Time `url:"created_at,omitempty" json:"created_at,omitempty"` + Internal *bool `url:"internal,omitempty" json:"internal,omitempty"` + MergeRequestDiffHeadSHA *string `url:"merge_request_diff_head_sha,omitempty" json:"merge_request_diff_head_sha,omitempty"` +} + +// CreateMergeRequestNote creates a new note for a single merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-merge-request-note +func (s *NotesService) CreateMergeRequestNote(pid any, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", PathEscape(project), mergeRequest) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateMergeRequestNoteOptions represents the available +// UpdateMergeRequestNote() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-merge-request-note +type UpdateMergeRequestNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateMergeRequestNote modifies existing note of a merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-merge-request-note +func (s *NotesService) UpdateMergeRequestNote(pid any, mergeRequest, note int, opt *UpdateMergeRequestNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/merge_requests/%d/notes/%d", PathEscape(project), mergeRequest, note) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteMergeRequestNote deletes an existing note of a merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#delete-a-merge-request-note +func (s *NotesService) DeleteMergeRequestNote(pid any, mergeRequest, note int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf( + "projects/%s/merge_requests/%d/notes/%d", PathEscape(project), mergeRequest, note) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListEpicNotesOptions represents the available ListEpicNotes() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-epic-notes +type ListEpicNotesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListEpicNotes gets a list of all notes for a single epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#list-all-epic-notes +func (s *NotesService) ListEpicNotes(gid any, epic int, opt *ListEpicNotesOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/notes", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var n []*Note + resp, err := s.client.Do(req, &n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// GetEpicNote returns a single note for an epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#get-single-epic-note +func (s *NotesService) GetEpicNote(gid any, epic, note int, options ...RequestOptionFunc) (*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", PathEscape(group), epic, note) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// CreateEpicNoteOptions represents the available CreateEpicNote() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-epic-note +type CreateEpicNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// CreateEpicNote creates a new note for a single merge request. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#create-new-epic-note +func (s *NotesService) CreateEpicNote(gid any, epic int, opt *CreateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/notes", PathEscape(group), epic) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// UpdateEpicNoteOptions represents the available UpdateEpicNote() options. +// Will be removed in v5 of the API, use Work Items API instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/notes/#modify-existing-epic-note +type UpdateEpicNoteOptions struct { + Body *string `url:"body,omitempty" json:"body,omitempty"` +} + +// UpdateEpicNote modifies existing note of an epic. +// Will be removed in v5 of the API, use Work Items API instead +// +// https://docs.gitlab.com/api/notes/#modify-existing-epic-note +func (s *NotesService) UpdateEpicNote(gid any, epic, note int, opt *UpdateEpicNoteOptions, options ...RequestOptionFunc) (*Note, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", PathEscape(group), epic, note) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + n := new(Note) + resp, err := s.client.Do(req, n) + if err != nil { + return nil, resp, err + } + + return n, resp, nil +} + +// DeleteEpicNote deletes an existing note of a merge request. +// Will be removed in v5 of the API, use Work Items API instead +// +// https://docs.gitlab.com/api/notes/#delete-an-epic-note +func (s *NotesService) DeleteEpicNote(gid any, epic, note int, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/epics/%d/notes/%d", PathEscape(group), epic, note) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/notifications.go b/vendor/gitlab.com/gitlab-org/api/client-go/notifications.go new file mode 100644 index 000000000..539600f3c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/notifications.go @@ -0,0 +1,255 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "errors" + "fmt" + "net/http" +) + +type ( + NotificationSettingsServiceInterface interface { + GetGlobalSettings(options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + GetSettingsForGroup(gid any, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + GetSettingsForProject(pid any, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + UpdateSettingsForGroup(gid any, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + UpdateSettingsForProject(pid any, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) + } + + // NotificationSettingsService handles communication with the notification settings + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/notification_settings/ + NotificationSettingsService struct { + client *Client + } +) + +var _ NotificationSettingsServiceInterface = (*NotificationSettingsService)(nil) + +// NotificationSettings represents the Gitlab notification setting. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#valid-notification-levels +type NotificationSettings struct { + Level NotificationLevelValue `json:"level"` + NotificationEmail string `json:"notification_email"` + Events *NotificationEvents `json:"events"` +} + +// NotificationEvents represents the available notification setting events. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#valid-notification-levels +type NotificationEvents struct { + CloseIssue bool `json:"close_issue"` + CloseMergeRequest bool `json:"close_merge_request"` + FailedPipeline bool `json:"failed_pipeline"` + FixedPipeline bool `json:"fixed_pipeline"` + IssueDue bool `json:"issue_due"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + MergeMergeRequest bool `json:"merge_merge_request"` + MovedProject bool `json:"moved_project"` + NewIssue bool `json:"new_issue"` + NewMergeRequest bool `json:"new_merge_request"` + NewEpic bool `json:"new_epic"` + NewNote bool `json:"new_note"` + PushToMergeRequest bool `json:"push_to_merge_request"` + ReassignIssue bool `json:"reassign_issue"` + ReassignMergeRequest bool `json:"reassign_merge_request"` + ReopenIssue bool `json:"reopen_issue"` + ReopenMergeRequest bool `json:"reopen_merge_request"` + SuccessPipeline bool `json:"success_pipeline"` +} + +func (ns NotificationSettings) String() string { + return Stringify(ns) +} + +// GetGlobalSettings returns current notification settings and email address. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#global-notification-settings +func (s *NotificationSettingsService) GetGlobalSettings(options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + u := "notification_settings" + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} + +// NotificationSettingsOptions represents the available options that can be passed +// to the API when updating the notification settings. +type NotificationSettingsOptions struct { + Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"` + NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"` + CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"` + CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"` + FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"` + FixedPipeline *bool `url:"fixed_pipeline,omitempty" json:"fixed_pipeline,omitempty"` + IssueDue *bool `url:"issue_due,omitempty" json:"issue_due,omitempty"` + MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"` + MergeWhenPipelineSucceeds *bool `url:"merge_when_pipeline_succeeds,omitempty" json:"merge_when_pipeline_succeeds,omitempty"` + MovedProject *bool `url:"moved_project,omitempty" json:"moved_project,omitempty"` + NewEpic *bool `url:"new_epic,omitempty" json:"new_epic,omitempty"` + NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"` + NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"` + NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"` + PushToMergeRequest *bool `url:"push_to_merge_request,omitempty" json:"push_to_merge_request,omitempty"` + ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"` + ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"` + ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"` + ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"` + SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"` +} + +// UpdateGlobalSettings updates current notification settings and email address. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#update-global-notification-settings +func (s *NotificationSettingsService) UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + if opt.Level != nil && *opt.Level == GlobalNotificationLevel { + return nil, nil, errors.New( + "notification level 'global' is not valid for global notification settings") + } + + u := "notification_settings" + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} + +// GetSettingsForGroup returns current group notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#group--project-level-notification-settings +func (s *NotificationSettingsService) GetSettingsForGroup(gid any, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/notification_settings", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} + +// GetSettingsForProject returns current project notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#group--project-level-notification-settings +func (s *NotificationSettingsService) GetSettingsForProject(pid any, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/notification_settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} + +// UpdateSettingsForGroup updates current group notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#update-groupproject-level-notification-settings +func (s *NotificationSettingsService) UpdateSettingsForGroup(gid any, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/notification_settings", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} + +// UpdateSettingsForProject updates current project notification settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/notification_settings/#update-groupproject-level-notification-settings +func (s *NotificationSettingsService) UpdateSettingsForProject(pid any, opt *NotificationSettingsOptions, options ...RequestOptionFunc) (*NotificationSettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/notification_settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ns := new(NotificationSettings) + resp, err := s.client.Do(req, ns) + if err != nil { + return nil, resp, err + } + + return ns, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/packages.go b/vendor/gitlab.com/gitlab-org/api/client-go/packages.go new file mode 100644 index 000000000..f9f3b59af --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/packages.go @@ -0,0 +1,273 @@ +// +// Copyright 2021, Kordian Bruck +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PackagesServiceInterface interface { + ListProjectPackages(pid any, opt *ListProjectPackagesOptions, options ...RequestOptionFunc) ([]*Package, *Response, error) + ListGroupPackages(gid any, opt *ListGroupPackagesOptions, options ...RequestOptionFunc) ([]*GroupPackage, *Response, error) + ListPackageFiles(pid any, pkg int, opt *ListPackageFilesOptions, options ...RequestOptionFunc) ([]*PackageFile, *Response, error) + DeleteProjectPackage(pid any, pkg int, options ...RequestOptionFunc) (*Response, error) + DeletePackageFile(pid any, pkg, file int, options ...RequestOptionFunc) (*Response, error) + } + + // PackagesService handles communication with the packages related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/packages/ + PackagesService struct { + client *Client + } +) + +var _ PackagesServiceInterface = (*PackagesService)(nil) + +// Package represents a GitLab package. +// +// GitLab API docs: https://docs.gitlab.com/api/packages/ +type Package struct { + ID int `json:"id"` + Name string `json:"name"` + Version string `json:"version"` + PackageType string `json:"package_type"` + Status string `json:"status"` + Links *PackageLinks `json:"_links"` + CreatedAt *time.Time `json:"created_at"` + LastDownloadedAt *time.Time `json:"last_downloaded_at"` + Tags []PackageTag `json:"tags"` +} + +func (s Package) String() string { + return Stringify(s) +} + +// GroupPackage represents a GitLab group package. +// +// GitLab API docs: https://docs.gitlab.com/api/packages/ +type GroupPackage struct { + Package + ProjectID int `json:"project_id"` + ProjectPath string `json:"project_path"` +} + +func (s GroupPackage) String() string { + return Stringify(s) +} + +// PackageLinks holds links for itself and deleting. +type PackageLinks struct { + WebPath string `json:"web_path"` + DeleteAPIPath string `json:"delete_api_path"` +} + +func (s PackageLinks) String() string { + return Stringify(s) +} + +// PackageTag holds label information about the package +type PackageTag struct { + ID int `json:"id"` + PackageID int `json:"package_id"` + Name string `json:"name"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` +} + +func (s PackageTag) String() string { + return Stringify(s) +} + +// PackageFile represents one file contained within a package. +// +// GitLab API docs: https://docs.gitlab.com/api/packages/ +type PackageFile struct { + ID int `json:"id"` + PackageID int `json:"package_id"` + CreatedAt *time.Time `json:"created_at"` + FileName string `json:"file_name"` + Size int `json:"size"` + FileMD5 string `json:"file_md5"` + FileSHA1 string `json:"file_sha1"` + FileSHA256 string `json:"file_sha256"` + Pipeline *[]Pipeline `json:"pipelines"` +} + +func (s PackageFile) String() string { + return Stringify(s) +} + +// ListProjectPackagesOptions represents the available ListProjectPackages() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#for-a-project +type ListProjectPackagesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + PackageType *string `url:"package_type,omitempty" json:"package_type,omitempty"` + PackageName *string `url:"package_name,omitempty" json:"package_name,omitempty"` + PackageVersion *string `url:"package_version,omitempty" json:"package_version,omitempty"` + IncludeVersionless *bool `url:"include_versionless,omitempty" json:"include_versionless,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` +} + +// ListProjectPackages gets a list of packages in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#for-a-project +func (s *PackagesService) ListProjectPackages(pid any, opt *ListProjectPackagesOptions, options ...RequestOptionFunc) ([]*Package, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/packages", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Package + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// ListGroupPackagesOptions represents the available ListGroupPackages() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#for-a-group +type ListGroupPackagesOptions struct { + ListOptions + ExcludeSubGroups *bool `url:"exclude_subgroups,omitempty" json:"exclude_subgroups,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + PackageType *string `url:"package_type,omitempty" json:"package_type,omitempty"` + PackageName *string `url:"package_name,omitempty" json:"package_name,omitempty"` + IncludeVersionless *bool `url:"include_versionless,omitempty" json:"include_versionless,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` +} + +// ListGroupPackages gets a list of packages in a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#for-a-group +func (s *PackagesService) ListGroupPackages(gid any, opt *ListGroupPackagesOptions, options ...RequestOptionFunc) ([]*GroupPackage, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/packages", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*GroupPackage + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// ListPackageFilesOptions represents the available ListPackageFiles() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#list-package-files +type ListPackageFilesOptions ListOptions + +// ListPackageFiles gets a list of files that are within a package +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#list-package-files +func (s *PackagesService) ListPackageFiles(pid any, pkg int, opt *ListPackageFilesOptions, options ...RequestOptionFunc) ([]*PackageFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/packages/%d/package_files", + PathEscape(project), + pkg, + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pfs []*PackageFile + resp, err := s.client.Do(req, &pfs) + if err != nil { + return nil, resp, err + } + + return pfs, resp, nil +} + +// DeleteProjectPackage deletes a package in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#delete-a-project-package +func (s *PackagesService) DeleteProjectPackage(pid any, pkg int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/packages/%d", PathEscape(project), pkg) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeletePackageFile deletes a file in project package +// +// GitLab API docs: +// https://docs.gitlab.com/api/packages/#delete-a-package-file +func (s *PackagesService) DeletePackageFile(pid any, pkg, file int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/packages/%d/package_files/%d", PathEscape(project), pkg, file) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pages.go b/vendor/gitlab.com/gitlab-org/api/client-go/pages.go new file mode 100644 index 000000000..379844054 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pages.go @@ -0,0 +1,141 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PagesServiceInterface interface { + UnpublishPages(gid any, options ...RequestOptionFunc) (*Response, error) + GetPages(gid any, options ...RequestOptionFunc) (*Pages, *Response, error) + UpdatePages(pid any, opt UpdatePagesOptions, options ...RequestOptionFunc) (*Pages, *Response, error) + } + + // PagesService handles communication with the pages related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/pages/ + PagesService struct { + client *Client + } +) + +var _ PagesServiceInterface = (*PagesService)(nil) + +// Pages represents the Pages of a project. +// +// GitLab API docs: https://docs.gitlab.com/api/pages/ +type Pages struct { + URL string `json:"url"` + IsUniqueDomainEnabled bool `json:"is_unique_domain_enabled"` + ForceHTTPS bool `json:"force_https"` + Deployments []*PagesDeployment `json:"deployments"` +} + +// PagesDeployment represents a Pages deployment. +// +// GitLab API docs: https://docs.gitlab.com/api/pages/ +type PagesDeployment struct { + CreatedAt time.Time `json:"created_at"` + URL string `json:"url"` + PathPrefix string `json:"path_prefix"` + RootDirectory string `json:"root_directory"` +} + +// UnpublishPages unpublished pages. The user must have admin privileges. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages/#unpublish-pages +func (s *PagesService) UnpublishPages(gid any, options ...RequestOptionFunc) (*Response, error) { + page, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/pages", PathEscape(page)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GetPages lists Pages settings for a project. The user must have at least +// maintainer privileges. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/pages/#get-pages-settings-for-a-project +func (s *PagesService) GetPages(gid any, options ...RequestOptionFunc) (*Pages, *Response, error) { + project, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pages) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// UpdatePages represents the available UpdatePages() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages/#update-pages-settings-for-a-project +type UpdatePagesOptions struct { + PagesUniqueDomainEnabled *bool `url:"pages_unique_domain_enabled,omitempty" json:"pages_unique_domain_enabled,omitempty"` + PagesHTTPSOnly *bool `url:"pages_https_only,omitempty" json:"pages_https_only,omitempty"` +} + +// UpdatePages updates Pages settings for a project. The user must have +// administrator privileges. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/pages/#update-pages-settings-for-a-project +func (s *PagesService) UpdatePages(pid any, opt UpdatePagesOptions, options ...RequestOptionFunc) (*Pages, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Pages) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pages_domains.go b/vendor/gitlab.com/gitlab-org/api/client-go/pages_domains.go new file mode 100644 index 000000000..c6b5d79eb --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pages_domains.go @@ -0,0 +1,229 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PagesDomainsServiceInterface interface { + ListPagesDomains(pid any, opt *ListPagesDomainsOptions, options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) + ListAllPagesDomains(options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) + GetPagesDomain(pid any, domain string, options ...RequestOptionFunc) (*PagesDomain, *Response, error) + CreatePagesDomain(pid any, opt *CreatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) + UpdatePagesDomain(pid any, domain string, opt *UpdatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) + DeletePagesDomain(pid any, domain string, options ...RequestOptionFunc) (*Response, error) + } + + // PagesDomainsService handles communication with the pages domains + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/pages_domains/ + PagesDomainsService struct { + client *Client + } +) + +var _ PagesDomainsServiceInterface = (*PagesDomainsService)(nil) + +// PagesDomain represents a pages domain. +// +// GitLab API docs: https://docs.gitlab.com/api/pages_domains/ +type PagesDomain struct { + Domain string `json:"domain"` + AutoSslEnabled bool `json:"auto_ssl_enabled"` + URL string `json:"url"` + ProjectID int `json:"project_id"` + Verified bool `json:"verified"` + VerificationCode string `json:"verification_code"` + EnabledUntil *time.Time `json:"enabled_until"` + Certificate struct { + Subject string `json:"subject"` + Expired bool `json:"expired"` + Expiration *time.Time `json:"expiration"` + Certificate string `json:"certificate"` + CertificateText string `json:"certificate_text"` + } `json:"certificate"` +} + +// ListPagesDomainsOptions represents the available ListPagesDomains() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#list-pages-domains +type ListPagesDomainsOptions ListOptions + +// ListPagesDomains gets a list of project pages domains. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#list-pages-domains +func (s *PagesDomainsService) ListPagesDomains(pid any, opt *ListPagesDomainsOptions, options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages/domains", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pd []*PagesDomain + resp, err := s.client.Do(req, &pd) + if err != nil { + return nil, resp, err + } + + return pd, resp, nil +} + +// ListAllPagesDomains gets a list of all pages domains. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#list-all-pages-domains +func (s *PagesDomainsService) ListAllPagesDomains(options ...RequestOptionFunc) ([]*PagesDomain, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "pages/domains", nil, options) + if err != nil { + return nil, nil, err + } + + var pd []*PagesDomain + resp, err := s.client.Do(req, &pd) + if err != nil { + return nil, resp, err + } + + return pd, resp, nil +} + +// GetPagesDomain get a specific pages domain for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#single-pages-domain +func (s *PagesDomainsService) GetPagesDomain(pid any, domain string, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages/domains/%s", PathEscape(project), domain) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pd := new(PagesDomain) + resp, err := s.client.Do(req, pd) + if err != nil { + return nil, resp, err + } + + return pd, resp, nil +} + +// CreatePagesDomainOptions represents the available CreatePagesDomain() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#create-new-pages-domain +type CreatePagesDomainOptions struct { + Domain *string `url:"domain,omitempty" json:"domain,omitempty"` + AutoSslEnabled *bool `url:"auto_ssl_enabled,omitempty" json:"auto_ssl_enabled,omitempty"` + Certificate *string `url:"certificate,omitempty" json:"certificate,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` +} + +// CreatePagesDomain creates a new project pages domain. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#create-new-pages-domain +func (s *PagesDomainsService) CreatePagesDomain(pid any, opt *CreatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages/domains", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pd := new(PagesDomain) + resp, err := s.client.Do(req, pd) + if err != nil { + return nil, resp, err + } + + return pd, resp, nil +} + +// UpdatePagesDomainOptions represents the available UpdatePagesDomain() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#update-pages-domain +type UpdatePagesDomainOptions struct { + AutoSslEnabled *bool `url:"auto_ssl_enabled,omitempty" json:"auto_ssl_enabled,omitempty"` + Certificate *string `url:"certificate,omitempty" json:"certificate,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` +} + +// UpdatePagesDomain updates an existing project pages domain. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#update-pages-domain +func (s *PagesDomainsService) UpdatePagesDomain(pid any, domain string, opt *UpdatePagesDomainOptions, options ...RequestOptionFunc) (*PagesDomain, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pages/domains/%s", PathEscape(project), domain) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pd := new(PagesDomain) + resp, err := s.client.Do(req, pd) + if err != nil { + return nil, resp, err + } + + return pd, resp, nil +} + +// DeletePagesDomain deletes an existing prject pages domain. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pages_domains/#delete-pages-domain +func (s *PagesDomainsService) DeletePagesDomain(pid any, domain string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/pages/domains/%s", PathEscape(project), domain) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pagination.go b/vendor/gitlab.com/gitlab-org/api/client-go/pagination.go new file mode 100644 index 000000000..cc7a1e708 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pagination.go @@ -0,0 +1,159 @@ +//go:build go1.23 +// +build go1.23 + +package gitlab + +import ( + "fmt" + "iter" +) + +type PaginationOptionFunc = RequestOptionFunc + +// Scan scans all pages for the given request function f and returns individual items in an iterator. +// If an error happens during pagination, the iterator stops immediately. +// The caller must consume the returned error function to retrieve potential errors. +// +// opts := &ListProjectsOptions{} +// it, hasErr := Scan(func(p PaginationOptionFunc) ([]*Project, *Response, error) { +// return c.Projects.ListProjects(opts, p) +// }) +// projects := slices.Collect(it) +// if err := hasErr(); err != nil { +// return err +// } +// +// or with keyset-based pagination: +// +// opts := &ListProjectsOptions{ +// ListOptions: ListOptions{ +// OrderBy: "id", +// Pagination: "keyset", +// }, +// } +// it, hasErr := Scan(func(p PaginationOptionFunc) ([]*Project, *Response, error) { +// return c.Projects.ListProjects(opts, p) +// }) +// projects := slices.Collect(it) +// if err := hasErr(); err != nil { +// return err +// } +// +// Attention: This API is experimental and may be subject to breaking changes to improve the API in the future. +func Scan[T any](f func(p PaginationOptionFunc) ([]T, *Response, error)) (iter.Seq[T], func() error) { + exhausted := false + var e error + it := func(yield func(T) bool) { + defer func() { + exhausted = true + }() + for t, err := range Scan2(f) { + if err != nil { + e = err + return + } + + if !yield(t) { + return + } + } + } + hasErr := func() error { + if !exhausted { + panic("called error function of Scan iterator before iterator was exhausted") + } + return e + } + return it, hasErr +} + +// Scan2 scans all pages for the given request function f and returns individual items and potential errors in an iterator. +// The caller must consume the error element of the iterator during each iteration +// to ensure that no errors happened. +// +// opts := &ListProjectsOptions{} +// for p, err := range Scan2(func(p PaginationOptionFunc) ([]*Project, *Response, error) { +// return c.Projects.ListProjects(opts, p) +// }) { +// if err != nil { +// return err +// } +// // do something with p +// } +// +// or with keyset-based pagination: +// +// opts := &ListProjectsOptions{ +// ListOptions: ListOptions{ +// OrderBy: "id", +// Pagination: "keyset", +// }, +// } +// for p, err := range Scan2(func(p PaginationOptionFunc) ([]*Project, *Response, error) { +// return c.Projects.ListProjects(opts, p) +// }) { +// if err != nil { +// return err +// } +// // do something with p +// } +// +// Attention: This API is experimental and may be subject to breaking changes to improve the API in the future. +func Scan2[T any](f func(p PaginationOptionFunc) ([]T, *Response, error)) iter.Seq2[T, error] { + return func(yield func(T, error) bool) { + var nextOpt PaginationOptionFunc + + Pagination: + for { + ts, resp, err := f(nextOpt) + if err != nil { + var t T + yield(t, err) + return + } + + for _, t := range ts { + if !yield(t, nil) { + return + } + } + + // the f request function was either configured for offset- or keyset-based + // pagination. We support both here, by checking if the next link is provided (keyset) + // or not. If both are provided, keyset-based pagination takes precedence. + switch { + case resp.NextLink != "": + nextOpt = WithKeysetPaginationParameters(resp.NextLink) + case resp.NextPage != 0: + nextOpt = WithOffsetPaginationParameters(resp.NextPage) + default: + // no more pages + break Pagination + } + } + } +} + +// Must provides a single item iterator for the provided two item iterator and panics if an error happens. +// +// opts := &ListProjectsOptions{} +// for p := range Must(Scan2(func(p PaginationOptionFunc) ([]*Project, *Response, error) { +// return c.Projects.ListProjects(opts, p) +// })) { +// // do something with p +// } +// +// Attention: This API is experimental and may be subject to breaking changes to improve the API in the future. +func Must[T any](it iter.Seq2[T, error]) iter.Seq[T] { + return func(yield func(T) bool) { + for x, err := range it { + if err != nil { + panic(fmt.Errorf("iterator produced an error: %w", err)) + } + + if !yield(x) { + return + } + } + } +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/personal_access_tokens.go b/vendor/gitlab.com/gitlab-org/api/client-go/personal_access_tokens.go new file mode 100644 index 000000000..0dd5da953 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/personal_access_tokens.go @@ -0,0 +1,247 @@ +// +// Copyright 2022, Ryan Glab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PersonalAccessTokensServiceInterface interface { + ListPersonalAccessTokens(opt *ListPersonalAccessTokensOptions, options ...RequestOptionFunc) ([]*PersonalAccessToken, *Response, error) + GetSinglePersonalAccessTokenByID(token int, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + GetSinglePersonalAccessToken(options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + RotatePersonalAccessToken(token int, opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + RotatePersonalAccessTokenByID(token int, opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + RotatePersonalAccessTokenSelf(opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + RevokePersonalAccessToken(token int, options ...RequestOptionFunc) (*Response, error) + RevokePersonalAccessTokenByID(token int, options ...RequestOptionFunc) (*Response, error) + RevokePersonalAccessTokenSelf(options ...RequestOptionFunc) (*Response, error) + } + + // PersonalAccessTokensService handles communication with the personal access + // tokens related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/personal_access_tokens/ + PersonalAccessTokensService struct { + client *Client + } +) + +var _ PersonalAccessTokensServiceInterface = (*PersonalAccessTokensService)(nil) + +// PersonalAccessToken represents a personal access token. +// +// GitLab API docs: https://docs.gitlab.com/api/personal_access_tokens/ +type PersonalAccessToken struct { + ID int `json:"id"` + Name string `json:"name"` + Revoked bool `json:"revoked"` + CreatedAt *time.Time `json:"created_at"` + Description string `json:"description"` + Scopes []string `json:"scopes"` + UserID int `json:"user_id"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Active bool `json:"active"` + ExpiresAt *ISOTime `json:"expires_at"` + Token string `json:"token,omitempty"` +} + +// ResourceAccessToken represents a generic access token used for both +// project and group access tokens. It's only used as an alias type, which +// is why it's not exported. +type resourceAccessToken struct { + PersonalAccessToken + AccessLevel AccessLevelValue `json:"access_level"` +} + +func (p PersonalAccessToken) String() string { + return Stringify(p) +} + +// ListPersonalAccessTokensOptions represents the available +// ListPersonalAccessTokens() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#list-all-personal-access-tokens +type ListPersonalAccessTokensOptions struct { + ListOptions + CreatedAfter *ISOTime `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *ISOTime `url:"created_before,omitempty" json:"created_before,omitempty"` + LastUsedAfter *ISOTime `url:"last_used_after,omitempty" json:"last_used_after,omitempty"` + LastUsedBefore *ISOTime `url:"last_used_before,omitempty" json:"last_used_before,omitempty"` + Revoked *bool `url:"revoked,omitempty" json:"revoked,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` +} + +// ListPersonalAccessTokens gets a list of all personal access tokens. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#list-all-personal-access-tokens +func (s *PersonalAccessTokensService) ListPersonalAccessTokens(opt *ListPersonalAccessTokensOptions, options ...RequestOptionFunc) ([]*PersonalAccessToken, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "personal_access_tokens", opt, options) + if err != nil { + return nil, nil, err + } + + var pats []*PersonalAccessToken + resp, err := s.client.Do(req, &pats) + if err != nil { + return nil, resp, err + } + + return pats, resp, nil +} + +// GetSinglePersonalAccessTokenByID get a single personal access token by its ID. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#get-details-on-a-personal-access-token +func (s *PersonalAccessTokensService) GetSinglePersonalAccessTokenByID(token int, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := fmt.Sprintf("personal_access_tokens/%d", token) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// GetSinglePersonalAccessToken get a single personal access token by using +// passing the token in a header. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#self-inform +func (s *PersonalAccessTokensService) GetSinglePersonalAccessToken(options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := "personal_access_tokens/self" + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotatePersonalAccessTokenOptions represents the available RotatePersonalAccessToken() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#rotate-a-personal-access-token +type RotatePersonalAccessTokenOptions struct { + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// RotatePersonalAccessToken is a backwards-compat shim for RotatePersonalAccessTokenByID. +func (s *PersonalAccessTokensService) RotatePersonalAccessToken(token int, opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + return s.RotatePersonalAccessTokenByID(token, opt, options...) +} + +// RotatePersonalAccessTokenByID revokes a token and returns a new token that +// expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#rotate-a-personal-access-token +func (s *PersonalAccessTokensService) RotatePersonalAccessTokenByID(token int, opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := fmt.Sprintf("personal_access_tokens/%d/rotate", token) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotatePersonalAccessTokenSelf revokes the currently authenticated token +// and returns a new token that expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#self-rotate +func (s *PersonalAccessTokensService) RotatePersonalAccessTokenSelf(opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := "personal_access_tokens/self/rotate" + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(PersonalAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RevokePersonalAccessToken is a backwards-compat shim for RevokePersonalAccessTokenByID. +func (s *PersonalAccessTokensService) RevokePersonalAccessToken(token int, options ...RequestOptionFunc) (*Response, error) { + return s.RevokePersonalAccessTokenByID(token, options...) +} + +// RevokePersonalAccessTokenByID revokes a personal access token by its ID. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#revoke-a-personal-access-token +func (s *PersonalAccessTokensService) RevokePersonalAccessTokenByID(token int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("personal_access_tokens/%d", token) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RevokePersonalAccessTokenSelf revokes the currently authenticated +// personal access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/personal_access_tokens/#self-revoke +func (s *PersonalAccessTokensService) RevokePersonalAccessTokenSelf(options ...RequestOptionFunc) (*Response, error) { + u := "personal_access_tokens/self" + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_schedules.go b/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_schedules.go new file mode 100644 index 000000000..2e2f156dd --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_schedules.go @@ -0,0 +1,409 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PipelineSchedulesServiceInterface interface { + ListPipelineSchedules(pid any, opt *ListPipelineSchedulesOptions, options ...RequestOptionFunc) ([]*PipelineSchedule, *Response, error) + GetPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) + ListPipelinesTriggeredBySchedule(pid any, schedule int, opt *ListPipelinesTriggeredByScheduleOptions, options ...RequestOptionFunc) ([]*Pipeline, *Response, error) + CreatePipelineSchedule(pid any, opt *CreatePipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) + EditPipelineSchedule(pid any, schedule int, opt *EditPipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) + TakeOwnershipOfPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) + DeletePipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*Response, error) + RunPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*Response, error) + CreatePipelineScheduleVariable(pid any, schedule int, opt *CreatePipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) + EditPipelineScheduleVariable(pid any, schedule int, key string, opt *EditPipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) + DeletePipelineScheduleVariable(pid any, schedule int, key string, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) + } + + // PipelineSchedulesService handles communication with the pipeline + // schedules related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/pipeline_schedules/ + PipelineSchedulesService struct { + client *Client + } +) + +var _ PipelineSchedulesServiceInterface = (*PipelineSchedulesService)(nil) + +// PipelineSchedule represents a pipeline schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/ +type PipelineSchedule struct { + ID int `json:"id"` + Description string `json:"description"` + Ref string `json:"ref"` + Cron string `json:"cron"` + CronTimezone string `json:"cron_timezone"` + NextRunAt *time.Time `json:"next_run_at"` + Active bool `json:"active"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Owner *User `json:"owner"` + LastPipeline *LastPipeline `json:"last_pipeline"` + Variables []*PipelineVariable `json:"variables"` + Inputs []*PipelineInput `json:"inputs"` +} + +// LastPipeline represents the last pipeline ran by schedule +// this will be returned only for individual schedule get operation +type LastPipeline struct { + ID int `json:"id"` + SHA string `json:"sha"` + Ref string `json:"ref"` + Status string `json:"status"` + WebURL string `json:"web_url"` +} + +// ListPipelineSchedulesOptions represents the available ListPipelineTriggers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipeline-schedules +type ListPipelineSchedulesOptions struct { + ListOptions + Scope *PipelineScheduleScopeValue `url:"scope,omitempty"` +} + +// ListPipelineSchedules gets a list of project triggers. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipeline-schedules +func (s *PipelineSchedulesService) ListPipelineSchedules(pid any, opt *ListPipelineSchedulesOptions, options ...RequestOptionFunc) ([]*PipelineSchedule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*PipelineSchedule + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// GetPipelineSchedule gets a pipeline schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-a-single-pipeline-schedule +func (s *PipelineSchedulesService) GetPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineSchedule) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ListPipelinesTriggeredByScheduleOptions represents the available +// ListPipelinesTriggeredBySchedule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipelines-triggered-by-a-pipeline-schedule +type ListPipelinesTriggeredByScheduleOptions ListOptions + +// ListPipelinesTriggeredBySchedule gets all pipelines triggered by a pipeline +// schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipelines-triggered-by-a-pipeline-schedule +func (s *PipelineSchedulesService) ListPipelinesTriggeredBySchedule(pid any, schedule int, opt *ListPipelinesTriggeredByScheduleOptions, options ...RequestOptionFunc) ([]*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/pipelines", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Pipeline + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreatePipelineScheduleOptions represents the available +// CreatePipelineSchedule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#create-a-new-pipeline-schedule +type CreatePipelineScheduleOptions struct { + Description *string `url:"description" json:"description"` + Ref *string `url:"ref" json:"ref"` + Cron *string `url:"cron" json:"cron"` + CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Inputs []*PipelineInput `url:"inputs,omitempty" json:"inputs,omitempty"` +} + +// CreatePipelineSchedule creates a pipeline schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#create-a-new-pipeline-schedule +func (s *PipelineSchedulesService) CreatePipelineSchedule(pid any, opt *CreatePipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineSchedule) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// EditPipelineScheduleOptions represents the available +// EditPipelineSchedule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#edit-a-pipeline-schedule +type EditPipelineScheduleOptions struct { + Description *string `url:"description,omitempty" json:"description,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Cron *string `url:"cron,omitempty" json:"cron,omitempty"` + CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Inputs []*PipelineInput `url:"inputs,omitempty" json:"inputs,omitempty"` +} + +// EditPipelineSchedule edits a pipeline schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#edit-a-pipeline-schedule +func (s *PipelineSchedulesService) EditPipelineSchedule(pid any, schedule int, opt *EditPipelineScheduleOptions, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineSchedule) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// TakeOwnershipOfPipelineSchedule sets the owner of the specified +// pipeline schedule to the user issuing the request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#take-ownership-of-a-pipeline-schedule +func (s *PipelineSchedulesService) TakeOwnershipOfPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*PipelineSchedule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/take_ownership", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineSchedule) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// DeletePipelineSchedule deletes a pipeline schedule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#delete-a-pipeline-schedule +func (s *PipelineSchedulesService) DeletePipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RunPipelineSchedule triggers a new scheduled pipeline to run immediately. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#run-a-scheduled-pipeline-immediately +func (s *PipelineSchedulesService) RunPipelineSchedule(pid any, schedule int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/play", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// CreatePipelineScheduleVariableOptions represents the available +// CreatePipelineScheduleVariable() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#create-a-new-pipeline-schedule +type CreatePipelineScheduleVariableOptions struct { + Key *string `url:"key" json:"key"` + Value *string `url:"value" json:"value"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// CreatePipelineScheduleVariable creates a pipeline schedule variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#create-a-new-pipeline-schedule +func (s *PipelineSchedulesService) CreatePipelineScheduleVariable(pid any, schedule int, opt *CreatePipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables", PathEscape(project), schedule) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineVariable) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// EditPipelineScheduleVariableOptions represents the available +// EditPipelineScheduleVariable() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#edit-a-pipeline-schedule-variable +type EditPipelineScheduleVariableOptions struct { + Value *string `url:"value" json:"value"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// EditPipelineScheduleVariable creates a pipeline schedule variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#edit-a-pipeline-schedule-variable +func (s *PipelineSchedulesService) EditPipelineScheduleVariable(pid any, schedule int, key string, opt *EditPipelineScheduleVariableOptions, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", PathEscape(project), schedule, key) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineVariable) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// DeletePipelineScheduleVariable creates a pipeline schedule variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#delete-a-pipeline-schedule-variable +func (s *PipelineSchedulesService) DeletePipelineScheduleVariable(pid any, schedule int, key string, options ...RequestOptionFunc) (*PipelineVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline_schedules/%d/variables/%s", PathEscape(project), schedule, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineVariable) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_triggers.go b/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_triggers.go new file mode 100644 index 000000000..deff0c89f --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pipeline_triggers.go @@ -0,0 +1,235 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + PipelineTriggersServiceInterface interface { + ListPipelineTriggers(pid any, opt *ListPipelineTriggersOptions, options ...RequestOptionFunc) ([]*PipelineTrigger, *Response, error) + GetPipelineTrigger(pid any, trigger int, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) + AddPipelineTrigger(pid any, opt *AddPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) + EditPipelineTrigger(pid any, trigger int, opt *EditPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) + DeletePipelineTrigger(pid any, trigger int, options ...RequestOptionFunc) (*Response, error) + RunPipelineTrigger(pid any, opt *RunPipelineTriggerOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) + } + + // PipelineTriggersService handles Project pipeline triggers. + // + // GitLab API docs: + // https://docs.gitlab.com/api/pipeline_triggers/ + PipelineTriggersService struct { + client *Client + } +) + +var _ PipelineTriggersServiceInterface = (*PipelineTriggersService)(nil) + +// PipelineTrigger represents a project pipeline trigger. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/ +type PipelineTrigger struct { + ID int `json:"id"` + Description string `json:"description"` + CreatedAt *time.Time `json:"created_at"` + DeletedAt *time.Time `json:"deleted_at"` + LastUsed *time.Time `json:"last_used"` + Token string `json:"token"` + UpdatedAt *time.Time `json:"updated_at"` + Owner *User `json:"owner"` +} + +// ListPipelineTriggersOptions represents the available ListPipelineTriggers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#list-project-trigger-tokens +type ListPipelineTriggersOptions ListOptions + +// ListPipelineTriggers gets a list of project triggers. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#list-project-trigger-tokens +func (s *PipelineTriggersService) ListPipelineTriggers(pid any, opt *ListPipelineTriggersOptions, options ...RequestOptionFunc) ([]*PipelineTrigger, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/triggers", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pt []*PipelineTrigger + resp, err := s.client.Do(req, &pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// GetPipelineTrigger gets a specific pipeline trigger for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#get-trigger-token-details +func (s *PipelineTriggersService) GetPipelineTrigger(pid any, trigger int, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/triggers/%d", PathEscape(project), trigger) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pt := new(PipelineTrigger) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// AddPipelineTriggerOptions represents the available AddPipelineTrigger() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#create-a-trigger-token +type AddPipelineTriggerOptions struct { + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// AddPipelineTrigger adds a pipeline trigger to a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#create-a-trigger-token +func (s *PipelineTriggersService) AddPipelineTrigger(pid any, opt *AddPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/triggers", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pt := new(PipelineTrigger) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// EditPipelineTriggerOptions represents the available EditPipelineTrigger() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#update-a-pipeline-trigger-token +type EditPipelineTriggerOptions struct { + Description *string `url:"description,omitempty" json:"description,omitempty"` +} + +// EditPipelineTrigger edits a trigger for a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#update-a-pipeline-trigger-token +func (s *PipelineTriggersService) EditPipelineTrigger(pid any, trigger int, opt *EditPipelineTriggerOptions, options ...RequestOptionFunc) (*PipelineTrigger, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/triggers/%d", PathEscape(project), trigger) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pt := new(PipelineTrigger) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// DeletePipelineTrigger removes a trigger from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#remove-a-pipeline-trigger-token +func (s *PipelineTriggersService) DeletePipelineTrigger(pid any, trigger int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/triggers/%d", PathEscape(project), trigger) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RunPipelineTriggerOptions represents the available RunPipelineTrigger() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#trigger-a-pipeline-with-a-token +type RunPipelineTriggerOptions struct { + Ref *string `url:"ref" json:"ref"` + Token *string `url:"token" json:"token"` + Variables map[string]string `url:"variables,omitempty" json:"variables,omitempty"` +} + +// RunPipelineTrigger starts a trigger from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_triggers/#trigger-a-pipeline-with-a-token +func (s *PipelineTriggersService) RunPipelineTrigger(pid any, opt *RunPipelineTriggerOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/trigger/pipeline", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pt := new(Pipeline) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/pipelines.go b/vendor/gitlab.com/gitlab-org/api/client-go/pipelines.go new file mode 100644 index 000000000..bf6768619 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/pipelines.go @@ -0,0 +1,501 @@ +// +// Copyright 2021, Igor Varavko +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type PipelineSource string + +// PipelineSource is the source of a pipeline. +// GitLab API docs: https://docs.gitlab.com/ci/jobs/job_rules/#ci_pipeline_source-predefined-variable +const ( + PipelineSourceAPI PipelineSource = "api" + PipelineSourceChat PipelineSource = "chat" + PipelineSourceExternal PipelineSource = "external" + PipelineSourceExternalPullRequestEvent PipelineSource = "external_pull_request_event" + PipelineSourceMergeRequestEvent PipelineSource = "merge_request_event" + PipelineSourceOndemandDastScan PipelineSource = "ondemand_dast_scan" + PipelineSourceOndemandDastValidation PipelineSource = "ondemand_dast_validation" + PipelineSourceParentPipeline PipelineSource = "parent_pipeline" + PipelineSourcePipeline PipelineSource = "pipeline" + PipelineSourcePush PipelineSource = "push" + PipelineSourceSchedule PipelineSource = "schedule" + PipelineSourceSecurityOrchestrationPolicy PipelineSource = "security_orchestration_policy" + PipelineSourceTrigger PipelineSource = "trigger" + PipelineSourceWeb PipelineSource = "web" + PipelineSourceWebIDE PipelineSource = "webide" +) + +type ( + PipelinesServiceInterface interface { + ListProjectPipelines(pid any, opt *ListProjectPipelinesOptions, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) + GetPipeline(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) + GetPipelineVariables(pid any, pipeline int, options ...RequestOptionFunc) ([]*PipelineVariable, *Response, error) + GetPipelineTestReport(pid any, pipeline int, options ...RequestOptionFunc) (*PipelineTestReport, *Response, error) + GetLatestPipeline(pid any, opt *GetLatestPipelineOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) + CreatePipeline(pid any, opt *CreatePipelineOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) + RetryPipelineBuild(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) + CancelPipelineBuild(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) + DeletePipeline(pid any, pipeline int, options ...RequestOptionFunc) (*Response, error) + UpdatePipelineMetadata(pid any, pipeline int, opt *UpdatePipelineMetadataOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) + } + + // PipelinesService handles communication with the repositories related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/pipelines/ + PipelinesService struct { + client *Client + } +) + +var _ PipelinesServiceInterface = (*PipelinesService)(nil) + +// PipelineVariable represents a pipeline variable. +// +// GitLab API docs: https://docs.gitlab.com/api/pipelines/ +type PipelineVariable struct { + Key string `json:"key"` + Value string `json:"value"` + VariableType VariableTypeValue `json:"variable_type"` +} + +// PipelineInput represents a pipeline input. +// +// GitLab API docs: https://docs.gitlab.com/api/pipelines/ +type PipelineInput struct { + Name string `json:"key"` + Value any `json:"value"` +} + +// Pipeline represents a GitLab pipeline. +// +// GitLab API docs: https://docs.gitlab.com/api/pipelines/ +type Pipeline struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Status string `json:"status"` + Source PipelineSource `json:"source"` + Ref string `json:"ref"` + Name string `json:"name"` + SHA string `json:"sha"` + BeforeSHA string `json:"before_sha"` + Tag bool `json:"tag"` + YamlErrors string `json:"yaml_errors"` + User *BasicUser `json:"user"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + StartedAt *time.Time `json:"started_at"` + FinishedAt *time.Time `json:"finished_at"` + CommittedAt *time.Time `json:"committed_at"` + Duration int `json:"duration"` + QueuedDuration int `json:"queued_duration"` + Coverage string `json:"coverage"` + WebURL string `json:"web_url"` + DetailedStatus *DetailedStatus `json:"detailed_status"` +} + +// DetailedStatus contains detailed information about the status of a pipeline. +type DetailedStatus struct { + Icon string `json:"icon"` + Text string `json:"text"` + Label string `json:"label"` + Group string `json:"group"` + Tooltip string `json:"tooltip"` + HasDetails bool `json:"has_details"` + DetailsPath string `json:"details_path"` + Illustration struct { + Image string `json:"image"` + } `json:"illustration"` + Favicon string `json:"favicon"` +} + +func (p Pipeline) String() string { + return Stringify(p) +} + +// PipelineTestReport contains a detailed report of a test run. +type PipelineTestReport struct { + TotalTime float64 `json:"total_time"` + TotalCount int `json:"total_count"` + SuccessCount int `json:"success_count"` + FailedCount int `json:"failed_count"` + SkippedCount int `json:"skipped_count"` + ErrorCount int `json:"error_count"` + TestSuites []*PipelineTestSuites `json:"test_suites"` +} + +// PipelineTestSuites contains test suites results. +type PipelineTestSuites struct { + Name string `json:"name"` + TotalTime float64 `json:"total_time"` + TotalCount int `json:"total_count"` + SuccessCount int `json:"success_count"` + FailedCount int `json:"failed_count"` + SkippedCount int `json:"skipped_count"` + ErrorCount int `json:"error_count"` + TestCases []*PipelineTestCases `json:"test_cases"` +} + +// PipelineTestCases contains test cases details. +type PipelineTestCases struct { + Status string `json:"status"` + Name string `json:"name"` + Classname string `json:"classname"` + File string `json:"file"` + ExecutionTime float64 `json:"execution_time"` + SystemOutput any `json:"system_output"` + StackTrace string `json:"stack_trace"` + AttachmentURL string `json:"attachment_url"` + RecentFailures *RecentFailures `json:"recent_failures"` +} + +// RecentFailures contains failures count for the project's default branch. +type RecentFailures struct { + Count int `json:"count"` + BaseBranch string `json:"base_branch"` +} + +func (p PipelineTestReport) String() string { + return Stringify(p) +} + +// PipelineInfo shows the basic entities of a pipeline, mostly used as fields +// on other assets, like Commit. +type PipelineInfo struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Status string `json:"status"` + Source string `json:"source"` + Ref string `json:"ref"` + SHA string `json:"sha"` + Name string `json:"name"` + WebURL string `json:"web_url"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` +} + +func (p PipelineInfo) String() string { + return Stringify(p) +} + +// ListProjectPipelinesOptions represents the available ListProjectPipelines() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#list-project-pipelines +type ListProjectPipelinesOptions struct { + ListOptions + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` + Status *BuildStateValue `url:"status,omitempty" json:"status,omitempty"` + Source *string `url:"source,omitempty" json:"source,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` + YamlErrors *bool `url:"yaml_errors,omitempty" json:"yaml_errors,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"` + UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListProjectPipelines gets a list of project piplines. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#list-project-pipelines +func (s *PipelinesService) ListProjectPipelines(pid any, opt *ListProjectPipelinesOptions, options ...RequestOptionFunc) ([]*PipelineInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*PipelineInfo + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetPipeline gets a single project pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#get-a-single-pipeline +func (s *PipelinesService) GetPipeline(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetPipelineVariables gets the variables of a single project pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#get-variables-of-a-pipeline +func (s *PipelinesService) GetPipelineVariables(pid any, pipeline int, options ...RequestOptionFunc) ([]*PipelineVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/variables", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var p []*PipelineVariable + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetPipelineTestReport gets the test report of a single project pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#get-a-pipelines-test-report +func (s *PipelinesService) GetPipelineTestReport(pid any, pipeline int, options ...RequestOptionFunc) (*PipelineTestReport, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/test_report", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(PipelineTestReport) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetLatestPipelineOptions represents the available GetLatestPipeline() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#get-the-latest-pipeline +type GetLatestPipelineOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// GetLatestPipeline gets the latest pipeline for a specific ref in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#get-the-latest-pipeline +func (s *PipelinesService) GetLatestPipeline(pid any, opt *GetLatestPipelineOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/latest", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreatePipelineOptions represents the available CreatePipeline() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#create-a-new-pipeline +type CreatePipelineOptions struct { + Ref *string `url:"ref" json:"ref"` + Variables *[]*PipelineVariableOptions `url:"variables,omitempty" json:"variables,omitempty"` +} + +// PipelineVariable represents a pipeline variable. +// +// GitLab API docs: https://docs.gitlab.com/api/pipelines/#create-a-new-pipeline +type PipelineVariableOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Value *string `url:"value,omitempty" json:"value,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// CreatePipeline creates a new project pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#create-a-new-pipeline +func (s *PipelinesService) CreatePipeline(pid any, opt *CreatePipelineOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipeline", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// RetryPipelineBuild retries failed builds in a pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#retry-jobs-in-a-pipeline +func (s *PipelinesService) RetryPipelineBuild(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/retry", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CancelPipelineBuild cancels a pipeline builds. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#cancel-a-pipelines-jobs +func (s *PipelinesService) CancelPipelineBuild(pid any, pipeline int, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/cancel", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// DeletePipeline deletes an existing pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#delete-a-pipeline +func (s *PipelinesService) DeletePipeline(pid any, pipeline int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdatePipelineMetadataOptions represents the available UpdatePipelineMetadata() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#update-pipeline-metadata +type UpdatePipelineMetadataOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// UpdatePipelineMetadata You can update the metadata of a pipeline. The metadata +// contains the name of the pipeline. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipelines/#update-pipeline-metadata +func (s *PipelinesService) UpdatePipelineMetadata(pid any, pipeline int, opt *UpdatePipelineMetadataOptions, options ...RequestOptionFunc) (*Pipeline, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/pipelines/%d/metadata", PathEscape(project), pipeline) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Pipeline) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/plan_limits.go b/vendor/gitlab.com/gitlab-org/api/client-go/plan_limits.go new file mode 100644 index 000000000..4d4986057 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/plan_limits.go @@ -0,0 +1,113 @@ +// +// Copyright 2021, Igor Varavko +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import "net/http" + +type ( + PlanLimitsServiceInterface interface { + GetCurrentPlanLimits(opt *GetCurrentPlanLimitsOptions, options ...RequestOptionFunc) (*PlanLimit, *Response, error) + ChangePlanLimits(opt *ChangePlanLimitOptions, options ...RequestOptionFunc) (*PlanLimit, *Response, error) + } + + // PlanLimitsService handles communication with the repositories related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/plan_limits/ + PlanLimitsService struct { + client *Client + } +) + +var _ PlanLimitsServiceInterface = (*PlanLimitsService)(nil) + +// PlanLimit represents a GitLab pipeline. +// +// GitLab API docs: https://docs.gitlab.com/api/plan_limits/ +type PlanLimit struct { + ConanMaxFileSize int `json:"conan_max_file_size,omitempty"` + GenericPackagesMaxFileSize int `json:"generic_packages_max_file_size,omitempty"` + HelmMaxFileSize int `json:"helm_max_file_size,omitempty"` + MavenMaxFileSize int `json:"maven_max_file_size,omitempty"` + NPMMaxFileSize int `json:"npm_max_file_size,omitempty"` + NugetMaxFileSize int `json:"nuget_max_file_size,omitempty"` + PyPiMaxFileSize int `json:"pypi_max_file_size,omitempty"` + TerraformModuleMaxFileSize int `json:"terraform_module_max_file_size,omitempty"` +} + +// GetCurrentPlanLimitsOptions represents the available GetCurrentPlanLimits() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/plan_limits/#get-current-plan-limits +type GetCurrentPlanLimitsOptions struct { + PlanName *string `url:"plan_name,omitempty" json:"plan_name,omitempty"` +} + +// List the current limits of a plan on the GitLab instance. +// +// GitLab API docs: +// https://docs.gitlab.com/api/plan_limits/#get-current-plan-limits +func (s *PlanLimitsService) GetCurrentPlanLimits(opt *GetCurrentPlanLimitsOptions, options ...RequestOptionFunc) (*PlanLimit, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "application/plan_limits", opt, options) + if err != nil { + return nil, nil, err + } + + pl := new(PlanLimit) + resp, err := s.client.Do(req, pl) + if err != nil { + return nil, resp, err + } + + return pl, resp, nil +} + +// ChangePlanLimitOptions represents the available ChangePlanLimits() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/plan_limits/#change-plan-limits +type ChangePlanLimitOptions struct { + PlanName *string `url:"plan_name,omitempty" json:"plan_name,omitempty"` + ConanMaxFileSize *int `url:"conan_max_file_size,omitempty" json:"conan_max_file_size,omitempty"` + GenericPackagesMaxFileSize *int `url:"generic_packages_max_file_size,omitempty" json:"generic_packages_max_file_size,omitempty"` + HelmMaxFileSize *int `url:"helm_max_file_size,omitempty" json:"helm_max_file_size,omitempty"` + MavenMaxFileSize *int `url:"maven_max_file_size,omitempty" json:"maven_max_file_size,omitempty"` + NPMMaxFileSize *int `url:"npm_max_file_size,omitempty" json:"npm_max_file_size,omitempty"` + NugetMaxFileSize *int `url:"nuget_max_file_size,omitempty" json:"nuget_max_file_size,omitempty"` + PyPiMaxFileSize *int `url:"pypi_max_file_size,omitempty" json:"pypi_max_file_size,omitempty"` + TerraformModuleMaxFileSize *int `url:"terraform_module_max_file_size,omitempty" json:"terraform_module_max_file_size,omitempty"` +} + +// ChangePlanLimits modifies the limits of a plan on the GitLab instance. +// +// GitLab API docs: +// https://docs.gitlab.com/api/plan_limits/#change-plan-limits +func (s *PlanLimitsService) ChangePlanLimits(opt *ChangePlanLimitOptions, options ...RequestOptionFunc) (*PlanLimit, *Response, error) { + req, err := s.client.NewRequest(http.MethodPut, "application/plan_limits", opt, options) + if err != nil { + return nil, nil, err + } + + pl := new(PlanLimit) + resp, err := s.client.Do(req, pl) + if err != nil { + return nil, resp, err + } + + return pl, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_access_tokens.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_access_tokens.go new file mode 100644 index 000000000..e98e65855 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_access_tokens.go @@ -0,0 +1,231 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ProjectAccessTokensServiceInterface interface { + ListProjectAccessTokens(pid any, opt *ListProjectAccessTokensOptions, options ...RequestOptionFunc) ([]*ProjectAccessToken, *Response, error) + GetProjectAccessToken(pid any, id int, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) + CreateProjectAccessToken(pid any, opt *CreateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) + RotateProjectAccessToken(pid any, id int, opt *RotateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) + RotateProjectAccessTokenSelf(pid any, opt *RotateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) + RevokeProjectAccessToken(pid any, id int, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectAccessTokensService handles communication with the + // project access tokens related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_access_tokens/ + ProjectAccessTokensService struct { + client *Client + } +) + +var _ ProjectAccessTokensServiceInterface = (*ProjectAccessTokensService)(nil) + +// ProjectAccessToken represents a GitLab project access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/ +type ProjectAccessToken resourceAccessToken + +func (v ProjectAccessToken) String() string { + return Stringify(v) +} + +// ListProjectAccessTokensOptions represents the available +// ListProjectAccessTokens() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#list-all-project-access-tokens +type ListProjectAccessTokensOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` +} + +// ListProjectAccessTokens gets a list of all project access tokens in a +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#list-all-project-access-tokens +func (s *ProjectAccessTokensService) ListProjectAccessTokens(pid any, opt *ListProjectAccessTokensOptions, options ...RequestOptionFunc) ([]*ProjectAccessToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pats []*ProjectAccessToken + resp, err := s.client.Do(req, &pats) + if err != nil { + return nil, resp, err + } + + return pats, resp, nil +} + +// GetProjectAccessToken gets a single project access tokens in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#get-details-on-a-project-access-token +func (s *ProjectAccessTokensService) GetProjectAccessToken(pid any, id int, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pat := new(ProjectAccessToken) + resp, err := s.client.Do(req, &pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// CreateProjectAccessTokenOptions represents the available CreateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#create-a-project-access-token +type CreateProjectAccessTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// CreateProjectAccessToken creates a new project access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#create-a-project-access-token +func (s *ProjectAccessTokensService) CreateProjectAccessToken(pid any, opt *CreateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(ProjectAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotateProjectAccessTokenOptions represents the available RotateProjectAccessToken() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#rotate-a-project-access-token +type RotateProjectAccessTokenOptions struct { + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// RotateProjectAccessToken revokes a project access token and returns a new +// project access token that expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#rotate-a-project-access-token +func (s *ProjectAccessTokensService) RotateProjectAccessToken(pid any, id int, opt *RotateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) { + projects, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens/%d/rotate", PathEscape(projects), id) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(ProjectAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RotateProjectAccessTokenSelf revokes the project access token used for the request +// and returns a new project access token that expires in one week per default. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#self-rotate +func (s *ProjectAccessTokensService) RotateProjectAccessTokenSelf(pid any, opt *RotateProjectAccessTokenOptions, options ...RequestOptionFunc) (*ProjectAccessToken, *Response, error) { + projects, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens/self/rotate", PathEscape(projects)) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pat := new(ProjectAccessToken) + resp, err := s.client.Do(req, pat) + if err != nil { + return nil, resp, err + } + + return pat, resp, nil +} + +// RevokeProjectAccessToken revokes a project access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_access_tokens/#revoke-a-project-access-token +func (s *ProjectAccessTokensService) RevokeProjectAccessToken(pid any, id int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/access_tokens/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_badges.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_badges.go new file mode 100644 index 000000000..c65daa389 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_badges.go @@ -0,0 +1,243 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ProjectBadgesServiceInterface interface { + ListProjectBadges(pid any, opt *ListProjectBadgesOptions, options ...RequestOptionFunc) ([]*ProjectBadge, *Response, error) + GetProjectBadge(pid any, badge int, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) + AddProjectBadge(pid any, opt *AddProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) + EditProjectBadge(pid any, badge int, opt *EditProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) + DeleteProjectBadge(pid any, badge int, options ...RequestOptionFunc) (*Response, error) + PreviewProjectBadge(pid any, opt *ProjectBadgePreviewOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) + } + + // ProjectBadgesService handles communication with the project badges + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/project_badges/ + ProjectBadgesService struct { + client *Client + } +) + +var _ ProjectBadgesServiceInterface = (*ProjectBadgesService)(nil) + +// ProjectBadge represents a project badge. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#list-all-badges-of-a-project +type ProjectBadge struct { + ID int `json:"id"` + Name string `json:"name"` + LinkURL string `json:"link_url"` + ImageURL string `json:"image_url"` + RenderedLinkURL string `json:"rendered_link_url"` + RenderedImageURL string `json:"rendered_image_url"` + // Kind represents a project badge kind. Can be empty, when used PreviewProjectBadge(). + Kind string `json:"kind"` +} + +// ListProjectBadgesOptions represents the available ListProjectBadges() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#list-all-badges-of-a-project +type ListProjectBadgesOptions struct { + ListOptions + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// ListProjectBadges gets a list of a project's badges and its group badges. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#list-all-badges-of-a-project +func (s *ProjectBadgesService) ListProjectBadges(pid any, opt *ListProjectBadgesOptions, options ...RequestOptionFunc) ([]*ProjectBadge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/badges", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pb []*ProjectBadge + resp, err := s.client.Do(req, &pb) + if err != nil { + return nil, resp, err + } + + return pb, resp, nil +} + +// GetProjectBadge gets a project badge. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#get-a-badge-of-a-project +func (s *ProjectBadgesService) GetProjectBadge(pid any, badge int, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/badges/%d", PathEscape(project), badge) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pb := new(ProjectBadge) + resp, err := s.client.Do(req, pb) + if err != nil { + return nil, resp, err + } + + return pb, resp, nil +} + +// AddProjectBadgeOptions represents the available AddProjectBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#add-a-badge-to-a-project +type AddProjectBadgeOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// AddProjectBadge adds a badge to a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#add-a-badge-to-a-project +func (s *ProjectBadgesService) AddProjectBadge(pid any, opt *AddProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/badges", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pb := new(ProjectBadge) + resp, err := s.client.Do(req, pb) + if err != nil { + return nil, resp, err + } + + return pb, resp, nil +} + +// EditProjectBadgeOptions represents the available EditProjectBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#edit-a-badge-of-a-project +type EditProjectBadgeOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// EditProjectBadge updates a badge of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#edit-a-badge-of-a-project +func (s *ProjectBadgesService) EditProjectBadge(pid any, badge int, opt *EditProjectBadgeOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/badges/%d", PathEscape(project), badge) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pb := new(ProjectBadge) + resp, err := s.client.Do(req, pb) + if err != nil { + return nil, resp, err + } + + return pb, resp, nil +} + +// DeleteProjectBadge removes a badge from a project. Only project's +// badges will be removed by using this endpoint. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#remove-a-badge-from-a-project +func (s *ProjectBadgesService) DeleteProjectBadge(pid any, badge int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/badges/%d", PathEscape(project), badge) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectBadgePreviewOptions represents the available PreviewProjectBadge() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#preview-a-badge-from-a-project +type ProjectBadgePreviewOptions struct { + LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"` + ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"` +} + +// PreviewProjectBadge returns how the link_url and image_url final URLs would be after +// resolving the placeholder interpolation. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_badges/#preview-a-badge-from-a-project +func (s *ProjectBadgesService) PreviewProjectBadge(pid any, opt *ProjectBadgePreviewOptions, options ...RequestOptionFunc) (*ProjectBadge, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/badges/render", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + pb := new(ProjectBadge) + resp, err := s.client.Do(req, &pb) + if err != nil { + return nil, resp, err + } + + return pb, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/project_clusters.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_clusters.go similarity index 61% rename from vendor/github.com/xanzy/go-gitlab/project_clusters.go rename to vendor/gitlab.com/gitlab-org/api/client-go/project_clusters.go index d6802da0a..0572e1b61 100644 --- a/vendor/github.com/xanzy/go-gitlab/project_clusters.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_clusters.go @@ -1,5 +1,5 @@ // -// Copyright 2019, Matej Velikonja +// Copyright 2021, Matej Velikonja // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,21 +18,43 @@ package gitlab import ( "fmt" + "net/http" "time" ) -// ProjectClustersService handles communication with the -// project clusters related methods of the GitLab API. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html -type ProjectClustersService struct { - client *Client -} +type ( + // Deprecated: in GitLab 14.5, to be removed in 19.0 + ProjectClustersServiceInterface interface { + // Deprecated: in GitLab 14.5, to be removed in 19.0 + ListClusters(pid any, options ...RequestOptionFunc) ([]*ProjectCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + GetCluster(pid any, cluster int, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + AddCluster(pid any, opt *AddClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + EditCluster(pid any, cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) + // Deprecated: in GitLab 14.5, to be removed in 19.0 + DeleteCluster(pid any, cluster int, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectClustersService handles communication with the + // project clusters related methods of the GitLab API. + // Deprecated: in GitLab 14.5, to be removed in 19.0 + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_clusters/ + ProjectClustersService struct { + client *Client + } +) + +// Deprecated: in GitLab 14.5, to be removed in 19.0 +var _ ProjectClustersServiceInterface = (*ProjectClustersService)(nil) // ProjectCluster represents a GitLab Project Cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // -// GitLab API docs: https://docs.gitlab.com/ee/api/project_clusters.html +// GitLab API docs: https://docs.gitlab.com/api/project_clusters/ type ProjectCluster struct { ID int `json:"id"` Name string `json:"name"` @@ -48,11 +70,13 @@ type ProjectCluster struct { Project *Project `json:"project"` } +// Deprecated: in GitLab 14.5, to be removed in 19.0 func (v ProjectCluster) String() string { return Stringify(v) } // PlatformKubernetes represents a GitLab Project Cluster PlatformKubernetes. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type PlatformKubernetes struct { APIURL string `json:"api_url"` Token string `json:"token"` @@ -62,6 +86,7 @@ type PlatformKubernetes struct { } // ManagementProject represents a GitLab Project Cluster management_project. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type ManagementProject struct { ID int `json:"id"` Description string `json:"description"` @@ -73,17 +98,18 @@ type ManagementProject struct { } // ListClusters gets a list of all clusters in a project. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#list-project-clusters -func (s *ProjectClustersService) ListClusters(pid interface{}, options ...RequestOptionFunc) ([]*ProjectCluster, *Response, error) { +// https://docs.gitlab.com/api/project_clusters/#list-project-clusters +func (s *ProjectClustersService) ListClusters(pid any, options ...RequestOptionFunc) ([]*ProjectCluster, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/clusters", pathEscape(project)) + u := fmt.Sprintf("projects/%s/clusters", PathEscape(project)) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -94,21 +120,22 @@ func (s *ProjectClustersService) ListClusters(pid interface{}, options ...Reques return nil, resp, err } - return pcs, resp, err + return pcs, resp, nil } // GetCluster gets a cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#get-a-single-project-cluster -func (s *ProjectClustersService) GetCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { +// https://docs.gitlab.com/api/project_clusters/#get-a-single-project-cluster +func (s *ProjectClustersService) GetCluster(pid any, cluster int, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/clusters/%d", pathEscape(project), cluster) + u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -119,13 +146,14 @@ func (s *ProjectClustersService) GetCluster(pid interface{}, cluster int, option return nil, resp, err } - return pc, resp, err + return pc, resp, nil } // AddClusterOptions represents the available AddCluster() options. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#add-existing-cluster-to-project +// https://docs.gitlab.com/api/project_clusters/#add-existing-cluster-to-project type AddClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` @@ -137,6 +165,7 @@ type AddClusterOptions struct { } // AddPlatformKubernetesOptions represents the available PlatformKubernetes options for adding. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type AddPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` @@ -146,17 +175,18 @@ type AddPlatformKubernetesOptions struct { } // AddCluster adds an existing cluster to the project. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#add-existing-cluster-to-project -func (s *ProjectClustersService) AddCluster(pid interface{}, opt *AddClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { +// https://docs.gitlab.com/api/project_clusters/#add-existing-cluster-to-project +func (s *ProjectClustersService) AddCluster(pid any, opt *AddClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/clusters/user", pathEscape(project)) + u := fmt.Sprintf("projects/%s/clusters/user", PathEscape(project)) - req, err := s.client.NewRequest("POST", u, opt, options) + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } @@ -167,13 +197,14 @@ func (s *ProjectClustersService) AddCluster(pid interface{}, opt *AddClusterOpti return nil, resp, err } - return pc, resp, err + return pc, resp, nil } // EditClusterOptions represents the available EditCluster() options. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#edit-project-cluster +// https://docs.gitlab.com/api/project_clusters/#edit-project-cluster type EditClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` @@ -183,6 +214,7 @@ type EditClusterOptions struct { } // EditPlatformKubernetesOptions represents the available PlatformKubernetes options for editing. +// Deprecated: in GitLab 14.5, to be removed in 19.0 type EditPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` @@ -191,17 +223,18 @@ type EditPlatformKubernetesOptions struct { } // EditCluster updates an existing project cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#edit-project-cluster -func (s *ProjectClustersService) EditCluster(pid interface{}, cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { +// https://docs.gitlab.com/api/project_clusters/#edit-project-cluster +func (s *ProjectClustersService) EditCluster(pid any, cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*ProjectCluster, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/clusters/%d", pathEscape(project), cluster) + u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) - req, err := s.client.NewRequest("PUT", u, opt, options) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } @@ -212,21 +245,22 @@ func (s *ProjectClustersService) EditCluster(pid interface{}, cluster int, opt * return nil, resp, err } - return pc, resp, err + return pc, resp, nil } // DeleteCluster deletes an existing project cluster. +// Deprecated: in GitLab 14.5, to be removed in 19.0 // // GitLab API docs: -// https://docs.gitlab.com/ee/api/project_clusters.html#delete-project-cluster -func (s *ProjectClustersService) DeleteCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*Response, error) { +// https://docs.gitlab.com/api/project_clusters/#delete-project-cluster +func (s *ProjectClustersService) DeleteCluster(pid any, cluster int, options ...RequestOptionFunc) (*Response, error) { project, err := parseID(pid) if err != nil { return nil, err } - u := fmt.Sprintf("projects/%s/clusters/%d", pathEscape(project), cluster) + u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_feature_flags.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_feature_flags.go new file mode 100644 index 000000000..53491bccf --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_feature_flags.go @@ -0,0 +1,258 @@ +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectFeatureFlagServiceInterface interface { + ListProjectFeatureFlags(pid any, opt *ListProjectFeatureFlagOptions, options ...RequestOptionFunc) ([]*ProjectFeatureFlag, *Response, error) + GetProjectFeatureFlag(pid any, name string, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) + CreateProjectFeatureFlag(pid any, opt *CreateProjectFeatureFlagOptions, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) + UpdateProjectFeatureFlag(pid any, name string, opt *UpdateProjectFeatureFlagOptions, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) + DeleteProjectFeatureFlag(pid any, name string, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectFeatureFlagService handles operations on gitlab project feature + // flags using the following api: + // + // GitLab API docs: https://docs.gitlab.com/api/feature_flags/ + ProjectFeatureFlagService struct { + client *Client + } +) + +var _ ProjectFeatureFlagServiceInterface = (*ProjectFeatureFlagService)(nil) + +// ProjectFeatureFlag represents a GitLab project iteration. +// +// GitLab API docs: https://docs.gitlab.com/api/feature_flags/ +type ProjectFeatureFlag struct { + Name string `json:"name"` + Description string `json:"description"` + Active bool `json:"active"` + Version string `json:"version"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Scopes []*ProjectFeatureFlagScope `json:"scopes"` + Strategies []*ProjectFeatureFlagStrategy `json:"strategies"` +} + +// ProjectFeatureFlagScope defines the scopes of a feature flag +// +// GitLab API docs: https://docs.gitlab.com/api/feature_flags/ +type ProjectFeatureFlagScope struct { + ID int `json:"id"` + EnvironmentScope string `json:"environment_scope"` +} + +// ProjectFeatureFlagStrategy defines the strategy used for a feature flag +// +// GitLab API docs: https://docs.gitlab.com/api/feature_flags/ +type ProjectFeatureFlagStrategy struct { + ID int `json:"id"` + Name string `json:"name"` + Parameters *ProjectFeatureFlagStrategyParameter `json:"parameters"` + Scopes []*ProjectFeatureFlagScope `json:"scopes"` +} + +// ProjectFeatureFlagStrategyParameter is used in updating and creating feature flags +// +// GitLab API docs: https://docs.gitlab.com/api/feature_flags/ +type ProjectFeatureFlagStrategyParameter struct { + GroupID string `json:"groupId,omitempty"` + UserIDs string `json:"userIds,omitempty"` + Percentage string `json:"percentage,omitempty"` + + // Following fields aren't documented in Gitlab API docs, + // but are present in Gitlab API since 13.5. + // Docs: https://docs.getunleash.io/reference/activation-strategies#gradual-rollout + Rollout string `json:"rollout,omitempty"` + Stickiness string `json:"stickiness,omitempty"` +} + +func (i ProjectFeatureFlag) String() string { + return Stringify(i) +} + +// ListProjectFeatureFlagOptions contains the options for ListProjectFeatureFlags +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flags/#list-feature-flags-for-a-project +type ListProjectFeatureFlagOptions struct { + ListOptions + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` +} + +// ListProjectFeatureFlags returns a list with the feature flags of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flags/#list-feature-flags-for-a-project +func (s *ProjectFeatureFlagService) ListProjectFeatureFlags(pid any, opt *ListProjectFeatureFlagOptions, options ...RequestOptionFunc) ([]*ProjectFeatureFlag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pffs []*ProjectFeatureFlag + resp, err := s.client.Do(req, &pffs) + if err != nil { + return nil, resp, err + } + + return pffs, resp, nil +} + +// GetProjectFeatureFlag gets a single feature flag for the specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/feature_flags/#get-a-single-feature-flag +func (s *ProjectFeatureFlagService) GetProjectFeatureFlag(pid any, name string, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags/%s", PathEscape(project), name) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + flag := new(ProjectFeatureFlag) + resp, err := s.client.Do(req, flag) + if err != nil { + return nil, resp, err + } + + return flag, resp, nil +} + +// CreateProjectFeatureFlagOptions represents the available +// CreateProjectFeatureFlag() options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#create-a-feature-flag +type CreateProjectFeatureFlagOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Version *string `url:"version,omitempty" json:"version,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Strategies *[]*FeatureFlagStrategyOptions `url:"strategies,omitempty" json:"strategies,omitempty"` +} + +// FeatureFlagStrategyOptions represents the available feature flag strategy +// options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#create-a-feature-flag +type FeatureFlagStrategyOptions struct { + ID *int `url:"id,omitempty" json:"id,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Parameters *ProjectFeatureFlagStrategyParameter `url:"parameters,omitempty" json:"parameters,omitempty"` + Scopes *[]*ProjectFeatureFlagScope `url:"scopes,omitempty" json:"scopes,omitempty"` +} + +// ProjectFeatureFlagScopeOptions represents the available feature flag scope +// options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#create-a-feature-flag +type ProjectFeatureFlagScopeOptions struct { + ID *int `url:"id,omitempty" json:"id,omitempty"` + EnvironmentScope *string `url:"id,omitempty" json:"environment_scope,omitempty"` +} + +// CreateProjectFeatureFlag creates a feature flag +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#create-a-feature-flag +func (s *ProjectFeatureFlagService) CreateProjectFeatureFlag(pid any, opt *CreateProjectFeatureFlagOptions, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags", + PathEscape(project), + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + flag := new(ProjectFeatureFlag) + resp, err := s.client.Do(req, flag) + if err != nil { + return flag, resp, err + } + + return flag, resp, nil +} + +// UpdateProjectFeatureFlagOptions represents the available +// UpdateProjectFeatureFlag() options. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#update-a-feature-flag +type UpdateProjectFeatureFlagOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Strategies *[]*FeatureFlagStrategyOptions `url:"strategies,omitempty" json:"strategies,omitempty"` +} + +// UpdateProjectFeatureFlag updates a feature flag +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#update-a-feature-flag +func (s *ProjectFeatureFlagService) UpdateProjectFeatureFlag(pid any, name string, opt *UpdateProjectFeatureFlagOptions, options ...RequestOptionFunc) (*ProjectFeatureFlag, *Response, error) { + group, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags/%s", + PathEscape(group), + name, + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + flag := new(ProjectFeatureFlag) + resp, err := s.client.Do(req, flag) + if err != nil { + return flag, resp, err + } + + return flag, resp, nil +} + +// DeleteProjectFeatureFlag deletes a feature flag +// +// Gitlab API docs: +// https://docs.gitlab.com/api/feature_flags/#delete-a-feature-flag +func (s *ProjectFeatureFlagService) DeleteProjectFeatureFlag(pid any, name string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/feature_flags/%s", PathEscape(project), name) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_import_export.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_import_export.go new file mode 100644 index 000000000..eab7e3edf --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_import_export.go @@ -0,0 +1,237 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/http" + "time" +) + +type ( + ProjectImportExportServiceInterface interface { + ScheduleExport(pid any, opt *ScheduleExportOptions, options ...RequestOptionFunc) (*Response, error) + ExportStatus(pid any, options ...RequestOptionFunc) (*ExportStatus, *Response, error) + ExportDownload(pid any, options ...RequestOptionFunc) ([]byte, *Response, error) + ImportFromFile(archive io.Reader, opt *ImportFileOptions, options ...RequestOptionFunc) (*ImportStatus, *Response, error) + ImportStatus(pid any, options ...RequestOptionFunc) (*ImportStatus, *Response, error) + } + + // ProjectImportExportService handles communication with the project + // import/export related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_import_export/ + ProjectImportExportService struct { + client *Client + } +) + +var _ ProjectImportExportServiceInterface = (*ProjectImportExportService)(nil) + +// ImportStatus represents a project import status. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#import-status +type ImportStatus struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreateAt *time.Time `json:"create_at"` + ImportStatus string `json:"import_status"` + ImportType string `json:"import_type"` + CorrelationID string `json:"correlation_id"` + ImportError string `json:"import_error"` +} + +func (s ImportStatus) String() string { + return Stringify(s) +} + +// ExportStatus represents a project export status. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#export-status +type ExportStatus struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreatedAt *time.Time `json:"created_at"` + ExportStatus string `json:"export_status"` + Message string `json:"message"` + Links struct { + APIURL string `json:"api_url"` + WebURL string `json:"web_url"` + } `json:"_links"` +} + +func (s ExportStatus) String() string { + return Stringify(s) +} + +// ScheduleExportOptions represents the available ScheduleExport() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#schedule-an-export +type ScheduleExportOptions struct { + Description *string `url:"description,omitempty" json:"description,omitempty"` + Upload struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + HTTPMethod *string `url:"http_method,omitempty" json:"http_method,omitempty"` + } `url:"upload,omitempty" json:"upload,omitempty"` +} + +// ScheduleExport schedules a project export. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#schedule-an-export +func (s *ProjectImportExportService) ScheduleExport(pid any, opt *ScheduleExportOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/export", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ExportStatus get the status of export. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#export-status +func (s *ProjectImportExportService) ExportStatus(pid any, options ...RequestOptionFunc) (*ExportStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/export", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + es := new(ExportStatus) + resp, err := s.client.Do(req, es) + if err != nil { + return nil, resp, err + } + + return es, resp, nil +} + +// ExportDownload download the finished export. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#export-download +func (s *ProjectImportExportService) ExportDownload(pid any, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/export/download", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// ImportFileOptions represents the available ImportFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#import-a-file +type ImportFileOptions struct { + Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Overwrite *bool `url:"overwrite,omitempty" json:"overwrite,omitempty"` + OverrideParams *CreateProjectOptions `url:"override_params,omitempty" json:"override_params,omitempty"` +} + +// Import a project from an archive file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#import-a-file +func (s *ProjectImportExportService) ImportFromFile(archive io.Reader, opt *ImportFileOptions, options ...RequestOptionFunc) (*ImportStatus, *Response, error) { + req, err := s.client.UploadRequest( + http.MethodPost, + "projects/import", + archive, + "archive.tar.gz", + UploadFile, + opt, + options, + ) + if err != nil { + return nil, nil, err + } + + is := new(ImportStatus) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} + +// ImportStatus get the status of an import. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_import_export/#import-status +func (s *ProjectImportExportService) ImportStatus(pid any, options ...RequestOptionFunc) (*ImportStatus, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/import", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + is := new(ImportStatus) + resp, err := s.client.Do(req, is) + if err != nil { + return nil, resp, err + } + + return is, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_iterations.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_iterations.go new file mode 100644 index 000000000..2495e4cfa --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_iterations.go @@ -0,0 +1,98 @@ +// +// Copyright 2022, Daniel Steinke +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectIterationsServiceInterface interface { + ListProjectIterations(pid any, opt *ListProjectIterationsOptions, options ...RequestOptionFunc) ([]*ProjectIteration, *Response, error) + } + + // ProjectIterationsService handles communication with the project iterations related + // methods of the GitLab API + // + // GitLab API docs: https://docs.gitlab.com/api/iterations/ + ProjectIterationsService struct { + client *Client + } +) + +var _ ProjectIterationsServiceInterface = (*ProjectIterationsService)(nil) + +// ProjectIteration represents a GitLab project iteration. +// +// GitLab API docs: https://docs.gitlab.com/api/iterations/ +type ProjectIteration struct { + ID int `json:"id"` + IID int `json:"iid"` + Sequence int `json:"sequence"` + GroupID int `json:"group_id"` + Title string `json:"title"` + Description string `json:"description"` + State int `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + DueDate *ISOTime `json:"due_date"` + StartDate *ISOTime `json:"start_date"` + WebURL string `json:"web_url"` +} + +func (i ProjectIteration) String() string { + return Stringify(i) +} + +// ListProjectIterationsOptions contains the available ListProjectIterations() +// options +// +// GitLab API docs: +// https://docs.gitlab.com/api/iterations/#list-project-iterations +type ListProjectIterationsOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"` +} + +// ListProjectIterations returns a list of projects iterations. +// +// GitLab API docs: +// https://docs.gitlab.com/api/iterations/#list-project-iterations +func (i *ProjectIterationsService) ListProjectIterations(pid any, opt *ListProjectIterationsOptions, options ...RequestOptionFunc) ([]*ProjectIteration, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/iterations", PathEscape(project)) + + req, err := i.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pis []*ProjectIteration + resp, err := i.client.Do(req, &pis) + if err != nil { + return nil, resp, err + } + + return pis, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_markdown_uploads.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_markdown_uploads.go new file mode 100644 index 000000000..b7d0ea307 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_markdown_uploads.go @@ -0,0 +1,134 @@ +// +// Copyright 2024, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "io" + "net/http" +) + +type ( + ProjectMarkdownUploadsServiceInterface interface { + UploadProjectMarkdown(pid any, content io.Reader, filename string, options ...RequestOptionFunc) (*ProjectMarkdownUploadedFile, *Response, error) + ListProjectMarkdownUploads(pid any, options ...RequestOptionFunc) ([]*ProjectMarkdownUpload, *Response, error) + DownloadProjectMarkdownUploadByID(pid any, uploadID int, options ...RequestOptionFunc) ([]byte, *Response, error) + DownloadProjectMarkdownUploadBySecretAndFilename(pid any, secret string, filename string, options ...RequestOptionFunc) ([]byte, *Response, error) + DeleteProjectMarkdownUploadByID(pid any, uploadID int, options ...RequestOptionFunc) (*Response, error) + DeleteProjectMarkdownUploadBySecretAndFilename(pid any, secret string, filename string, options ...RequestOptionFunc) (*Response, error) + } + + // MarkdownUploadsService handles communication with the project + // markdown uploads related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_markdown_uploads/ + ProjectMarkdownUploadsService struct { + client *Client + } +) + +var _ ProjectMarkdownUploadsServiceInterface = (*ProjectMarkdownUploadsService)(nil) + +// Type aliases for backward compatibility +type ( + ProjectMarkdownUpload = MarkdownUpload + ProjectMarkdownUploadedFile = MarkdownUploadedFile +) + +// UploadProjectMarkdown uploads a markdown file to a project. +// +// GitLab docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#upload-a-file +func (s *ProjectMarkdownUploadsService) UploadProjectMarkdown(pid any, content io.Reader, filename string, options ...RequestOptionFunc) (*ProjectMarkdownUploadedFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/uploads", PathEscape(project)) + + req, err := s.client.UploadRequest( + http.MethodPost, + u, + content, + filename, + UploadFile, + nil, + options, + ) + if err != nil { + return nil, nil, err + } + + f := new(ProjectMarkdownUploadedFile) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, nil +} + +// ListProjectMarkdownUploads gets all markdown uploads for a project. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#list-uploads +func (s *ProjectMarkdownUploadsService) ListProjectMarkdownUploads(pid any, options ...RequestOptionFunc) ([]*ProjectMarkdownUpload, *Response, error) { + return listMarkdownUploads[ProjectMarkdownUpload](s.client, ProjectResource, pid, nil, options) +} + +// DownloadProjectMarkdownUploadByID downloads a specific upload by ID. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#download-an-uploaded-file-by-id +func (s *ProjectMarkdownUploadsService) DownloadProjectMarkdownUploadByID(pid any, uploadID int, options ...RequestOptionFunc) ([]byte, *Response, error) { + buffer, resp, err := downloadMarkdownUploadByID(s.client, ProjectResource, pid, uploadID, options) + if err != nil { + return nil, resp, err + } + return buffer.Bytes(), resp, nil +} + +// DownloadProjectMarkdownUploadBySecretAndFilename downloads a specific upload +// by secret and filename. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#download-an-uploaded-file-by-secret-and-filename +func (s *ProjectMarkdownUploadsService) DownloadProjectMarkdownUploadBySecretAndFilename(pid any, secret string, filename string, options ...RequestOptionFunc) ([]byte, *Response, error) { + buffer, resp, err := downloadMarkdownUploadBySecretAndFilename(s.client, ProjectResource, pid, secret, filename, options) + if err != nil { + return nil, resp, err + } + return buffer.Bytes(), resp, nil +} + +// DeleteProjectMarkdownUploadByID deletes an upload by ID. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#delete-an-uploaded-file-by-id +func (s *ProjectMarkdownUploadsService) DeleteProjectMarkdownUploadByID(pid any, uploadID int, options ...RequestOptionFunc) (*Response, error) { + return deleteMarkdownUploadByID(s.client, ProjectResource, pid, uploadID, options) +} + +// DeleteProjectMarkdownUploadBySecretAndFilename deletes an upload +// by secret and filename. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_markdown_uploads/#delete-an-uploaded-file-by-secret-and-filename +func (s *ProjectMarkdownUploadsService) DeleteProjectMarkdownUploadBySecretAndFilename(pid any, secret string, filename string, options ...RequestOptionFunc) (*Response, error) { + return deleteMarkdownUploadBySecretAndFilename(s.client, ProjectResource, pid, secret, filename, options) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_members.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_members.go new file mode 100644 index 000000000..fa4bbcef7 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_members.go @@ -0,0 +1,272 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectMembersServiceInterface interface { + ListProjectMembers(pid any, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) + ListAllProjectMembers(pid any, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) + GetProjectMember(pid any, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) + GetInheritedProjectMember(pid any, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) + AddProjectMember(pid any, opt *AddProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) + EditProjectMember(pid any, user int, opt *EditProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) + DeleteProjectMember(pid any, user int, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectMembersService handles communication with the project members + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/members/ + ProjectMembersService struct { + client *Client + } +) + +var _ ProjectMembersServiceInterface = (*ProjectMembersService)(nil) + +// ProjectMember represents a project member. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/ +type ProjectMember struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *ISOTime `json:"expires_at"` + AccessLevel AccessLevelValue `json:"access_level"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + MemberRole *MemberRole `json:"member_role"` +} + +// ListProjectMembersOptions represents the available ListProjectMembers() and +// ListAllProjectMembers() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project +type ListProjectMembersOptions struct { + ListOptions + Query *string `url:"query,omitempty" json:"query,omitempty"` + UserIDs *[]int `url:"user_ids[],omitempty" json:"user_ids,omitempty"` +} + +// ListProjectMembers gets a list of a project's team members viewable by the +// authenticated user. Returns only direct members and not inherited members +// through ancestors groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project +func (s *ProjectMembersService) ListProjectMembers(pid any, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pm []*ProjectMember + resp, err := s.client.Do(req, &pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// ListAllProjectMembers gets a list of a project's team members viewable by the +// authenticated user. Returns a list including inherited members through +// ancestor groups. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project-including-inherited-and-invited-members +func (s *ProjectMembersService) ListAllProjectMembers(pid any, opt *ListProjectMembersOptions, options ...RequestOptionFunc) ([]*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/all", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pm []*ProjectMember + resp, err := s.client.Do(req, &pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// GetProjectMember gets a project team member. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#get-a-member-of-a-group-or-project +func (s *ProjectMembersService) GetProjectMember(pid any, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// GetInheritedProjectMember gets a project team member, including inherited +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#get-a-member-of-a-group-or-project-including-inherited-and-invited-members +func (s *ProjectMembersService) GetInheritedProjectMember(pid any, user int, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/all/%d", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// AddProjectMemberOptions represents the available AddProjectMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#add-a-member-to-a-group-or-project +type AddProjectMemberOptions struct { + UserID any `url:"user_id,omitempty" json:"user_id,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// AddProjectMember adds a user to a project team. This is an idempotent +// method and can be called multiple times with the same parameters. Adding +// team membership to a user that is already a member does not affect the +// existing membership. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#add-a-member-to-a-group-or-project +func (s *ProjectMembersService) AddProjectMember(pid any, opt *AddProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// EditProjectMemberOptions represents the available EditProjectMember() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#edit-a-member-of-a-group-or-project +type EditProjectMemberOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at,omitempty"` + MemberRoleID *int `url:"member_role_id,omitempty" json:"member_role_id,omitempty"` +} + +// EditProjectMember updates a project team member to a specified access level.. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#edit-a-member-of-a-group-or-project +func (s *ProjectMembersService) EditProjectMember(pid any, user int, opt *EditProjectMemberOptions, options ...RequestOptionFunc) (*ProjectMember, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMember) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// DeleteProjectMember removes a user from a project team. +// +// GitLab API docs: +// https://docs.gitlab.com/api/members/#remove-a-member-from-a-group-or-project +func (s *ProjectMembersService) DeleteProjectMember(pid any, user int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/members/%d", PathEscape(project), user) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_mirror.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_mirror.go new file mode 100644 index 000000000..c8ef60970 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_mirror.go @@ -0,0 +1,240 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectMirrorServiceInterface interface { + ListProjectMirror(pid any, opt *ListProjectMirrorOptions, options ...RequestOptionFunc) ([]*ProjectMirror, *Response, error) + GetProjectMirror(pid any, mirror int, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) + GetProjectMirrorPublicKey(pid any, mirror int, options ...RequestOptionFunc) (*ProjectMirrorPublicKey, *Response, error) + AddProjectMirror(pid any, opt *AddProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) + EditProjectMirror(pid any, mirror int, opt *EditProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) + DeleteProjectMirror(pid any, mirror int, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectMirrorService handles communication with the project mirror + // related methods of the GitLab API. + // + // GitLAb API docs: https://docs.gitlab.com/api/remote_mirrors/ + ProjectMirrorService struct { + client *Client + } +) + +var _ ProjectMirrorServiceInterface = (*ProjectMirrorService)(nil) + +// ProjectMirror represents a project mirror configuration. +// +// GitLAb API docs: https://docs.gitlab.com/api/remote_mirrors/ +type ProjectMirror struct { + Enabled bool `json:"enabled"` + ID int `json:"id"` + LastError string `json:"last_error"` + LastSuccessfulUpdateAt *time.Time `json:"last_successful_update_at"` + LastUpdateAt *time.Time `json:"last_update_at"` + LastUpdateStartedAt *time.Time `json:"last_update_started_at"` + MirrorBranchRegex string `json:"mirror_branch_regex"` + OnlyProtectedBranches bool `json:"only_protected_branches"` + KeepDivergentRefs bool `json:"keep_divergent_refs"` + UpdateStatus string `json:"update_status"` + URL string `json:"url"` + AuthMethod string `json:"auth_method"` +} + +type ProjectMirrorPublicKey struct { + PublicKey string `json:"public_key"` +} + +// ListProjectMirrorOptions represents the available ListProjectMirror() options. +type ListProjectMirrorOptions ListOptions + +// ListProjectMirror gets a list of mirrors configured on the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#list-a-projects-remote-mirrors +func (s *ProjectMirrorService) ListProjectMirror(pid any, opt *ListProjectMirrorOptions, options ...RequestOptionFunc) ([]*ProjectMirror, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pm []*ProjectMirror + resp, err := s.client.Do(req, &pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// GetProjectMirror gets a single mirror configured on the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#get-a-single-projects-remote-mirror +func (s *ProjectMirrorService) GetProjectMirror(pid any, mirror int, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors/%d", PathEscape(project), mirror) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMirror) + resp, err := s.client.Do(req, &pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// GetProjectMirrorPublicKey gets the SSH public key for a single mirror configured on the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#get-a-single-projects-remote-mirror-public-key +func (s *ProjectMirrorService) GetProjectMirrorPublicKey(pid any, mirror int, options ...RequestOptionFunc) (*ProjectMirrorPublicKey, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors/%d/public_key", PathEscape(project), mirror) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pmpk := new(ProjectMirrorPublicKey) + resp, err := s.client.Do(req, &pmpk) + if err != nil { + return nil, resp, err + } + + return pmpk, resp, nil +} + +// AddProjectMirrorOptions contains the properties requires to create +// a new project mirror. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#create-a-push-mirror +type AddProjectMirrorOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + KeepDivergentRefs *bool `url:"keep_divergent_refs,omitempty" json:"keep_divergent_refs,omitempty"` + OnlyProtectedBranches *bool `url:"only_protected_branches,omitempty" json:"only_protected_branches,omitempty"` + MirrorBranchRegex *string `url:"mirror_branch_regex,omitempty" json:"mirror_branch_regex,omitempty"` + AuthMethod *string `url:"auth_method,omitempty" json:"auth_method,omitempty"` +} + +// AddProjectMirror creates a new mirror on the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#create-a-push-mirror +func (s *ProjectMirrorService) AddProjectMirror(pid any, opt *AddProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMirror) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// EditProjectMirrorOptions contains the properties requires to edit +// an existing project mirror. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#update-a-remote-mirrors-attributes +type EditProjectMirrorOptions struct { + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + KeepDivergentRefs *bool `url:"keep_divergent_refs,omitempty" json:"keep_divergent_refs,omitempty"` + OnlyProtectedBranches *bool `url:"only_protected_branches,omitempty" json:"only_protected_branches,omitempty"` + MirrorBranchRegex *string `url:"mirror_branch_regex,omitempty" json:"mirror_branch_regex,omitempty"` + AuthMethod *string `url:"auth_method,omitempty" json:"auth_method,omitempty"` +} + +// EditProjectMirror updates a project team member to a specified access level.. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#update-a-remote-mirrors-attributes +func (s *ProjectMirrorService) EditProjectMirror(pid any, mirror int, opt *EditProjectMirrorOptions, options ...RequestOptionFunc) (*ProjectMirror, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors/%d", PathEscape(project), mirror) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pm := new(ProjectMirror) + resp, err := s.client.Do(req, pm) + if err != nil { + return nil, resp, err + } + + return pm, resp, nil +} + +// DeleteProjectMirror deletes a project mirror. +// +// GitLab API docs: +// https://docs.gitlab.com/api/remote_mirrors/#delete-a-remote-mirror +func (s *ProjectMirrorService) DeleteProjectMirror(pid any, mirror int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/remote_mirrors/%d", PathEscape(project), mirror) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_repository_storage_move.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_repository_storage_move.go new file mode 100644 index 000000000..fe23dfbc8 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_repository_storage_move.go @@ -0,0 +1,212 @@ +// +// Copyright 2023, Nick Westbury +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectRepositoryStorageMoveServiceInterface interface { + RetrieveAllStorageMoves(opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) + RetrieveAllStorageMovesForProject(project int, opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) + GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) + GetStorageMoveForProject(project int, repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) + ScheduleStorageMoveForProject(project int, opts ScheduleStorageMoveForProjectOptions, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) + ScheduleAllStorageMoves(opts ScheduleAllProjectStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectRepositoryStorageMoveService handles communication with the + // repositories related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_repository_storage_moves/ + ProjectRepositoryStorageMoveService struct { + client *Client + } +) + +var _ ProjectRepositoryStorageMoveServiceInterface = (*ProjectRepositoryStorageMoveService)(nil) + +// ProjectRepositoryStorageMove represents the status of a repository move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/ +type ProjectRepositoryStorageMove struct { + ID int `json:"id"` + CreatedAt *time.Time `json:"created_at"` + State string `json:"state"` + SourceStorageName string `json:"source_storage_name"` + DestinationStorageName string `json:"destination_storage_name"` + Project *RepositoryProject `json:"project"` +} + +type RepositoryProject struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreatedAt *time.Time `json:"created_at"` +} + +// RetrieveAllProjectStorageMovesOptions represents the available +// RetrieveAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#retrieve-all-project-repository-storage-moves +type RetrieveAllProjectStorageMovesOptions ListOptions + +// RetrieveAllStorageMoves retrieves all project repository storage moves +// accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#retrieve-all-project-repository-storage-moves +func (p ProjectRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) { + req, err := p.client.NewRequest(http.MethodGet, "project_repository_storage_moves", opts, options) + if err != nil { + return nil, nil, err + } + + var psms []*ProjectRepositoryStorageMove + resp, err := p.client.Do(req, &psms) + if err != nil { + return nil, resp, err + } + + return psms, resp, err +} + +// RetrieveAllStorageMovesForProject retrieves all repository storage moves for +// a single project accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#retrieve-all-repository-storage-moves-for-a-project +func (p ProjectRepositoryStorageMoveService) RetrieveAllStorageMovesForProject(project int, opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("projects/%d/repository_storage_moves", project) + + req, err := p.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var psms []*ProjectRepositoryStorageMove + resp, err := p.client.Do(req, &psms) + if err != nil { + return nil, resp, err + } + + return psms, resp, err +} + +// GetStorageMove gets a single project repository storage move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#get-a-single-project-repository-storage-move +func (p ProjectRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("project_repository_storage_moves/%d", repositoryStorage) + + req, err := p.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + psm := new(ProjectRepositoryStorageMove) + resp, err := p.client.Do(req, psm) + if err != nil { + return nil, resp, err + } + + return psm, resp, err +} + +// GetStorageMoveForProject gets a single repository storage move for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#get-a-single-repository-storage-move-for-a-project +func (p ProjectRepositoryStorageMoveService) GetStorageMoveForProject(project int, repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("projects/%d/repository_storage_moves/%d", project, repositoryStorage) + + req, err := p.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + psm := new(ProjectRepositoryStorageMove) + resp, err := p.client.Do(req, psm) + if err != nil { + return nil, resp, err + } + + return psm, resp, err +} + +// ScheduleStorageMoveForProjectOptions represents the available +// ScheduleStorageMoveForProject() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#schedule-a-repository-storage-move-for-a-project +type ScheduleStorageMoveForProjectOptions struct { + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleStorageMoveForProject schedule a repository to be moved for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#schedule-a-repository-storage-move-for-a-project +func (p ProjectRepositoryStorageMoveService) ScheduleStorageMoveForProject(project int, opts ScheduleStorageMoveForProjectOptions, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("projects/%d/repository_storage_moves", project) + + req, err := p.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + psm := new(ProjectRepositoryStorageMove) + resp, err := p.client.Do(req, psm) + if err != nil { + return nil, resp, err + } + + return psm, resp, err +} + +// ScheduleAllProjectStorageMovesOptions represents the available +// ScheduleAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#schedule-repository-storage-moves-for-all-projects-on-a-storage-shard +type ScheduleAllProjectStorageMovesOptions struct { + SourceStorageName *string `url:"source_storage_name,omitempty" json:"source_storage_name,omitempty"` + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleAllStorageMoves schedules all repositories to be moved. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_repository_storage_moves/#schedule-repository-storage-moves-for-all-projects-on-a-storage-shard +func (p ProjectRepositoryStorageMoveService) ScheduleAllStorageMoves(opts ScheduleAllProjectStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := p.client.NewRequest(http.MethodPost, "project_repository_storage_moves", opts, options) + if err != nil { + return nil, err + } + + return p.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_security_settings.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_security_settings.go new file mode 100644 index 000000000..028d62724 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_security_settings.go @@ -0,0 +1,123 @@ +// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ProjectSecuritySettingsServiceInterface interface { + ListProjectSecuritySettings(pid any, options ...RequestOptionFunc) (*ProjectSecuritySettings, *Response, error) + UpdateSecretPushProtectionEnabledSetting(pid any, opt UpdateProjectSecuritySettingsOptions, options ...RequestOptionFunc) (*ProjectSecuritySettings, *Response, error) + } + + // ProjectSecuritySettingsService handles communication with the Project Security Settings + // related methods of the GitLab API. + // + // Gitlab API docs: + // https://docs.gitlab.com/api/project_security_settings/ + ProjectSecuritySettingsService struct { + client *Client + } +) + +var _ ProjectSecuritySettingsServiceInterface = (*ProjectSecuritySettingsService)(nil) + +// ProjectSecuritySettings represents the project security settings data. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/project_security_settings/ +type ProjectSecuritySettings struct { + ProjectID int64 `json:"project_id"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + AutoFixContainerScanning bool `json:"auto_fix_container_scanning"` + AutoFixDAST bool `json:"auto_fix_dast"` + AutoFixDependencyScanning bool `json:"auto_fix_dependency_scanning"` + AutoFixSAST bool `json:"auto_fix_sast"` + ContinuousVulnerabilityScansEnabled bool `json:"continuous_vulnerability_scans_enabled"` + ContainerScanningForRegistryEnabled bool `json:"container_scanning_for_registry_enabled"` + SecretPushProtectionEnabled bool `json:"secret_push_protection_enabled"` +} + +// Gets a string representation of the ProjectSecuritySettings data. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_security_settings/ +func (s ProjectSecuritySettings) String() string { + return Stringify(s) +} + +// ListProjectSecuritySettings lists all of a project's security settings. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_security_settings/#list-project-security-settings +func (s *ProjectSecuritySettingsService) ListProjectSecuritySettings(pid any, options ...RequestOptionFunc) (*ProjectSecuritySettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/security_settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + settings := new(ProjectSecuritySettings) + resp, err := s.client.Do(req, &settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, err +} + +// UpdateProjectSecuritySettingsOptions represent the request options for updating +// the project security settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_security_settings/#update-secret_push_protection_enabled-setting +type UpdateProjectSecuritySettingsOptions struct { + SecretPushProtectionEnabled *bool `url:"secret_push_protection_enabled,omitempty" json:"secret_push_protection_enabled,omitempty"` +} + +// UpdateSecretPushProtectionEnabledSetting updates the secret_push_protection_enabled +// setting for the all projects in a project to the provided value. +// +// GitLab API Docs: +// https://docs.gitlab.com/api/project_security_settings/#update-secret_push_protection_enabled-setting +func (s *ProjectSecuritySettingsService) UpdateSecretPushProtectionEnabledSetting(pid any, opt UpdateProjectSecuritySettingsOptions, options ...RequestOptionFunc) (*ProjectSecuritySettings, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/security_settings", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + settings := new(ProjectSecuritySettings) + resp, err := s.client.Do(req, &settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_snippets.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_snippets.go new file mode 100644 index 000000000..61c7e59e2 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_snippets.go @@ -0,0 +1,228 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/http" +) + +type ( + ProjectSnippetsServiceInterface interface { + ListSnippets(pid any, opt *ListProjectSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) + GetSnippet(pid any, snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) + CreateSnippet(pid any, opt *CreateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) + UpdateSnippet(pid any, snippet int, opt *UpdateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) + DeleteSnippet(pid any, snippet int, options ...RequestOptionFunc) (*Response, error) + SnippetContent(pid any, snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) + } + + // ProjectSnippetsService handles communication with the project snippets + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/project_snippets/ + ProjectSnippetsService struct { + client *Client + } +) + +var _ ProjectSnippetsServiceInterface = (*ProjectSnippetsService)(nil) + +// ListProjectSnippetsOptions represents the available ListSnippets() options. +// +// GitLab API docs: https://docs.gitlab.com/api/project_snippets/#list-snippets +type ListProjectSnippetsOptions ListOptions + +// ListSnippets gets a list of project snippets. +// +// GitLab API docs: https://docs.gitlab.com/api/project_snippets/#list-snippets +func (s *ProjectSnippetsService) ListSnippets(pid any, opt *ListProjectSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Snippet + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// GetSnippet gets a single project snippet +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#single-snippet +func (s *ProjectSnippetsService) GetSnippet(pid any, snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// CreateProjectSnippetOptions represents the available CreateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#create-new-snippet +type CreateProjectSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + Files *[]*CreateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` + + // Deprecated: use Files instead + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + // Deprecated: use Files instead + Content *string `url:"content,omitempty" json:"content,omitempty"` +} + +// CreateSnippet creates a new project snippet. The user must have permission +// to create new snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#create-new-snippet +func (s *ProjectSnippetsService) CreateSnippet(pid any, opt *CreateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// UpdateProjectSnippetOptions represents the available UpdateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#update-snippet +type UpdateProjectSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + Files *[]*UpdateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` + + // Deprecated: use Files instead + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + // Deprecated: use Files instead + Content *string `url:"content,omitempty" json:"content,omitempty"` +} + +// UpdateSnippet updates an existing project snippet. The user must have +// permission to change an existing snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#update-snippet +func (s *ProjectSnippetsService) UpdateSnippet(pid any, snippet int, opt *UpdateProjectSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// DeleteSnippet deletes an existing project snippet. This is an idempotent +// function and deleting a non-existent snippet still returns a 200 OK status +// code. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#delete-snippet +func (s *ProjectSnippetsService) DeleteSnippet(pid any, snippet int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SnippetContent returns the raw project snippet as plain text. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_snippets/#snippet-content +func (s *ProjectSnippetsService) SnippetContent(pid any, snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/snippets/%d/raw", PathEscape(project), snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_templates.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_templates.go new file mode 100644 index 000000000..1e7c6489a --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_templates.go @@ -0,0 +1,119 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ProjectTemplatesServiceInterface interface { + ListTemplates(pid any, templateType string, opt *ListProjectTemplatesOptions, options ...RequestOptionFunc) ([]*ProjectTemplate, *Response, error) + GetProjectTemplate(pid any, templateType string, templateName string, options ...RequestOptionFunc) (*ProjectTemplate, *Response, error) + } + + // ProjectTemplatesService handles communication with the project templates + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/project_templates/ + ProjectTemplatesService struct { + client *Client + } +) + +var _ ProjectTemplatesServiceInterface = (*ProjectTemplatesService)(nil) + +// ProjectTemplate represents a GitLab ProjectTemplate. +// +// GitLab API docs: https://docs.gitlab.com/api/project_templates/ +type ProjectTemplate struct { + Key string `json:"key"` + Name string `json:"name"` + Nickname string `json:"nickname"` + Popular bool `json:"popular"` + HTMLURL string `json:"html_url"` + SourceURL string `json:"source_url"` + Description string `json:"description"` + Conditions []string `json:"conditions"` + Permissions []string `json:"permissions"` + Limitations []string `json:"limitations"` + Content string `json:"content"` +} + +func (s ProjectTemplate) String() string { + return Stringify(s) +} + +// ListProjectTemplatesOptions represents the available ListSnippets() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_templates/#get-all-templates-of-a-particular-type +type ListProjectTemplatesOptions struct { + ListOptions + ID *int `url:"id,omitempty" json:"id,omitempty"` + Type *string `url:"type,omitempty" json:"type,omitempty"` +} + +// ListTemplates gets a list of project templates. +// +// GitLab API docs: https://docs.gitlab.com/api/project_templates/#get-all-templates-of-a-particular-type +func (s *ProjectTemplatesService) ListTemplates(pid any, templateType string, opt *ListProjectTemplatesOptions, options ...RequestOptionFunc) ([]*ProjectTemplate, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/templates/%s", PathEscape(project), templateType) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pt []*ProjectTemplate + resp, err := s.client.Do(req, &pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// GetProjectTemplate gets a single project template. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_templates/#get-one-template-of-a-particular-type +func (s *ProjectTemplatesService) GetProjectTemplate(pid any, templateType string, templateName string, options ...RequestOptionFunc) (*ProjectTemplate, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/templates/%s/%s", PathEscape(project), templateType, templateName) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ptd := new(ProjectTemplate) + resp, err := s.client.Do(req, ptd) + if err != nil { + return nil, resp, err + } + + return ptd, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_variables.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_variables.go new file mode 100644 index 000000000..870837ec6 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_variables.go @@ -0,0 +1,246 @@ +// +// Copyright 2021, Patrick Webster +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + ProjectVariablesServiceInterface interface { + ListVariables(pid any, opt *ListProjectVariablesOptions, options ...RequestOptionFunc) ([]*ProjectVariable, *Response, error) + GetVariable(pid any, key string, opt *GetProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) + CreateVariable(pid any, opt *CreateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) + UpdateVariable(pid any, key string, opt *UpdateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) + RemoveVariable(pid any, key string, opt *RemoveProjectVariableOptions, options ...RequestOptionFunc) (*Response, error) + } + + // ProjectVariablesService handles communication with the + // project variables related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/project_level_variables/ + ProjectVariablesService struct { + client *Client + } +) + +var _ ProjectVariablesServiceInterface = (*ProjectVariablesService)(nil) + +// ProjectVariable represents a GitLab Project Variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/ +type ProjectVariable struct { + Key string `json:"key"` + Value string `json:"value"` + VariableType VariableTypeValue `json:"variable_type"` + Protected bool `json:"protected"` + Masked bool `json:"masked"` + Hidden bool `json:"hidden"` + Raw bool `json:"raw"` + EnvironmentScope string `json:"environment_scope"` + Description string `json:"description"` +} + +func (v ProjectVariable) String() string { + return Stringify(v) +} + +// VariableFilter filters available for project variable related functions +type VariableFilter struct { + EnvironmentScope string `url:"environment_scope, omitempty" json:"environment_scope,omitempty"` +} + +// ListProjectVariablesOptions represents the available options for listing variables +// in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#list-project-variables +type ListProjectVariablesOptions ListOptions + +// ListVariables gets a list of all variables in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#list-project-variables +func (s *ProjectVariablesService) ListVariables(pid any, opt *ListProjectVariablesOptions, options ...RequestOptionFunc) ([]*ProjectVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var vs []*ProjectVariable + resp, err := s.client.Do(req, &vs) + if err != nil { + return nil, resp, err + } + + return vs, resp, nil +} + +// GetProjectVariableOptions represents the available GetVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#get-a-single-variable +type GetProjectVariableOptions struct { + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` +} + +// GetVariable gets a variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#get-a-single-variable +func (s *ProjectVariablesService) GetVariable(pid any, key string, opt *GetProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", PathEscape(project), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(ProjectVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// CreateProjectVariableOptions represents the available CreateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#create-a-variable +type CreateProjectVariableOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` + Value *string `url:"value,omitempty" json:"value,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` + Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + MaskedAndHidden *bool `url:"masked_and_hidden,omitempty" json:"masked_and_hidden,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// CreateVariable creates a new project variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#create-a-variable +func (s *ProjectVariablesService) CreateVariable(pid any, opt *CreateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(ProjectVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// UpdateProjectVariableOptions represents the available UpdateVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#update-a-variable +type UpdateProjectVariableOptions struct { + Value *string `url:"value,omitempty" json:"value,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` + Masked *bool `url:"masked,omitempty" json:"masked,omitempty"` + Protected *bool `url:"protected,omitempty" json:"protected,omitempty"` + Raw *bool `url:"raw,omitempty" json:"raw,omitempty"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` +} + +// UpdateVariable updates a project's variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#update-a-variable +func (s *ProjectVariablesService) UpdateVariable(pid any, key string, opt *UpdateProjectVariableOptions, options ...RequestOptionFunc) (*ProjectVariable, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", PathEscape(project), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + v := new(ProjectVariable) + resp, err := s.client.Do(req, v) + if err != nil { + return nil, resp, err + } + + return v, resp, nil +} + +// RemoveProjectVariableOptions represents the available RemoveVariable() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#delete-a-variable +type RemoveProjectVariableOptions struct { + Filter *VariableFilter `url:"filter,omitempty" json:"filter,omitempty"` +} + +// RemoveVariable removes a project's variable. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_level_variables/#delete-a-variable +func (s *ProjectVariablesService) RemoveVariable(pid any, key string, opt *RemoveProjectVariableOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/variables/%s", PathEscape(project), url.PathEscape(key)) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/project_vulnerabilities.go b/vendor/gitlab.com/gitlab-org/api/client-go/project_vulnerabilities.go new file mode 100644 index 000000000..9b939e0bf --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/project_vulnerabilities.go @@ -0,0 +1,170 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + // Deprecated: use GraphQL Query.vulnerabilities instead + ProjectVulnerabilitiesServiceInterface interface { + // Deprecated: use GraphQL Query.vulnerabilities instead + ListProjectVulnerabilities(pid any, opt *ListProjectVulnerabilitiesOptions, options ...RequestOptionFunc) ([]*ProjectVulnerability, *Response, error) + // Deprecated: use GraphQL Query.vulnerabilities instead + CreateVulnerability(pid any, opt *CreateVulnerabilityOptions, options ...RequestOptionFunc) (*ProjectVulnerability, *Response, error) + } + + // ProjectVulnerabilitiesService handles communication with the projects + // vulnerabilities related methods of the GitLab API. + // Deprecated: use GraphQL Query.vulnerabilities instead + // + // GitLab API docs: https://docs.gitlab.com/api/project_vulnerabilities/ + ProjectVulnerabilitiesService struct { + client *Client + } +) + +// Deprecated: use GraphQL Query.vulnerabilities instead +var _ ProjectVulnerabilitiesServiceInterface = (*ProjectVulnerabilitiesService)(nil) + +// Project represents a GitLab project vulnerability. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: https://docs.gitlab.com/api/project_vulnerabilities/ +type ProjectVulnerability struct { + AuthorID int `json:"author_id"` + Confidence string `json:"confidence"` + CreatedAt *time.Time `json:"created_at"` + Description string `json:"description"` + DismissedAt *time.Time `json:"dismissed_at"` + DismissedByID int `json:"dismissed_by_id"` + DueDate *time.Time `json:"due_date"` + Finding *Finding `json:"finding"` + ID int `json:"id"` + LastEditedAt *time.Time `json:"last_edited_at"` + LastEditedByID int `json:"last_edited_by_id"` + Project *Project `json:"project"` + ProjectDefaultBranch string `json:"project_default_branch"` + ReportType string `json:"report_type"` + ResolvedAt *time.Time `json:"resolved_at"` + ResolvedByID int `json:"resolved_by_id"` + ResolvedOnDefaultBranch bool `json:"resolved_on_default_branch"` + Severity string `json:"severity"` + StartDate *time.Time `json:"start_date"` + State string `json:"state"` + Title string `json:"title"` + UpdatedAt *time.Time `json:"updated_at"` + UpdatedByID int `json:"updated_by_id"` +} + +// Project represents a GitLab project vulnerability finding. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: https://docs.gitlab.com/api/project_vulnerabilities/ +type Finding struct { + Confidence string `json:"confidence"` + CreatedAt *time.Time `json:"created_at"` + ID int `json:"id"` + LocationFingerprint string `json:"location_fingerprint"` + MetadataVersion string `json:"metadata_version"` + Name string `json:"name"` + PrimaryIdentifierID int `json:"primary_identifier_id"` + ProjectFingerprint string `json:"project_fingerprint"` + ProjectID int `json:"project_id"` + RawMetadata string `json:"raw_metadata"` + ReportType string `json:"report_type"` + ScannerID int `json:"scanner_id"` + Severity string `json:"severity"` + UpdatedAt *time.Time `json:"updated_at"` + UUID string `json:"uuid"` + VulnerabilityID int `json:"vulnerability_id"` +} + +// ListProjectVulnerabilitiesOptions represents the available +// ListProjectVulnerabilities() options. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_vulnerabilities/#list-project-vulnerabilities +type ListProjectVulnerabilitiesOptions struct { + ListOptions +} + +// ListProjectVulnerabilities gets a list of all project vulnerabilities. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_vulnerabilities/#list-project-vulnerabilities +func (s *ProjectVulnerabilitiesService) ListProjectVulnerabilities(pid any, opt *ListProjectVulnerabilitiesOptions, options ...RequestOptionFunc) ([]*ProjectVulnerability, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/vulnerabilities", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProjectVulnerability + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreateVulnerabilityOptions represents the available CreateVulnerability() +// options. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_vulnerabilities/#new-vulnerability +type CreateVulnerabilityOptions struct { + FindingID *int `url:"finding_id,omitempty" json:"finding_id,omitempty"` +} + +// CreateVulnerability creates a new vulnerability on the selected project. +// Deprecated: use GraphQL Query.vulnerabilities instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_vulnerabilities/#new-vulnerability +func (s *ProjectVulnerabilitiesService) CreateVulnerability(pid any, opt *CreateVulnerabilityOptions, options ...RequestOptionFunc) (*ProjectVulnerability, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/vulnerabilities", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(ProjectVulnerability) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/projects.go b/vendor/gitlab.com/gitlab-org/api/client-go/projects.go new file mode 100644 index 000000000..aa5baaf2e --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/projects.go @@ -0,0 +1,2356 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + "github.com/hashicorp/go-retryablehttp" +) + +type ( + // ProjectsServiceInterface handles communication with the repositories related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/projects/ + ProjectsServiceInterface interface { + ListProjects(opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + ListUserProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + ListUserContributedProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + ListUserStarredProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + ListProjectsUsers(pid any, opt *ListProjectUserOptions, options ...RequestOptionFunc) ([]*ProjectUser, *Response, error) + ListProjectsGroups(pid any, opt *ListProjectGroupOptions, options ...RequestOptionFunc) ([]*ProjectGroup, *Response, error) + GetProjectLanguages(pid any, options ...RequestOptionFunc) (*ProjectLanguages, *Response, error) + GetProject(pid any, opt *GetProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) + CreateProject(opt *CreateProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) + CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...RequestOptionFunc) (*Project, *Response, error) + EditProject(pid any, opt *EditProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) + ForkProject(pid any, opt *ForkProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) + StarProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) + ListProjectsInvitedGroups(pid any, opt *ListProjectInvidedGroupOptions, options ...RequestOptionFunc) ([]*ProjectGroup, *Response, error) + UnstarProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) + ArchiveProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) + UnarchiveProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) + DeleteProject(pid any, opt *DeleteProjectOptions, options ...RequestOptionFunc) (*Response, error) + ShareProjectWithGroup(pid any, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Response, error) + DeleteSharedProjectFromGroup(pid any, groupID int, options ...RequestOptionFunc) (*Response, error) + ListProjectHooks(pid any, opt *ListProjectHooksOptions, options ...RequestOptionFunc) ([]*ProjectHook, *Response, error) + GetProjectHook(pid any, hook int, options ...RequestOptionFunc) (*ProjectHook, *Response, error) + AddProjectHook(pid any, opt *AddProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) + EditProjectHook(pid any, hook int, opt *EditProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) + DeleteProjectHook(pid any, hook int, options ...RequestOptionFunc) (*Response, error) + TriggerTestProjectHook(pid any, hook int, event ProjectHookEvent, options ...RequestOptionFunc) (*Response, error) + SetProjectCustomHeader(pid any, hook int, key string, opt *SetHookCustomHeaderOptions, options ...RequestOptionFunc) (*Response, error) + DeleteProjectCustomHeader(pid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) + CreateProjectForkRelation(pid any, fork int, options ...RequestOptionFunc) (*ProjectForkRelation, *Response, error) + DeleteProjectForkRelation(pid any, options ...RequestOptionFunc) (*Response, error) + UploadAvatar(pid any, avatar io.Reader, filename string, options ...RequestOptionFunc) (*Project, *Response, error) + DownloadAvatar(pid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) + ListProjectForks(pid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + GetProjectPushRules(pid any, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) + AddProjectPushRule(pid any, opt *AddProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) + EditProjectPushRule(pid any, opt *EditProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) + DeleteProjectPushRule(pid any, options ...RequestOptionFunc) (*Response, error) + GetApprovalConfiguration(pid any, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) + ChangeApprovalConfiguration(pid any, opt *ChangeApprovalConfigurationOptions, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) + GetProjectApprovalRules(pid any, opt *GetProjectApprovalRulesListsOptions, options ...RequestOptionFunc) ([]*ProjectApprovalRule, *Response, error) + GetProjectApprovalRule(pid any, ruleID int, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) + CreateProjectApprovalRule(pid any, opt *CreateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) + UpdateProjectApprovalRule(pid any, approvalRule int, opt *UpdateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) + DeleteProjectApprovalRule(pid any, approvalRule int, options ...RequestOptionFunc) (*Response, error) + GetProjectPullMirrorDetails(pid any, options ...RequestOptionFunc) (*ProjectPullMirrorDetails, *Response, error) + ConfigureProjectPullMirror(pid any, opt *ConfigureProjectPullMirrorOptions, options ...RequestOptionFunc) (*ProjectPullMirrorDetails, *Response, error) + StartMirroringProject(pid any, options ...RequestOptionFunc) (*Response, error) + TransferProject(pid any, opt *TransferProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) + StartHousekeepingProject(pid any, options ...RequestOptionFunc) (*Response, error) + GetRepositoryStorage(pid any, options ...RequestOptionFunc) (*ProjectReposityStorage, *Response, error) + } + + // ProjectsService handles communication with the repositories related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/projects/ + ProjectsService struct { + client *Client + } +) + +var _ ProjectsServiceInterface = (*ProjectsService)(nil) + +// Project represents a GitLab project. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/ +type Project struct { + ID int `json:"id"` + Description string `json:"description"` + DefaultBranch string `json:"default_branch"` + Visibility VisibilityValue `json:"visibility"` + SSHURLToRepo string `json:"ssh_url_to_repo"` + HTTPURLToRepo string `json:"http_url_to_repo"` + WebURL string `json:"web_url"` + ReadmeURL string `json:"readme_url"` + Topics []string `json:"topics"` + Owner *User `json:"owner"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + OpenIssuesCount int `json:"open_issues_count"` + ResolveOutdatedDiffDiscussions bool `json:"resolve_outdated_diff_discussions"` + ContainerExpirationPolicy *ContainerExpirationPolicy `json:"container_expiration_policy,omitempty"` + ContainerRegistryAccessLevel AccessControlValue `json:"container_registry_access_level"` + ContainerRegistryImagePrefix string `json:"container_registry_image_prefix,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + LastActivityAt *time.Time `json:"last_activity_at,omitempty"` + CreatorID int `json:"creator_id"` + Namespace *ProjectNamespace `json:"namespace"` + Permissions *Permissions `json:"permissions"` + MarkedForDeletionOn *ISOTime `json:"marked_for_deletion_on"` + EmptyRepo bool `json:"empty_repo"` + Archived bool `json:"archived"` + AvatarURL string `json:"avatar_url"` + LicenseURL string `json:"license_url"` + License *ProjectLicense `json:"license"` + SharedRunnersEnabled bool `json:"shared_runners_enabled"` + GroupRunnersEnabled bool `json:"group_runners_enabled"` + RunnerTokenExpirationInterval int `json:"runner_token_expiration_interval"` + ForksCount int `json:"forks_count"` + StarCount int `json:"star_count"` + RunnersToken string `json:"runners_token"` + AllowMergeOnSkippedPipeline bool `json:"allow_merge_on_skipped_pipeline"` + AllowPipelineTriggerApproveDeployment bool `json:"allow_pipeline_trigger_approve_deployment"` + OnlyAllowMergeIfPipelineSucceeds bool `json:"only_allow_merge_if_pipeline_succeeds"` + OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved"` + RemoveSourceBranchAfterMerge bool `json:"remove_source_branch_after_merge"` + PreventMergeWithoutJiraIssue bool `json:"prevent_merge_without_jira_issue"` + PrintingMergeRequestLinkEnabled bool `json:"printing_merge_request_link_enabled"` + LFSEnabled bool `json:"lfs_enabled"` + RepositoryStorage string `json:"repository_storage"` + RequestAccessEnabled bool `json:"request_access_enabled"` + MergeMethod MergeMethodValue `json:"merge_method"` + CanCreateMergeRequestIn bool `json:"can_create_merge_request_in"` + ForkedFromProject *ForkParent `json:"forked_from_project"` + Mirror bool `json:"mirror"` + MirrorUserID int `json:"mirror_user_id"` + MirrorTriggerBuilds bool `json:"mirror_trigger_builds"` + OnlyMirrorProtectedBranches bool `json:"only_mirror_protected_branches"` + MirrorOverwritesDivergedBranches bool `json:"mirror_overwrites_diverged_branches"` + PackagesEnabled bool `json:"packages_enabled"` + ServiceDeskEnabled bool `json:"service_desk_enabled"` + ServiceDeskAddress string `json:"service_desk_address"` + IssuesAccessLevel AccessControlValue `json:"issues_access_level"` + ReleasesAccessLevel AccessControlValue `json:"releases_access_level,omitempty"` + RepositoryAccessLevel AccessControlValue `json:"repository_access_level"` + MergeRequestsAccessLevel AccessControlValue `json:"merge_requests_access_level"` + ForkingAccessLevel AccessControlValue `json:"forking_access_level"` + WikiAccessLevel AccessControlValue `json:"wiki_access_level"` + BuildsAccessLevel AccessControlValue `json:"builds_access_level"` + SnippetsAccessLevel AccessControlValue `json:"snippets_access_level"` + PagesAccessLevel AccessControlValue `json:"pages_access_level"` + OperationsAccessLevel AccessControlValue `json:"operations_access_level"` + AnalyticsAccessLevel AccessControlValue `json:"analytics_access_level"` + EnvironmentsAccessLevel AccessControlValue `json:"environments_access_level"` + FeatureFlagsAccessLevel AccessControlValue `json:"feature_flags_access_level"` + InfrastructureAccessLevel AccessControlValue `json:"infrastructure_access_level"` + MonitorAccessLevel AccessControlValue `json:"monitor_access_level"` + AutocloseReferencedIssues bool `json:"autoclose_referenced_issues"` + SuggestionCommitMessage string `json:"suggestion_commit_message"` + SquashOption SquashOptionValue `json:"squash_option"` + EnforceAuthChecksOnUploads bool `json:"enforce_auth_checks_on_uploads,omitempty"` + SharedWithGroups []struct { + GroupID int `json:"group_id"` + GroupName string `json:"group_name"` + GroupFullPath string `json:"group_full_path"` + GroupAccessLevel int `json:"group_access_level"` + } `json:"shared_with_groups"` + Statistics *Statistics `json:"statistics"` + Links *Links `json:"_links,omitempty"` + ImportURL string `json:"import_url"` + ImportType string `json:"import_type"` + ImportStatus string `json:"import_status"` + ImportError string `json:"import_error"` + CIDefaultGitDepth int `json:"ci_default_git_depth"` + CIDeletePipelinesInSeconds int `json:"ci_delete_pipelines_in_seconds,omitempty"` + CIForwardDeploymentEnabled bool `json:"ci_forward_deployment_enabled"` + CIForwardDeploymentRollbackAllowed bool `json:"ci_forward_deployment_rollback_allowed"` + CIIdTokenSubClaimComponents []string `json:"ci_id_token_sub_claim_components"` + CISeperateCache bool `json:"ci_separated_caches"` + CIJobTokenScopeEnabled bool `json:"ci_job_token_scope_enabled"` + CIOptInJWT bool `json:"ci_opt_in_jwt"` + CIAllowForkPipelinesToRunInParentProject bool `json:"ci_allow_fork_pipelines_to_run_in_parent_project"` + CIRestrictPipelineCancellationRole AccessControlValue `json:"ci_restrict_pipeline_cancellation_role"` + PublicJobs bool `json:"public_jobs"` + BuildTimeout int `json:"build_timeout"` + AutoCancelPendingPipelines string `json:"auto_cancel_pending_pipelines"` + CIConfigPath string `json:"ci_config_path"` + CustomAttributes []*CustomAttribute `json:"custom_attributes"` + ComplianceFrameworks []string `json:"compliance_frameworks"` + BuildCoverageRegex string `json:"build_coverage_regex"` + IssuesTemplate string `json:"issues_template"` + MergeRequestsTemplate string `json:"merge_requests_template"` + IssueBranchTemplate string `json:"issue_branch_template"` + KeepLatestArtifact bool `json:"keep_latest_artifact"` + MergePipelinesEnabled bool `json:"merge_pipelines_enabled"` + MergeTrainsEnabled bool `json:"merge_trains_enabled"` + CIPipelineVariablesMinimumOverrideRole CIPipelineVariablesMinimumOverrideRoleValue `json:"ci_pipeline_variables_minimum_override_role"` + MergeCommitTemplate string `json:"merge_commit_template"` + SquashCommitTemplate string `json:"squash_commit_template"` + AutoDevopsDeployStrategy string `json:"auto_devops_deploy_strategy"` + AutoDevopsEnabled bool `json:"auto_devops_enabled"` + BuildGitStrategy string `json:"build_git_strategy"` + EmailsEnabled bool `json:"emails_enabled"` + ExternalAuthorizationClassificationLabel string `json:"external_authorization_classification_label"` + RequirementsEnabled bool `json:"requirements_enabled"` + RequirementsAccessLevel AccessControlValue `json:"requirements_access_level"` + SecurityAndComplianceEnabled bool `json:"security_and_compliance_enabled"` + SecurityAndComplianceAccessLevel AccessControlValue `json:"security_and_compliance_access_level"` + MergeRequestDefaultTargetSelf bool `json:"mr_default_target_self"` + ModelExperimentsAccessLevel AccessControlValue `json:"model_experiments_access_level"` + ModelRegistryAccessLevel AccessControlValue `json:"model_registry_access_level"` + PreReceiveSecretDetectionEnabled bool `json:"pre_receive_secret_detection_enabled"` + + // Deprecated: use Topics instead + TagList []string `json:"tag_list"` + // Deprecated: use IssuesAccessLevel instead + IssuesEnabled bool `json:"issues_enabled"` + // Deprecated: use MergeRequestsAccessLevel instead + MergeRequestsEnabled bool `json:"merge_requests_enabled"` + // Deprecated: use Merge Request Approvals API instead + ApprovalsBeforeMerge int `json:"approvals_before_merge"` + // Deprecated: use BuildsAccessLevel instead + JobsEnabled bool `json:"jobs_enabled"` + // Deprecated: use WikiAccessLevel instead + WikiEnabled bool `json:"wiki_enabled"` + // Deprecated: use SnippetsAccessLevel instead + SnippetsEnabled bool `json:"snippets_enabled"` + // Deprecated: use ContainerRegistryAccessLevel instead + ContainerRegistryEnabled bool `json:"container_registry_enabled"` + // Deprecated: use MarkedForDeletionOn instead + MarkedForDeletionAt *ISOTime `json:"marked_for_deletion_at"` + // Deprecated: use CIPipelineVariablesMinimumOverrideRole instead + RestrictUserDefinedVariables bool `json:"restrict_user_defined_variables"` + // Deprecated: Use EmailsEnabled instead + EmailsDisabled bool `json:"emails_disabled"` + // Deprecated: This parameter has been renamed to PublicJobs in GitLab 9.0. + PublicBuilds bool `json:"public_builds"` +} + +// BasicProject included in other service responses (such as todos). +type BasicProject struct { + ID int `json:"id"` + Description string `json:"description"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + CreatedAt *time.Time `json:"created_at"` +} + +// ContainerExpirationPolicy represents the container expiration policy. +type ContainerExpirationPolicy struct { + Cadence string `json:"cadence"` + KeepN int `json:"keep_n"` + OlderThan string `json:"older_than"` + NameRegexDelete string `json:"name_regex_delete"` + NameRegexKeep string `json:"name_regex_keep"` + Enabled bool `json:"enabled"` + NextRunAt *time.Time `json:"next_run_at"` + + // Deprecated: use NameRegexDelete instead + NameRegex string `json:"name_regex"` +} + +// ForkParent represents the parent project when this is a fork. +type ForkParent struct { + ID int `json:"id"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + HTTPURLToRepo string `json:"http_url_to_repo"` + WebURL string `json:"web_url"` + RepositoryStorage string `json:"repository_storage"` +} + +// GroupAccess represents group access. +type GroupAccess struct { + AccessLevel AccessLevelValue `json:"access_level"` + NotificationLevel NotificationLevelValue `json:"notification_level"` +} + +// Links represents a project web links for self, issues, merge_requests, +// repo_branches, labels, events, members. +type Links struct { + Self string `json:"self"` + Issues string `json:"issues"` + MergeRequests string `json:"merge_requests"` + RepoBranches string `json:"repo_branches"` + Labels string `json:"labels"` + Events string `json:"events"` + Members string `json:"members"` + ClusterAgents string `json:"cluster_agents"` +} + +// Permissions represents permissions. +type Permissions struct { + ProjectAccess *ProjectAccess `json:"project_access"` + GroupAccess *GroupAccess `json:"group_access"` +} + +// ProjectAccess represents project access. +type ProjectAccess struct { + AccessLevel AccessLevelValue `json:"access_level"` + NotificationLevel NotificationLevelValue `json:"notification_level"` +} + +// ProjectLicense represent the license for a project. +type ProjectLicense struct { + Key string `json:"key"` + Name string `json:"name"` + Nickname string `json:"nickname"` + HTMLURL string `json:"html_url"` + SourceURL string `json:"source_url"` +} + +// ProjectNamespace represents a project namespace. +type ProjectNamespace struct { + ID int `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Kind string `json:"kind"` + FullPath string `json:"full_path"` + ParentID int `json:"parent_id"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` +} + +// Repository represents a repository. +type Repository struct { + Name string `json:"name"` + Description string `json:"description"` + WebURL string `json:"web_url"` + AvatarURL string `json:"avatar_url"` + GitSSHURL string `json:"git_ssh_url"` + GitHTTPURL string `json:"git_http_url"` + Namespace string `json:"namespace"` + Visibility VisibilityValue `json:"visibility"` + PathWithNamespace string `json:"path_with_namespace"` + DefaultBranch string `json:"default_branch"` + Homepage string `json:"homepage"` + URL string `json:"url"` + SSHURL string `json:"ssh_url"` + HTTPURL string `json:"http_url"` +} + +// Statistics represents a statistics record for a group or project. +type Statistics struct { + CommitCount int64 `json:"commit_count"` + StorageSize int64 `json:"storage_size"` + RepositorySize int64 `json:"repository_size"` + WikiSize int64 `json:"wiki_size"` + LFSObjectsSize int64 `json:"lfs_objects_size"` + JobArtifactsSize int64 `json:"job_artifacts_size"` + PipelineArtifactsSize int64 `json:"pipeline_artifacts_size"` + PackagesSize int64 `json:"packages_size"` + SnippetsSize int64 `json:"snippets_size"` + UploadsSize int64 `json:"uploads_size"` + ContainerRegistrySize int64 `json:"container_registry_size"` +} + +func (s Project) String() string { + return Stringify(s) +} + +// ProjectApprovalRule represents a GitLab project approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-all-approval-rules-for-project +type ProjectApprovalRule struct { + ID int `json:"id"` + Name string `json:"name"` + RuleType string `json:"rule_type"` + ReportType string `json:"report_type"` + EligibleApprovers []*BasicUser `json:"eligible_approvers"` + ApprovalsRequired int `json:"approvals_required"` + Users []*BasicUser `json:"users"` + Groups []*Group `json:"groups"` + ContainsHiddenGroups bool `json:"contains_hidden_groups"` + ProtectedBranches []*ProtectedBranch `json:"protected_branches"` + AppliesToAllProtectedBranches bool `json:"applies_to_all_protected_branches"` +} + +func (s ProjectApprovalRule) String() string { + return Stringify(s) +} + +// ListProjectsOptions represents the available ListProjects() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#list-all-projects +type ListProjectsOptions struct { + ListOptions + Archived *bool `url:"archived,omitempty" json:"archived,omitempty"` + IDAfter *int `url:"id_after,omitempty" json:"id_after,omitempty"` + IDBefore *int `url:"id_before,omitempty" json:"id_before,omitempty"` + Imported *bool `url:"imported,omitempty" json:"imported,omitempty"` + IncludeHidden *bool `url:"include_hidden,omitempty" json:"include_hidden,omitempty"` + IncludePendingDelete *bool `url:"include_pending_delete,omitempty" json:"include_pending_delete,omitempty"` + LastActivityAfter *time.Time `url:"last_activity_after,omitempty" json:"last_activity_after,omitempty"` + LastActivityBefore *time.Time `url:"last_activity_before,omitempty" json:"last_activity_before,omitempty"` + Membership *bool `url:"membership,omitempty" json:"membership,omitempty"` + MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Owned *bool `url:"owned,omitempty" json:"owned,omitempty"` + RepositoryChecksumFailed *bool `url:"repository_checksum_failed,omitempty" json:"repository_checksum_failed,omitempty"` + RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + SearchNamespaces *bool `url:"search_namespaces,omitempty" json:"search_namespaces,omitempty"` + Simple *bool `url:"simple,omitempty" json:"simple,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + Starred *bool `url:"starred,omitempty" json:"starred,omitempty"` + Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` + Topic *string `url:"topic,omitempty" json:"topic,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + WikiChecksumFailed *bool `url:"wiki_checksum_failed,omitempty" json:"wiki_checksum_failed,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"` + WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"` + WithProgrammingLanguage *string `url:"with_programming_language,omitempty" json:"with_programming_language,omitempty"` +} + +// ListProjects gets a list of projects accessible by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#list-all-projects +func (s *ProjectsService) ListProjects(opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "projects", opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ListUserProjects gets a list of projects for the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-a-users-projects +func (s *ProjectsService) ListUserProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("users/%s/projects", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ListUserContributedProjects gets a list of visible projects a given user has contributed to. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-projects-a-user-has-contributed-to +func (s *ProjectsService) ListUserContributedProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("users/%s/contributed_projects", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ListUserStarredProjects gets a list of projects starred by the given user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_starring/#list-projects-starred-by-a-user +func (s *ProjectsService) ListUserStarredProjects(uid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("users/%s/starred_projects", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*Project + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ProjectUser represents a GitLab project user. +type ProjectUser struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` +} + +// ListProjectUserOptions represents the available ListProjectsUsers() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#list-users +type ListProjectUserOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListProjectsUsers gets a list of users for the given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-users +func (s *ProjectsService) ListProjectsUsers(pid any, opt *ListProjectUserOptions, options ...RequestOptionFunc) ([]*ProjectUser, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/users", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProjectUser + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ProjectGroup represents a GitLab project group. +// GitLab API docs: https://docs.gitlab.com/api/projects/#list-groups +type ProjectGroup struct { + ID int `json:"id"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + FullName string `json:"full_name"` + FullPath string `json:"full_path"` +} + +// ListProjectGroupOptions represents the available ListProjectsGroups() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#list-groups +type ListProjectGroupOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + SharedMinAccessLevel *AccessLevelValue `url:"shared_min_access_level,omitempty" json:"shared_min_access_level,omitempty"` + SharedVisiableOnly *bool `url:"shared_visible_only,omitempty" json:"shared_visible_only,omitempty"` + SkipGroups *[]int `url:"skip_groups,omitempty" json:"skip_groups,omitempty"` + WithShared *bool `url:"with_shared,omitempty" json:"with_shared,omitempty"` +} + +// ListProjectsGroups gets a list of groups for the given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-groups +func (s *ProjectsService) ListProjectsGroups(pid any, opt *ListProjectGroupOptions, options ...RequestOptionFunc) ([]*ProjectGroup, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/groups", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProjectGroup + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ProjectLanguages is a map of strings because the response is arbitrary +// +// Gitlab API docs: +// https://docs.gitlab.com/api/projects/#list-programming-languages-used +type ProjectLanguages map[string]float32 + +// GetProjectLanguages gets a list of languages used by the project +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-programming-languages-used +func (s *ProjectsService) GetProjectLanguages(pid any, options ...RequestOptionFunc) (*ProjectLanguages, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/languages", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(ProjectLanguages) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetProjectOptions represents the available GetProject() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#get-a-single-project +type GetProjectOptions struct { + License *bool `url:"license,omitempty" json:"license,omitempty"` + Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` +} + +// GetProject gets a specific project, identified by project ID or +// NAMESPACE/PROJECT_NAME, which is owned by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#get-a-single-project +func (s *ProjectsService) GetProject(pid any, opt *GetProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreateProjectOptions represents the available CreateProject() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-a-project +type CreateProjectOptions struct { + AllowMergeOnSkippedPipeline *bool `url:"allow_merge_on_skipped_pipeline,omitempty" json:"allow_merge_on_skipped_pipeline,omitempty"` + OnlyAllowMergeIfAllStatusChecksPassed *bool `url:"only_allow_merge_if_all_status_checks_passed,omitempty" json:"only_allow_merge_if_all_status_checks_passed,omitempty"` + AnalyticsAccessLevel *AccessControlValue `url:"analytics_access_level,omitempty" json:"analytics_access_level,omitempty"` + AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` + AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` + AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` + AutocloseReferencedIssues *bool `url:"autoclose_referenced_issues,omitempty" json:"autoclose_referenced_issues,omitempty"` + Avatar *ProjectAvatar `url:"-" json:"-"` + BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` + BuildGitStrategy *string `url:"build_git_strategy,omitempty" json:"build_git_strategy,omitempty"` + BuildTimeout *int `url:"build_timeout,omitempty" json:"build_timeout,omitempty"` + BuildsAccessLevel *AccessControlValue `url:"builds_access_level,omitempty" json:"builds_access_level,omitempty"` + CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` + ContainerExpirationPolicyAttributes *ContainerExpirationPolicyAttributes `url:"container_expiration_policy_attributes,omitempty" json:"container_expiration_policy_attributes,omitempty"` + ContainerRegistryAccessLevel *AccessControlValue `url:"container_registry_access_level,omitempty" json:"container_registry_access_level,omitempty"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"` + EnforceAuthChecksOnUploads *bool `url:"enforce_auth_checks_on_uploads,omitempty" json:"enforce_auth_checks_on_uploads,omitempty"` + ExternalAuthorizationClassificationLabel *string `url:"external_authorization_classification_label,omitempty" json:"external_authorization_classification_label,omitempty"` + ForkingAccessLevel *AccessControlValue `url:"forking_access_level,omitempty" json:"forking_access_level,omitempty"` + GroupWithProjectTemplatesID *int `url:"group_with_project_templates_id,omitempty" json:"group_with_project_templates_id,omitempty"` + ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` + InitializeWithReadme *bool `url:"initialize_with_readme,omitempty" json:"initialize_with_readme,omitempty"` + IssuesAccessLevel *AccessControlValue `url:"issues_access_level,omitempty" json:"issues_access_level,omitempty"` + IssueBranchTemplate *string `url:"issue_branch_template,omitempty" json:"issue_branch_template,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + MergeCommitTemplate *string `url:"merge_commit_template,omitempty" json:"merge_commit_template,omitempty"` + MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` + MergePipelinesEnabled *bool `url:"merge_pipelines_enabled,omitempty" json:"merge_pipelines_enabled,omitempty"` + MergeRequestsAccessLevel *AccessControlValue `url:"merge_requests_access_level,omitempty" json:"merge_requests_access_level,omitempty"` + MergeTrainsEnabled *bool `url:"merge_trains_enabled,omitempty" json:"merge_trains_enabled,omitempty"` + Mirror *bool `url:"mirror,omitempty" json:"mirror,omitempty"` + MirrorTriggerBuilds *bool `url:"mirror_trigger_builds,omitempty" json:"mirror_trigger_builds,omitempty"` + ModelExperimentsAccessLevel *AccessControlValue `url:"model_experiments_access_level,omitempty" json:"model_experiments_access_level,omitempty"` + ModelRegistryAccessLevel *AccessControlValue `url:"model_registry_access_level,omitempty" json:"model_registry_access_level,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + NamespaceID *int `url:"namespace_id,omitempty" json:"namespace_id,omitempty"` + OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` + OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` + OperationsAccessLevel *AccessControlValue `url:"operations_access_level,omitempty" json:"operations_access_level,omitempty"` + PackagesEnabled *bool `url:"packages_enabled,omitempty" json:"packages_enabled,omitempty"` + PagesAccessLevel *AccessControlValue `url:"pages_access_level,omitempty" json:"pages_access_level,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + ReleasesAccessLevel *AccessControlValue `url:"releases_access_level,omitempty" json:"releases_access_level,omitempty"` + EnvironmentsAccessLevel *AccessControlValue `url:"environments_access_level,omitempty" json:"environments_access_level,omitempty"` + FeatureFlagsAccessLevel *AccessControlValue `url:"feature_flags_access_level,omitempty" json:"feature_flags_access_level,omitempty"` + InfrastructureAccessLevel *AccessControlValue `url:"infrastructure_access_level,omitempty" json:"infrastructure_access_level,omitempty"` + MonitorAccessLevel *AccessControlValue `url:"monitor_access_level,omitempty" json:"monitor_access_level,omitempty"` + RemoveSourceBranchAfterMerge *bool `url:"remove_source_branch_after_merge,omitempty" json:"remove_source_branch_after_merge,omitempty"` + PrintingMergeRequestLinkEnabled *bool `url:"printing_merge_request_link_enabled,omitempty" json:"printing_merge_request_link_enabled,omitempty"` + RepositoryAccessLevel *AccessControlValue `url:"repository_access_level,omitempty" json:"repository_access_level,omitempty"` + RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` + RequirementsAccessLevel *AccessControlValue `url:"requirements_access_level,omitempty" json:"requirements_access_level,omitempty"` + ResolveOutdatedDiffDiscussions *bool `url:"resolve_outdated_diff_discussions,omitempty" json:"resolve_outdated_diff_discussions,omitempty"` + SecurityAndComplianceAccessLevel *AccessControlValue `url:"security_and_compliance_access_level,omitempty" json:"security_and_compliance_access_level,omitempty"` + SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` + GroupRunnersEnabled *bool `url:"group_runners_enabled,omitempty" json:"group_runners_enabled,omitempty"` + ShowDefaultAwardEmojis *bool `url:"show_default_award_emojis,omitempty" json:"show_default_award_emojis,omitempty"` + SnippetsAccessLevel *AccessControlValue `url:"snippets_access_level,omitempty" json:"snippets_access_level,omitempty"` + SquashCommitTemplate *string `url:"squash_commit_template,omitempty" json:"squash_commit_template,omitempty"` + SquashOption *SquashOptionValue `url:"squash_option,omitempty" json:"squash_option,omitempty"` + SuggestionCommitMessage *string `url:"suggestion_commit_message,omitempty" json:"suggestion_commit_message,omitempty"` + TemplateName *string `url:"template_name,omitempty" json:"template_name,omitempty"` + TemplateProjectID *int `url:"template_project_id,omitempty" json:"template_project_id,omitempty"` + Topics *[]string `url:"topics,omitempty" json:"topics,omitempty"` + UseCustomTemplate *bool `url:"use_custom_template,omitempty" json:"use_custom_template,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` + + // Deprecated: use Merge Request Approvals API instead + ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` + // Deprecated: use PublicJobs instead + PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + // Deprecated: No longer supported in recent versions. + CIForwardDeploymentEnabled *bool `url:"ci_forward_deployment_enabled,omitempty" json:"ci_forward_deployment_enabled,omitempty"` + // Deprecated: Use ContainerRegistryAccessLevel instead. + ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` + // Deprecated: Use EmailsEnabled instead + EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` + // Deprecated: Use IssuesAccessLevel instead. + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + // Deprecated: No longer supported in recent versions. + IssuesTemplate *string `url:"issues_template,omitempty" json:"issues_template,omitempty"` + // Deprecated: Use BuildsAccessLevel instead. + JobsEnabled *bool `url:"jobs_enabled,omitempty" json:"jobs_enabled,omitempty"` + // Deprecated: Use MergeRequestsAccessLevel instead. + MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` + // Deprecated: No longer supported in recent versions. + MergeRequestsTemplate *string `url:"merge_requests_template,omitempty" json:"merge_requests_template,omitempty"` + // Deprecated: No longer supported in recent versions. + ServiceDeskEnabled *bool `url:"service_desk_enabled,omitempty" json:"service_desk_enabled,omitempty"` + // Deprecated: Use SnippetsAccessLevel instead. + SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` + // Deprecated: Use Topics instead. (Deprecated in GitLab 14.0) + TagList *[]string `url:"tag_list,omitempty" json:"tag_list,omitempty"` + // Deprecated: Use WikiAccessLevel instead. + WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` +} + +// ContainerExpirationPolicyAttributes represents the available container +// expiration policy attributes. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-a-project +type ContainerExpirationPolicyAttributes struct { + Cadence *string `url:"cadence,omitempty" json:"cadence,omitempty"` + KeepN *int `url:"keep_n,omitempty" json:"keep_n,omitempty"` + OlderThan *string `url:"older_than,omitempty" json:"older_than,omitempty"` + NameRegexDelete *string `url:"name_regex_delete,omitempty" json:"name_regex_delete,omitempty"` + NameRegexKeep *string `url:"name_regex_keep,omitempty" json:"name_regex_keep,omitempty"` + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + + // Deprecated: Is replaced by NameRegexDelete and is internally hardwired to its value. + NameRegex *string `url:"name_regex,omitempty" json:"name_regex,omitempty"` +} + +// ProjectAvatar represents a GitLab project avatar. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-a-project +type ProjectAvatar struct { + Filename string + Image io.Reader +} + +// MarshalJSON implements the json.Marshaler interface. +func (a *ProjectAvatar) MarshalJSON() ([]byte, error) { + if a.Filename == "" && a.Image == nil { + return []byte(`""`), nil + } + type alias ProjectAvatar + return json.Marshal((*alias)(a)) +} + +// CreateProject creates a new project owned by the authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-a-project +func (s *ProjectsService) CreateProject(opt *CreateProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + if opt.ContainerExpirationPolicyAttributes != nil { + // This is needed to satisfy the API. Should be deleted + // when NameRegex is removed (it's now deprecated). + opt.ContainerExpirationPolicyAttributes.NameRegex = opt.ContainerExpirationPolicyAttributes.NameRegexDelete + } + + var err error + var req *retryablehttp.Request + + if opt.Avatar == nil { + req, err = s.client.NewRequest(http.MethodPost, "projects", opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPost, + "projects", + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// CreateProjectForUserOptions represents the available CreateProjectForUser() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#create-a-project-for-a-user +type CreateProjectForUserOptions CreateProjectOptions + +// CreateProjectForUser creates a new project owned by the specified user. +// Available only for admins. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#create-a-project-for-a-user +func (s *ProjectsService) CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + if opt.ContainerExpirationPolicyAttributes != nil { + // This is needed to satisfy the API. Should be deleted + // when NameRegex is removed (it's now deprecated). + opt.ContainerExpirationPolicyAttributes.NameRegex = opt.ContainerExpirationPolicyAttributes.NameRegexDelete + } + + var err error + var req *retryablehttp.Request + u := fmt.Sprintf("projects/user/%d", user) + + if opt.Avatar == nil { + req, err = s.client.NewRequest(http.MethodPost, u, opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPost, + u, + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// EditProjectOptions represents the available EditProject() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#edit-a-project +type EditProjectOptions struct { + AllowMergeOnSkippedPipeline *bool `url:"allow_merge_on_skipped_pipeline,omitempty" json:"allow_merge_on_skipped_pipeline,omitempty"` + AllowPipelineTriggerApproveDeployment *bool `url:"allow_pipeline_trigger_approve_deployment,omitempty" json:"allow_pipeline_trigger_approve_deployment,omitempty"` + OnlyAllowMergeIfAllStatusChecksPassed *bool `url:"only_allow_merge_if_all_status_checks_passed,omitempty" json:"only_allow_merge_if_all_status_checks_passed,omitempty"` + AnalyticsAccessLevel *AccessControlValue `url:"analytics_access_level,omitempty" json:"analytics_access_level,omitempty"` + AutoCancelPendingPipelines *string `url:"auto_cancel_pending_pipelines,omitempty" json:"auto_cancel_pending_pipelines,omitempty"` + AutoDevopsDeployStrategy *string `url:"auto_devops_deploy_strategy,omitempty" json:"auto_devops_deploy_strategy,omitempty"` + AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` + AutocloseReferencedIssues *bool `url:"autoclose_referenced_issues,omitempty" json:"autoclose_referenced_issues,omitempty"` + Avatar *ProjectAvatar `url:"-" json:"avatar,omitempty"` + BuildCoverageRegex *string `url:"build_coverage_regex,omitempty" json:"build_coverage_regex,omitempty"` + BuildGitStrategy *string `url:"build_git_strategy,omitempty" json:"build_git_strategy,omitempty"` + BuildTimeout *int `url:"build_timeout,omitempty" json:"build_timeout,omitempty"` + BuildsAccessLevel *AccessControlValue `url:"builds_access_level,omitempty" json:"builds_access_level,omitempty"` + CIConfigPath *string `url:"ci_config_path,omitempty" json:"ci_config_path,omitempty"` + CIDefaultGitDepth *int `url:"ci_default_git_depth,omitempty" json:"ci_default_git_depth,omitempty"` + CIDeletePipelinesInSeconds *int `url:"ci_delete_pipelines_in_seconds,omitempty" json:"ci_delete_pipelines_in_seconds,omitempty"` + CIForwardDeploymentEnabled *bool `url:"ci_forward_deployment_enabled,omitempty" json:"ci_forward_deployment_enabled,omitempty"` + CIForwardDeploymentRollbackAllowed *bool `url:"ci_forward_deployment_rollback_allowed,omitempty" json:"ci_forward_deployment_rollback_allowed,omitempty"` + CIIdTokenSubClaimComponents *[]string `url:"ci_id_token_sub_claim_components,omitempty" json:"ci_id_token_sub_claim_components,omitempty"` + CISeperateCache *bool `url:"ci_separated_caches,omitempty" json:"ci_separated_caches,omitempty"` + CIRestrictPipelineCancellationRole *AccessControlValue `url:"ci_restrict_pipeline_cancellation_role,omitempty" json:"ci_restrict_pipeline_cancellation_role,omitempty"` + CIPipelineVariablesMinimumOverrideRole *CIPipelineVariablesMinimumOverrideRoleValue `url:"ci_pipeline_variables_minimum_override_role,omitempty" json:"ci_pipeline_variables_minimum_override_role,omitempty"` + ContainerExpirationPolicyAttributes *ContainerExpirationPolicyAttributes `url:"container_expiration_policy_attributes,omitempty" json:"container_expiration_policy_attributes,omitempty"` + ContainerRegistryAccessLevel *AccessControlValue `url:"container_registry_access_level,omitempty" json:"container_registry_access_level,omitempty"` + DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"` + EnforceAuthChecksOnUploads *bool `url:"enforce_auth_checks_on_uploads,omitempty" json:"enforce_auth_checks_on_uploads,omitempty"` + ExternalAuthorizationClassificationLabel *string `url:"external_authorization_classification_label,omitempty" json:"external_authorization_classification_label,omitempty"` + ForkingAccessLevel *AccessControlValue `url:"forking_access_level,omitempty" json:"forking_access_level,omitempty"` + ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"` + IssuesAccessLevel *AccessControlValue `url:"issues_access_level,omitempty" json:"issues_access_level,omitempty"` + IssueBranchTemplate *string `url:"issue_branch_template,omitempty" json:"issue_branch_template,omitempty"` + IssuesTemplate *string `url:"issues_template,omitempty" json:"issues_template,omitempty"` + KeepLatestArtifact *bool `url:"keep_latest_artifact,omitempty" json:"keep_latest_artifact,omitempty"` + LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"` + MergeCommitTemplate *string `url:"merge_commit_template,omitempty" json:"merge_commit_template,omitempty"` + MergeRequestDefaultTargetSelf *bool `url:"mr_default_target_self,omitempty" json:"mr_default_target_self,omitempty"` + MergeMethod *MergeMethodValue `url:"merge_method,omitempty" json:"merge_method,omitempty"` + MergePipelinesEnabled *bool `url:"merge_pipelines_enabled,omitempty" json:"merge_pipelines_enabled,omitempty"` + MergeRequestsAccessLevel *AccessControlValue `url:"merge_requests_access_level,omitempty" json:"merge_requests_access_level,omitempty"` + MergeRequestsTemplate *string `url:"merge_requests_template,omitempty" json:"merge_requests_template,omitempty"` + MergeTrainsEnabled *bool `url:"merge_trains_enabled,omitempty" json:"merge_trains_enabled,omitempty"` + Mirror *bool `url:"mirror,omitempty" json:"mirror,omitempty"` + MirrorBranchRegex *string `url:"mirror_branch_regex,omitempty" json:"mirror_branch_regex,omitempty"` + MirrorOverwritesDivergedBranches *bool `url:"mirror_overwrites_diverged_branches,omitempty" json:"mirror_overwrites_diverged_branches,omitempty"` + MirrorTriggerBuilds *bool `url:"mirror_trigger_builds,omitempty" json:"mirror_trigger_builds,omitempty"` + MirrorUserID *int `url:"mirror_user_id,omitempty" json:"mirror_user_id,omitempty"` + ModelExperimentsAccessLevel *AccessControlValue `url:"model_experiments_access_level,omitempty" json:"model_experiments_access_level,omitempty"` + ModelRegistryAccessLevel *AccessControlValue `url:"model_registry_access_level,omitempty" json:"model_registry_access_level,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"` + OnlyAllowMergeIfPipelineSucceeds *bool `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"` + OnlyMirrorProtectedBranches *bool `url:"only_mirror_protected_branches,omitempty" json:"only_mirror_protected_branches,omitempty"` + OperationsAccessLevel *AccessControlValue `url:"operations_access_level,omitempty" json:"operations_access_level,omitempty"` + PackagesEnabled *bool `url:"packages_enabled,omitempty" json:"packages_enabled,omitempty"` + PagesAccessLevel *AccessControlValue `url:"pages_access_level,omitempty" json:"pages_access_level,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + PublicJobs *bool `url:"public_jobs,omitempty" json:"public_jobs,omitempty"` + ReleasesAccessLevel *AccessControlValue `url:"releases_access_level,omitempty" json:"releases_access_level,omitempty"` + EnvironmentsAccessLevel *AccessControlValue `url:"environments_access_level,omitempty" json:"environments_access_level,omitempty"` + FeatureFlagsAccessLevel *AccessControlValue `url:"feature_flags_access_level,omitempty" json:"feature_flags_access_level,omitempty"` + InfrastructureAccessLevel *AccessControlValue `url:"infrastructure_access_level,omitempty" json:"infrastructure_access_level,omitempty"` + MonitorAccessLevel *AccessControlValue `url:"monitor_access_level,omitempty" json:"monitor_access_level,omitempty"` + RemoveSourceBranchAfterMerge *bool `url:"remove_source_branch_after_merge,omitempty" json:"remove_source_branch_after_merge,omitempty"` + PreventMergeWithoutJiraIssue *bool `url:"prevent_merge_without_jira_issue,omitempty" json:"prevent_merge_without_jira_issue,omitempty"` + PrintingMergeRequestLinkEnabled *bool `url:"printing_merge_request_link_enabled,omitempty" json:"printing_merge_request_link_enabled,omitempty"` + RepositoryAccessLevel *AccessControlValue `url:"repository_access_level,omitempty" json:"repository_access_level,omitempty"` + RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"` + RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"` + RequirementsAccessLevel *AccessControlValue `url:"requirements_access_level,omitempty" json:"requirements_access_level,omitempty"` + ResolveOutdatedDiffDiscussions *bool `url:"resolve_outdated_diff_discussions,omitempty" json:"resolve_outdated_diff_discussions,omitempty"` + SecurityAndComplianceAccessLevel *AccessControlValue `url:"security_and_compliance_access_level,omitempty" json:"security_and_compliance_access_level,omitempty"` + ServiceDeskEnabled *bool `url:"service_desk_enabled,omitempty" json:"service_desk_enabled,omitempty"` + SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` + GroupRunnersEnabled *bool `url:"group_runners_enabled,omitempty" json:"group_runners_enabled,omitempty"` + ShowDefaultAwardEmojis *bool `url:"show_default_award_emojis,omitempty" json:"show_default_award_emojis,omitempty"` + SnippetsAccessLevel *AccessControlValue `url:"snippets_access_level,omitempty" json:"snippets_access_level,omitempty"` + SquashCommitTemplate *string `url:"squash_commit_template,omitempty" json:"squash_commit_template,omitempty"` + SquashOption *SquashOptionValue `url:"squash_option,omitempty" json:"squash_option,omitempty"` + SuggestionCommitMessage *string `url:"suggestion_commit_message,omitempty" json:"suggestion_commit_message,omitempty"` + Topics *[]string `url:"topics,omitempty" json:"topics,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"` + + // Deprecated: use Merge Request Approvals API instead + ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` + // Deprecated: use PublicJobs instead + PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"` + // Deprecated: use CIPipelineVariablesMinimumOverrideRole instead + RestrictUserDefinedVariables *bool `url:"restrict_user_defined_variables,omitempty" json:"restrict_user_defined_variables,omitempty"` + // Deprecated: Use ContainerRegistryAccessLevel instead. + ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"` + // Deprecated: Use EmailsEnabled instead + EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"` + // Deprecated: Use IssuesAccessLevel instead. + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + // Deprecated: Use BuildsAccessLevel instead. + JobsEnabled *bool `url:"jobs_enabled,omitempty" json:"jobs_enabled,omitempty"` + // Deprecated: Use MergeRequestsAccessLevel instead. + MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"` + // Deprecated: Use SnippetsAccessLevel instead. + SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"` + // Deprecated: Use Topics instead. (Deprecated in GitLab 14.0) + TagList *[]string `url:"tag_list,omitempty" json:"tag_list,omitempty"` + // Deprecated: Use WikiAccessLevel instead. + WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"` +} + +// EditProject updates an existing project. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#edit-a-project +func (s *ProjectsService) EditProject(pid any, opt *EditProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + if opt.ContainerExpirationPolicyAttributes != nil { + // This is needed to satisfy the API. Should be deleted + // when NameRegex is removed (it's now deprecated). + opt.ContainerExpirationPolicyAttributes.NameRegex = opt.ContainerExpirationPolicyAttributes.NameRegexDelete + } + + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s", PathEscape(project)) + + var req *retryablehttp.Request + + if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) { + req, err = s.client.NewRequest(http.MethodPut, u, opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPut, + u, + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ForkProjectOptions represents the available ForkProject() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#fork-a-project +type ForkProjectOptions struct { + Branches *string `url:"branches,omitempty" json:"branches,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + MergeRequestDefaultTargetSelf *bool `url:"mr_default_target_self,omitempty" json:"mr_default_target_self,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + NamespaceID *int `url:"namespace_id,omitempty" json:"namespace_id,omitempty"` + NamespacePath *string `url:"namespace_path,omitempty" json:"namespace_path,omitempty"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + + // Deprecated: This parameter has been split into NamespaceID and NamespacePath. + Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` +} + +// ForkProject forks a project into the user namespace of the authenticated +// user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#fork-a-project +func (s *ProjectsService) ForkProject(pid any, opt *ForkProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/fork", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// StarProject stars a given the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_starring/#star-a-project +func (s *ProjectsService) StarProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/star", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ListProjectInvidedGroupOptions represents the available +// ListProjectsInvitedGroups() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-a-projects-invited-groups +type ListProjectInvidedGroupOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` + MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"` + Relation *[]string `url:"relation,omitempty" json:"relation,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` +} + +// ListProjectsInvitedGroups lists invited groups of a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#list-a-projects-invited-groups +func (s *ProjectsService) ListProjectsInvitedGroups(pid any, opt *ListProjectInvidedGroupOptions, options ...RequestOptionFunc) ([]*ProjectGroup, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/invited_groups", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pg []*ProjectGroup + resp, err := s.client.Do(req, &pg) + if err != nil { + return nil, resp, err + } + + return pg, resp, nil +} + +// UnstarProject unstars a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_starring/#unstar-a-project +func (s *ProjectsService) UnstarProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/unstar", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ArchiveProject archives the project if the user is either admin or the +// project owner of this project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#archive-a-project +func (s *ProjectsService) ArchiveProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/archive", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// UnarchiveProject unarchives the project if the user is either admin or +// the project owner of this project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#unarchive-a-project +func (s *ProjectsService) UnarchiveProject(pid any, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/unarchive", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// DeleteProjectOptions represents the available DeleteProject() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#delete-a-project +type DeleteProjectOptions struct { + FullPath *string `url:"full_path" json:"full_path"` + PermanentlyRemove *bool `url:"permanently_remove" json:"permanently_remove"` +} + +// DeleteProject removes a project including all associated resources +// (issues, merge requests etc.) +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#delete-a-project +func (s *ProjectsService) DeleteProject(pid any, opt *DeleteProjectOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ShareWithGroupOptions represents the available SharedWithGroup() options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#share-a-project-with-a-group +type ShareWithGroupOptions struct { + ExpiresAt *string `url:"expires_at" json:"expires_at"` + GroupAccess *AccessLevelValue `url:"group_access" json:"group_access"` + GroupID *int `url:"group_id" json:"group_id"` +} + +// ShareProjectWithGroup allows to share a project with a group. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#share-a-project-with-a-group +func (s *ProjectsService) ShareProjectWithGroup(pid any, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/share", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteSharedProjectFromGroup allows to unshare a project from a group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#delete-a-shared-project-link-in-a-group +func (s *ProjectsService) DeleteSharedProjectFromGroup(pid any, groupID int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/share/%d", PathEscape(project), groupID) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// HookCustomHeader represents a project or group hook custom header +// Note: "Key" is returned from the Get operation, but "Value" is not +// The List operation doesn't return any headers at all for Projects, +// but does return headers for Groups +type HookCustomHeader struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// ProjectHook represents a project hook. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#list-webhooks-for-a-project +type ProjectHook struct { + ID int `json:"id"` + URL string `json:"url"` + Name string `json:"name"` + Description string `json:"description"` + ConfidentialNoteEvents bool `json:"confidential_note_events"` + ProjectID int `json:"project_id"` + PushEvents bool `json:"push_events"` + PushEventsBranchFilter string `json:"push_events_branch_filter"` + IssuesEvents bool `json:"issues_events"` + ConfidentialIssuesEvents bool `json:"confidential_issues_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + TagPushEvents bool `json:"tag_push_events"` + NoteEvents bool `json:"note_events"` + JobEvents bool `json:"job_events"` + PipelineEvents bool `json:"pipeline_events"` + WikiPageEvents bool `json:"wiki_page_events"` + DeploymentEvents bool `json:"deployment_events"` + ReleasesEvents bool `json:"releases_events"` + EnableSSLVerification bool `json:"enable_ssl_verification"` + AlertStatus string `json:"alert_status"` + CreatedAt *time.Time `json:"created_at"` + ResourceAccessTokenEvents bool `json:"resource_access_token_events"` + CustomWebhookTemplate string `json:"custom_webhook_template"` + CustomHeaders []*HookCustomHeader `json:"custom_headers"` +} + +// ListProjectHooksOptions represents the available ListProjectHooks() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#list-webhooks-for-a-project +type ListProjectHooksOptions ListOptions + +// ListProjectHooks gets a list of project hooks. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#list-webhooks-for-a-project +func (s *ProjectsService) ListProjectHooks(pid any, opt *ListProjectHooksOptions, options ...RequestOptionFunc) ([]*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ph []*ProjectHook + resp, err := s.client.Do(req, &ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, nil +} + +// GetProjectHook gets a specific hook for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#get-a-project-webhook +func (s *ProjectsService) GetProjectHook(pid any, hook int, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", PathEscape(project), hook) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, nil +} + +// AddProjectHookOptions represents the available AddProjectHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#add-a-webhook-to-a-project +type AddProjectHookOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` + ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + ResourceAccessTokenEvents *bool `url:"resource_access_token_events,omitempty" json:"resource_access_token_events,omitempty"` + CustomWebhookTemplate *string `url:"custom_webhook_template,omitempty" json:"custom_webhook_template,omitempty"` + CustomHeaders *[]*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` +} + +// AddProjectHook adds a hook to a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#add-a-webhook-to-a-project +func (s *ProjectsService) AddProjectHook(pid any, opt *AddProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, nil +} + +// EditProjectHookOptions represents the available EditProjectHook() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#edit-a-project-webhook +type EditProjectHookOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + PushEventsBranchFilter *string `url:"push_events_branch_filter,omitempty" json:"push_events_branch_filter,omitempty"` + ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + Token *string `url:"token,omitempty" json:"token,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + ResourceAccessTokenEvents *bool `url:"resource_access_token_events,omitempty" json:"resource_access_token_events,omitempty"` + CustomWebhookTemplate *string `url:"custom_webhook_template,omitempty" json:"custom_webhook_template,omitempty"` + CustomHeaders *[]*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` +} + +// EditProjectHook edits a hook for a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#edit-a-project-webhook +func (s *ProjectsService) EditProjectHook(pid any, hook int, opt *EditProjectHookOptions, options ...RequestOptionFunc) (*ProjectHook, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", PathEscape(project), hook) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ph := new(ProjectHook) + resp, err := s.client.Do(req, ph) + if err != nil { + return nil, resp, err + } + + return ph, resp, nil +} + +// DeleteProjectHook removes a hook from a project. This is an idempotent +// method and can be called multiple times. Either the hook is available or not. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#delete-project-webhook +func (s *ProjectsService) DeleteProjectHook(pid any, hook int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d", PathEscape(project), hook) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// TriggerTestProjectHook Trigger a test hook for a specified project. +// +// In GitLab 17.0 and later, this endpoint has a special rate limit. +// In GitLab 17.0 the rate was three requests per minute for each project hook. +// In GitLab 17.1 this was changed to five requests per minute for each project +// and authenticated user. +// +// To disable this limit on self-managed GitLab and GitLab Dedicated, +// an administrator can disable the feature flag named web_hook_test_api_endpoint_rate_limit. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#trigger-a-test-project-webhook +func (s *ProjectsService) TriggerTestProjectHook(pid any, hook int, event ProjectHookEvent, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d/test/%s", PathEscape(project), hook, string(event)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SetHookCustomHeaderOptions represents the available SetProjectCustomHeader() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#set-a-custom-header +type SetHookCustomHeaderOptions struct { + Value *string `json:"value,omitempty"` +} + +// SetProjectCustomHeader creates or updates a project custom webhook header. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#set-a-custom-header +func (s *ProjectsService) SetProjectCustomHeader(pid any, hook int, key string, opt *SetHookCustomHeaderOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d/custom_headers/%s", PathEscape(project), hook, key) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteProjectCustomHeader deletes a project custom webhook header. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_webhooks/#delete-a-custom-header +func (s *ProjectsService) DeleteProjectCustomHeader(pid any, hook int, key string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/hooks/%d/custom_headers/%s", PathEscape(project), hook, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectForkRelation represents a project fork relationship. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#create-a-fork-relationship-between-projects +type ProjectForkRelation struct { + ID int `json:"id"` + ForkedToProjectID int `json:"forked_to_project_id"` + ForkedFromProjectID int `json:"forked_from_project_id"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` +} + +// CreateProjectForkRelation creates a forked from/to relation between +// existing projects. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#create-a-fork-relationship-between-projects +func (s *ProjectsService) CreateProjectForkRelation(pid any, fork int, options ...RequestOptionFunc) (*ProjectForkRelation, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/fork/%d", PathEscape(project), fork) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + pfr := new(ProjectForkRelation) + resp, err := s.client.Do(req, pfr) + if err != nil { + return nil, resp, err + } + + return pfr, resp, nil +} + +// DeleteProjectForkRelation deletes an existing forked from relationship. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#delete-a-fork-relationship-between-projects +func (s *ProjectsService) DeleteProjectForkRelation(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/fork", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UploadAvatar uploads an avatar. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#upload-a-project-avatar +func (s *ProjectsService) UploadAvatar(pid any, avatar io.Reader, filename string, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s", PathEscape(project)) + + req, err := s.client.UploadRequest( + http.MethodPut, + u, + avatar, + filename, + UploadAvatar, + nil, + options, + ) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// DownloadAvatar downloads an avatar. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#download-a-project-avatar +func (s *ProjectsService) DownloadAvatar(pid any, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/avatar", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + avatar := new(bytes.Buffer) + resp, err := s.client.Do(req, avatar) + if err != nil { + return nil, resp, err + } + + return bytes.NewReader(avatar.Bytes()), resp, err +} + +// ListProjectForks gets a list of project forks. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_forks/#list-forks-of-a-project +func (s *ProjectsService) ListProjectForks(pid any, opt *ListProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/forks", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var forks []*Project + resp, err := s.client.Do(req, &forks) + if err != nil { + return nil, resp, err + } + + return forks, resp, nil +} + +// ProjectPushRules represents a project push rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/ +type ProjectPushRules struct { + ID int `json:"id"` + ProjectID int `json:"project_id"` + CommitMessageRegex string `json:"commit_message_regex"` + CommitMessageNegativeRegex string `json:"commit_message_negative_regex"` + BranchNameRegex string `json:"branch_name_regex"` + DenyDeleteTag bool `json:"deny_delete_tag"` + CreatedAt *time.Time `json:"created_at"` + MemberCheck bool `json:"member_check"` + PreventSecrets bool `json:"prevent_secrets"` + AuthorEmailRegex string `json:"author_email_regex"` + FileNameRegex string `json:"file_name_regex"` + MaxFileSize int `json:"max_file_size"` + CommitCommitterCheck bool `json:"commit_committer_check"` + CommitCommitterNameCheck bool `json:"commit_committer_name_check"` + RejectUnsignedCommits bool `json:"reject_unsigned_commits"` + RejectNonDCOCommits bool `json:"reject_non_dco_commits"` +} + +// GetProjectPushRules gets the push rules of a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#get-project-push-rules +func (s *ProjectsService) GetProjectPushRules(pid any, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/push_rule", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ppr := new(ProjectPushRules) + resp, err := s.client.Do(req, ppr) + if err != nil { + return nil, resp, err + } + + return ppr, resp, nil +} + +// AddProjectPushRuleOptions represents the available AddProjectPushRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#add-a-project-push-rule +type AddProjectPushRuleOptions struct { + AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` + BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` + CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` + CommitCommitterNameCheck *bool `url:"commit_committer_name_check,omitempty" json:"commit_committer_name_check,omitempty"` + CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` + CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` + DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` + FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` + MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` + MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` + PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` + RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` + RejectNonDCOCommits *bool `url:"reject_non_dco_commits,omitempty" json:"reject_non_dco_commits,omitempty"` +} + +// AddProjectPushRule adds a push rule to a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#add-a-project-push-rule +func (s *ProjectsService) AddProjectPushRule(pid any, opt *AddProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/push_rule", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + ppr := new(ProjectPushRules) + resp, err := s.client.Do(req, ppr) + if err != nil { + return nil, resp, err + } + + return ppr, resp, nil +} + +// EditProjectPushRuleOptions represents the available EditProjectPushRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#edit-project-push-rule +type EditProjectPushRuleOptions struct { + AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"` + BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"` + CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"` + CommitCommitterNameCheck *bool `url:"commit_committer_name_check,omitempty" json:"commit_committer_name_check,omitempty"` + CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"` + CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"` + DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"` + FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"` + MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"` + MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"` + PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"` + RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"` + RejectNonDCOCommits *bool `url:"reject_non_dco_commits,omitempty" json:"reject_non_dco_commits,omitempty"` +} + +// EditProjectPushRule edits a push rule for a specified project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#edit-project-push-rule +func (s *ProjectsService) EditProjectPushRule(pid any, opt *EditProjectPushRuleOptions, options ...RequestOptionFunc) (*ProjectPushRules, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/push_rule", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ppr := new(ProjectPushRules) + resp, err := s.client.Do(req, ppr) + if err != nil { + return nil, resp, err + } + + return ppr, resp, nil +} + +// DeleteProjectPushRule removes a push rule from a project. This is an +// idempotent method and can be called multiple times. Either the push rule is +// available or not. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_push_rules/#delete-project-push-rule +func (s *ProjectsService) DeleteProjectPushRule(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/push_rule", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectApprovals represents GitLab project level merge request approvals. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#project-approval-rules +type ProjectApprovals struct { + Approvers []*MergeRequestApproverUser `json:"approvers"` + ApproverGroups []*MergeRequestApproverGroup `json:"approver_groups"` + ResetApprovalsOnPush bool `json:"reset_approvals_on_push"` + DisableOverridingApproversPerMergeRequest bool `json:"disable_overriding_approvers_per_merge_request"` + MergeRequestsAuthorApproval bool `json:"merge_requests_author_approval"` + MergeRequestsDisableCommittersApproval bool `json:"merge_requests_disable_committers_approval"` + RequirePasswordToApprove bool `json:"require_password_to_approve"` + SelectiveCodeOwnerRemovals bool `json:"selective_code_owner_removals,omitempty"` + + // Deprecated: use Merge Request Approvals API instead + ApprovalsBeforeMerge int `json:"approvals_before_merge"` +} + +// GetApprovalConfiguration get the approval configuration for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#project-approval-rules +func (s *ProjectsService) GetApprovalConfiguration(pid any, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approvals", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pa := new(ProjectApprovals) + resp, err := s.client.Do(req, pa) + if err != nil { + return nil, resp, err + } + + return pa, resp, nil +} + +// ChangeApprovalConfigurationOptions represents the available +// ApprovalConfiguration() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#change-configuration +type ChangeApprovalConfigurationOptions struct { + DisableOverridingApproversPerMergeRequest *bool `url:"disable_overriding_approvers_per_merge_request,omitempty" json:"disable_overriding_approvers_per_merge_request,omitempty"` + MergeRequestsAuthorApproval *bool `url:"merge_requests_author_approval,omitempty" json:"merge_requests_author_approval,omitempty"` + MergeRequestsDisableCommittersApproval *bool `url:"merge_requests_disable_committers_approval,omitempty" json:"merge_requests_disable_committers_approval,omitempty"` + RequirePasswordToApprove *bool `url:"require_password_to_approve,omitempty" json:"require_password_to_approve,omitempty"` + ResetApprovalsOnPush *bool `url:"reset_approvals_on_push,omitempty" json:"reset_approvals_on_push,omitempty"` + SelectiveCodeOwnerRemovals *bool `url:"selective_code_owner_removals,omitempty" json:"selective_code_owner_removals,omitempty"` + + // Deprecated: use Merge Request Approvals API instead + ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"` +} + +// ChangeApprovalConfiguration updates the approval configuration for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#change-configuration +func (s *ProjectsService) ChangeApprovalConfiguration(pid any, opt *ChangeApprovalConfigurationOptions, options ...RequestOptionFunc) (*ProjectApprovals, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approvals", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pa := new(ProjectApprovals) + resp, err := s.client.Do(req, pa) + if err != nil { + return nil, resp, err + } + + return pa, resp, nil +} + +// GetProjectApprovalRulesListsOptions represents the available +// GetProjectApprovalRules() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-all-approval-rules-for-project +type GetProjectApprovalRulesListsOptions ListOptions + +// GetProjectApprovalRules looks up the list of project level approver rules. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-all-approval-rules-for-project +func (s *ProjectsService) GetProjectApprovalRules(pid any, opt *GetProjectApprovalRulesListsOptions, options ...RequestOptionFunc) ([]*ProjectApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approval_rules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var par []*ProjectApprovalRule + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// GetProjectApprovalRule gets the project level approvers. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#get-single-approval-rule-for-project +func (s *ProjectsService) GetProjectApprovalRule(pid any, ruleID int, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approval_rules/%d", PathEscape(project), ruleID) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + par := new(ProjectApprovalRule) + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// CreateProjectLevelRuleOptions represents the available CreateProjectApprovalRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#create-project-approval-rule +type CreateProjectLevelRuleOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` + ReportType *string `url:"report_type,omitempty" json:"report_type,omitempty"` + RuleType *string `url:"rule_type,omitempty" json:"rule_type,omitempty"` + UserIDs *[]int `url:"user_ids,omitempty" json:"user_ids,omitempty"` + GroupIDs *[]int `url:"group_ids,omitempty" json:"group_ids,omitempty"` + ProtectedBranchIDs *[]int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` + AppliesToAllProtectedBranches *bool `url:"applies_to_all_protected_branches,omitempty" json:"applies_to_all_protected_branches,omitempty"` + Usernames *[]string `url:"usernames,omitempty" json:"usernames,omitempty"` +} + +// CreateProjectApprovalRule creates a new project-level approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#create-project-approval-rule +func (s *ProjectsService) CreateProjectApprovalRule(pid any, opt *CreateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approval_rules", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + par := new(ProjectApprovalRule) + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// UpdateProjectLevelRuleOptions represents the available UpdateProjectApprovalRule() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#update-project-approval-rule +type UpdateProjectLevelRuleOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"` + UserIDs *[]int `url:"user_ids,omitempty" json:"user_ids,omitempty"` + GroupIDs *[]int `url:"group_ids,omitempty" json:"group_ids,omitempty"` + ProtectedBranchIDs *[]int `url:"protected_branch_ids,omitempty" json:"protected_branch_ids,omitempty"` + AppliesToAllProtectedBranches *bool `url:"applies_to_all_protected_branches,omitempty" json:"applies_to_all_protected_branches,omitempty"` + Usernames *[]string `url:"usernames,omitempty" json:"usernames,omitempty"` +} + +// UpdateProjectApprovalRule updates an existing approval rule with new options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#update-project-approval-rule +func (s *ProjectsService) UpdateProjectApprovalRule(pid any, approvalRule int, opt *UpdateProjectLevelRuleOptions, options ...RequestOptionFunc) (*ProjectApprovalRule, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/approval_rules/%d", PathEscape(project), approvalRule) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + par := new(ProjectApprovalRule) + resp, err := s.client.Do(req, &par) + if err != nil { + return nil, resp, err + } + + return par, resp, nil +} + +// DeleteProjectApprovalRule deletes a project-level approval rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/merge_request_approvals/#delete-project-approval-rule +func (s *ProjectsService) DeleteProjectApprovalRule(pid any, approvalRule int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/approval_rules/%d", PathEscape(project), approvalRule) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ProjectPullMirrorDetails represent the details of the configuration pull +// mirror and its update status. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_pull_mirroring/ +type ProjectPullMirrorDetails struct { + ID int `json:"id"` + LastError string `json:"last_error"` + LastSuccessfulUpdateAt *time.Time `json:"last_successful_update_at"` + LastUpdateAt *time.Time `json:"last_update_at"` + LastUpdateStartedAt *time.Time `json:"last_update_started_at"` + UpdateStatus string `json:"update_status"` + URL string `json:"url"` +} + +// GetProjectPullMirrorDetails returns the pull mirror details. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_pull_mirroring/#get-a-projects-pull-mirror-details +func (s *ProjectsService) GetProjectPullMirrorDetails(pid any, options ...RequestOptionFunc) (*ProjectPullMirrorDetails, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/mirror/pull", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pmd := new(ProjectPullMirrorDetails) + resp, err := s.client.Do(req, pmd) + if err != nil { + return nil, resp, err + } + + return pmd, resp, nil +} + +// ConfigureProjectPullMirrorOptions represents the available ConfigureProjectPullMirror() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_pull_mirroring/#configure-pull-mirroring-for-a-project +type ConfigureProjectPullMirrorOptions struct { + Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + AuthUser *string `url:"auth_user,omitempty" json:"auth_user,omitempty"` + AuthPassword *string `url:"auth_password,omitempty" json:"auth_password,omitempty"` + MirrorTriggerBuilds *bool `url:"mirror_trigger_builds,omitempty" json:"mirror_trigger_builds,omitempty"` + OnlyMirrorProtectedBranches *bool `url:"only_mirror_protected_branches,omitempty" json:"only_mirror_protected_branches,omitempty"` + MirrorOverwritesDivergedBranches *bool `url:"mirror_overwrites_diverged_branches,omitempty" json:"mirror_overwrites_diverged_branches,omitempty"` + MirrorBranchRegex *string `url:"mirror_branch_regex,omitempty" json:"mirror_branch_regex,omitempty"` +} + +// ConfigureProjectPullMirror configures pull mirroring settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_pull_mirroring/#configure-pull-mirroring-for-a-project +func (s *ProjectsService) ConfigureProjectPullMirror(pid any, opt *ConfigureProjectPullMirrorOptions, options ...RequestOptionFunc) (*ProjectPullMirrorDetails, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/mirror/pull", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pmd := new(ProjectPullMirrorDetails) + resp, err := s.client.Do(req, pmd) + if err != nil { + return nil, resp, err + } + + return pmd, resp, nil +} + +// StartMirroringProject start the pull mirroring process for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_pull_mirroring/#start-the-pull-mirroring-process-for-a-project +func (s *ProjectsService) StartMirroringProject(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/mirror/pull", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// TransferProjectOptions represents the available TransferProject() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#transfer-a-project-to-a-new-namespace +type TransferProjectOptions struct { + Namespace any `url:"namespace,omitempty" json:"namespace,omitempty"` +} + +// TransferProject transfer a project into the specified namespace +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#transfer-a-project-to-a-new-namespace +func (s *ProjectsService) TransferProject(pid any, opt *TransferProjectOptions, options ...RequestOptionFunc) (*Project, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/transfer", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(Project) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// StartHousekeepingProject start the Housekeeping task for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#start-the-housekeeping-task-for-a-project +func (s *ProjectsService) StartHousekeepingProject(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/housekeeping", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GetRepositoryStorage Get the path to repository storage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#get-the-path-to-repository-storage +type ProjectReposityStorage struct { + ProjectID int `json:"project_id"` + DiskPath string `json:"disk_path"` + CreatedAt *time.Time `json:"created_at"` + RepositoryStorage string `json:"repository_storage"` +} + +// GetRepositoryStorage Get the path to repository storage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/projects/#get-the-path-to-repository-storage +func (s *ProjectsService) GetRepositoryStorage(pid any, options ...RequestOptionFunc) (*ProjectReposityStorage, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/storage", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + prs := new(ProjectReposityStorage) + resp, err := s.client.Do(req, prs) + if err != nil { + return nil, resp, err + } + + return prs, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/protected_branches.go b/vendor/gitlab.com/gitlab-org/api/client-go/protected_branches.go new file mode 100644 index 000000000..d3c1aaa76 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/protected_branches.go @@ -0,0 +1,247 @@ +// +// Copyright 2021, Sander van Harmelen, Michael Lihs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "net/url" +) + +type ( + ProtectedBranchesServiceInterface interface { + ListProtectedBranches(pid any, opt *ListProtectedBranchesOptions, options ...RequestOptionFunc) ([]*ProtectedBranch, *Response, error) + GetProtectedBranch(pid any, branch string, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) + ProtectRepositoryBranches(pid any, opt *ProtectRepositoryBranchesOptions, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) + UnprotectRepositoryBranches(pid any, branch string, options ...RequestOptionFunc) (*Response, error) + UpdateProtectedBranch(pid any, branch string, opt *UpdateProtectedBranchOptions, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) + } + + // ProtectedBranchesService handles communication with the protected branch + // related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/protected_branches/ + ProtectedBranchesService struct { + client *Client + } +) + +var _ ProtectedBranchesServiceInterface = (*ProtectedBranchesService)(nil) + +// ProtectedBranch represents a protected branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#list-protected-branches +type ProtectedBranch struct { + ID int `json:"id"` + Name string `json:"name"` + PushAccessLevels []*BranchAccessDescription `json:"push_access_levels"` + MergeAccessLevels []*BranchAccessDescription `json:"merge_access_levels"` + UnprotectAccessLevels []*BranchAccessDescription `json:"unprotect_access_levels"` + AllowForcePush bool `json:"allow_force_push"` + CodeOwnerApprovalRequired bool `json:"code_owner_approval_required"` +} + +// BranchAccessDescription represents the access description for a protected +// branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#list-protected-branches +type BranchAccessDescription struct { + ID int `json:"id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + DeployKeyID int `json:"deploy_key_id"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` +} + +// ListProtectedBranchesOptions represents the available ListProtectedBranches() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#list-protected-branches +type ListProtectedBranchesOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListProtectedBranches gets a list of protected branches from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#list-protected-branches +func (s *ProtectedBranchesService) ListProtectedBranches(pid any, opt *ListProtectedBranchesOptions, options ...RequestOptionFunc) ([]*ProtectedBranch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_branches", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var p []*ProtectedBranch + resp, err := s.client.Do(req, &p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// GetProtectedBranch gets a single protected branch or wildcard protected branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#get-a-single-protected-branch-or-wildcard-protected-branch +func (s *ProtectedBranchesService) GetProtectedBranch(pid any, branch string, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_branches/%s", PathEscape(project), url.PathEscape(branch)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + p := new(ProtectedBranch) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// ProtectRepositoryBranchesOptions represents the available +// ProtectRepositoryBranches() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#protect-repository-branches +type ProtectRepositoryBranchesOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + PushAccessLevel *AccessLevelValue `url:"push_access_level,omitempty" json:"push_access_level,omitempty"` + MergeAccessLevel *AccessLevelValue `url:"merge_access_level,omitempty" json:"merge_access_level,omitempty"` + UnprotectAccessLevel *AccessLevelValue `url:"unprotect_access_level,omitempty" json:"unprotect_access_level,omitempty"` + AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` + AllowedToPush *[]*BranchPermissionOptions `url:"allowed_to_push,omitempty" json:"allowed_to_push,omitempty"` + AllowedToMerge *[]*BranchPermissionOptions `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` + AllowedToUnprotect *[]*BranchPermissionOptions `url:"allowed_to_unprotect,omitempty" json:"allowed_to_unprotect,omitempty"` + CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` +} + +// BranchPermissionOptions represents a branch permission option. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#protect-repository-branches +type BranchPermissionOptions struct { + ID *int `url:"id,omitempty" json:"id,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + DeployKeyID *int `url:"deploy_key_id,omitempty" json:"deploy_key_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` +} + +// ProtectRepositoryBranches protects a single repository branch or several +// project repository branches using a wildcard protected branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#protect-repository-branches +func (s *ProtectedBranchesService) ProtectRepositoryBranches(pid any, opt *ProtectRepositoryBranchesOptions, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_branches", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(ProtectedBranch) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} + +// UnprotectRepositoryBranches unprotects the given protected branch or wildcard +// protected branch. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#unprotect-repository-branches +func (s *ProtectedBranchesService) UnprotectRepositoryBranches(pid any, branch string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/protected_branches/%s", PathEscape(project), url.PathEscape(branch)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UpdateProtectedBranchOptions represents the available +// UpdateProtectedBranch() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_branches/#update-a-protected-branch +type UpdateProtectedBranchOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` + CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` + AllowedToPush *[]*BranchPermissionOptions `url:"allowed_to_push,omitempty" json:"allowed_to_push,omitempty"` + AllowedToMerge *[]*BranchPermissionOptions `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` + AllowedToUnprotect *[]*BranchPermissionOptions `url:"allowed_to_unprotect,omitempty" json:"allowed_to_unprotect,omitempty"` +} + +// UpdateProtectedBranch updates a protected branch. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/protected_branches/#update-a-protected-branch +func (s *ProtectedBranchesService) UpdateProtectedBranch(pid any, branch string, opt *UpdateProtectedBranchOptions, options ...RequestOptionFunc) (*ProtectedBranch, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_branches/%s", PathEscape(project), url.PathEscape(branch)) + + req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) + if err != nil { + return nil, nil, err + } + + p := new(ProtectedBranch) + resp, err := s.client.Do(req, p) + if err != nil { + return nil, resp, err + } + + return p, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/protected_environments.go b/vendor/gitlab.com/gitlab-org/api/client-go/protected_environments.go new file mode 100644 index 000000000..0135b1ee1 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/protected_environments.go @@ -0,0 +1,294 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ProtectedEnvironmentsServiceInterface interface { + ListProtectedEnvironments(pid any, opt *ListProtectedEnvironmentsOptions, options ...RequestOptionFunc) ([]*ProtectedEnvironment, *Response, error) + GetProtectedEnvironment(pid any, environment string, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) + ProtectRepositoryEnvironments(pid any, opt *ProtectRepositoryEnvironmentsOptions, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) + UpdateProtectedEnvironments(pid any, environment string, opt *UpdateProtectedEnvironmentsOptions, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) + UnprotectEnvironment(pid any, environment string, options ...RequestOptionFunc) (*Response, error) + } + + // ProtectedEnvironmentsService handles communication with the protected + // environment methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/protected_environments/ + ProtectedEnvironmentsService struct { + client *Client + } +) + +var _ ProtectedEnvironmentsServiceInterface = (*ProtectedEnvironmentsService)(nil) + +// ProtectedEnvironment represents a protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/ +type ProtectedEnvironment struct { + Name string `json:"name"` + DeployAccessLevels []*EnvironmentAccessDescription `json:"deploy_access_levels"` + RequiredApprovalCount int `json:"required_approval_count"` + ApprovalRules []*EnvironmentApprovalRule `json:"approval_rules"` +} + +// EnvironmentAccessDescription represents the access decription for a protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/ +type EnvironmentAccessDescription struct { + ID int `json:"id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + GroupInheritanceType int `json:"group_inheritance_type"` +} + +// EnvironmentApprovalRule represents the approval rules for a protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#protect-a-single-environment +type EnvironmentApprovalRule struct { + ID int `json:"id"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + RequiredApprovalCount int `json:"required_approvals"` + GroupInheritanceType int `json:"group_inheritance_type"` +} + +// ListProtectedEnvironmentsOptions represents the available +// ListProtectedEnvironments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#list-protected-environments +type ListProtectedEnvironmentsOptions ListOptions + +// ListProtectedEnvironments returns a list of protected environments from a +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#list-protected-environments +func (s *ProtectedEnvironmentsService) ListProtectedEnvironments(pid any, opt *ListProtectedEnvironmentsOptions, options ...RequestOptionFunc) ([]*ProtectedEnvironment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_environments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pes []*ProtectedEnvironment + resp, err := s.client.Do(req, &pes) + if err != nil { + return nil, resp, err + } + + return pes, resp, nil +} + +// GetProtectedEnvironment returns a single protected environment or wildcard +// protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#get-a-single-protected-environment +func (s *ProtectedEnvironmentsService) GetProtectedEnvironment(pid any, environment string, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_environments/%s", PathEscape(project), PathEscape(environment)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pe := new(ProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// ProtectRepositoryEnvironmentsOptions represents the available +// ProtectRepositoryEnvironments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#protect-a-single-environment +type ProtectRepositoryEnvironmentsOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + DeployAccessLevels *[]*EnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` + RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + ApprovalRules *[]*EnvironmentApprovalRuleOptions `url:"approval_rules,omitempty" json:"approval_rules,omitempty"` +} + +// EnvironmentAccessOptions represents the options for an access decription for +// a protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#protect-a-single-environment +type EnvironmentAccessOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` +} + +// EnvironmentApprovalRuleOptions represents the approval rules for a protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#protect-a-single-environment +type EnvironmentApprovalRuleOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + AccessLevelDescription *string `url:"access_level_description,omitempty" json:"access_level_description,omitempty"` + RequiredApprovalCount *int `url:"required_approvals,omitempty" json:"required_approvals,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` +} + +// ProtectRepositoryEnvironments protects a single repository environment or +// several project repository environments using wildcard protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#protect-a-single-environment +func (s *ProtectedEnvironmentsService) ProtectRepositoryEnvironments(pid any, opt *ProtectRepositoryEnvironmentsOptions, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_environments", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pe := new(ProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// UpdateProtectedEnvironmentsOptions represents the available +// UpdateProtectedEnvironments() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#update-a-protected-environment +type UpdateProtectedEnvironmentsOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + DeployAccessLevels *[]*UpdateEnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` + RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + ApprovalRules *[]*UpdateEnvironmentApprovalRuleOptions `url:"approval_rules,omitempty" json:"approval_rules,omitempty"` +} + +// UpdateEnvironmentAccessOptions represents the options for updates to an +// access decription for a protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#update-a-protected-environment +type UpdateEnvironmentAccessOptions struct { + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + ID *int `url:"id,omitempty" json:"id,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` + Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` +} + +// UpdateEnvironmentApprovalRuleOptions represents the updates to the approval +// rules for a protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#update-a-protected-environment +type UpdateEnvironmentApprovalRuleOptions struct { + ID *int `url:"id,omitempty" json:"id,omitempty"` + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + AccessLevelDescription *string `url:"access_level_description,omitempty" json:"access_level_description,omitempty"` + RequiredApprovalCount *int `url:"required_approvals,omitempty" json:"required_approvals,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` + Destroy *bool `url:"_destroy,omitempty" json:"_destroy,omitempty"` +} + +// UpdateProtectedEnvironments updates a single repository environment or +// several project repository environments using wildcard protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#update-a-protected-environment +func (s *ProtectedEnvironmentsService) UpdateProtectedEnvironments(pid any, environment string, opt *UpdateProtectedEnvironmentsOptions, options ...RequestOptionFunc) (*ProtectedEnvironment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_environments/%s", PathEscape(project), PathEscape(environment)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + pe := new(ProtectedEnvironment) + resp, err := s.client.Do(req, pe) + if err != nil { + return nil, resp, err + } + + return pe, resp, nil +} + +// UnprotectEnvironment unprotects the given protected environment or wildcard +// protected environment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_environments/#unprotect-a-single-environment +func (s *ProtectedEnvironmentsService) UnprotectEnvironment(pid any, environment string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/protected_environments/%s", PathEscape(project), PathEscape(environment)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/protected_tags.go b/vendor/gitlab.com/gitlab-org/api/client-go/protected_tags.go new file mode 100644 index 000000000..e9adfe248 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/protected_tags.go @@ -0,0 +1,187 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ProtectedTagsServiceInterface interface { + ListProtectedTags(pid any, opt *ListProtectedTagsOptions, options ...RequestOptionFunc) ([]*ProtectedTag, *Response, error) + GetProtectedTag(pid any, tag string, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) + ProtectRepositoryTags(pid any, opt *ProtectRepositoryTagsOptions, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) + UnprotectRepositoryTags(pid any, tag string, options ...RequestOptionFunc) (*Response, error) + } + + // ProtectedTagsService handles communication with the protected tag methods + // of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/protected_tags/ + ProtectedTagsService struct { + client *Client + } +) + +var _ ProtectedTagsServiceInterface = (*ProtectedTagsService)(nil) + +// ProtectedTag represents a protected tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/ +type ProtectedTag struct { + Name string `json:"name"` + CreateAccessLevels []*TagAccessDescription `json:"create_access_levels"` +} + +// TagAccessDescription reperesents the access decription for a protected tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/ +type TagAccessDescription struct { + ID int `json:"id"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` +} + +// ListProtectedTagsOptions represents the available ListProtectedTags() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#list-protected-tags +type ListProtectedTagsOptions ListOptions + +// ListProtectedTags returns a list of protected tags from a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#list-protected-tags +func (s *ProtectedTagsService) ListProtectedTags(pid any, opt *ListProtectedTagsOptions, options ...RequestOptionFunc) ([]*ProtectedTag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_tags", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var pts []*ProtectedTag + resp, err := s.client.Do(req, &pts) + if err != nil { + return nil, resp, err + } + + return pts, resp, nil +} + +// GetProtectedTag returns a single protected tag or wildcard protected tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#get-a-single-protected-tag-or-wildcard-protected-tag +func (s *ProtectedTagsService) GetProtectedTag(pid any, tag string, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_tags/%s", PathEscape(project), PathEscape(tag)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + pt := new(ProtectedTag) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// ProtectRepositoryTagsOptions represents the available ProtectRepositoryTags() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#protect-repository-tags +type ProtectRepositoryTagsOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + CreateAccessLevel *AccessLevelValue `url:"create_access_level,omitempty" json:"create_access_level,omitempty"` + AllowedToCreate *[]*TagsPermissionOptions `url:"allowed_to_create,omitempty" json:"allowed_to_create,omitempty"` +} + +// TagsPermissionOptions represents a protected tag permission option. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#protect-repository-tags +type TagsPermissionOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` +} + +// ProtectRepositoryTags protects a single repository tag or several project +// repository tags using a wildcard protected tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#protect-repository-tags +func (s *ProtectedTagsService) ProtectRepositoryTags(pid any, opt *ProtectRepositoryTagsOptions, options ...RequestOptionFunc) (*ProtectedTag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/protected_tags", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + pt := new(ProtectedTag) + resp, err := s.client.Do(req, pt) + if err != nil { + return nil, resp, err + } + + return pt, resp, nil +} + +// UnprotectRepositoryTags unprotects the given protected tag or wildcard +// protected tag. +// +// GitLab API docs: +// https://docs.gitlab.com/api/protected_tags/#unprotect-repository-tags +func (s *ProtectedTagsService) UnprotectRepositoryTags(pid any, tag string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/protected_tags/%s", PathEscape(project), PathEscape(tag)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/releaselinks.go b/vendor/gitlab.com/gitlab-org/api/client-go/releaselinks.go new file mode 100644 index 000000000..804e1ae51 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/releaselinks.go @@ -0,0 +1,213 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ReleaseLinksServiceInterface interface { + ListReleaseLinks(pid any, tagName string, opt *ListReleaseLinksOptions, options ...RequestOptionFunc) ([]*ReleaseLink, *Response, error) + GetReleaseLink(pid any, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) + CreateReleaseLink(pid any, tagName string, opt *CreateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) + UpdateReleaseLink(pid any, tagName string, link int, opt *UpdateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) + DeleteReleaseLink(pid any, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) + } + + // ReleaseLinksService handles communication with the release link methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/releases/links/ + ReleaseLinksService struct { + client *Client + } +) + +var _ ReleaseLinksServiceInterface = (*ReleaseLinksService)(nil) + +// ReleaseLink represents a release link. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/ +type ReleaseLink struct { + ID int `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + DirectAssetURL string `json:"direct_asset_url"` + External bool `json:"external"` + LinkType LinkTypeValue `json:"link_type"` +} + +// ListReleaseLinksOptions represents ListReleaseLinks() options. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#list-links-of-a-release +type ListReleaseLinksOptions ListOptions + +// ListReleaseLinks gets assets as links from a Release. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#list-links-of-a-release +func (s *ReleaseLinksService) ListReleaseLinks(pid any, tagName string, opt *ListReleaseLinksOptions, options ...RequestOptionFunc) ([]*ReleaseLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s/assets/links", PathEscape(project), PathEscape(tagName)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var rls []*ReleaseLink + resp, err := s.client.Do(req, &rls) + if err != nil { + return nil, resp, err + } + + return rls, resp, nil +} + +// GetReleaseLink returns a link from release assets. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#get-a-release-link +func (s *ReleaseLinksService) GetReleaseLink(pid any, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", + PathEscape(project), + PathEscape(tagName), + link) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + rl := new(ReleaseLink) + resp, err := s.client.Do(req, rl) + if err != nil { + return nil, resp, err + } + + return rl, resp, nil +} + +// CreateReleaseLinkOptions represents CreateReleaseLink() options. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#create-a-release-link +type CreateReleaseLinkOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + FilePath *string `url:"filepath,omitempty" json:"filepath,omitempty"` + DirectAssetPath *string `url:"direct_asset_path,omitempty" json:"direct_asset_path,omitempty"` + LinkType *LinkTypeValue `url:"link_type,omitempty" json:"link_type,omitempty"` +} + +// CreateReleaseLink creates a link. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#create-a-release-link +func (s *ReleaseLinksService) CreateReleaseLink(pid any, tagName string, opt *CreateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s/assets/links", PathEscape(project), PathEscape(tagName)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + rl := new(ReleaseLink) + resp, err := s.client.Do(req, rl) + if err != nil { + return nil, resp, err + } + + return rl, resp, nil +} + +// UpdateReleaseLinkOptions represents UpdateReleaseLink() options. +// +// You have to specify at least one of Name of URL. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#update-a-release-link +type UpdateReleaseLinkOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + FilePath *string `url:"filepath,omitempty" json:"filepath,omitempty"` + DirectAssetPath *string `url:"direct_asset_path,omitempty" json:"direct_asset_path,omitempty"` + LinkType *LinkTypeValue `url:"link_type,omitempty" json:"link_type,omitempty"` +} + +// UpdateReleaseLink updates an asset link. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#update-a-release-link +func (s *ReleaseLinksService) UpdateReleaseLink(pid any, tagName string, link int, opt *UpdateReleaseLinkOptions, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", + PathEscape(project), + PathEscape(tagName), + link) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + rl := new(ReleaseLink) + resp, err := s.client.Do(req, rl) + if err != nil { + return nil, resp, err + } + + return rl, resp, nil +} + +// DeleteReleaseLink deletes a link from release. +// +// GitLab API docs: https://docs.gitlab.com/api/releases/links/#delete-a-release-link +func (s *ReleaseLinksService) DeleteReleaseLink(pid any, tagName string, link int, options ...RequestOptionFunc) (*ReleaseLink, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s/assets/links/%d", + PathEscape(project), + PathEscape(tagName), + link, + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, nil, err + } + + rl := new(ReleaseLink) + resp, err := s.client.Do(req, rl) + if err != nil { + return nil, resp, err + } + + return rl, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/releases.go b/vendor/gitlab.com/gitlab-org/api/client-go/releases.go new file mode 100644 index 000000000..1d335e314 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/releases.go @@ -0,0 +1,336 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ReleasesServiceInterface interface { + ListReleases(pid any, opt *ListReleasesOptions, options ...RequestOptionFunc) ([]*Release, *Response, error) + GetRelease(pid any, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) + GetLatestRelease(pid any, options ...RequestOptionFunc) (*Release, *Response, error) + CreateRelease(pid any, opts *CreateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) + UpdateRelease(pid any, tagName string, opts *UpdateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) + DeleteRelease(pid any, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) + } + + // ReleasesService handles communication with the releases methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/releases/ + ReleasesService struct { + client *Client + } +) + +var _ ReleasesServiceInterface = (*ReleasesService)(nil) + +// Release represents a project release. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +type Release struct { + TagName string `json:"tag_name"` + Name string `json:"name"` + Description string `json:"description"` + DescriptionHTML string `json:"description_html"` + CreatedAt *time.Time `json:"created_at"` + ReleasedAt *time.Time `json:"released_at"` + Author struct { + ID int `json:"id"` + Name string `json:"name"` + Username string `json:"username"` + State string `json:"state"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` + } `json:"author"` + Commit Commit `json:"commit"` + Milestones []*ReleaseMilestone `json:"milestones"` + UpcomingRelease bool `json:"upcoming_release"` + CommitPath string `json:"commit_path"` + TagPath string `json:"tag_path"` + Assets struct { + Count int `json:"count"` + Sources []struct { + Format string `json:"format"` + URL string `json:"url"` + } `json:"sources"` + Links []*ReleaseLink `json:"links"` + EvidenceFilePath string `json:"evidence_file_path"` + } `json:"assets"` + Evidences []*ReleaseEvidence `json:"evidences"` + Links struct { + ClosedIssueURL string `json:"closed_issues_url"` + ClosedMergeRequest string `json:"closed_merge_requests_url"` + EditURL string `json:"edit_url"` + MergedMergeRequest string `json:"merged_merge_requests_url"` + OpenedIssues string `json:"opened_issues_url"` + OpenedMergeRequest string `json:"opened_merge_requests_url"` + Self string `json:"self"` + } `json:"_links"` +} + +// ReleaseMilestone represents a project release milestone. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +type ReleaseMilestone struct { + ID int `json:"id"` + IID int `json:"iid"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + DueDate *ISOTime `json:"due_date"` + StartDate *ISOTime `json:"start_date"` + WebURL string `json:"web_url"` + IssueStats *ReleaseMilestoneIssueStats `json:"issue_stats"` +} + +// ReleaseMilestoneIssueStats represents a project release milestone's +// related issues statistics. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +type ReleaseMilestoneIssueStats struct { + Total int `json:"total"` + Closed int `json:"closed"` +} + +// ReleaseEvidence represents a project release's evidence. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +type ReleaseEvidence struct { + SHA string `json:"sha"` + Filepath string `json:"filepath"` + CollectedAt *time.Time `json:"collected_at"` +} + +// ListReleasesOptions represents ListReleases() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +type ListReleasesOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + IncludeHTMLDescription *bool `url:"include_html_description,omitempty" json:"include_html_description,omitempty"` +} + +// ListReleases gets a pagenated of releases accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#list-releases +func (s *ReleasesService) ListReleases(pid any, opt *ListReleasesOptions, options ...RequestOptionFunc) ([]*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Release + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// GetRelease returns a single release, identified by a tag name. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#get-a-release-by-a-tag-name +func (s *ReleasesService) GetRelease(pid any, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s", PathEscape(project), PathEscape(tagName)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(Release) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// GetLatestRelease returns the latest release for the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#get-the-latest-release +func (s *ReleasesService) GetLatestRelease(pid any, options ...RequestOptionFunc) (*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/permalink/latest", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(Release) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, err +} + +// CreateReleaseOptions represents CreateRelease() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#create-a-release +type CreateReleaseOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"` + TagMessage *string `url:"tag_message,omitempty" json:"tag_message,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Milestones *[]string `url:"milestones,omitempty" json:"milestones,omitempty"` + Assets *ReleaseAssetsOptions `url:"assets,omitempty" json:"assets,omitempty"` + ReleasedAt *time.Time `url:"released_at,omitempty" json:"released_at,omitempty"` +} + +// ReleaseAssetsOptions represents release assets in CreateRelease() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#create-a-release +type ReleaseAssetsOptions struct { + Links []*ReleaseAssetLinkOptions `url:"links,omitempty" json:"links,omitempty"` +} + +// ReleaseAssetLinkOptions represents release asset link in CreateRelease() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#create-a-release +type ReleaseAssetLinkOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + URL *string `url:"url,omitempty" json:"url,omitempty"` + FilePath *string `url:"filepath,omitempty" json:"filepath,omitempty"` + DirectAssetPath *string `url:"direct_asset_path,omitempty" json:"direct_asset_path,omitempty"` + LinkType *LinkTypeValue `url:"link_type,omitempty" json:"link_type,omitempty"` +} + +// CreateRelease creates a release. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#create-a-release +func (s *ReleasesService) CreateRelease(pid any, opts *CreateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + r := new(Release) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// UpdateReleaseOptions represents UpdateRelease() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#update-a-release +type UpdateReleaseOptions struct { + Name *string `url:"name" json:"name"` + Description *string `url:"description" json:"description"` + Milestones *[]string `url:"milestones,omitempty" json:"milestones,omitempty"` + ReleasedAt *time.Time `url:"released_at,omitempty" json:"released_at,omitempty"` +} + +// UpdateRelease updates a release. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#update-a-release +func (s *ReleasesService) UpdateRelease(pid any, tagName string, opts *UpdateReleaseOptions, options ...RequestOptionFunc) (*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s", PathEscape(project), PathEscape(tagName)) + + req, err := s.client.NewRequest(http.MethodPut, u, opts, options) + if err != nil { + return nil, nil, err + } + + r := new(Release) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// DeleteRelease deletes a release. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/#delete-a-release +func (s *ReleasesService) DeleteRelease(pid any, tagName string, options ...RequestOptionFunc) (*Release, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/releases/%s", PathEscape(project), PathEscape(tagName)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(Release) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/repositories.go b/vendor/gitlab.com/gitlab-org/api/client-go/repositories.go new file mode 100644 index 000000000..50da7ceb1 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/repositories.go @@ -0,0 +1,439 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/url" +) + +type ( + RepositoriesServiceInterface interface { + ListTree(pid any, opt *ListTreeOptions, options ...RequestOptionFunc) ([]*TreeNode, *Response, error) + Blob(pid any, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) + RawBlobContent(pid any, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) + Archive(pid any, opt *ArchiveOptions, options ...RequestOptionFunc) ([]byte, *Response, error) + StreamArchive(pid any, w io.Writer, opt *ArchiveOptions, options ...RequestOptionFunc) (*Response, error) + Compare(pid any, opt *CompareOptions, options ...RequestOptionFunc) (*Compare, *Response, error) + Contributors(pid any, opt *ListContributorsOptions, options ...RequestOptionFunc) ([]*Contributor, *Response, error) + MergeBase(pid any, opt *MergeBaseOptions, options ...RequestOptionFunc) (*Commit, *Response, error) + AddChangelog(pid any, opt *AddChangelogOptions, options ...RequestOptionFunc) (*Response, error) + GenerateChangelogData(pid any, opt GenerateChangelogDataOptions, options ...RequestOptionFunc) (*ChangelogData, *Response, error) + } + + // RepositoriesService handles communication with the repositories related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/repositories/ + RepositoriesService struct { + client *Client + } +) + +var _ RepositoriesServiceInterface = (*RepositoriesService)(nil) + +// TreeNode represents a GitLab repository file or directory. +// +// GitLab API docs: https://docs.gitlab.com/api/repositories/ +type TreeNode struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Path string `json:"path"` + Mode string `json:"mode"` +} + +func (t TreeNode) String() string { + return Stringify(t) +} + +// ListTreeOptions represents the available ListTree() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#list-repository-tree +type ListTreeOptions struct { + ListOptions + Path *string `url:"path,omitempty" json:"path,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Recursive *bool `url:"recursive,omitempty" json:"recursive,omitempty"` +} + +// ListTree gets a list of repository files and directories in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#list-repository-tree +func (s *RepositoriesService) ListTree(pid any, opt *ListTreeOptions, options ...RequestOptionFunc) ([]*TreeNode, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tree", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var t []*TreeNode + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// Blob gets information about blob in repository like size and content. Note +// that blob content is Base64 encoded. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#get-a-blob-from-repository +func (s *RepositoriesService) Blob(pid any, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/blobs/%s", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// RawBlobContent gets the raw file contents for a blob by blob SHA. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#raw-blob-content +func (s *RepositoriesService) RawBlobContent(pid any, sha string, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/blobs/%s/raw", PathEscape(project), url.PathEscape(sha)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// ArchiveOptions represents the available Archive() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#get-file-archive +type ArchiveOptions struct { + Format *string `url:"-" json:"-"` + Path *string `url:"path,omitempty" json:"path,omitempty"` + SHA *string `url:"sha,omitempty" json:"sha,omitempty"` +} + +// Archive gets an archive of the repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#get-file-archive +func (s *RepositoriesService) Archive(pid any, opt *ArchiveOptions, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/archive", PathEscape(project)) + + // Set an optional format for the archive. + if opt != nil && opt.Format != nil { + u = fmt.Sprintf("%s.%s", u, *opt.Format) + } + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// StreamArchive streams an archive of the repository to the provided +// io.Writer. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#get-file-archive +func (s *RepositoriesService) StreamArchive(pid any, w io.Writer, opt *ArchiveOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/archive", PathEscape(project)) + + // Set an optional format for the archive. + if opt != nil && opt.Format != nil { + u = fmt.Sprintf("%s.%s", u, *opt.Format) + } + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, w) +} + +// Compare represents the result of a comparison of branches, tags or commits. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#compare-branches-tags-or-commits +type Compare struct { + Commit *Commit `json:"commit"` + Commits []*Commit `json:"commits"` + Diffs []*Diff `json:"diffs"` + CompareTimeout bool `json:"compare_timeout"` + CompareSameRef bool `json:"compare_same_ref"` + WebURL string `json:"web_url"` +} + +func (c Compare) String() string { + return Stringify(c) +} + +// CompareOptions represents the available Compare() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#compare-branches-tags-or-commits +type CompareOptions struct { + From *string `url:"from,omitempty" json:"from,omitempty"` + To *string `url:"to,omitempty" json:"to,omitempty"` + Straight *bool `url:"straight,omitempty" json:"straight,omitempty"` + Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` +} + +// Compare compares branches, tags or commits. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#compare-branches-tags-or-commits +func (s *RepositoriesService) Compare(pid any, opt *CompareOptions, options ...RequestOptionFunc) (*Compare, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/compare", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Compare) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// Contributor represents a GitLap contributor. +// +// GitLab API docs: https://docs.gitlab.com/api/repositories/#contributors +type Contributor struct { + Name string `json:"name"` + Email string `json:"email"` + Commits int `json:"commits"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` +} + +func (c Contributor) String() string { + return Stringify(c) +} + +// ListContributorsOptions represents the available ListContributors() options. +// +// GitLab API docs: https://docs.gitlab.com/api/repositories/#contributors +type ListContributorsOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// Contributors gets the repository contributors list. +// +// GitLab API docs: https://docs.gitlab.com/api/repositories/#contributors +func (s *RepositoriesService) Contributors(pid any, opt *ListContributorsOptions, options ...RequestOptionFunc) ([]*Contributor, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/contributors", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var c []*Contributor + resp, err := s.client.Do(req, &c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// MergeBaseOptions represents the available MergeBase() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#merge-base +type MergeBaseOptions struct { + Ref *[]string `url:"refs[],omitempty" json:"refs,omitempty"` +} + +// MergeBase gets the common ancestor for 2 refs (commit SHAs, branch +// names or tags). +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#merge-base +func (s *RepositoriesService) MergeBase(pid any, opt *MergeBaseOptions, options ...RequestOptionFunc) (*Commit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/merge_base", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + c := new(Commit) + resp, err := s.client.Do(req, c) + if err != nil { + return nil, resp, err + } + + return c, resp, nil +} + +// AddChangelogOptions represents the available AddChangelog() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#add-changelog-data-to-a-changelog-file +type AddChangelogOptions struct { + Version *string `url:"version,omitempty" json:"version,omitempty"` + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + ConfigFile *string `url:"config_file,omitempty" json:"config_file,omitempty"` + Date *ISOTime `url:"date,omitempty" json:"date,omitempty"` + File *string `url:"file,omitempty" json:"file,omitempty"` + From *string `url:"from,omitempty" json:"from,omitempty"` + Message *string `url:"message,omitempty" json:"message,omitempty"` + To *string `url:"to,omitempty" json:"to,omitempty"` + Trailer *string `url:"trailer,omitempty" json:"trailer,omitempty"` +} + +// AddChangelog generates changelog data based on commits in a repository. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/repositories/#add-changelog-data-to-a-changelog-file +func (s *RepositoriesService) AddChangelog(pid any, opt *AddChangelogOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/changelog", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ChangelogData represents the generated changelog data. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#generate-changelog-data +type ChangelogData struct { + Notes string `json:"notes"` +} + +func (c ChangelogData) String() string { + return Stringify(c) +} + +// GenerateChangelogDataOptions represents the available GenerateChangelogData() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repositories/#generate-changelog-data +type GenerateChangelogDataOptions struct { + Version *string `url:"version,omitempty" json:"version,omitempty"` + ConfigFile *string `url:"config_file,omitempty" json:"config_file,omitempty"` + Date *ISOTime `url:"date,omitempty" json:"date,omitempty"` + From *string `url:"from,omitempty" json:"from,omitempty"` + To *string `url:"to,omitempty" json:"to,omitempty"` + Trailer *string `url:"trailer,omitempty" json:"trailer,omitempty"` +} + +// GenerateChangelogData generates changelog data based on commits in a +// repository, without committing them to a changelog file. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/repositories/#generate-changelog-data +func (s *RepositoriesService) GenerateChangelogData(pid any, opt GenerateChangelogDataOptions, options ...RequestOptionFunc) (*ChangelogData, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/changelog", project) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + cd := new(ChangelogData) + resp, err := s.client.Do(req, cd) + if err != nil { + return nil, resp, err + } + + return cd, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/repository_files.go b/vendor/gitlab.com/gitlab-org/api/client-go/repository_files.go new file mode 100644 index 000000000..32d1a4988 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/repository_files.go @@ -0,0 +1,446 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/http" + "strconv" + "time" +) + +type ( + RepositoryFilesServiceInterface interface { + GetFile(pid any, fileName string, opt *GetFileOptions, options ...RequestOptionFunc) (*File, *Response, error) + GetFileMetaData(pid any, fileName string, opt *GetFileMetaDataOptions, options ...RequestOptionFunc) (*File, *Response, error) + GetFileBlame(pid any, file string, opt *GetFileBlameOptions, options ...RequestOptionFunc) ([]*FileBlameRange, *Response, error) + GetRawFile(pid any, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) ([]byte, *Response, error) + GetRawFileMetaData(pid any, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) (*File, *Response, error) + CreateFile(pid any, fileName string, opt *CreateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) + UpdateFile(pid any, fileName string, opt *UpdateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) + DeleteFile(pid any, fileName string, opt *DeleteFileOptions, options ...RequestOptionFunc) (*Response, error) + } + + // RepositoryFilesService handles communication with the repository files + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/repository_files/ + RepositoryFilesService struct { + client *Client + } +) + +var _ RepositoryFilesServiceInterface = (*RepositoryFilesService)(nil) + +// File represents a GitLab repository file. +// +// GitLab API docs: https://docs.gitlab.com/api/repository_files/ +type File struct { + FileName string `json:"file_name"` + FilePath string `json:"file_path"` + Size int `json:"size"` + Encoding string `json:"encoding"` + Content string `json:"content"` + ExecuteFilemode bool `json:"execute_filemode"` + Ref string `json:"ref"` + BlobID string `json:"blob_id"` + CommitID string `json:"commit_id"` + SHA256 string `json:"content_sha256"` + LastCommitID string `json:"last_commit_id"` +} + +func (r File) String() string { + return Stringify(r) +} + +// GetFileOptions represents the available GetFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-from-repository +type GetFileOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// GetFile allows you to receive information about a file in repository like +// name, size, content. Note that file content is Base64 encoded. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-from-repository +func (s *RepositoryFilesService) GetFile(pid any, fileName string, opt *GetFileOptions, options ...RequestOptionFunc) (*File, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(File) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, nil +} + +// GetFileMetaDataOptions represents the available GetFileMetaData() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-from-repository +type GetFileMetaDataOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// GetFileMetaData allows you to receive meta information about a file in +// repository like name, size. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-from-repository +func (s *RepositoryFilesService) GetFileMetaData(pid any, fileName string, opt *GetFileMetaDataOptions, options ...RequestOptionFunc) (*File, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodHead, u, opt, options) + if err != nil { + return nil, nil, err + } + + resp, err := s.client.Do(req, nil) + if err != nil { + return nil, resp, err + } + + file, err := getMetaDataFileFromHeaders(resp) + if err != nil { + return nil, resp, err + } + + return file, resp, nil +} + +// getMetaDataFileFromHeaders extracts file metadata from response +// headers and converts it into a File object. +func getMetaDataFileFromHeaders(resp *Response) (*File, error) { + file := &File{ + BlobID: resp.Header.Get("X-Gitlab-Blob-Id"), + CommitID: resp.Header.Get("X-Gitlab-Commit-Id"), + Encoding: resp.Header.Get("X-Gitlab-Encoding"), + FileName: resp.Header.Get("X-Gitlab-File-Name"), + FilePath: resp.Header.Get("X-Gitlab-File-Path"), + ExecuteFilemode: resp.Header.Get("X-Gitlab-Execute-Filemode") == "true", + Ref: resp.Header.Get("X-Gitlab-Ref"), + SHA256: resp.Header.Get("X-Gitlab-Content-Sha256"), + LastCommitID: resp.Header.Get("X-Gitlab-Last-Commit-Id"), + } + + if sizeString := resp.Header.Get("X-Gitlab-Size"); sizeString != "" { + size, err := strconv.Atoi(sizeString) + if err != nil { + return nil, err + } + file.Size = size + } + + return file, nil +} + +// FileBlameRange represents one item of blame information. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-blame-from-repository +type FileBlameRange struct { + Commit struct { + ID string `json:"id"` + ParentIDs []string `json:"parent_ids"` + Message string `json:"message"` + AuthoredDate *time.Time `json:"authored_date"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + CommittedDate *time.Time `json:"committed_date"` + CommitterName string `json:"committer_name"` + CommitterEmail string `json:"committer_email"` + } `json:"commit"` + Lines []string `json:"lines"` +} + +func (b FileBlameRange) String() string { + return Stringify(b) +} + +// GetFileBlameOptions represents the available GetFileBlame() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-blame-from-repository +type GetFileBlameOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + RangeStart *int `url:"range[start],omitempty" json:"range[start],omitempty"` + RangeEnd *int `url:"range[end],omitempty" json:"range[end],omitempty"` +} + +// GetFileBlame allows you to receive blame information. Each blame range +// contains lines and corresponding commit info. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-file-blame-from-repository +func (s *RepositoryFilesService) GetFileBlame(pid any, file string, opt *GetFileBlameOptions, options ...RequestOptionFunc) ([]*FileBlameRange, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s/blame", + PathEscape(project), + PathEscape(file), + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var br []*FileBlameRange + resp, err := s.client.Do(req, &br) + if err != nil { + return nil, resp, err + } + + return br, resp, nil +} + +// GetRawFileOptions represents the available GetRawFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-raw-file-from-repository +type GetRawFileOptions struct { + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + LFS *bool `url:"lfs,omitempty" json:"lfs,omitempty"` +} + +// GetRawFile gets the contents of a raw file from a repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-raw-file-from-repository +func (s *RepositoryFilesService) GetRawFile(pid any, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) ([]byte, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s/raw", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var f bytes.Buffer + resp, err := s.client.Do(req, &f) + if err != nil { + return nil, resp, err + } + + return f.Bytes(), resp, err +} + +// GetRawFileMetaData gets the metadata of a raw file from a repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#get-raw-file-from-repository +func (s *RepositoryFilesService) GetRawFileMetaData(pid any, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) (*File, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s/raw", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodHead, u, opt, options) + if err != nil { + return nil, nil, err + } + + resp, err := s.client.Do(req, nil) + if err != nil { + return nil, resp, err + } + + file, err := getMetaDataFileFromHeaders(resp) + if err != nil { + return nil, resp, err + } + + return file, resp, nil +} + +// FileInfo represents file details of a GitLab repository file. +// +// GitLab API docs: https://docs.gitlab.com/api/repository_files/ +type FileInfo struct { + FilePath string `json:"file_path"` + Branch string `json:"branch"` +} + +func (r FileInfo) String() string { + return Stringify(r) +} + +// CreateFileOptions represents the available CreateFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#create-new-file-in-repository +type CreateFileOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` + Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` + ExecuteFilemode *bool `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"` +} + +// CreateFile creates a new file in a repository. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#create-new-file-in-repository +func (s *RepositoryFilesService) CreateFile(pid any, fileName string, opt *CreateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(FileInfo) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, nil +} + +// UpdateFileOptions represents the available UpdateFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#update-existing-file-in-repository +type UpdateFileOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` + Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` + LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` + ExecuteFilemode *bool `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"` +} + +// UpdateFile updates an existing file in a repository +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#update-existing-file-in-repository +func (s *RepositoryFilesService) UpdateFile(pid any, fileName string, opt *UpdateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + f := new(FileInfo) + resp, err := s.client.Do(req, f) + if err != nil { + return nil, resp, err + } + + return f, resp, nil +} + +// DeleteFileOptions represents the available DeleteFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#delete-existing-file-in-repository +type DeleteFileOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"` + AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"` + AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` + LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"` +} + +// DeleteFile deletes an existing file in a repository +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_files/#delete-existing-file-in-repository +func (s *RepositoryFilesService) DeleteFile(pid any, fileName string, opt *DeleteFileOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/files/%s", + PathEscape(project), + PathEscape(fileName), + ) + + req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/repository_submodules.go b/vendor/gitlab.com/gitlab-org/api/client-go/repository_submodules.go new file mode 100644 index 000000000..84a0491d4 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/repository_submodules.go @@ -0,0 +1,101 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + RepositorySubmodulesServiceInterface interface { + UpdateSubmodule(pid any, submodule string, opt *UpdateSubmoduleOptions, options ...RequestOptionFunc) (*SubmoduleCommit, *Response, error) + } + + // RepositorySubmodulesService handles communication with the repository + // submodules related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/repository_submodules/ + RepositorySubmodulesService struct { + client *Client + } +) + +var _ RepositorySubmodulesServiceInterface = (*RepositorySubmodulesService)(nil) + +// SubmoduleCommit represents a GitLab submodule commit. +// +// GitLab API docs: https://docs.gitlab.com/api/repository_submodules/ +type SubmoduleCommit struct { + ID string `json:"id"` + ShortID string `json:"short_id"` + Title string `json:"title"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + CommitterName string `json:"committer_name"` + CommitterEmail string `json:"committer_email"` + CreatedAt *time.Time `json:"created_at"` + Message string `json:"message"` + ParentIDs []string `json:"parent_ids"` + CommittedDate *time.Time `json:"committed_date"` + AuthoredDate *time.Time `json:"authored_date"` + Status *BuildStateValue `json:"status"` +} + +func (r SubmoduleCommit) String() string { + return Stringify(r) +} + +// UpdateSubmoduleOptions represents the available UpdateSubmodule() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_submodules/#update-existing-submodule-reference-in-repository +type UpdateSubmoduleOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` + CommitSHA *string `url:"commit_sha,omitempty" json:"commit_sha,omitempty"` + CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"` +} + +// UpdateSubmodule updates an existing submodule reference. +// +// GitLab API docs: +// https://docs.gitlab.com/api/repository_submodules/#update-existing-submodule-reference-in-repository +func (s *RepositorySubmodulesService) UpdateSubmodule(pid any, submodule string, opt *UpdateSubmoduleOptions, options ...RequestOptionFunc) (*SubmoduleCommit, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf( + "projects/%s/repository/submodules/%s", + PathEscape(project), + PathEscape(submodule), + ) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + sc := new(SubmoduleCommit) + resp, err := s.client.Do(req, sc) + if err != nil { + return nil, resp, err + } + + return sc, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/request_options.go b/vendor/gitlab.com/gitlab-org/api/client-go/request_options.go new file mode 100644 index 000000000..16f699c08 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/request_options.go @@ -0,0 +1,138 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "context" + "net/url" + "strconv" + + retryablehttp "github.com/hashicorp/go-retryablehttp" +) + +// RequestOptionFunc can be passed to all API requests to customize the API request. +type RequestOptionFunc func(*retryablehttp.Request) error + +// WithContext runs the request with the provided context +func WithContext(ctx context.Context) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + newCtx := copyContextValues(req.Context(), ctx) + + *req = *req.WithContext(newCtx) + return nil + } +} + +// copyContextValues copy some context key and values in old context +func copyContextValues(oldCtx context.Context, newCtx context.Context) context.Context { + cheryRetry := checkRetryFromContext(oldCtx) + + if cheryRetry != nil { + newCtx = contextWithCheckRetry(newCtx, cheryRetry) + } + + return newCtx +} + +// WithHeader takes a header name and value and appends it to the request headers. +func WithHeader(name, value string) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + req.Header.Set(name, value) + return nil + } +} + +// WithHeaders takes a map of header name/value pairs and appends them to the +// request headers. +func WithHeaders(headers map[string]string) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + for k, v := range headers { + req.Header.Set(k, v) + } + return nil + } +} + +// WithKeysetPaginationParameters takes a "next" link from the Link header of a +// response to a keyset-based paginated request and modifies the values of each +// query parameter in the request with its corresponding response parameter. +func WithKeysetPaginationParameters(nextLink string) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + nextUrl, err := url.Parse(nextLink) + if err != nil { + return err + } + q := req.URL.Query() + for k, values := range nextUrl.Query() { + q.Del(k) + for _, v := range values { + q.Add(k, v) + } + } + req.URL.RawQuery = q.Encode() + return nil + } +} + +// WithOffsetPaginationParameters takes a page number and modifies the request +// to use that page for offset-based pagination, overriding any existing page value. +func WithOffsetPaginationParameters(page int) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + q := req.URL.Query() + q.Del("page") + q.Add("page", strconv.Itoa(page)) + req.URL.RawQuery = q.Encode() + return nil + } +} + +// WithSudo takes either a username or user ID and sets the SUDO request header. +func WithSudo(uid any) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + user, err := parseID(uid) + if err != nil { + return err + } + req.Header.Set("SUDO", user) + return nil + } +} + +// WithToken takes a token which is then used when making this one request. +func WithToken(authType AuthType, token string) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + switch authType { + case JobToken: + req.Header.Set("JOB-TOKEN", token) + case OAuthToken: + req.Header.Set("Authorization", "Bearer "+token) + case PrivateToken: + req.Header.Set("PRIVATE-TOKEN", token) + } + return nil + } +} + +// WithRequestRetry takes a `retryablehttp.CheckRetry` which is then used when making this one request. +func WithRequestRetry(checkRetry retryablehttp.CheckRetry) RequestOptionFunc { + return func(req *retryablehttp.Request) error { + // Store checkRetry to context + ctx := contextWithCheckRetry(req.Context(), checkRetry) + *req = *req.WithContext(ctx) + return nil + } +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/resource_group.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_group.go new file mode 100644 index 000000000..7471c2959 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_group.go @@ -0,0 +1,176 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ResourceGroupServiceInterface interface { + GetAllResourceGroupsForAProject(pid any, options ...RequestOptionFunc) ([]*ResourceGroup, *Response, error) + GetASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) (*ResourceGroup, *Response, error) + ListUpcomingJobsForASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) ([]*Job, *Response, error) + EditAnExistingResourceGroup(pid any, key string, opts *EditAnExistingResourceGroupOptions, options ...RequestOptionFunc) (*ResourceGroup, *Response, error) + } + + // ResourceGroupService handles communication with the resource + // group related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/resource_groups/ + ResourceGroupService struct { + client *Client + } +) + +var _ ResourceGroupServiceInterface = (*ResourceGroupService)(nil) + +// ResourceGrouop represents a GitLab Project Resource Group. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/ +type ResourceGroup struct { + ID int `json:"id"` + Key string `json:"key"` + ProcessMode string `json:"process_mode"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` +} + +// Gets a string representation of a ResourceGroup +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/ +func (rg ResourceGroup) String() string { + return Stringify(rg) +} + +// GetAllResourceGroupsForAProject allows you to get all resource +// groups associated with a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/#get-all-resource-groups-for-a-project +func (s *ResourceGroupService) GetAllResourceGroupsForAProject(pid any, options ...RequestOptionFunc) ([]*ResourceGroup, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/resource_groups", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var rgs []*ResourceGroup + resp, err := s.client.Do(req, &rgs) + if err != nil { + return nil, resp, err + } + + return rgs, resp, nil +} + +// GetASpecificResourceGroup allows you to get a specific +// resource group for a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/#get-a-specific-resource-group +func (s *ResourceGroupService) GetASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) (*ResourceGroup, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/resource_groups/%s", PathEscape(project), key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + rg := new(ResourceGroup) + resp, err := s.client.Do(req, rg) + if err != nil { + return nil, resp, err + } + + return rg, resp, nil +} + +// ListUpcomingJobsForASpecificResourceGroup allows you to get all +// upcoming jobs for a specific resource group for a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/#list-upcoming-jobs-for-a-specific-resource-group +func (s *ResourceGroupService) ListUpcomingJobsForASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) ([]*Job, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/resource_groups/%s/upcoming_jobs", PathEscape(project), key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var js []*Job + resp, err := s.client.Do(req, &js) + if err != nil { + return nil, resp, err + } + + return js, resp, nil +} + +// EditAnExistingResourceGroupOptions represents the available +// EditAnExistingResourceGroup options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/#edit-an-existing-resource-group +type EditAnExistingResourceGroupOptions struct { + ProcessMode *ResourceGroupProcessMode `url:"process_mode,omitempty" json:"process_mode,omitempty"` +} + +// EditAnExistingResourceGroup allows you to edit a specific +// resource group for a given project +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_groups/#edit-an-existing-resource-group +func (s *ResourceGroupService) EditAnExistingResourceGroup(pid any, key string, opts *EditAnExistingResourceGroupOptions, options ...RequestOptionFunc) (*ResourceGroup, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/resource_groups/%s", PathEscape(project), key) + + req, err := s.client.NewRequest(http.MethodPut, u, opts, options) + if err != nil { + return nil, nil, err + } + + rg := new(ResourceGroup) + resp, err := s.client.Do(req, rg) + if err != nil { + return nil, resp, err + } + + return rg, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/resource_iteration_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_iteration_events.go new file mode 100644 index 000000000..bb52fc0ee --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_iteration_events.go @@ -0,0 +1,131 @@ +// +// Copyright 2023, Hakki Ceylan, Yavuz Turk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ResourceIterationEventsServiceInterface interface { + ListIssueIterationEvents(pid any, issue int, opt *ListIterationEventsOptions, options ...RequestOptionFunc) ([]*IterationEvent, *Response, error) + GetIssueIterationEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*IterationEvent, *Response, error) + } + + // ResourceIterationEventsService handles communication with the event related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/resource_iteration_events/ + ResourceIterationEventsService struct { + client *Client + } +) + +var _ ResourceIterationEventsServiceInterface = (*ResourceIterationEventsService)(nil) + +// IterationEvent represents a resource iteration event. +// +// GitLab API docs: https://docs.gitlab.com/api/resource_iteration_events/ +type IterationEvent struct { + ID int `json:"id"` + User *BasicUser `json:"user"` + CreatedAt *time.Time `json:"created_at"` + ResourceType string `json:"resource_type"` + ResourceID int `json:"resource_id"` + Iteration *Iteration `json:"iteration"` + Action string `json:"action"` +} + +// Iteration represents a project issue iteration. +// +// GitLab API docs: https://docs.gitlab.com/api/resource_iteration_events/ +type Iteration struct { + ID int `json:"id"` + IID int `json:"iid"` + Sequence int `json:"sequence"` + GroupID int `json:"group_id"` + Title string `json:"title"` + Description string `json:"description"` + State int `json:"state"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + DueDate *ISOTime `json:"due_date"` + StartDate *ISOTime `json:"start_date"` + WebURL string `json:"web_url"` +} + +// ListIterationEventsOptions represents the options for all resource state +// events list methods. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_iteration_events/#list-project-issue-iteration-events +type ListIterationEventsOptions struct { + ListOptions +} + +// ListIssueIterationEvents retrieves resource iteration events for the +// specified project and issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_iteration_events/#list-project-issue-iteration-events +func (s *ResourceIterationEventsService) ListIssueIterationEvents(pid any, issue int, opt *ListIterationEventsOptions, options ...RequestOptionFunc) ([]*IterationEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_iteration_events", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ies []*IterationEvent + resp, err := s.client.Do(req, &ies) + if err != nil { + return nil, resp, err + } + + return ies, resp, nil +} + +// GetIssueIterationEvent gets a single issue iteration event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_iteration_events/#get-single-issue-iteration-event +func (s *ResourceIterationEventsService) GetIssueIterationEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*IterationEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_iteration_events/%d", PathEscape(project), issue, event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ie := new(IterationEvent) + resp, err := s.client.Do(req, ie) + if err != nil { + return nil, resp, err + } + + return ie, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/resource_label_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_label_events.go similarity index 52% rename from vendor/github.com/xanzy/go-gitlab/resource_label_events.go rename to vendor/gitlab.com/gitlab-org/api/client-go/resource_label_events.go index 8d290b74d..f37296748 100644 --- a/vendor/github.com/xanzy/go-gitlab/resource_label_events.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_label_events.go @@ -1,5 +1,5 @@ // -// Copyright 2017, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,21 +18,38 @@ package gitlab import ( "fmt" + "net/http" "time" ) -// ResourceLabelEventsService handles communication with the event related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ee/api/resource_label_events.html -type ResourceLabelEventsService struct { - client *Client -} +type ( + ResourceLabelEventsServiceInterface interface { + ListIssueLabelEvents(pid any, issue int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) + GetIssueLabelEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) + ListMergeRequestsLabelEvents(pid any, request int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) + GetMergeRequestLabelEvent(pid any, request int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) + + // Will be removed in v5, use Work Items API instead + ListGroupEpicLabelEvents(gid any, epic int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) + // Will be removed in v5, use Work Items API instead + GetGroupEpicLabelEvent(gid any, epic int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) + } + + // ResourceLabelEventsService handles communication with the event related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/resource_label_events/ + ResourceLabelEventsService struct { + client *Client + } +) + +var _ ResourceLabelEventsServiceInterface = (*ResourceLabelEventsService)(nil) // LabelEvent represents a resource label event. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#get-single-issue-label-event +// https://docs.gitlab.com/api/resource_label_events/#get-single-issue-label-event type LabelEvent struct { ID int `json:"id"` Action string `json:"action"` @@ -60,7 +77,7 @@ type LabelEvent struct { // list methods. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#list-project-issue-label-events +// https://docs.gitlab.com/api/resource_label_events/#list-project-issue-label-events type ListLabelEventsOptions struct { ListOptions } @@ -69,15 +86,15 @@ type ListLabelEventsOptions struct { // specified project and issue. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#list-project-issue-label-events -func (s *ResourceLabelEventsService) ListIssueLabelEvents(pid interface{}, issue int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#list-project-issue-label-events +func (s *ResourceLabelEventsService) ListIssueLabelEvents(pid any, issue int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/issues/%d/resource_label_events", pathEscape(project), issue) + u := fmt.Sprintf("projects/%s/issues/%d/resource_label_events", PathEscape(project), issue) - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -88,21 +105,21 @@ func (s *ResourceLabelEventsService) ListIssueLabelEvents(pid interface{}, issue return nil, resp, err } - return ls, resp, err + return ls, resp, nil } // GetIssueLabelEvent gets a single issue-label-event. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#get-single-issue-label-event -func (s *ResourceLabelEventsService) GetIssueLabelEvent(pid interface{}, issue int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#get-single-issue-label-event +func (s *ResourceLabelEventsService) GetIssueLabelEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/issues/%d/resource_label_events/%d", pathEscape(project), issue, event) + u := fmt.Sprintf("projects/%s/issues/%d/resource_label_events/%d", PathEscape(project), issue, event) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -113,22 +130,23 @@ func (s *ResourceLabelEventsService) GetIssueLabelEvent(pid interface{}, issue i return nil, resp, err } - return l, resp, err + return l, resp, nil } // ListGroupEpicLabelEvents retrieves resource label events for the specified // group and epic. +// Will be removed in v5, use Work Items API instead // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#list-group-epic-label-events -func (s *ResourceLabelEventsService) ListGroupEpicLabelEvents(gid interface{}, epic int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#list-group-epic-label-events +func (s *ResourceLabelEventsService) ListGroupEpicLabelEvents(gid any, epic int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { group, err := parseID(gid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/epics/%d/resource_label_events", pathEscape(group), epic) + u := fmt.Sprintf("groups/%s/epics/%d/resource_label_events", PathEscape(group), epic) - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -139,21 +157,22 @@ func (s *ResourceLabelEventsService) ListGroupEpicLabelEvents(gid interface{}, e return nil, resp, err } - return ls, resp, err + return ls, resp, nil } // GetGroupEpicLabelEvent gets a single group epic label event. +// Will be removed in v5, use Work Items API instead // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#get-single-epic-label-event -func (s *ResourceLabelEventsService) GetGroupEpicLabelEvent(gid interface{}, epic int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#get-single-epic-label-event +func (s *ResourceLabelEventsService) GetGroupEpicLabelEvent(gid any, epic int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { group, err := parseID(gid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("groups/%s/epics/%d/resource_label_events/%d", pathEscape(group), epic, event) + u := fmt.Sprintf("groups/%s/epics/%d/resource_label_events/%d", PathEscape(group), epic, event) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -164,22 +183,22 @@ func (s *ResourceLabelEventsService) GetGroupEpicLabelEvent(gid interface{}, epi return nil, resp, err } - return l, resp, err + return l, resp, nil } -// ListMergeLabelEvents retrieves resource label events for the specified +// ListMergeRequestsLabelEvents retrieves resource label events for the specified // project and merge request. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#list-project-merge-request-label-events -func (s *ResourceLabelEventsService) ListMergeLabelEvents(pid interface{}, request int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#list-project-merge-request-label-events +func (s *ResourceLabelEventsService) ListMergeRequestsLabelEvents(pid any, request int, opt *ListLabelEventsOptions, options ...RequestOptionFunc) ([]*LabelEvent, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_label_events", pathEscape(project), request) + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_label_events", PathEscape(project), request) - req, err := s.client.NewRequest("GET", u, opt, options) + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } @@ -190,21 +209,21 @@ func (s *ResourceLabelEventsService) ListMergeLabelEvents(pid interface{}, reque return nil, resp, err } - return ls, resp, err + return ls, resp, nil } // GetMergeRequestLabelEvent gets a single merge request label event. // // GitLab API docs: -// https://docs.gitlab.com/ee/api/resource_label_events.html#get-single-merge-request-label-event -func (s *ResourceLabelEventsService) GetMergeRequestLabelEvent(pid interface{}, request int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { +// https://docs.gitlab.com/api/resource_label_events/#get-single-merge-request-label-event +func (s *ResourceLabelEventsService) GetMergeRequestLabelEvent(pid any, request int, event int, options ...RequestOptionFunc) (*LabelEvent, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } - u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_label_events/%d", pathEscape(project), request, event) + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_label_events/%d", PathEscape(project), request, event) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -215,5 +234,5 @@ func (s *ResourceLabelEventsService) GetMergeRequestLabelEvent(pid interface{}, return nil, resp, err } - return l, resp, err + return l, resp, nil } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/resource_milestone_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_milestone_events.go new file mode 100644 index 000000000..76cb105da --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_milestone_events.go @@ -0,0 +1,166 @@ +// +// Copyright 2022, Mai Lapyst +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ResourceMilestoneEventsServiceInterface interface { + ListIssueMilestoneEvents(pid any, issue int, opt *ListMilestoneEventsOptions, options ...RequestOptionFunc) ([]*MilestoneEvent, *Response, error) + GetIssueMilestoneEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*MilestoneEvent, *Response, error) + ListMergeMilestoneEvents(pid any, request int, opt *ListMilestoneEventsOptions, options ...RequestOptionFunc) ([]*MilestoneEvent, *Response, error) + GetMergeRequestMilestoneEvent(pid any, request int, event int, options ...RequestOptionFunc) (*MilestoneEvent, *Response, error) + } + + // ResourceMilestoneEventsService handles communication with the event related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/resource_milestone_events/ + ResourceMilestoneEventsService struct { + client *Client + } +) + +var _ ResourceMilestoneEventsServiceInterface = (*ResourceMilestoneEventsService)(nil) + +// MilestoneEvent represents a resource milestone event. +// +// GitLab API docs: https://docs.gitlab.com/api/resource_milestone_events/ +type MilestoneEvent struct { + ID int `json:"id"` + User *BasicUser `json:"user"` + CreatedAt *time.Time `json:"created_at"` + ResourceType string `json:"resource_type"` + ResourceID int `json:"resource_id"` + Milestone *Milestone `json:"milestone"` + Action string `json:"action"` +} + +// ListMilestoneEventsOptions represents the options for all resource state events +// list methods. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_milestone_events/#list-project-issue-milestone-events +type ListMilestoneEventsOptions struct { + ListOptions +} + +// ListIssueMilestoneEvents retrieves resource milestone events for the specified +// project and issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_milestone_events/#list-project-issue-milestone-events +func (s *ResourceMilestoneEventsService) ListIssueMilestoneEvents(pid any, issue int, opt *ListMilestoneEventsOptions, options ...RequestOptionFunc) ([]*MilestoneEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_milestone_events", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mes []*MilestoneEvent + resp, err := s.client.Do(req, &mes) + if err != nil { + return nil, resp, err + } + + return mes, resp, nil +} + +// GetIssueMilestoneEvent gets a single issue milestone event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_milestone_events/#get-single-issue-milestone-event +func (s *ResourceMilestoneEventsService) GetIssueMilestoneEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*MilestoneEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_milestone_events/%d", PathEscape(project), issue, event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + me := new(MilestoneEvent) + resp, err := s.client.Do(req, me) + if err != nil { + return nil, resp, err + } + + return me, resp, nil +} + +// ListMergeMilestoneEvents retrieves resource milestone events for the specified +// project and merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_milestone_events/#list-project-merge-request-milestone-events +func (s *ResourceMilestoneEventsService) ListMergeMilestoneEvents(pid any, request int, opt *ListMilestoneEventsOptions, options ...RequestOptionFunc) ([]*MilestoneEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_milestone_events", PathEscape(project), request) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var mes []*MilestoneEvent + resp, err := s.client.Do(req, &mes) + if err != nil { + return nil, resp, err + } + + return mes, resp, nil +} + +// GetMergeRequestMilestoneEvent gets a single merge request milestone event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_milestone_events/#get-single-merge-request-milestone-event +func (s *ResourceMilestoneEventsService) GetMergeRequestMilestoneEvent(pid any, request int, event int, options ...RequestOptionFunc) (*MilestoneEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_milestone_events/%d", PathEscape(project), request, event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + me := new(MilestoneEvent) + resp, err := s.client.Do(req, me) + if err != nil { + return nil, resp, err + } + + return me, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/resource_state_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_state_events.go new file mode 100644 index 000000000..b1acec9ce --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_state_events.go @@ -0,0 +1,165 @@ +// +// Copyright 2021, Matthias Simon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ResourceStateEventsServiceInterface interface { + ListIssueStateEvents(pid any, issue int, opt *ListStateEventsOptions, options ...RequestOptionFunc) ([]*StateEvent, *Response, error) + GetIssueStateEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*StateEvent, *Response, error) + ListMergeStateEvents(pid any, request int, opt *ListStateEventsOptions, options ...RequestOptionFunc) ([]*StateEvent, *Response, error) + GetMergeRequestStateEvent(pid any, request int, event int, options ...RequestOptionFunc) (*StateEvent, *Response, error) + } + + // ResourceStateEventsService handles communication with the event related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/resource_state_events/ + ResourceStateEventsService struct { + client *Client + } +) + +var _ ResourceStateEventsServiceInterface = (*ResourceStateEventsService)(nil) + +// StateEvent represents a resource state event. +// +// GitLab API docs: https://docs.gitlab.com/api/resource_state_events/ +type StateEvent struct { + ID int `json:"id"` + User *BasicUser `json:"user"` + CreatedAt *time.Time `json:"created_at"` + ResourceType string `json:"resource_type"` + ResourceID int `json:"resource_id"` + State EventTypeValue `json:"state"` +} + +// ListStateEventsOptions represents the options for all resource state events +// list methods. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_state_events/#list-project-issue-state-events +type ListStateEventsOptions struct { + ListOptions +} + +// ListIssueStateEvents retrieves resource state events for the specified +// project and issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_state_events/#list-project-issue-state-events +func (s *ResourceStateEventsService) ListIssueStateEvents(pid any, issue int, opt *ListStateEventsOptions, options ...RequestOptionFunc) ([]*StateEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_state_events", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ses []*StateEvent + resp, err := s.client.Do(req, &ses) + if err != nil { + return nil, resp, err + } + + return ses, resp, nil +} + +// GetIssueStateEvent gets a single issue-state-event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_state_events/#get-single-issue-state-event +func (s *ResourceStateEventsService) GetIssueStateEvent(pid any, issue int, event int, options ...RequestOptionFunc) (*StateEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_state_events/%d", PathEscape(project), issue, event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + se := new(StateEvent) + resp, err := s.client.Do(req, se) + if err != nil { + return nil, resp, err + } + + return se, resp, nil +} + +// ListMergeStateEvents retrieves resource state events for the specified +// project and merge request. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_state_events/#list-project-merge-request-state-events +func (s *ResourceStateEventsService) ListMergeStateEvents(pid any, request int, opt *ListStateEventsOptions, options ...RequestOptionFunc) ([]*StateEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_state_events", PathEscape(project), request) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ses []*StateEvent + resp, err := s.client.Do(req, &ses) + if err != nil { + return nil, resp, err + } + + return ses, resp, nil +} + +// GetMergeRequestStateEvent gets a single merge request state event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_state_events/#get-single-merge-request-state-event +func (s *ResourceStateEventsService) GetMergeRequestStateEvent(pid any, request int, event int, options ...RequestOptionFunc) (*StateEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/merge_requests/%d/resource_state_events/%d", PathEscape(project), request, event) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + se := new(StateEvent) + resp, err := s.client.Do(req, se) + if err != nil { + return nil, resp, err + } + + return se, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/resource_weight_events.go b/vendor/gitlab.com/gitlab-org/api/client-go/resource_weight_events.go new file mode 100644 index 000000000..e515f312a --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/resource_weight_events.go @@ -0,0 +1,88 @@ +// +// Copyright 2021, Matthias Simon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + ResourceWeightEventsServiceInterface interface { + ListIssueWeightEvents(pid any, issue int, opt *ListWeightEventsOptions, options ...RequestOptionFunc) ([]*WeightEvent, *Response, error) + } + + // ResourceWeightEventsService handles communication with the event related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/resource_weight_events/ + ResourceWeightEventsService struct { + client *Client + } +) + +var _ ResourceWeightEventsServiceInterface = (*ResourceWeightEventsService)(nil) + +// WeightEvent represents a resource weight event. +// +// GitLab API docs: https://docs.gitlab.com/api/resource_weight_events/ +type WeightEvent struct { + ID int `json:"id"` + User *BasicUser `json:"user"` + CreatedAt *time.Time `json:"created_at"` + ResourceType string `json:"resource_type"` + ResourceID int `json:"resource_id"` + State EventTypeValue `json:"state"` + IssueID int `json:"issue_id"` + Weight int `json:"weight"` +} + +// ListWeightEventsOptions represents the options for all resource weight events +// list methods. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_weight_events/#list-project-issue-weight-events +type ListWeightEventsOptions struct { + ListOptions +} + +// ListIssueWeightEvents retrieves resource weight events for the specified +// project and issue. +// +// GitLab API docs: +// https://docs.gitlab.com/api/resource_weight_events/#list-project-issue-weight-events +func (s *ResourceWeightEventsService) ListIssueWeightEvents(pid any, issue int, opt *ListWeightEventsOptions, options ...RequestOptionFunc) ([]*WeightEvent, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/issues/%d/resource_weight_events", PathEscape(project), issue) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var wes []*WeightEvent + resp, err := s.client.Do(req, &wes) + if err != nil { + return nil, resp, err + } + + return wes, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/runners.go b/vendor/gitlab.com/gitlab-org/api/client-go/runners.go new file mode 100644 index 000000000..b5285c806 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/runners.go @@ -0,0 +1,649 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + RunnersServiceInterface interface { + ListRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) + ListAllRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) + GetRunnerDetails(rid any, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) + UpdateRunnerDetails(rid any, opt *UpdateRunnerDetailsOptions, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) + RemoveRunner(rid any, options ...RequestOptionFunc) (*Response, error) + ListRunnerJobs(rid any, opt *ListRunnerJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) + ListProjectRunners(pid any, opt *ListProjectRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) + EnableProjectRunner(pid any, opt *EnableProjectRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) + DisableProjectRunner(pid any, runner int, options ...RequestOptionFunc) (*Response, error) + ListGroupsRunners(gid any, opt *ListGroupsRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) + RegisterNewRunner(opt *RegisterNewRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) + DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) + DeleteRegisteredRunnerByID(rid int, options ...RequestOptionFunc) (*Response, error) + VerifyRegisteredRunner(opt *VerifyRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) + ResetRunnerAuthenticationToken(rid int, options ...RequestOptionFunc) (*RunnerAuthenticationToken, *Response, error) + + // Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead + ResetInstanceRunnerRegistrationToken(options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) + + // Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead + ResetGroupRunnerRegistrationToken(gid any, options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) + + // Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead + ResetProjectRunnerRegistrationToken(pid any, options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) + } + + // RunnersService handles communication with the runner related methods of the + // GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/runners/ + RunnersService struct { + client *Client + } +) + +var _ RunnersServiceInterface = (*RunnersService)(nil) + +// Runner represents a GitLab CI Runner. +// +// GitLab API docs: https://docs.gitlab.com/api/runners/ +type Runner struct { + ID int `json:"id"` + Description string `json:"description"` + Paused bool `json:"paused"` + IsShared bool `json:"is_shared"` + RunnerType string `json:"runner_type"` + Name string `json:"name"` + Online bool `json:"online"` + Status string `json:"status"` + Token string `json:"token"` + TokenExpiresAt *time.Time `json:"token_expires_at"` + + // Deprecated: for removal in v5 of the API, use Paused instead + Active bool `json:"active"` + + // Deprecated: for removal in v5 of the API, returns an empty string from 17.0 onwards, see GraphQL resource CiRunnerManager instead + IPAddress string `json:"ip_address"` +} + +// RunnerDetails represents the GitLab CI runner details. +// +// GitLab API docs: https://docs.gitlab.com/api/runners/ +type RunnerDetails struct { + Paused bool `json:"paused"` + Description string `json:"description"` + ID int `json:"id"` + IsShared bool `json:"is_shared"` + RunnerType string `json:"runner_type"` + ContactedAt *time.Time `json:"contacted_at"` + MaintenanceNote string `json:"maintenance_note"` + Name string `json:"name"` + Online bool `json:"online"` + Status string `json:"status"` + Projects []struct { + ID int `json:"id"` + Name string `json:"name"` + NameWithNamespace string `json:"name_with_namespace"` + Path string `json:"path"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"projects"` + Token string `json:"token"` + TagList []string `json:"tag_list"` + RunUntagged bool `json:"run_untagged"` + Locked bool `json:"locked"` + AccessLevel string `json:"access_level"` + MaximumTimeout int `json:"maximum_timeout"` + Groups []struct { + ID int `json:"id"` + Name string `json:"name"` + WebURL string `json:"web_url"` + } `json:"groups"` + + // Deprecated: for removal in v5 of the API, see GraphQL resource CiRunnerManager instead + Architecture string `json:"architecture"` + + // Deprecated: for removal in v5 of the API, returns an empty string from 17.0 onwards, see GraphQL resource CiRunnerManager instead + IPAddress string `json:"ip_address"` + + // Deprecated: for removal in v5 of the API, see GraphQL resource CiRunnerManager instead + Platform string `json:"platform"` + + // Deprecated: for removal in v5 of the API, see GraphQL resource CiRunnerManager instead + Revision string `json:"revision"` + + // Deprecated: for removal in v5 of the API, see GraphQL resource CiRunnerManager instead + Version string `json:"version"` + + // Deprecated: for removal in v5 of the API, use Paused instead + Active bool `json:"active"` +} + +// ListRunnersOptions represents the available ListRunners() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-owned-runners +type ListRunnersOptions struct { + ListOptions + Type *string `url:"type,omitempty" json:"type,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` + Paused *bool `url:"paused,omitempty" json:"paused,omitempty"` + TagList *[]string `url:"tag_list,comma,omitempty" json:"tag_list,omitempty"` + + // Deprecated: Use Type or Status instead. + Scope *string `url:"scope,omitempty" json:"scope,omitempty"` +} + +// ListRunners gets a list of runners accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-owned-runners +func (s *RunnersService) ListRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "runners", opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Runner + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// ListAllRunners gets a list of all runners in the GitLab instance. Access is +// restricted to users with admin privileges. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-all-runners +func (s *RunnersService) ListAllRunners(opt *ListRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "runners/all", opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Runner + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// GetRunnerDetails returns details for given runner. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#get-runners-details +func (s *RunnersService) GetRunnerDetails(rid any, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) { + runner, err := parseID(rid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("runners/%s", runner) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + rs := new(RunnerDetails) + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// UpdateRunnerDetailsOptions represents the available UpdateRunnerDetails() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#update-runners-details +type UpdateRunnerDetailsOptions struct { + Description *string `url:"description,omitempty" json:"description,omitempty"` + Paused *bool `url:"paused,omitempty" json:"paused,omitempty"` + TagList *[]string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` + RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` + Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` + AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"` + MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` + MaintenanceNote *string `url:"maintenance_note,omitempty" json:"maintenance_note,omitempty"` + + // Deprecated: for removal in v5 of the API, use Paused instead + Active *bool `url:"active,omitempty" json:"active,omitempty"` +} + +// UpdateRunnerDetails updates details for a given runner. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#update-runners-details +func (s *RunnersService) UpdateRunnerDetails(rid any, opt *UpdateRunnerDetailsOptions, options ...RequestOptionFunc) (*RunnerDetails, *Response, error) { + runner, err := parseID(rid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("runners/%s", runner) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + rs := new(RunnerDetails) + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// RemoveRunner removes a runner. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#delete-a-runner +func (s *RunnersService) RemoveRunner(rid any, options ...RequestOptionFunc) (*Response, error) { + runner, err := parseID(rid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("runners/%s", runner) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListRunnerJobsOptions represents the available ListRunnerJobs() +// options. Status can be one of: running, success, failed, canceled. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-jobs-processed-by-a-runner +type ListRunnerJobsOptions struct { + ListOptions + Status *string `url:"status,omitempty" json:"status,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListRunnerJobs gets a list of jobs that are being processed or were processed by specified Runner. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-jobs-processed-by-a-runner +func (s *RunnersService) ListRunnerJobs(rid any, opt *ListRunnerJobsOptions, options ...RequestOptionFunc) ([]*Job, *Response, error) { + runner, err := parseID(rid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("runners/%s/jobs", runner) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Job + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// ListProjectRunnersOptions represents the available ListProjectRunners() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-projects-runners +type ListProjectRunnersOptions ListRunnersOptions + +// ListProjectRunners gets a list of runners accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-projects-runners +func (s *RunnersService) ListProjectRunners(pid any, opt *ListProjectRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/runners", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Runner + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// EnableProjectRunnerOptions represents the available EnableProjectRunner() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#assign-a-runner-to-project +type EnableProjectRunnerOptions struct { + RunnerID int `json:"runner_id"` +} + +// EnableProjectRunner enables an available specific runner in the project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#assign-a-runner-to-project +func (s *RunnersService) EnableProjectRunner(pid any, opt *EnableProjectRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/runners", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + r := new(Runner) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// DisableProjectRunner disables a specific runner from project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#unassign-a-runner-from-project +func (s *RunnersService) DisableProjectRunner(pid any, runner int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/runners/%d", PathEscape(project), runner) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGroupsRunnersOptions represents the available ListGroupsRunners() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-groups-runners +type ListGroupsRunnersOptions struct { + ListOptions + Type *string `url:"type,omitempty" json:"type,omitempty"` + Status *string `url:"status,omitempty" json:"status,omitempty"` + TagList *[]string `url:"tag_list,comma,omitempty" json:"tag_list,omitempty"` +} + +// ListGroupsRunners lists all runners (specific and shared) available in the +// group as well it’s ancestor groups. Shared runners are listed if at least one +// shared runner is defined. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#list-groups-runners +func (s *RunnersService) ListGroupsRunners(gid any, opt *ListGroupsRunnersOptions, options ...RequestOptionFunc) ([]*Runner, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/runners", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var rs []*Runner + resp, err := s.client.Do(req, &rs) + if err != nil { + return nil, resp, err + } + + return rs, resp, nil +} + +// RegisterNewRunnerOptions represents the available RegisterNewRunner() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#create-a-runner +type RegisterNewRunnerOptions struct { + Token *string `url:"token" json:"token"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Info *RegisterNewRunnerInfoOptions `url:"info,omitempty" json:"info,omitempty"` + Paused *bool `url:"paused,omitempty" json:"paused,omitempty"` + Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` + RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` + TagList *[]string `url:"tag_list[],omitempty" json:"tag_list,omitempty"` + AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"` + MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` + MaintenanceNote *string `url:"maintenance_note,omitempty" json:"maintenance_note,omitempty"` + + // Deprecated: for removal in v5 of the API, use Paused instead + Active *bool `url:"active,omitempty" json:"active,omitempty"` +} + +// RegisterNewRunnerInfoOptions represents the info hashmap parameter in +// RegisterNewRunnerOptions. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#create-a-runner +type RegisterNewRunnerInfoOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Version *string `url:"version,omitempty" json:"version,omitempty"` + Revision *string `url:"revision,omitempty" json:"revision,omitempty"` + Platform *string `url:"platform,omitempty" json:"platform,omitempty"` + Architecture *string `url:"architecture,omitempty" json:"architecture,omitempty"` +} + +// RegisterNewRunner registers a new Runner for the instance. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#create-a-runner +func (s *RunnersService) RegisterNewRunner(opt *RegisterNewRunnerOptions, options ...RequestOptionFunc) (*Runner, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "runners", opt, options) + if err != nil { + return nil, nil, err + } + + r := new(Runner) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// DeleteRegisteredRunnerOptions represents the available +// DeleteRegisteredRunner() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#delete-a-runner-by-authentication-token +type DeleteRegisteredRunnerOptions struct { + Token *string `url:"token" json:"token"` +} + +// DeleteRegisteredRunner deletes a Runner by Token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#delete-a-runner-by-authentication-token +func (s *RunnersService) DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, "runners", opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteRegisteredRunnerByID deletes a runner by ID. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#delete-a-runner-by-id +func (s *RunnersService) DeleteRegisteredRunnerByID(rid int, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodDelete, fmt.Sprintf("runners/%d", rid), nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// VerifyRegisteredRunnerOptions represents the available +// VerifyRegisteredRunner() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#verify-authentication-for-a-registered-runner +type VerifyRegisteredRunnerOptions struct { + Token *string `url:"token" json:"token"` +} + +// VerifyRegisteredRunner registers a new runner for the instance. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#verify-authentication-for-a-registered-runner +func (s *RunnersService) VerifyRegisteredRunner(opt *VerifyRegisteredRunnerOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "runners/verify", opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +type RunnerRegistrationToken struct { + Token *string `url:"token" json:"token"` + TokenExpiresAt *time.Time `url:"token_expires_at" json:"token_expires_at"` +} + +// ResetInstanceRunnerRegistrationToken resets the instance runner registration +// token. +// Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#reset-instances-runner-registration-token +func (s *RunnersService) ResetInstanceRunnerRegistrationToken(options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "runners/reset_registration_token", nil, options) + if err != nil { + return nil, nil, err + } + + r := new(RunnerRegistrationToken) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// ResetGroupRunnerRegistrationToken resets a group's runner registration token. +// Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#reset-groups-runner-registration-token +func (s *RunnersService) ResetGroupRunnerRegistrationToken(gid any, options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("groups/%s/runners/reset_registration_token", PathEscape(group)) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(RunnerRegistrationToken) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// ResetProjectRunnerRegistrationToken resets a projects's runner registration token. +// Deprecated: for removal in GitLab 20.0, see https://docs.gitlab.com/ci/runners/new_creation_workflow/ instead +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#reset-projects-runner-registration-token +func (s *RunnersService) ResetProjectRunnerRegistrationToken(pid any, options ...RequestOptionFunc) (*RunnerRegistrationToken, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/runners/reset_registration_token", PathEscape(project)) + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(RunnerRegistrationToken) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +type RunnerAuthenticationToken struct { + Token *string `url:"token" json:"token"` + TokenExpiresAt *time.Time `url:"token_expires_at" json:"token_expires_at"` +} + +// ResetRunnerAuthenticationToken resets a runner's authentication token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/runners/#reset-runners-authentication-token-by-using-the-runner-id +func (s *RunnersService) ResetRunnerAuthenticationToken(rid int, options ...RequestOptionFunc) (*RunnerAuthenticationToken, *Response, error) { + u := fmt.Sprintf("runners/%d/reset_authentication_token", rid) + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + r := new(RunnerAuthenticationToken) + resp, err := s.client.Do(req, &r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/search.go b/vendor/gitlab.com/gitlab-org/api/client-go/search.go new file mode 100644 index 000000000..b857f7641 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/search.go @@ -0,0 +1,381 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + SearchServiceInterface interface { + Projects(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + ProjectsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) + Issues(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + IssuesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + IssuesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) + MergeRequests(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) + MergeRequestsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) + MergeRequestsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) + Milestones(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) + MilestonesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) + MilestonesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) + SnippetTitles(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) + NotesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) + WikiBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) + WikiBlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) + WikiBlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) + Commits(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) + CommitsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) + CommitsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) + Blobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) + BlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) + BlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) + Users(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + UsersByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + UsersByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + } + + // SearchService handles communication with the search related methods of the + // GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/search/ + SearchService struct { + client *Client + } +) + +var _ SearchServiceInterface = (*SearchService)(nil) + +// SearchOptions represents the available options for all search methods. +// +// GitLab API docs: https://docs.gitlab.com/api/search/ +type SearchOptions struct { + ListOptions + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +type searchOptions struct { + SearchOptions + Scope string `url:"scope" json:"scope"` + Search string `url:"search" json:"search"` +} + +// Projects searches the expression within projects +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-projects +func (s *SearchService) Projects(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + var ps []*Project + resp, err := s.search("projects", query, &ps, opt, options...) + return ps, resp, err +} + +// ProjectsByGroup searches the expression within projects for +// the specified group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#group-search-api +func (s *SearchService) ProjectsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { + var ps []*Project + resp, err := s.searchByGroup(gid, "projects", query, &ps, opt, options...) + return ps, resp, err +} + +// Issues searches the expression within issues +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-issues +func (s *SearchService) Issues(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + var is []*Issue + resp, err := s.search("issues", query, &is, opt, options...) + return is, resp, err +} + +// IssuesByGroup searches the expression within issues for +// the specified group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-issues-1 +func (s *SearchService) IssuesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + var is []*Issue + resp, err := s.searchByGroup(gid, "issues", query, &is, opt, options...) + return is, resp, err +} + +// IssuesByProject searches the expression within issues for +// the specified project +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-issues-2 +func (s *SearchService) IssuesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { + var is []*Issue + resp, err := s.searchByProject(pid, "issues", query, &is, opt, options...) + return is, resp, err +} + +// MergeRequests searches the expression within merge requests +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-merge_requests +func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { + var ms []*MergeRequest + resp, err := s.search("merge_requests", query, &ms, opt, options...) + return ms, resp, err +} + +// MergeRequestsByGroup searches the expression within merge requests for +// the specified group +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-merge_requests-1 +func (s *SearchService) MergeRequestsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { + var ms []*MergeRequest + resp, err := s.searchByGroup(gid, "merge_requests", query, &ms, opt, options...) + return ms, resp, err +} + +// MergeRequestsByProject searches the expression within merge requests for +// the specified project +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-merge_requests-2 +func (s *SearchService) MergeRequestsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { + var ms []*MergeRequest + resp, err := s.searchByProject(pid, "merge_requests", query, &ms, opt, options...) + return ms, resp, err +} + +// Milestones searches the expression within milestones +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-milestones +func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { + var ms []*Milestone + resp, err := s.search("milestones", query, &ms, opt, options...) + return ms, resp, err +} + +// MilestonesByGroup searches the expression within milestones for +// the specified group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-milestones-1 +func (s *SearchService) MilestonesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { + var ms []*Milestone + resp, err := s.searchByGroup(gid, "milestones", query, &ms, opt, options...) + return ms, resp, err +} + +// MilestonesByProject searches the expression within milestones for +// the specified project +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-milestones-2 +func (s *SearchService) MilestonesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { + var ms []*Milestone + resp, err := s.searchByProject(pid, "milestones", query, &ms, opt, options...) + return ms, resp, err +} + +// SnippetTitles searches the expression within snippet titles +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-snippet_titles +func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { + var ss []*Snippet + resp, err := s.search("snippet_titles", query, &ss, opt, options...) + return ss, resp, err +} + +// NotesByProject searches the expression within notes for the specified +// project +// +// GitLab API docs: // https://docs.gitlab.com/api/search/#scope-notes +func (s *SearchService) NotesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { + var ns []*Note + resp, err := s.searchByProject(pid, "notes", query, &ns, opt, options...) + return ns, resp, err +} + +// WikiBlobs searches the expression within all wiki blobs +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-wiki_blobs +func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { + var ws []*Wiki + resp, err := s.search("wiki_blobs", query, &ws, opt, options...) + return ws, resp, err +} + +// WikiBlobsByGroup searches the expression within wiki blobs for +// specified group +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-wiki_blobs-1 +func (s *SearchService) WikiBlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { + var ws []*Wiki + resp, err := s.searchByGroup(gid, "wiki_blobs", query, &ws, opt, options...) + return ws, resp, err +} + +// WikiBlobsByProject searches the expression within wiki blobs for +// the specified project +// +// GitLab API docs: +// https://docs.gitlab.com/api/search/#scope-wiki_blobs-2 +func (s *SearchService) WikiBlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { + var ws []*Wiki + resp, err := s.searchByProject(pid, "wiki_blobs", query, &ws, opt, options...) + return ws, resp, err +} + +// Commits searches the expression within all commits +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-commits +func (s *SearchService) Commits(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { + var cs []*Commit + resp, err := s.search("commits", query, &cs, opt, options...) + return cs, resp, err +} + +// CommitsByGroup searches the expression within commits for the specified +// group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-commits-1 +func (s *SearchService) CommitsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { + var cs []*Commit + resp, err := s.searchByGroup(gid, "commits", query, &cs, opt, options...) + return cs, resp, err +} + +// CommitsByProject searches the expression within commits for the +// specified project +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-commits-2 +func (s *SearchService) CommitsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { + var cs []*Commit + resp, err := s.searchByProject(pid, "commits", query, &cs, opt, options...) + return cs, resp, err +} + +// Blob represents a single blob. +type Blob struct { + Basename string `json:"basename"` + Data string `json:"data"` + Path string `json:"path"` + Filename string `json:"filename"` + ID string `json:"id"` + Ref string `json:"ref"` + Startline int `json:"startline"` + ProjectID int `json:"project_id"` +} + +// Blobs searches the expression within all blobs +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-blobs +func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { + var bs []*Blob + resp, err := s.search("blobs", query, &bs, opt, options...) + return bs, resp, err +} + +// BlobsByGroup searches the expression within blobs for the specified +// group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-blobs-1 +func (s *SearchService) BlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { + var bs []*Blob + resp, err := s.searchByGroup(gid, "blobs", query, &bs, opt, options...) + return bs, resp, err +} + +// BlobsByProject searches the expression within blobs for the specified +// project +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-blobs-2 +func (s *SearchService) BlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { + var bs []*Blob + resp, err := s.searchByProject(pid, "blobs", query, &bs, opt, options...) + return bs, resp, err +} + +// Users searches the expression within all users +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-users +func (s *SearchService) Users(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + var ret []*User + resp, err := s.search("users", query, &ret, opt, options...) + return ret, resp, err +} + +// UsersByGroup searches the expression within users for the specified +// group +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-users-1 +func (s *SearchService) UsersByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + var ret []*User + resp, err := s.searchByGroup(gid, "users", query, &ret, opt, options...) + return ret, resp, err +} + +// UsersByProject searches the expression within users for the +// specified project +// +// GitLab API docs: https://docs.gitlab.com/api/search/#scope-users-2 +func (s *SearchService) UsersByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + var ret []*User + resp, err := s.searchByProject(pid, "users", query, &ret, opt, options...) + return ret, resp, err +} + +func (s *SearchService) search(scope, query string, result any, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { + opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} + + req, err := s.client.NewRequest(http.MethodGet, "search", opts, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, result) +} + +func (s *SearchService) searchByGroup(gid any, scope, query string, result any, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { + group, err := parseID(gid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("groups/%s/-/search", PathEscape(group)) + + opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, result) +} + +func (s *SearchService) searchByProject(pid any, scope, query string, result any, opt *SearchOptions, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/-/search", PathEscape(project)) + + opts := &searchOptions{SearchOptions: *opt, Scope: scope, Search: query} + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, result) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/secure_files.go b/vendor/gitlab.com/gitlab-org/api/client-go/secure_files.go new file mode 100644 index 000000000..761beff90 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/secure_files.go @@ -0,0 +1,233 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "io" + "net/http" + "time" +) + +type ( + SecureFilesServiceInterface interface { + ListProjectSecureFiles(pid any, opt *ListProjectSecureFilesOptions, options ...RequestOptionFunc) ([]*SecureFile, *Response, error) + ShowSecureFileDetails(pid any, id int, options ...RequestOptionFunc) (*SecureFile, *Response, error) + CreateSecureFile(pid any, content io.Reader, opt *CreateSecureFileOptions, options ...RequestOptionFunc) (*SecureFile, *Response, error) + DownloadSecureFile(pid any, id int, options ...RequestOptionFunc) (io.Reader, *Response, error) + RemoveSecureFile(pid any, id int, options ...RequestOptionFunc) (*Response, error) + } + + // SecureFilesService handles communication with the secure files related + // methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/secure_files/ + SecureFilesService struct { + client *Client + } +) + +var _ SecureFilesServiceInterface = (*SecureFilesService)(nil) + +// SecureFile represents a single secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/ +type SecureFile struct { + ID int `json:"id"` + Name string `json:"name"` + Checksum string `json:"checksum"` + ChecksumAlgorithm string `json:"checksum_algorithm"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *time.Time `json:"expires_at"` + Metadata *SecureFileMetadata `json:"metadata"` +} + +// SecureFileMetadata represents the metadata for a secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/ +type SecureFileMetadata struct { + ID string `json:"id"` + Issuer SecureFileIssuer `json:"issuer"` + Subject SecureFileSubject `json:"subject"` + ExpiresAt *time.Time `json:"expires_at"` +} + +// SecureFileIssuer represents the issuer of a secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/ +type SecureFileIssuer struct { + C string `json:"C"` + O string `json:"O"` + CN string `json:"CN"` + OU string `json:"OU"` +} + +// SecureFileSubject represents the subject of a secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/ +type SecureFileSubject struct { + C string `json:"C"` + O string `json:"O"` + CN string `json:"CN"` + OU string `json:"OU"` + UID string `json:"UID"` +} + +// Gets a string representation of a SecureFile. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/ +func (f SecureFile) String() string { + return Stringify(f) +} + +// ListProjectSecureFilesOptions represents the available +// ListProjectSecureFiles() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#list-project-secure-files +type ListProjectSecureFilesOptions ListOptions + +// ListProjectSecureFiles gets a list of secure files in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#list-project-secure-files +func (s SecureFilesService) ListProjectSecureFiles(pid any, opt *ListProjectSecureFilesOptions, options ...RequestOptionFunc) ([]*SecureFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/secure_files", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var files []*SecureFile + resp, err := s.client.Do(req, &files) + if err != nil { + return nil, resp, err + } + return files, resp, nil +} + +// ShowSecureFileDetails gets the details of a specific secure file in a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#show-secure-file-details +func (s SecureFilesService) ShowSecureFileDetails(pid any, id int, options ...RequestOptionFunc) (*SecureFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/secure_files/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + file := new(SecureFile) + resp, err := s.client.Do(req, file) + if err != nil { + return nil, resp, err + } + + return file, resp, nil +} + +// CreateSecureFileOptions represents the available +// CreateSecureFile() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#create-secure-file +type CreateSecureFileOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` +} + +// CreateSecureFile creates a new secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#create-secure-file +func (s SecureFilesService) CreateSecureFile(pid any, content io.Reader, opt *CreateSecureFileOptions, options ...RequestOptionFunc) (*SecureFile, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/secure_files", PathEscape(project)) + + req, err := s.client.UploadRequest(http.MethodPost, u, content, *opt.Name, UploadFile, opt, options) + if err != nil { + return nil, nil, err + } + + file := new(SecureFile) + resp, err := s.client.Do(req, file) + if err != nil { + return nil, resp, err + } + + return file, resp, nil +} + +// DownloadSecureFile downloads the contents of a project's secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#download-secure-file +func (s SecureFilesService) DownloadSecureFile(pid any, id int, options ...RequestOptionFunc) (io.Reader, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/secure_files/%d/download", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var file bytes.Buffer + resp, err := s.client.Do(req, &file) + if err != nil { + return nil, resp, err + } + + return &file, resp, err +} + +// RemoveSecureFile removes a project's secure file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/secure_files/#remove-secure-file +func (s SecureFilesService) RemoveSecureFile(pid any, id int, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/secure_files/%d", PathEscape(project), id) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/services.go b/vendor/gitlab.com/gitlab-org/api/client-go/services.go new file mode 100644 index 000000000..7ce79c4ea --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/services.go @@ -0,0 +1,2387 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "time" +) + +type ( + ServicesServiceInterface interface { + ListServices(pid any, options ...RequestOptionFunc) ([]*Service, *Response, error) + GetCustomIssueTrackerService(pid any, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) + SetCustomIssueTrackerService(pid any, opt *SetCustomIssueTrackerServiceOptions, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) + DeleteCustomIssueTrackerService(pid any, options ...RequestOptionFunc) (*Response, error) + GetDataDogService(pid any, options ...RequestOptionFunc) (*DataDogService, *Response, error) + SetDataDogService(pid any, opt *SetDataDogServiceOptions, options ...RequestOptionFunc) (*DataDogService, *Response, error) + DeleteDataDogService(pid any, options ...RequestOptionFunc) (*Response, error) + GetDiscordService(pid any, options ...RequestOptionFunc) (*DiscordService, *Response, error) + SetDiscordService(pid any, opt *SetDiscordServiceOptions, options ...RequestOptionFunc) (*DiscordService, *Response, error) + DeleteDiscordService(pid any, options ...RequestOptionFunc) (*Response, error) + GetDroneCIService(pid any, options ...RequestOptionFunc) (*DroneCIService, *Response, error) + SetDroneCIService(pid any, opt *SetDroneCIServiceOptions, options ...RequestOptionFunc) (*DroneCIService, *Response, error) + DeleteDroneCIService(pid any, options ...RequestOptionFunc) (*Response, error) + GetEmailsOnPushService(pid any, options ...RequestOptionFunc) (*EmailsOnPushService, *Response, error) + SetEmailsOnPushService(pid any, opt *SetEmailsOnPushServiceOptions, options ...RequestOptionFunc) (*EmailsOnPushService, *Response, error) + DeleteEmailsOnPushService(pid any, options ...RequestOptionFunc) (*Response, error) + GetExternalWikiService(pid any, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) + SetExternalWikiService(pid any, opt *SetExternalWikiServiceOptions, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) + DeleteExternalWikiService(pid any, options ...RequestOptionFunc) (*Response, error) + GetGithubService(pid any, options ...RequestOptionFunc) (*GithubService, *Response, error) + SetGithubService(pid any, opt *SetGithubServiceOptions, options ...RequestOptionFunc) (*GithubService, *Response, error) + DeleteGithubService(pid any, options ...RequestOptionFunc) (*Response, error) + GetHarborService(pid any, options ...RequestOptionFunc) (*HarborService, *Response, error) + SetHarborService(pid any, opt *SetHarborServiceOptions, options ...RequestOptionFunc) (*HarborService, *Response, error) + DeleteHarborService(pid any, options ...RequestOptionFunc) (*Response, error) + GetSlackApplication(pid any, options ...RequestOptionFunc) (*SlackApplication, *Response, error) + SetSlackApplication(pid any, opt *SetSlackApplicationOptions, options ...RequestOptionFunc) (*SlackApplication, *Response, error) + DisableSlackApplication(pid any, options ...RequestOptionFunc) (*Response, error) + GetJenkinsCIService(pid any, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) + SetJenkinsCIService(pid any, opt *SetJenkinsCIServiceOptions, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) + DeleteJenkinsCIService(pid any, options ...RequestOptionFunc) (*Response, error) + GetJiraService(pid any, options ...RequestOptionFunc) (*JiraService, *Response, error) + SetJiraService(pid any, opt *SetJiraServiceOptions, options ...RequestOptionFunc) (*JiraService, *Response, error) + DeleteJiraService(pid any, options ...RequestOptionFunc) (*Response, error) + GetMattermostService(pid any, options ...RequestOptionFunc) (*MattermostService, *Response, error) + SetMattermostService(pid any, opt *SetMattermostServiceOptions, options ...RequestOptionFunc) (*MattermostService, *Response, error) + DeleteMattermostService(pid any, options ...RequestOptionFunc) (*Response, error) + GetMattermostSlashCommandsService(pid any, options ...RequestOptionFunc) (*MattermostSlashCommandsService, *Response, error) + SetMattermostSlashCommandsService(pid any, opt *SetMattermostSlashCommandsServiceOptions, options ...RequestOptionFunc) (*MattermostSlashCommandsService, *Response, error) + DeleteMattermostSlashCommandsService(pid any, options ...RequestOptionFunc) (*Response, error) + GetMicrosoftTeamsService(pid any, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) + SetMicrosoftTeamsService(pid any, opt *SetMicrosoftTeamsServiceOptions, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) + DeleteMicrosoftTeamsService(pid any, options ...RequestOptionFunc) (*Response, error) + GetPipelinesEmailService(pid any, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) + SetPipelinesEmailService(pid any, opt *SetPipelinesEmailServiceOptions, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) + DeletePipelinesEmailService(pid any, options ...RequestOptionFunc) (*Response, error) + GetRedmineService(pid any, options ...RequestOptionFunc) (*RedmineService, *Response, error) + SetRedmineService(pid any, opt *SetRedmineServiceOptions, options ...RequestOptionFunc) (*RedmineService, *Response, error) + DeleteRedmineService(pid any, options ...RequestOptionFunc) (*Response, error) + GetSlackService(pid any, options ...RequestOptionFunc) (*SlackService, *Response, error) + SetSlackService(pid any, opt *SetSlackServiceOptions, options ...RequestOptionFunc) (*SlackService, *Response, error) + DeleteSlackService(pid any, options ...RequestOptionFunc) (*Response, error) + GetSlackSlashCommandsService(pid any, options ...RequestOptionFunc) (*SlackSlashCommandsService, *Response, error) + SetSlackSlashCommandsService(pid any, opt *SetSlackSlashCommandsServiceOptions, options ...RequestOptionFunc) (*SlackSlashCommandsService, *Response, error) + DeleteSlackSlashCommandsService(pid any, options ...RequestOptionFunc) (*Response, error) + GetTelegramService(pid any, options ...RequestOptionFunc) (*TelegramService, *Response, error) + SetTelegramService(pid any, opt *SetTelegramServiceOptions, options ...RequestOptionFunc) (*TelegramService, *Response, error) + DeleteTelegramService(pid any, options ...RequestOptionFunc) (*Response, error) + GetYouTrackService(pid any, options ...RequestOptionFunc) (*YouTrackService, *Response, error) + SetYouTrackService(pid any, opt *SetYouTrackServiceOptions, options ...RequestOptionFunc) (*YouTrackService, *Response, error) + DeleteYouTrackService(pid any, options ...RequestOptionFunc) (*Response, error) + } + + // ServicesService handles communication with the services related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/project_integrations/ + ServicesService struct { + client *Client + } +) + +var _ ServicesServiceInterface = (*ServicesService)(nil) + +// Service represents a GitLab service. +// +// GitLab API docs: https://docs.gitlab.com/api/project_integrations/ +type Service struct { + ID int `json:"id"` + Title string `json:"title"` + Slug string `json:"slug"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Active bool `json:"active"` + AlertEvents bool `json:"alert_events"` + CommitEvents bool `json:"commit_events"` + ConfidentialIssuesEvents bool `json:"confidential_issues_events"` + ConfidentialNoteEvents bool `json:"confidential_note_events"` + DeploymentEvents bool `json:"deployment_events"` + GroupConfidentialMentionEvents bool `json:"group_confidential_mention_events"` + GroupMentionEvents bool `json:"group_mention_events"` + IncidentEvents bool `json:"incident_events"` + IssuesEvents bool `json:"issues_events"` + JobEvents bool `json:"job_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + NoteEvents bool `json:"note_events"` + PipelineEvents bool `json:"pipeline_events"` + PushEvents bool `json:"push_events"` + TagPushEvents bool `json:"tag_push_events"` + VulnerabilityEvents bool `json:"vulnerability_events"` + WikiPageEvents bool `json:"wiki_page_events"` + CommentOnEventEnabled bool `json:"comment_on_event_enabled"` + Inherited bool `json:"inherited"` +} + +// ListServices gets a list of all active services. +// +// GitLab API docs: https://docs.gitlab.com/api/project_integrations/#list-all-active-integrations +func (s *ServicesService) ListServices(pid any, options ...RequestOptionFunc) ([]*Service, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var svcs []*Service + resp, err := s.client.Do(req, &svcs) + if err != nil { + return nil, resp, err + } + + return svcs, resp, nil +} + +// CustomIssueTrackerService represents Custom Issue Tracker service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#custom-issue-tracker +type CustomIssueTrackerService struct { + Service + Properties *CustomIssueTrackerServiceProperties `json:"properties"` +} + +// CustomIssueTrackerServiceProperties represents Custom Issue Tracker specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#custom-issue-tracker +type CustomIssueTrackerServiceProperties struct { + ProjectURL string `json:"project_url,omitempty"` + IssuesURL string `json:"issues_url,omitempty"` + NewIssueURL string `json:"new_issue_url,omitempty"` +} + +// GetCustomIssueTrackerService gets Custom Issue Tracker service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-custom-issue-tracker-settings +func (s *ServicesService) GetCustomIssueTrackerService(pid any, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(CustomIssueTrackerService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetCustomIssueTrackerServiceOptions represents the available SetCustomIssueTrackerService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-a-custom-issue-tracker +type SetCustomIssueTrackerServiceOptions struct { + NewIssueURL *string `url:"new_issue_url,omitempty" json:"new_issue_url,omitempty"` + IssuesURL *string `url:"issues_url,omitempty" json:"issues_url,omitempty"` + ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` +} + +// SetCustomIssueTrackerService sets Custom Issue Tracker service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-a-custom-issue-tracker +func (s *ServicesService) SetCustomIssueTrackerService(pid any, opt *SetCustomIssueTrackerServiceOptions, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(CustomIssueTrackerService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteCustomIssueTrackerService deletes Custom Issue Tracker service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-a-custom-issue-tracker +func (s *ServicesService) DeleteCustomIssueTrackerService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DataDogService represents DataDog service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#datadog +type DataDogService struct { + Service + Properties *DataDogServiceProperties `json:"properties"` +} + +// DataDogServiceProperties represents DataDog specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#datadog +type DataDogServiceProperties struct { + APIURL string `url:"api_url,omitempty" json:"api_url,omitempty"` + DataDogEnv string `url:"datadog_env,omitempty" json:"datadog_env,omitempty"` + DataDogService string `url:"datadog_service,omitempty" json:"datadog_service,omitempty"` + DataDogSite string `url:"datadog_site,omitempty" json:"datadog_site,omitempty"` + DataDogTags string `url:"datadog_tags,omitempty" json:"datadog_tags,omitempty"` + ArchiveTraceEvents bool `url:"archive_trace_events,omitempty" json:"archive_trace_events,omitempty"` +} + +// GetDataDogService gets DataDog service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-datadog-settings +func (s *ServicesService) GetDataDogService(pid any, options ...RequestOptionFunc) (*DataDogService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/datadog", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(DataDogService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetDataDogServiceOptions represents the available SetDataDogService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-datadog +type SetDataDogServiceOptions struct { + APIKey *string `url:"api_key,omitempty" json:"api_key,omitempty"` + APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` + DataDogEnv *string `url:"datadog_env,omitempty" json:"datadog_env,omitempty"` + DataDogService *string `url:"datadog_service,omitempty" json:"datadog_service,omitempty"` + DataDogSite *string `url:"datadog_site,omitempty" json:"datadog_site,omitempty"` + DataDogTags *string `url:"datadog_tags,omitempty" json:"datadog_tags,omitempty"` + ArchiveTraceEvents *bool `url:"archive_trace_events,omitempty" json:"archive_trace_events,omitempty"` +} + +// SetDataDogService sets DataDog service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-datadog +func (s *ServicesService) SetDataDogService(pid any, opt *SetDataDogServiceOptions, options ...RequestOptionFunc) (*DataDogService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/datadog", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(DataDogService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteDataDogService deletes the DataDog service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-datadog +func (s *ServicesService) DeleteDataDogService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/datadog", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DiscordService represents Discord service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#discord-notifications +type DiscordService struct { + Service + Properties *DiscordServiceProperties `json:"properties"` +} + +// DiscordServiceProperties represents Discord specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#discord-notifications +type DiscordServiceProperties struct { + BranchesToBeNotified string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + NotifyOnlyBrokenPipelines bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` +} + +// GetDiscordService gets Discord service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-discord-notifications-settings +func (s *ServicesService) GetDiscordService(pid any, options ...RequestOptionFunc) (*DiscordService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/discord", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(DiscordService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetDiscordServiceOptions represents the available SetDiscordService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-discord-notifications +type SetDiscordServiceOptions struct { + WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + ConfidentialIssuesChannel *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + ConfidentialNoteChannel *string `url:"confidential_note_channel,omitempty" json:"confidential_note_channel,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + DeploymentChannel *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"` + GroupConfidentialMentionsEvents *bool `url:"group_confidential_mentions_events,omitempty" json:"group_confidential_mentions_events,omitempty"` + GroupConfidentialMentionsChannel *string `url:"group_confidential_mentions_channel,omitempty" json:"group_confidential_mentions_channel,omitempty"` + GroupMentionsEvents *bool `url:"group_mentions_events,omitempty" json:"group_mentions_events,omitempty"` + GroupMentionsChannel *string `url:"group_mentions_channel,omitempty" json:"group_mentions_channel,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + IssueChannel *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + MergeRequestChannel *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + NoteChannel *string `url:"note_channel,omitempty" json:"note_channel,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + PushChannel *string `url:"push_channel,omitempty" json:"push_channel,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + TagPushChannel *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"` +} + +// SetDiscordService sets Discord service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-discord-notifications +func (s *ServicesService) SetDiscordService(pid any, opt *SetDiscordServiceOptions, options ...RequestOptionFunc) (*DiscordService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/discord", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(DiscordService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// DeleteDiscordService deletes Discord service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-discord-notifications +func (s *ServicesService) DeleteDiscordService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/discord", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DroneCIService represents Drone CI service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#drone +type DroneCIService struct { + Service + Properties *DroneCIServiceProperties `json:"properties"` +} + +// DroneCIServiceProperties represents Drone CI specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#drone +type DroneCIServiceProperties struct { + DroneURL string `json:"drone_url"` + EnableSSLVerification bool `json:"enable_ssl_verification"` +} + +// GetDroneCIService gets Drone CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-drone-settings +func (s *ServicesService) GetDroneCIService(pid any, options ...RequestOptionFunc) (*DroneCIService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(DroneCIService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetDroneCIServiceOptions represents the available SetDroneCIService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-drone +type SetDroneCIServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` + DroneURL *string `url:"drone_url,omitempty" json:"drone_url,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` +} + +// SetDroneCIService sets Drone CI service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-drone +func (s *ServicesService) SetDroneCIService(pid any, opt *SetDroneCIServiceOptions, options ...RequestOptionFunc) (*DroneCIService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(DroneCIService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteDroneCIService deletes Drone CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-drone +func (s *ServicesService) DeleteDroneCIService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// EmailsOnPushService represents Emails on Push service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#emails-on-push +type EmailsOnPushService struct { + Service + Properties *EmailsOnPushServiceProperties `json:"properties"` +} + +// EmailsOnPushServiceProperties represents Emails on Push specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#emails-on-push +type EmailsOnPushServiceProperties struct { + Recipients string `json:"recipients"` + DisableDiffs bool `json:"disable_diffs"` + SendFromCommitterEmail bool `json:"send_from_committer_email"` + PushEvents bool `json:"push_events"` + TagPushEvents bool `json:"tag_push_events"` + BranchesToBeNotified string `json:"branches_to_be_notified"` +} + +// GetEmailsOnPushService gets Emails on Push service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-emails-on-push-settings +func (s *ServicesService) GetEmailsOnPushService(pid any, options ...RequestOptionFunc) (*EmailsOnPushService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/emails-on-push", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(EmailsOnPushService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetEmailsOnPushServiceOptions represents the available SetEmailsOnPushService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-emails-on-push +type SetEmailsOnPushServiceOptions struct { + Recipients *string `url:"recipients,omitempty" json:"recipients,omitempty"` + DisableDiffs *bool `url:"disable_diffs,omitempty" json:"disable_diffs,omitempty"` + SendFromCommitterEmail *bool `url:"send_from_committer_email,omitempty" json:"send_from_committer_email,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` +} + +// SetEmailsOnPushService sets Emails on Push service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-emails-on-push +func (s *ServicesService) SetEmailsOnPushService(pid any, opt *SetEmailsOnPushServiceOptions, options ...RequestOptionFunc) (*EmailsOnPushService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/emails-on-push", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(EmailsOnPushService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteEmailsOnPushService deletes Emails on Push service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-emails-on-push +func (s *ServicesService) DeleteEmailsOnPushService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/integrations/emails-on-push", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ExternalWikiService represents External Wiki service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#external-wiki +type ExternalWikiService struct { + Service + Properties *ExternalWikiServiceProperties `json:"properties"` +} + +// ExternalWikiServiceProperties represents External Wiki specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#external-wiki +type ExternalWikiServiceProperties struct { + ExternalWikiURL string `json:"external_wiki_url"` +} + +// GetExternalWikiService gets External Wiki service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-external-wiki-settings +func (s *ServicesService) GetExternalWikiService(pid any, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(ExternalWikiService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetExternalWikiServiceOptions represents the available SetExternalWikiService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-an-external-wiki +type SetExternalWikiServiceOptions struct { + ExternalWikiURL *string `url:"external_wiki_url,omitempty" json:"external_wiki_url,omitempty"` +} + +// SetExternalWikiService sets External Wiki service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-an-external-wiki +func (s *ServicesService) SetExternalWikiService(pid any, opt *SetExternalWikiServiceOptions, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(ExternalWikiService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteExternalWikiService deletes External Wiki service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-an-external-wiki +func (s *ServicesService) DeleteExternalWikiService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GithubService represents Github service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#github +type GithubService struct { + Service + Properties *GithubServiceProperties `json:"properties"` +} + +// GithubServiceProperties represents Github specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#github +type GithubServiceProperties struct { + RepositoryURL string `json:"repository_url"` + StaticContext bool `json:"static_context"` +} + +// GetGithubService gets Github service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-github-settings +func (s *ServicesService) GetGithubService(pid any, options ...RequestOptionFunc) (*GithubService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/github", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(GithubService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetGithubServiceOptions represents the available SetGithubService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-github +type SetGithubServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` + RepositoryURL *string `url:"repository_url,omitempty" json:"repository_url,omitempty"` + StaticContext *bool `url:"static_context,omitempty" json:"static_context,omitempty"` +} + +// SetGithubService sets Github service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-github +func (s *ServicesService) SetGithubService(pid any, opt *SetGithubServiceOptions, options ...RequestOptionFunc) (*GithubService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/github", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(GithubService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteGithubService deletes Github service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-github +func (s *ServicesService) DeleteGithubService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/github", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// HarborService represents the Harbor service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#harbor +type HarborService struct { + Service + Properties *HarborServiceProperties `json:"properties"` +} + +// HarborServiceProperties represents Harbor specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#harbor +type HarborServiceProperties struct { + URL string `json:"url"` + ProjectName string `json:"project_name"` + Username string `json:"username"` + Password string `json:"password"` + UseInheritedSettings bool `json:"use_inherited_settings"` +} + +// GetHarborService gets Harbor service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-harbor-settings +func (s *ServicesService) GetHarborService(pid any, options ...RequestOptionFunc) (*HarborService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/harbor", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(HarborService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetHarborServiceOptions represents the available SetHarborService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-harbor +type SetHarborServiceOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + UseInheritedSettings *bool `url:"use_inherited_settings,omitempty" json:"use_inherited_settings,omitempty"` +} + +// SetHarborService sets Harbor service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-harbor +func (s *ServicesService) SetHarborService(pid any, opt *SetHarborServiceOptions, options ...RequestOptionFunc) (*HarborService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/harbor", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(HarborService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteHarborService deletes Harbor service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-harbor +func (s *ServicesService) DeleteHarborService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/integrations/harbor", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SlackApplication represents GitLab for slack application settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#gitlab-for-slack-app +type SlackApplication struct { + Service + Properties *SlackApplicationProperties `json:"properties"` +} + +// SlackApplicationProperties represents GitLab for slack application specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#gitlab-for-slack-app +type SlackApplicationProperties struct { + Channel string `json:"channel"` + NotifyOnlyBrokenPipelines bool `json:"notify_only_broken_pipelines"` + BranchesToBeNotified string `json:"branches_to_be_notified"` + LabelsToBeNotified string `json:"labels_to_be_notified"` + LabelsToBeNotifiedBehavior string `json:"labels_to_be_notified_behavior"` + PushChannel string `json:"push_channel"` + IssueChannel string `json:"issue_channel"` + ConfidentialIssueChannel string `json:"confidential_issue_channel"` + MergeRequestChannel string `json:"merge_request_channel"` + NoteChannel string `json:"note_channel"` + ConfidentialNoteChannel string `json:"confidential_note_channel"` + TagPushChannel string `json:"tag_push_channel"` + PipelineChannel string `json:"pipeline_channel"` + WikiPageChannel string `json:"wiki_page_channel"` + DeploymentChannel string `json:"deployment_channel"` + IncidentChannel string `json:"incident_channel"` + VulnerabilityChannel string `json:"vulnerability_channel"` + AlertChannel string `json:"alert_channel"` + + // Deprecated: This parameter has been replaced with BranchesToBeNotified. + NotifyOnlyDefaultBranch bool `json:"notify_only_default_branch"` +} + +// GetSlackApplication gets the GitLab for Slack app integration settings for a +// project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-gitlab-for-slack-app-settings +func (s *ServicesService) GetSlackApplication(pid any, options ...RequestOptionFunc) (*SlackApplication, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/gitlab-slack-application", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackApplication) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetSlackApplicationOptions represents the available SetSlackApplication() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-gitlab-for-slack-app +type SetSlackApplicationOptions struct { + Channel *string `url:"channel,omitempty" json:"channel,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + AlertEvents *bool `url:"alert_events,omitempty" json:"alert_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + IncidentsEvents *bool `url:"incidents_events,omitempty" json:"incidents_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + VulnerabilityEvents *bool `url:"vulnerability_events,omitempty" json:"vulnerability_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + LabelsToBeNotified *string `url:"labels_to_be_notified,omitempty" json:"labels_to_be_notified,omitempty"` + LabelsToBeNotifiedBehavior *string `url:"labels_to_be_notified_behavior,omitempty" json:"labels_to_be_notified_behavior,omitempty"` + PushChannel *string `url:"push_channel,omitempty" json:"push_channel,omitempty"` + IssueChannel *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"` + ConfidentialIssueChannel *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"` + MergeRequestChannel *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"` + NoteChannel *string `url:"note_channel,omitempty" json:"note_channel,omitempty"` + ConfidentialNoteChannel *string `url:"confidential_note_channel,omitempty" json:"confidential_note_channel,omitempty"` + TagPushChannel *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"` + PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"` + WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"` + DeploymentChannel *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"` + IncidentChannel *string `url:"incident_channel,omitempty" json:"incident_channel,omitempty"` + VulnerabilityChannel *string `url:"vulnerability_channel,omitempty" json:"vulnerability_channel,omitempty"` + AlertChannel *string `url:"alert_channel,omitempty" json:"alert_channel,omitempty"` + UseInheritedSettings *bool `url:"use_inherited_settings,omitempty" json:"use_inherited_settings,omitempty"` + + // Deprecated: This parameter has been replaced with BranchesToBeNotified. + NotifyOnlyDefaultBranch *bool `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"` +} + +// SetSlackApplication update the GitLab for Slack app integration for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-gitlab-for-slack-app +func (s *ServicesService) SetSlackApplication(pid any, opt *SetSlackApplicationOptions, options ...RequestOptionFunc) (*SlackApplication, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/gitlab-slack-application", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackApplication) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DisableSlackApplication disable the GitLab for Slack app integration for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-gitlab-for-slack-app +func (s *ServicesService) DisableSlackApplication(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/integrations/gitlab-slack-application", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// JenkinsCIService represents Jenkins CI service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#jenkins +type JenkinsCIService struct { + Service + Properties *JenkinsCIServiceProperties `json:"properties"` +} + +// JenkinsCIServiceProperties represents Jenkins CI specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#jenkins +type JenkinsCIServiceProperties struct { + URL string `json:"jenkins_url"` + EnableSSLVerification bool `json:"enable_ssl_verification"` + ProjectName string `json:"project_name"` + Username string `json:"username"` +} + +// GetJenkinsCIService gets Jenkins CI service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-jenkins-settings +func (s *ServicesService) GetJenkinsCIService(pid any, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(JenkinsCIService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetJenkinsCIServiceOptions represents the available SetJenkinsCIService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#jenkins +type SetJenkinsCIServiceOptions struct { + URL *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"` + EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` + ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` +} + +// SetJenkinsCIService sets Jenkins service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-jenkins +func (s *ServicesService) SetJenkinsCIService(pid any, opt *SetJenkinsCIServiceOptions, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(JenkinsCIService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteJenkinsCIService deletes Jenkins CI service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-jenkins +func (s *ServicesService) DeleteJenkinsCIService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// JiraService represents Jira service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#jira-issues +type JiraService struct { + Service + Properties *JiraServiceProperties `json:"properties"` +} + +// JiraServiceProperties represents Jira specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#jira-issues +type JiraServiceProperties struct { + URL string `json:"url"` + APIURL string `json:"api_url"` + Username string `json:"username" ` + Password string `json:"password" ` + Active bool `json:"active"` + JiraAuthType int `json:"jira_auth_type"` + JiraIssuePrefix string `json:"jira_issue_prefix"` + JiraIssueRegex string `json:"jira_issue_regex"` + JiraIssueTransitionAutomatic bool `json:"jira_issue_transition_automatic"` + JiraIssueTransitionID string `json:"jira_issue_transition_id"` + CommitEvents bool `json:"commit_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + CommentOnEventEnabled bool `json:"comment_on_event_enabled"` + IssuesEnabled bool `json:"issues_enabled"` + ProjectKeys []string `json:"project_keys" ` + UseInheritedSettings bool `json:"use_inherited_settings"` +} + +// UnmarshalJSON decodes the Jira Service Properties. +// +// This allows support of JiraIssueTransitionID for both type string (>11.9) and float64 (<11.9) +func (p *JiraServiceProperties) UnmarshalJSON(b []byte) error { + type Alias JiraServiceProperties + raw := struct { + *Alias + JiraIssueTransitionID any `json:"jira_issue_transition_id"` + }{ + Alias: (*Alias)(p), + } + + if err := json.Unmarshal(b, &raw); err != nil { + return err + } + + switch id := raw.JiraIssueTransitionID.(type) { + case nil: + // No action needed. + case string: + p.JiraIssueTransitionID = id + case float64: + p.JiraIssueTransitionID = strconv.Itoa(int(id)) + default: + return fmt.Errorf("failed to unmarshal JiraTransitionID of type: %T", id) + } + + return nil +} + +// GetJiraService gets Jira service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-jira-settings +func (s *ServicesService) GetJiraService(pid any, options ...RequestOptionFunc) (*JiraService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/jira", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(JiraService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetJiraServiceOptions represents the available SetJiraService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-jira-issues +type SetJiraServiceOptions struct { + URL *string `url:"url,omitempty" json:"url,omitempty"` + APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty" ` + Password *string `url:"password,omitempty" json:"password,omitempty" ` + Active *bool `url:"active,omitempty" json:"active,omitempty"` + JiraAuthType *int `url:"jira_auth_type,omitempty" json:"jira_auth_type,omitempty"` + JiraIssuePrefix *string `url:"jira_issue_prefix,omitempty" json:"jira_issue_prefix,omitempty"` + JiraIssueRegex *string `url:"jira_issue_regex,omitempty" json:"jira_issue_regex,omitempty"` + JiraIssueTransitionAutomatic *bool `url:"jira_issue_transition_automatic,omitempty" json:"jira_issue_transition_automatic,omitempty"` + JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"` + CommitEvents *bool `url:"commit_events,omitempty" json:"commit_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + CommentOnEventEnabled *bool `url:"comment_on_event_enabled,omitempty" json:"comment_on_event_enabled,omitempty"` + IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"` + ProjectKeys *[]string `url:"project_keys,comma,omitempty" json:"project_keys,omitempty" ` + UseInheritedSettings *bool `url:"use_inherited_settings,omitempty" json:"use_inherited_settings,omitempty"` +} + +// SetJiraService sets Jira service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-jira-issues +func (s *ServicesService) SetJiraService(pid any, opt *SetJiraServiceOptions, options ...RequestOptionFunc) (*JiraService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/jira", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(JiraService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteJiraService deletes Jira service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-jira +func (s *ServicesService) DeleteJiraService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/integrations/jira", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// MattermostService represents Mattermost service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#mattermost-notifications +type MattermostService struct { + Service + Properties *MattermostServiceProperties `json:"properties"` +} + +// MattermostServiceProperties represents Mattermost specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#mattermost-notifications +type MattermostServiceProperties struct { + WebHook string `json:"webhook"` + Username string `json:"username"` + Channel string `json:"channel"` + NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"` + BranchesToBeNotified string `json:"branches_to_be_notified"` + ConfidentialIssueChannel string `json:"confidential_issue_channel"` + ConfidentialNoteChannel string `json:"confidential_note_channel"` + IssueChannel string `json:"issue_channel"` + MergeRequestChannel string `json:"merge_request_channel"` + NoteChannel string `json:"note_channel"` + TagPushChannel string `json:"tag_push_channel"` + PipelineChannel string `json:"pipeline_channel"` + PushChannel string `json:"push_channel"` + VulnerabilityChannel string `json:"vulnerability_channel"` + WikiPageChannel string `json:"wiki_page_channel"` +} + +// GetMattermostService gets Mattermost service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-mattermost-notifications-settings +func (s *ServicesService) GetMattermostService(pid any, options ...RequestOptionFunc) (*MattermostService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(MattermostService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetMattermostServiceOptions represents the available SetMattermostService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-mattermost-notifications +type SetMattermostServiceOptions struct { + WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Channel *string `url:"channel,omitempty" json:"channel,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteChannel *string `url:"confidential_note_channel,omitempty" json:"confidential_note_channel,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` + PushChannel *string `url:"push_channel,omitempty" json:"push_channel,omitempty"` + IssueChannel *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"` + ConfidentialIssueChannel *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"` + MergeRequestChannel *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"` + NoteChannel *string `url:"note_channel,omitempty" json:"note_channel,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + TagPushChannel *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"` + PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"` + WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"` +} + +// SetMattermostService sets Mattermost service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-mattermost-notifications +func (s *ServicesService) SetMattermostService(pid any, opt *SetMattermostServiceOptions, options ...RequestOptionFunc) (*MattermostService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(MattermostService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteMattermostService deletes Mattermost service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-mattermost-notifications +func (s *ServicesService) DeleteMattermostService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// MattermostSlashCommandsService represents Mattermost slash commands settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#mattermost-slash-commands +type MattermostSlashCommandsService struct { + Service + Properties *MattermostSlashCommandsProperties `json:"properties"` +} + +// MattermostSlashCommandsProperties represents Mattermost slash commands specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#mattermost-slash-commands +type MattermostSlashCommandsProperties struct { + Token string `json:"token"` + Username string `json:"username,omitempty"` +} + +// GetMattermostSlashCommandsService gets Slack Mattermost commands service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-mattermost-slash-commands-settings +func (s *ServicesService) GetMattermostSlashCommandsService(pid any, options ...RequestOptionFunc) (*MattermostSlashCommandsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(MattermostSlashCommandsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetMattermostSlashCommandsServiceOptions represents the available SetSlackSlashCommandsService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-mattermost-slash-commands +type SetMattermostSlashCommandsServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` +} + +// SetMattermostSlashCommandsService sets Mattermost slash commands service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-mattermost-slash-commands +func (s *ServicesService) SetMattermostSlashCommandsService(pid any, opt *SetMattermostSlashCommandsServiceOptions, options ...RequestOptionFunc) (*MattermostSlashCommandsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(MattermostSlashCommandsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteMattermostSlashCommandsService deletes Mattermost slash commands service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-mattermost-slash-commands +func (s *ServicesService) DeleteMattermostSlashCommandsService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/mattermost-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// MicrosoftTeamsService represents Microsoft Teams service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#microsoft-teams-notifications +type MicrosoftTeamsService struct { + Service + Properties *MicrosoftTeamsServiceProperties `json:"properties"` +} + +// MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#microsoft-teams-notifications +type MicrosoftTeamsServiceProperties struct { + WebHook string `json:"webhook"` + NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"` + BranchesToBeNotified string `json:"branches_to_be_notified"` + IssuesEvents BoolValue `json:"issues_events"` + ConfidentialIssuesEvents BoolValue `json:"confidential_issues_events"` + MergeRequestsEvents BoolValue `json:"merge_requests_events"` + TagPushEvents BoolValue `json:"tag_push_events"` + NoteEvents BoolValue `json:"note_events"` + ConfidentialNoteEvents BoolValue `json:"confidential_note_events"` + PipelineEvents BoolValue `json:"pipeline_events"` + WikiPageEvents BoolValue `json:"wiki_page_events"` +} + +// GetMicrosoftTeamsService gets MicrosoftTeams service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-microsoft-teams-notifications-settings +func (s *ServicesService) GetMicrosoftTeamsService(pid any, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(MicrosoftTeamsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetMicrosoftTeamsServiceOptions represents the available SetMicrosoftTeamsService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-microsoft-teams-notifications +type SetMicrosoftTeamsServiceOptions struct { + WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` +} + +// SetMicrosoftTeamsService sets Microsoft Teams service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-microsoft-teams-notifications +func (s *ServicesService) SetMicrosoftTeamsService(pid any, opt *SetMicrosoftTeamsServiceOptions, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(MicrosoftTeamsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteMicrosoftTeamsService deletes Microsoft Teams service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-microsoft-teams-notifications +func (s *ServicesService) DeleteMicrosoftTeamsService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// PipelinesEmailService represents Pipelines Email service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#pipeline-status-emails +type PipelinesEmailService struct { + Service + Properties *PipelinesEmailProperties `json:"properties"` +} + +// PipelinesEmailProperties represents PipelinesEmail specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#pipeline-status-emails +type PipelinesEmailProperties struct { + Recipients string `json:"recipients"` + NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"` + NotifyOnlyDefaultBranch BoolValue `json:"notify_only_default_branch"` + BranchesToBeNotified string `json:"branches_to_be_notified"` +} + +// GetPipelinesEmailService gets Pipelines Email service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-pipeline-status-emails-settings +func (s *ServicesService) GetPipelinesEmailService(pid any, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(PipelinesEmailService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetPipelinesEmailServiceOptions represents the available +// SetPipelinesEmailService() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-pipeline-status-emails +type SetPipelinesEmailServiceOptions struct { + Recipients *string `url:"recipients,omitempty" json:"recipients,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + NotifyOnlyDefaultBranch *bool `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"` + AddPusher *bool `url:"add_pusher,omitempty" json:"add_pusher,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` +} + +// SetPipelinesEmailService sets Pipelines Email service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-pipeline-status-emails +func (s *ServicesService) SetPipelinesEmailService(pid any, opt *SetPipelinesEmailServiceOptions, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(PipelinesEmailService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeletePipelinesEmailService deletes Pipelines Email service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-pipeline-status-emails +func (s *ServicesService) DeletePipelinesEmailService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// RedmineService represents the Redmine service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#redmine +type RedmineService struct { + Service + Properties *RedmineServiceProperties `json:"properties"` +} + +// RedmineServiceProperties represents Redmine specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#redmine +type RedmineServiceProperties struct { + NewIssueURL string `json:"new_issue_url"` + ProjectURL string `json:"project_url"` + IssuesURL string `json:"issues_url"` + UseInheritedSettings BoolValue `json:"use_inherited_settings"` +} + +// GetRedmineService gets Redmine service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-redmine-settings +func (s *ServicesService) GetRedmineService(pid any, options ...RequestOptionFunc) (*RedmineService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(RedmineService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetRedmineServiceOptions represents the available SetRedmineService(). +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-redmine +type SetRedmineServiceOptions struct { + NewIssueURL *string `url:"new_issue_url,omitempty" json:"new_issue_url,omitempty"` + ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` + IssuesURL *string `url:"issues_url,omitempty" json:"issues_url,omitempty"` + UseInheritedSettings *bool `url:"use_inherited_settings,omitempty" json:"use_inherited_settings,omitempty"` +} + +// SetRedmineService sets Redmine service for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-redmine +func (s *ServicesService) SetRedmineService(pid any, opt *SetRedmineServiceOptions, options ...RequestOptionFunc) (*RedmineService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(RedmineService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteRedmineService deletes Redmine service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-redmine +func (s *ServicesService) DeleteRedmineService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SlackService represents Slack service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#slack-notifications +type SlackService struct { + Service + Properties *SlackServiceProperties `json:"properties"` +} + +// SlackServiceProperties represents Slack specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#slack-notifications +type SlackServiceProperties struct { + WebHook string `json:"webhook"` + Username string `json:"username"` + Channel string `json:"channel"` + NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"` + NotifyOnlyDefaultBranch BoolValue `json:"notify_only_default_branch"` + BranchesToBeNotified string `json:"branches_to_be_notified"` + AlertChannel string `json:"alert_channel"` + ConfidentialIssueChannel string `json:"confidential_issue_channel"` + ConfidentialNoteChannel string `json:"confidential_note_channel"` + DeploymentChannel string `json:"deployment_channel"` + IssueChannel string `json:"issue_channel"` + MergeRequestChannel string `json:"merge_request_channel"` + NoteChannel string `json:"note_channel"` + TagPushChannel string `json:"tag_push_channel"` + PipelineChannel string `json:"pipeline_channel"` + PushChannel string `json:"push_channel"` + VulnerabilityChannel string `json:"vulnerability_channel"` + WikiPageChannel string `json:"wiki_page_channel"` +} + +// GetSlackService gets Slack service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-slack-notifications-settings +func (s *ServicesService) GetSlackService(pid any, options ...RequestOptionFunc) (*SlackService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetSlackServiceOptions represents the available SetSlackService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-slack-notifications +type SetSlackServiceOptions struct { + WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Channel *string `url:"channel,omitempty" json:"channel,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + NotifyOnlyDefaultBranch *bool `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + AlertChannel *string `url:"alert_channel,omitempty" json:"alert_channel,omitempty"` + AlertEvents *bool `url:"alert_events,omitempty" json:"alert_events,omitempty"` + ConfidentialIssueChannel *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + ConfidentialNoteChannel *string `url:"confidential_note_channel,omitempty" json:"confidential_note_channel,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + DeploymentChannel *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"` + DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"` + IssueChannel *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + MergeRequestChannel *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + NoteChannel *string `url:"note_channel,omitempty" json:"note_channel,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + PushChannel *string `url:"push_channel,omitempty" json:"push_channel,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + TagPushChannel *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` +} + +// SetSlackService sets Slack service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-slack-notifications +func (s *ServicesService) SetSlackService(pid any, opt *SetSlackServiceOptions, options ...RequestOptionFunc) (*SlackService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteSlackService deletes Slack service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-slack-notifications +func (s *ServicesService) DeleteSlackService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// SlackSlashCommandsService represents Slack slash commands settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#slack-slash-commands +type SlackSlashCommandsService struct { + Service + Properties *SlackSlashCommandsProperties `json:"properties"` +} + +// SlackSlashCommandsProperties represents Slack slash commands specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#slack-slash-commands +type SlackSlashCommandsProperties struct { + Token string `json:"token"` +} + +// GetSlackSlashCommandsService gets Slack slash commands service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-slack-slash-commands-settings +func (s *ServicesService) GetSlackSlashCommandsService(pid any, options ...RequestOptionFunc) (*SlackSlashCommandsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackSlashCommandsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetSlackSlashCommandsServiceOptions represents the available SetSlackSlashCommandsService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-slack-slash-commands +type SetSlackSlashCommandsServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` +} + +// SetSlackSlashCommandsService sets Slack slash commands service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-slack-slash-commands +func (s *ServicesService) SetSlackSlashCommandsService(pid any, opt *SetSlackSlashCommandsServiceOptions, options ...RequestOptionFunc) (*SlackSlashCommandsService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(SlackSlashCommandsService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteSlackSlashCommandsService deletes Slack slash commands service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-slack-slash-commands +func (s *ServicesService) DeleteSlackSlashCommandsService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// TelegramService represents Telegram service settings. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/project_integrations/#telegram +type TelegramService struct { + Service + Properties *TelegramServiceProperties `json:"properties"` +} + +// TelegramServiceProperties represents Telegram specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-telegram +type TelegramServiceProperties struct { + Room string `json:"room"` + NotifyOnlyBrokenPipelines bool `json:"notify_only_broken_pipelines"` + BranchesToBeNotified string `json:"branches_to_be_notified"` +} + +// GetTelegramService gets MicrosoftTeams service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-telegram-settings +func (s *ServicesService) GetTelegramService(pid any, options ...RequestOptionFunc) (*TelegramService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/telegram", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(TelegramService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetTelegramServiceOptions represents the available SetTelegramService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-telegram +type SetTelegramServiceOptions struct { + Token *string `url:"token,omitempty" json:"token,omitempty"` + Room *string `url:"room,omitempty" json:"room,omitempty"` + NotifyOnlyBrokenPipelines *bool `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"` + BranchesToBeNotified *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` + IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"` + ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"` + MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` + TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` + NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"` + ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"` + PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"` + WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"` +} + +// SetTelegramService sets Telegram service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-telegram +func (s *ServicesService) SetTelegramService(pid any, opt *SetTelegramServiceOptions, options ...RequestOptionFunc) (*TelegramService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/telegram", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + svc := new(TelegramService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteTelegramService deletes Telegram service for project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-telegram +func (s *ServicesService) DeleteTelegramService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/telegram", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// YouTrackService represents YouTrack service settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#youtrack +type YouTrackService struct { + Service + Properties *YouTrackServiceProperties `json:"properties"` +} + +// YouTrackServiceProperties represents YouTrack specific properties. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#youtrack +type YouTrackServiceProperties struct { + IssuesURL string `json:"issues_url"` + ProjectURL string `json:"project_url"` + Description string `json:"description"` + PushEvents bool `json:"push_events"` +} + +// GetYouTrackService gets YouTrack service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#get-youtrack-settings +func (s *ServicesService) GetYouTrackService(pid any, options ...RequestOptionFunc) (*YouTrackService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + svc := new(YouTrackService) + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, resp, err + } + + return svc, resp, nil +} + +// SetYouTrackServiceOptions represents the available SetYouTrackService() +// options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-youtrack +type SetYouTrackServiceOptions struct { + IssuesURL *string `url:"issues_url,omitempty" json:"issues_url,omitempty"` + ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` +} + +// SetYouTrackService sets YouTrack service for a project +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#set-up-youtrack +func (s *ServicesService) SetYouTrackService(pid any, opt *SetYouTrackServiceOptions, options ...RequestOptionFunc) (*YouTrackService, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project)) + + svc := new(YouTrackService) + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + resp, err := s.client.Do(req, svc) + if err != nil { + return nil, nil, err + } + + return svc, resp, nil +} + +// DeleteYouTrackService deletes YouTrack service settings for a project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/project_integrations/#disable-youtrack +func (s *ServicesService) DeleteYouTrackService(pid any, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/settings.go b/vendor/gitlab.com/gitlab-org/api/client-go/settings.go new file mode 100644 index 000000000..2f04c29b0 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/settings.go @@ -0,0 +1,1000 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "net/http" + "time" +) + +type ( + SettingsServiceInterface interface { + GetSettings(options ...RequestOptionFunc) (*Settings, *Response, error) + UpdateSettings(opt *UpdateSettingsOptions, options ...RequestOptionFunc) (*Settings, *Response, error) + } + + // SettingsService handles communication with the application SettingsService + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/settings/ + SettingsService struct { + client *Client + } +) + +var _ SettingsServiceInterface = (*SettingsService)(nil) + +// Settings represents the GitLab application settings. +// +// GitLab API docs: https://docs.gitlab.com/api/settings/ +// +// The available parameters have been modeled directly after the code, as the +// documentation seems to be inaccurate. +// +// https://gitlab.com/gitlab-org/gitlab/-/blob/v14.9.3-ee/lib/api/settings.rb +// https://gitlab.com/gitlab-org/gitlab/-/blob/v14.9.3-ee/lib/api/entities/application_setting.rb#L5 +// https://gitlab.com/gitlab-org/gitlab/-/blob/v14.9.3-ee/app/helpers/application_settings_helper.rb#L192 +// https://gitlab.com/gitlab-org/gitlab/-/blob/v14.9.3-ee/ee/lib/ee/api/helpers/settings_helpers.rb#L10 +// https://gitlab.com/gitlab-org/gitlab/-/blob/v14.9.3-ee/ee/app/helpers/ee/application_settings_helper.rb#L20 +type Settings struct { + ID int `json:"id"` + AbuseNotificationEmail string `json:"abuse_notification_email"` + AdminMode bool `json:"admin_mode"` + AfterSignOutPath string `json:"after_sign_out_path"` + AfterSignUpText string `json:"after_sign_up_text"` + AkismetAPIKey string `json:"akismet_api_key"` + AkismetEnabled bool `json:"akismet_enabled"` + AllowAccountDeletion bool `json:"allow_account_deletion"` + AllowAllIntegrations bool `json:"allow_all_integrations"` + AllowedIntegrations []string `json:"allowed_integrations"` + AllowGroupOwnersToManageLDAP bool `json:"allow_group_owners_to_manage_ldap"` + AllowLocalRequestsFromSystemHooks bool `json:"allow_local_requests_from_system_hooks"` + AllowLocalRequestsFromWebHooksAndServices bool `json:"allow_local_requests_from_web_hooks_and_services"` + AllowProjectCreationForGuestAndBelow bool `json:"allow_project_creation_for_guest_and_below"` + AllowRunnerRegistrationToken bool `json:"allow_runner_registration_token"` + ArchiveBuildsInHumanReadable string `json:"archive_builds_in_human_readable"` + ASCIIDocMaxIncludes int `json:"asciidoc_max_includes"` + AssetProxyAllowlist []string `json:"asset_proxy_allowlist"` + AssetProxyEnabled bool `json:"asset_proxy_enabled"` + AssetProxyURL string `json:"asset_proxy_url"` + AssetProxySecretKey string `json:"asset_proxy_secret_key"` + AuthorizedKeysEnabled bool `json:"authorized_keys_enabled"` + AutoBanUserOnExcessiveProjectsDownload bool `json:"auto_ban_user_on_excessive_projects_download"` + AutocompleteUsers int `json:"autocomplete_users"` + AutocompleteUsersUnauthenticated int `json:"autocomplete_users_unauthenticated"` + AutoDevOpsDomain string `json:"auto_devops_domain"` + AutoDevOpsEnabled bool `json:"auto_devops_enabled"` + AutomaticPurchasedStorageAllocation bool `json:"automatic_purchased_storage_allocation"` + BulkImportConcurrentPipelineBatchLimit int `json:"bulk_import_concurrent_pipeline_batch_limit"` + BulkImportEnabled bool `json:"bulk_import_enabled"` + BulkImportMaxDownloadFileSize int `json:"bulk_import_max_download_file_size"` + CanCreateGroup bool `json:"can_create_group"` + CheckNamespacePlan bool `json:"check_namespace_plan"` + CIJobLiveTraceEnabled bool `json:"ci_job_live_trace_enabled"` + CIMaxIncludes int `json:"ci_max_includes"` + CIMaxTotalYAMLSizeBytes int `json:"ci_max_total_yaml_size_bytes"` + CIPartitionsSizeLimit int `json:"ci_partitions_size_limit"` + CommitEmailHostname string `json:"commit_email_hostname"` + ConcurrentBitbucketImportJobsLimit int `json:"concurrent_bitbucket_import_jobs_limit"` + ConcurrentBitbucketServerImportJobsLimit int `json:"concurrent_bitbucket_server_import_jobs_limit"` + ConcurrentGitHubImportJobsLimit int `json:"concurrent_github_import_jobs_limit"` + ContainerExpirationPoliciesEnableHistoricEntries bool `json:"container_expiration_policies_enable_historic_entries"` + ContainerRegistryCleanupTagsServiceMaxListSize int `json:"container_registry_cleanup_tags_service_max_list_size"` + ContainerRegistryDeleteTagsServiceTimeout int `json:"container_registry_delete_tags_service_timeout"` + ContainerRegistryExpirationPoliciesCaching bool `json:"container_registry_expiration_policies_caching"` + ContainerRegistryExpirationPoliciesWorkerCapacity int `json:"container_registry_expiration_policies_worker_capacity"` + ContainerRegistryImportCreatedBefore *time.Time `json:"container_registry_import_created_before"` + ContainerRegistryImportMaxRetries int `json:"container_registry_import_max_retries"` + ContainerRegistryImportMaxStepDuration int `json:"container_registry_import_max_step_duration"` + ContainerRegistryImportMaxTagsCount int `json:"container_registry_import_max_tags_count"` + ContainerRegistryImportStartMaxRetries int `json:"container_registry_import_start_max_retries"` + ContainerRegistryImportTargetPlan string `json:"container_registry_import_target_plan"` + ContainerRegistryTokenExpireDelay int `json:"container_registry_token_expire_delay"` + CreatedAt *time.Time `json:"created_at"` + CustomHTTPCloneURLRoot string `json:"custom_http_clone_url_root"` + DNSRebindingProtectionEnabled bool `json:"dns_rebinding_protection_enabled"` + DSAKeyRestriction int `json:"dsa_key_restriction"` + DeactivateDormantUsers bool `json:"deactivate_dormant_users"` + DeactivateDormantUsersPeriod int `json:"deactivate_dormant_users_period"` + DecompressArchiveFileTimeout int `json:"decompress_archive_file_timeout"` + DefaultArtifactsExpireIn string `json:"default_artifacts_expire_in"` + DefaultBranchName string `json:"default_branch_name"` + DefaultBranchProtectionDefaults *BranchProtectionDefaults `json:"default_branch_protection_defaults,omitempty"` + DefaultCiConfigPath string `json:"default_ci_config_path"` + DefaultGroupVisibility VisibilityValue `json:"default_group_visibility"` + DefaultPreferredLanguage string `json:"default_preferred_language"` + DefaultProjectCreation int `json:"default_project_creation"` + DefaultProjectDeletionProtection bool `json:"default_project_deletion_protection"` + DefaultProjectVisibility VisibilityValue `json:"default_project_visibility"` + DefaultProjectsLimit int `json:"default_projects_limit"` + DefaultSnippetVisibility VisibilityValue `json:"default_snippet_visibility"` + DefaultSyntaxHighlightingTheme int `json:"default_syntax_highlighting_theme"` + DelayedGroupDeletion bool `json:"delayed_group_deletion"` + DelayedProjectDeletion bool `json:"delayed_project_deletion"` + DeleteInactiveProjects bool `json:"delete_inactive_projects"` + DeleteUnconfirmedUsers bool `json:"delete_unconfirmed_users"` + DeletionAdjournedPeriod int `json:"deletion_adjourned_period"` + DiagramsnetEnabled bool `json:"diagramsnet_enabled"` + DiagramsnetURL string `json:"diagramsnet_url"` + DiffMaxFiles int `json:"diff_max_files"` + DiffMaxLines int `json:"diff_max_lines"` + DiffMaxPatchBytes int `json:"diff_max_patch_bytes"` + DisableAdminOAuthScopes bool `json:"disable_admin_oauth_scopes"` + DisableFeedToken bool `json:"disable_feed_token"` + DisableOverridingApproversPerMergeRequest bool `json:"disable_overriding_approvers_per_merge_request"` + DisablePersonalAccessTokens bool `json:"disable_personal_access_tokens"` + DisabledOauthSignInSources []string `json:"disabled_oauth_sign_in_sources"` + DomainAllowlist []string `json:"domain_allowlist"` + DomainDenylist []string `json:"domain_denylist"` + DomainDenylistEnabled bool `json:"domain_denylist_enabled"` + DownstreamPipelineTriggerLimitPerProjectUserSHA int `json:"downstream_pipeline_trigger_limit_per_project_user_sha"` + DuoFeaturesEnabled bool `json:"duo_features_enabled"` + ECDSAKeyRestriction int `json:"ecdsa_key_restriction"` + ECDSASKKeyRestriction int `json:"ecdsa_sk_key_restriction"` + EKSAccessKeyID string `json:"eks_access_key_id"` + EKSAccountID string `json:"eks_account_id"` + EKSIntegrationEnabled bool `json:"eks_integration_enabled"` + EKSSecretAccessKey string `json:"eks_secret_access_key"` + Ed25519KeyRestriction int `json:"ed25519_key_restriction"` + Ed25519SKKeyRestriction int `json:"ed25519_sk_key_restriction"` + ElasticsearchAWS bool `json:"elasticsearch_aws"` + ElasticsearchAWSAccessKey string `json:"elasticsearch_aws_access_key"` + ElasticsearchAWSRegion string `json:"elasticsearch_aws_region"` + ElasticsearchAWSSecretAccessKey string `json:"elasticsearch_aws_secret_access_key"` + ElasticsearchAnalyzersKuromojiEnabled bool `json:"elasticsearch_analyzers_kuromoji_enabled"` + ElasticsearchAnalyzersKuromojiSearch bool `json:"elasticsearch_analyzers_kuromoji_search"` + ElasticsearchAnalyzersSmartCNEnabled bool `json:"elasticsearch_analyzers_smartcn_enabled"` + ElasticsearchAnalyzersSmartCNSearch bool `json:"elasticsearch_analyzers_smartcn_search"` + ElasticsearchClientRequestTimeout int `json:"elasticsearch_client_request_timeout"` + ElasticsearchIndexedFieldLengthLimit int `json:"elasticsearch_indexed_field_length_limit"` + ElasticsearchIndexedFileSizeLimitKB int `json:"elasticsearch_indexed_file_size_limit_kb"` + ElasticsearchIndexing bool `json:"elasticsearch_indexing"` + ElasticsearchLimitIndexing bool `json:"elasticsearch_limit_indexing"` + ElasticsearchMaxBulkConcurrency int `json:"elasticsearch_max_bulk_concurrency"` + ElasticsearchMaxBulkSizeMB int `json:"elasticsearch_max_bulk_size_mb"` + ElasticsearchMaxCodeIndexingConcurrency int `json:"elasticsearch_max_code_indexing_concurrency"` + ElasticsearchNamespaceIDs []int `json:"elasticsearch_namespace_ids"` + ElasticsearchPassword string `json:"elasticsearch_password"` + ElasticsearchPauseIndexing bool `json:"elasticsearch_pause_indexing"` + ElasticsearchProjectIDs []int `json:"elasticsearch_project_ids"` + ElasticsearchReplicas int `json:"elasticsearch_replicas"` + ElasticsearchRequeueWorkers bool `json:"elasticsearch_requeue_workers"` + ElasticsearchRetryOnFailure int `json:"elasticsearch_retry_on_failure"` + ElasticsearchSearch bool `json:"elasticsearch_search"` + ElasticsearchShards int `json:"elasticsearch_shards"` + ElasticsearchURL []string `json:"elasticsearch_url"` + ElasticsearchUsername string `json:"elasticsearch_username"` + ElasticsearchWorkerNumberOfShards int `json:"elasticsearch_worker_number_of_shards"` + EmailAdditionalText string `json:"email_additional_text"` + EmailAuthorInBody bool `json:"email_author_in_body"` + EmailConfirmationSetting string `json:"email_confirmation_setting"` + EmailRestrictions string `json:"email_restrictions"` + EmailRestrictionsEnabled bool `json:"email_restrictions_enabled"` + EnableArtifactExternalRedirectWarningPage bool `json:"enable_artifact_external_redirect_warning_page"` + EnabledGitAccessProtocol string `json:"enabled_git_access_protocol"` + EnforceCIInboundJobTokenScopeEnabled bool `json:"enforce_ci_inbound_job_token_scope_enabled"` + EnforceNamespaceStorageLimit bool `json:"enforce_namespace_storage_limit"` + EnforcePATExpiration bool `json:"enforce_pat_expiration"` + EnforceSSHKeyExpiration bool `json:"enforce_ssh_key_expiration"` + EnforceTerms bool `json:"enforce_terms"` + ExternalAuthClientCert string `json:"external_auth_client_cert"` + ExternalAuthClientKey string `json:"external_auth_client_key"` + ExternalAuthClientKeyPass string `json:"external_auth_client_key_pass"` + ExternalAuthorizationServiceDefaultLabel string `json:"external_authorization_service_default_label"` + ExternalAuthorizationServiceEnabled bool `json:"external_authorization_service_enabled"` + ExternalAuthorizationServiceTimeout float64 `json:"external_authorization_service_timeout"` + ExternalAuthorizationServiceURL string `json:"external_authorization_service_url"` + ExternalPipelineValidationServiceTimeout int `json:"external_pipeline_validation_service_timeout"` + ExternalPipelineValidationServiceToken string `json:"external_pipeline_validation_service_token"` + ExternalPipelineValidationServiceURL string `json:"external_pipeline_validation_service_url"` + FailedLoginAttemptsUnlockPeriodInMinutes int `json:"failed_login_attempts_unlock_period_in_minutes"` + FileTemplateProjectID int `json:"file_template_project_id"` + FirstDayOfWeek int `json:"first_day_of_week"` + FlocEnabled bool `json:"floc_enabled"` + GeoNodeAllowedIPs string `json:"geo_node_allowed_ips"` + GeoStatusTimeout int `json:"geo_status_timeout"` + GitRateLimitUsersAlertlist []int `json:"git_rate_limit_users_alertlist"` + GitTwoFactorSessionExpiry int `json:"git_two_factor_session_expiry"` + GitalyTimeoutDefault int `json:"gitaly_timeout_default"` + GitalyTimeoutFast int `json:"gitaly_timeout_fast"` + GitalyTimeoutMedium int `json:"gitaly_timeout_medium"` + GitlabDedicatedInstance bool `json:"gitlab_dedicated_instance"` + GitlabEnvironmentToolkitInstance bool `json:"gitlab_environment_toolkit_instance"` + GitlabShellOperationLimit int `json:"gitlab_shell_operation_limit"` + GitpodEnabled bool `json:"gitpod_enabled"` + GitpodURL string `json:"gitpod_url"` + GitRateLimitUsersAllowlist []string `json:"git_rate_limit_users_allowlist"` + GloballyAllowedIPs string `json:"globally_allowed_ips"` + GrafanaEnabled bool `json:"grafana_enabled"` + GrafanaURL string `json:"grafana_url"` + GravatarEnabled bool `json:"gravatar_enabled"` + GroupDownloadExportLimit int `json:"group_download_export_limit"` + GroupExportLimit int `json:"group_export_limit"` + GroupImportLimit int `json:"group_import_limit"` + GroupOwnersCanManageDefaultBranchProtection bool `json:"group_owners_can_manage_default_branch_protection"` + GroupRunnerTokenExpirationInterval int `json:"group_runner_token_expiration_interval"` + HTMLEmailsEnabled bool `json:"html_emails_enabled"` + HashedStorageEnabled bool `json:"hashed_storage_enabled"` + HelpPageDocumentationBaseURL string `json:"help_page_documentation_base_url"` + HelpPageHideCommercialContent bool `json:"help_page_hide_commercial_content"` + HelpPageSupportURL string `json:"help_page_support_url"` + HelpPageText string `json:"help_page_text"` + HelpText string `json:"help_text"` + HideThirdPartyOffers bool `json:"hide_third_party_offers"` + HomePageURL string `json:"home_page_url"` + HousekeepingEnabled bool `json:"housekeeping_enabled"` + HousekeepingOptimizeRepositoryPeriod int `json:"housekeeping_optimize_repository_period"` + ImportSources []string `json:"import_sources"` + InactiveProjectsDeleteAfterMonths int `json:"inactive_projects_delete_after_months"` + InactiveProjectsMinSizeMB int `json:"inactive_projects_min_size_mb"` + InactiveProjectsSendWarningEmailAfterMonths int `json:"inactive_projects_send_warning_email_after_months"` + IncludeOptionalMetricsInServicePing bool `json:"include_optional_metrics_in_service_ping"` + InProductMarketingEmailsEnabled bool `json:"in_product_marketing_emails_enabled"` + InvisibleCaptchaEnabled bool `json:"invisible_captcha_enabled"` + IssuesCreateLimit int `json:"issues_create_limit"` + JiraConnectApplicationKey string `json:"jira_connect_application_key"` + JiraConnectPublicKeyStorageEnabled bool `json:"jira_connect_public_key_storage_enabled"` + JiraConnectProxyURL string `json:"jira_connect_proxy_url"` + KeepLatestArtifact bool `json:"keep_latest_artifact"` + KrokiEnabled bool `json:"kroki_enabled"` + KrokiFormats map[string]bool `json:"kroki_formats"` + KrokiURL string `json:"kroki_url"` + LocalMarkdownVersion int `json:"local_markdown_version"` + LockDuoFeaturesEnabled bool `json:"lock_duo_features_enabled"` + LockMembershipsToLDAP bool `json:"lock_memberships_to_ldap"` + LoginRecaptchaProtectionEnabled bool `json:"login_recaptcha_protection_enabled"` + MailgunEventsEnabled bool `json:"mailgun_events_enabled"` + MailgunSigningKey string `json:"mailgun_signing_key"` + MaintenanceMode bool `json:"maintenance_mode"` + MaintenanceModeMessage string `json:"maintenance_mode_message"` + MavenPackageRequestsForwarding bool `json:"maven_package_requests_forwarding"` + MaxArtifactsSize int `json:"max_artifacts_size"` + MaxAttachmentSize int `json:"max_attachment_size"` + MaxDecompressedArchiveSize int `json:"max_decompressed_archive_size"` + MaxExportSize int `json:"max_export_size"` + MaxImportRemoteFileSize int `json:"max_import_remote_file_size"` + MaxImportSize int `json:"max_import_size"` + MaxLoginAttempts int `json:"max_login_attempts"` + MaxNumberOfRepositoryDownloads int `json:"max_number_of_repository_downloads"` + MaxNumberOfRepositoryDownloadsWithinTimePeriod int `json:"max_number_of_repository_downloads_within_time_period"` + MaxPagesSize int `json:"max_pages_size"` + MaxPersonalAccessTokenLifetime int `json:"max_personal_access_token_lifetime"` + MaxSSHKeyLifetime int `json:"max_ssh_key_lifetime"` + MaxTerraformStateSizeBytes int `json:"max_terraform_state_size_bytes"` + MaxYAMLDepth int `json:"max_yaml_depth"` + MaxYAMLSizeBytes int `json:"max_yaml_size_bytes"` + MetricsMethodCallThreshold int `json:"metrics_method_call_threshold"` + MinimumPasswordLength int `json:"minimum_password_length"` + MirrorAvailable bool `json:"mirror_available"` + MirrorCapacityThreshold int `json:"mirror_capacity_threshold"` + MirrorMaxCapacity int `json:"mirror_max_capacity"` + MirrorMaxDelay int `json:"mirror_max_delay"` + NPMPackageRequestsForwarding bool `json:"npm_package_requests_forwarding"` + NotesCreateLimit int `json:"notes_create_limit"` + NotifyOnUnknownSignIn bool `json:"notify_on_unknown_sign_in"` + NugetSkipMetadataURLValidation bool `json:"nuget_skip_metadata_url_validation"` + OutboundLocalRequestsAllowlistRaw string `json:"outbound_local_requests_allowlist_raw"` + OutboundLocalRequestsWhitelist []string `json:"outbound_local_requests_whitelist"` + PackageMetadataPURLTypes []int `json:"package_metadata_purl_types"` + PackageRegistryAllowAnyoneToPullOption bool `json:"package_registry_allow_anyone_to_pull_option"` + PackageRegistryCleanupPoliciesWorkerCapacity int `json:"package_registry_cleanup_policies_worker_capacity"` + PagesDomainVerificationEnabled bool `json:"pages_domain_verification_enabled"` + PasswordAuthenticationEnabledForGit bool `json:"password_authentication_enabled_for_git"` + PasswordAuthenticationEnabledForWeb bool `json:"password_authentication_enabled_for_web"` + PasswordNumberRequired bool `json:"password_number_required"` + PasswordSymbolRequired bool `json:"password_symbol_required"` + PasswordUppercaseRequired bool `json:"password_uppercase_required"` + PasswordLowercaseRequired bool `json:"password_lowercase_required"` + PerformanceBarAllowedGroupPath string `json:"performance_bar_allowed_group_path"` + PersonalAccessTokenPrefix string `json:"personal_access_token_prefix"` + PipelineLimitPerProjectUserSha int `json:"pipeline_limit_per_project_user_sha"` + PlantumlEnabled bool `json:"plantuml_enabled"` + PlantumlURL string `json:"plantuml_url"` + PollingIntervalMultiplier float64 `json:"polling_interval_multiplier,string"` + PreventMergeRequestsAuthorApproval bool `json:"prevent_merge_request_author_approval"` + PreventMergeRequestsCommittersApproval bool `json:"prevent_merge_request_committers_approval"` + ProjectDownloadExportLimit int `json:"project_download_export_limit"` + ProjectExportEnabled bool `json:"project_export_enabled"` + ProjectExportLimit int `json:"project_export_limit"` + ProjectImportLimit int `json:"project_import_limit"` + ProjectJobsAPIRateLimit int `json:"project_jobs_api_rate_limit"` + ProjectRunnerTokenExpirationInterval int `json:"project_runner_token_expiration_interval"` + ProjectsAPIRateLimitUnauthenticated int `json:"projects_api_rate_limit_unauthenticated"` + PrometheusMetricsEnabled bool `json:"prometheus_metrics_enabled"` + ProtectedCIVariables bool `json:"protected_ci_variables"` + PseudonymizerEnabled bool `json:"pseudonymizer_enabled"` + PushEventActivitiesLimit int `json:"push_event_activities_limit"` + PushEventHooksLimit int `json:"push_event_hooks_limit"` + PyPIPackageRequestsForwarding bool `json:"pypi_package_requests_forwarding"` + RSAKeyRestriction int `json:"rsa_key_restriction"` + RateLimitingResponseText string `json:"rate_limiting_response_text"` + RawBlobRequestLimit int `json:"raw_blob_request_limit"` + RecaptchaEnabled bool `json:"recaptcha_enabled"` + RecaptchaPrivateKey string `json:"recaptcha_private_key"` + RecaptchaSiteKey string `json:"recaptcha_site_key"` + ReceiveMaxInputSize int `json:"receive_max_input_size"` + ReceptiveClusterAgentsEnabled bool `json:"receptive_cluster_agents_enabled"` + RememberMeEnabled bool `json:"remember_me_enabled"` + RepositoryChecksEnabled bool `json:"repository_checks_enabled"` + RepositorySizeLimit int `json:"repository_size_limit"` + RepositoryStorages []string `json:"repository_storages"` + RepositoryStoragesWeighted map[string]int `json:"repository_storages_weighted"` + RequireAdminApprovalAfterUserSignup bool `json:"require_admin_approval_after_user_signup"` + RequireAdminTwoFactorAuthentication bool `json:"require_admin_two_factor_authentication"` + RequirePersonalAccessTokenExpiry bool `json:"require_personal_access_token_expiry"` + RequireTwoFactorAuthentication bool `json:"require_two_factor_authentication"` + RestrictedVisibilityLevels []VisibilityValue `json:"restricted_visibility_levels"` + RunnerTokenExpirationInterval int `json:"runner_token_expiration_interval"` + SearchRateLimit int `json:"search_rate_limit"` + SearchRateLimitUnauthenticated int `json:"search_rate_limit_unauthenticated"` + SecretDetectionRevocationTokenTypesURL string `json:"secret_detection_revocation_token_types_url"` + SecretDetectionTokenRevocationEnabled bool `json:"secret_detection_token_revocation_enabled"` + SecretDetectionTokenRevocationToken string `json:"secret_detection_token_revocation_token"` + SecretDetectionTokenRevocationURL string `json:"secret_detection_token_revocation_url"` + SecurityApprovalPoliciesLimit int `json:"security_approval_policies_limit"` + SecurityPolicyGlobalGroupApproversEnabled bool `json:"security_policy_global_group_approvers_enabled"` + SecurityTXTContent string `json:"security_txt_content"` + SendUserConfirmationEmail bool `json:"send_user_confirmation_email"` + SentryClientsideDSN string `json:"sentry_clientside_dsn"` + SentryDSN string `json:"sentry_dsn"` + SentryEnabled bool `json:"sentry_enabled"` + SentryEnvironment string `json:"sentry_environment"` + ServiceAccessTokensExpirationEnforced bool `json:"service_access_tokens_expiration_enforced"` + SessionExpireDelay int `json:"session_expire_delay"` + SharedRunnersEnabled bool `json:"shared_runners_enabled"` + SharedRunnersMinutes int `json:"shared_runners_minutes"` + SharedRunnersText string `json:"shared_runners_text"` + SidekiqJobLimiterCompressionThresholdBytes int `json:"sidekiq_job_limiter_compression_threshold_bytes"` + SidekiqJobLimiterLimitBytes int `json:"sidekiq_job_limiter_limit_bytes"` + SidekiqJobLimiterMode string `json:"sidekiq_job_limiter_mode"` + SignInText string `json:"sign_in_text"` + SignupEnabled bool `json:"signup_enabled"` + SilentAdminExportsEnabled bool `json:"silent_admin_exports_enabled"` + SilentModeEnabled bool `json:"silent_mode_enabled"` + SlackAppEnabled bool `json:"slack_app_enabled"` + SlackAppID string `json:"slack_app_id"` + SlackAppSecret string `json:"slack_app_secret"` + SlackAppSigningSecret string `json:"slack_app_signing_secret"` + SlackAppVerificationToken string `json:"slack_app_verification_token"` + SnippetSizeLimit int `json:"snippet_size_limit"` + SnowplowAppID string `json:"snowplow_app_id"` + SnowplowCollectorHostname string `json:"snowplow_collector_hostname"` + SnowplowCookieDomain string `json:"snowplow_cookie_domain"` + SnowplowDatabaseCollectorHostname string `json:"snowplow_database_collector_hostname"` + SnowplowEnabled bool `json:"snowplow_enabled"` + SourcegraphEnabled bool `json:"sourcegraph_enabled"` + SourcegraphPublicOnly bool `json:"sourcegraph_public_only"` + SourcegraphURL string `json:"sourcegraph_url"` + SpamCheckAPIKey string `json:"spam_check_api_key"` + SpamCheckEndpointEnabled bool `json:"spam_check_endpoint_enabled"` + SpamCheckEndpointURL string `json:"spam_check_endpoint_url"` + StaticObjectsExternalStorageAuthToken string `json:"static_objects_external_storage_auth_token"` + StaticObjectsExternalStorageURL string `json:"static_objects_external_storage_url"` + SuggestPipelineEnabled bool `json:"suggest_pipeline_enabled"` + TerminalMaxSessionTime int `json:"terminal_max_session_time"` + Terms string `json:"terms"` + ThrottleAuthenticatedAPIEnabled bool `json:"throttle_authenticated_api_enabled"` + ThrottleAuthenticatedAPIPeriodInSeconds int `json:"throttle_authenticated_api_period_in_seconds"` + ThrottleAuthenticatedAPIRequestsPerPeriod int `json:"throttle_authenticated_api_requests_per_period"` + ThrottleAuthenticatedDeprecatedAPIEnabled bool `json:"throttle_authenticated_deprecated_api_enabled"` + ThrottleAuthenticatedDeprecatedAPIPeriodInSeconds int `json:"throttle_authenticated_deprecated_api_period_in_seconds"` + ThrottleAuthenticatedDeprecatedAPIRequestsPerPeriod int `json:"throttle_authenticated_deprecated_api_requests_per_period"` + ThrottleAuthenticatedFilesAPIEnabled bool `json:"throttle_authenticated_files_api_enabled"` + ThrottleAuthenticatedFilesAPIPeriodInSeconds int `json:"throttle_authenticated_files_api_period_in_seconds"` + ThrottleAuthenticatedFilesAPIRequestsPerPeriod int `json:"throttle_authenticated_files_api_requests_per_period"` + ThrottleAuthenticatedGitLFSEnabled bool `json:"throttle_authenticated_git_lfs_enabled"` + ThrottleAuthenticatedGitLFSPeriodInSeconds int `json:"throttle_authenticated_git_lfs_period_in_seconds"` + ThrottleAuthenticatedGitLFSRequestsPerPeriod int `json:"throttle_authenticated_git_lfs_requests_per_period"` + ThrottleAuthenticatedPackagesAPIEnabled bool `json:"throttle_authenticated_packages_api_enabled"` + ThrottleAuthenticatedPackagesAPIPeriodInSeconds int `json:"throttle_authenticated_packages_api_period_in_seconds"` + ThrottleAuthenticatedPackagesAPIRequestsPerPeriod int `json:"throttle_authenticated_packages_api_requests_per_period"` + ThrottleAuthenticatedWebEnabled bool `json:"throttle_authenticated_web_enabled"` + ThrottleAuthenticatedWebPeriodInSeconds int `json:"throttle_authenticated_web_period_in_seconds"` + ThrottleAuthenticatedWebRequestsPerPeriod int `json:"throttle_authenticated_web_requests_per_period"` + ThrottleIncidentManagementNotificationEnabled bool `json:"throttle_incident_management_notification_enabled"` + ThrottleIncidentManagementNotificationPerPeriod int `json:"throttle_incident_management_notification_per_period"` + ThrottleIncidentManagementNotificationPeriodInSeconds int `json:"throttle_incident_management_notification_period_in_seconds"` + ThrottleProtectedPathsEnabled bool `json:"throttle_protected_paths_enabled"` + ThrottleProtectedPathsPeriodInSeconds int `json:"throttle_protected_paths_period_in_seconds"` + ThrottleProtectedPathsRequestsPerPeriod int `json:"throttle_protected_paths_requests_per_period"` + ThrottleUnauthenticatedAPIEnabled bool `json:"throttle_unauthenticated_api_enabled"` + ThrottleUnauthenticatedAPIPeriodInSeconds int `json:"throttle_unauthenticated_api_period_in_seconds"` + ThrottleUnauthenticatedAPIRequestsPerPeriod int `json:"throttle_unauthenticated_api_requests_per_period"` + ThrottleUnauthenticatedDeprecatedAPIEnabled bool `json:"throttle_unauthenticated_deprecated_api_enabled"` + ThrottleUnauthenticatedDeprecatedAPIPeriodInSeconds int `json:"throttle_unauthenticated_deprecated_api_period_in_seconds"` + ThrottleUnauthenticatedDeprecatedAPIRequestsPerPeriod int `json:"throttle_unauthenticated_deprecated_api_requests_per_period"` + ThrottleUnauthenticatedFilesAPIEnabled bool `json:"throttle_unauthenticated_files_api_enabled"` + ThrottleUnauthenticatedFilesAPIPeriodInSeconds int `json:"throttle_unauthenticated_files_api_period_in_seconds"` + ThrottleUnauthenticatedFilesAPIRequestsPerPeriod int `json:"throttle_unauthenticated_files_api_requests_per_period"` + ThrottleUnauthenticatedGitLFSEnabled bool `json:"throttle_unauthenticated_git_lfs_enabled"` + ThrottleUnauthenticatedGitLFSPeriodInSeconds int `json:"throttle_unauthenticated_git_lfs_period_in_seconds"` + ThrottleUnauthenticatedGitLFSRequestsPerPeriod int `json:"throttle_unauthenticated_git_lfs_requests_per_period"` + ThrottleUnauthenticatedPackagesAPIEnabled bool `json:"throttle_unauthenticated_packages_api_enabled"` + ThrottleUnauthenticatedPackagesAPIPeriodInSeconds int `json:"throttle_unauthenticated_packages_api_period_in_seconds"` + ThrottleUnauthenticatedPackagesAPIRequestsPerPeriod int `json:"throttle_unauthenticated_packages_api_requests_per_period"` + ThrottleUnauthenticatedWebEnabled bool `json:"throttle_unauthenticated_web_enabled"` + ThrottleUnauthenticatedWebPeriodInSeconds int `json:"throttle_unauthenticated_web_period_in_seconds"` + ThrottleUnauthenticatedWebRequestsPerPeriod int `json:"throttle_unauthenticated_web_requests_per_period"` + TimeTrackingLimitToHours bool `json:"time_tracking_limit_to_hours"` + TwoFactorGracePeriod int `json:"two_factor_grace_period"` + UnconfirmedUsersDeleteAfterDays int `json:"unconfirmed_users_delete_after_days"` + UniqueIPsLimitEnabled bool `json:"unique_ips_limit_enabled"` + UniqueIPsLimitPerUser int `json:"unique_ips_limit_per_user"` + UniqueIPsLimitTimeWindow int `json:"unique_ips_limit_time_window"` + UpdateRunnerVersionsEnabled bool `json:"update_runner_versions_enabled"` + UpdatedAt *time.Time `json:"updated_at"` + UpdatingNameDisabledForUsers bool `json:"updating_name_disabled_for_users"` + UsagePingEnabled bool `json:"usage_ping_enabled"` + UsagePingFeaturesEnabled bool `json:"usage_ping_features_enabled"` + UseClickhouseForAnalytics bool `json:"use_clickhouse_for_analytics"` + UserDeactivationEmailsEnabled bool `json:"user_deactivation_emails_enabled"` + UserDefaultExternal bool `json:"user_default_external"` + UserDefaultInternalRegex string `json:"user_default_internal_regex"` + UserDefaultsToPrivateProfile bool `json:"user_defaults_to_private_profile"` + UserOauthApplications bool `json:"user_oauth_applications"` + UserShowAddSSHKeyMessage bool `json:"user_show_add_ssh_key_message"` + UsersGetByIDLimit int `json:"users_get_by_id_limit"` + UsersGetByIDLimitAllowlistRaw string `json:"users_get_by_id_limit_allowlist_raw"` + ValidRunnerRegistrars []string `json:"valid_runner_registrars"` + VersionCheckEnabled bool `json:"version_check_enabled"` + WebIDEClientsidePreviewEnabled bool `json:"web_ide_clientside_preview_enabled"` + WhatsNewVariant string `json:"whats_new_variant"` + WikiPageMaxContentBytes int `json:"wiki_page_max_content_bytes"` + + // Deprecated: Use DefaultBranchProtectionDefaults instead. + DefaultBranchProtection int `json:"default_branch_protection"` + // Deprecated: Cannot be set through the API, always true + HousekeepingBitmapsEnabled bool `json:"housekeeping_bitmaps_enabled"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingFullRepackPeriod int `json:"housekeeping_full_repack_period"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingGcPeriod int `json:"housekeeping_gc_period"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingIncrementalRepackPeriod int `json:"housekeeping_incremental_repack_period"` + // Deprecated: use PerformanceBarAllowedGroupPath instead + PerformanceBarAllowedGroupID int `json:"performance_bar_allowed_group_id"` + // Deprecated: use PerformanceBarAllowedGroupPath: nil instead + PerformanceBarEnabled bool `json:"performance_bar_enabled"` + // Deprecated: Use AbuseNotificationEmail instead. + AdminNotificationEmail string `json:"admin_notification_email"` + // Deprecated: Use AllowLocalRequestsFromWebHooksAndServices instead. + AllowLocalRequestsFromHooksAndServices bool `json:"allow_local_requests_from_hooks_and_services"` + // Deprecated: Use AssetProxyAllowlist instead. + AssetProxyWhitelist []string `json:"asset_proxy_whitelist"` + // Deprecated: Use ThrottleUnauthenticatedWebEnabled or ThrottleUnauthenticatedAPIEnabled instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedEnabled bool `json:"throttle_unauthenticated_enabled"` + // Deprecated: Use ThrottleUnauthenticatedWebPeriodInSeconds or ThrottleUnauthenticatedAPIPeriodInSeconds instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedPeriodInSeconds int `json:"throttle_unauthenticated_period_in_seconds"` + // Deprecated: Use ThrottleUnauthenticatedWebRequestsPerPeriod or ThrottleUnauthenticatedAPIRequestsPerPeriod instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedRequestsPerPeriod int `json:"throttle_unauthenticated_requests_per_period"` + // Deprecated: Replaced by SearchRateLimit in GitLab 14.9 (removed in 15.0). + UserEmailLookupLimit int `json:"user_email_lookup_limit"` +} + +// Settings requires a custom unmarshaller in order to properly unmarshal +// `container_registry_import_created_before` which is either a time.Time or +// an empty string if no value is set. +func (s *Settings) UnmarshalJSON(data []byte) error { + type Alias Settings + + raw := make(map[string]any) + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + + // If empty string, remove the value to leave it nil in the response. + if v, ok := raw["container_registry_import_created_before"]; ok && v == "" { + delete(raw, "container_registry_import_created_before") + + data, err = json.Marshal(raw) + if err != nil { + return err + } + } + + return json.Unmarshal(data, (*Alias)(s)) +} + +func (s Settings) String() string { + return Stringify(s) +} + +// GetSettings gets the current application settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/settings/#get-details-on-current-application-settings +func (s *SettingsService) GetSettings(options ...RequestOptionFunc) (*Settings, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "application/settings", nil, options) + if err != nil { + return nil, nil, err + } + + as := new(Settings) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} + +// UpdateSettingsOptions represents the available UpdateSettings() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/settings/#update-application-settings +type UpdateSettingsOptions struct { + AbuseNotificationEmail *string `url:"abuse_notification_email,omitempty" json:"abuse_notification_email,omitempty"` + AdminMode *bool `url:"admin_mode,omitempty" json:"admin_mode,omitempty"` + AfterSignOutPath *string `url:"after_sign_out_path,omitempty" json:"after_sign_out_path,omitempty"` + AfterSignUpText *string `url:"after_sign_up_text,omitempty" json:"after_sign_up_text,omitempty"` + AkismetAPIKey *string `url:"akismet_api_key,omitempty" json:"akismet_api_key,omitempty"` + AkismetEnabled *bool `url:"akismet_enabled,omitempty" json:"akismet_enabled,omitempty"` + AllowAccountDeletion *bool `url:"allow_account_deletion,omitempty" json:"allow_account_deletion,omitempty"` + AllowAllIntegrations *bool `url:"allow_all_integrations,omitempty" json:"allow_all_integrations,omitempty"` + AllowedIntegrations *[]string `url:"allowed_integrations,omitempty" json:"allowed_integrations,omitempty"` + AllowGroupOwnersToManageLDAP *bool `url:"allow_group_owners_to_manage_ldap,omitempty" json:"allow_group_owners_to_manage_ldap,omitempty"` + AllowLocalRequestsFromSystemHooks *bool `url:"allow_local_requests_from_system_hooks,omitempty" json:"allow_local_requests_from_system_hooks,omitempty"` + AllowLocalRequestsFromWebHooksAndServices *bool `url:"allow_local_requests_from_web_hooks_and_services,omitempty" json:"allow_local_requests_from_web_hooks_and_services,omitempty"` + AllowProjectCreationForGuestAndBelow *bool `url:"allow_project_creation_for_guest_and_below,omitempty" json:"allow_project_creation_for_guest_and_below,omitempty"` + AllowRunnerRegistrationToken *bool `url:"allow_runner_registration_token,omitempty" json:"allow_runner_registration_token,omitempty"` + ArchiveBuildsInHumanReadable *string `url:"archive_builds_in_human_readable,omitempty" json:"archive_builds_in_human_readable,omitempty"` + ASCIIDocMaxIncludes *int `url:"asciidoc_max_includes,omitempty" json:"asciidoc_max_includes,omitempty"` + AssetProxyAllowlist *[]string `url:"asset_proxy_allowlist,omitempty" json:"asset_proxy_allowlist,omitempty"` + AssetProxyEnabled *bool `url:"asset_proxy_enabled,omitempty" json:"asset_proxy_enabled,omitempty"` + AssetProxySecretKey *string `url:"asset_proxy_secret_key,omitempty" json:"asset_proxy_secret_key,omitempty"` + AssetProxyURL *string `url:"asset_proxy_url,omitempty" json:"asset_proxy_url,omitempty"` + AuthorizedKeysEnabled *bool `url:"authorized_keys_enabled,omitempty" json:"authorized_keys_enabled,omitempty"` + AutoBanUserOnExcessiveProjectsDownload *bool `url:"auto_ban_user_on_excessive_projects_download,omitempty" json:"auto_ban_user_on_excessive_projects_download,omitempty"` + AutocompleteUsers *int `url:"autocomplete_users,omitempty" json:"autocomplete_users,omitempty"` + AutocompleteUsersUnauthenticated *int `url:"autocomplete_users_unauthenticated,omitempty" json:"autocomplete_users_unauthenticated,omitempty"` + AutoDevOpsDomain *string `url:"auto_devops_domain,omitempty" json:"auto_devops_domain,omitempty"` + AutoDevOpsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"` + AutomaticPurchasedStorageAllocation *bool `url:"automatic_purchased_storage_allocation,omitempty" json:"automatic_purchased_storage_allocation,omitempty"` + BulkImportConcurrentPipelineBatchLimit *int `url:"bulk_import_concurrent_pipeline_batch_limit,omitempty" json:"bulk_import_concurrent_pipeline_batch_limit,omitempty"` + BulkImportEnabled *bool `url:"bulk_import_enabled,omitempty" json:"bulk_import_enabled,omitempty"` + BulkImportMaxDownloadFileSize *int `url:"bulk_import_max_download_file_size,omitempty" json:"bulk_import_max_download_file_size,omitempty"` + CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` + CheckNamespacePlan *bool `url:"check_namespace_plan,omitempty" json:"check_namespace_plan,omitempty"` + CIJobLiveTraceEnabled *bool `url:"ci_job_live_trace_enabled,omitempty" json:"ci_job_live_trace_enabled,omitempty"` + CIMaxIncludes *int `url:"ci_max_includes,omitempty" json:"ci_max_includes,omitempty"` + CIMaxTotalYAMLSizeBytes *int `url:"ci_max_total_yaml_size_bytes,omitempty" json:"ci_max_total_yaml_size_bytes,omitempty"` + CIPartitionsSizeLimit *int `url:"ci_partitions_size_limit,omitempty" json:"ci_partitions_size_limit,omitempty"` + CommitEmailHostname *string `url:"commit_email_hostname,omitempty" json:"commit_email_hostname,omitempty"` + ConcurrentBitbucketImportJobsLimit *int `url:"concurrent_bitbucket_import_jobs_limit,omitempty" json:"concurrent_bitbucket_import_jobs_limit,omitempty"` + ConcurrentBitbucketServerImportJobsLimit *int `url:"concurrent_bitbucket_server_import_jobs_limit,omitempty" json:"concurrent_bitbucket_server_import_jobs_limit,omitempty"` + ConcurrentGitHubImportJobsLimit *int `url:"concurrent_github_import_jobs_limit,omitempty" json:"concurrent_github_import_jobs_limit,omitempty"` + ContainerExpirationPoliciesEnableHistoricEntries *bool `url:"container_expiration_policies_enable_historic_entries,omitempty" json:"container_expiration_policies_enable_historic_entries,omitempty"` + ContainerRegistryCleanupTagsServiceMaxListSize *int `url:"container_registry_cleanup_tags_service_max_list_size,omitempty" json:"container_registry_cleanup_tags_service_max_list_size,omitempty"` + ContainerRegistryDeleteTagsServiceTimeout *int `url:"container_registry_delete_tags_service_timeout,omitempty" json:"container_registry_delete_tags_service_timeout,omitempty"` + ContainerRegistryExpirationPoliciesCaching *bool `url:"container_registry_expiration_policies_caching,omitempty" json:"container_registry_expiration_policies_caching,omitempty"` + ContainerRegistryExpirationPoliciesWorkerCapacity *int `url:"container_registry_expiration_policies_worker_capacity,omitempty" json:"container_registry_expiration_policies_worker_capacity,omitempty"` + ContainerRegistryImportCreatedBefore *time.Time `url:"container_registry_import_created_before,omitempty" json:"container_registry_import_created_before,omitempty"` + ContainerRegistryImportMaxRetries *int `url:"container_registry_import_max_retries,omitempty" json:"container_registry_import_max_retries,omitempty"` + ContainerRegistryImportMaxStepDuration *int `url:"container_registry_import_max_step_duration,omitempty" json:"container_registry_import_max_step_duration,omitempty"` + ContainerRegistryImportMaxTagsCount *int `url:"container_registry_import_max_tags_count,omitempty" json:"container_registry_import_max_tags_count,omitempty"` + ContainerRegistryImportStartMaxRetries *int `url:"container_registry_import_start_max_retries,omitempty" json:"container_registry_import_start_max_retries,omitempty"` + ContainerRegistryImportTargetPlan *string `url:"container_registry_import_target_plan,omitempty" json:"container_registry_import_target_plan,omitempty"` + ContainerRegistryTokenExpireDelay *int `url:"container_registry_token_expire_delay,omitempty" json:"container_registry_token_expire_delay,omitempty"` + CustomHTTPCloneURLRoot *string `url:"custom_http_clone_url_root,omitempty" json:"custom_http_clone_url_root,omitempty"` + DNSRebindingProtectionEnabled *bool `url:"dns_rebinding_protection_enabled,omitempty" json:"dns_rebinding_protection_enabled,omitempty"` + DSAKeyRestriction *int `url:"dsa_key_restriction,omitempty" json:"dsa_key_restriction,omitempty"` + DeactivateDormantUsers *bool `url:"deactivate_dormant_users,omitempty" json:"deactivate_dormant_users,omitempty"` + DeactivateDormantUsersPeriod *int `url:"deactivate_dormant_users_period,omitempty" json:"deactivate_dormant_users_period,omitempty"` + DecompressArchiveFileTimeout *int `url:"decompress_archive_file_timeout,omitempty" json:"decompress_archive_file_timeout,omitempty"` + DefaultArtifactsExpireIn *string `url:"default_artifacts_expire_in,omitempty" json:"default_artifacts_expire_in,omitempty"` + DefaultBranchName *string `url:"default_branch_name,omitempty" json:"default_branch_name,omitempty"` + DefaultBranchProtectionDefaults *DefaultBranchProtectionDefaultsOptions `url:"default_branch_protection_defaults,omitempty" json:"default_branch_protection_defaults,omitempty"` + DefaultCiConfigPath *string `url:"default_ci_config_path,omitempty" json:"default_ci_config_path,omitempty"` + DefaultGroupVisibility *VisibilityValue `url:"default_group_visibility,omitempty" json:"default_group_visibility,omitempty"` + DefaultPreferredLanguage *string `url:"default_preferred_language,omitempty" json:"default_preferred_language,omitempty"` + DefaultProjectCreation *int `url:"default_project_creation,omitempty" json:"default_project_creation,omitempty"` + DefaultProjectDeletionProtection *bool `url:"default_project_deletion_protection,omitempty" json:"default_project_deletion_protection,omitempty"` + DefaultProjectVisibility *VisibilityValue `url:"default_project_visibility,omitempty" json:"default_project_visibility,omitempty"` + DefaultProjectsLimit *int `url:"default_projects_limit,omitempty" json:"default_projects_limit,omitempty"` + DefaultSnippetVisibility *VisibilityValue `url:"default_snippet_visibility,omitempty" json:"default_snippet_visibility,omitempty"` + DefaultSyntaxHighlightingTheme *int `url:"default_syntax_highlighting_theme,omitempty" json:"default_syntax_highlighting_theme,omitempty"` + DelayedGroupDeletion *bool `url:"delayed_group_deletion,omitempty" json:"delayed_group_deletion,omitempty"` + DelayedProjectDeletion *bool `url:"delayed_project_deletion,omitempty" json:"delayed_project_deletion,omitempty"` + DeleteInactiveProjects *bool `url:"delete_inactive_projects,omitempty" json:"delete_inactive_projects,omitempty"` + DeleteUnconfirmedUsers *bool `url:"delete_unconfirmed_users,omitempty" json:"delete_unconfirmed_users,omitempty"` + DeletionAdjournedPeriod *int `url:"deletion_adjourned_period,omitempty" json:"deletion_adjourned_period,omitempty"` + DiagramsnetEnabled *bool `url:"diagramsnet_enabled,omitempty" json:"diagramsnet_enabled,omitempty"` + DiagramsnetURL *string `url:"diagramsnet_url,omitempty" json:"diagramsnet_url,omitempty"` + DiffMaxFiles *int `url:"diff_max_files,omitempty" json:"diff_max_files,omitempty"` + DiffMaxLines *int `url:"diff_max_lines,omitempty" json:"diff_max_lines,omitempty"` + DiffMaxPatchBytes *int `url:"diff_max_patch_bytes,omitempty" json:"diff_max_patch_bytes,omitempty"` + DisableFeedToken *bool `url:"disable_feed_token,omitempty" json:"disable_feed_token,omitempty"` + DisableAdminOAuthScopes *bool `url:"disable_admin_oauth_scopes,omitempty" json:"disable_admin_oauth_scopes,omitempty"` + DisableOverridingApproversPerMergeRequest *bool `url:"disable_overriding_approvers_per_merge_request,omitempty" json:"disable_overriding_approvers_per_merge_request,omitempty"` + DisablePersonalAccessTokens *bool `url:"disable_personal_access_tokens,omitempty" json:"disable_personal_access_tokens,omitempty"` + DisabledOauthSignInSources *[]string `url:"disabled_oauth_sign_in_sources,omitempty" json:"disabled_oauth_sign_in_sources,omitempty"` + DomainAllowlist *[]string `url:"domain_allowlist,omitempty" json:"domain_allowlist,omitempty"` + DomainDenylist *[]string `url:"domain_denylist,omitempty" json:"domain_denylist,omitempty"` + DomainDenylistEnabled *bool `url:"domain_denylist_enabled,omitempty" json:"domain_denylist_enabled,omitempty"` + DownstreamPipelineTriggerLimitPerProjectUserSHA *int `url:"downstream_pipeline_trigger_limit_per_project_user_sha,omitempty" json:"downstream_pipeline_trigger_limit_per_project_user_sha,omitempty"` + DuoFeaturesEnabled *bool `url:"duo_features_enabled,omitempty" json:"duo_features_enabled,omitempty"` + ECDSAKeyRestriction *int `url:"ecdsa_key_restriction,omitempty" json:"ecdsa_key_restriction,omitempty"` + ECDSASKKeyRestriction *int `url:"ecdsa_sk_key_restriction,omitempty" json:"ecdsa_sk_key_restriction,omitempty"` + EKSAccessKeyID *string `url:"eks_access_key_id,omitempty" json:"eks_access_key_id,omitempty"` + EKSAccountID *string `url:"eks_account_id,omitempty" json:"eks_account_id,omitempty"` + EKSIntegrationEnabled *bool `url:"eks_integration_enabled,omitempty" json:"eks_integration_enabled,omitempty"` + EKSSecretAccessKey *string `url:"eks_secret_access_key,omitempty" json:"eks_secret_access_key,omitempty"` + Ed25519KeyRestriction *int `url:"ed25519_key_restriction,omitempty" json:"ed25519_key_restriction,omitempty"` + Ed25519SKKeyRestriction *int `url:"ed25519_sk_key_restriction,omitempty" json:"ed25519_sk_key_restriction,omitempty"` + ElasticsearchAWS *bool `url:"elasticsearch_aws,omitempty" json:"elasticsearch_aws,omitempty"` + ElasticsearchAWSAccessKey *string `url:"elasticsearch_aws_access_key,omitempty" json:"elasticsearch_aws_access_key,omitempty"` + ElasticsearchAWSRegion *string `url:"elasticsearch_aws_region,omitempty" json:"elasticsearch_aws_region,omitempty"` + ElasticsearchAWSSecretAccessKey *string `url:"elasticsearch_aws_secret_access_key,omitempty" json:"elasticsearch_aws_secret_access_key,omitempty"` + ElasticsearchAnalyzersKuromojiEnabled *bool `url:"elasticsearch_analyzers_kuromoji_enabled,omitempty" json:"elasticsearch_analyzers_kuromoji_enabled,omitempty"` + ElasticsearchAnalyzersKuromojiSearch *int `url:"elasticsearch_analyzers_kuromoji_search,omitempty" json:"elasticsearch_analyzers_kuromoji_search,omitempty"` + ElasticsearchAnalyzersSmartCNEnabled *bool `url:"elasticsearch_analyzers_smartcn_enabled,omitempty" json:"elasticsearch_analyzers_smartcn_enabled,omitempty"` + ElasticsearchAnalyzersSmartCNSearch *int `url:"elasticsearch_analyzers_smartcn_search,omitempty" json:"elasticsearch_analyzers_smartcn_search,omitempty"` + ElasticsearchClientRequestTimeout *int `url:"elasticsearch_client_request_timeout,omitempty" json:"elasticsearch_client_request_timeout,omitempty"` + ElasticsearchIndexedFieldLengthLimit *int `url:"elasticsearch_indexed_field_length_limit,omitempty" json:"elasticsearch_indexed_field_length_limit,omitempty"` + ElasticsearchIndexedFileSizeLimitKB *int `url:"elasticsearch_indexed_file_size_limit_kb,omitempty" json:"elasticsearch_indexed_file_size_limit_kb,omitempty"` + ElasticsearchIndexing *bool `url:"elasticsearch_indexing,omitempty" json:"elasticsearch_indexing,omitempty"` + ElasticsearchLimitIndexing *bool `url:"elasticsearch_limit_indexing,omitempty" json:"elasticsearch_limit_indexing,omitempty"` + ElasticsearchMaxBulkConcurrency *int `url:"elasticsearch_max_bulk_concurrency,omitempty" json:"elasticsearch_max_bulk_concurrency,omitempty"` + ElasticsearchMaxBulkSizeMB *int `url:"elasticsearch_max_bulk_size_mb,omitempty" json:"elasticsearch_max_bulk_size_mb,omitempty"` + ElasticsearchMaxCodeIndexingConcurrency *int `url:"elasticsearch_max_code_indexing_concurrency,omitempty" json:"elasticsearch_max_code_indexing_concurrency,omitempty"` + ElasticsearchNamespaceIDs *[]int `url:"elasticsearch_namespace_ids,omitempty" json:"elasticsearch_namespace_ids,omitempty"` + ElasticsearchPassword *string `url:"elasticsearch_password,omitempty" json:"elasticsearch_password,omitempty"` + ElasticsearchPauseIndexing *bool `url:"elasticsearch_pause_indexing,omitempty" json:"elasticsearch_pause_indexing,omitempty"` + ElasticsearchProjectIDs *[]int `url:"elasticsearch_project_ids,omitempty" json:"elasticsearch_project_ids,omitempty"` + ElasticsearchReplicas *int `url:"elasticsearch_replicas,omitempty" json:"elasticsearch_replicas,omitempty"` + ElasticsearchRequeueWorkers *bool `url:"elasticsearch_requeue_workers,omitempty" json:"elasticsearch_requeue_workers,omitempty"` + ElasticsearchRetryOnFailure *int `url:"elasticsearch_retry_on_failure,omitempty" json:"elasticsearch_retry_on_failure,omitempty"` + ElasticsearchSearch *bool `url:"elasticsearch_search,omitempty" json:"elasticsearch_search,omitempty"` + ElasticsearchShards *int `url:"elasticsearch_shards,omitempty" json:"elasticsearch_shards,omitempty"` + ElasticsearchURL *string `url:"elasticsearch_url,omitempty" json:"elasticsearch_url,omitempty"` + ElasticsearchUsername *string `url:"elasticsearch_username,omitempty" json:"elasticsearch_username,omitempty"` + ElasticsearchWorkerNumberOfShards *int `url:"elasticsearch_worker_number_of_shards,omitempty" json:"elasticsearch_worker_number_of_shards,omitempty"` + EmailAdditionalText *string `url:"email_additional_text,omitempty" json:"email_additional_text,omitempty"` + EmailAuthorInBody *bool `url:"email_author_in_body,omitempty" json:"email_author_in_body,omitempty"` + EmailConfirmationSetting *string `url:"email_confirmation_setting,omitempty" json:"email_confirmation_setting,omitempty"` + EmailRestrictions *string `url:"email_restrictions,omitempty" json:"email_restrictions,omitempty"` + EmailRestrictionsEnabled *bool `url:"email_restrictions_enabled,omitempty" json:"email_restrictions_enabled,omitempty"` + EnableArtifactExternalRedirectWarningPage *bool `url:"enable_artifact_external_redirect_warning_page,omitempty" json:"enable_artifact_external_redirect_warning_page,omitempty"` + EnabledGitAccessProtocol *string `url:"enabled_git_access_protocol,omitempty" json:"enabled_git_access_protocol,omitempty"` + EnforceCIInboundJobTokenScopeEnabled *bool `url:"enforce_ci_inbound_job_token_scope_enabled,omitempty" json:"enforce_ci_inbound_job_token_scope_enabled,omitempty"` + EnforceNamespaceStorageLimit *bool `url:"enforce_namespace_storage_limit,omitempty" json:"enforce_namespace_storage_limit,omitempty"` + EnforcePATExpiration *bool `url:"enforce_pat_expiration,omitempty" json:"enforce_pat_expiration,omitempty"` + EnforceSSHKeyExpiration *bool `url:"enforce_ssh_key_expiration,omitempty" json:"enforce_ssh_key_expiration,omitempty"` + EnforceTerms *bool `url:"enforce_terms,omitempty" json:"enforce_terms,omitempty"` + ExternalAuthClientCert *string `url:"external_auth_client_cert,omitempty" json:"external_auth_client_cert,omitempty"` + ExternalAuthClientKey *string `url:"external_auth_client_key,omitempty" json:"external_auth_client_key,omitempty"` + ExternalAuthClientKeyPass *string `url:"external_auth_client_key_pass,omitempty" json:"external_auth_client_key_pass,omitempty"` + ExternalAuthorizationServiceDefaultLabel *string `url:"external_authorization_service_default_label,omitempty" json:"external_authorization_service_default_label,omitempty"` + ExternalAuthorizationServiceEnabled *bool `url:"external_authorization_service_enabled,omitempty" json:"external_authorization_service_enabled,omitempty"` + ExternalAuthorizationServiceTimeout *float64 `url:"external_authorization_service_timeout,omitempty" json:"external_authorization_service_timeout,omitempty"` + ExternalAuthorizationServiceURL *string `url:"external_authorization_service_url,omitempty" json:"external_authorization_service_url,omitempty"` + ExternalPipelineValidationServiceTimeout *int `url:"external_pipeline_validation_service_timeout,omitempty" json:"external_pipeline_validation_service_timeout,omitempty"` + ExternalPipelineValidationServiceToken *string `url:"external_pipeline_validation_service_token,omitempty" json:"external_pipeline_validation_service_token,omitempty"` + ExternalPipelineValidationServiceURL *string `url:"external_pipeline_validation_service_url,omitempty" json:"external_pipeline_validation_service_url,omitempty"` + FailedLoginAttemptsUnlockPeriodInMinutes *int `url:"failed_login_attempts_unlock_period_in_minutes,omitempty" json:"failed_login_attempts_unlock_period_in_minutes,omitempty"` + FileTemplateProjectID *int `url:"file_template_project_id,omitempty" json:"file_template_project_id,omitempty"` + FirstDayOfWeek *int `url:"first_day_of_week,omitempty" json:"first_day_of_week,omitempty"` + FlocEnabled *bool `url:"floc_enabled,omitempty" json:"floc_enabled,omitempty"` + GeoNodeAllowedIPs *string `url:"geo_node_allowed_ips,omitempty" json:"geo_node_allowed_ips,omitempty"` + GeoStatusTimeout *int `url:"geo_status_timeout,omitempty" json:"geo_status_timeout,omitempty"` + GitRateLimitUsersAlertlist *[]int `url:"git_rate_limit_users_alertlist,omitempty" json:"git_rate_limit_users_alertlist,omitempty"` + GitTwoFactorSessionExpiry *int `url:"git_two_factor_session_expiry,omitempty" json:"git_two_factor_session_expiry,omitempty"` + GitalyTimeoutDefault *int `url:"gitaly_timeout_default,omitempty" json:"gitaly_timeout_default,omitempty"` + GitalyTimeoutFast *int `url:"gitaly_timeout_fast,omitempty" json:"gitaly_timeout_fast,omitempty"` + GitalyTimeoutMedium *int `url:"gitaly_timeout_medium,omitempty" json:"gitaly_timeout_medium,omitempty"` + GitlabDedicatedInstance *bool `url:"gitlab_dedicated_instance,omitempty" json:"gitlab_dedicated_instance,omitempty"` + GitlabEnvironmentToolkitInstance *bool `url:"gitlab_environment_toolkit_instance,omitempty" json:"gitlab_environment_toolkit_instance,omitempty"` + GitlabShellOperationLimit *int `url:"gitlab_shell_operation_limit,omitempty" json:"gitlab_shell_operation_limit,omitempty"` + GitpodEnabled *bool `url:"gitpod_enabled,omitempty" json:"gitpod_enabled,omitempty"` + GitpodURL *string `url:"gitpod_url,omitempty" json:"gitpod_url,omitempty"` + GitRateLimitUsersAllowlist *[]string `url:"git_rate_limit_users_allowlist,omitempty" json:"git_rate_limit_users_allowlist,omitempty"` + GloballyAllowedIPs *string `url:"globally_allowed_ips,omitempty" json:"globally_allowed_ips,omitempty"` + GrafanaEnabled *bool `url:"grafana_enabled,omitempty" json:"grafana_enabled,omitempty"` + GrafanaURL *string `url:"grafana_url,omitempty" json:"grafana_url,omitempty"` + GravatarEnabled *bool `url:"gravatar_enabled,omitempty" json:"gravatar_enabled,omitempty"` + GroupDownloadExportLimit *int `url:"group_download_export_limit,omitempty" json:"group_download_export_limit,omitempty"` + GroupExportLimit *int `url:"group_export_limit,omitempty" json:"group_export_limit,omitempty"` + GroupImportLimit *int `url:"group_import_limit,omitempty" json:"group_import_limit,omitempty"` + GroupOwnersCanManageDefaultBranchProtection *bool `url:"group_owners_can_manage_default_branch_protection,omitempty" json:"group_owners_can_manage_default_branch_protection,omitempty"` + GroupRunnerTokenExpirationInterval *int `url:"group_runner_token_expiration_interval,omitempty" json:"group_runner_token_expiration_interval,omitempty"` + HTMLEmailsEnabled *bool `url:"html_emails_enabled,omitempty" json:"html_emails_enabled,omitempty"` + HashedStorageEnabled *bool `url:"hashed_storage_enabled,omitempty" json:"hashed_storage_enabled,omitempty"` + HelpPageDocumentationBaseURL *string `url:"help_page_documentation_base_url,omitempty" json:"help_page_documentation_base_url,omitempty"` + HelpPageHideCommercialContent *bool `url:"help_page_hide_commercial_content,omitempty" json:"help_page_hide_commercial_content,omitempty"` + HelpPageSupportURL *string `url:"help_page_support_url,omitempty" json:"help_page_support_url,omitempty"` + HelpPageText *string `url:"help_page_text,omitempty" json:"help_page_text,omitempty"` + HelpText *string `url:"help_text,omitempty" json:"help_text,omitempty"` + HideThirdPartyOffers *bool `url:"hide_third_party_offers,omitempty" json:"hide_third_party_offers,omitempty"` + HomePageURL *string `url:"home_page_url,omitempty" json:"home_page_url,omitempty"` + HousekeepingEnabled *bool `url:"housekeeping_enabled,omitempty" json:"housekeeping_enabled,omitempty"` + HousekeepingOptimizeRepositoryPeriod *int `url:"housekeeping_optimize_repository_period,omitempty" json:"housekeeping_optimize_repository_period,omitempty"` + ImportSources *[]string `url:"import_sources,omitempty" json:"import_sources,omitempty"` + InactiveProjectsDeleteAfterMonths *int `url:"inactive_projects_delete_after_months,omitempty" json:"inactive_projects_delete_after_months,omitempty"` + InactiveProjectsMinSizeMB *int `url:"inactive_projects_min_size_mb,omitempty" json:"inactive_projects_min_size_mb,omitempty"` + InactiveProjectsSendWarningEmailAfterMonths *int `url:"inactive_projects_send_warning_email_after_months,omitempty" json:"inactive_projects_send_warning_email_after_months,omitempty"` + IncludeOptionalMetricsInServicePing *bool `url:"include_optional_metrics_in_service_ping,omitempty" json:"include_optional_metrics_in_service_ping,omitempty"` + InProductMarketingEmailsEnabled *bool `url:"in_product_marketing_emails_enabled,omitempty" json:"in_product_marketing_emails_enabled,omitempty"` + InvisibleCaptchaEnabled *bool `url:"invisible_captcha_enabled,omitempty" json:"invisible_captcha_enabled,omitempty"` + IssuesCreateLimit *int `url:"issues_create_limit,omitempty" json:"issues_create_limit,omitempty"` + JiraConnectApplicationKey *string `url:"jira_connect_application_key,omitempty" json:"jira_connect_application_key,omitempty"` + JiraConnectPublicKeyStorageEnabled *bool `url:"jira_connect_public_key_storage_enabled,omitempty" json:"jira_connect_public_key_storage_enabled,omitempty"` + JiraConnectProxyURL *string `url:"jira_connect_proxy_url,omitempty" json:"jira_connect_proxy_url,omitempty"` + KeepLatestArtifact *bool `url:"keep_latest_artifact,omitempty" json:"keep_latest_artifact,omitempty"` + KrokiEnabled *bool `url:"kroki_enabled,omitempty" json:"kroki_enabled,omitempty"` + KrokiFormats *map[string]bool `url:"kroki_formats,omitempty" json:"kroki_formats,omitempty"` + KrokiURL *string `url:"kroki_url,omitempty" json:"kroki_url,omitempty"` + LocalMarkdownVersion *int `url:"local_markdown_version,omitempty" json:"local_markdown_version,omitempty"` + LockDuoFeaturesEnabled *bool `url:"lock_duo_features_enabled,omitempty" json:"lock_duo_features_enabled,omitempty"` + LockMembershipsToLDAP *bool `url:"lock_memberships_to_ldap,omitempty" json:"lock_memberships_to_ldap,omitempty"` + LoginRecaptchaProtectionEnabled *bool `url:"login_recaptcha_protection_enabled,omitempty" json:"login_recaptcha_protection_enabled,omitempty"` + MailgunEventsEnabled *bool `url:"mailgun_events_enabled,omitempty" json:"mailgun_events_enabled,omitempty"` + MailgunSigningKey *string `url:"mailgun_signing_key,omitempty" json:"mailgun_signing_key,omitempty"` + MaintenanceMode *bool `url:"maintenance_mode,omitempty" json:"maintenance_mode,omitempty"` + MaintenanceModeMessage *string `url:"maintenance_mode_message,omitempty" json:"maintenance_mode_message,omitempty"` + MavenPackageRequestsForwarding *bool `url:"maven_package_requests_forwarding,omitempty" json:"maven_package_requests_forwarding,omitempty"` + MaxArtifactsSize *int `url:"max_artifacts_size,omitempty" json:"max_artifacts_size,omitempty"` + MaxAttachmentSize *int `url:"max_attachment_size,omitempty" json:"max_attachment_size,omitempty"` + MaxDecompressedArchiveSize *int `url:"max_decompressed_archive_size,omitempty" json:"max_decompressed_archive_size,omitempty"` + MaxExportSize *int `url:"max_export_size,omitempty" json:"max_export_size,omitempty"` + MaxImportRemoteFileSize *int `url:"max_import_remote_file_size,omitempty" json:"max_import_remote_file_size,omitempty"` + MaxImportSize *int `url:"max_import_size,omitempty" json:"max_import_size,omitempty"` + MaxLoginAttempts *int `url:"max_login_attempts,omitempty" json:"max_login_attempts,omitempty"` + MaxNumberOfRepositoryDownloads *int `url:"max_number_of_repository_downloads,omitempty" json:"max_number_of_repository_downloads,omitempty"` + MaxNumberOfRepositoryDownloadsWithinTimePeriod *int `url:"max_number_of_repository_downloads_within_time_period,omitempty" json:"max_number_of_repository_downloads_within_time_period,omitempty"` + MaxPagesSize *int `url:"max_pages_size,omitempty" json:"max_pages_size,omitempty"` + MaxPersonalAccessTokenLifetime *int `url:"max_personal_access_token_lifetime,omitempty" json:"max_personal_access_token_lifetime,omitempty"` + MaxSSHKeyLifetime *int `url:"max_ssh_key_lifetime,omitempty" json:"max_ssh_key_lifetime,omitempty"` + MaxTerraformStateSizeBytes *int `url:"max_terraform_state_size_bytes,omitempty" json:"max_terraform_state_size_bytes,omitempty"` + MaxYAMLDepth *int `url:"max_yaml_depth,omitempty" json:"max_yaml_depth,omitempty"` + MaxYAMLSizeBytes *int `url:"max_yaml_size_bytes,omitempty" json:"max_yaml_size_bytes,omitempty"` + MetricsMethodCallThreshold *int `url:"metrics_method_call_threshold,omitempty" json:"metrics_method_call_threshold,omitempty"` + MinimumPasswordLength *int `url:"minimum_password_length,omitempty" json:"minimum_password_length,omitempty"` + MirrorAvailable *bool `url:"mirror_available,omitempty" json:"mirror_available,omitempty"` + MirrorCapacityThreshold *int `url:"mirror_capacity_threshold,omitempty" json:"mirror_capacity_threshold,omitempty"` + MirrorMaxCapacity *int `url:"mirror_max_capacity,omitempty" json:"mirror_max_capacity,omitempty"` + MirrorMaxDelay *int `url:"mirror_max_delay,omitempty" json:"mirror_max_delay,omitempty"` + NPMPackageRequestsForwarding *bool `url:"npm_package_requests_forwarding,omitempty" json:"npm_package_requests_forwarding,omitempty"` + NotesCreateLimit *int `url:"notes_create_limit,omitempty" json:"notes_create_limit,omitempty"` + NotifyOnUnknownSignIn *bool `url:"notify_on_unknown_sign_in,omitempty" json:"notify_on_unknown_sign_in,omitempty"` + NugetSkipMetadataURLValidation *bool `url:"nuget_skip_metadata_url_validation,omitempty" json:"nuget_skip_metadata_url_validation,omitempty"` + OutboundLocalRequestsAllowlistRaw *string `url:"outbound_local_requests_allowlist_raw,omitempty" json:"outbound_local_requests_allowlist_raw,omitempty"` + OutboundLocalRequestsWhitelist *[]string `url:"outbound_local_requests_whitelist,omitempty" json:"outbound_local_requests_whitelist,omitempty"` + PackageMetadataPURLTypes *[]int `url:"package_metadata_purl_types,omitempty" json:"package_metadata_purl_types,omitempty"` + PackageRegistryAllowAnyoneToPullOption *bool `url:"package_registry_allow_anyone_to_pull_option,omitempty" json:"package_registry_allow_anyone_to_pull_option,omitempty"` + PackageRegistryCleanupPoliciesWorkerCapacity *int `url:"package_registry_cleanup_policies_worker_capacity,omitempty" json:"package_registry_cleanup_policies_worker_capacity,omitempty"` + PagesDomainVerificationEnabled *bool `url:"pages_domain_verification_enabled,omitempty" json:"pages_domain_verification_enabled,omitempty"` + PasswordAuthenticationEnabledForGit *bool `url:"password_authentication_enabled_for_git,omitempty" json:"password_authentication_enabled_for_git,omitempty"` + PasswordAuthenticationEnabledForWeb *bool `url:"password_authentication_enabled_for_web,omitempty" json:"password_authentication_enabled_for_web,omitempty"` + PasswordNumberRequired *bool `url:"password_number_required,omitempty" json:"password_number_required,omitempty"` + PasswordSymbolRequired *bool `url:"password_symbol_required,omitempty" json:"password_symbol_required,omitempty"` + PasswordUppercaseRequired *bool `url:"password_uppercase_required,omitempty" json:"password_uppercase_required,omitempty"` + PasswordLowercaseRequired *bool `url:"password_lowercase_required,omitempty" json:"password_lowercase_required,omitempty"` + PerformanceBarAllowedGroupPath *string `url:"performance_bar_allowed_group_path,omitempty" json:"performance_bar_allowed_group_path,omitempty"` + PersonalAccessTokenPrefix *string `url:"personal_access_token_prefix,omitempty" json:"personal_access_token_prefix,omitempty"` + PlantumlEnabled *bool `url:"plantuml_enabled,omitempty" json:"plantuml_enabled,omitempty"` + PlantumlURL *string `url:"plantuml_url,omitempty" json:"plantuml_url,omitempty"` + PipelineLimitPerProjectUserSha *int `url:"pipeline_limit_per_project_user_sha,omitempty" json:"pipeline_limit_per_project_user_sha,omitempty"` + PollingIntervalMultiplier *float64 `url:"polling_interval_multiplier,omitempty" json:"polling_interval_multiplier,omitempty"` + PreventMergeRequestsAuthorApproval *bool `url:"prevent_merge_requests_author_approval,omitempty" json:"prevent_merge_requests_author_approval,omitempty"` + PreventMergeRequestsCommittersApproval *bool `url:"prevent_merge_requests_committers_approval,omitempty" json:"prevent_merge_requests_committers_approval,omitempty"` + ProjectDownloadExportLimit *int `url:"project_download_export_limit,omitempty" json:"project_download_export_limit,omitempty"` + ProjectExportEnabled *bool `url:"project_export_enabled,omitempty" json:"project_export_enabled,omitempty"` + ProjectExportLimit *int `url:"project_export_limit,omitempty" json:"project_export_limit,omitempty"` + ProjectImportLimit *int `url:"project_import_limit,omitempty" json:"project_import_limit,omitempty"` + ProjectJobsAPIRateLimit *int `url:"project_jobs_api_rate_limit,omitempty" json:"project_jobs_api_rate_limit,omitempty"` + ProjectRunnerTokenExpirationInterval *int `url:"project_runner_token_expiration_interval,omitempty" json:"project_runner_token_expiration_interval,omitempty"` + ProjectsAPIRateLimitUnauthenticated *int `url:"projects_api_rate_limit_unauthenticated,omitempty" json:"projects_api_rate_limit_unauthenticated,omitempty"` + PrometheusMetricsEnabled *bool `url:"prometheus_metrics_enabled,omitempty" json:"prometheus_metrics_enabled,omitempty"` + ProtectedCIVariables *bool `url:"protected_ci_variables,omitempty" json:"protected_ci_variables,omitempty"` + PseudonymizerEnabled *bool `url:"pseudonymizer_enabled,omitempty" json:"pseudonymizer_enabled,omitempty"` + PushEventActivitiesLimit *int `url:"push_event_activities_limit,omitempty" json:"push_event_activities_limit,omitempty"` + PushEventHooksLimit *int `url:"push_event_hooks_limit,omitempty" json:"push_event_hooks_limit,omitempty"` + PyPIPackageRequestsForwarding *bool `url:"pypi_package_requests_forwarding,omitempty" json:"pypi_package_requests_forwarding,omitempty"` + RSAKeyRestriction *int `url:"rsa_key_restriction,omitempty" json:"rsa_key_restriction,omitempty"` + RateLimitingResponseText *string `url:"rate_limiting_response_text,omitempty" json:"rate_limiting_response_text,omitempty"` + RawBlobRequestLimit *int `url:"raw_blob_request_limit,omitempty" json:"raw_blob_request_limit,omitempty"` + RecaptchaEnabled *bool `url:"recaptcha_enabled,omitempty" json:"recaptcha_enabled,omitempty"` + RecaptchaPrivateKey *string `url:"recaptcha_private_key,omitempty" json:"recaptcha_private_key,omitempty"` + RecaptchaSiteKey *string `url:"recaptcha_site_key,omitempty" json:"recaptcha_site_key,omitempty"` + ReceiveMaxInputSize *int `url:"receive_max_input_size,omitempty" json:"receive_max_input_size,omitempty"` + ReceptiveClusterAgentsEnabled *bool `url:"receptive_cluster_agents_enabled,omitempty" json:"receptive_cluster_agents_enabled,omitempty"` + RememberMeEnabled *bool `url:"remember_me_enabled,omitempty" json:"remember_me_enabled,omitempty"` + RepositoryChecksEnabled *bool `url:"repository_checks_enabled,omitempty" json:"repository_checks_enabled,omitempty"` + RepositorySizeLimit *int `url:"repository_size_limit,omitempty" json:"repository_size_limit,omitempty"` + RepositoryStorages *[]string `url:"repository_storages,omitempty" json:"repository_storages,omitempty"` + RepositoryStoragesWeighted *map[string]int `url:"repository_storages_weighted,omitempty" json:"repository_storages_weighted,omitempty"` + RequireAdminApprovalAfterUserSignup *bool `url:"require_admin_approval_after_user_signup,omitempty" json:"require_admin_approval_after_user_signup,omitempty"` + RequireAdminTwoFactorAuthentication *bool `url:"require_admin_two_factor_authentication,omitempty" json:"require_admin_two_factor_authentication,omitempty"` + RequirePersonalAccessTokenExpiry *bool `url:"require_personal_access_token_expiry,omitempty" json:"require_personal_access_token_expiry,omitempty"` + RequireTwoFactorAuthentication *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"` + RestrictedVisibilityLevels *[]VisibilityValue `url:"restricted_visibility_levels,omitempty" json:"restricted_visibility_levels,omitempty"` + RunnerTokenExpirationInterval *int `url:"runner_token_expiration_interval,omitempty" json:"runner_token_expiration_interval,omitempty"` + SearchRateLimit *int `url:"search_rate_limit,omitempty" json:"search_rate_limit,omitempty"` + SearchRateLimitUnauthenticated *int `url:"search_rate_limit_unauthenticated,omitempty" json:"search_rate_limit_unauthenticated,omitempty"` + SecretDetectionRevocationTokenTypesURL *string `url:"secret_detection_revocation_token_types_url,omitempty" json:"secret_detection_revocation_token_types_url,omitempty"` + SecretDetectionTokenRevocationEnabled *bool `url:"secret_detection_token_revocation_enabled,omitempty" json:"secret_detection_token_revocation_enabled,omitempty"` + SecretDetectionTokenRevocationToken *string `url:"secret_detection_token_revocation_token,omitempty" json:"secret_detection_token_revocation_token,omitempty"` + SecretDetectionTokenRevocationURL *string `url:"secret_detection_token_revocation_url,omitempty" json:"secret_detection_token_revocation_url,omitempty"` + SecurityApprovalPoliciesLimit *int `url:"security_approval_policies_limit,omitempty" json:"security_approval_policies_limit,omitempty"` + SecurityPolicyGlobalGroupApproversEnabled *bool `url:"security_policy_global_group_approvers_enabled,omitempty" json:"security_policy_global_group_approvers_enabled,omitempty"` + SecurityTXTContent *string `url:"security_txt_content,omitempty" json:"security_txt_content,omitempty"` + SendUserConfirmationEmail *bool `url:"send_user_confirmation_email,omitempty" json:"send_user_confirmation_email,omitempty"` + SentryClientsideDSN *string `url:"sentry_clientside_dsn,omitempty" json:"sentry_clientside_dsn,omitempty"` + SentryDSN *string `url:"sentry_dsn,omitempty" json:"sentry_dsn,omitempty"` + SentryEnabled *string `url:"sentry_enabled,omitempty" json:"sentry_enabled,omitempty"` + SentryEnvironment *string `url:"sentry_environment,omitempty" json:"sentry_environment,omitempty"` + ServiceAccessTokensExpirationEnforced *bool `url:"service_access_tokens_expiration_enforced,omitempty" json:"service_access_tokens_expiration_enforced,omitempty"` + SessionExpireDelay *int `url:"session_expire_delay,omitempty" json:"session_expire_delay,omitempty"` + SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"` + SharedRunnersMinutes *int `url:"shared_runners_minutes,omitempty" json:"shared_runners_minutes,omitempty"` + SharedRunnersText *string `url:"shared_runners_text,omitempty" json:"shared_runners_text,omitempty"` + SidekiqJobLimiterCompressionThresholdBytes *int `url:"sidekiq_job_limiter_compression_threshold_bytes,omitempty" json:"sidekiq_job_limiter_compression_threshold_bytes,omitempty"` + SidekiqJobLimiterLimitBytes *int `url:"sidekiq_job_limiter_limit_bytes,omitempty" json:"sidekiq_job_limiter_limit_bytes,omitempty"` + SidekiqJobLimiterMode *string `url:"sidekiq_job_limiter_mode,omitempty" json:"sidekiq_job_limiter_mode,omitempty"` + SignInText *string `url:"sign_in_text,omitempty" json:"sign_in_text,omitempty"` + SignupEnabled *bool `url:"signup_enabled,omitempty" json:"signup_enabled,omitempty"` + SilentAdminExportsEnabled *bool `url:"silent_admin_exports_enabled,omitempty" json:"silent_admin_exports_enabled,omitempty"` + SilentModeEnabled *bool `url:"silent_mode_enabled,omitempty" json:"silent_mode_enabled,omitempty"` + SlackAppEnabled *bool `url:"slack_app_enabled,omitempty" json:"slack_app_enabled,omitempty"` + SlackAppID *string `url:"slack_app_id,omitempty" json:"slack_app_id,omitempty"` + SlackAppSecret *string `url:"slack_app_secret,omitempty" json:"slack_app_secret,omitempty"` + SlackAppSigningSecret *string `url:"slack_app_signing_secret,omitempty" json:"slack_app_signing_secret,omitempty"` + SlackAppVerificationToken *string `url:"slack_app_verification_token,omitempty" json:"slack_app_verification_token,omitempty"` + SnippetSizeLimit *int `url:"snippet_size_limit,omitempty" json:"snippet_size_limit,omitempty"` + SnowplowAppID *string `url:"snowplow_app_id,omitempty" json:"snowplow_app_id,omitempty"` + SnowplowCollectorHostname *string `url:"snowplow_collector_hostname,omitempty" json:"snowplow_collector_hostname,omitempty"` + SnowplowCookieDomain *string `url:"snowplow_cookie_domain,omitempty" json:"snowplow_cookie_domain,omitempty"` + SnowplowDatabaseCollectorHostname *string `url:"snowplow_database_collector_hostname,omitempty" json:"snowplow_database_collector_hostname,omitempty"` + SnowplowEnabled *bool `url:"snowplow_enabled,omitempty" json:"snowplow_enabled,omitempty"` + SourcegraphEnabled *bool `url:"sourcegraph_enabled,omitempty" json:"sourcegraph_enabled,omitempty"` + SourcegraphPublicOnly *bool `url:"sourcegraph_public_only,omitempty" json:"sourcegraph_public_only,omitempty"` + SourcegraphURL *string `url:"sourcegraph_url,omitempty" json:"sourcegraph_url,omitempty"` + SpamCheckAPIKey *string `url:"spam_check_api_key,omitempty" json:"spam_check_api_key,omitempty"` + SpamCheckEndpointEnabled *bool `url:"spam_check_endpoint_enabled,omitempty" json:"spam_check_endpoint_enabled,omitempty"` + SpamCheckEndpointURL *string `url:"spam_check_endpoint_url,omitempty" json:"spam_check_endpoint_url,omitempty"` + StaticObjectsExternalStorageAuthToken *string `url:"static_objects_external_storage_auth_token,omitempty" json:"static_objects_external_storage_auth_token,omitempty"` + StaticObjectsExternalStorageURL *string `url:"static_objects_external_storage_url,omitempty" json:"static_objects_external_storage_url,omitempty"` + SuggestPipelineEnabled *bool `url:"suggest_pipeline_enabled,omitempty" json:"suggest_pipeline_enabled,omitempty"` + TerminalMaxSessionTime *int `url:"terminal_max_session_time,omitempty" json:"terminal_max_session_time,omitempty"` + Terms *string `url:"terms,omitempty" json:"terms,omitempty"` + ThrottleAuthenticatedAPIEnabled *bool `url:"throttle_authenticated_api_enabled,omitempty" json:"throttle_authenticated_api_enabled,omitempty"` + ThrottleAuthenticatedAPIPeriodInSeconds *int `url:"throttle_authenticated_api_period_in_seconds,omitempty" json:"throttle_authenticated_api_period_in_seconds,omitempty"` + ThrottleAuthenticatedAPIRequestsPerPeriod *int `url:"throttle_authenticated_api_requests_per_period,omitempty" json:"throttle_authenticated_api_requests_per_period,omitempty"` + ThrottleAuthenticatedDeprecatedAPIEnabled *bool `url:"throttle_authenticated_deprecated_api_enabled,omitempty" json:"throttle_authenticated_deprecated_api_enabled,omitempty"` + ThrottleAuthenticatedDeprecatedAPIPeriodInSeconds *int `url:"throttle_authenticated_deprecated_api_period_in_seconds,omitempty" json:"throttle_authenticated_deprecated_api_period_in_seconds,omitempty"` + ThrottleAuthenticatedDeprecatedAPIRequestsPerPeriod *int `url:"throttle_authenticated_deprecated_api_requests_per_period,omitempty" json:"throttle_authenticated_deprecated_api_requests_per_period,omitempty"` + ThrottleAuthenticatedFilesAPIEnabled *bool `url:"throttle_authenticated_files_api_enabled,omitempty" json:"throttle_authenticated_files_api_enabled,omitempty"` + ThrottleAuthenticatedFilesAPIPeriodInSeconds *int `url:"throttle_authenticated_files_api_period_in_seconds,omitempty" json:"throttle_authenticated_files_api_period_in_seconds,omitempty"` + ThrottleAuthenticatedFilesAPIRequestsPerPeriod *int `url:"throttle_authenticated_files_api_requests_per_period,omitempty" json:"throttle_authenticated_files_api_requests_per_period,omitempty"` + ThrottleAuthenticatedGitLFSEnabled *bool `url:"throttle_authenticated_git_lfs_enabled,omitempty" json:"throttle_authenticated_git_lfs_enabled,omitempty"` + ThrottleAuthenticatedGitLFSPeriodInSeconds *int `url:"throttle_authenticated_git_lfs_period_in_seconds,omitempty" json:"throttle_authenticated_git_lfs_period_in_seconds,omitempty"` + ThrottleAuthenticatedGitLFSRequestsPerPeriod *int `url:"throttle_authenticated_git_lfs_requests_per_period,omitempty" json:"throttle_authenticated_git_lfs_requests_per_period,omitempty"` + ThrottleAuthenticatedPackagesAPIEnabled *bool `url:"throttle_authenticated_packages_api_enabled,omitempty" json:"throttle_authenticated_packages_api_enabled,omitempty"` + ThrottleAuthenticatedPackagesAPIPeriodInSeconds *int `url:"throttle_authenticated_packages_api_period_in_seconds,omitempty" json:"throttle_authenticated_packages_api_period_in_seconds,omitempty"` + ThrottleAuthenticatedPackagesAPIRequestsPerPeriod *int `url:"throttle_authenticated_packages_api_requests_per_period,omitempty" json:"throttle_authenticated_packages_api_requests_per_period,omitempty"` + ThrottleAuthenticatedWebEnabled *bool `url:"throttle_authenticated_web_enabled,omitempty" json:"throttle_authenticated_web_enabled,omitempty"` + ThrottleAuthenticatedWebPeriodInSeconds *int `url:"throttle_authenticated_web_period_in_seconds,omitempty" json:"throttle_authenticated_web_period_in_seconds,omitempty"` + ThrottleAuthenticatedWebRequestsPerPeriod *int `url:"throttle_authenticated_web_requests_per_period,omitempty" json:"throttle_authenticated_web_requests_per_period,omitempty"` + ThrottleIncidentManagementNotificationEnabled *bool `url:"throttle_incident_management_notification_enabled,omitempty" json:"throttle_incident_management_notification_enabled,omitempty"` + ThrottleIncidentManagementNotificationPerPeriod *int `url:"throttle_incident_management_notification_per_period,omitempty" json:"throttle_incident_management_notification_per_period,omitempty"` + ThrottleIncidentManagementNotificationPeriodInSeconds *int `url:"throttle_incident_management_notification_period_in_seconds,omitempty" json:"throttle_incident_management_notification_period_in_seconds,omitempty"` + ThrottleProtectedPathsEnabled *bool `url:"throttle_protected_paths_enabled_enabled,omitempty" json:"throttle_protected_paths_enabled,omitempty"` + ThrottleProtectedPathsPeriodInSeconds *int `url:"throttle_protected_paths_enabled_period_in_seconds,omitempty" json:"throttle_protected_paths_period_in_seconds,omitempty"` + ThrottleProtectedPathsRequestsPerPeriod *int `url:"throttle_protected_paths_enabled_requests_per_period,omitempty" json:"throttle_protected_paths_per_period,omitempty"` + ThrottleUnauthenticatedAPIEnabled *bool `url:"throttle_unauthenticated_api_enabled,omitempty" json:"throttle_unauthenticated_api_enabled,omitempty"` + ThrottleUnauthenticatedAPIPeriodInSeconds *int `url:"throttle_unauthenticated_api_period_in_seconds,omitempty" json:"throttle_unauthenticated_api_period_in_seconds,omitempty"` + ThrottleUnauthenticatedAPIRequestsPerPeriod *int `url:"throttle_unauthenticated_api_requests_per_period,omitempty" json:"throttle_unauthenticated_api_requests_per_period,omitempty"` + ThrottleUnauthenticatedDeprecatedAPIEnabled *bool `url:"throttle_unauthenticated_deprecated_api_enabled,omitempty" json:"throttle_unauthenticated_deprecated_api_enabled,omitempty"` + ThrottleUnauthenticatedDeprecatedAPIPeriodInSeconds *int `url:"throttle_unauthenticated_deprecated_api_period_in_seconds,omitempty" json:"throttle_unauthenticated_deprecated_api_period_in_seconds,omitempty"` + ThrottleUnauthenticatedDeprecatedAPIRequestsPerPeriod *int `url:"throttle_unauthenticated_deprecated_api_requests_per_period,omitempty" json:"throttle_unauthenticated_deprecated_api_requests_per_period,omitempty"` + ThrottleUnauthenticatedFilesAPIEnabled *bool `url:"throttle_unauthenticated_files_api_enabled,omitempty" json:"throttle_unauthenticated_files_api_enabled,omitempty"` + ThrottleUnauthenticatedFilesAPIPeriodInSeconds *int `url:"throttle_unauthenticated_files_api_period_in_seconds,omitempty" json:"throttle_unauthenticated_files_api_period_in_seconds,omitempty"` + ThrottleUnauthenticatedFilesAPIRequestsPerPeriod *int `url:"throttle_unauthenticated_files_api_requests_per_period,omitempty" json:"throttle_unauthenticated_files_api_requests_per_period,omitempty"` + ThrottleUnauthenticatedGitLFSEnabled *bool `url:"throttle_unauthenticated_git_lfs_enabled,omitempty" json:"throttle_unauthenticated_git_lfs_enabled,omitempty"` + ThrottleUnauthenticatedGitLFSPeriodInSeconds *int `url:"throttle_unauthenticated_git_lfs_period_in_seconds,omitempty" json:"throttle_unauthenticated_git_lfs_period_in_seconds,omitempty"` + ThrottleUnauthenticatedGitLFSRequestsPerPeriod *int `url:"throttle_unauthenticated_git_lfs_requests_per_period,omitempty" json:"throttle_unauthenticated_git_lfs_requests_per_period,omitempty"` + ThrottleUnauthenticatedPackagesAPIEnabled *bool `url:"throttle_unauthenticated_packages_api_enabled,omitempty" json:"throttle_unauthenticated_packages_api_enabled,omitempty"` + ThrottleUnauthenticatedPackagesAPIPeriodInSeconds *int `url:"throttle_unauthenticated_packages_api_period_in_seconds,omitempty" json:"throttle_unauthenticated_packages_api_period_in_seconds,omitempty"` + ThrottleUnauthenticatedPackagesAPIRequestsPerPeriod *int `url:"throttle_unauthenticated_packages_api_requests_per_period,omitempty" json:"throttle_unauthenticated_packages_api_requests_per_period,omitempty"` + ThrottleUnauthenticatedWebEnabled *bool `url:"throttle_unauthenticated_web_enabled,omitempty" json:"throttle_unauthenticated_web_enabled,omitempty"` + ThrottleUnauthenticatedWebPeriodInSeconds *int `url:"throttle_unauthenticated_web_period_in_seconds,omitempty" json:"throttle_unauthenticated_web_period_in_seconds,omitempty"` + ThrottleUnauthenticatedWebRequestsPerPeriod *int `url:"throttle_unauthenticated_web_requests_per_period,omitempty" json:"throttle_unauthenticated_web_requests_per_period,omitempty"` + TimeTrackingLimitToHours *bool `url:"time_tracking_limit_to_hours,omitempty" json:"time_tracking_limit_to_hours,omitempty"` + TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"` + UnconfirmedUsersDeleteAfterDays *int `url:"unconfirmed_users_delete_after_days,omitempty" json:"unconfirmed_users_delete_after_days,omitempty"` + UniqueIPsLimitEnabled *bool `url:"unique_ips_limit_enabled,omitempty" json:"unique_ips_limit_enabled,omitempty"` + UniqueIPsLimitPerUser *int `url:"unique_ips_limit_per_user,omitempty" json:"unique_ips_limit_per_user,omitempty"` + UniqueIPsLimitTimeWindow *int `url:"unique_ips_limit_time_window,omitempty" json:"unique_ips_limit_time_window,omitempty"` + UpdateRunnerVersionsEnabled *bool `url:"update_runner_versions_enabled,omitempty" json:"update_runner_versions_enabled,omitempty"` + UpdatingNameDisabledForUsers *bool `url:"updating_name_disabled_for_users,omitempty" json:"updating_name_disabled_for_users,omitempty"` + UsagePingEnabled *bool `url:"usage_ping_enabled,omitempty" json:"usage_ping_enabled,omitempty"` + UsagePingFeaturesEnabled *bool `url:"usage_ping_features_enabled,omitempty" json:"usage_ping_features_enabled,omitempty"` + UseClickhouseForAnalytics *bool `url:"use_clickhouse_for_analytics,omitempty" json:"use_clickhouse_for_analytics,omitempty"` + UserDeactivationEmailsEnabled *bool `url:"user_deactivation_emails_enabled,omitempty" json:"user_deactivation_emails_enabled,omitempty"` + UserDefaultExternal *bool `url:"user_default_external,omitempty" json:"user_default_external,omitempty"` + UserDefaultInternalRegex *string `url:"user_default_internal_regex,omitempty" json:"user_default_internal_regex,omitempty"` + UserDefaultsToPrivateProfile *bool `url:"user_defaults_to_private_profile,omitempty" json:"user_defaults_to_private_profile,omitempty"` + UserEmailLookupLimit *int `url:"user_email_lookup_limit,omitempty" json:"user_email_lookup_limit,omitempty"` + UserOauthApplications *bool `url:"user_oauth_applications,omitempty" json:"user_oauth_applications,omitempty"` + UserShowAddSSHKeyMessage *bool `url:"user_show_add_ssh_key_message,omitempty" json:"user_show_add_ssh_key_message,omitempty"` + UsersGetByIDLimit *int `url:"users_get_by_id_limit,omitempty" json:"users_get_by_id_limit,omitempty"` + UsersGetByIDLimitAllowlistRaw *string `url:"users_get_by_id_limit_allowlist_raw,omitempty" json:"users_get_by_id_limit_allowlist_raw,omitempty"` + ValidRunnerRegistrars *[]string `url:"valid_runner_registrars,omitempty" json:"valid_runner_registrars,omitempty"` + VersionCheckEnabled *bool `url:"version_check_enabled,omitempty" json:"version_check_enabled,omitempty"` + WebIDEClientsidePreviewEnabled *bool `url:"web_ide_clientside_preview_enabled,omitempty" json:"web_ide_clientside_preview_enabled,omitempty"` + WhatsNewVariant *string `url:"whats_new_variant,omitempty" json:"whats_new_variant,omitempty"` + WikiPageMaxContentBytes *int `url:"wiki_page_max_content_bytes,omitempty" json:"wiki_page_max_content_bytes,omitempty"` + + // Deprecated: Use AbuseNotificationEmail instead. + AdminNotificationEmail *string `url:"admin_notification_email,omitempty" json:"admin_notification_email,omitempty"` + // Deprecated: Use AllowLocalRequestsFromWebHooksAndServices instead. + AllowLocalRequestsFromHooksAndServices *bool `url:"allow_local_requests_from_hooks_and_services,omitempty" json:"allow_local_requests_from_hooks_and_services,omitempty"` + // Deprecated: Use AssetProxyAllowlist instead. + AssetProxyWhitelist *[]string `url:"asset_proxy_whitelist,omitempty" json:"asset_proxy_whitelist,omitempty"` + // Deprecated: Use DefaultBranchProtectionDefaults instead. + DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"` + // Deprecated: Cannot be set through the API, always true + HousekeepingBitmapsEnabled *bool `url:"housekeeping_bitmaps_enabled,omitempty" json:"housekeeping_bitmaps_enabled,omitempty"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingFullRepackPeriod *int `url:"housekeeping_full_repack_period,omitempty" json:"housekeeping_full_repack_period,omitempty"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingGcPeriod *int `url:"housekeeping_gc_period,omitempty" json:"housekeeping_gc_period,omitempty"` + // Deprecated: use HousekeepingOptimizeRepositoryPeriod instead + HousekeepingIncrementalRepackPeriod *int `url:"housekeeping_incremental_repack_period,omitempty" json:"housekeeping_incremental_repack_period,omitempty"` + // Deprecated: use PerformanceBarAllowedGroupPath instead + PerformanceBarAllowedGroupID *int `url:"performance_bar_allowed_group_id,omitempty" json:"performance_bar_allowed_group_id,omitempty"` + // Deprecated: use PerformanceBarAllowedGroupPath: nil instead + PerformanceBarEnabled *bool `url:"performance_bar_enabled,omitempty" json:"performance_bar_enabled,omitempty"` + // Deprecated: Use ThrottleUnauthenticatedWebEnabled or ThrottleUnauthenticatedAPIEnabled instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedEnabled *bool `url:"throttle_unauthenticated_enabled,omitempty" json:"throttle_unauthenticated_enabled,omitempty"` + // Deprecated: Use ThrottleUnauthenticatedWebPeriodInSeconds or ThrottleUnauthenticatedAPIPeriodInSeconds instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedPeriodInSeconds *int `url:"throttle_unauthenticated_period_in_seconds,omitempty" json:"throttle_unauthenticated_period_in_seconds,omitempty"` + // Deprecated: Use ThrottleUnauthenticatedWebRequestsPerPeriod or ThrottleUnauthenticatedAPIRequestsPerPeriod instead. (Deprecated in GitLab 14.3) + ThrottleUnauthenticatedRequestsPerPeriod *int `url:"throttle_unauthenticated_requests_per_period,omitempty" json:"throttle_unauthenticated_requests_per_period,omitempty"` +} + +// BranchProtectionDefaultsOptions represents default Git protected branch permissions options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-default_branch_protection_defaults +type BranchProtectionDefaultsOptions struct { + AllowedToPush *[]int `url:"allowed_to_push,omitempty" json:"allowed_to_push,omitempty"` + AllowForcePush *bool `url:"allow_force_push,omitempty" json:"allow_force_push,omitempty"` + AllowedToMerge *[]int `url:"allowed_to_merge,omitempty" json:"allowed_to_merge,omitempty"` + DeveloperCanInitialPush *bool `url:"developer_can_initial_push,omitempty" json:"developer_can_initial_push,omitempty"` +} + +// UpdateSettings updates the application settings. +// +// GitLab API docs: +// https://docs.gitlab.com/api/settings/#update-application-settings +func (s *SettingsService) UpdateSettings(opt *UpdateSettingsOptions, options ...RequestOptionFunc) (*Settings, *Response, error) { + req, err := s.client.NewRequest(http.MethodPut, "application/settings", opt, options) + if err != nil { + return nil, nil, err + } + + as := new(Settings) + resp, err := s.client.Do(req, as) + if err != nil { + return nil, resp, err + } + + return as, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/sidekiq_metrics.go b/vendor/gitlab.com/gitlab-org/api/client-go/sidekiq_metrics.go similarity index 63% rename from vendor/github.com/xanzy/go-gitlab/sidekiq_metrics.go rename to vendor/gitlab.com/gitlab-org/api/client-go/sidekiq_metrics.go index 45c205d9a..0a985847f 100644 --- a/vendor/github.com/xanzy/go-gitlab/sidekiq_metrics.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/sidekiq_metrics.go @@ -1,5 +1,5 @@ // -// Copyright 2018, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,19 +16,33 @@ package gitlab -import "time" +import ( + "net/http" + "time" +) + +type ( + SidekiqServiceInterface interface { + GetQueueMetrics(options ...RequestOptionFunc) (*QueueMetrics, *Response, error) + GetProcessMetrics(options ...RequestOptionFunc) (*ProcessMetrics, *Response, error) + GetJobStats(options ...RequestOptionFunc) (*JobStats, *Response, error) + GetCompoundMetrics(options ...RequestOptionFunc) (*CompoundMetrics, *Response, error) + } -// SidekiqService handles communication with the sidekiq service -// -// GitLab API docs: https://docs.gitlab.com/ce/api/sidekiq_metrics.html -type SidekiqService struct { - client *Client -} + // SidekiqService handles communication with the sidekiq service + // + // GitLab API docs: https://docs.gitlab.com/api/sidekiq_metrics/ + SidekiqService struct { + client *Client + } +) + +var _ SidekiqServiceInterface = (*SidekiqService)(nil) // QueueMetrics represents the GitLab sidekiq queue metrics. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-queue-metrics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-queue-metrics type QueueMetrics struct { Queues map[string]struct { Backlog int `json:"backlog"` @@ -40,9 +54,9 @@ type QueueMetrics struct { // their backlog and their latency. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-queue-metrics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-queue-metrics func (s *SidekiqService) GetQueueMetrics(options ...RequestOptionFunc) (*QueueMetrics, *Response, error) { - req, err := s.client.NewRequest("GET", "/sidekiq/queue_metrics", nil, options) + req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/queue_metrics", nil, options) if err != nil { return nil, nil, err } @@ -53,13 +67,13 @@ func (s *SidekiqService) GetQueueMetrics(options ...RequestOptionFunc) (*QueueMe return nil, resp, err } - return q, resp, err + return q, resp, nil } // ProcessMetrics represents the GitLab sidekiq process metrics. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-process-metrics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-process-metrics type ProcessMetrics struct { Processes []struct { Hostname string `json:"hostname"` @@ -77,9 +91,9 @@ type ProcessMetrics struct { // to process your queues. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-process-metrics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-process-metrics func (s *SidekiqService) GetProcessMetrics(options ...RequestOptionFunc) (*ProcessMetrics, *Response, error) { - req, err := s.client.NewRequest("GET", "/sidekiq/process_metrics", nil, options) + req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/process_metrics", nil, options) if err != nil { return nil, nil, err } @@ -90,13 +104,13 @@ func (s *SidekiqService) GetProcessMetrics(options ...RequestOptionFunc) (*Proce return nil, resp, err } - return p, resp, err + return p, resp, nil } // JobStats represents the GitLab sidekiq job stats. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-job-statistics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-job-statistics type JobStats struct { Jobs struct { Processed int `json:"processed"` @@ -108,9 +122,9 @@ type JobStats struct { // GetJobStats list information about the jobs that Sidekiq has performed. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-job-statistics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-the-current-job-statistics func (s *SidekiqService) GetJobStats(options ...RequestOptionFunc) (*JobStats, *Response, error) { - req, err := s.client.NewRequest("GET", "/sidekiq/job_stats", nil, options) + req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/job_stats", nil, options) if err != nil { return nil, nil, err } @@ -121,13 +135,13 @@ func (s *SidekiqService) GetJobStats(options ...RequestOptionFunc) (*JobStats, * return nil, resp, err } - return j, resp, err + return j, resp, nil } // CompoundMetrics represents the GitLab sidekiq compounded stats. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-a-compound-response-of-all-the-previously-mentioned-metrics +// https://docs.gitlab.com/api/sidekiq_metrics/#get-a-compound-response-of-all-the-previously-mentioned-metrics type CompoundMetrics struct { QueueMetrics ProcessMetrics @@ -137,9 +151,10 @@ type CompoundMetrics struct { // GetCompoundMetrics lists all the currently available information about Sidekiq. // Get a compound response of all the previously mentioned metrics // -// GitLab API docs: https://docs.gitlab.com/ce/api/sidekiq_metrics.html#get-the-current-job-statistics +// GitLab API docs: +// https://docs.gitlab.com/api/sidekiq_metrics/#get-a-compound-response-of-all-the-previously-mentioned-metrics func (s *SidekiqService) GetCompoundMetrics(options ...RequestOptionFunc) (*CompoundMetrics, *Response, error) { - req, err := s.client.NewRequest("GET", "/sidekiq/compound_metrics", nil, options) + req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/compound_metrics", nil, options) if err != nil { return nil, nil, err } @@ -150,5 +165,5 @@ func (s *SidekiqService) GetCompoundMetrics(options ...RequestOptionFunc) (*Comp return nil, resp, err } - return c, resp, err + return c, resp, nil } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/snippet_repository_storage_move.go b/vendor/gitlab.com/gitlab-org/api/client-go/snippet_repository_storage_move.go new file mode 100644 index 000000000..b25c3a487 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/snippet_repository_storage_move.go @@ -0,0 +1,217 @@ +// +// Copyright 2023, Nick Westbury +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + SnippetRepositoryStorageMoveServiceInterface interface { + RetrieveAllStorageMoves(opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) + RetrieveAllStorageMovesForSnippet(snippet int, opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) + GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) + GetStorageMoveForSnippet(snippet int, repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) + ScheduleStorageMoveForSnippet(snippet int, opts ScheduleStorageMoveForSnippetOptions, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) + ScheduleAllStorageMoves(opts ScheduleAllSnippetStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) + } + + // SnippetRepositoryStorageMoveService handles communication with the + // snippets related methods of the GitLab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/snippet_repository_storage_moves/ + SnippetRepositoryStorageMoveService struct { + client *Client + } +) + +var _ SnippetRepositoryStorageMoveServiceInterface = (*SnippetRepositoryStorageMoveService)(nil) + +// SnippetRepositoryStorageMove represents the status of a repository move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/ +type SnippetRepositoryStorageMove struct { + ID int `json:"id"` + CreatedAt *time.Time `json:"created_at"` + State string `json:"state"` + SourceStorageName string `json:"source_storage_name"` + DestinationStorageName string `json:"destination_storage_name"` + Snippet *RepositorySnippet `json:"snippet"` +} + +type RepositorySnippet struct { + ID int `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + Visibility VisibilityValue `json:"visibility"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + ProjectID int `json:"project_id"` + WebURL string `json:"web_url"` + RawURL string `json:"raw_url"` + SSHURLToRepo string `json:"ssh_url_to_repo"` + HTTPURLToRepo string `json:"http_url_to_repo"` +} + +// RetrieveAllSnippetStorageMovesOptions represents the available +// RetrieveAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#retrieve-all-snippet-repository-storage-moves +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#retrieve-all-repository-storage-moves-for-a-snippet +type RetrieveAllSnippetStorageMovesOptions ListOptions + +// RetrieveAllStorageMoves retrieves all snippet repository storage moves +// accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#retrieve-all-snippet-repository-storage-moves +func (s SnippetRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "snippet_repository_storage_moves", opts, options) + if err != nil { + return nil, nil, err + } + + var ssms []*SnippetRepositoryStorageMove + resp, err := s.client.Do(req, &ssms) + if err != nil { + return nil, resp, err + } + + return ssms, resp, err +} + +// RetrieveAllStorageMovesForSnippet retrieves all repository storage moves for +// a single snippet accessible by the authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#retrieve-all-repository-storage-moves-for-a-snippet +func (s SnippetRepositoryStorageMoveService) RetrieveAllStorageMovesForSnippet(snippet int, opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("snippets/%d/repository_storage_moves", snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, opts, options) + if err != nil { + return nil, nil, err + } + + var ssms []*SnippetRepositoryStorageMove + resp, err := s.client.Do(req, &ssms) + if err != nil { + return nil, resp, err + } + + return ssms, resp, err +} + +// GetStorageMove gets a single snippet repository storage move. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#get-a-single-snippet-repository-storage-move +func (s SnippetRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("snippet_repository_storage_moves/%d", repositoryStorage) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ssm := new(SnippetRepositoryStorageMove) + resp, err := s.client.Do(req, ssm) + if err != nil { + return nil, resp, err + } + + return ssm, resp, err +} + +// GetStorageMoveForSnippet gets a single repository storage move for a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#get-a-single-repository-storage-move-for-a-snippet +func (s SnippetRepositoryStorageMoveService) GetStorageMoveForSnippet(snippet int, repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("snippets/%d/repository_storage_moves/%d", snippet, repositoryStorage) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ssm := new(SnippetRepositoryStorageMove) + resp, err := s.client.Do(req, ssm) + if err != nil { + return nil, resp, err + } + + return ssm, resp, err +} + +// ScheduleStorageMoveForSnippetOptions represents the available +// ScheduleStorageMoveForSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#schedule-a-repository-storage-move-for-a-snippet +type ScheduleStorageMoveForSnippetOptions struct { + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleStorageMoveForSnippet schedule a repository to be moved for a snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#schedule-a-repository-storage-move-for-a-snippet +func (s SnippetRepositoryStorageMoveService) ScheduleStorageMoveForSnippet(snippet int, opts ScheduleStorageMoveForSnippetOptions, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) { + u := fmt.Sprintf("snippets/%d/repository_storage_moves", snippet) + + req, err := s.client.NewRequest(http.MethodPost, u, opts, options) + if err != nil { + return nil, nil, err + } + + ssm := new(SnippetRepositoryStorageMove) + resp, err := s.client.Do(req, ssm) + if err != nil { + return nil, resp, err + } + + return ssm, resp, err +} + +// ScheduleAllSnippetStorageMovesOptions represents the available +// ScheduleAllStorageMoves() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#schedule-repository-storage-moves-for-all-snippets-on-a-storage-shard +type ScheduleAllSnippetStorageMovesOptions struct { + SourceStorageName *string `url:"source_storage_name,omitempty" json:"source_storage_name,omitempty"` + DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"` +} + +// ScheduleAllStorageMoves schedules all snippet repositories to be moved. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippet_repository_storage_moves/#schedule-repository-storage-moves-for-all-snippets-on-a-storage-shard +func (s SnippetRepositoryStorageMoveService) ScheduleAllStorageMoves(opts ScheduleAllSnippetStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "snippet_repository_storage_moves", opts, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/snippets.go b/vendor/gitlab.com/gitlab-org/api/client-go/snippets.go new file mode 100644 index 000000000..d3bdad822 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/snippets.go @@ -0,0 +1,330 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "fmt" + "net/http" + "time" +) + +type ( + SnippetsServiceInterface interface { + ListSnippets(opt *ListSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) + GetSnippet(snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) + SnippetContent(snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) + SnippetFileContent(snippet int, ref, filename string, options ...RequestOptionFunc) ([]byte, *Response, error) + CreateSnippet(opt *CreateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) + UpdateSnippet(snippet int, opt *UpdateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) + DeleteSnippet(snippet int, options ...RequestOptionFunc) (*Response, error) + ExploreSnippets(opt *ExploreSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) + ListAllSnippets(opt *ListAllSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) + } + + // SnippetsService handles communication with the snippets + // related methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/snippets/ + SnippetsService struct { + client *Client + } +) + +var _ SnippetsServiceInterface = (*SnippetsService)(nil) + +// Snippet represents a GitLab snippet. +// +// GitLab API docs: https://docs.gitlab.com/api/snippets/ +type Snippet struct { + ID int `json:"id"` + Title string `json:"title"` + FileName string `json:"file_name"` + Description string `json:"description"` + Visibility string `json:"visibility"` + Author struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` + } `json:"author"` + UpdatedAt *time.Time `json:"updated_at"` + CreatedAt *time.Time `json:"created_at"` + ProjectID int `json:"project_id"` + WebURL string `json:"web_url"` + RawURL string `json:"raw_url"` + Files []struct { + Path string `json:"path"` + RawURL string `json:"raw_url"` + } `json:"files"` + RepositoryStorage string `json:"repository_storage"` +} + +func (s Snippet) String() string { + return Stringify(s) +} + +// ListSnippetsOptions represents the available ListSnippets() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-snippets-for-current-user +type ListSnippetsOptions ListOptions + +// ListSnippets gets a list of snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-snippets-for-current-user +func (s *SnippetsService) ListSnippets(opt *ListSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "snippets", opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Snippet + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// GetSnippet gets a single snippet +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#get-a-single-snippet +func (s *SnippetsService) GetSnippet(snippet int, options ...RequestOptionFunc) (*Snippet, *Response, error) { + u := fmt.Sprintf("snippets/%d", snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// SnippetContent gets a single snippet’s raw contents. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#single-snippet-contents +func (s *SnippetsService) SnippetContent(snippet int, options ...RequestOptionFunc) ([]byte, *Response, error) { + u := fmt.Sprintf("snippets/%d/raw", snippet) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// SnippetFileContent returns the raw file content as plain text. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#snippet-repository-file-content +func (s *SnippetsService) SnippetFileContent(snippet int, ref, filename string, options ...RequestOptionFunc) ([]byte, *Response, error) { + filepath := PathEscape(filename) + u := fmt.Sprintf("snippets/%d/files/%s/%s/raw", snippet, ref, filepath) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var b bytes.Buffer + resp, err := s.client.Do(req, &b) + if err != nil { + return nil, resp, err + } + + return b.Bytes(), resp, err +} + +// CreateSnippetFileOptions represents the create snippet file options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#create-new-snippet +type CreateSnippetFileOptions struct { + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` +} + +// CreateSnippetOptions represents the available CreateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#create-new-snippet +type CreateSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + Files *[]*CreateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` +} + +// CreateSnippet creates a new snippet. The user must have permission +// to create new snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#create-new-snippet +func (s *SnippetsService) CreateSnippet(opt *CreateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "snippets", opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// UpdateSnippetFileOptions represents the update snippet file options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#update-snippet +type UpdateSnippetFileOptions struct { + Action *string `url:"action,omitempty" json:"action,omitempty"` + FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + PreviousPath *string `url:"previous_path,omitempty" json:"previous_path,omitempty"` +} + +// UpdateSnippetOptions represents the available UpdateSnippet() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#update-snippet +type UpdateSnippetOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Content *string `url:"content,omitempty" json:"content,omitempty"` + Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"` + Files *[]*UpdateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` +} + +// UpdateSnippet updates an existing snippet. The user must have +// permission to change an existing snippet. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#update-snippet +func (s *SnippetsService) UpdateSnippet(snippet int, opt *UpdateSnippetOptions, options ...RequestOptionFunc) (*Snippet, *Response, error) { + u := fmt.Sprintf("snippets/%d", snippet) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + ps := new(Snippet) + resp, err := s.client.Do(req, ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// DeleteSnippet deletes an existing snippet. This is an idempotent +// function and deleting a non-existent snippet still returns a 200 OK status +// code. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#delete-snippet +func (s *SnippetsService) DeleteSnippet(snippet int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("snippets/%d", snippet) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ExploreSnippetsOptions represents the available ExploreSnippets() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-public-snippets +type ExploreSnippetsOptions ListOptions + +// ExploreSnippets gets the list of public snippets. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-public-snippets +func (s *SnippetsService) ExploreSnippets(opt *ExploreSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "snippets/public", opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Snippet + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} + +// ListAllSnippetsOptions represents the available ListAllSnippets() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-snippets +type ListAllSnippetsOptions struct { + ListOptions + CreatedAfter *ISOTime `url:"created_after,omitempty" json:"created_after,omitempty"` + CreatedBefore *ISOTime `url:"created_before,omitempty" json:"created_before,omitempty"` + RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"` +} + +// ListAllSnippets gets all snippets the current user has access to. +// +// GitLab API docs: +// https://docs.gitlab.com/api/snippets/#list-all-snippets +func (s *SnippetsService) ListAllSnippets(opt *ListAllSnippetsOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "snippets/all", opt, options) + if err != nil { + return nil, nil, err + } + + var ps []*Snippet + resp, err := s.client.Do(req, &ps) + if err != nil { + return nil, resp, err + } + + return ps, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/strings.go b/vendor/gitlab.com/gitlab-org/api/client-go/strings.go similarity index 89% rename from vendor/github.com/xanzy/go-gitlab/strings.go rename to vendor/gitlab.com/gitlab-org/api/client-go/strings.go index aeefb6b8d..def37b255 100644 --- a/vendor/github.com/xanzy/go-gitlab/strings.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/strings.go @@ -1,5 +1,5 @@ // -// Copyright 2017, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,14 +19,13 @@ package gitlab import ( "bytes" "fmt" - "reflect" ) // Stringify attempts to create a reasonable string representation of types in -// the GitHub library. It does things like resolve pointers to their values +// the Gitlab library. It does things like resolve pointers to their values // and omits struct fields with nil values. -func Stringify(message interface{}) string { +func Stringify(message any) string { var buf bytes.Buffer v := reflect.ValueOf(message) stringifyValue(&buf, v) @@ -47,7 +46,7 @@ func stringifyValue(buf *bytes.Buffer, val reflect.Value) { fmt.Fprintf(buf, `"%s"`, v) case reflect.Slice: buf.WriteByte('[') - for i := 0; i < v.Len(); i++ { + for i := range v.Len() { if i > 0 { buf.WriteByte(' ') } @@ -65,7 +64,7 @@ func stringifyValue(buf *bytes.Buffer, val reflect.Value) { buf.WriteByte('{') var sep bool - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { fv := v.Field(i) if fv.Kind() == reflect.Ptr && fv.IsNil() { continue diff --git a/vendor/github.com/xanzy/go-gitlab/system_hooks.go b/vendor/gitlab.com/gitlab-org/api/client-go/system_hooks.go similarity index 56% rename from vendor/github.com/xanzy/go-gitlab/system_hooks.go rename to vendor/gitlab.com/gitlab-org/api/client-go/system_hooks.go index 041264e95..7fe26a461 100644 --- a/vendor/github.com/xanzy/go-gitlab/system_hooks.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/system_hooks.go @@ -1,5 +1,5 @@ // -// Copyright 2017, Sander van Harmelen +// Copyright 2021, Sander van Harmelen // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,24 +18,42 @@ package gitlab import ( "fmt" + "net/http" "time" ) -// SystemHooksService handles communication with the system hooks related -// methods of the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html -type SystemHooksService struct { - client *Client -} +type ( + SystemHooksServiceInterface interface { + ListHooks(options ...RequestOptionFunc) ([]*Hook, *Response, error) + GetHook(hook int, options ...RequestOptionFunc) (*Hook, *Response, error) + AddHook(opt *AddHookOptions, options ...RequestOptionFunc) (*Hook, *Response, error) + TestHook(hook int, options ...RequestOptionFunc) (*HookEvent, *Response, error) + DeleteHook(hook int, options ...RequestOptionFunc) (*Response, error) + } + + // SystemHooksService handles communication with the system hooks related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/system_hooks/ + SystemHooksService struct { + client *Client + } +) + +var _ SystemHooksServiceInterface = (*SystemHooksService)(nil) // Hook represents a GitLap system hook. // -// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html +// GitLab API docs: https://docs.gitlab.com/api/system_hooks/ type Hook struct { - ID int `json:"id"` - URL string `json:"url"` - CreatedAt *time.Time `json:"created_at"` + ID int `json:"id"` + URL string `json:"url"` + CreatedAt *time.Time `json:"created_at"` + PushEvents bool `json:"push_events"` + TagPushEvents bool `json:"tag_push_events"` + MergeRequestsEvents bool `json:"merge_requests_events"` + RepositoryUpdateEvents bool `json:"repository_update_events"` + EnableSSLVerification bool `json:"enable_ssl_verification"` } func (h Hook) String() string { @@ -45,9 +63,9 @@ func (h Hook) String() string { // ListHooks gets a list of system hooks. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/system_hooks.html#list-system-hooks +// https://docs.gitlab.com/api/system_hooks/#list-system-hooks func (s *SystemHooksService) ListHooks(options ...RequestOptionFunc) ([]*Hook, *Response, error) { - req, err := s.client.NewRequest("GET", "hooks", nil, options) + req, err := s.client.NewRequest(http.MethodGet, "hooks", nil, options) if err != nil { return nil, nil, err } @@ -58,13 +76,34 @@ func (s *SystemHooksService) ListHooks(options ...RequestOptionFunc) ([]*Hook, * return nil, resp, err } - return h, resp, err + return h, resp, nil +} + +// GetHook get a single system hook. +// +// GitLab API docs: +// https://docs.gitlab.com/api/system_hooks/#get-system-hook +func (s *SystemHooksService) GetHook(hook int, options ...RequestOptionFunc) (*Hook, *Response, error) { + u := fmt.Sprintf("hooks/%d", hook) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var h *Hook + resp, err := s.client.Do(req, &h) + if err != nil { + return nil, resp, err + } + + return h, resp, nil } // AddHookOptions represents the available AddHook() options. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook +// https://docs.gitlab.com/api/system_hooks/#add-new-system-hook type AddHookOptions struct { URL *string `url:"url,omitempty" json:"url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` @@ -78,9 +117,9 @@ type AddHookOptions struct { // AddHook adds a new system hook hook. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook +// https://docs.gitlab.com/api/system_hooks/#add-new-system-hook func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...RequestOptionFunc) (*Hook, *Response, error) { - req, err := s.client.NewRequest("POST", "hooks", opt, options) + req, err := s.client.NewRequest(http.MethodPost, "hooks", opt, options) if err != nil { return nil, nil, err } @@ -91,12 +130,12 @@ func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...RequestOpti return nil, resp, err } - return h, resp, err + return h, resp, nil } // HookEvent represents an event trigger by a GitLab system hook. // -// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html +// GitLab API docs: https://docs.gitlab.com/api/system_hooks/ type HookEvent struct { EventName string `json:"event_name"` Name string `json:"name"` @@ -113,11 +152,11 @@ func (h HookEvent) String() string { // TestHook tests a system hook. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/system_hooks.html#test-system-hook +// https://docs.gitlab.com/api/system_hooks/#test-system-hook func (s *SystemHooksService) TestHook(hook int, options ...RequestOptionFunc) (*HookEvent, *Response, error) { u := fmt.Sprintf("hooks/%d", hook) - req, err := s.client.NewRequest("GET", u, nil, options) + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } @@ -128,7 +167,7 @@ func (s *SystemHooksService) TestHook(hook int, options ...RequestOptionFunc) (* return nil, resp, err } - return h, resp, err + return h, resp, nil } // DeleteHook deletes a system hook. This is an idempotent API function and @@ -136,11 +175,11 @@ func (s *SystemHooksService) TestHook(hook int, options ...RequestOptionFunc) (* // is also returned as JSON. // // GitLab API docs: -// https://docs.gitlab.com/ce/api/system_hooks.html#delete-system-hook +// https://docs.gitlab.com/api/system_hooks/#delete-system-hook func (s *SystemHooksService) DeleteHook(hook int, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("hooks/%d", hook) - req, err := s.client.NewRequest("DELETE", u, nil, options) + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/tags.go b/vendor/gitlab.com/gitlab-org/api/client-go/tags.go new file mode 100644 index 000000000..43b0e37a2 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/tags.go @@ -0,0 +1,237 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "math/big" + "net/http" + "net/url" +) + +type ( + TagsServiceInterface interface { + ListTags(pid any, opt *ListTagsOptions, options ...RequestOptionFunc) ([]*Tag, *Response, error) + GetTag(pid any, tag string, options ...RequestOptionFunc) (*Tag, *Response, error) + GetTagSignature(pid any, tag string, options ...RequestOptionFunc) (*X509Signature, *Response, error) + CreateTag(pid any, opt *CreateTagOptions, options ...RequestOptionFunc) (*Tag, *Response, error) + DeleteTag(pid any, tag string, options ...RequestOptionFunc) (*Response, error) + } + + // TagsService handles communication with the tags related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/tags/ + TagsService struct { + client *Client + } +) + +var _ TagsServiceInterface = (*TagsService)(nil) + +// Tag represents a GitLab tag. +// +// GitLab API docs: https://docs.gitlab.com/api/tags/ +type Tag struct { + Commit *Commit `json:"commit"` + Release *ReleaseNote `json:"release"` + Name string `json:"name"` + Message string `json:"message"` + Protected bool `json:"protected"` + Target string `json:"target"` +} + +// X509Signature represents a GitLab Tag Signature object. +// +// GitLab API docs: https://docs.gitlab.com/api/tags/#get-x509-signature-of-a-tag +type X509Signature struct { + SignatureType string `json:"signature_type"` + VerificationStatus string `json:"verification_status"` + X509Certificate X509Certificate `json:"x509_certificate"` +} + +type X509Certificate struct { + ID int `json:"id"` + Subject string `json:"subject"` + SubjectKeyIdentifier string `json:"subject_key_identifier"` + Email string `json:"email"` + SerialNumber *big.Int `json:"serial_number"` + CertificateStatus string `json:"certificate_status"` + X509Issuer X509Issuer `json:"x509_issuer"` +} + +type X509Issuer struct { + ID int `json:"id"` + Subject string `json:"subject"` + SubjectKeyIdentifier string `json:"subject_key_identifier"` + CrlUrl string `json:"crl_url"` +} + +// ReleaseNote represents a GitLab version release. +// +// GitLab API docs: https://docs.gitlab.com/api/tags/ +type ReleaseNote struct { + TagName string `json:"tag_name"` + Description string `json:"description"` +} + +func (t Tag) String() string { + return Stringify(t) +} + +// ListTagsOptions represents the available ListTags() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#list-project-repository-tags +type ListTagsOptions struct { + ListOptions + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Search *string `url:"search,omitempty" json:"search,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` +} + +// ListTags gets a list of tags from a project, sorted by name in reverse +// alphabetical order. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#list-project-repository-tags +func (s *TagsService) ListTags(pid any, opt *ListTagsOptions, options ...RequestOptionFunc) ([]*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var t []*Tag + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// GetTag a specific repository tag determined by its name. It returns 200 together +// with the tag information if the tag exists. It returns 404 if the tag does not exist. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#get-a-single-repository-tag +func (s *TagsService) GetTag(pid any, tag string, options ...RequestOptionFunc) (*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags/%s", PathEscape(project), url.PathEscape(tag)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var t *Tag + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// GetTagSignature a specific repository tag determined by its name. It returns 200 together +// with the signature if the tag exists. It returns 404 if the tag does not exist. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#get-x509-signature-of-a-tag +func (s *TagsService) GetTagSignature(pid any, tag string, options ...RequestOptionFunc) (*X509Signature, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags/%s/signature", PathEscape(project), url.PathEscape(tag)) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var sig *X509Signature + resp, err := s.client.Do(req, &sig) + if err != nil { + return nil, resp, err + } + + return sig, resp, nil +} + +// CreateTagOptions represents the available CreateTag() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#create-a-new-tag +type CreateTagOptions struct { + TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` + Message *string `url:"message,omitempty" json:"message,omitempty"` +} + +// CreateTag creates a new tag in the repository that points to the supplied ref. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#create-a-new-tag +func (s *TagsService) CreateTag(pid any, opt *CreateTagOptions, options ...RequestOptionFunc) (*Tag, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(Tag) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// DeleteTag deletes a tag of a repository with given name. +// +// GitLab API docs: +// https://docs.gitlab.com/api/tags/#delete-a-tag +func (s *TagsService) DeleteTag(pid any, tag string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/repository/tags/%s", PathEscape(project), url.PathEscape(tag)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/time_stats.go b/vendor/gitlab.com/gitlab-org/api/client-go/time_stats.go new file mode 100644 index 000000000..580acf1a6 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/time_stats.go @@ -0,0 +1,180 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +// timeStatsService handles communication with the time tracking related +// methods of the GitLab API. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#time-tracking +type timeStatsService struct { + client *Client +} + +// TimeStats represents the time estimates and time spent for an issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#time-tracking +type TimeStats struct { + HumanTimeEstimate string `json:"human_time_estimate"` + HumanTotalTimeSpent string `json:"human_total_time_spent"` + TimeEstimate int `json:"time_estimate"` + TotalTimeSpent int `json:"total_time_spent"` +} + +func (t TimeStats) String() string { + return Stringify(t) +} + +// SetTimeEstimateOptions represents the available SetTimeEstimate() +// options. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#set-a-time-estimate-for-an-issue +type SetTimeEstimateOptions struct { + Duration *string `url:"duration,omitempty" json:"duration,omitempty"` +} + +// setTimeEstimate sets the time estimate for a single project issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#set-a-time-estimate-for-an-issue +func (s *timeStatsService) setTimeEstimate(pid any, entity string, issue int, opt *SetTimeEstimateOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/time_estimate", PathEscape(project), entity, issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// resetTimeEstimate resets the time estimate for a single project issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#reset-the-time-estimate-for-an-issue +func (s *timeStatsService) resetTimeEstimate(pid any, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/reset_time_estimate", PathEscape(project), entity, issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// AddSpentTimeOptions represents the available AddSpentTime() options. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#add-spent-time-for-an-issue +type AddSpentTimeOptions struct { + Duration *string `url:"duration,omitempty" json:"duration,omitempty"` + Summary *string `url:"summary,omitempty" json:"summary,omitempty"` +} + +// addSpentTime adds spent time for a single project issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#add-spent-time-for-an-issue +func (s *timeStatsService) addSpentTime(pid any, entity string, issue int, opt *AddSpentTimeOptions, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/add_spent_time", PathEscape(project), entity, issue) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// resetSpentTime resets the spent time for a single project issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#reset-spent-time-for-an-issue +func (s *timeStatsService) resetSpentTime(pid any, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/reset_spent_time", PathEscape(project), entity, issue) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// getTimeSpent gets the spent time for a single project issue. +// +// GitLab docs: https://docs.gitlab.com/api/issues/#get-time-tracking-stats +func (s *timeStatsService) getTimeSpent(pid any, entity string, issue int, options ...RequestOptionFunc) (*TimeStats, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/%s/%d/time_stats", PathEscape(project), entity, issue) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(TimeStats) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/todos.go b/vendor/gitlab.com/gitlab-org/api/client-go/todos.go new file mode 100644 index 000000000..7711e7250 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/todos.go @@ -0,0 +1,174 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" + "time" +) + +type ( + TodosServiceInterface interface { + ListTodos(opt *ListTodosOptions, options ...RequestOptionFunc) ([]*Todo, *Response, error) + MarkTodoAsDone(id int, options ...RequestOptionFunc) (*Response, error) + MarkAllTodosAsDone(options ...RequestOptionFunc) (*Response, error) + } + + // TodosService handles communication with the todos related methods of + // the Gitlab API. + // + // GitLab API docs: https://docs.gitlab.com/api/todos/ + TodosService struct { + client *Client + } +) + +var _ TodosServiceInterface = (*TodosService)(nil) + +// Todo represents a GitLab todo. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/ +type Todo struct { + ID int `json:"id"` + Project *BasicProject `json:"project"` + Author *BasicUser `json:"author"` + ActionName TodoAction `json:"action_name"` + TargetType TodoTargetType `json:"target_type"` + Target *TodoTarget `json:"target"` + TargetURL string `json:"target_url"` + Body string `json:"body"` + State string `json:"state"` + CreatedAt *time.Time `json:"created_at"` +} + +func (t Todo) String() string { + return Stringify(t) +} + +// TodoTarget represents a todo target of type Issue or MergeRequest +type TodoTarget struct { + Assignees []*BasicUser `json:"assignees"` + Assignee *BasicUser `json:"assignee"` + Author *BasicUser `json:"author"` + CreatedAt *time.Time `json:"created_at"` + Description string `json:"description"` + Downvotes int `json:"downvotes"` + ID any `json:"id"` + IID int `json:"iid"` + Labels []string `json:"labels"` + Milestone *Milestone `json:"milestone"` + ProjectID int `json:"project_id"` + State string `json:"state"` + Subscribed bool `json:"subscribed"` + TaskCompletionStatus *TasksCompletionStatus `json:"task_completion_status"` + Title string `json:"title"` + UpdatedAt *time.Time `json:"updated_at"` + Upvotes int `json:"upvotes"` + UserNotesCount int `json:"user_notes_count"` + WebURL string `json:"web_url"` + + // Only available for type Issue + Confidential bool `json:"confidential"` + DueDate string `json:"due_date"` + HasTasks bool `json:"has_tasks"` + Links *IssueLinks `json:"_links"` + MovedToID int `json:"moved_to_id"` + TimeStats *TimeStats `json:"time_stats"` + Weight int `json:"weight"` + + // Only available for type MergeRequest + MergedAt *time.Time `json:"merged_at"` + ApprovalsBeforeMerge int `json:"approvals_before_merge"` + ForceRemoveSourceBranch bool `json:"force_remove_source_branch"` + MergeCommitSHA string `json:"merge_commit_sha"` + MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` + MergeStatus string `json:"merge_status"` + Reference string `json:"reference"` + Reviewers []*BasicUser `json:"reviewers"` + SHA string `json:"sha"` + ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"` + SourceBranch string `json:"source_branch"` + SourceProjectID int `json:"source_project_id"` + Squash bool `json:"squash"` + TargetBranch string `json:"target_branch"` + TargetProjectID int `json:"target_project_id"` + WorkInProgress bool `json:"work_in_progress"` + + // Only available for type DesignManagement::Design + FileName string `json:"filename"` + ImageURL string `json:"image_url"` +} + +// ListTodosOptions represents the available ListTodos() options. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/#get-a-list-of-to-do-items +type ListTodosOptions struct { + ListOptions + Action *TodoAction `url:"action,omitempty" json:"action,omitempty"` + AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"` + ProjectID *int `url:"project_id,omitempty" json:"project_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + State *string `url:"state,omitempty" json:"state,omitempty"` + Type *string `url:"type,omitempty" json:"type,omitempty"` +} + +// ListTodos lists all todos created by authenticated user. +// When no filter is applied, it returns all pending todos for the current user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/todos/#get-a-list-of-to-do-items +func (s *TodosService) ListTodos(opt *ListTodosOptions, options ...RequestOptionFunc) ([]*Todo, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "todos", opt, options) + if err != nil { + return nil, nil, err + } + + var t []*Todo + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// MarkTodoAsDone marks a single pending todo given by its ID for the current user as done. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/#mark-a-to-do-item-as-done +func (s *TodosService) MarkTodoAsDone(id int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("todos/%d/mark_as_done", id) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// MarkAllTodosAsDone marks all pending todos for the current user as done. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/#mark-all-to-do-items-as-done +func (s *TodosService) MarkAllTodosAsDone(options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "todos/mark_as_done", nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/topics.go b/vendor/gitlab.com/gitlab-org/api/client-go/topics.go new file mode 100644 index 000000000..abd4ff453 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/topics.go @@ -0,0 +1,234 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + retryablehttp "github.com/hashicorp/go-retryablehttp" +) + +type ( + TopicsServiceInterface interface { + ListTopics(opt *ListTopicsOptions, options ...RequestOptionFunc) ([]*Topic, *Response, error) + GetTopic(topic int, options ...RequestOptionFunc) (*Topic, *Response, error) + CreateTopic(opt *CreateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) + UpdateTopic(topic int, opt *UpdateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) + DeleteTopic(topic int, options ...RequestOptionFunc) (*Response, error) + } + + // TopicsService handles communication with the topics related methods + // of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/topics/ + TopicsService struct { + client *Client + } +) + +var _ TopicsServiceInterface = (*TopicsService)(nil) + +// Topic represents a GitLab project topic. +// +// GitLab API docs: https://docs.gitlab.com/api/topics/ +type Topic struct { + ID int `json:"id"` + Name string `json:"name"` + Title string `json:"title"` + Description string `json:"description"` + TotalProjectsCount uint64 `json:"total_projects_count"` + AvatarURL string `json:"avatar_url"` +} + +func (t Topic) String() string { + return Stringify(t) +} + +// ListTopicsOptions represents the available ListTopics() options. +// +// GitLab API docs: https://docs.gitlab.com/api/topics/#list-topics +type ListTopicsOptions struct { + ListOptions + Search *string `url:"search,omitempty" json:"search,omitempty"` +} + +// ListTopics returns a list of project topics in the GitLab instance ordered +// by number of associated projects. +// +// GitLab API docs: https://docs.gitlab.com/api/topics/#list-topics +func (s *TopicsService) ListTopics(opt *ListTopicsOptions, options ...RequestOptionFunc) ([]*Topic, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "topics", opt, options) + if err != nil { + return nil, nil, err + } + + var t []*Topic + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// GetTopic gets a project topic by ID. +// +// GitLab API docs: https://docs.gitlab.com/api/topics/#get-a-topic +func (s *TopicsService) GetTopic(topic int, options ...RequestOptionFunc) (*Topic, *Response, error) { + u := fmt.Sprintf("topics/%d", topic) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(Topic) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// CreateTopicOptions represents the available CreateTopic() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/topics/#create-a-project-topic +type CreateTopicOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Avatar *TopicAvatar `url:"-" json:"-"` +} + +// TopicAvatar represents a GitLab topic avatar. +type TopicAvatar struct { + Filename string + Image io.Reader +} + +// MarshalJSON implements the json.Marshaler interface. +func (a *TopicAvatar) MarshalJSON() ([]byte, error) { + if a.Filename == "" && a.Image == nil { + return []byte(`""`), nil + } + type alias TopicAvatar + return json.Marshal((*alias)(a)) +} + +// CreateTopic creates a new project topic. +// +// GitLab API docs: +// https://docs.gitlab.com/api/topics/#create-a-project-topic +func (s *TopicsService) CreateTopic(opt *CreateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) { + var err error + var req *retryablehttp.Request + + if opt.Avatar == nil { + req, err = s.client.NewRequest(http.MethodPost, "topics", opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPost, + "topics", + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + t := new(Topic) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// UpdateTopicOptions represents the available UpdateTopic() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/topics/#update-a-project-topic +type UpdateTopicOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Avatar *TopicAvatar `url:"-" json:"avatar,omitempty"` +} + +// UpdateTopic updates a project topic. Only available to administrators. +// +// To remove a topic avatar set the TopicAvatar.Filename to an empty string +// and set TopicAvatar.Image to nil. +// +// GitLab API docs: +// https://docs.gitlab.com/api/topics/#update-a-project-topic +func (s *TopicsService) UpdateTopic(topic int, opt *UpdateTopicOptions, options ...RequestOptionFunc) (*Topic, *Response, error) { + u := fmt.Sprintf("topics/%d", topic) + + var err error + var req *retryablehttp.Request + + if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) { + req, err = s.client.NewRequest(http.MethodPut, u, opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPut, + u, + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + t := new(Topic) + resp, err := s.client.Do(req, t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// DeleteTopic deletes a project topic. Only available to administrators. +// +// GitLab API docs: +// https://docs.gitlab.com/api/topics/#delete-a-project-topic +func (s *TopicsService) DeleteTopic(topic int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("topics/%d", topic) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/types.go b/vendor/gitlab.com/gitlab-org/api/client-go/types.go new file mode 100644 index 000000000..b06e5744c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/types.go @@ -0,0 +1,900 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/url" + "reflect" + "strconv" + "strings" + "time" +) + +// Ptr is a helper that returns a pointer to v. +func Ptr[T any](v T) *T { + return &v +} + +// AccessControlValue represents an access control value within GitLab, +// used for managing access to certain project features. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/ +type AccessControlValue string + +// List of available access control values. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/ +const ( + DisabledAccessControl AccessControlValue = "disabled" + EnabledAccessControl AccessControlValue = "enabled" + PrivateAccessControl AccessControlValue = "private" + PublicAccessControl AccessControlValue = "public" +) + +// AccessLevelValue represents a permission level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/user/permissions/#roles +type AccessLevelValue int + +// List of available access levels. +// +// GitLab API docs: https://docs.gitlab.com/api/access_requests/#valid-access-levels +const ( + NoPermissions AccessLevelValue = 0 + MinimalAccessPermissions AccessLevelValue = 5 + GuestPermissions AccessLevelValue = 10 + PlannerPermissions AccessLevelValue = 15 + ReporterPermissions AccessLevelValue = 20 + DeveloperPermissions AccessLevelValue = 30 + MaintainerPermissions AccessLevelValue = 40 + OwnerPermissions AccessLevelValue = 50 + AdminPermissions AccessLevelValue = 60 +) + +type AccessLevelDetails struct { + IntegerValue AccessLevelValue `json:"integer_value"` + StringValue string `json:"string_value"` +} + +// AccessTokenState identifies if an access token is active or inactive. +// +// GitLab API docs: +// https://docs.gitlab.com/api/group_access_tokens/#list-all-group-access-tokens +// https://docs.gitlab.com/api/project_access_tokens/#list-all-project-access-tokens +type AccessTokenState string + +const ( + AccessTokenStateActive AccessTokenState = "active" + AccessTokenStateInactive AccessTokenState = "inactive" +) + +// UserIDValue represents a user ID value within GitLab. +type UserIDValue string + +// List of available user ID values. +const ( + UserIDAny UserIDValue = "Any" + UserIDNone UserIDValue = "None" +) + +// ApproverIDsValue represents an approver ID value within GitLab. +type ApproverIDsValue struct { + value any +} + +// ApproverIDs is a helper routine that creates a new ApproverIDsValue. +func ApproverIDs(v any) *ApproverIDsValue { + switch v.(type) { + case UserIDValue, []int: + return &ApproverIDsValue{value: v} + default: + panic("Unsupported value passed as approver ID") + } +} + +// EncodeValues implements the query.Encoder interface. +func (a *ApproverIDsValue) EncodeValues(key string, v *url.Values) error { + switch value := a.value.(type) { + case UserIDValue: + v.Set(key, string(value)) + case []int: + v.Del(key) + v.Del(key + "[]") + for _, id := range value { + v.Add(key+"[]", strconv.Itoa(id)) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (a ApproverIDsValue) MarshalJSON() ([]byte, error) { + return json.Marshal(a.value) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (a *ApproverIDsValue) UnmarshalJSON(bytes []byte) error { + return json.Unmarshal(bytes, a.value) +} + +// AssigneeIDValue represents an assignee ID value within GitLab. +type AssigneeIDValue struct { + value any +} + +// AssigneeID is a helper routine that creates a new AssigneeIDValue. +func AssigneeID(v any) *AssigneeIDValue { + switch v.(type) { + case UserIDValue, int: + return &AssigneeIDValue{value: v} + default: + panic("Unsupported value passed as assignee ID") + } +} + +// EncodeValues implements the query.Encoder interface. +func (a *AssigneeIDValue) EncodeValues(key string, v *url.Values) error { + switch value := a.value.(type) { + case UserIDValue: + v.Set(key, string(value)) + case int: + v.Set(key, strconv.Itoa(value)) + } + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (a AssigneeIDValue) MarshalJSON() ([]byte, error) { + return json.Marshal(a.value) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (a *AssigneeIDValue) UnmarshalJSON(bytes []byte) error { + return json.Unmarshal(bytes, a.value) +} + +// ReviewerIDValue represents a reviewer ID value within GitLab. +type ReviewerIDValue struct { + value any +} + +// ReviewerID is a helper routine that creates a new ReviewerIDValue. +func ReviewerID(v any) *ReviewerIDValue { + switch v.(type) { + case UserIDValue, int: + return &ReviewerIDValue{value: v} + default: + panic("Unsupported value passed as reviewer ID") + } +} + +// EncodeValues implements the query.Encoder interface. +func (a *ReviewerIDValue) EncodeValues(key string, v *url.Values) error { + switch value := a.value.(type) { + case UserIDValue: + v.Set(key, string(value)) + case int: + v.Set(key, strconv.Itoa(value)) + } + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (a ReviewerIDValue) MarshalJSON() ([]byte, error) { + return json.Marshal(a.value) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (a *ReviewerIDValue) UnmarshalJSON(bytes []byte) error { + return json.Unmarshal(bytes, a.value) +} + +// AvailabilityValue represents an availability value within GitLab. +type AvailabilityValue string + +// List of available availability values. +// +// Undocummented, see code at: +// https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/app/models/user_status.rb#L22 +const ( + NotSet AvailabilityValue = "not_set" + Busy AvailabilityValue = "busy" +) + +// ClearStatusAfterValue represents the time period after which the user's status will be cleared. +// +// The duration is specified using one of the constants defined in this package. +type ClearStatusAfterValue string + +// List of available clear status after values. +// +// https://docs.gitlab.com/api/users/#set-your-user-status:~:text=clear_status_after +const ( + ClearStatusAfter30Minutes ClearStatusAfterValue = "30_minutes" + ClearStatusAfter3Hours ClearStatusAfterValue = "3_hours" + ClearStatusAfter8Hours ClearStatusAfterValue = "8_hours" + ClearStatusAfter1Day ClearStatusAfterValue = "1_day" + ClearStatusAfter3Days ClearStatusAfterValue = "3_days" + ClearStatusAfter7Days ClearStatusAfterValue = "7_days" + ClearStatusAfter30Days ClearStatusAfterValue = "30_days" +) + +// BuildStateValue represents a GitLab build state. +type BuildStateValue string + +// These constants represent all valid build states. +const ( + Created BuildStateValue = "created" + WaitingForResource BuildStateValue = "waiting_for_resource" + Preparing BuildStateValue = "preparing" + Pending BuildStateValue = "pending" + Running BuildStateValue = "running" + Success BuildStateValue = "success" + Failed BuildStateValue = "failed" + Canceled BuildStateValue = "canceled" + Skipped BuildStateValue = "skipped" + Manual BuildStateValue = "manual" + Scheduled BuildStateValue = "scheduled" +) + +// CommentEventAction identifies if a comment has been newly created or updated. +// +// GitLab API docs: +// https://docs.gitlab.com/user/project/integrations/webhook_events/#comment-events +type CommentEventAction string + +const ( + CommentEventActionCreate CommentEventAction = "create" + CommentEventActionUpdate CommentEventAction = "update" +) + +// ContainerRegistryStatus represents the status of a Container Registry. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_registry/#list-registry-repositories +type ContainerRegistryStatus string + +// ContainerRegistryStatus represents all valid statuses of a Container Registry. +// +// Undocumented, see code at: +// https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/container_repository.rb?ref_type=heads#L35 +const ( + ContainerRegistryStatusDeleteScheduled ContainerRegistryStatus = "delete_scheduled" + ContainerRegistryStatusDeleteFailed ContainerRegistryStatus = "delete_failed" + ContainerRegistryStatusDeleteOngoing ContainerRegistryStatus = "delete_ongoing" +) + +// ProtectionRuleAccessLevel represents the access level for a Container +// Registry Protection Rule. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/ +type ProtectionRuleAccessLevel string + +// These constants represent all valid protection rule access levels. +// +// GitLab API docs: +// https://docs.gitlab.com/api/container_repository_protection_rules/ +const ( + ProtectionRuleAccessLevelMaintainer ProtectionRuleAccessLevel = "maintainer" + ProtectionRuleAccessLevelOwner ProtectionRuleAccessLevel = "owner" + ProtectionRuleAccessLevelAdmin ProtectionRuleAccessLevel = "admin" +) + +// DeploymentApprovalStatus represents a Gitlab deployment approval status. +type DeploymentApprovalStatus string + +// These constants represent all valid deployment approval statuses. +const ( + DeploymentApprovalStatusApproved DeploymentApprovalStatus = "approved" + DeploymentApprovalStatusRejected DeploymentApprovalStatus = "rejected" +) + +// DeploymentStatusValue represents a Gitlab deployment status. +type DeploymentStatusValue string + +// These constants represent all valid deployment statuses. +const ( + DeploymentStatusCreated DeploymentStatusValue = "created" + DeploymentStatusRunning DeploymentStatusValue = "running" + DeploymentStatusSuccess DeploymentStatusValue = "success" + DeploymentStatusFailed DeploymentStatusValue = "failed" + DeploymentStatusCanceled DeploymentStatusValue = "canceled" +) + +// DORAMetricType represents all valid DORA metrics types. +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +type DORAMetricType string + +// List of available DORA metric type names. +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +const ( + DORAMetricDeploymentFrequency DORAMetricType = "deployment_frequency" + DORAMetricLeadTimeForChanges DORAMetricType = "lead_time_for_changes" + DORAMetricTimeToRestoreService DORAMetricType = "time_to_restore_service" + DORAMetricChangeFailureRate DORAMetricType = "change_failure_rate" +) + +// DORAMetricInterval represents the time period over which the +// metrics are aggregated. +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +type DORAMetricInterval string + +// List of available DORA metric interval types. +// +// GitLab API docs: https://docs.gitlab.com/api/dora/metrics/ +const ( + DORAMetricIntervalDaily DORAMetricInterval = "daily" + DORAMetricIntervalMonthly DORAMetricInterval = "monthly" + DORAMetricIntervalAll DORAMetricInterval = "all" +) + +// EventTypeValue represents actions type for contribution events. +type EventTypeValue string + +// List of available action type. +// +// GitLab API docs: +// https://docs.gitlab.com/user/profile/contributions_calendar/#user-contribution-events +const ( + CreatedEventType EventTypeValue = "created" + UpdatedEventType EventTypeValue = "updated" + ClosedEventType EventTypeValue = "closed" + ReopenedEventType EventTypeValue = "reopened" + PushedEventType EventTypeValue = "pushed" + CommentedEventType EventTypeValue = "commented" + MergedEventType EventTypeValue = "merged" + JoinedEventType EventTypeValue = "joined" + LeftEventType EventTypeValue = "left" + DestroyedEventType EventTypeValue = "destroyed" + ExpiredEventType EventTypeValue = "expired" +) + +// EventTargetTypeValue represents actions type value for contribution events. +type EventTargetTypeValue string + +// List of available action type. +// +// GitLab API docs: https://docs.gitlab.com/api/events/#target-types +const ( + IssueEventTargetType EventTargetTypeValue = "issue" + MilestoneEventTargetType EventTargetTypeValue = "milestone" + MergeRequestEventTargetType EventTargetTypeValue = "merge_request" + NoteEventTargetType EventTargetTypeValue = "note" + ProjectEventTargetType EventTargetTypeValue = "project" + SnippetEventTargetType EventTargetTypeValue = "snippet" + UserEventTargetType EventTargetTypeValue = "user" +) + +// FileActionValue represents the available actions that can be performed on a file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/commits/#create-a-commit-with-multiple-files-and-actions +type FileActionValue string + +// The available file actions. +const ( + FileCreate FileActionValue = "create" + FileDelete FileActionValue = "delete" + FileMove FileActionValue = "move" + FileUpdate FileActionValue = "update" + FileChmod FileActionValue = "chmod" +) + +// GenericPackageSelectValue represents a generic package select value. +type GenericPackageSelectValue string + +// The available generic package select values. +const ( + SelectPackageFile GenericPackageSelectValue = "package_file" +) + +// GenericPackageStatusValue represents a generic package status. +type GenericPackageStatusValue string + +// The available generic package statuses. +const ( + PackageDefault GenericPackageStatusValue = "default" + PackageHidden GenericPackageStatusValue = "hidden" +) + +// GroupHookTrigger represents the type of event to trigger for a group +// hook test. +type GroupHookTrigger string + +// List of available group hook trigger types. +const ( + GroupHookTriggerPush GroupHookTrigger = "push_events" + GroupHookTriggerTagPush GroupHookTrigger = "tag_push_events" + GroupHookTriggerIssue GroupHookTrigger = "issues_events" + GroupHookTriggerConfidentialIssue GroupHookTrigger = "confidential_issues_events" + GroupHookTriggerNote GroupHookTrigger = "note_events" + GroupHookTriggerMergeRequest GroupHookTrigger = "merge_requests_events" + GroupHookTriggerJob GroupHookTrigger = "job_events" + GroupHookTriggerPipeline GroupHookTrigger = "pipeline_events" + GroupHookTriggerWikiPage GroupHookTrigger = "wiki_page_events" + GroupHookTriggerRelease GroupHookTrigger = "releases_events" + GroupHookTriggerEmoji GroupHookTrigger = "emoji_events" + GroupHookTriggerResourceAccessToken GroupHookTrigger = "resource_access_token_events" +) + +// ISOTime represents an ISO 8601 formatted date. +type ISOTime time.Time + +// ISO 8601 date format. +const iso8601 = "2006-01-02" + +// ParseISOTime parses an ISO 8601 formatted date. +func ParseISOTime(s string) (ISOTime, error) { + t, err := time.Parse(iso8601, s) + return ISOTime(t), err +} + +// MarshalJSON implements the json.Marshaler interface. +func (t ISOTime) MarshalJSON() ([]byte, error) { + if reflect.ValueOf(t).IsZero() { + return []byte(`null`), nil + } + + if y := time.Time(t).Year(); y < 0 || y >= 10000 { + // ISO 8901 uses 4 digits for the years. + return nil, errors.New("json: ISOTime year outside of range [0,9999]") + } + + b := make([]byte, 0, len(iso8601)+2) + b = append(b, '"') + b = time.Time(t).AppendFormat(b, iso8601) + b = append(b, '"') + + return b, nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (t *ISOTime) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + isotime, err := time.Parse(`"`+iso8601+`"`, string(data)) + *t = ISOTime(isotime) + + return err +} + +// EncodeValues implements the query.Encoder interface. +func (t *ISOTime) EncodeValues(key string, v *url.Values) error { + if t == nil || (time.Time(*t)).IsZero() { + return nil + } + v.Add(key, t.String()) + return nil +} + +// String implements the Stringer interface. +func (t ISOTime) String() string { + return time.Time(t).Format(iso8601) +} + +// Labels represents a list of labels. +type Labels []string + +// LabelOptions is a custom type with specific marshaling characteristics. +type LabelOptions []string + +// MarshalJSON implements the json.Marshaler interface. +func (l *LabelOptions) MarshalJSON() ([]byte, error) { + if *l == nil { + return []byte(`null`), nil + } + return json.Marshal(strings.Join(*l, ",")) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (l *LabelOptions) UnmarshalJSON(data []byte) error { + type alias LabelOptions + if !bytes.HasPrefix(data, []byte("[")) { + data = fmt.Appendf(nil, "[%s]", string(data)) + } + return json.Unmarshal(data, (*alias)(l)) +} + +// EncodeValues implements the query.EncodeValues interface. +func (l *LabelOptions) EncodeValues(key string, v *url.Values) error { + v.Set(key, strings.Join(*l, ",")) + return nil +} + +// LinkTypeValue represents a release link type. +type LinkTypeValue string + +// List of available release link types. +// +// GitLab API docs: +// https://docs.gitlab.com/api/releases/links/#create-a-release-link +const ( + ImageLinkType LinkTypeValue = "image" + OtherLinkType LinkTypeValue = "other" + PackageLinkType LinkTypeValue = "package" + RunbookLinkType LinkTypeValue = "runbook" +) + +// MergeMethodValue represents a project merge type within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#project-merge-method +type MergeMethodValue string + +// List of available merge type +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#project-merge-method +const ( + NoFastForwardMerge MergeMethodValue = "merge" + FastForwardMerge MergeMethodValue = "ff" + RebaseMerge MergeMethodValue = "rebase_merge" +) + +// NoteTypeValue represents the type of a Note. +type NoteTypeValue string + +// List of available note types. +const ( + DiffNote NoteTypeValue = "DiffNote" + DiscussionNote NoteTypeValue = "DiscussionNote" + GenericNote NoteTypeValue = "Note" + LegacyDiffNote NoteTypeValue = "LegacyDiffNote" +) + +// NotificationLevelValue represents a notification level. +type NotificationLevelValue int + +// String implements the fmt.Stringer interface. +func (l NotificationLevelValue) String() string { + return notificationLevelNames[l] +} + +// MarshalJSON implements the json.Marshaler interface. +func (l NotificationLevelValue) MarshalJSON() ([]byte, error) { + return json.Marshal(l.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (l *NotificationLevelValue) UnmarshalJSON(data []byte) error { + var raw any + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + switch raw := raw.(type) { + case float64: + *l = NotificationLevelValue(raw) + case string: + *l = notificationLevelTypes[raw] + case nil: + // No action needed. + default: + return fmt.Errorf("json: cannot unmarshal %T into Go value of type %T", raw, *l) + } + + return nil +} + +// List of valid notification levels. +const ( + DisabledNotificationLevel NotificationLevelValue = iota + ParticipatingNotificationLevel + WatchNotificationLevel + GlobalNotificationLevel + MentionNotificationLevel + CustomNotificationLevel +) + +var notificationLevelNames = [...]string{ + "disabled", + "participating", + "watch", + "global", + "mention", + "custom", +} + +var notificationLevelTypes = map[string]NotificationLevelValue{ + "disabled": DisabledNotificationLevel, + "participating": ParticipatingNotificationLevel, + "watch": WatchNotificationLevel, + "global": GlobalNotificationLevel, + "mention": MentionNotificationLevel, + "custom": CustomNotificationLevel, +} + +// DependencyPackageManagerValue represents a dependency package manager. +// +// GitLab API docs: https://docs.gitlab.com/api/dependencies/ +type DependencyPackageManagerValue string + +// List of available package manager for dependencies +// +// GitLab API docs: https://docs.gitlab.com/api/dependencies/ +const ( + Bundler DependencyPackageManagerValue = "bundler" + Composer DependencyPackageManagerValue = "composer" + Conan DependencyPackageManagerValue = "conan" + Go DependencyPackageManagerValue = "go" + Gradle DependencyPackageManagerValue = "gradle" + Maven DependencyPackageManagerValue = "maven" + NPM DependencyPackageManagerValue = "npm" + NuGet DependencyPackageManagerValue = "nuget" + Pip DependencyPackageManagerValue = "pip" + Pipenv DependencyPackageManagerValue = "pipenv" + PNPM DependencyPackageManagerValue = "pnpm" + Yarn DependencyPackageManagerValue = "yarn" + SBT DependencyPackageManagerValue = "sbt" + Setuptools DependencyPackageManagerValue = "setuptools" +) + +// PipelineScheduleScopeValue represents a pipeline schedule scope within GitLab. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipeline-schedules +type PipelineScheduleScopeValue string + +// List of available pipeline schedule scope values. +// +// GitLab API docs: +// https://docs.gitlab.com/api/pipeline_schedules/#get-all-pipeline-schedules +const ( + PipelineScheduleActive PipelineScheduleScopeValue = "active" + PipelineScheduleInactive PipelineScheduleScopeValue = "inactive" +) + +// ProjectCreationLevelValue represents a project creation level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type ProjectCreationLevelValue string + +// List of available project creation levels. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +const ( + NoOneProjectCreation ProjectCreationLevelValue = "noone" + MaintainerProjectCreation ProjectCreationLevelValue = "maintainer" + DeveloperProjectCreation ProjectCreationLevelValue = "developer" + OwnerProjectCreation ProjectCreationLevelValue = "owner" +) + +// ProjectHookEvent represents a project hook event. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#hook-events +type ProjectHookEvent string + +// List of available project hook events. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#hook-events +const ( + ProjectHookEventPush ProjectHookEvent = "push_events" + ProjectHookEventTagPush ProjectHookEvent = "tag_push_events" + ProjectHookEventIssues ProjectHookEvent = "issues_events" + ProjectHookEventConfidentialIssues ProjectHookEvent = "confidential_issues_events" + ProjectHookEventNote ProjectHookEvent = "note_events" + ProjectHookEventMergeRequests ProjectHookEvent = "merge_requests_events" + ProjectHookEventJob ProjectHookEvent = "job_events" + ProjectHookEventPipeline ProjectHookEvent = "pipeline_events" + ProjectHookEventWiki ProjectHookEvent = "wiki_page_events" + ProjectHookEventReleases ProjectHookEvent = "releases_events" + ProjectHookEventEmoji ProjectHookEvent = "emoji_events" + ProjectHookEventResourceAccessToken ProjectHookEvent = "resource_access_token_events" +) + +// ResourceGroupProcessMode represents a process mode for a resource group +// within a GitLab project. +// +// GitLab API docs: +// https://docs.gitlab.com/ci/resource_groups/#process-modes +type ResourceGroupProcessMode string + +// List of available resource group process modes. +// +// GitLab API docs: +// https://docs.gitlab.com/ci/resource_groups/#process-modes +const ( + Unordered ResourceGroupProcessMode = "unordered" + OldestFirst ResourceGroupProcessMode = "oldest_first" + NewestFirst ResourceGroupProcessMode = "newest_first" +) + +// SharedRunnersSettingValue determines whether shared runners are enabled for a +// group’s subgroups and projects. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-shared_runners_setting +type SharedRunnersSettingValue string + +// List of available shared runner setting levels. +// +// GitLab API docs: +// https://docs.gitlab.com/api/groups/#options-for-shared_runners_setting +const ( + EnabledSharedRunnersSettingValue SharedRunnersSettingValue = "enabled" + DisabledAndOverridableSharedRunnersSettingValue SharedRunnersSettingValue = "disabled_and_overridable" + DisabledAndUnoverridableSharedRunnersSettingValue SharedRunnersSettingValue = "disabled_and_unoverridable" + + // Deprecated: DisabledWithOverrideSharedRunnersSettingValue is deprecated + // in favor of DisabledAndOverridableSharedRunnersSettingValue. + DisabledWithOverrideSharedRunnersSettingValue SharedRunnersSettingValue = "disabled_with_override" +) + +// SubGroupCreationLevelValue represents a sub group creation level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type SubGroupCreationLevelValue string + +// List of available sub group creation levels. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +const ( + OwnerSubGroupCreationLevelValue SubGroupCreationLevelValue = "owner" + MaintainerSubGroupCreationLevelValue SubGroupCreationLevelValue = "maintainer" +) + +// SquashOptionValue represents a squash optional level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-project +type SquashOptionValue string + +// List of available squash options. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/#create-project +const ( + SquashOptionNever SquashOptionValue = "never" + SquashOptionAlways SquashOptionValue = "always" + SquashOptionDefaultOff SquashOptionValue = "default_off" + SquashOptionDefaultOn SquashOptionValue = "default_on" +) + +// TasksCompletionStatus represents tasks of the issue/merge request. +type TasksCompletionStatus struct { + Count int `json:"count"` + CompletedCount int `json:"completed_count"` +} + +// TodoAction represents the available actions that can be performed on a todo. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/ +type TodoAction string + +// The available todo actions. +const ( + TodoAssigned TodoAction = "assigned" + TodoMentioned TodoAction = "mentioned" + TodoBuildFailed TodoAction = "build_failed" + TodoMarked TodoAction = "marked" + TodoApprovalRequired TodoAction = "approval_required" + TodoDirectlyAddressed TodoAction = "directly_addressed" +) + +// TodoTargetType represents the available target that can be linked to a todo. +// +// GitLab API docs: https://docs.gitlab.com/api/todos/ +type TodoTargetType string + +const ( + TodoTargetAlertManagement TodoTargetType = "AlertManagement::Alert" + TodoTargetDesignManagement TodoTargetType = "DesignManagement::Design" + TodoTargetIssue TodoTargetType = "Issue" + TodoTargetMergeRequest TodoTargetType = "MergeRequest" +) + +// UploadType represents the available upload types. +type UploadType string + +// The available upload types. +const ( + UploadAvatar UploadType = "avatar" + UploadFile UploadType = "file" +) + +// VariableTypeValue represents a variable type within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/group_level_variables/ +type VariableTypeValue string + +// List of available variable types. +// +// GitLab API docs: https://docs.gitlab.com/api/group_level_variables/ +const ( + EnvVariableType VariableTypeValue = "env_var" + FileVariableType VariableTypeValue = "file" +) + +// VisibilityValue represents a visibility level within GitLab. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +type VisibilityValue string + +// List of available visibility levels. +// +// GitLab API docs: https://docs.gitlab.com/api/groups/ +const ( + PrivateVisibility VisibilityValue = "private" + InternalVisibility VisibilityValue = "internal" + PublicVisibility VisibilityValue = "public" +) + +// WikiFormatValue represents the available wiki formats. +// +// GitLab API docs: https://docs.gitlab.com/api/wikis/ +type WikiFormatValue string + +// The available wiki formats. +const ( + WikiFormatMarkdown WikiFormatValue = "markdown" + WikiFormatRDoc WikiFormatValue = "rdoc" + WikiFormatASCIIDoc WikiFormatValue = "asciidoc" + WikiFormatOrg WikiFormatValue = "org" +) + +// BoolValue is a boolean value with advanced json unmarshaling features. +type BoolValue bool + +// UnmarshalJSON allows 1, 0, "true", and "false" to be considered as boolean values +// Needed for: +// https://gitlab.com/gitlab-org/gitlab-ce/issues/50122 +// https://gitlab.com/gitlab-org/gitlab/-/issues/233941 +// https://github.com/gitlabhq/terraform-provider-gitlab/issues/348 +func (t *BoolValue) UnmarshalJSON(b []byte) error { + switch string(b) { + case `"1"`: + *t = true + return nil + case `"0"`: + *t = false + return nil + case `"true"`: + *t = true + return nil + case `"false"`: + *t = false + return nil + default: + var v bool + err := json.Unmarshal(b, &v) + *t = BoolValue(v) + return err + } +} + +// CIPipelineVariablesMinimumOverrideRoleValue represents an access control +// value used for managing access to the CI Pipeline Variable Override feature. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/ +type CIPipelineVariablesMinimumOverrideRoleValue = string + +// List of available CIPipelineVariablesMinimumOverrideRoleValue values. +// +// GitLab API docs: https://docs.gitlab.com/api/projects/ +const ( + CIPipelineVariablesNoOneAllowedRole CIPipelineVariablesMinimumOverrideRoleValue = "no_one_allowed" + CiPipelineVariablesOwnerRole CIPipelineVariablesMinimumOverrideRoleValue = "owner" + CiPipelineVariablesMaintainerRole CIPipelineVariablesMinimumOverrideRoleValue = "maintainer" + CIPipelineVariablesDeveloperRole CIPipelineVariablesMinimumOverrideRoleValue = "developer" +) diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/usage_data.go b/vendor/gitlab.com/gitlab-org/api/client-go/usage_data.go new file mode 100644 index 000000000..788522a64 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/usage_data.go @@ -0,0 +1,203 @@ +package gitlab + +import ( + "bytes" + "io" + "net/http" + "time" +) + +type ( + UsageDataServiceInterface interface { + GetServicePing(options ...RequestOptionFunc) (*ServicePingData, *Response, error) + GetMetricDefinitionsAsYAML(options ...RequestOptionFunc) (io.Reader, *Response, error) + GetQueries(options ...RequestOptionFunc) (*ServicePingQueries, *Response, error) + GetNonSQLMetrics(options ...RequestOptionFunc) (*ServicePingNonSqlMetrics, *Response, error) + TrackEvent(opt *TrackEventOptions, options ...RequestOptionFunc) (*Response, error) + TrackEvents(opt *TrackEventsOptions, options ...RequestOptionFunc) (*Response, error) + } + + // UsageDataService handles communication with the service ping related + // methods of the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/usage_data/ + UsageDataService struct { + client *Client + } +) + +// ServicePingData represents a service ping data response. +type ServicePingData struct { + RecordedAt *time.Time `json:"recorded_at"` + License map[string]string `json:"license"` + Counts map[string]int `json:"counts"` +} + +// GetServicePing gets the current service ping data. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#export-service-ping-data +func (s *UsageDataService) GetServicePing(options ...RequestOptionFunc) (*ServicePingData, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "usage_data/service_ping", nil, options) + if err != nil { + return nil, nil, err + } + + sp := new(ServicePingData) + resp, err := s.client.Do(req, sp) + if err != nil { + return nil, resp, err + } + + return sp, resp, nil +} + +// GetMetricDefinitionsAsYAML gets all metric definitions as a single YAML file. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#export-metric-definitions-as-a-single-yaml-file +func (s *UsageDataService) GetMetricDefinitionsAsYAML(options ...RequestOptionFunc) (io.Reader, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "usage_data/metric_definitions", nil, options) + if err != nil { + return nil, nil, err + } + + req.Header.Set("Accept", "text/yaml") + + var buf bytes.Buffer + resp, err := s.client.Do(req, &buf) + if err != nil { + return nil, resp, err + } + + return &buf, resp, nil +} + +// ServicePingQueries represents the raw service ping SQL queries. +type ServicePingQueries struct { + RecordedAt *time.Time `json:"recorded_at"` + UUID string `json:"uuid"` + Hostname string `json:"hostname"` + Version string `json:"version"` + InstallationType string `json:"installation_type"` + ActiveUserCount string `json:"active_user_count"` + Edition string `json:"edition"` + LicenseMD5 string `json:"license_md5"` + LicenseSHA256 string `json:"license_sha256"` + LicenseID string `json:"license_id"` + HistoricalMaxUsers int `json:"historical_max_users"` + Licensee map[string]string `json:"licensee"` + LicenseUserCount int `json:"license_user_count"` + LicenseStartsAt string `json:"license_starts_at"` + LicenseExpiresAt string `json:"license_expires_at"` + LicensePlan string `json:"license_plan"` + LicenseAddOns map[string]int `json:"license_add_ons"` + LicenseTrial string `json:"license_trial"` + LicenseSubscriptionID string `json:"license_subscription_id"` + License map[string]string `json:"license"` + Settings map[string]string `json:"settings"` + Counts map[string]string `json:"counts"` +} + +// GetQueries gets all raw SQL queries used to compute service ping. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#export-service-ping-sql-queries +func (s *UsageDataService) GetQueries(options ...RequestOptionFunc) (*ServicePingQueries, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "usage_data/queries", nil, options) + if err != nil { + return nil, nil, err + } + + sq := new(ServicePingQueries) + resp, err := s.client.Do(req, sq) + if err != nil { + return nil, resp, err + } + + return sq, resp, nil +} + +// ServicePingNonSqlMetrics represents the non-SQL metrics used in service ping. +type ServicePingNonSqlMetrics struct { + RecordedAt string `json:"recorded_at"` + UUID string `json:"uuid"` + Hostname string `json:"hostname"` + Version string `json:"version"` + InstallationType string `json:"installation_type"` + ActiveUserCount int `json:"active_user_count"` + Edition string `json:"edition"` + LicenseMD5 string `json:"license_md5"` + LicenseSHA256 string `json:"license_sha256"` + LicenseID string `json:"license_id"` + HistoricalMaxUsers int `json:"historical_max_users"` + Licensee map[string]string `json:"licensee"` + LicenseUserCount int `json:"license_user_count"` + LicenseStartsAt string `json:"license_starts_at"` + LicenseExpiresAt string `json:"license_expires_at"` + LicensePlan string `json:"license_plan"` + LicenseAddOns map[string]int `json:"license_add_ons"` + LicenseTrial string `json:"license_trial"` + LicenseSubscriptionID string `json:"license_subscription_id"` + License map[string]string `json:"license"` + Settings map[string]string `json:"settings"` +} + +// GetNonSQLMetrics gets all non-SQL metrics data used in the service ping. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#usagedatanonsqlmetrics-api +func (s *UsageDataService) GetNonSQLMetrics(options ...RequestOptionFunc) (*ServicePingNonSqlMetrics, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "usage_data/non_sql_metrics", nil, options) + if err != nil { + return nil, nil, err + } + + nsm := new(ServicePingNonSqlMetrics) + resp, err := s.client.Do(req, nsm) + if err != nil { + return nil, resp, err + } + + return nsm, resp, nil +} + +// TrackEventOptions represents the available options for tracking events. +type TrackEventOptions struct { + Event string `json:"event" url:"event"` + SendToSnowplow *bool `json:"send_to_snowplow,omitempty" url:"send_to_snowplow,omitempty"` + NamespaceID *int `json:"namespace_id,omitempty" url:"namespace_id,omitempty"` + ProjectID *int `json:"project_id,omitempty" url:"project_id,omitempty"` + AdditionalProperties map[string]string `json:"additional_properties,omitempty" url:"additional_properties,omitempty"` +} + +// TrackEvent tracks an internal GitLab event. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#events-tracking-api +func (s *UsageDataService) TrackEvent(opt *TrackEventOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "usage_data/track_event", opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// TrackEventsOptions represents the available options for tracking multiple events. +type TrackEventsOptions struct { + Events []TrackEventOptions `json:"events" url:"events"` +} + +// TrackEvents tracks multiple internal GitLab events. +// +// GitLab API docs: +// https://docs.gitlab.com/api/usage_data/#events-tracking-api +func (s *UsageDataService) TrackEvents(opt *TrackEventsOptions, options ...RequestOptionFunc) (*Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "usage_data/track_events", opt, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/users.go b/vendor/gitlab.com/gitlab-org/api/client-go/users.go new file mode 100644 index 000000000..e790aa4c1 --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/users.go @@ -0,0 +1,1740 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net" + "net/http" + "strings" + "time" + + "github.com/hashicorp/go-retryablehttp" +) + +type ( + UsersServiceInterface interface { + ListUsers(opt *ListUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) + GetUser(user int, opt GetUsersOptions, options ...RequestOptionFunc) (*User, *Response, error) + CreateUser(opt *CreateUserOptions, options ...RequestOptionFunc) (*User, *Response, error) + ModifyUser(user int, opt *ModifyUserOptions, options ...RequestOptionFunc) (*User, *Response, error) + DeleteUser(user int, options ...RequestOptionFunc) (*Response, error) + CurrentUser(options ...RequestOptionFunc) (*User, *Response, error) + CurrentUserStatus(options ...RequestOptionFunc) (*UserStatus, *Response, error) + GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) + SetUserStatus(opt *UserStatusOptions, options ...RequestOptionFunc) (*UserStatus, *Response, error) + GetUserAssociationsCount(user int, options ...RequestOptionFunc) (*UserAssociationsCount, *Response, error) + ListSSHKeys(opt *ListSSHKeysOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) + ListSSHKeysForUser(uid any, opt *ListSSHKeysForUserOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) + GetSSHKey(key int, options ...RequestOptionFunc) (*SSHKey, *Response, error) + GetSSHKeyForUser(user int, key int, options ...RequestOptionFunc) (*SSHKey, *Response, error) + AddSSHKey(opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) + AddSSHKeyForUser(user int, opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) + DeleteSSHKey(key int, options ...RequestOptionFunc) (*Response, error) + DeleteSSHKeyForUser(user, key int, options ...RequestOptionFunc) (*Response, error) + ListGPGKeys(options ...RequestOptionFunc) ([]*GPGKey, *Response, error) + GetGPGKey(key int, options ...RequestOptionFunc) (*GPGKey, *Response, error) + AddGPGKey(opt *AddGPGKeyOptions, options ...RequestOptionFunc) (*GPGKey, *Response, error) + DeleteGPGKey(key int, options ...RequestOptionFunc) (*Response, error) + ListGPGKeysForUser(user int, options ...RequestOptionFunc) ([]*GPGKey, *Response, error) + GetGPGKeyForUser(user, key int, options ...RequestOptionFunc) (*GPGKey, *Response, error) + AddGPGKeyForUser(user int, opt *AddGPGKeyOptions, options ...RequestOptionFunc) (*GPGKey, *Response, error) + DeleteGPGKeyForUser(user, key int, options ...RequestOptionFunc) (*Response, error) + ListEmails(options ...RequestOptionFunc) ([]*Email, *Response, error) + ListEmailsForUser(user int, opt *ListEmailsForUserOptions, options ...RequestOptionFunc) ([]*Email, *Response, error) + GetEmail(email int, options ...RequestOptionFunc) (*Email, *Response, error) + AddEmail(opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) + AddEmailForUser(user int, opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) + DeleteEmail(email int, options ...RequestOptionFunc) (*Response, error) + DeleteEmailForUser(user, email int, options ...RequestOptionFunc) (*Response, error) + BlockUser(user int, options ...RequestOptionFunc) error + UnblockUser(user int, options ...RequestOptionFunc) error + BanUser(user int, options ...RequestOptionFunc) error + UnbanUser(user int, options ...RequestOptionFunc) error + DeactivateUser(user int, options ...RequestOptionFunc) error + ActivateUser(user int, options ...RequestOptionFunc) error + ApproveUser(user int, options ...RequestOptionFunc) error + RejectUser(user int, options ...RequestOptionFunc) error + GetAllImpersonationTokens(user int, opt *GetAllImpersonationTokensOptions, options ...RequestOptionFunc) ([]*ImpersonationToken, *Response, error) + GetImpersonationToken(user, token int, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) + CreateImpersonationToken(user int, opt *CreateImpersonationTokenOptions, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) + RevokeImpersonationToken(user, token int, options ...RequestOptionFunc) (*Response, error) + CreatePersonalAccessToken(user int, opt *CreatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + CreatePersonalAccessTokenForCurrentUser(opt *CreatePersonalAccessTokenForCurrentUserOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) + GetUserActivities(opt *GetUserActivitiesOptions, options ...RequestOptionFunc) ([]*UserActivity, *Response, error) + GetUserMemberships(user int, opt *GetUserMembershipOptions, options ...RequestOptionFunc) ([]*UserMembership, *Response, error) + DisableTwoFactor(user int, options ...RequestOptionFunc) error + CreateUserRunner(opts *CreateUserRunnerOptions, options ...RequestOptionFunc) (*UserRunner, *Response, error) + CreateServiceAccountUser(opts *CreateServiceAccountUserOptions, options ...RequestOptionFunc) (*User, *Response, error) + ListServiceAccounts(opt *ListServiceAccountsOptions, options ...RequestOptionFunc) ([]*ServiceAccount, *Response, error) + UploadAvatar(avatar io.Reader, filename string, options ...RequestOptionFunc) (*User, *Response, error) + DeleteUserIdentity(user int, provider string, options ...RequestOptionFunc) (*Response, error) + + // events.go + ListUserContributionEvents(uid any, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) + } + + // UsersService handles communication with the user related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/users/ + UsersService struct { + client *Client + } +) + +var _ UsersServiceInterface = (*UsersService)(nil) + +// List a couple of standard errors. +var ( + ErrUserActivatePrevented = errors.New("cannot activate a user that is blocked by admin or by LDAP synchronization") + ErrUserApprovePrevented = errors.New("cannot approve a user that is blocked by admin or by LDAP synchronization") + ErrUserBlockPrevented = errors.New("cannot block a user that is already blocked by LDAP synchronization") + ErrUserConflict = errors.New("user does not have a pending request") + ErrUserDeactivatePrevented = errors.New("cannot deactivate a user that is blocked by admin or by LDAP synchronization") + ErrUserDisableTwoFactorPrevented = errors.New("cannot disable two factor authentication if not authenticated as administrator") + ErrUserNotFound = errors.New("user does not exist") + ErrUserRejectPrevented = errors.New("cannot reject a user if not authenticated as administrator") + ErrUserTwoFactorNotEnabled = errors.New("cannot disable two factor authentication if not enabled") + ErrUserUnblockPrevented = errors.New("cannot unblock a user that is blocked by LDAP synchronization") +) + +// BasicUser included in other service responses (such as merge requests, pipelines, etc). +type BasicUser struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + State string `json:"state"` + Locked bool `json:"locked"` + CreatedAt *time.Time `json:"created_at"` + AvatarURL string `json:"avatar_url"` + WebURL string `json:"web_url"` +} + +// ServiceAccount represents a GitLab service account. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_service_accounts/ +type ServiceAccount struct { + ID int `json:"id"` + Username string `json:"username"` + Name string `json:"name"` +} + +// User represents a GitLab user. +// +// GitLab API docs: https://docs.gitlab.com/api/users/ +type User struct { + ID int `json:"id"` + Username string `json:"username"` + Email string `json:"email"` + Name string `json:"name"` + State string `json:"state"` + WebURL string `json:"web_url"` + CreatedAt *time.Time `json:"created_at"` + Bio string `json:"bio"` + Bot bool `json:"bot"` + Location string `json:"location"` + PublicEmail string `json:"public_email"` + Skype string `json:"skype"` + Linkedin string `json:"linkedin"` + Twitter string `json:"twitter"` + WebsiteURL string `json:"website_url"` + Organization string `json:"organization"` + JobTitle string `json:"job_title"` + ExternUID string `json:"extern_uid"` + Provider string `json:"provider"` + ThemeID int `json:"theme_id"` + LastActivityOn *ISOTime `json:"last_activity_on"` + ColorSchemeID int `json:"color_scheme_id"` + IsAdmin bool `json:"is_admin"` + IsAuditor bool `json:"is_auditor"` + AvatarURL string `json:"avatar_url"` + CanCreateGroup bool `json:"can_create_group"` + CanCreateProject bool `json:"can_create_project"` + ProjectsLimit int `json:"projects_limit"` + CurrentSignInAt *time.Time `json:"current_sign_in_at"` + CurrentSignInIP *net.IP `json:"current_sign_in_ip"` + LastSignInAt *time.Time `json:"last_sign_in_at"` + LastSignInIP *net.IP `json:"last_sign_in_ip"` + ConfirmedAt *time.Time `json:"confirmed_at"` + TwoFactorEnabled bool `json:"two_factor_enabled"` + Note string `json:"note"` + Identities []*UserIdentity `json:"identities"` + External bool `json:"external"` + PrivateProfile bool `json:"private_profile"` + SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"` + ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"` + UsingLicenseSeat bool `json:"using_license_seat"` + CustomAttributes []*CustomAttribute `json:"custom_attributes"` + NamespaceID int `json:"namespace_id"` + Locked bool `json:"locked"` + CreatedBy *BasicUser `json:"created_by"` +} + +// UserIdentity represents a user identity. +type UserIdentity struct { + Provider string `json:"provider"` + ExternUID string `json:"extern_uid"` +} + +// UserAvatar represents a GitLab user avatar. +// +// GitLab API docs: https://docs.gitlab.com/api/users/ +type UserAvatar struct { + Filename string + Image io.Reader +} + +// MarshalJSON implements the json.Marshaler interface. +func (a *UserAvatar) MarshalJSON() ([]byte, error) { + if a.Filename == "" && a.Image == nil { + return []byte(`""`), nil + } + type alias UserAvatar + return json.Marshal((*alias)(a)) +} + +// ListUsersOptions represents the available ListUsers() options. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#list-users +type ListUsersOptions struct { + ListOptions + Active *bool `url:"active,omitempty" json:"active,omitempty"` + Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"` + Humans *bool `url:"humans,omitempty" json:"humans,omitempty"` + ExcludeInternal *bool `url:"exclude_internal,omitempty" json:"exclude_internal,omitempty"` + ExcludeActive *bool `url:"exclude_active,omitempty" json:"exclude_active,omitempty"` + ExcludeExternal *bool `url:"exclude_external,omitempty" json:"exclude_external,omitempty"` + ExcludeHumans *bool `url:"exclude_humans,omitempty" json:"exclude_humans,omitempty"` + + // The options below are only available for admins. + Search *string `url:"search,omitempty" json:"search,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + ExternalUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"` + CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"` + OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"` + Sort *string `url:"sort,omitempty" json:"sort,omitempty"` + TwoFactor *string `url:"two_factor,omitempty" json:"two_factor,omitempty"` + Admins *bool `url:"admins,omitempty" json:"admins,omitempty"` + External *bool `url:"external,omitempty" json:"external,omitempty"` + WithoutProjects *bool `url:"without_projects,omitempty" json:"without_projects,omitempty"` + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` + WithoutProjectBots *bool `url:"without_project_bots,omitempty" json:"without_project_bots,omitempty"` +} + +// ListUsers gets a list of users. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#list-users +func (s *UsersService) ListUsers(opt *ListUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "users", opt, options) + if err != nil { + return nil, nil, err + } + + var usr []*User + resp, err := s.client.Do(req, &usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// GetUsersOptions represents the available GetUser() options. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#get-a-single-user +type GetUsersOptions struct { + WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` +} + +// GetUser gets a single user. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#get-a-single-user +func (s *UsersService) GetUser(user int, opt GetUsersOptions, options ...RequestOptionFunc) (*User, *Response, error) { + u := fmt.Sprintf("users/%d", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// CreateUserOptions represents the available CreateUser() options. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#create-a-user +type CreateUserOptions struct { + Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` + Avatar *UserAvatar `url:"-" json:"-"` + Bio *string `url:"bio,omitempty" json:"bio,omitempty"` + CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` + Email *string `url:"email,omitempty" json:"email,omitempty"` + External *bool `url:"external,omitempty" json:"external,omitempty"` + ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` + ForceRandomPassword *bool `url:"force_random_password,omitempty" json:"force_random_password,omitempty"` + JobTitle *string `url:"job_title,omitempty" json:"job_title,omitempty"` + Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` + Location *string `url:"location,omitempty" json:"location,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Note *string `url:"note,omitempty" json:"note,omitempty"` + Organization *string `url:"organization,omitempty" json:"organization,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` + ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + ResetPassword *bool `url:"reset_password,omitempty" json:"reset_password,omitempty"` + SkipConfirmation *bool `url:"skip_confirmation,omitempty" json:"skip_confirmation,omitempty"` + Skype *string `url:"skype,omitempty" json:"skype,omitempty"` + ThemeID *int `url:"theme_id,omitempty" json:"theme_id,omitempty"` + Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` +} + +// CreateUser creates a new user. Note only administrators can create new users. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#create-a-user +func (s *UsersService) CreateUser(opt *CreateUserOptions, options ...RequestOptionFunc) (*User, *Response, error) { + var err error + var req *retryablehttp.Request + + if opt.Avatar == nil { + req, err = s.client.NewRequest(http.MethodPost, "users", opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPost, + "users", + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// ModifyUserOptions represents the available ModifyUser() options. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#modify-a-user +type ModifyUserOptions struct { + Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` + Avatar *UserAvatar `url:"-" json:"avatar,omitempty"` + Bio *string `url:"bio,omitempty" json:"bio,omitempty"` + CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` + CommitEmail *string `url:"commit_email,omitempty" json:"commit_email,omitempty"` + Email *string `url:"email,omitempty" json:"email,omitempty"` + External *bool `url:"external,omitempty" json:"external,omitempty"` + ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` + JobTitle *string `url:"job_title,omitempty" json:"job_title,omitempty"` + Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` + Location *string `url:"location,omitempty" json:"location,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + Note *string `url:"note,omitempty" json:"note,omitempty"` + Organization *string `url:"organization,omitempty" json:"organization,omitempty"` + Password *string `url:"password,omitempty" json:"password,omitempty"` + PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` + ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` + Provider *string `url:"provider,omitempty" json:"provider,omitempty"` + PublicEmail *string `url:"public_email,omitempty" json:"public_email,omitempty"` + SkipReconfirmation *bool `url:"skip_reconfirmation,omitempty" json:"skip_reconfirmation,omitempty"` + Skype *string `url:"skype,omitempty" json:"skype,omitempty"` + ThemeID *int `url:"theme_id,omitempty" json:"theme_id,omitempty"` + Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` +} + +// ModifyUser modifies an existing user. Only administrators can change attributes +// of a user. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#modify-a-user +func (s *UsersService) ModifyUser(user int, opt *ModifyUserOptions, options ...RequestOptionFunc) (*User, *Response, error) { + var err error + var req *retryablehttp.Request + u := fmt.Sprintf("users/%d", user) + + if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) { + req, err = s.client.NewRequest(http.MethodPut, u, opt, options) + } else { + req, err = s.client.UploadRequest( + http.MethodPut, + u, + opt.Avatar.Image, + opt.Avatar.Filename, + UploadAvatar, + opt, + options, + ) + } + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// DeleteUser deletes a user. Available only for administrators. This is an +// idempotent function, calling this function for a non-existent user id still +// returns a status code 200 OK. The JSON response differs if the user was +// actually deleted or not. In the former the user is returned and in the +// latter not. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#delete-a-user +func (s *UsersService) DeleteUser(user int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d", user) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// CurrentUser gets currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/users/#get-the-current-user +func (s *UsersService) CurrentUser(options ...RequestOptionFunc) (*User, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user", nil, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// UserStatus represents the current status of a user +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#get-your-user-status +type UserStatus struct { + Emoji string `json:"emoji"` + Availability AvailabilityValue `json:"availability"` + Message string `json:"message"` + MessageHTML string `json:"message_html"` + ClearStatusAt *time.Time `json:"clear_status_at"` +} + +// CurrentUserStatus retrieves the user status +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#get-your-user-status +func (s *UsersService) CurrentUserStatus(options ...RequestOptionFunc) (*UserStatus, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user/status", nil, options) + if err != nil { + return nil, nil, err + } + + status := new(UserStatus) + resp, err := s.client.Do(req, status) + if err != nil { + return nil, resp, err + } + + return status, resp, nil +} + +// GetUserStatus retrieves a user's status. +// +// uid can be either a user ID (int) or a username (string); will trim one "@" character off the username, if present. +// Other types will cause an error to be returned. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#get-the-status-of-a-user +func (s *UsersService) GetUserStatus(uid any, options ...RequestOptionFunc) (*UserStatus, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + + u := fmt.Sprintf("users/%s/status", strings.TrimPrefix(user, "@")) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + status := new(UserStatus) + resp, err := s.client.Do(req, status) + if err != nil { + return nil, resp, err + } + + return status, resp, nil +} + +// UserStatusOptions represents the options required to set the status +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#set-your-user-status +type UserStatusOptions struct { + Emoji *string `url:"emoji,omitempty" json:"emoji,omitempty"` + Availability *AvailabilityValue `url:"availability,omitempty" json:"availability,omitempty"` + Message *string `url:"message,omitempty" json:"message,omitempty"` + ClearStatusAfter *ClearStatusAfterValue `url:"clear_status_after,omitempty" json:"clear_status_after,omitempty"` +} + +// SetUserStatus sets the user's status +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#set-your-user-status +func (s *UsersService) SetUserStatus(opt *UserStatusOptions, options ...RequestOptionFunc) (*UserStatus, *Response, error) { + req, err := s.client.NewRequest(http.MethodPut, "user/status", opt, options) + if err != nil { + return nil, nil, err + } + + status := new(UserStatus) + resp, err := s.client.Do(req, status) + if err != nil { + return nil, resp, err + } + + return status, resp, nil +} + +// UserAssociationsCount represents the user associations count. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/users/#get-a-count-of-a-users-projects-groups-issues-and-merge-requests +type UserAssociationsCount struct { + GroupsCount int `json:"groups_count"` + ProjectsCount int `json:"projects_count"` + IssuesCount int `json:"issues_count"` + MergeRequestsCount int `json:"merge_requests_count"` +} + +// GetUserAssociationsCount gets a list of a specified user associations. +// +// Gitlab API docs: +// https://docs.gitlab.com/api/users/#get-a-count-of-a-users-projects-groups-issues-and-merge-requests +func (s *UsersService) GetUserAssociationsCount(user int, options ...RequestOptionFunc) (*UserAssociationsCount, *Response, error) { + u := fmt.Sprintf("users/%d/associations_count", user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + uac := new(UserAssociationsCount) + resp, err := s.client.Do(req, uac) + if err != nil { + return nil, resp, err + } + + return uac, resp, nil +} + +// SSHKey represents a SSH key. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#list-all-ssh-keys +type SSHKey struct { + ID int `json:"id"` + Title string `json:"title"` + Key string `json:"key"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *time.Time `json:"expires_at"` + UsageType string `json:"usage_type"` +} + +// ListSSHKeysOptions represents the available ListSSHKeys options. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#list-all-ssh-keys +type ListSSHKeysOptions ListOptions + +// ListSSHKeys gets a list of currently authenticated user's SSH keys. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#list-all-ssh-keys +func (s *UsersService) ListSSHKeys(opt *ListSSHKeysOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user/keys", opt, options) + if err != nil { + return nil, nil, err + } + + var k []*SSHKey + resp, err := s.client.Do(req, &k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// ListSSHKeysForUserOptions represents the available ListSSHKeysForUser() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#list-all-ssh-keys-for-a-user +type ListSSHKeysForUserOptions ListOptions + +// ListSSHKeysForUser gets a list of a specified user's SSH keys. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#list-all-ssh-keys-for-a-user +func (s *UsersService) ListSSHKeysForUser(uid any, opt *ListSSHKeysForUserOptions, options ...RequestOptionFunc) ([]*SSHKey, *Response, error) { + user, err := parseID(uid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("users/%s/keys", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var k []*SSHKey + resp, err := s.client.Do(req, &k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// GetSSHKey gets a single key. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#get-an-ssh-key +func (s *UsersService) GetSSHKey(key int, options ...RequestOptionFunc) (*SSHKey, *Response, error) { + u := fmt.Sprintf("user/keys/%d", key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// GetSSHKeyForUser gets a single key for a given user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#get-an-ssh-key-for-a-user +func (s *UsersService) GetSSHKeyForUser(user int, key int, options ...RequestOptionFunc) (*SSHKey, *Response, error) { + u := fmt.Sprintf("users/%d/keys/%d", user, key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// AddSSHKeyOptions represents the available AddSSHKey() options. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#add-an-ssh-key +type AddSSHKeyOptions struct { + Title *string `url:"title,omitempty" json:"title,omitempty"` + Key *string `url:"key,omitempty" json:"key,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` + UsageType *string `url:"usage_type,omitempty" json:"usage_type,omitempty"` +} + +// AddSSHKey creates a new key owned by the currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#add-an-ssh-key +func (s *UsersService) AddSSHKey(opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "user/keys", opt, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// AddSSHKeyForUser creates new key owned by specified user. Available only for +// admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#add-an-ssh-key-for-a-user +func (s *UsersService) AddSSHKeyForUser(user int, opt *AddSSHKeyOptions, options ...RequestOptionFunc) (*SSHKey, *Response, error) { + u := fmt.Sprintf("users/%d/keys", user) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(SSHKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// DeleteSSHKey deletes key owned by currently authenticated user. This is an +// idempotent function and calling it on a key that is already deleted or not +// available results in 200 OK. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#delete-an-ssh-key +func (s *UsersService) DeleteSSHKey(key int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("user/keys/%d", key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteSSHKeyForUser deletes key owned by a specified user. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#delete-an-ssh-key-for-a-user +func (s *UsersService) DeleteSSHKeyForUser(user, key int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/keys/%d", user, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// GPGKey represents a GPG key. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#list-all-gpg-keys +type GPGKey struct { + ID int `json:"id"` + Key string `json:"key"` + CreatedAt *time.Time `json:"created_at"` +} + +// ListGPGKeys gets a list of currently authenticated user’s GPG keys. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#list-all-gpg-keys +func (s *UsersService) ListGPGKeys(options ...RequestOptionFunc) ([]*GPGKey, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user/gpg_keys", nil, options) + if err != nil { + return nil, nil, err + } + + var ks []*GPGKey + resp, err := s.client.Do(req, &ks) + if err != nil { + return nil, resp, err + } + + return ks, resp, nil +} + +// GetGPGKey gets a specific GPG key of currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#get-a-gpg-key +func (s *UsersService) GetGPGKey(key int, options ...RequestOptionFunc) (*GPGKey, *Response, error) { + u := fmt.Sprintf("user/gpg_keys/%d", key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(GPGKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// AddGPGKeyOptions represents the available AddGPGKey() options. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#add-a-gpg-key +type AddGPGKeyOptions struct { + Key *string `url:"key,omitempty" json:"key,omitempty"` +} + +// AddGPGKey creates a new GPG key owned by the currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#add-a-gpg-key +func (s *UsersService) AddGPGKey(opt *AddGPGKeyOptions, options ...RequestOptionFunc) (*GPGKey, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "user/gpg_keys", opt, options) + if err != nil { + return nil, nil, err + } + + k := new(GPGKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// DeleteGPGKey deletes a GPG key owned by currently authenticated user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#delete-a-gpg-key +func (s *UsersService) DeleteGPGKey(key int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("user/gpg_keys/%d", key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// ListGPGKeysForUser gets a list of a specified user’s GPG keys. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#list-all-gpg-keys-for-a-user +func (s *UsersService) ListGPGKeysForUser(user int, options ...RequestOptionFunc) ([]*GPGKey, *Response, error) { + u := fmt.Sprintf("users/%d/gpg_keys", user) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + var ks []*GPGKey + resp, err := s.client.Do(req, &ks) + if err != nil { + return nil, resp, err + } + + return ks, resp, nil +} + +// GetGPGKeyForUser gets a specific GPG key for a given user. +// +// GitLab API docs: https://docs.gitlab.com/api/user_keys/#get-a-gpg-key-for-a-user +func (s *UsersService) GetGPGKeyForUser(user, key int, options ...RequestOptionFunc) (*GPGKey, *Response, error) { + u := fmt.Sprintf("users/%d/gpg_keys/%d", user, key) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + k := new(GPGKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// AddGPGKeyForUser creates new GPG key owned by the specified user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#add-a-gpg-key-for-a-user +func (s *UsersService) AddGPGKeyForUser(user int, opt *AddGPGKeyOptions, options ...RequestOptionFunc) (*GPGKey, *Response, error) { + u := fmt.Sprintf("users/%d/gpg_keys", user) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + k := new(GPGKey) + resp, err := s.client.Do(req, k) + if err != nil { + return nil, resp, err + } + + return k, resp, nil +} + +// DeleteGPGKeyForUser deletes a GPG key owned by a specified user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_keys/#delete-a-gpg-key-for-a-user +func (s *UsersService) DeleteGPGKeyForUser(user, key int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/gpg_keys/%d", user, key) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// Email represents an Email. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#list-all-email-addresses +type Email struct { + ID int `json:"id"` + Email string `json:"email"` + ConfirmedAt *time.Time `json:"confirmed_at"` +} + +// ListEmails gets a list of currently authenticated user's Emails. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#list-all-email-addresses +func (s *UsersService) ListEmails(options ...RequestOptionFunc) ([]*Email, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user/emails", nil, options) + if err != nil { + return nil, nil, err + } + + var e []*Email + resp, err := s.client.Do(req, &e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// ListEmailsForUserOptions represents the available ListEmailsForUser() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#list-all-email-addresses-for-a-user +type ListEmailsForUserOptions ListOptions + +// ListEmailsForUser gets a list of a specified user's Emails. Available +// only for admin +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#list-all-email-addresses-for-a-user +func (s *UsersService) ListEmailsForUser(user int, opt *ListEmailsForUserOptions, options ...RequestOptionFunc) ([]*Email, *Response, error) { + u := fmt.Sprintf("users/%d/emails", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var e []*Email + resp, err := s.client.Do(req, &e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// GetEmail gets a single email. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#get-details-on-an-email-address +func (s *UsersService) GetEmail(email int, options ...RequestOptionFunc) (*Email, *Response, error) { + u := fmt.Sprintf("user/emails/%d", email) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// AddEmailOptions represents the available AddEmail() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#add-an-email-address +type AddEmailOptions struct { + Email *string `url:"email,omitempty" json:"email,omitempty"` + SkipConfirmation *bool `url:"skip_confirmation,omitempty" json:"skip_confirmation,omitempty"` +} + +// AddEmail creates a new email owned by the currently authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#add-an-email-address +func (s *UsersService) AddEmail(opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "user/emails", opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// AddEmailForUser creates new email owned by specified user. Available only for +// admin. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#add-an-email-address-for-a-user +func (s *UsersService) AddEmailForUser(user int, opt *AddEmailOptions, options ...RequestOptionFunc) (*Email, *Response, error) { + u := fmt.Sprintf("users/%d/emails", user) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + e := new(Email) + resp, err := s.client.Do(req, e) + if err != nil { + return nil, resp, err + } + + return e, resp, nil +} + +// DeleteEmail deletes email owned by currently authenticated user. This is an +// idempotent function and calling it on a key that is already deleted or not +// available results in 200 OK. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#delete-an-email-address +func (s *UsersService) DeleteEmail(email int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("user/emails/%d", email) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// DeleteEmailForUser deletes email owned by a specified user. Available only +// for admin. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_email_addresses/#delete-an-email-address-for-a-user +func (s *UsersService) DeleteEmailForUser(user, email int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/emails/%d", user, email) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// BlockUser blocks the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#block-access-to-a-user +func (s *UsersService) BlockUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/block", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 403: + return ErrUserBlockPrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// UnblockUser unblocks the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#unblock-access-to-a-user +func (s *UsersService) UnblockUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/unblock", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 403: + return ErrUserUnblockPrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// BanUser bans the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#ban-a-user +func (s *UsersService) BanUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/ban", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// UnbanUser unbans the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#unban-a-user +func (s *UsersService) UnbanUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/unban", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// DeactivateUser deactivate the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#deactivate-a-user +func (s *UsersService) DeactivateUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/deactivate", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 403: + return ErrUserDeactivatePrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// ActivateUser activate the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#reactivate-a-user +func (s *UsersService) ActivateUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/activate", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 403: + return ErrUserActivatePrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// ApproveUser approve the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#approve-access-to-a-user +func (s *UsersService) ApproveUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/approve", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 201: + return nil + case 403: + return ErrUserApprovePrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// RejectUser reject the specified user. Available only for admin. +// +// GitLab API docs: https://docs.gitlab.com/api/user_moderation/#reject-access-to-a-user +func (s *UsersService) RejectUser(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/reject", user) + + req, err := s.client.NewRequest(http.MethodPost, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 200: + return nil + case 403: + return ErrUserRejectPrevented + case 404: + return ErrUserNotFound + case 409: + return ErrUserConflict + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// ImpersonationToken represents an impersonation token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#list-all-impersonation-tokens-for-a-user +type ImpersonationToken struct { + ID int `json:"id"` + Name string `json:"name"` + Active bool `json:"active"` + Token string `json:"token"` + Scopes []string `json:"scopes"` + Revoked bool `json:"revoked"` + CreatedAt *time.Time `json:"created_at"` + ExpiresAt *ISOTime `json:"expires_at"` + LastUsedAt *time.Time `json:"last_used_at"` +} + +// GetAllImpersonationTokensOptions represents the available +// GetAllImpersonationTokens() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#list-all-impersonation-tokens-for-a-user +type GetAllImpersonationTokensOptions struct { + ListOptions + State *string `url:"state,omitempty" json:"state,omitempty"` +} + +// GetAllImpersonationTokens retrieves all impersonation tokens of a user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#list-all-impersonation-tokens-for-a-user +func (s *UsersService) GetAllImpersonationTokens(user int, opt *GetAllImpersonationTokensOptions, options ...RequestOptionFunc) ([]*ImpersonationToken, *Response, error) { + u := fmt.Sprintf("users/%d/impersonation_tokens", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ts []*ImpersonationToken + resp, err := s.client.Do(req, &ts) + if err != nil { + return nil, resp, err + } + + return ts, resp, nil +} + +// GetImpersonationToken retrieves an impersonation token of a user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#get-an-impersonation-token-for-a-user +func (s *UsersService) GetImpersonationToken(user, token int, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) { + u := fmt.Sprintf("users/%d/impersonation_tokens/%d", user, token) + + req, err := s.client.NewRequest(http.MethodGet, u, nil, options) + if err != nil { + return nil, nil, err + } + + t := new(ImpersonationToken) + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// CreateImpersonationTokenOptions represents the available +// CreateImpersonationToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-an-impersonation-token +type CreateImpersonationTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` + ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// CreateImpersonationToken creates an impersonation token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-an-impersonation-token +func (s *UsersService) CreateImpersonationToken(user int, opt *CreateImpersonationTokenOptions, options ...RequestOptionFunc) (*ImpersonationToken, *Response, error) { + u := fmt.Sprintf("users/%d/impersonation_tokens", user) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(ImpersonationToken) + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// RevokeImpersonationToken revokes an impersonation token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#revoke-an-impersonation-token +func (s *UsersService) RevokeImpersonationToken(user, token int, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/impersonation_tokens/%d", user, token) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// CreatePersonalAccessTokenOptions represents the available +// CreatePersonalAccessToken() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-a-personal-access-token-for-a-user +type CreatePersonalAccessTokenOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` +} + +// CreatePersonalAccessToken creates a personal access token. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-a-personal-access-token-for-a-user +func (s *UsersService) CreatePersonalAccessToken(user int, opt *CreatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := fmt.Sprintf("users/%d/personal_access_tokens", user) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(PersonalAccessToken) + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// CreatePersonalAccessTokenForCurrentUserOptions represents the available +// CreatePersonalAccessTokenForCurrentUser() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-a-personal-access-token +type CreatePersonalAccessTokenForCurrentUserOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` + ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` +} + +// CreatePersonalAccessTokenForCurrentUser creates a personal access token with limited scopes for the currently authenticated user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_tokens/#create-a-personal-access-token +func (s *UsersService) CreatePersonalAccessTokenForCurrentUser(opt *CreatePersonalAccessTokenForCurrentUserOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { + u := "user/personal_access_tokens" + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + t := new(PersonalAccessToken) + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// UserActivity represents an entry in the user/activities response +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#list-a-users-activity +type UserActivity struct { + Username string `json:"username"` + LastActivityOn *ISOTime `json:"last_activity_on"` +} + +// GetUserActivitiesOptions represents the options for GetUserActivities +// +// GitLap API docs: +// https://docs.gitlab.com/api/users/#list-a-users-activity +type GetUserActivitiesOptions struct { + ListOptions + From *ISOTime `url:"from,omitempty" json:"from,omitempty"` +} + +// GetUserActivities retrieves user activities (admin only) +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#list-a-users-activity +func (s *UsersService) GetUserActivities(opt *GetUserActivitiesOptions, options ...RequestOptionFunc) ([]*UserActivity, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "user/activities", opt, options) + if err != nil { + return nil, nil, err + } + + var t []*UserActivity + resp, err := s.client.Do(req, &t) + if err != nil { + return nil, resp, err + } + + return t, resp, nil +} + +// UserMembership represents a membership of the user in a namespace or project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#list-projects-and-groups-that-a-user-is-a-member-of +type UserMembership struct { + SourceID int `json:"source_id"` + SourceName string `json:"source_name"` + SourceType string `json:"source_type"` + AccessLevel AccessLevelValue `json:"access_level"` +} + +// GetUserMembershipOptions represents the options available to query user memberships. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#list-projects-and-groups-that-a-user-is-a-member-of +type GetUserMembershipOptions struct { + ListOptions + Type *string `url:"type,omitempty" json:"type,omitempty"` +} + +// GetUserMemberships retrieves a list of the user's memberships. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#list-projects-and-groups-that-a-user-is-a-member-of +func (s *UsersService) GetUserMemberships(user int, opt *GetUserMembershipOptions, options ...RequestOptionFunc) ([]*UserMembership, *Response, error) { + u := fmt.Sprintf("users/%d/memberships", user) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var m []*UserMembership + resp, err := s.client.Do(req, &m) + if err != nil { + return nil, resp, err + } + + return m, resp, nil +} + +// DisableTwoFactor disables two factor authentication for the specified user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#disable-two-factor-authentication-for-a-user +func (s *UsersService) DisableTwoFactor(user int, options ...RequestOptionFunc) error { + u := fmt.Sprintf("users/%d/disable_two_factor", user) + + req, err := s.client.NewRequest(http.MethodPatch, u, nil, options) + if err != nil { + return err + } + + resp, err := s.client.Do(req, nil) + if err != nil && resp == nil { + return err + } + + switch resp.StatusCode { + case 204: + return nil + case 400: + return ErrUserTwoFactorNotEnabled + case 403: + return ErrUserDisableTwoFactorPrevented + case 404: + return ErrUserNotFound + default: + return fmt.Errorf("received unexpected result code: %d", resp.StatusCode) + } +} + +// UserRunner represents a GitLab runner linked to the current user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#create-a-runner-linked-to-a-user +type UserRunner struct { + ID int `json:"id"` + Token string `json:"token"` + TokenExpiresAt *time.Time `json:"token_expires_at"` +} + +// CreateUserRunnerOptions represents the available CreateUserRunner() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#create-a-runner-linked-to-a-user +type CreateUserRunnerOptions struct { + RunnerType *string `url:"runner_type,omitempty" json:"runner_type,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + ProjectID *int `url:"project_id,omitempty" json:"project_id,omitempty"` + Description *string `url:"description,omitempty" json:"description,omitempty"` + Paused *bool `url:"paused,omitempty" json:"paused,omitempty"` + Locked *bool `url:"locked,omitempty" json:"locked,omitempty"` + RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"` + TagList *[]string `url:"tag_list,omitempty" json:"tag_list,omitempty"` + AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"` + MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"` + MaintenanceNote *string `url:"maintenance_note,omitempty" json:"maintenance_note,omitempty"` +} + +// CreateUserRunner creates a runner linked to the current user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#create-a-runner-linked-to-a-user +func (s *UsersService) CreateUserRunner(opts *CreateUserRunnerOptions, options ...RequestOptionFunc) (*UserRunner, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "user/runners", opts, options) + if err != nil { + return nil, nil, err + } + + r := new(UserRunner) + resp, err := s.client.Do(req, r) + if err != nil { + return nil, resp, err + } + + return r, resp, nil +} + +// CreateServiceAccountUserOptions represents the available CreateServiceAccountUser() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_service_accounts/#create-a-service-account-user +type CreateServiceAccountUserOptions struct { + Name *string `url:"name,omitempty" json:"name,omitempty"` + Username *string `url:"username,omitempty" json:"username,omitempty"` + Email *string `url:"email,omitempty" json:"email,omitempty"` +} + +// CreateServiceAccountUser creates a new service account user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_service_accounts/#create-a-service-account-user +func (s *UsersService) CreateServiceAccountUser(opts *CreateServiceAccountUserOptions, options ...RequestOptionFunc) (*User, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "service_accounts", opts, options) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// ListServiceAccounts lists all service accounts. +// +// GitLab API docs: +// https://docs.gitlab.com/api/user_service_accounts/#list-all-service-account-users +func (s *UsersService) ListServiceAccounts(opt *ListServiceAccountsOptions, options ...RequestOptionFunc) ([]*ServiceAccount, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "service_accounts", opt, options) + if err != nil { + return nil, nil, err + } + + var sas []*ServiceAccount + resp, err := s.client.Do(req, &sas) + if err != nil { + return nil, resp, err + } + + return sas, resp, nil +} + +// UploadAvatar uploads an avatar to the current user. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#upload-an-avatar-for-yourself +func (s *UsersService) UploadAvatar(avatar io.Reader, filename string, options ...RequestOptionFunc) (*User, *Response, error) { + u := "user/avatar" + + req, err := s.client.UploadRequest( + http.MethodPut, + u, + avatar, + filename, + UploadAvatar, + nil, + options, + ) + if err != nil { + return nil, nil, err + } + + usr := new(User) + resp, err := s.client.Do(req, usr) + if err != nil { + return nil, resp, err + } + + return usr, resp, nil +} + +// DeleteUserIdentity deletes a user's authentication identity using the provider +// name associated with that identity. Only available for administrators. +// +// GitLab API docs: +// https://docs.gitlab.com/api/users/#delete-authentication-identity-from-a-user +func (s *UsersService) DeleteUserIdentity(user int, provider string, options ...RequestOptionFunc) (*Response, error) { + u := fmt.Sprintf("users/%d/identities/%s", user, provider) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/validate.go b/vendor/gitlab.com/gitlab-org/api/client-go/validate.go new file mode 100644 index 000000000..9b05ad4ab --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/validate.go @@ -0,0 +1,149 @@ +// +// Copyright 2021, Sander van Harmelen +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package gitlab + +import ( + "fmt" + "net/http" +) + +type ( + ValidateServiceInterface interface { + ProjectNamespaceLint(pid any, opt *ProjectNamespaceLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) + ProjectLint(pid any, opt *ProjectLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) + } + + // ValidateService handles communication with the validation related methods of + // the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/lint/ + ValidateService struct { + client *Client + } +) + +var _ ValidateServiceInterface = (*ValidateService)(nil) + +// LintResult represents the linting results. +// +// GitLab API docs: https://docs.gitlab.com/api/lint/ +type LintResult struct { + Status string `json:"status"` + Errors []string `json:"errors"` + Warnings []string `json:"warnings"` + MergedYaml string `json:"merged_yaml"` +} + +// ProjectLintResult represents the linting results by project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/lint/ +type ProjectLintResult struct { + Valid bool `json:"valid"` + Errors []string `json:"errors"` + Warnings []string `json:"warnings"` + MergedYaml string `json:"merged_yaml"` + Includes []Include `json:"includes"` +} + +// Include contains the details about an include block in the .gitlab-ci.yml file. +// It is used in ProjectLintResult. +// +// Reference can be found at the lint API endpoint in the openapi yaml: +// https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/api/openapi/openapi_v2.yaml +type Include struct { + Type string `json:"type"` + Location string `json:"location"` + Blob string `json:"blob"` + Raw string `json:"raw"` + Extra map[string]any `json:"extra"` + ContextProject string `json:"context_project"` + ContextSHA string `json:"context_sha"` +} + +// ProjectNamespaceLintOptions represents the available ProjectNamespaceLint() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/lint/#validate-sample-cicd-configuration +type ProjectNamespaceLintOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"` + IncludeJobs *bool `url:"include_jobs,omitempty" json:"include_jobs,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// ProjectNamespaceLint validates .gitlab-ci.yml content by project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/lint/#validate-sample-cicd-configuration +func (s *ValidateService) ProjectNamespaceLint(pid any, opt *ProjectNamespaceLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/ci/lint", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, &opt, options) + if err != nil { + return nil, nil, err + } + + l := new(ProjectLintResult) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} + +// ProjectLintOptions represents the available ProjectLint() options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/lint/#validate-a-projects-cicd-configuration +type ProjectLintOptions struct { + ContentRef *string `url:"content_ref,omitempty" json:"content_ref,omitempty"` + DryRunRef *string `url:"dry_run_ref,omitempty" json:"dry_run_ref,omitempty"` + DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"` + IncludeJobs *bool `url:"include_jobs,omitempty" json:"include_jobs,omitempty"` + Ref *string `url:"ref,omitempty" json:"ref,omitempty"` +} + +// ProjectLint validates .gitlab-ci.yml content by project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/lint/#validate-a-projects-cicd-configuration +func (s *ValidateService) ProjectLint(pid any, opt *ProjectLintOptions, options ...RequestOptionFunc) (*ProjectLintResult, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/ci/lint", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, &opt, options) + if err != nil { + return nil, nil, err + } + + l := new(ProjectLintResult) + resp, err := s.client.Do(req, l) + if err != nil { + return nil, resp, err + } + + return l, resp, nil +} diff --git a/vendor/github.com/xanzy/go-gitlab/version.go b/vendor/gitlab.com/gitlab-org/api/client-go/version.go similarity index 57% rename from vendor/github.com/xanzy/go-gitlab/version.go rename to vendor/gitlab.com/gitlab-org/api/client-go/version.go index f1a3a7f52..90bd2552a 100644 --- a/vendor/github.com/xanzy/go-gitlab/version.go +++ b/vendor/gitlab.com/gitlab-org/api/client-go/version.go @@ -1,5 +1,5 @@ // -// Copyright 2017, Andrea Funto' +// Copyright 2021, Andrea Funto' // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,17 +16,27 @@ package gitlab -// VersionService handles communication with the GitLab server instance to -// retrieve its version information via the GitLab API. -// -// GitLab API docs: https://docs.gitlab.com/ce/api/version.md -type VersionService struct { - client *Client -} +import "net/http" + +type ( + VersionServiceInterface interface { + GetVersion(options ...RequestOptionFunc) (*Version, *Response, error) + } + + // VersionService handles communication with the GitLab server instance to + // retrieve its version information via the GitLab API. + // + // GitLab API docs: https://docs.gitlab.com/api/version/ + VersionService struct { + client *Client + } +) + +var _ VersionServiceInterface = (*VersionService)(nil) // Version represents a GitLab instance version. // -// GitLab API docs: https://docs.gitlab.com/ce/api/version.md +// GitLab API docs: https://docs.gitlab.com/api/version/ type Version struct { Version string `json:"version"` Revision string `json:"revision"` @@ -39,9 +49,9 @@ func (s Version) String() string { // GetVersion gets a GitLab server instance version; it is only available to // authenticated users. // -// GitLab API docs: https://docs.gitlab.com/ce/api/version.md -func (s *VersionService) GetVersion() (*Version, *Response, error) { - req, err := s.client.NewRequest("GET", "version", nil, nil) +// GitLab API docs: https://docs.gitlab.com/api/version/ +func (s *VersionService) GetVersion(options ...RequestOptionFunc) (*Version, *Response, error) { + req, err := s.client.NewRequest(http.MethodGet, "version", nil, options) if err != nil { return nil, nil, err } @@ -52,5 +62,5 @@ func (s *VersionService) GetVersion() (*Version, *Response, error) { return nil, resp, err } - return v, resp, err + return v, resp, nil } diff --git a/vendor/gitlab.com/gitlab-org/api/client-go/wikis.go b/vendor/gitlab.com/gitlab-org/api/client-go/wikis.go new file mode 100644 index 000000000..e17b2041c --- /dev/null +++ b/vendor/gitlab.com/gitlab-org/api/client-go/wikis.go @@ -0,0 +1,277 @@ +// +// Copyright 2021, Stany MARCEL +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitlab + +import ( + "fmt" + "io" + "net/http" + "net/url" +) + +type ( + WikisServiceInterface interface { + ListWikis(pid any, opt *ListWikisOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) + GetWikiPage(pid any, slug string, opt *GetWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) + CreateWikiPage(pid any, opt *CreateWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) + EditWikiPage(pid any, slug string, opt *EditWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) + DeleteWikiPage(pid any, slug string, options ...RequestOptionFunc) (*Response, error) + UploadWikiAttachment(pid any, content io.Reader, filename string, opt *UploadWikiAttachmentOptions, options ...RequestOptionFunc) (*WikiAttachment, *Response, error) + } + + // WikisService handles communication with the wikis related methods of + // the Gitlab API. + // + // GitLab API docs: + // https://docs.gitlab.com/api/wikis/ + WikisService struct { + client *Client + } +) + +var _ WikisServiceInterface = (*WikisService)(nil) + +// Wiki represents a GitLab wiki. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/ +type Wiki struct { + Content string `json:"content"` + Encoding string `json:"encoding"` + Format WikiFormatValue `json:"format"` + Slug string `json:"slug"` + Title string `json:"title"` +} + +func (w Wiki) String() string { + return Stringify(w) +} + +// WikiAttachment represents a GitLab wiki attachment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/ +type WikiAttachment struct { + FileName string `json:"file_name"` + FilePath string `json:"file_path"` + Branch string `json:"branch"` + Link WikiAttachmentLink `json:"link"` +} + +// WikiAttachmentLink represents a GitLab wiki attachment link. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/ +type WikiAttachmentLink struct { + URL string `json:"url"` + Markdown string `json:"markdown"` +} + +func (wa WikiAttachment) String() string { + return Stringify(wa) +} + +// ListWikisOptions represents the available ListWikis options. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#list-wiki-pages +type ListWikisOptions struct { + WithContent *bool `url:"with_content,omitempty" json:"with_content,omitempty"` +} + +// ListWikis lists all pages of the wiki of the given project id. +// When with_content is set, it also returns the content of the pages. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#list-wiki-pages +func (s *WikisService) ListWikis(pid any, opt *ListWikisOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/wikis", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + var ws []*Wiki + resp, err := s.client.Do(req, &ws) + if err != nil { + return nil, resp, err + } + + return ws, resp, nil +} + +// GetWikiPageOptions represents options to GetWikiPage +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#get-a-wiki-page +type GetWikiPageOptions struct { + RenderHTML *bool `url:"render_html,omitempty" json:"render_html,omitempty"` + Version *string `url:"version,omitempty" json:"version,omitempty"` +} + +// GetWikiPage gets a wiki page for a given project. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#get-a-wiki-page +func (s *WikisService) GetWikiPage(pid any, slug string, opt *GetWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/wikis/%s", PathEscape(project), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodGet, u, opt, options) + if err != nil { + return nil, nil, err + } + + w := new(Wiki) + resp, err := s.client.Do(req, w) + if err != nil { + return nil, resp, err + } + + return w, resp, nil +} + +// CreateWikiPageOptions represents options to CreateWikiPage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#create-a-new-wiki-page +type CreateWikiPageOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"` +} + +// CreateWikiPage creates a new wiki page for the given repository with +// the given title, slug, and content. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#create-a-new-wiki-page +func (s *WikisService) CreateWikiPage(pid any, opt *CreateWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/wikis", PathEscape(project)) + + req, err := s.client.NewRequest(http.MethodPost, u, opt, options) + if err != nil { + return nil, nil, err + } + + w := new(Wiki) + resp, err := s.client.Do(req, w) + if err != nil { + return nil, resp, err + } + + return w, resp, nil +} + +// EditWikiPageOptions represents options to EditWikiPage. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#edit-an-existing-wiki-page +type EditWikiPageOptions struct { + Content *string `url:"content,omitempty" json:"content,omitempty"` + Title *string `url:"title,omitempty" json:"title,omitempty"` + Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"` +} + +// EditWikiPage Updates an existing wiki page. At least one parameter is +// required to update the wiki page. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#edit-an-existing-wiki-page +func (s *WikisService) EditWikiPage(pid any, slug string, opt *EditWikiPageOptions, options ...RequestOptionFunc) (*Wiki, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/wikis/%s", PathEscape(project), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + if err != nil { + return nil, nil, err + } + + w := new(Wiki) + resp, err := s.client.Do(req, w) + if err != nil { + return nil, resp, err + } + + return w, resp, nil +} + +// DeleteWikiPage deletes a wiki page with a given slug. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#delete-a-wiki-page +func (s *WikisService) DeleteWikiPage(pid any, slug string, options ...RequestOptionFunc) (*Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, err + } + u := fmt.Sprintf("projects/%s/wikis/%s", PathEscape(project), url.PathEscape(slug)) + + req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) + if err != nil { + return nil, err + } + + return s.client.Do(req, nil) +} + +// UploadWikiAttachmentOptions represents options to UploadWikiAttachment. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#upload-an-attachment-to-the-wiki-repository +type UploadWikiAttachmentOptions struct { + Branch *string `url:"branch,omitempty" json:"branch,omitempty"` +} + +// UploadWikiAttachment uploads a file to the attachment folder inside the wiki’s repository. The attachment folder is the uploads folder. +// +// GitLab API docs: +// https://docs.gitlab.com/api/wikis/#upload-an-attachment-to-the-wiki-repository +func (s *WikisService) UploadWikiAttachment(pid any, content io.Reader, filename string, opt *UploadWikiAttachmentOptions, options ...RequestOptionFunc) (*WikiAttachment, *Response, error) { + project, err := parseID(pid) + if err != nil { + return nil, nil, err + } + u := fmt.Sprintf("projects/%s/wikis/attachments", PathEscape(project)) + + req, err := s.client.UploadRequest(http.MethodPost, u, content, filename, UploadFile, opt, options) + if err != nil { + return nil, nil, err + } + + attachment := new(WikiAttachment) + resp, err := s.client.Do(req, attachment) + if err != nil { + return nil, resp, err + } + + return attachment, resp, nil +} From 699fd7270e41be5780fa0cbb0d57b22b32939c0e Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Sun, 25 May 2025 01:59:38 +0000 Subject: [PATCH 02/20] wip: replace go-playground/webhook --- pkg/adapter/receive_adapter.go | 44 +------ pkg/adapter/receive_adapter_test.go | 55 ++++----- pkg/adapter/webhook.go | 116 ++++++++++++++++++ .../webhooks.v5/gitlab/gitlab.go | 1 + 4 files changed, 145 insertions(+), 71 deletions(-) create mode 100644 pkg/adapter/webhook.go diff --git a/pkg/adapter/receive_adapter.go b/pkg/adapter/receive_adapter.go index 192a2727f..da42f69b2 100644 --- a/pkg/adapter/receive_adapter.go +++ b/pkg/adapter/receive_adapter.go @@ -27,8 +27,6 @@ import ( cloudevents "github.com/cloudevents/sdk-go/v2" "go.uber.org/zap" - "gopkg.in/go-playground/webhooks.v5/gitlab" - sourcesv1alpha1 "knative.dev/eventing-gitlab/pkg/apis/sources/v1alpha1" "knative.dev/eventing/pkg/adapter/v2" "knative.dev/pkg/logging" @@ -86,16 +84,13 @@ func (ra *gitLabReceiveAdapter) Start(ctx context.Context) error { } func (ra *gitLabReceiveAdapter) start(stopCh <-chan struct{}) error { - hook, err := gitlab.New(gitlab.Options.Secret(ra.secretToken)) - if err != nil { - return fmt.Errorf("cannot create gitlab hook: %v", err) - } + wh := NewWebhookHandler(ra.secretToken) server := &http.Server{ ReadTimeout: 10 * time.Second, ReadHeaderTimeout: 2 * time.Second, Addr: ":" + ra.port, - Handler: ra.newRouter(hook), + Handler: wh, } var wg sync.WaitGroup @@ -130,41 +125,6 @@ func gracefulShutdown(server *http.Server, logger *zap.SugaredLogger, stopCh <-c } } -func (ra *gitLabReceiveAdapter) newRouter(hook *gitlab.Webhook) *http.ServeMux { - router := http.NewServeMux() - router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - payload, err := hook.Parse(r, - gitlab.PushEvents, - gitlab.TagEvents, - gitlab.IssuesEvents, - gitlab.ConfidentialIssuesEvents, - gitlab.CommentEvents, - gitlab.MergeRequestEvents, - gitlab.WikiPageEvents, - gitlab.PipelineEvents, - gitlab.BuildEvents, - ) - if err != nil { - ra.logger.Error("Hook parser error: ", err) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - return - } - - if err := ra.handleEvent(payload, r.Header); err != nil { - ra.logger.Error("Event handler error: ", err) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - return - } - - ra.logger.Debug("Event processed") - w.WriteHeader(http.StatusAccepted) - }) - - return router -} - func (ra *gitLabReceiveAdapter) handleEvent(payload interface{}, header http.Header) error { eventHeader := header.Get(glHeaderEvent) eventType := gitlabEventHeaderToEventType(eventHeader) diff --git a/pkg/adapter/receive_adapter_test.go b/pkg/adapter/receive_adapter_test.go index 52bde0935..10281b057 100644 --- a/pkg/adapter/receive_adapter_test.go +++ b/pkg/adapter/receive_adapter_test.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "io" "net/http" "net/http/httptest" @@ -31,7 +32,7 @@ import ( cloudevents "github.com/cloudevents/sdk-go/v2" "go.uber.org/zap" - "gopkg.in/go-playground/webhooks.v5/gitlab" + gitlab "gitlab.com/gitlab-org/api/client-go" "knative.dev/eventing-gitlab/pkg/apis/sources/v1alpha1" "knative.dev/eventing/pkg/adapter/v2" @@ -60,64 +61,64 @@ type testCase struct { payload interface{} // eventType is the GitLab event type - eventType gitlab.Event + eventType gitlab.EventType } var testCases = []testCase{ { name: "valid comment", - payload: gitlab.CommentEventPayload{}, - eventType: gitlab.CommentEvents, + payload: gitlab.IssueCommentEvent{}, + eventType: gitlab.EventTypeNote, statusCode: 202, }, { name: "valid issues", - payload: gitlab.IssueEventPayload{}, - eventType: gitlab.IssuesEvents, + payload: gitlab.IssueEvent{}, + eventType: gitlab.EventTypeIssue, statusCode: 202, }, { name: "valid push", - payload: gitlab.PushEventPayload{}, - eventType: gitlab.PushEvents, + payload: gitlab.PushEvent{}, + eventType: gitlab.EventTypePush, statusCode: 202, }, { name: "valid tag event", - payload: gitlab.TagEventPayload{}, - eventType: gitlab.TagEvents, + payload: gitlab.TagEvent{}, + eventType: gitlab.EventTypeTagPush, statusCode: 202, }, { name: "valid confidential issue event", - payload: gitlab.ConfidentialIssueEventPayload{}, - eventType: gitlab.ConfidentialIssuesEvents, + payload: gitlab.IssueEvent{}, + eventType: gitlab.EventTypeIssue, statusCode: 202, }, { name: "valid merge request event", - payload: gitlab.MergeRequestEventPayload{}, - eventType: gitlab.MergeRequestEvents, + payload: gitlab.MergeEvent{}, + eventType: gitlab.EventTypeMergeRequest, statusCode: 202, }, { name: "valid wiki page event", - payload: gitlab.WikiPageEventPayload{}, - eventType: gitlab.WikiPageEvents, + payload: gitlab.WikiPageEvent{}, + eventType: gitlab.EventTypeWikiPage, statusCode: 202, }, { name: "valid pipeline event", - payload: gitlab.PipelineEventPayload{}, - eventType: gitlab.PipelineEvents, + payload: gitlab.PipelineEvent{}, + eventType: gitlab.EventTypePipeline, statusCode: 202, }, { name: "valid build event", - payload: gitlab.BuildEventPayload{}, - eventType: gitlab.BuildEvents, + payload: gitlab.BuildEvent{}, + eventType: gitlab.EventTypeBuild, statusCode: 202, }, { name: "invalid nil payload", payload: nil, - eventType: gitlab.Event("Invalid Hook"), - wantErr: gitlab.ErrEventNotFound, + eventType: "Invalid Hook", + wantErr: errors.New(""), statusCode: 400, }, { name: "invalid empty eventType", - wantErr: gitlab.ErrMissingGitLabEventHeader, + wantErr: errors.New(""), statusCode: 400, }, } @@ -144,12 +145,8 @@ func TestServer(t *testing.T) { for _, tc := range testCases { ce := adaptertest.NewTestClient() ra := newTestAdapter(t, ce) - hook, err := gitlab.New(gitlab.Options.Secret(ra.secretToken)) - if err != nil { - t.Error(err) - } - router := ra.newRouter(hook) - server := httptest.NewServer(router) + hook := NewWebhookHandler(ra.secretToken) + server := httptest.NewServer(hook) defer server.Close() t.Run(tc.name, tc.runner(t, server.URL, ce)) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go new file mode 100644 index 000000000..922255528 --- /dev/null +++ b/pkg/adapter/webhook.go @@ -0,0 +1,116 @@ +package adapter + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "log" + "net/http" + "slices" + "strings" + + gitlab "gitlab.com/gitlab-org/api/client-go" +) + +var ( + ErrMissingGitLabEventHeader = errors.New("missing X-Gitlab-Event Header") + ErrEventNotSpecifiedToParse = errors.New("event not defined to be parsed") + ErrReadingfRequestBody = errors.New("error reading request body") + ErrGitLabTokenVerificationFailed = errors.New("token validation failed") +) + +// webhook is a HTTP Handler for Gitlab Webhook events. +type webhook struct { + Secret string + EventsToAccept []gitlab.EventType +} + +// webhookExample shows how to create a Webhook server to parse Gitlab events. +func NewWebhookHandler(secret string) webhook { + wh := webhook{ + Secret: secret, + EventsToAccept: []gitlab.EventType{}, + } + + return wh +} + +// ServeHTTP tries to parse Gitlab events sent and calls handle function +// with the successfully parsed events. +func (hook webhook) ServeHTTP(writer http.ResponseWriter, request *http.Request) { + event, err := hook.parse(request) + if err != nil { + writer.WriteHeader(500) + fmt.Fprintf(writer, "could parse the webhook event: %v", err) + return + } + + // Handle the event before we return. + if err := hook.handle(event); err != nil { + writer.WriteHeader(500) + fmt.Fprintf(writer, "error handling the event: %v", err) + return + } + + // Write a response when were done. + writer.WriteHeader(204) +} + +func (hook webhook) handle(event any) error { + str, err := json.Marshal(event) + if err != nil { + return fmt.Errorf("could not marshal json event for logging: %v", err) + } + + // Just write the event for this example. + fmt.Println(string(str)) + + return nil +} + +// parse verifies and parses the events specified in the request and +// returns the parsed event or an error. +func (hook webhook) parse(r *http.Request) (any, error) { + defer func() { + if _, err := io.Copy(io.Discard, r.Body); err != nil { + log.Printf("could discard request body: %v", err) + } + if err := r.Body.Close(); err != nil { + log.Printf("could not close request body: %v", err) + } + }() + + if r.Method != http.MethodPost { + return nil, errors.New("invalid HTTP Method") + } + + // If we have a secret set, we should check if the request matches it. + if len(hook.Secret) > 0 { + signature := r.Header.Get("X-Gitlab-Token") + if signature != hook.Secret { + return nil, errors.New("token validation failed") + } + } + + event := r.Header.Get("X-Gitlab-Event") + if strings.TrimSpace(event) == "" { + return nil, ErrMissingGitLabEventHeader + } + + eventType := gitlab.EventType(event) + if !isEventSubscribed(eventType, hook.EventsToAccept) { + return nil, ErrEventNotSpecifiedToParse + } + + payload, err := io.ReadAll(r.Body) + if err != nil || len(payload) == 0 { + return nil, ErrReadingfRequestBody + } + + return gitlab.ParseWebhook(eventType, payload) +} + +func isEventSubscribed(event gitlab.EventType, events []gitlab.EventType) bool { + return slices.Contains(events, event) +} diff --git a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go b/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go index f94ed23b9..4d490161d 100644 --- a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go +++ b/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go @@ -172,6 +172,7 @@ func eventParsing(gitLabEvent Event, events []Event, payload []byte) (interface{ var pl BuildEventPayload err := json.Unmarshal([]byte(payload), &pl) return pl, err + case JobEvents: var p1 JobEventPayload err := json.Unmarshal([]byte(payload), &p1) From a76adcf2a1ee1cf55cc2cc6c1c03573696885e72 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Sun, 25 May 2025 09:45:10 +0000 Subject: [PATCH 03/20] test: complete the test migration to go-gitlab --- go.sum | 2 - pkg/adapter/receive_adapter.go | 2 +- pkg/adapter/receive_adapter_test.go | 17 +- pkg/adapter/webhook.go | 64 +-- .../go-playground/webhooks.v5/LICENSE | 22 - .../webhooks.v5/gitlab/gitlab.go | 209 ------- .../webhooks.v5/gitlab/payload.go | 518 ------------------ vendor/modules.txt | 3 - 8 files changed, 39 insertions(+), 798 deletions(-) delete mode 100644 vendor/gopkg.in/go-playground/webhooks.v5/LICENSE delete mode 100644 vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go delete mode 100644 vendor/gopkg.in/go-playground/webhooks.v5/gitlab/payload.go diff --git a/go.sum b/go.sum index 6b91b3b56..ba317cb6d 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/webhooks.v5 v5.15.0 h1:vnD8c5hN/w8qs0K3fQvIDAeYAHBnCclJHPnxNSJeBCw= -gopkg.in/go-playground/webhooks.v5 v5.15.0/go.mod h1:LZbya/qLVdbqDR1aKrGuWV6qbia2zCYSR5dpom2SInQ= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= diff --git a/pkg/adapter/receive_adapter.go b/pkg/adapter/receive_adapter.go index da42f69b2..a6af66328 100644 --- a/pkg/adapter/receive_adapter.go +++ b/pkg/adapter/receive_adapter.go @@ -84,7 +84,7 @@ func (ra *gitLabReceiveAdapter) Start(ctx context.Context) error { } func (ra *gitLabReceiveAdapter) start(stopCh <-chan struct{}) error { - wh := NewWebhookHandler(ra.secretToken) + wh := NewWebhookHandler(ra.secretToken, ra.handleEvent) server := &http.Server{ ReadTimeout: 10 * time.Second, diff --git a/pkg/adapter/receive_adapter_test.go b/pkg/adapter/receive_adapter_test.go index 10281b057..08844e2c9 100644 --- a/pkg/adapter/receive_adapter_test.go +++ b/pkg/adapter/receive_adapter_test.go @@ -66,11 +66,6 @@ type testCase struct { var testCases = []testCase{ { - name: "valid comment", - payload: gitlab.IssueCommentEvent{}, - eventType: gitlab.EventTypeNote, - statusCode: 202, - }, { name: "valid issues", payload: gitlab.IssueEvent{}, eventType: gitlab.EventTypeIssue, @@ -112,13 +107,13 @@ var testCases = []testCase{ statusCode: 202, }, { name: "invalid nil payload", - payload: nil, - eventType: "Invalid Hook", - wantErr: errors.New(""), + payload: []byte("{\"key\": \"value\""), + eventType: gitlab.EventTypeBuild, + wantErr: ErrCouldNotParseWebhookEvent, statusCode: 400, }, { name: "invalid empty eventType", - wantErr: errors.New(""), + wantErr: ErrMissingGitLabEventHeader, statusCode: 400, }, } @@ -145,7 +140,7 @@ func TestServer(t *testing.T) { for _, tc := range testCases { ce := adaptertest.NewTestClient() ra := newTestAdapter(t, ce) - hook := NewWebhookHandler(ra.secretToken) + hook := NewWebhookHandler(ra.secretToken, ra.handleEvent) server := httptest.NewServer(hook) defer server.Close() @@ -228,7 +223,7 @@ func (tc *testCase) validateAcceptedPayload(t *testing.T, ce *adaptertest.TestCl func (tc *testCase) validateResponse(t *testing.T, body string) { if tc.wantErr != nil { - assert.EqualError(t, tc.wantErr, body) + assert.ErrorContains(t, errors.New(body), tc.wantErr.Error()) return } assert.Empty(t, body) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index 922255528..8af983e9f 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -1,13 +1,28 @@ +/* +Copyright 2020 The Knative Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ package adapter +// ref: https://gitlab.com/gitlab-org/api/client-go/-/blob/main/examples/webhook.go?ref_type=heads + import ( - "encoding/json" "errors" "fmt" "io" "log" "net/http" - "slices" "strings" gitlab "gitlab.com/gitlab-org/api/client-go" @@ -18,19 +33,23 @@ var ( ErrEventNotSpecifiedToParse = errors.New("event not defined to be parsed") ErrReadingfRequestBody = errors.New("error reading request body") ErrGitLabTokenVerificationFailed = errors.New("token validation failed") + ErrCouldNotParseWebhookEvent = errors.New("could parse the webhook event") + ErrCouldNotHandleEvent = errors.New("error handling the event") ) +type EventSender func(payload interface{}, header http.Header) error + // webhook is a HTTP Handler for Gitlab Webhook events. type webhook struct { - Secret string - EventsToAccept []gitlab.EventType + Secret string + EventSender EventSender } // webhookExample shows how to create a Webhook server to parse Gitlab events. -func NewWebhookHandler(secret string) webhook { +func NewWebhookHandler(secret string, sender EventSender) webhook { wh := webhook{ - Secret: secret, - EventsToAccept: []gitlab.EventType{}, + Secret: secret, + EventSender: sender, } return wh @@ -41,32 +60,20 @@ func NewWebhookHandler(secret string) webhook { func (hook webhook) ServeHTTP(writer http.ResponseWriter, request *http.Request) { event, err := hook.parse(request) if err != nil { - writer.WriteHeader(500) - fmt.Fprintf(writer, "could parse the webhook event: %v", err) + writer.WriteHeader(400) + fmt.Fprintf(writer, "%v: %v", ErrCouldNotParseWebhookEvent, err) return } // Handle the event before we return. - if err := hook.handle(event); err != nil { + if err := hook.EventSender(event, request.Header); err != nil { writer.WriteHeader(500) - fmt.Fprintf(writer, "error handling the event: %v", err) + fmt.Fprintf(writer, "%v: %v", ErrCouldNotHandleEvent, err) return } // Write a response when were done. - writer.WriteHeader(204) -} - -func (hook webhook) handle(event any) error { - str, err := json.Marshal(event) - if err != nil { - return fmt.Errorf("could not marshal json event for logging: %v", err) - } - - // Just write the event for this example. - fmt.Println(string(str)) - - return nil + writer.WriteHeader(202) } // parse verifies and parses the events specified in the request and @@ -89,7 +96,7 @@ func (hook webhook) parse(r *http.Request) (any, error) { if len(hook.Secret) > 0 { signature := r.Header.Get("X-Gitlab-Token") if signature != hook.Secret { - return nil, errors.New("token validation failed") + return nil, ErrGitLabTokenVerificationFailed } } @@ -99,9 +106,6 @@ func (hook webhook) parse(r *http.Request) (any, error) { } eventType := gitlab.EventType(event) - if !isEventSubscribed(eventType, hook.EventsToAccept) { - return nil, ErrEventNotSpecifiedToParse - } payload, err := io.ReadAll(r.Body) if err != nil || len(payload) == 0 { @@ -110,7 +114,3 @@ func (hook webhook) parse(r *http.Request) (any, error) { return gitlab.ParseWebhook(eventType, payload) } - -func isEventSubscribed(event gitlab.EventType, events []gitlab.EventType) bool { - return slices.Contains(events, event) -} diff --git a/vendor/gopkg.in/go-playground/webhooks.v5/LICENSE b/vendor/gopkg.in/go-playground/webhooks.v5/LICENSE deleted file mode 100644 index 6a2ae9aa4..000000000 --- a/vendor/gopkg.in/go-playground/webhooks.v5/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Dean Karn - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go b/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go deleted file mode 100644 index 4d490161d..000000000 --- a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/gitlab.go +++ /dev/null @@ -1,209 +0,0 @@ -package gitlab - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" -) - -// parse errors -var ( - ErrEventNotSpecifiedToParse = errors.New("no Event specified to parse") - ErrInvalidHTTPMethod = errors.New("invalid HTTP Method") - ErrMissingGitLabEventHeader = errors.New("missing X-Gitlab-Event Header") - ErrGitLabTokenVerificationFailed = errors.New("X-Gitlab-Token validation failed") - ErrEventNotFound = errors.New("event not defined to be parsed") - ErrParsingPayload = errors.New("error parsing payload") - ErrParsingSystemPayload = errors.New("error parsing system payload") - // ErrHMACVerificationFailed = errors.New("HMAC verification failed") -) - -// GitLab hook types -const ( - PushEvents Event = "Push Hook" - TagEvents Event = "Tag Push Hook" - IssuesEvents Event = "Issue Hook" - ConfidentialIssuesEvents Event = "Confidential Issue Hook" - CommentEvents Event = "Note Hook" - MergeRequestEvents Event = "Merge Request Hook" - WikiPageEvents Event = "Wiki Page Hook" - PipelineEvents Event = "Pipeline Hook" - BuildEvents Event = "Build Hook" - JobEvents Event = "Job Hook" - SystemHookEvents Event = "System Hook" - - objectPush string = "push" - objectTag string = "tag_push" - objectMergeRequest string = "merge_request" -) - -// Option is a configuration option for the webhook -type Option func(*Webhook) error - -// Options is a namespace var for configuration options -var Options = WebhookOptions{} - -// WebhookOptions is a namespace for configuration option methods -type WebhookOptions struct{} - -// Secret registers the GitLab secret -func (WebhookOptions) Secret(secret string) Option { - return func(hook *Webhook) error { - hook.secret = secret - return nil - } -} - -// Webhook instance contains all methods needed to process events -type Webhook struct { - secret string -} - -// Event defines a GitLab hook event type by the X-Gitlab-Event Header -type Event string - -// New creates and returns a WebHook instance denoted by the Provider type -func New(options ...Option) (*Webhook, error) { - hook := new(Webhook) - for _, opt := range options { - if err := opt(hook); err != nil { - return nil, errors.New("Error applying Option") - } - } - return hook, nil -} - -// Parse verifies and parses the events specified and returns the payload object or an error -func (hook Webhook) Parse(r *http.Request, events ...Event) (interface{}, error) { - defer func() { - _, _ = io.Copy(ioutil.Discard, r.Body) - _ = r.Body.Close() - }() - - if len(events) == 0 { - return nil, ErrEventNotSpecifiedToParse - } - if r.Method != http.MethodPost { - return nil, ErrInvalidHTTPMethod - } - - // If we have a Secret set, we should check the MAC - if len(hook.secret) > 0 { - signature := r.Header.Get("X-Gitlab-Token") - if signature != hook.secret { - return nil, ErrGitLabTokenVerificationFailed - } - } - - event := r.Header.Get("X-Gitlab-Event") - if len(event) == 0 { - return nil, ErrMissingGitLabEventHeader - } - - gitLabEvent := Event(event) - - payload, err := ioutil.ReadAll(r.Body) - if err != nil || len(payload) == 0 { - return nil, ErrParsingPayload - } - - return eventParsing(gitLabEvent, events, payload) -} - -func eventParsing(gitLabEvent Event, events []Event, payload []byte) (interface{}, error) { - - var found bool - for _, evt := range events { - if evt == gitLabEvent { - found = true - break - } - } - // event not defined to be parsed - if !found { - return nil, ErrEventNotFound - } - - switch gitLabEvent { - case PushEvents: - var pl PushEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case TagEvents: - var pl TagEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case ConfidentialIssuesEvents: - var pl ConfidentialIssueEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case IssuesEvents: - var pl IssueEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case CommentEvents: - var pl CommentEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case MergeRequestEvents: - var pl MergeRequestEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case WikiPageEvents: - var pl WikiPageEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case PipelineEvents: - var pl PipelineEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case BuildEvents: - var pl BuildEventPayload - err := json.Unmarshal([]byte(payload), &pl) - return pl, err - - case JobEvents: - var p1 JobEventPayload - err := json.Unmarshal([]byte(payload), &p1) - return p1, err - - case SystemHookEvents: - var pl SystemHookPayload - err := json.Unmarshal([]byte(payload), &pl) - if err != nil { - return nil, err - } - switch pl.ObjectKind { - case objectPush: - return eventParsing(PushEvents, events, payload) - case objectTag: - return eventParsing(TagEvents, events, payload) - case objectMergeRequest: - return eventParsing(MergeRequestEvents, events, payload) - default: - switch pl.EventName { - case objectPush: - return eventParsing(PushEvents, events, payload) - case objectTag: - return eventParsing(TagEvents, events, payload) - case objectMergeRequest: - return eventParsing(MergeRequestEvents, events, payload) - default: - return nil, fmt.Errorf("unknown system hook event %s", gitLabEvent) - } - } - default: - return nil, fmt.Errorf("unknown event %s", gitLabEvent) - } -} diff --git a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/payload.go b/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/payload.go deleted file mode 100644 index 6c04176db..000000000 --- a/vendor/gopkg.in/go-playground/webhooks.v5/gitlab/payload.go +++ /dev/null @@ -1,518 +0,0 @@ -package gitlab - -import ( - "strings" - "time" -) - -type customTime struct { - time.Time -} - -func (t *customTime) UnmarshalJSON(b []byte) (err error) { - layout := []string{ - "2006-01-02 15:04:05 MST", - "2006-01-02 15:04:05 Z07:00", - "2006-01-02 15:04:05 Z0700", - time.RFC3339, - } - s := strings.Trim(string(b), "\"") - if s == "null" { - t.Time = time.Time{} - return - } - for _, l := range layout { - t.Time, err = time.Parse(l, s) - if err == nil { - break - } - } - return -} - -// IssueEventPayload contains the information for GitLab's issue event -type IssueEventPayload struct { - ObjectKind string `json:"object_kind"` - User User `json:"user"` - Project Project `json:"project"` - Repository Repository `json:"repository"` - ObjectAttributes ObjectAttributes `json:"object_attributes"` - Assignee Assignee `json:"assignee"` - Changes Changes `json:"changes"` -} - -// ConfidentialIssueEventPayload contains the information for GitLab's confidential issue event -type ConfidentialIssueEventPayload struct { - // The data for confidential issues is currently the same as normal issues, - // so we can just embed the normal issue payload type here. - IssueEventPayload -} - -// MergeRequestEventPayload contains the information for GitLab's merge request event -type MergeRequestEventPayload struct { - ObjectKind string `json:"object_kind"` - User User `json:"user"` - ObjectAttributes ObjectAttributes `json:"object_attributes"` - Changes Changes `json:"changes"` - Project Project `json:"project"` - Repository Repository `json:"repository"` -} - -// PushEventPayload contains the information for GitLab's push event -type PushEventPayload struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int64 `json:"user_id"` - UserName string `json:"user_name"` - UserUsername string `json:"user_username"` - UserEmail string `json:"user_email"` - UserAvatar string `json:"user_avatar"` - ProjectID int64 `json:"project_id"` - Project Project `json:"Project"` - Repository Repository `json:"repository"` - Commits []Commit `json:"commits"` - TotalCommitsCount int64 `json:"total_commits_count"` -} - -// TagEventPayload contains the information for GitLab's tag push event -type TagEventPayload struct { - ObjectKind string `json:"object_kind"` - Before string `json:"before"` - After string `json:"after"` - Ref string `json:"ref"` - CheckoutSHA string `json:"checkout_sha"` - UserID int64 `json:"user_id"` - UserName string `json:"user_name"` - UserUsername string `json:"user_username"` - UserAvatar string `json:"user_avatar"` - ProjectID int64 `json:"project_id"` - Project Project `json:"Project"` - Repository Repository `json:"repository"` - Commits []Commit `json:"commits"` - TotalCommitsCount int64 `json:"total_commits_count"` -} - -// WikiPageEventPayload contains the information for GitLab's wiki created/updated event -type WikiPageEventPayload struct { - ObjectKind string `json:"object_kind"` - User User `json:"user"` - Project Project `json:"project"` - Wiki Wiki `json:"wiki"` - ObjectAttributes ObjectAttributes `json:"object_attributes"` -} - -// PipelineEventPayload contains the information for GitLab's pipeline status change event -type PipelineEventPayload struct { - ObjectKind string `json:"object_kind"` - User User `json:"user"` - Project Project `json:"project"` - Commit Commit `json:"commit"` - ObjectAttributes PipelineObjectAttributes `json:"object_attributes"` - Jobs []Job `json:"jobs"` -} - -// CommentEventPayload contains the information for GitLab's comment event -type CommentEventPayload struct { - ObjectKind string `json:"object_kind"` - User User `json:"user"` - ProjectID int64 `json:"project_id"` - Project Project `json:"project"` - Repository Repository `json:"repository"` - ObjectAttributes ObjectAttributes `json:"object_attributes"` - MergeRequest MergeRequest `json:"merge_request"` - Commit Commit `json:"commit"` - Issue Issue `json:"issue"` - Snippet Snippet `json:"snippet"` -} - -// BuildEventPayload contains the information for GitLab's build status change event -type BuildEventPayload struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - BuildID int64 `json:"build_id"` - BuildName string `json:"build_name"` - BuildStage string `json:"build_stage"` - BuildStatus string `json:"build_status"` - BuildStartedAt customTime `json:"build_started_at"` - BuildFinishedAt customTime `json:"build_finished_at"` - BuildDuration int64 `json:"build_duration"` - BuildAllowFailure bool `json:"build_allow_failure"` - ProjectID int64 `json:"project_id"` - ProjectName string `json:"project_name"` - User User `json:"user"` - Commit BuildCommit `json:"commit"` - Repository Repository `json:"repository"` -} - -// JobEventPayload contains the information for GitLab's Job status change -type JobEventPayload struct { - ObjectKind string `json:"object_kind"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - BeforeSHA string `json:"before_sha"` - SHA string `json:"sha"` - JobID int64 `json:"Job_id"` - JobName string `json:"Job_name"` - JobStage string `json:"Job_stage"` - JobStatus string `json:"Job_status"` - JobStartedAt customTime `json:"Job_started_at"` - JobFinishedAt customTime `json:"Job_finished_at"` - JobDuration int64 `json:"Job_duration"` - Job bool `json:"Job"` - JobFailureReason string `json:"job_failure_reason"` - ProjectID int64 `json:"project_id"` - ProjectName string `json:"project_name"` - User User `json:"user"` - Commit BuildCommit `json:"commit"` - Repository Repository `json:"repository"` -} - -// SystemHookPayload contains the ObjectKind to match with real hook events -type SystemHookPayload struct { - ObjectKind string `json:"object_kind"` - EventName string `json:"event_name"` -} - -// Issue contains all of the GitLab issue information -type Issue struct { - ID int64 `json:"id"` - Title string `json:"title"` - AssigneeID int64 `json:"assignee_id"` - AuthorID int64 `json:"author_id"` - ProjectID int64 `json:"project_id"` - CreatedAt customTime `json:"created_at"` - UpdatedAt customTime `json:"updated_at"` - Position int64 `json:"position"` - BranchName string `json:"branch_name"` - Description string `json:"description"` - MilestoneID int64 `json:"milestone_id"` - State string `json:"state"` - IID int64 `json:"iid"` -} - -// Job contains all of the GitLab job information -type Job struct { - ID int64 `json:"id"` - Stage string `json:"stage"` - Name string `json:"name"` - Status string `json:"status"` - CreatedAt customTime `json:"created_at"` - StartedAt customTime `json:"started_at"` - FinishedAt customTime `json:"finished_at"` - When string `json:"when"` - Manual bool `json:"manual"` - User User `json:"user"` - Runner Runner `json:"runner"` - ArtifactsFile ArtifactsFile `json:"artifactsfile"` -} - -// Runner represents a runner agent -type Runner struct { - ID int64 `json:"id"` - Description string `json:"description"` - Active bool `json:"active"` - IsShared bool `json:"is_shared"` -} - -// ArtifactsFile contains all of the GitLab artifact information -type ArtifactsFile struct { - Filename string `json:"filename"` - Size string `json:"size"` -} - -// Wiki contains all of the GitLab wiki information -type Wiki struct { - WebURL string `json:"web_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` -} - -// Commit contains all of the GitLab commit information -type Commit struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp customTime `json:"timestamp"` - URL string `json:"url"` - Author Author `json:"author"` - Added []string `json:"added"` - Modified []string `json:"modified"` - Removed []string `json:"removed"` -} - -// BuildCommit contains all of the GitLab build commit information -type BuildCommit struct { - ID int64 `json:"id"` - SHA string `json:"sha"` - Message string `json:"message"` - AuthorName string `json:"auuthor_name"` - AuthorEmail string `json:"author_email"` - Status string `json:"status"` - Duration int64 `json:"duration"` - StartedAt customTime `json:"started_at"` - FinishedAt customTime `json:"finished_at"` -} - -// Snippet contains all of the GitLab snippet information -type Snippet struct { - ID int64 `json:"id"` - Title string `json:"title"` - Content string `json:"content"` - AuthorID int64 `json:"author_id"` - ProjectID int64 `json:"project_id"` - CreatedAt customTime `json:"created_at"` - UpdatedAt customTime `json:"updated_at"` - FileName string `json:"file_name"` - ExpiresAt customTime `json:"expires_at"` - Type string `json:"type"` - VisibilityLevel int64 `json:"visibility_level"` -} - -// User contains all of the GitLab user information -type User struct { - Name string `json:"name"` - UserName string `json:"username"` - AvatarURL string `json:"avatar_url"` -} - -// Project contains all of the GitLab project information -type Project struct { - ID int64 `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - WebURL string `json:"web_url"` - AvatarURL string `json:"avatar_url"` - GitSSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - VisibilityLevel int64 `json:"visibility_level"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` -} - -// Repository contains all of the GitLab repository information -type Repository struct { - Name string `json:"name"` - URL string `json:"url"` - Description string `json:"description"` - Homepage string `json:"homepage"` -} - -// ObjectAttributes contains all of the GitLab object attributes information -type ObjectAttributes struct { - ID int64 `json:"id"` - Title string `json:"title"` - AssigneeID int64 `json:"assignee_id"` - AuthorID int64 `json:"author_id"` - ProjectID int64 `json:"project_id"` - CreatedAt customTime `json:"created_at"` - UpdatedAt customTime `json:"updated_at"` - ChangePosition Position `json:"change_position"` - OriginalPosition Position `json:"original_position"` - Position Position `json:"position"` - BranchName string `json:"branch_name"` - Description string `json:"description"` - MilestoneID int64 `json:"milestone_id"` - State string `json:"state"` - IID int64 `json:"iid"` - URL string `json:"url"` - Action string `json:"action"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int64 `json:"source_project_id"` - TargetProjectID int64 `json:"target_project_id"` - StCommits string `json:"st_commits"` - MergeStatus string `json:"merge_status"` - Content string `json:"content"` - Format string `json:"format"` - Message string `json:"message"` - Slug string `json:"slug"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - SHA string `json:"sha"` - BeforeSHA string `json:"before_sha"` - Status string `json:"status"` - Stages []string `json:"stages"` - Duration int64 `json:"duration"` - Note string `json:"note"` - NotebookType string `json:"noteable_type"` - At customTime `json:"attachment"` - LineCode string `json:"line_code"` - CommitID string `json:"commit_id"` - NoteableID int64 `json:"noteable_id"` - System bool `json:"system"` - WorkInProgress bool `json:"work_in_progress"` - StDiffs []StDiff `json:"st_diffs"` - Source Source `json:"source"` - Target Target `json:"target"` - LastCommit LastCommit `json:"last_commit"` - Assignee Assignee `json:"assignee"` -} - -// PipelineObjectAttributes contains pipeline specific GitLab object attributes information -type PipelineObjectAttributes struct { - ID int64 `json:"id"` - Ref string `json:"ref"` - Tag bool `json:"tag"` - SHA string `json:"sha"` - BeforeSHA string `json:"before_sha"` - Source string `json:"source"` - Status string `json:"status"` - Stages []string `json:"stages"` - CreatedAt customTime `json:"created_at"` - FinishedAt customTime `json:"finished_at"` - Duration int64 `json:"duration"` -} - -// Position defines a specific location, identified by paths line numbers and -// image coordinates, within a specific diff, identified by start, head and -// base commit ids. -// -// Text position will have: new_line and old_line -// Image position will have: width, height, x, y -type Position struct { - BaseSHA string `json:"base_sha"` - StartSHA string `json:"start_sha"` - HeadSHA string `json:"head_sha"` - OldPath string `json:"old_path"` - NewPath string `json:"new_path"` - PositionType string `json:"position_type"` - OldLine int64 `json:"old_line"` - NewLine int64 `json:"new_line"` - Width int64 `json:"width"` - Height int64 `json:"height"` - X int64 `json:"x"` - Y int64 `json:"y"` -} - -// MergeRequest contains all of the GitLab merge request information -type MergeRequest struct { - ID int64 `json:"id"` - TargetBranch string `json:"target_branch"` - SourceBranch string `json:"source_branch"` - SourceProjectID int64 `json:"source_project_id"` - AssigneeID int64 `json:"assignee_id"` - AuthorID int64 `json:"author_id"` - Title string `json:"title"` - CreatedAt customTime `json:"created_at"` - UpdatedAt customTime `json:"updated_at"` - MilestoneID int64 `json:"milestone_id"` - State string `json:"state"` - MergeStatus string `json:"merge_status"` - TargetProjectID int64 `json:"target_project_id"` - IID int64 `json:"iid"` - Description string `json:"description"` - Position int64 `json:"position"` - LockedAt customTime `json:"locked_at"` - Source Source `json:"source"` - Target Target `json:"target"` - LastCommit LastCommit `json:"last_commit"` - WorkInProgress bool `json:"work_in_progress"` - Assignee Assignee `json:"assignee"` -} - -// Assignee contains all of the GitLab assignee information -type Assignee struct { - Name string `json:"name"` - Username string `json:"username"` - AvatarURL string `json:"avatar_url"` -} - -// StDiff contains all of the GitLab diff information -type StDiff struct { - Diff string `json:"diff"` - NewPath string `json:"new_path"` - OldPath string `json:"old_path"` - AMode string `json:"a_mode"` - BMode string `json:"b_mode"` - NewFile bool `json:"new_file"` - RenamedFile bool `json:"renamed_file"` - DeletedFile bool `json:"deleted_file"` -} - -// Source contains all of the GitLab source information -type Source struct { - Name string `json:"name"` - Description string `json:"description"` - WebURL string `json:"web_url"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - VisibilityLevel int64 `json:"visibility_level"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` -} - -// Target contains all of the GitLab target information -type Target struct { - Name string `json:"name"` - Description string `json:"description"` - WebURL string `json:"web_url"` - AvatarURL string `json:"avatar_url"` - GitSSHURL string `json:"git_ssh_url"` - GitHTTPURL string `json:"git_http_url"` - Namespace string `json:"namespace"` - VisibilityLevel int64 `json:"visibility_level"` - PathWithNamespace string `json:"path_with_namespace"` - DefaultBranch string `json:"default_branch"` - Homepage string `json:"homepage"` - URL string `json:"url"` - SSHURL string `json:"ssh_url"` - HTTPURL string `json:"http_url"` -} - -// LastCommit contains all of the GitLab last commit information -type LastCommit struct { - ID string `json:"id"` - Message string `json:"message"` - Timestamp customTime `json:"timestamp"` - URL string `json:"url"` - Author Author `json:"author"` -} - -// Author contains all of the GitLab author information -type Author struct { - Name string `json:"name"` - Email string `json:"email"` -} - -// Changes contains all changes associated with a GitLab issue or MR -type Changes struct { - LabelChanges LabelChanges `json:"labels"` -} - -// LabelChanges contains changes in labels assocatiated with a GitLab issue or MR -type LabelChanges struct { - Previous []Label `json:"previous"` - Current []Label `json:"current"` -} - -// Label contains all of the GitLab label information -type Label struct { - ID int64 `json:"id"` - Title string `json:"title"` - Color string `json:"color"` - ProjectID int64 `json:"project_id"` - CreatedAt customTime `json:"created_at"` - UpdatedAt customTime `json:"updated_at"` - Template bool `json:"template"` - Description string `json:"description"` - Type string `json:"type"` - GroupID int64 `json:"group_id"` -} diff --git a/vendor/modules.txt b/vendor/modules.txt index c5d78f4c6..8b3cfa60d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -555,9 +555,6 @@ google.golang.org/protobuf/types/known/wrapperspb # gopkg.in/evanphx/json-patch.v4 v4.12.0 ## explicit gopkg.in/evanphx/json-patch.v4 -# gopkg.in/go-playground/webhooks.v5 v5.15.0 -## explicit -gopkg.in/go-playground/webhooks.v5/gitlab # gopkg.in/inf.v0 v0.9.1 ## explicit gopkg.in/inf.v0 From 34c6f5f07de5190eb865cf99a54125331f94a058 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Tue, 1 Jul 2025 16:55:21 +0100 Subject: [PATCH 04/20] chore(gitlabsource): update event types --- config/300-gitlabsource.yaml | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/config/300-gitlabsource.yaml b/config/300-gitlabsource.yaml index 73480946f..7b699866f 100644 --- a/config/300-gitlabsource.yaml +++ b/config/300-gitlabsource.yaml @@ -26,18 +26,22 @@ metadata: # NOTE(antoineco): GitLab doesn't currently provide schemas for those events (gitlab-org/gitlab#208924) registry.knative.dev/eventTypes: | [ - { - "type": "dev.knative.sources.gitlab.build", - "description": "Triggered on status change of a job." - }, { "type": "dev.knative.sources.gitlab.deployment", "description": "Triggered when a deployment starts, succeeds, fails, or is cancelled." }, + { + "type": "dev.knative.sources.gitlab.feature_flag", + "description": "Triggered when a feature flag is turned on or off.." + }, { "type": "dev.knative.sources.gitlab.issue", "description": "Triggered when a new issue is created or an existing issue was updated/closed/reopened." }, + { + "type": "dev.knative.sources.gitlab.job", + "description": "Triggered when a new issue is created or an existing issue was updated/closed/reopened." + }, { "type": "dev.knative.sources.gitlab.merge_request", "description": "Triggered when a merge request is created/updated/merged/closed or a commit is added in the source branch." @@ -53,6 +57,10 @@ metadata: { "type": "dev.knative.sources.gitlab.push", "description": "Triggered when you push to the repository except when pushing tags." + }, + { + "type": "dev.knative.sources.gitlab.release", + "description": "Triggered when a release is created, edited, or deleted." }, { "type": "dev.knative.sources.gitlab.tag_push", @@ -61,6 +69,10 @@ metadata: { "type": "dev.knative.sources.gitlab.wiki_page", "description": "Triggered when a wiki page is created, updated or deleted." + }, + { + "type": "dev.knative.sources.gitlab.resource_access_token", + "description": "Triggered when a project or group access token will expire in seven days." } ] spec: @@ -103,14 +115,17 @@ spec: - confidential_issues_events - confidential_note_events - deployment_events + - feature_flag_events - issues_events - job_events - merge_requests_events - note_events - pipeline_events - push_events + - releases_events - tag_push_events - wiki_page_events + - resource_access_token_events minItems: 1 accessToken: description: Access token for the GitLab API. From aacad6c2cc3fb711bb2d8e59a4953699fb0500cf Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Sun, 13 Jul 2025 22:10:02 +0100 Subject: [PATCH 05/20] chore: update DEVELOPMENT.md Signed-off-by: Alexandre Couedelo --- DEVELOPMENT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 5a52ccc5f..5099af957 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -41,9 +41,9 @@ To check out this repository: ```shell mkdir -p ${GOPATH}/src/knative.dev cd ${GOPATH}/src/knative.dev -git clone git@github.com:${YOUR_GITHUB_USERNAME}/eventing-contrib.git +git clone git@github.com:${YOUR_GITHUB_USERNAME}/eventing-gitlab.git cd eventing-contrib -git remote add upstream git@github.com:knative/eventing-contrib.git +git remote add upstream git@github.com:knative-extensions/eventing-gitlab.git git remote set-url --push upstream no_push ``` From f3790c0aaef5cb8b8aa806e3f1e35f0a5a0a85d6 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Mon, 14 Jul 2025 01:03:03 +0100 Subject: [PATCH 06/20] test: implement e2e tests Signed-off-by: Alexandre Couedelo --- DEVELOPMENT.md | 2 +- pkg/adapter/webhook.go | 3 +- samples/gitlabsource.yaml | 2 +- test/README.md | 0 test/e2e_test.go | 213 +++++++++++++++++++++++++ test/testdata/merge-request-hook.json5 | 202 +++++++++++++++++++++++ test/testdata/push-hook.json5 | 73 +++++++++ test/testdata/wiki-page-hook.json5 | 46 ++++++ 8 files changed, 538 insertions(+), 3 deletions(-) create mode 100644 test/README.md create mode 100644 test/e2e_test.go create mode 100644 test/testdata/merge-request-hook.json5 create mode 100644 test/testdata/push-hook.json5 create mode 100644 test/testdata/wiki-page-hook.json5 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 5099af957..053e64014 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -60,7 +60,7 @@ of the sources _Github Source_, _AWS SQS Source_, _Camel Source_, _Kafka Source_ with: ``` -ko apply -f /config # e.g. github/config +ko apply -f ./config ``` These commands are idempotent, so you can run them at any time to update your diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index 8af983e9f..da0a34c3a 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ + package adapter // ref: https://gitlab.com/gitlab-org/api/client-go/-/blob/main/examples/webhook.go?ref_type=heads diff --git a/samples/gitlabsource.yaml b/samples/gitlabsource.yaml index 5b73b54e0..ca4db4167 100644 --- a/samples/gitlabsource.yaml +++ b/samples/gitlabsource.yaml @@ -6,7 +6,7 @@ spec: eventTypes: - push_events - issues_events - projectUrl: + projectUrl: "https://gitlab.example.com" accessToken: secretKeyRef: name: gitlabsecret diff --git a/test/README.md b/test/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/test/e2e_test.go b/test/e2e_test.go new file mode 100644 index 000000000..268afbe82 --- /dev/null +++ b/test/e2e_test.go @@ -0,0 +1,213 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "bytes" + "context" + "io" + "net/http" + "os" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + servingv1 "knative.dev/serving/pkg/apis/serving/v1" + servingclient "knative.dev/serving/pkg/client/clientset/versioned" + + gitlabclient "knative.dev/eventing-gitlab/pkg/client/clientset/versioned" +) + +const ( + // Default namespace for the test + testNamespace = "default" + // Expected service name prefix based on the sample GitLabSource + expectedServicePrefix = "gitlabsource-sample-" + // Timeout for waiting for resources + waitTimeout = 5 * time.Minute + // GitLab webhook header for token validation + gitlabTokenHeader = "X-Gitlab-Token" +) + +func TestE2E_GitLabSourceWebhookIntegration(t *testing.T) { + // Create Kubernetes client config + config, err := rest.InClusterConfig() + if err != nil { + // Fallback to kubeconfig if not running in cluster + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + configOverrides := &clientcmd.ConfigOverrides{} + kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) + config, err = kubeConfig.ClientConfig() + require.NoError(t, err, "Failed to create Kubernetes client config") + } + + // Create clients + servingClient, err := servingclient.NewForConfig(config) + require.NoError(t, err, "Failed to create Knative Serving client") + + gitlabClient, err := gitlabclient.NewForConfig(config) + require.NoError(t, err, "Failed to create GitLab client") + + k8sClient, err := kubernetes.NewForConfig(config) + require.NoError(t, err, "Failed to create Kubernetes client") + + ctx := context.Background() + + // Get the GitLabSource resource + gitlabSource, err := gitlabClient.SourcesV1alpha1().GitLabSources(testNamespace).Get(ctx, "gitlabsource-sample", metav1.GetOptions{}) + require.NoError(t, err, "Failed to get GitLabSource") + + t.Logf("Found GitLabSource: %s", gitlabSource.Name) + t.Logf("GitLab Project URL: %s", gitlabSource.Spec.ProjectURL) + + // Get the secret containing the secret token + secretName := gitlabSource.Spec.SecretToken.SecretKeyRef.Name + secretKey := gitlabSource.Spec.SecretToken.SecretKeyRef.Key + + secret, err := k8sClient.CoreV1().Secrets(testNamespace).Get(ctx, secretName, metav1.GetOptions{}) + require.NoError(t, err, "Failed to get secret %s", secretName) + + secretToken, exists := secret.Data[secretKey] + require.True(t, exists, "Secret key %s not found in secret %s", secretKey, secretName) + + t.Logf("Retrieved secret token from secret %s, key %s (length: %d)", secretName, secretKey, len(secretToken)) + + // Find the GitLabSource adapter service + services, err := servingClient.ServingV1().Services(testNamespace).List(ctx, metav1.ListOptions{}) + require.NoError(t, err, "Failed to list Knative services") + + var gitlabSourceService *servingv1.Service + for i, service := range services.Items { + if strings.HasPrefix(service.Name, expectedServicePrefix) { + gitlabSourceService = &services.Items[i] + break + } + } + + require.NotNil(t, gitlabSourceService, "Expected to find a Knative service with prefix %s", expectedServicePrefix) + t.Logf("Found GitLabSource service: %s", gitlabSourceService.Name) + + // Verify the service has the expected labels + expectedLabels := map[string]string{ + "receive-adapter": "gitlab", + } + for key, expectedValue := range expectedLabels { + actualValue, exists := gitlabSourceService.Labels[key] + assert.True(t, exists, "Expected label %s to exist", key) + assert.Equal(t, expectedValue, actualValue, "Expected label %s to have value %s", key, expectedValue) + } + + // Get the webhook URL + require.NotNil(t, gitlabSourceService.Status.URL, "Service should have a URL") + webhookURL := gitlabSourceService.Status.URL.String() + t.Logf("GitLabSource webhook URL: %s", webhookURL) + + // Now run the webhook simulation subtests with the discovered endpoint + t.Run("WebhookSimulation", func(t *testing.T) { + // Discover all webhook payload files in testdata + testdataDir := "testdata" + files, err := os.ReadDir(testdataDir) + require.NoError(t, err, "Failed to read testdata directory") + + // Filter for webhook payload files + var webhookFiles []string + for _, file := range files { + if !file.IsDir() && strings.HasSuffix(file.Name(), ".json5") { + webhookFiles = append(webhookFiles, file.Name()) + } + } + + require.NotEmpty(t, webhookFiles, "No webhook payload files found in testdata") + t.Logf("Found %d webhook payload files: %v", len(webhookFiles), webhookFiles) + + // Test each webhook payload file + for _, filename := range webhookFiles { + // Extract webhook type from filename (e.g., "push-hook.json5" -> "push-hook") + webhookType := strings.TrimSuffix(filename, ".json5") + + t.Run(webhookType, func(t *testing.T) { + // Read the test payload + payloadFile := testdataDir + "/" + filename + payload, err := os.ReadFile(payloadFile) + require.NoError(t, err, "Failed to read test payload file %s", payloadFile) + + // Convert JSON5 to JSON by removing comments + jsonPayload := removeJSON5Comments(string(payload)) + + t.Logf("Sending GitLab %s webhook to %s", webhookType, webhookURL) + + // Create HTTP request + req, err := http.NewRequest("POST", webhookURL, bytes.NewReader([]byte(jsonPayload))) + require.NoError(t, err, "Failed to create HTTP request") + + // Set GitLab webhook headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", "GitLab/test") + + // Set the event type header based on the filename + eventType := getGitLabEventType(webhookType) + req.Header.Set("X-Gitlab-Event", eventType) + req.Header.Set(gitlabTokenHeader, string(secretToken)) + + // Send the webhook + client := &http.Client{Timeout: 30 * time.Second} + resp, err := client.Do(req) + require.NoError(t, err, "Failed to send webhook request") + defer resp.Body.Close() + + // Read response + respBody, err := io.ReadAll(resp.Body) + require.NoError(t, err, "Failed to read response body") + + // Verify the webhook was accepted (expecting 200-202 range) + assert.True(t, resp.StatusCode >= 200 && resp.StatusCode < 300, + "Expected successful response for %s webhook, got %d: %s", webhookType, resp.StatusCode, string(respBody)) + }) + } + }) +} + +// removeJSON5Comments removes JSON5 style comments to convert to valid JSON +func removeJSON5Comments(content string) string { + lines := strings.Split(content, "\n") + var result []string + + for _, line := range lines { + // Remove lines that start with // + trimmed := strings.TrimSpace(line) + if !strings.HasPrefix(trimmed, "//") { + result = append(result, line) + } + } + + return strings.Join(result, "\n") +} + +// getGitLabEventType convert "some-hook" to "Some Hook" +func getGitLabEventType(webhookType string) string { + parts := strings.Split(webhookType, "-") + for i, part := range parts { + parts[i] = strings.Title(part) + } + return strings.Join(parts, " ") +} diff --git a/test/testdata/merge-request-hook.json5 b/test/testdata/merge-request-hook.json5 new file mode 100644 index 000000000..fce5cc4d2 --- /dev/null +++ b/test/testdata/merge-request-hook.json5 @@ -0,0 +1,202 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#merge-request-events +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon", + "email": "admin@example.com" + }, + "project": { + "id": 1, + "name":"Gitlab Test", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/gitlabhq/gitlab-test", + "avatar_url":null, + "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", + "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", + "namespace":"GitlabHQ", + "visibility_level":20, + "path_with_namespace":"gitlabhq/gitlab-test", + "default_branch":"master", + "ci_config_path":"", + "homepage":"http://example.com/gitlabhq/gitlab-test", + "url":"http://example.com/gitlabhq/gitlab-test.git", + "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", + "http_url":"http://example.com/gitlabhq/gitlab-test.git" + }, + "repository": { + "name": "Gitlab Test", + "url": "http://example.com/gitlabhq/gitlab-test.git", + "description": "Aut reprehenderit ut est.", + "homepage": "http://example.com/gitlabhq/gitlab-test" + }, + "object_attributes": { + "id": 99, + "iid": 1, + "target_branch": "master", + "source_branch": "ms-viewport", + "source_project_id": 14, + "author_id": 51, + "assignee_ids": [6], + "assignee_id": 6, + "reviewer_ids": [6], + "title": "MS-Viewport", + "created_at": "2013-12-03T17:23:34Z", + "updated_at": "2013-12-03T17:23:34Z", + "last_edited_at": "2013-12-03T17:23:34Z", + "last_edited_by_id": 1, + "milestone_id": null, + "state_id": 1, + "state": "opened", + "blocking_discussions_resolved": true, + "work_in_progress": false, + "draft": false, + "first_contribution": true, + "merge_status": "unchecked", + "target_project_id": 14, + "description": "", + "prepared_at": "2013-12-03T19:23:34Z", + "total_time_spent": 1800, + "time_change": 30, + "human_total_time_spent": "30m", + "human_time_change": "30s", + "human_time_estimate": "30m", + "url": "http://example.com/diaspora/merge_requests/1", + "source": { + "name":"Awesome Project", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/awesome_space/awesome_project", + "avatar_url":null, + "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", + "git_http_url":"http://example.com/awesome_space/awesome_project.git", + "namespace":"Awesome Space", + "visibility_level":20, + "path_with_namespace":"awesome_space/awesome_project", + "default_branch":"master", + "homepage":"http://example.com/awesome_space/awesome_project", + "url":"http://example.com/awesome_space/awesome_project.git", + "ssh_url":"git@example.com:awesome_space/awesome_project.git", + "http_url":"http://example.com/awesome_space/awesome_project.git" + }, + "target": { + "name":"Awesome Project", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/awesome_space/awesome_project", + "avatar_url":null, + "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", + "git_http_url":"http://example.com/awesome_space/awesome_project.git", + "namespace":"Awesome Space", + "visibility_level":20, + "path_with_namespace":"awesome_space/awesome_project", + "default_branch":"master", + "homepage":"http://example.com/awesome_space/awesome_project", + "url":"http://example.com/awesome_space/awesome_project.git", + "ssh_url":"git@example.com:awesome_space/awesome_project.git", + "http_url":"http://example.com/awesome_space/awesome_project.git" + }, + "last_commit": { + "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "message": "fixed readme", + "title": "Update file README.md", + "timestamp": "2012-01-03T23:36:29+02:00", + "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "author": { + "name": "GitLab dev user", + "email": "gitlabdev@dv6700.(none)" + } + }, + "labels": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "action": "open", + "detailed_merge_status": "mergeable" + }, + "labels": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "changes": { + "updated_by_id": { + "previous": null, + "current": 1 + }, + "draft": { + "previous": true, + "current": false + }, + "updated_at": { + "previous": "2017-09-15 16:50:55 UTC", + "current":"2017-09-15 16:52:00 UTC" + }, + "labels": { + "previous": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "current": [{ + "id": 205, + "title": "Platform", + "color": "#123123", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "Platform related issues", + "type": "ProjectLabel", + "group_id": 41 + }] + }, + "last_edited_at": { + "previous": null, + "current": "2023-03-15 00:00:10 UTC" + }, + "last_edited_by_id": { + "previous": null, + "current": 3278533 + } + }, + "assignees": [ + { + "id": 6, + "name": "User1", + "username": "user1", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" + } + ], + "reviewers": [ + { + "id": 6, + "name": "User1", + "username": "user1", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" + } + ] +} diff --git a/test/testdata/push-hook.json5 b/test/testdata/push-hook.json5 new file mode 100644 index 000000000..5d984088c --- /dev/null +++ b/test/testdata/push-hook.json5 @@ -0,0 +1,73 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#push-events +{ + "object_kind": "push", + "event_name": "push", + "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", + "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "ref": "refs/heads/master", + "ref_protected": true, + "checkout_sha": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "user_id": 4, + "user_name": "John Smith", + "user_username": "jsmith", + "user_email": "john@example.com", + "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80", + "project_id": 15, + "project":{ + "id": 15, + "name":"Diaspora", + "description":"", + "web_url":"http://example.com/mike/diaspora", + "avatar_url":null, + "git_ssh_url":"git@example.com:mike/diaspora.git", + "git_http_url":"http://example.com/mike/diaspora.git", + "namespace":"Mike", + "visibility_level":0, + "path_with_namespace":"mike/diaspora", + "default_branch":"master", + "homepage":"http://example.com/mike/diaspora", + "url":"git@example.com:mike/diaspora.git", + "ssh_url":"git@example.com:mike/diaspora.git", + "http_url":"http://example.com/mike/diaspora.git" + }, + "repository":{ + "name": "Diaspora", + "url": "git@example.com:mike/diaspora.git", + "description": "", + "homepage": "http://example.com/mike/diaspora", + "git_http_url":"http://example.com/mike/diaspora.git", + "git_ssh_url":"git@example.com:mike/diaspora.git", + "visibility_level":0 + }, + "commits": [ + { + "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "message": "Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information", + "title": "Update Catalan translation to e38cb41.", + "timestamp": "2011-12-12T14:27:31+02:00", + "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", + "author": { + "name": "Jordi Mallach", + "email": "jordi@softcatala.org" + }, + "added": ["CHANGELOG"], + "modified": ["app/controller/application.rb"], + "removed": [] + }, + { + "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "message": "fixed readme", + "title": "fixed readme", + "timestamp": "2012-01-03T23:36:29+02:00", + "url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "author": { + "name": "GitLab dev user", + "email": "gitlabdev@dv6700.(none)" + }, + "added": ["CHANGELOG"], + "modified": ["app/controller/application.rb"], + "removed": [] + } + ], + "total_commits_count": 4 +} diff --git a/test/testdata/wiki-page-hook.json5 b/test/testdata/wiki-page-hook.json5 new file mode 100644 index 000000000..82db171b9 --- /dev/null +++ b/test/testdata/wiki-page-hook.json5 @@ -0,0 +1,46 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#wiki-page-events +{ + "object_kind": "wiki_page", + "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "project": { + "id": 1, + "name": "awesome-project", + "description": "This is awesome", + "web_url": "http://example.com/root/awesome-project", + "avatar_url": null, + "git_ssh_url": "git@example.com:root/awesome-project.git", + "git_http_url": "http://example.com/root/awesome-project.git", + "namespace": "root", + "visibility_level": 0, + "path_with_namespace": "root/awesome-project", + "default_branch": "master", + "homepage": "http://example.com/root/awesome-project", + "url": "git@example.com:root/awesome-project.git", + "ssh_url": "git@example.com:root/awesome-project.git", + "http_url": "http://example.com/root/awesome-project.git" + }, + "wiki": { + "web_url": "http://example.com/root/awesome-project/-/wikis/home", + "git_ssh_url": "git@example.com:root/awesome-project.wiki.git", + "git_http_url": "http://example.com/root/awesome-project.wiki.git", + "path_with_namespace": "root/awesome-project.wiki", + "default_branch": "master" + }, + "object_attributes": { + "title": "Awesome", + "content": "awesome content goes here", + "format": "markdown", + "message": "adding an awesome page to the wiki", + "slug": "awesome", + "url": "http://example.com/root/awesome-project/-/wikis/awesome", + "action": "create", + "diff_url": "http://example.com/root/awesome-project/-/wikis/home/diff?version_id=78ee4a6705abfbff4f4132c6646dbaae9c8fb6ec", + "version_id": "3ad67c972065298d226dd80b2b03e0fc2421e731" + } +} From 57b860fc1de815dde8a6dacb423d70f3d59c48d7 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Mon, 14 Jul 2025 01:17:50 +0100 Subject: [PATCH 07/20] test: more cases Signed-off-by: Alexandre Couedelo --- test/testdata/deployment-hook.json5 | 42 +++++ test/testdata/job-hook.json5 | 88 ++++++++++ test/testdata/pipeline-hook.json5 | 263 ++++++++++++++++++++++++++++ test/testdata/release-hook.json5 | 71 ++++++++ 4 files changed, 464 insertions(+) create mode 100644 test/testdata/deployment-hook.json5 create mode 100644 test/testdata/job-hook.json5 create mode 100644 test/testdata/pipeline-hook.json5 create mode 100644 test/testdata/release-hook.json5 diff --git a/test/testdata/deployment-hook.json5 b/test/testdata/deployment-hook.json5 new file mode 100644 index 000000000..c07f9f4ec --- /dev/null +++ b/test/testdata/deployment-hook.json5 @@ -0,0 +1,42 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#deployment-events +{ + "object_kind": "deployment", + "status": "success", + "status_changed_at":"2021-04-28 21:50:00 +0200", + "deployment_id": 15, + "deployable_id": 796, + "deployable_url": "http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796", + "environment": "staging", + "environment_tier": "staging", + "environment_slug": "staging", + "environment_external_url": "https://staging.example.com", + "project": { + "id": 30, + "name": "test-deployment-webhooks", + "description": "", + "web_url": "http://10.126.0.2:3000/root/test-deployment-webhooks", + "avatar_url": null, + "git_ssh_url": "ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git", + "git_http_url": "http://10.126.0.2:3000/root/test-deployment-webhooks.git", + "namespace": "Administrator", + "visibility_level": 0, + "path_with_namespace": "root/test-deployment-webhooks", + "default_branch": "master", + "ci_config_path": "", + "homepage": "http://10.126.0.2:3000/root/test-deployment-webhooks", + "url": "ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git", + "ssh_url": "ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git", + "http_url": "http://10.126.0.2:3000/root/test-deployment-webhooks.git" + }, + "short_sha": "279484c0", + "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "email": "admin@example.com" + }, + "user_url": "http://10.126.0.2:3000/root", + "commit_url": "http://10.126.0.2:3000/root/test-deployment-webhooks/-/commit/279484c09fbe69ededfced8c1bb6e6d24616b468", + "commit_title": "Add new file" +} diff --git a/test/testdata/job-hook.json5 b/test/testdata/job-hook.json5 new file mode 100644 index 000000000..ef2171509 --- /dev/null +++ b/test/testdata/job-hook.json5 @@ -0,0 +1,88 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#pipeline-events +{ + "object_kind": "build", + "ref": "gitlab-script-trigger", + "tag": false, + "before_sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", + "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", + "build_id": 1977, + "build_name": "test", + "build_stage": "test", + "build_status": "created", + "build_created_at": "2021-02-23T02:41:37.886Z", + "build_created_at_iso": "2021-02-23T02:41:37Z", + "build_started_at": null, + "build_started_at_iso": null, + "build_finished_at": null, + "build_finished_at_iso": null, + "build_duration": null, + "build_queued_duration": 1095.588715, + "build_allow_failure": false, + "build_failure_reason": "script_failure", + "retries_count": 2, + "pipeline_id": 2366, + "project_id": 380, + "project_name": "gitlab-org/gitlab-test", + "user": { + "id": 3, + "name": "User", + "email": "user@gitlab.com", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon" + }, + "commit": { + "id": 2366, + "name": "Build pipeline", + "sha": "2293ada6b400935a1378653304eaf6221e0fdb8f", + "message": "test\n", + "author_name": "User", + "author_email": "user@gitlab.com", + "status": "created", + "duration": null, + "started_at": null, + "started_at_iso": null, + "finished_at": null, + "finished_at_iso": null + }, + "repository": { + "name": "gitlab_test", + "description": "Atque in sunt eos similique dolores voluptatem.", + "homepage": "http://192.168.64.1:3005/gitlab-org/gitlab-test", + "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", + "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", + "visibility_level": 20 + }, + "project":{ + "id": 380, + "name": "Gitlab Test", + "description": "Atque in sunt eos similique dolores voluptatem.", + "web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test", + "avatar_url": null, + "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", + "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", + "namespace": "Gitlab Org", + "visibility_level": 20, + "path_with_namespace": "gitlab-org/gitlab-test", + "default_branch": "master" + }, + "runner": { + "active": true, + "runner_type": "project_type", + "is_shared": false, + "id": 380987, + "description": "shared-runners-manager-6.gitlab.com", + "tags": [ + "linux", + "docker" + ] + }, + "environment": null, + "source_pipeline":{ + "project":{ + "id": 41, + "web_url": "https://gitlab.example.com/gitlab-org/upstream-project", + "path_with_namespace": "gitlab-org/upstream-project" + }, + "pipeline_id": 30, + "job_id": 3401 + } +} diff --git a/test/testdata/pipeline-hook.json5 b/test/testdata/pipeline-hook.json5 new file mode 100644 index 000000000..c53c560c2 --- /dev/null +++ b/test/testdata/pipeline-hook.json5 @@ -0,0 +1,263 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#pipeline-events +{ + "object_kind": "pipeline", + "object_attributes":{ + "id": 31, + "iid": 3, + "name": "Pipeline for branch: master", + "ref": "master", + "tag": false, + "sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "source": "merge_request_event", + "status": "success", + "stages":[ + "build", + "test", + "deploy" + ], + "created_at": "2016-08-12 15:23:28 UTC", + "finished_at": "2016-08-12 15:26:29 UTC", + "duration": 63, + "variables": [ + { + "key": "NESTOR_PROD_ENVIRONMENT", + "value": "us-west-1" + } + ], + "url": "http://example.com/gitlab-org/gitlab-test/-/pipelines/31" + }, + "merge_request": { + "id": 1, + "iid": 1, + "title": "Test", + "source_branch": "test", + "source_project_id": 1, + "target_branch": "master", + "target_project_id": 1, + "state": "opened", + "merge_status": "can_be_merged", + "detailed_merge_status": "mergeable", + "url": "http://192.168.64.1:3005/gitlab-org/gitlab-test/merge_requests/1" + }, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "user_email@gitlab.com" + }, + "project":{ + "id": 1, + "name": "Gitlab Test", + "description": "Atque in sunt eos similique dolores voluptatem.", + "web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test", + "avatar_url": null, + "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", + "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", + "namespace": "Gitlab Org", + "visibility_level": 20, + "path_with_namespace": "gitlab-org/gitlab-test", + "default_branch": "master" + }, + "commit":{ + "id": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "message": "test\n", + "timestamp": "2016-08-12T17:23:21+02:00", + "url": "http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2", + "author":{ + "name": "User", + "email": "user@gitlab.com" + } + }, + "source_pipeline":{ + "project":{ + "id": 41, + "web_url": "https://gitlab.example.com/gitlab-org/upstream-project", + "path_with_namespace": "gitlab-org/upstream-project" + }, + "pipeline_id": 30, + "job_id": 3401 + }, + "builds":[ + { + "id": 380, + "stage": "deploy", + "name": "production", + "status": "skipped", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": null, + "finished_at": null, + "duration": null, + "queued_duration": null, + "failure_reason": null, + "when": "manual", + "manual": true, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": null, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": { + "name": "production", + "action": "start", + "deployment_tier": "production" + } + }, + { + "id": 377, + "stage": "test", + "name": "test-image", + "status": "success", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": "2016-08-12 15:26:12 UTC", + "finished_at": "2016-08-12 15:26:29 UTC", + "duration": 17.0, + "queued_duration": 196.0, + "failure_reason": null, + "when": "on_success", + "manual": false, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": { + "id": 380987, + "description": "shared-runners-manager-6.gitlab.com", + "active": true, + "runner_type": "instance_type", + "is_shared": true, + "tags": [ + "linux", + "docker", + "shared-runner" + ] + }, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": null + }, + { + "id": 378, + "stage": "test", + "name": "test-build", + "status": "failed", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": "2016-08-12 15:26:12 UTC", + "finished_at": "2016-08-12 15:26:29 UTC", + "duration": 17.0, + "queued_duration": 196.0, + "failure_reason": "script_failure", + "when": "on_success", + "manual": false, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": { + "id":380987, + "description":"shared-runners-manager-6.gitlab.com", + "active":true, + "runner_type": "instance_type", + "is_shared": true, + "tags": [ + "linux", + "docker" + ] + }, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": null + }, + { + "id": 376, + "stage": "build", + "name": "build-image", + "status": "success", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": "2016-08-12 15:24:56 UTC", + "finished_at": "2016-08-12 15:25:26 UTC", + "duration": 17.0, + "queued_duration": 196.0, + "failure_reason": null, + "when": "on_success", + "manual": false, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": { + "id": 380987, + "description": "shared-runners-manager-6.gitlab.com", + "active": true, + "runner_type": "instance_type", + "is_shared": true, + "tags": [ + "linux", + "docker" + ] + }, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": null + }, + { + "id": 379, + "stage": "deploy", + "name": "staging", + "status": "created", + "created_at": "2016-08-12 15:23:28 UTC", + "started_at": null, + "finished_at": null, + "duration": null, + "queued_duration": null, + "failure_reason": null, + "when": "on_success", + "manual": false, + "allow_failure": false, + "user":{ + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", + "email": "admin@example.com" + }, + "runner": null, + "artifacts_file":{ + "filename": null, + "size": null + }, + "environment": { + "name": "staging", + "action": "start", + "deployment_tier": "staging" + } + } + ] +} diff --git a/test/testdata/release-hook.json5 b/test/testdata/release-hook.json5 new file mode 100644 index 000000000..94e57059a --- /dev/null +++ b/test/testdata/release-hook.json5 @@ -0,0 +1,71 @@ +// ref: https://docs.gitlab.com/user/project/integrations/webhook_events/#release-events +{ + "id": 1, + "created_at": "2020-11-02 12:55:12 UTC", + "description": "v1.1 has been released", + "name": "v1.1", + "released_at": "2020-11-02 12:55:12 UTC", + "tag": "v1.1", + "object_kind": "release", + "project": { + "id": 2, + "name": "release-webhook-example", + "description": "", + "web_url": "https://example.com/gitlab-org/release-webhook-example", + "avatar_url": null, + "git_ssh_url": "ssh://git@example.com/gitlab-org/release-webhook-example.git", + "git_http_url": "https://example.com/gitlab-org/release-webhook-example.git", + "namespace": "Gitlab", + "visibility_level": 0, + "path_with_namespace": "gitlab-org/release-webhook-example", + "default_branch": "master", + "ci_config_path": null, + "homepage": "https://example.com/gitlab-org/release-webhook-example", + "url": "ssh://git@example.com/gitlab-org/release-webhook-example.git", + "ssh_url": "ssh://git@example.com/gitlab-org/release-webhook-example.git", + "http_url": "https://example.com/gitlab-org/release-webhook-example.git" + }, + "url": "https://example.com/gitlab-org/release-webhook-example/-/releases/v1.1", + "action": "create", + "assets": { + "count": 5, + "links": [ + { + "id": 1, + "external": true, + "link_type": "other", + "name": "Changelog", + "url": "https://example.net/changelog" + } + ], + "sources": [ + { + "format": "zip", + "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.zip" + }, + { + "format": "tar.gz", + "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.gz" + }, + { + "format": "tar.bz2", + "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.bz2" + }, + { + "format": "tar", + "url": "https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar" + } + ] + }, + "commit": { + "id": "ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8", + "message": "Release v1.1", + "title": "Release v1.1", + "timestamp": "2020-10-31T14:58:32+11:00", + "url": "https://example.com/gitlab-org/release-webhook-example/-/commit/ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8", + "author": { + "name": "Example User", + "email": "user@example.com" + } + } +} From 6f6cb1ad351327b3d8dd714ddde650972126a8b6 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Mon, 14 Jul 2025 01:27:49 +0100 Subject: [PATCH 08/20] test: add build tag Signed-off-by: Alexandre Couedelo --- test/e2e_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/e2e_test.go b/test/e2e_test.go index 268afbe82..ce74de3ea 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1,3 +1,5 @@ +//go:build integration + /* Copyright 2021 The Knative Authors From 91c46df9f3a811d54b85c423fc36ee7f54fa9056 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Mon, 14 Jul 2025 01:37:46 +0100 Subject: [PATCH 09/20] docs: e2e test Signed-off-by: Alexandre Couedelo --- test/README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/README.md b/test/README.md index e69de29bb..f6e846e60 100644 --- a/test/README.md +++ b/test/README.md @@ -0,0 +1,51 @@ +# e2e test + +This directory contains end-to-end integration tests for the GitLab eventing source. These tests verify the complete webhook integration by setting up a GitLabSource and simulating real GitLab webhook events. + +## Prerequisites + +- A Kubernetes cluster with Knative Serving and Eventing installed +- `kubectl` configured to access your cluster +- The GitLab eventing source controller deployed + +## Local Setup with Kind + +For local testing, you can use Knative Quickstart with Kind: + +```bash +kn quickstart kind +``` + +## Deploy Test Resources + +Deploy the required test resources in the following order: + +```bash +# Deploy an event display service to receive webhook events +kubectl -n default apply -f samples/event-display.yaml + +# Create the secret containing GitLab tokens +kubectl -n default apply -f samples/secret.yaml + +# Deploy the GitLabSource +kubectl -n default apply -f samples/gitlabsource.yaml +``` + +## Wait for Resources to be Ready + +Ensure all resources are ready before running tests: + +```bash +# Wait for the GitLabSource to be ready +kubectl wait --for=condition=Ready gitlabsource/gitlabsource-sample -n default --timeout=300s + +# Check the GitLabSource adapter service is created +kubectl get ksvc -n default | grep gitlabsource-sample +``` + +### Run Integration Tests Only + +```bash +# Run all integration tests +go test -tags=integration ./test -v +``` From 0bdcff2b07ac2f535c27c4dfdb76ee6dc70e864e Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Mon, 14 Jul 2025 09:28:40 +0100 Subject: [PATCH 10/20] test: event tracking validation Signed-off-by: Alexandre Couedelo --- test/e2e_test.go | 33 ++++++- test/event_tracker.go | 219 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 test/event_tracker.go diff --git a/test/e2e_test.go b/test/e2e_test.go index ce74de3ea..633c7a9ba 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1,7 +1,7 @@ //go:build integration /* -Copyright 2021 The Knative Authors +Copyright 2020 The Knative Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -124,6 +124,16 @@ func TestE2E_GitLabSourceWebhookIntegration(t *testing.T) { webhookURL := gitlabSourceService.Status.URL.String() t.Logf("GitLabSource webhook URL: %s", webhookURL) + // Start streaming event display logs in background + tracker := NewCloudEventTracker() + logCtx, cancelLogs := context.WithCancel(ctx) + defer cancelLogs() + + go streamEventDisplayLogs(t, logCtx, k8sClient, testNamespace, tracker) + + // Wait a moment for log streaming to start + time.Sleep(2 * time.Second) + // Now run the webhook simulation subtests with the discovered endpoint t.Run("WebhookSimulation", func(t *testing.T) { // Discover all webhook payload files in testdata @@ -181,9 +191,30 @@ func TestE2E_GitLabSourceWebhookIntegration(t *testing.T) { respBody, err := io.ReadAll(resp.Body) require.NoError(t, err, "Failed to read response body") + t.Logf("Webhook response status: %d", resp.StatusCode) + if len(respBody) > 0 { + t.Logf("Webhook response body: %s", string(respBody)) + } + // Verify the webhook was accepted (expecting 200-202 range) assert.True(t, resp.StatusCode >= 200 && resp.StatusCode < 300, "Expected successful response for %s webhook, got %d: %s", webhookType, resp.StatusCode, string(respBody)) + + // If webhook was accepted, verify that CloudEvents were produced + if resp.StatusCode >= 200 && resp.StatusCode < 300 { + expectedEventType := getExpectedCloudEventType(t, webhookType) + t.Logf("Waiting for CloudEvent of type: %s", expectedEventType) + + // Use assert.Eventually to wait for the expected event type + assert.Eventually(t, func() bool { + return tracker.HasEventType(expectedEventType) + }, 30*time.Second, 1*time.Second, + "Expected CloudEvent type %s was not received within timeout", expectedEventType) + + if tracker.HasEventType(expectedEventType) { + t.Logf("✅ CloudEvent of type %s successfully received", expectedEventType) + } + } }) } }) diff --git a/test/event_tracker.go b/test/event_tracker.go new file mode 100644 index 000000000..1da39ab04 --- /dev/null +++ b/test/event_tracker.go @@ -0,0 +1,219 @@ +//go:build integration + +/* +Copyright 2020 The Knative Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "context" + "io" + "strings" + "sync" + "testing" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +// CloudEventTracker tracks CloudEvent types seen in the event display logs +type CloudEventTracker struct { + mu sync.RWMutex + eventTypes map[string]bool +} + +// NewCloudEventTracker creates a new CloudEventTracker instance +func NewCloudEventTracker() *CloudEventTracker { + return &CloudEventTracker{ + eventTypes: make(map[string]bool), + } +} + +// AddEventType adds a CloudEvent type to the tracker +func (c *CloudEventTracker) AddEventType(eventType string) { + c.mu.Lock() + defer c.mu.Unlock() + c.eventTypes[eventType] = true +} + +// HasEventType checks if a CloudEvent type has been seen +func (c *CloudEventTracker) HasEventType(eventType string) bool { + c.mu.RLock() + defer c.mu.RUnlock() + return c.eventTypes[eventType] +} + +// GetTrackedEventTypes returns a list of all tracked event types +func (c *CloudEventTracker) GetTrackedEventTypes() []string { + c.mu.RLock() + defer c.mu.RUnlock() + + var types []string + for eventType := range c.eventTypes { + types = append(types, eventType) + } + return types +} + +// getEventDisplayLogs retrieves the current logs from the event display service +func getEventDisplayLogs(t *testing.T, ctx context.Context, k8sClient kubernetes.Interface, namespace string) string { + t.Helper() + + // Find the event display pod + pods, err := k8sClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: "serving.knative.dev/service=gitlab-event-display", + }) + if err != nil { + t.Logf("Warning: Failed to list event display pods: %v", err) + return "" + } + + if len(pods.Items) == 0 { + t.Logf("Warning: No event display pods found") + return "" + } + + // Get logs from the first pod + pod := pods.Items[0] + req := k8sClient.CoreV1().Pods(namespace).GetLogs(pod.Name, &corev1.PodLogOptions{ + Container: "user-container", // Knative serving container name + }) + + logs, err := req.Stream(ctx) + if err != nil { + t.Logf("Warning: Failed to stream logs from pod %s: %v", pod.Name, err) + return "" + } + defer logs.Close() + + logBytes, err := io.ReadAll(logs) + if err != nil { + t.Logf("Warning: Failed to read logs: %v", err) + return "" + } + + return string(logBytes) +} + +// streamEventDisplayLogs streams the logs from the event display service and tracks CloudEvent types +func streamEventDisplayLogs(t *testing.T, ctx context.Context, k8sClient kubernetes.Interface, namespace string, tracker *CloudEventTracker) { + t.Helper() + + var lastLogLength int + + for { + select { + case <-ctx.Done(): + return + default: + // Wait for the event display service to scale up (pods to exist) + pods, err := k8sClient.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: "serving.knative.dev/service=gitlab-event-display", + }) + if err != nil { + time.Sleep(5 * time.Second) + continue + } + + // If no pods exist, the service is scaled to zero - wait for scale up + if len(pods.Items) == 0 { + time.Sleep(2 * time.Second) + continue + } + + // Find a running pod + var runningPod *corev1.Pod + for i, pod := range pods.Items { + if pod.Status.Phase == corev1.PodRunning { + runningPod = &pods.Items[i] + break + } + } + + // If no running pods, wait for them to start + if runningPod == nil { + time.Sleep(2 * time.Second) + continue + } + + // Get logs from the running pod + req := k8sClient.CoreV1().Pods(namespace).GetLogs(runningPod.Name, &corev1.PodLogOptions{ + Container: "user-container", // Knative serving container name + }) + + logs, err := req.Stream(ctx) + if err != nil { + time.Sleep(5 * time.Second) + continue + } + + logBytes, err := io.ReadAll(logs) + logs.Close() + if err != nil { + time.Sleep(5 * time.Second) + continue + } + + currentLogs := string(logBytes) + + // Only process new log entries since last check + if len(currentLogs) > lastLogLength { + newLogs := currentLogs[lastLogLength:] + lastLogLength = len(currentLogs) + + // Process new log lines for CloudEvent types + lines := strings.Split(newLogs, "\n") + for _, line := range lines { + eventType := extractCloudEventType(t, line) + if eventType != "" { + tracker.AddEventType(eventType) + } + } + } + + time.Sleep(2 * time.Second) + } + } +} + +// extractCloudEventType extracts the CloudEvent type from a log line +func extractCloudEventType(t *testing.T, logLine string) string { + t.Helper() + + // Look for the line containing "type:" which indicates the event type + if strings.Contains(logLine, "type:") { + // Extract the part after "type: " + parts := strings.Split(logLine, "type: ") + if len(parts) > 1 { + // The event type is usually the first word in the next part + fields := strings.Fields(parts[1]) + if len(fields) > 0 { + return fields[0] + } + } + } + return "" +} + +// getExpectedCloudEventType converts webhook type to expected CloudEvent type +func getExpectedCloudEventType(t *testing.T, webhookType string) string { + t.Helper() + + eventType := strings.TrimSuffix(webhookType, "-hook") + return "dev.knative.sources.gitlab." + strings.ReplaceAll(eventType, "-", "_") +} From 1c3a95afdc87e96ed88abb29432575c3aee1b1ad Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Tue, 22 Jul 2025 13:28:25 +0100 Subject: [PATCH 11/20] Apply suggestion from @Cali0707 Co-authored-by: Calum Murray --- test/event_tracker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/event_tracker.go b/test/event_tracker.go index 1da39ab04..975c8b739 100644 --- a/test/event_tracker.go +++ b/test/event_tracker.go @@ -1,7 +1,7 @@ //go:build integration /* -Copyright 2020 The Knative Authors. +Copyright 2025 The Knative Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 998a65cc6b2a628c590eeab883f09332b6ca1cb6 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Tue, 22 Jul 2025 13:28:44 +0100 Subject: [PATCH 12/20] Apply suggestion from @Cali0707 Co-authored-by: Calum Murray --- test/e2e_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e_test.go b/test/e2e_test.go index 633c7a9ba..8d2fb7163 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1,7 +1,7 @@ //go:build integration /* -Copyright 2020 The Knative Authors. +Copyright 2025 The Knative Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 09abef87390628e7378a0f91c7f9aaa59141de28 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Tue, 22 Jul 2025 13:29:00 +0100 Subject: [PATCH 13/20] Apply suggestion from @xNok --- pkg/adapter/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index da0a34c3a..b40579612 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Knative Authors. +Copyright 2025 The Knative Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From 406fa4fa42b35d3f146540684dee4cf21f29acd2 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 18:28:13 +0000 Subject: [PATCH 14/20] chore: tidy dependencies --- go.mod | 1 - go.sum | 13 ++----------- vendor/modules.txt | 6 +++--- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 6ed35194f..f0b06c4f1 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/stretchr/testify v1.11.1 gitlab.com/gitlab-org/api/client-go v0.129.0 go.uber.org/zap v1.27.0 - gopkg.in/go-playground/webhooks.v5 v5.15.0 k8s.io/api v0.33.4 k8s.io/apimachinery v0.33.4 k8s.io/client-go v0.33.4 diff --git a/go.sum b/go.sum index ba317cb6d..549f4759f 100644 --- a/go.sum +++ b/go.sum @@ -174,9 +174,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -187,11 +185,11 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xanzy/go-gitlab v0.39.0 h1:7aiZ03fJfCdqoHFhsZq/SoVYp2lR91hfYWmiXLOU5Qo= -github.com/xanzy/go-gitlab v0.39.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +gitlab.com/gitlab-org/api/client-go v0.129.0 h1:o9KLn6fezmxBQWYnQrnilwyuOjlx4206KP0bUn3HuBE= +gitlab.com/gitlab-org/api/client-go v0.129.0/go.mod h1:ZhSxLAWadqP6J9lMh40IAZOlOxBLPRh7yFOXR/bMJWM= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= @@ -254,9 +252,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -268,11 +264,9 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= -golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -312,7 +306,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -334,7 +327,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= @@ -358,7 +350,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/modules.txt b/vendor/modules.txt index 8b3cfa60d..0ec1c8c5c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -227,9 +227,9 @@ github.com/stretchr/testify/require # github.com/x448/float16 v0.8.4 ## explicit; go 1.11 github.com/x448/float16 -# github.com/xanzy/go-gitlab v0.39.0 -## explicit; go 1.13 -github.com/xanzy/go-gitlab +# gitlab.com/gitlab-org/api/client-go v0.129.0 +## explicit; go 1.23.0 +gitlab.com/gitlab-org/api/client-go # go.opentelemetry.io/auto/sdk v1.1.0 ## explicit; go 1.22.0 go.opentelemetry.io/auto/sdk From 251c8e76c7d3495ea588bace1f3e67be78670d42 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 20:33:44 +0200 Subject: [PATCH 15/20] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config/300-gitlabsource.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/300-gitlabsource.yaml b/config/300-gitlabsource.yaml index 7b699866f..639c47cab 100644 --- a/config/300-gitlabsource.yaml +++ b/config/300-gitlabsource.yaml @@ -40,7 +40,7 @@ metadata: }, { "type": "dev.knative.sources.gitlab.job", - "description": "Triggered when a new issue is created or an existing issue was updated/closed/reopened." + "description": "Triggered when a job starts, succeeds, fails, or is cancelled." }, { "type": "dev.knative.sources.gitlab.merge_request", From b679050f3ef5f92d909a5df9a0f3824378d867a9 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 20:34:07 +0200 Subject: [PATCH 16/20] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config/300-gitlabsource.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/300-gitlabsource.yaml b/config/300-gitlabsource.yaml index 639c47cab..9d697d429 100644 --- a/config/300-gitlabsource.yaml +++ b/config/300-gitlabsource.yaml @@ -58,7 +58,7 @@ metadata: "type": "dev.knative.sources.gitlab.push", "description": "Triggered when you push to the repository except when pushing tags." }, - { + { "type": "dev.knative.sources.gitlab.release", "description": "Triggered when a release is created, edited, or deleted." }, From 2da7b1e6968e246f2fb57d5185538477cf37c63e Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 20:37:38 +0200 Subject: [PATCH 17/20] Apply suggestion from @xNok --- pkg/adapter/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index b40579612..8bd2f0b08 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -46,7 +46,7 @@ type webhook struct { EventSender EventSender } -// webhookExample shows how to create a Webhook server to parse Gitlab events. +// NewWebhookHandler provide a webhook receiver that parses Gitlab events and emits CloudEvents. func NewWebhookHandler(secret string, sender EventSender) webhook { wh := webhook{ Secret: secret, From 11944cbebb74314849dee031ad4fd0dfb3760766 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 20:38:08 +0200 Subject: [PATCH 18/20] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/adapter/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index 8bd2f0b08..0c9a9aefe 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -32,7 +32,7 @@ import ( var ( ErrMissingGitLabEventHeader = errors.New("missing X-Gitlab-Event Header") ErrEventNotSpecifiedToParse = errors.New("event not defined to be parsed") - ErrReadingfRequestBody = errors.New("error reading request body") + ErrReadingRequestBody = errors.New("error reading request body") ErrGitLabTokenVerificationFailed = errors.New("token validation failed") ErrCouldNotParseWebhookEvent = errors.New("could parse the webhook event") ErrCouldNotHandleEvent = errors.New("error handling the event") From 584d167df078cec9c4ac22f86f6b7b991fd9d818 Mon Sep 17 00:00:00 2001 From: Alexandre Couedelo Date: Wed, 13 Aug 2025 20:39:14 +0200 Subject: [PATCH 19/20] Apply suggestion from @xNok --- pkg/adapter/webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index 0c9a9aefe..a1c7cbf23 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -110,7 +110,7 @@ func (hook webhook) parse(r *http.Request) (any, error) { payload, err := io.ReadAll(r.Body) if err != nil || len(payload) == 0 { - return nil, ErrReadingfRequestBody + return nil, ErrReadingRequestBody } return gitlab.ParseWebhook(eventType, payload) From 1beb0cc0e07b852a54944c51b96e5b5e166e7409 Mon Sep 17 00:00:00 2001 From: Dave Protasowski Date: Thu, 18 Sep 2025 11:04:21 -0400 Subject: [PATCH 20/20] fix boilerplate --- pkg/adapter/webhook.go | 2 +- test/e2e_test.go | 2 +- test/event_tracker.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/adapter/webhook.go b/pkg/adapter/webhook.go index a1c7cbf23..aba7c5fcb 100644 --- a/pkg/adapter/webhook.go +++ b/pkg/adapter/webhook.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The Knative Authors. +Copyright 2025 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/e2e_test.go b/test/e2e_test.go index 8d2fb7163..3afb3ab7d 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -1,7 +1,7 @@ //go:build integration /* -Copyright 2025 The Knative Authors. +Copyright 2025 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/event_tracker.go b/test/event_tracker.go index 975c8b739..a4a47714a 100644 --- a/test/event_tracker.go +++ b/test/event_tracker.go @@ -1,7 +1,7 @@ //go:build integration /* -Copyright 2025 The Knative Authors. +Copyright 2025 The Knative Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.