// // 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" ) // AccessRequest represents a access request for a group or project. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/api/access_requests.html type AccessRequestsService struct { client *Client } // ListAccessRequestsOptions represents the available // ListProjectAccessRequests() or ListGroupAccessRequests() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(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/ee/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(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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // Copyright 2023, 徐晓伟 <xuxiaowei@xuxiaowei.com.cn> // // 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" // AppearanceService handles communication with appearance of the Gitlab API. // // Gitlab API docs : https://docs.gitlab.com/ee/api/appearance.html type AppearanceService struct { client *Client } // Appearance represents a GitLab appearance. // // Gitlab API docs : https://docs.gitlab.com/ee/api/appearance.html 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"` 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/ee/api/appearance.html#get-current-appearance-configuration 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/ee/api/appearance.html#change-appearance-configuration 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"` 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/ee/api/appearance.html#change-appearance-configuration 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 }
// // 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" ) // 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 } // Application represents a GitLab application type Application struct { ID int `json:"id"` ApplicationID string `json:"application_id"` ApplicationName string `json:"application_name"` Secret string `json:"secret"` CallbackURL string `json:"callback_url"` Confidential bool `json:"confidential"` } // CreateApplicationOptions represents the available CreateApplication() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/applications.html#create-an-application type CreateApplicationOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` RedirectURI *string `url:"redirect_uri,omitempty" json:"redirect_uri,omitempty"` Scopes *string `url:"scopes,omitempty" json:"scopes,omitempty"` Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"` } // CreateApplication creates a new application owned by the authenticated user. // // Gitlab API docs : https://docs.gitlab.com/ee/api/applications.html#create-an-application func (s *ApplicationsService) CreateApplication(opt *CreateApplicationOptions, options ...RequestOptionFunc) (*Application, *Response, error) { req, err := s.client.NewRequest(http.MethodPost, "applications", opt, options) if err != nil { return nil, nil, err } a := new(Application) resp, err := s.client.Do(req, a) if err != nil { return nil, 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/ee/api/applications.html#list-all-applications func (s *ApplicationsService) ListApplications(opt *ListApplicationsOptions, options ...RequestOptionFunc) ([]*Application, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "applications", opt, options) if err != nil { return nil, nil, err } var as []*Application resp, err := s.client.Do(req, &as) if err != nil { return nil, resp, err } return as, resp, nil } // DeleteApplication removes a specific application. // // GitLab API docs: // https://docs.gitlab.com/ee/api/applications.html#delete-an-application func (s *ApplicationsService) DeleteApplication(application int, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("applications/%d", application) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
package gitlab import ( "fmt" "net/http" "time" ) // AuditEvent represents an audit event for a group, a project or the instance. // // GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html type AuditEvent struct { ID int `json:"id"` AuthorID int `json:"author_id"` EntityID int `json:"entity_id"` EntityType string `json:"entity_type"` 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/ee/api/audit_events.html 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 interface{} `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"` } // AuditEventsService handles communication with the project/group/instance // audit event related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html type AuditEventsService struct { client *Client } // ListAuditEventsOptions represents the available ListProjectAuditEvents(), // ListGroupAuditEvents() or ListInstanceAuditEvents() options. // // GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html 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/ee/api/audit_events.html#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/ee/api/audit_events.html#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/ee/api/audit_events.html#retrieve-all-group-audit-events func (s *AuditEventsService) ListGroupAuditEvents(gid interface{}, 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/ee/api/audit_events.html#retrieve-a-specific-group-audit-event func (s *AuditEventsService) GetGroupAuditEvent(gid interface{}, 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/ee/api/audit_events.html#retrieve-all-project-audit-events func (s *AuditEventsService) ListProjectAuditEvents(pid interface{}, 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/ee/api/audit_events.html#retrieve-a-specific-project-audit-event func (s *AuditEventsService) GetProjectAuditEvent(pid interface{}, 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 }
// // 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" ) // AvatarRequestsService handles communication with the avatar related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/avatar.html type AvatarRequestsService struct { client *Client } // Avatar represents a GitLab avatar. // // GitLab API docs: https://docs.gitlab.com/ee/api/avatar.html type Avatar struct { AvatarURL string `json:"avatar_url"` } // GetAvatarOptions represents the available GetAvatar() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/avatar.html#get-a-single-avatar-url 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/ee/api/avatar.html#get-a-single-avatar-url 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 }
// // 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" ) // AwardEmojiService handles communication with the emoji awards related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/award_emoji.html type AwardEmojiService struct { client *Client } // AwardEmoji represents a GitLab Award Emoji. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/api/award_emoji.html#list-an-awardables-award-emojis 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/ee/api/award_emoji.html#list-an-awardables-award-emojis 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/ee/api/award_emoji.html#list-an-awardables-award-emojis 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(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/ee/api/award_emoji.html#get-single-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/ee/api/award_emoji.html#get-single-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/ee/api/award_emoji.html#get-single-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(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/ee/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/ee/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/ee/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/ee/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(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/ee/api/award_emoji.html#delete-an-award-emoji func (s *AwardEmojiService) DeleteIssueAwardEmoji(pid interface{}, 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/ee/api/award_emoji.html#delete-an-award-emoji 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/ee/api/award_emoji.html#delete-an-award-emoji func (s *AwardEmojiService) DeleteSnippetAwardEmoji(pid interface{}, 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/ee/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(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/ee/api/award_emoji.html#list-a-comments-award-emojis 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/ee/api/award_emoji.html#list-a-comments-award-emojis 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/ee/api/award_emoji.html#list-a-comments-award-emojis 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(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/ee/api/award_emoji.html#get-an-award-emoji-for-a-comment 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/ee/api/award_emoji.html#get-an-award-emoji-for-a-comment 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/ee/api/award_emoji.html#get-an-award-emoji-for-a-comment 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(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/ee/api/award_emoji.html#award-a-new-emoji-on-a-comment 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/ee/api/award_emoji.html#award-a-new-emoji-on-a-comment 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/ee/api/award_emoji.html#award-a-new-emoji-on-a-comment 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/ee/api/award_emoji.html#award-a-new-emoji-on-a-comment 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(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/ee/api/award_emoji.html#delete-an-award-emoji-from-a-comment 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/ee/api/award_emoji.html#delete-an-award-emoji-from-a-comment 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/ee/api/award_emoji.html#delete-an-award-emoji-from-a-comment 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // IssueBoardsService handles communication with the issue board related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/boards.html type IssueBoardsService struct { client *Client } // IssueBoard represents a GitLab issue board. // // GitLab API docs: https://docs.gitlab.com/ee/api/boards.html 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/ee/api/boards.html 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/ee/api/boards.html#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/ee/api/boards.html#create-an-issue-board 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(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/ee/api/boards.html#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/ee/api/boards.html#update-an-issue-board 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(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/ee/api/boards.html#delete-an-issue-board 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(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/ee/api/boards.html#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/ee/api/boards.html#list-project-issue-boards 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(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/ee/api/boards.html#show-a-single-issue-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(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/ee/api/boards.html#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/ee/api/boards.html#list-board-lists-in-a-project-issue-board 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(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/ee/api/boards.html#show-a-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(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/ee/api/boards.html#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/ee/api/boards.html#create-a-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(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/ee/api/boards.html#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/ee/api/boards.html#reorder-a-list-in-a-board 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(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/ee/api/boards.html#delete-a-board-list-from-a-board 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // BranchesService handles communication with the branch related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/branches.html type BranchesService struct { client *Client } // Branch represents a GitLab branch. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/api/branches.html#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/ee/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(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/ee/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(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 } // ProtectBranchOptions represents the available ProtectBranch() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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. // // Deprecated: This endpoint has been replaced by // ProtectedBranchesService.ProtectRepositoryBranches() // // GitLab API docs: // https://docs.gitlab.com/ee/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(http.MethodPut, 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, nil } // 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. // // Deprecated: This endpoint has been replaced by // ProtectedBranchesService.UnprotectRepositoryBranches() // // GitLab API docs: // https://docs.gitlab.com/ee/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(http.MethodPut, 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/ee/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/ee/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(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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // BroadcastMessagesService handles communication with the broadcast // messages methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/broadcast_messages.html type BroadcastMessagesService struct { client *Client } // BroadcastMessage represents a GitLab issue board. // // GitLab API docs: // https://docs.gitlab.com/ee/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"` 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"` // Deprecated: This parameter was removed in GitLab 15.6. Color string `json:"color"` } // ListBroadcastMessagesOptions represents the available ListBroadcastMessages() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/api/broadcast_messages.html#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/ee/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(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/ee/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"` 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"` // Deprecated: This parameter was removed in GitLab 15.6. Color *string `url:"color,omitempty" json:"color,omitempty"` } // CreateBroadcastMessage creates a message to broadcast. // // GitLab API docs: // https://docs.gitlab.com/ee/api/broadcast_messages.html#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/ee/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"` 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"` // Deprecated: This parameter was removed in GitLab 15.6. Color *string `url:"color,omitempty" json:"color,omitempty"` } // UpdateBroadcastMessage update a broadcasted message. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // CIYMLTemplatesService handles communication with the gitlab // CI YML templates related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/api/templates/gitlab_ci_ymls.html 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/ee/api/templates/gitlab_ci_ymls.html type CIYMLTemplateListItem struct { Key string `json:"key"` Name string `json:"name"` } // ListCIYMLTemplatesOptions represents the available ListAllTemplates() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/gitlab_ci_ymls.html#list-gitlab-ci-yaml-templates type ListCIYMLTemplatesOptions ListOptions // ListAllTemplates get all GitLab CI YML templates. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/gitlab_ci_ymls.html#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/ee/api/templates/gitlab_ci_ymls.html#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 }
// // 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 } }
// // Copyright 2022, Timo Furrer <tuxtimo@gmail.com> // // 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" ) // ClusterAgentsService handles communication with the cluster agents related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/cluster_agents.html type ClusterAgentsService struct { client *Client } // Agent represents a GitLab agent for Kubernetes. // // GitLab API docs: https://docs.gitlab.com/ee/api/cluster_agents.html 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/ee/api/cluster_agents.html#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/ee/api/cluster_agents.html#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/ee/api/cluster_agents.html#list-the-agents-for-a-project func (s *ClusterAgentsService) ListAgents(pid interface{}, 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/ee/api/cluster_agents.html#get-details-about-an-agent func (s *ClusterAgentsService) GetAgent(pid interface{}, 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/ee/api/cluster_agents.html#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/ee/api/cluster_agents.html#register-an-agent-with-a-project func (s *ClusterAgentsService) RegisterAgent(pid interface{}, 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/ee/api/cluster_agents.html#delete-a-registered-agent func (s *ClusterAgentsService) DeleteAgent(pid interface{}, 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/ee/api/cluster_agents.html#list-tokens-for-an-agent type ListAgentTokensOptions ListOptions // ListAgentTokens returns a list of tokens for an agent. // // GitLab API docs: // https://docs.gitlab.com/ee/api/cluster_agents.html#list-tokens-for-an-agent func (s *ClusterAgentsService) ListAgentTokens(pid interface{}, 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/ee/api/cluster_agents.html#get-a-single-agent-token func (s *ClusterAgentsService) GetAgentToken(pid interface{}, 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/ee/api/cluster_agents.html#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/ee/api/cluster_agents.html#create-an-agent-token func (s *ClusterAgentsService) CreateAgentToken(pid interface{}, 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/ee/api/cluster_agents.html#revoke-an-agent-token func (s *ClusterAgentsService) RevokeAgentToken(pid interface{}, 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) }
// // 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/ee/api/commits.html type CommitsService struct { client *Client } // Commit represents a GitLab commit. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/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/ee/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"` 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/ee/api/commits.html#list-repository-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(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/ee/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/ee/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/ee/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(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/ee/api/commits.html#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/ee/api/commits.html#get-a-single-commit func (s *CommitsService) GetCommit(pid interface{}, 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/ee/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" 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/ee/api/commits.html#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/ee/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(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/ee/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/ee/api/commits.html#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/ee/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(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/ee/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/ee/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/ee/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(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/ee/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/ee/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(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/ee/api/commits.html#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/ee/api/commits.html#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/ee/api/commits.html#list-the-statuses-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(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/ee/api/commits.html#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/ee/api/commits.html#set-the-pipeline-status-of-a-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(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/ee/api/commits.html#list-merge-requests-associated-with-a-commit func (s *CommitsService) ListMergeRequestsByCommit(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(http.MethodGet, 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, nil } // CherryPickCommitOptions represents the available CherryPickCommit() options. // // GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#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/ee/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(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/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(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/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"` } // GetGPGSignature 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) GetGPGSignature(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(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 }
// // 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" ) // 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"` 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/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 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/ee/api/container_registry.html#within-a-project func (s *ContainerRegistryService) ListProjectRegistryRepositories(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(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/ee/api/container_registry.html#within-a-group func (s *ContainerRegistryService) ListGroupRegistryRepositories(gid interface{}, 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/ee/api/container_registry.html#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/ee/api/container_registry.html#get-details-of-a-single-repository func (s *ContainerRegistryService) GetSingleRegistryRepository(pid interface{}, 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/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(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/ee/api/container_registry.html#list-registry-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-registry-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(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/ee/api/container_registry.html#get-details-of-a-registry-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(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/ee/api/container_registry.html#delete-a-registry-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(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/ee/api/container_registry.html#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/ee/api/container_registry.html#delete-registry-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(http.MethodDelete, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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/ee/api/custom_attributes.html type CustomAttributesService struct { client *Client } // CustomAttribute struct is used to unmarshal response to api calls. // // GitLab API docs: https://docs.gitlab.com/ee/api/custom_attributes.html type CustomAttribute struct { Key string `json:"key"` Value string `json:"value"` } // ListCustomUserAttributes lists the custom attributes of the specified user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#list-custom-attributes func (s *CustomAttributesService) ListCustomUserAttributes(user int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { return s.listCustomAttributes("users", user, options...) } // ListCustomGroupAttributes lists the custom attributes of the specified group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#list-custom-attributes func (s *CustomAttributesService) ListCustomGroupAttributes(group int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) { return s.listCustomAttributes("groups", group, options...) } // ListCustomProjectAttributes lists the custom attributes of the specified project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var cas []*CustomAttribute resp, err := s.client.Do(req, &cas) if err != nil { return nil, resp, err } return cas, resp, nil } // GetCustomUserAttribute returns the user attribute with a speciifc key. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var ca *CustomAttribute resp, err := s.client.Do(req, &ca) if err != nil { return nil, resp, err } return ca, resp, nil } // SetCustomUserAttribute sets the custom attributes of the specified user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#set-custom-attribute func (s *CustomAttributesService) SetCustomUserAttribute(user int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.setCustomAttribute("users", user, c, options...) } // SetCustomGroupAttribute sets the custom attributes of the specified group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#set-custom-attribute func (s *CustomAttributesService) SetCustomGroupAttribute(group int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) { return s.setCustomAttribute("groups", group, c, options...) } // SetCustomProjectAttribute sets the custom attributes of the specified project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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(http.MethodPut, u, c, options) if err != nil { return nil, nil, err } ca := new(CustomAttribute) resp, err := s.client.Do(req, ca) if err != nil { return nil, resp, err } return ca, resp, nil } // DeleteCustomUserAttribute removes the custom attribute of the specified user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#delete-custom-attribute func (s *CustomAttributesService) DeleteCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*Response, error) { return s.deleteCustomAttribute("users", user, key, options...) } // DeleteCustomGroupAttribute removes the custom attribute of the specified group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#delete-custom-attribute func (s *CustomAttributesService) DeleteCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*Response, error) { return s.deleteCustomAttribute("groups", group, key, options...) } // DeleteCustomProjectAttribute removes the custom attribute of the specified project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/custom_attributes.html#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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // DeployKeysService handles communication with the keys related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/deploy_keys.html type DeployKeysService struct { client *Client } // 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"` CreatedAt *time.Time `json:"created_at"` CanPush bool `json:"can_push"` } func (k ProjectDeployKey) String() string { return Stringify(k) } // ListProjectDeployKeysOptions represents the available ListAllDeployKeys() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/deploy_keys.html#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/ee/api/deploy_keys.html#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/ee/api/deploy_keys.html#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/ee/api/deploy_keys.html#list-deploy-keys-for-project func (s *DeployKeysService) ListProjectDeployKeys(pid interface{}, 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/ee/api/deploy_keys.html#get-a-single-deploy-key func (s *DeployKeysService) GetDeployKey(pid interface{}, 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/ee/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/ee/api/deploy_keys.html#add-deploy-key func (s *DeployKeysService) AddDeployKey(pid interface{}, 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/ee/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(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/ee/api/deploy_keys.html#enable-a-deploy-key func (s *DeployKeysService) EnableDeployKey(pid interface{}, 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/ee/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/ee/api/deploy_keys.html#update-deploy-key func (s *DeployKeysService) UpdateDeployKey(pid interface{}, 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 }
// // 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" ) // DeployTokensService handles communication with the deploy tokens related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/api/deploy_tokens.html#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/ee/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/ee/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(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/ee/api/deploy_tokens.html#get-a-project-deploy-token func (s *DeployTokensService) GetProjectDeployToken(pid interface{}, 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/ee/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/ee/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(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/ee/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(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/ee/api/deploy_tokens.html#list-group-deploy-tokens type ListGroupDeployTokensOptions ListOptions // ListGroupDeployTokens gets a list of a group’s deploy tokens. // // GitLab API docs: // https://docs.gitlab.com/ee/api/deploy_tokens.html#list-group-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(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/ee/api/deploy_tokens.html#get-a-group-deploy-token func (s *DeployTokensService) GetGroupDeployToken(gid interface{}, 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/ee/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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // DeploymentsService handles communication with the deployment related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/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"` 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/ee/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(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/ee/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(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/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(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/ee/api/deployments.html#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/ee/api/deployments.html#update-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(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/ee/api/deployments.html#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/ee/api/deployments.html#approve-or-reject-a-blocked-deployment func (s *DeploymentsService) ApproveOrRejectProjectDeployment(pid interface{}, 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/ee/api/deployments.html#delete-a-specific-deployment func (s *DeploymentsService) DeleteProjectDeployment(pid interface{}, 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) }
// 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" ) // DeploymentMergeRequestsService handles communication with the deployment's // merge requests related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/deployments.html#list-of-merge-requests-associated-with-a-deployment type DeploymentMergeRequestsService struct { client *Client } // ListDeploymentMergeRequests get the merge requests associated with deployment. // // GitLab API docs: // https://docs.gitlab.com/ee/api/deployments.html#list-of-merge-requests-associated-with-a-deployment func (s *DeploymentMergeRequestsService) ListDeploymentMergeRequests(pid interface{}, 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 }
// // 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" ) // DiscussionsService handles communication with the discussions related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/discussions.html type DiscussionsService struct { client *Client } // Discussion represents a GitLab discussion. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/api/discussions.html#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/ee/api/discussions.html#create-new-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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/api/discussions.html#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"` } // CreateMergeRequestDiscussion creates a new discussion for a single merge // request. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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/ee/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(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/ee/api/discussions.html#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/ee/api/discussions.html#add-note-to-existing-merge-request-thread 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(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/ee/api/discussions.html#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/ee/api/discussions.html#modify-an-existing-merge-request-thread-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(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/ee/api/discussions.html#delete-a-merge-request-thread-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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // DockerfileTemplatesService handles communication with the Dockerfile // templates related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/templates/dockerfiles.html type DockerfileTemplatesService struct { client *Client } // DockerfileTemplate represents a GitLab Dockerfile template. // // GitLab API docs: https://docs.gitlab.com/ee/api/templates/dockerfiles.html 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/ee/api/templates/dockerfiles.html type DockerfileTemplateListItem struct { Key string `json:"key"` Name string `json:"name"` } // ListDockerfileTemplatesOptions represents the available ListAllTemplates() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/dockerfiles.html#list-dockerfile-templates type ListDockerfileTemplatesOptions ListOptions // ListTemplates get a list of available Dockerfile templates. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/dockerfiles.html#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/ee/api/templates/dockerfiles.html#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 }
// // 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" ) // DORAMetricsService handles communication with the DORA metrics related methods // of the GitLab API. // // Gitlab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html type DORAMetricsService struct { client *Client } // DORAMetric represents a single DORA metric data point. // // Gitlab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html 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/ee/api/dora/metrics.html 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/ee/api/dora/metrics.html 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"` // Deprecated, use environment tiers instead EnvironmentTier *string `url:"environment_tier,omitempty" json:"environment_tier,omitempty"` } // GetProjectDORAMetrics gets the DORA metrics for a project. // // GitLab API Docs: // https://docs.gitlab.com/ee/api/dora/metrics.html#get-project-level-dora-metrics func (s *DORAMetricsService) GetProjectDORAMetrics(pid interface{}, 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/ee/api/dora/metrics.html#get-group-level-dora-metrics func (s *DORAMetricsService) GetGroupDORAMetrics(gid interface{}, 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 }
// // 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 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"` } // DraftNotesService handles communication with the draft notes related methods // of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/draft_notes.html#list-all-merge-request-draft-notes type DraftNotesService struct { client *Client } // ListDraftNotesOptions represents the available ListDraftNotes() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/draft_notes.html#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/ee/api/draft_notes.html#list-all-merge-request-draft-notes func (s *DraftNotesService) ListDraftNotes(pid interface{}, 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/ee/api/draft_notes.html#get-a-single-draft-note func (s *DraftNotesService) GetDraftNote(pid interface{}, 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/ee/api/draft_notes.html#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/ee/api/draft_notes.html#create-a-draft-note func (s *DraftNotesService) CreateDraftNote(pid interface{}, 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/ee/api/draft_notes.html#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/ee/api/draft_notes.html#create-a-draft-note func (s *DraftNotesService) UpdateDraftNote(pid interface{}, 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/ee/api/draft_notes.html#delete-a-draft-note func (s *DraftNotesService) DeleteDraftNote(pid interface{}, 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/ee/api/draft_notes.html#publish-a-draft-note func (s *DraftNotesService) PublishDraftNote(pid interface{}, 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/ee/api/draft_notes.html#publish-a-draft-note func (s *DraftNotesService) PublishAllDraftNotes(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/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) }
// // 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" ) // EnvironmentsService handles communication with the environment related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/environments.html type EnvironmentsService struct { client *Client } // Environment represents a GitLab environment. // // GitLab API docs: https://docs.gitlab.com/ee/api/environments.html type Environment struct { ID int `json:"id"` Name string `json:"name"` Slug string `json:"slug"` 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"` } 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 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/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(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/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(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/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"` Tier *string `url:"tier,omitempty" json:"tier,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(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/ee/api/environments.html#update-an-existing-environment type EditEnvironmentOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"` Tier *string `url:"tier,omitempty" json:"tier,omitempty"` } // EditEnvironment updates a project team environment to a specified access level.. // // GitLab API docs: // https://docs.gitlab.com/ee/api/environments.html#update-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(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/ee/api/environments.html#delete-an-environment 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(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/ee/api/environments.html#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/ee/api/environments.html#stop-an-environment func (s *EnvironmentsService) StopEnvironment(pid interface{}, 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 }
// // 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" ) // 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(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. // // 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(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. // // 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(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 } // 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(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 }
// // 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" ) // 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"` 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"` } 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 *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. // // 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(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. // // 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(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. // // 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(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. // // GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#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. // // 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(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. // // GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#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. // // 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(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. // // 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // Copyright 2022, Ryan Glab <ryan.j.glab@gmail.com> // // 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" ) // ErrorTrackingService handles communication with the error tracking // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/error_tracking.html type ErrorTrackingService struct { client *Client } // ErrorTrackingClientKey represents an error tracking client key. // // GitLab docs: // https://docs.gitlab.com/ee/api/error_tracking.html#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/ee/api/error_tracking.html#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/ee/api/error_tracking.html#get-error-tracking-settings func (s *ErrorTrackingService) GetErrorTrackingSettings(pid interface{}, 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/ee/api/error_tracking.html#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/ee/api/error_tracking.html#enable-or-disable-the-error-tracking-project-settings func (s *ErrorTrackingService) EnableDisableErrorTracking(pid interface{}, 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/ee/api/error_tracking.html#list-project-client-keys type ListClientKeysOptions ListOptions // ListClientKeys lists error tracking project client keys. // // GitLab API docs: // https://docs.gitlab.com/ee/api/error_tracking.html#list-project-client-keys func (s *ErrorTrackingService) ListClientKeys(pid interface{}, 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/ee/api/error_tracking.html#create-a-client-key func (s *ErrorTrackingService) CreateClientKey(pid interface{}, 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/ee/api/error_tracking.html#delete-a-client-key func (s *ErrorTrackingService) DeleteClientKey(pid interface{}, 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) }
// // 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 := 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 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 := 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 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]interface{}{} 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 }
// // 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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#issue-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/ee/user/project/integrations/webhook_events.html#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"` } // MemberEvent represents a member event. // // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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"` 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/ee/user/project/integrations/webhook_events.html#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"` 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 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 } // PipelineEvent represents a pipeline event. // // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#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"` SourcePipline 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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#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/ee/user/project/integrations/webhook_events.html#issue-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"` }
// // 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" ) // EventsService handles communication with the event related methods of // the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/events.html type EventsService struct { client *Client } // ContributionEvent represents a user's contribution // // GitLab API docs: // https://docs.gitlab.com/ee/api/events.html#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/ee/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/ee/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(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/ee/api/events.html#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/ee/api/events.html#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/ee/api/events.html#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/ee/api/events.html#list-a-projects-visible-events func (s *EventsService) ListProjectVisibleEvents(pid interface{}, 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 }
package gitlab import ( "fmt" "net/http" "time" ) // ExternalStatusChecksService handles communication with the external // status check related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/status_checks.html type ExternalStatusChecksService struct { client *Client } 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/ee/api/status_checks.html#list-status-checks-for-a-merge-request func (s *ExternalStatusChecksService) ListMergeStatusChecks(pid interface{}, 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/ee/api/status_checks.html#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/ee/api/status_checks.html#set-status-of-an-external-status-check func (s *ExternalStatusChecksService) SetExternalStatusCheckStatus(pid interface{}, 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/ee/api/status_checks.html#get-project-external-status-checks func (s *ExternalStatusChecksService) ListProjectStatusChecks(pid interface{}, 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/ee/api/status_checks.html#create-external-status-check 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/ee/api/status_checks.html#create-external-status-check func (s *ExternalStatusChecksService) CreateExternalStatusCheck(pid interface{}, 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/ee/api/status_checks.html#delete-external-status-check func (s *ExternalStatusChecksService) DeleteExternalStatusCheck(pid interface{}, 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/ee/api/status_checks.html#update-external-status-check 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/ee/api/status_checks.html#update-external-status-check func (s *ExternalStatusChecksService) UpdateExternalStatusCheck(pid interface{}, 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/ee/api/status_checks.html#retry-failed-status-check-for-a-merge-request func (s *ExternalStatusChecksService) RetryFailedStatusCheckForAMergeRequest(pid interface{}, 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) }
// // 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" ) // FeaturesService handles the communication with the application FeaturesService // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/features.html type FeaturesService struct { client *Client } // Feature represents a GitLab feature flag. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/api/features.html#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 } // SetFeatureFlag sets or creates a feature flag gate // // GitLab API docs: // https://docs.gitlab.com/ee/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(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 }
// // 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. // 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" ) // FreezePeriodsService handles the communication with the freeze periods // related methods of the GitLab API. // // https://docs.gitlab.com/ee/api/freeze_periods.html type FreezePeriodsService struct { client *Client } // FreezePeriod represents a freeze period object. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#list-freeze-periods type FreezePeriod struct { ID int `json:"id"` FreezeStart string `json:"freeze_start"` FreezeEnd string `json:"freeze_end"` CronTimezone string `json:"cron_timezone"` CreatedAt *time.Time `json:"created_at"` UpdatedAt *time.Time `json:"updated_at"` } // ListFreezePeriodsOptions represents the available ListFreezePeriodsOptions() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#list-freeze-periods type ListFreezePeriodsOptions ListOptions // ListFreezePeriods gets a list of project project freeze periods. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#list-freeze-periods func (s *FreezePeriodsService) ListFreezePeriods(pid interface{}, 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)) req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } var fp []*FreezePeriod resp, err := s.client.Do(req, &fp) if err != nil { return nil, resp, err } return fp, resp, nil } // GetFreezePeriod gets a specific freeze period for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/freeze_periods/%d", PathEscape(project), freezePeriod) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } fp := new(FreezePeriod) resp, err := s.client.Do(req, fp) if err != nil { return nil, resp, err } return fp, resp, nil } // CreateFreezePeriodOptions represents the available CreateFreezePeriodOptions() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#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"` CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` } // CreateFreezePeriodOptions adds a freeze period to a specified project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#create-a-freeze-period func (s *FreezePeriodsService) CreateFreezePeriodOptions(pid interface{}, 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)) req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } fp := new(FreezePeriod) resp, err := s.client.Do(req, fp) if err != nil { return nil, resp, err } return fp, resp, nil } // UpdateFreezePeriodOptions represents the available UpdateFreezePeriodOptions() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#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"` CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"` } // UpdateFreezePeriodOptions edits a freeze period for a specified project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/freeze_periods.html#update-a-freeze-period func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid interface{}, 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) req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } fp := new(FreezePeriod) resp, err := s.client.Do(req, fp) if err != nil { return nil, resp, err } return fp, resp, nil } // DeleteFreezePeriod removes a freeze period 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/ee/api/freeze_periods.html#delete-a-freeze-period func (s *FreezePeriodsService) DeleteFreezePeriod(pid interface{}, 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) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // GenericPackagesService handles communication with the packages related // methods of the GitLab API. // // GitLab docs: // https://docs.gitlab.com/ee/user/packages/generic_packages/index.html type GenericPackagesService struct { client *Client } // GenericPackagesFile represents a GitLab generic package file. // // GitLab API docs: // https://docs.gitlab.com/ee/user/packages/generic_packages/index.html#publish-a-package-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 interface{}, 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/ee/user/packages/generic_packages/index.html#publish-a-package-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/ee/user/packages/generic_packages/index.html#publish-a-package-file func (s *GenericPackagesService) PublishPackageFile(pid interface{}, 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/ee/user/packages/generic_packages/index.html#download-package-file func (s *GenericPackagesService) DownloadPackageFile(pid interface{}, 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 }
// // 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" ) // GeoNode represents a GitLab Geo Node. // // GitLab API docs: https://docs.gitlab.com/ee/api/geo_nodes.html 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. // // GitLab API docs: https://docs.gitlab.com/ee/api/geo_nodes.html type GeoNodeLinks struct { Self string `json:"self"` Status string `json:"status"` Repair string `json:"repair"` } // GeoNodesService handles communication with Geo Nodes related methods // of GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/geo_nodes.html type GeoNodesService struct { client *Client } // CreateGeoNodesOptions represents the available CreateGeoNode() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#retrieve-configuration-about-all-geo-nodes type ListGeoNodesOptions ListOptions // ListGeoNodes gets a list of geo nodes. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/geo_nodes.html#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 }
// // 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" ) // GitIgnoreTemplatesService handles communication with the gitignore // templates related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/templates/gitignores.html type GitIgnoreTemplatesService struct { client *Client } // GitIgnoreTemplate represents a GitLab gitignore template. // // GitLab API docs: https://docs.gitlab.com/ee/api/templates/gitignores.html 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/ee/api/templates/gitignores.html type GitIgnoreTemplateListItem struct { Key string `json:"key"` Name string `json:"name"` } // ListTemplatesOptions represents the available ListAllTemplates() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/gitignores.html#get-all-gitignore-templates type ListTemplatesOptions ListOptions // ListTemplates get a list of available git ignore templates // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/gitignores.html#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 []*GitIgnoreTemplateListItem resp, err := s.client.Do(req, &gs) if err != nil { return nil, resp, err } return gs, resp, nil } // GetTemplate get a git ignore template // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/gitignores.html#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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } g := new(GitIgnoreTemplate) resp, err := s.client.Do(req, g) if err != nil { return nil, resp, err } return g, resp, nil }
// // 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" "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/ee/api/ type AuthType int // List of available authentication types. // // GitLab API docs: https://docs.gitlab.com/ee/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 // Services used for talking to different parts of the GitLab API. AccessRequests *AccessRequestsService Appearance *AppearanceService Applications *ApplicationsService AuditEvents *AuditEventsService Avatar *AvatarRequestsService AwardEmoji *AwardEmojiService Boards *IssueBoardsService Branches *BranchesService BroadcastMessage *BroadcastMessagesService CIYMLTemplate *CIYMLTemplatesService ClusterAgents *ClusterAgentsService Commits *CommitsService ContainerRegistry *ContainerRegistryService CustomAttribute *CustomAttributesService DeployKeys *DeployKeysService DeployTokens *DeployTokensService DeploymentMergeRequests *DeploymentMergeRequestsService Deployments *DeploymentsService Discussions *DiscussionsService DockerfileTemplate *DockerfileTemplatesService DORAMetrics *DORAMetricsService DraftNotes *DraftNotesService Environments *EnvironmentsService EpicIssues *EpicIssuesService Epics *EpicsService ErrorTracking *ErrorTrackingService Events *EventsService ExternalStatusChecks *ExternalStatusChecksService Features *FeaturesService FreezePeriods *FreezePeriodsService GenericPackages *GenericPackagesService GeoNodes *GeoNodesService GitIgnoreTemplates *GitIgnoreTemplatesService GroupAccessTokens *GroupAccessTokensService GroupBadges *GroupBadgesService GroupCluster *GroupClustersService GroupEpicBoards *GroupEpicBoardsService GroupImportExport *GroupImportExportService GroupIssueBoards *GroupIssueBoardsService GroupIterations *GroupIterationsService GroupLabels *GroupLabelsService GroupMembers *GroupMembersService GroupMilestones *GroupMilestonesService GroupProtectedEnvironments *GroupProtectedEnvironmentsService GroupRepositoryStorageMove *GroupRepositoryStorageMoveService GroupSSHCertificates *GroupSSHCertificatesService GroupVariables *GroupVariablesService GroupWikis *GroupWikisService Groups *GroupsService Import *ImportService InstanceCluster *InstanceClustersService InstanceVariables *InstanceVariablesService Invites *InvitesService IssueLinks *IssueLinksService Issues *IssuesService IssuesStatistics *IssuesStatisticsService Jobs *JobsService JobTokenScope *JobTokenScopeService Keys *KeysService Labels *LabelsService License *LicenseService LicenseTemplates *LicenseTemplatesService ManagedLicenses *ManagedLicensesService Markdown *MarkdownService MemberRolesService *MemberRolesService MergeRequestApprovals *MergeRequestApprovalsService MergeRequests *MergeRequestsService MergeTrains *MergeTrainsService Metadata *MetadataService Milestones *MilestonesService Namespaces *NamespacesService Notes *NotesService NotificationSettings *NotificationSettingsService Packages *PackagesService Pages *PagesService PagesDomains *PagesDomainsService PersonalAccessTokens *PersonalAccessTokensService PipelineSchedules *PipelineSchedulesService PipelineTriggers *PipelineTriggersService Pipelines *PipelinesService PlanLimits *PlanLimitsService ProjectAccessTokens *ProjectAccessTokensService ProjectBadges *ProjectBadgesService ProjectCluster *ProjectClustersService ProjectFeatureFlags *ProjectFeatureFlagService ProjectImportExport *ProjectImportExportService ProjectIterations *ProjectIterationsService ProjectMembers *ProjectMembersService ProjectMirrors *ProjectMirrorService ProjectRepositoryStorageMove *ProjectRepositoryStorageMoveService ProjectSnippets *ProjectSnippetsService ProjectTemplates *ProjectTemplatesService ProjectVariables *ProjectVariablesService ProjectVulnerabilities *ProjectVulnerabilitiesService Projects *ProjectsService ProtectedBranches *ProtectedBranchesService ProtectedEnvironments *ProtectedEnvironmentsService ProtectedTags *ProtectedTagsService ReleaseLinks *ReleaseLinksService Releases *ReleasesService Repositories *RepositoriesService RepositoryFiles *RepositoryFilesService RepositorySubmodules *RepositorySubmodulesService ResourceGroup *ResourceGroupService ResourceIterationEvents *ResourceIterationEventsService ResourceLabelEvents *ResourceLabelEventsService ResourceMilestoneEvents *ResourceMilestoneEventsService ResourceStateEvents *ResourceStateEventsService ResourceWeightEvents *ResourceWeightEventsService Runners *RunnersService Search *SearchService Services *ServicesService Settings *SettingsService Sidekiq *SidekiqService SnippetRepositoryStorageMove *SnippetRepositoryStorageMoveService Snippets *SnippetsService SystemHooks *SystemHooksService Tags *TagsService Todos *TodosService Topics *TopicsService Users *UsersService Validate *ValidateService Version *VersionService Wikis *WikisService } // ListOptions specifies the optional parameters to various List methods that // support pagination. type ListOptions struct { // For offset-based paginated result sets, page of results to retrieve. Page int `url:"page,omitempty" json:"page,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 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, the value must be `"keyset"` Pagination string `url:"pagination,omitempty" json:"pagination,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} // Create all the public services. c.AccessRequests = &AccessRequestsService{client: c} c.Appearance = &AppearanceService{client: c} c.Applications = &ApplicationsService{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.CIYMLTemplate = &CIYMLTemplatesService{client: c} c.ClusterAgents = &ClusterAgentsService{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.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.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.Features = &FeaturesService{client: c} c.FreezePeriods = &FreezePeriodsService{client: c} c.GenericPackages = &GenericPackagesService{client: c} c.GeoNodes = &GeoNodesService{client: c} c.GitIgnoreTemplates = &GitIgnoreTemplatesService{client: c} c.GroupAccessTokens = &GroupAccessTokensService{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.GroupMembers = &GroupMembersService{client: c} c.GroupMilestones = &GroupMilestonesService{client: c} c.GroupProtectedEnvironments = &GroupProtectedEnvironmentsService{client: c} c.GroupRepositoryStorageMove = &GroupRepositoryStorageMoveService{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.ManagedLicenses = &ManagedLicensesService{client: c} c.Markdown = &MarkdownService{client: c} c.MemberRolesService = &MemberRolesService{client: c} c.MergeRequestApprovals = &MergeRequestApprovalsService{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.ProjectMembers = &ProjectMembersService{client: c} c.ProjectMirrors = &ProjectMirrorService{client: c} c.ProjectRepositoryStorageMove = &ProjectRepositoryStorageMoveService{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.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.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, _ 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(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 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 == 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. for k, v := range reqHeaders { req.Header[k] = v } 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 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) } 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. 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 // 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 interface{}) (*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) } } 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() 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 } // 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.ReplaceAll(url.PathEscape(s), ".", "%2E") } // An ErrorResponse reports one or more errors caused by an API request. // // GitLab API docs: // https://docs.gitlab.com/ee/api/index.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) 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 interface{} 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": { // "<property-name>": [ // "<error-message>", // "<error-message>", // ... // ], // "<embed-entity>": { // "<property-name>": [ // "<error-message>", // "<error-message>", // ... // ], // } // }, // "error": "<error-message>" // } 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) } }
// // 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" "time" ) // GroupAccessTokensService handles communication with the // groups access tokens related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_access_tokens.html type GroupAccessTokensService struct { client *Client } // GroupAccessToken represents a GitLab group access token. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_access_tokens.html type GroupAccessToken struct { ID int `json:"id"` UserID int `json:"user_id"` Name string `json:"name"` Scopes []string `json:"scopes"` CreatedAt *time.Time `json:"created_at"` ExpiresAt *ISOTime `json:"expires_at"` LastUsedAt *time.Time `json:"last_used_at"` Active bool `json:"active"` Revoked bool `json:"revoked"` Token string `json:"token"` AccessLevel AccessLevelValue `json:"access_level"` } func (v GroupAccessToken) String() string { return Stringify(v) } // ListGroupAccessTokensOptions represents the available options for // listing variables in a group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_access_tokens.html#list-group-access-tokens type ListGroupAccessTokensOptions ListOptions // ListGroupAccessTokens gets a list of all group access tokens in a group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_access_tokens.html#list-group-access-tokens func (s *GroupAccessTokensService) ListGroupAccessTokens(gid interface{}, 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/ee/api/group_access_tokens.html#get-a-group-access-token func (s *GroupAccessTokensService) GetGroupAccessToken(gid interface{}, 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/ee/api/group_access_tokens.html#create-a-group-access-token type CreateGroupAccessTokenOptions struct { Name *string `url:"name,omitempty" json:"name,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/ee/api/group_access_tokens.html#create-a-group-access-token func (s *GroupAccessTokensService) CreateGroupAccessToken(gid interface{}, 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/ee/api/group_access_tokens.html#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/ee/api/group_access_tokens.html#rotate-a-group-access-token func (s *GroupAccessTokensService) RotateGroupAccessToken(gid interface{}, 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 } // RevokeGroupAccessToken revokes a group access token. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_access_tokens.html#revoke-a-group-access-token func (s *GroupAccessTokensService) RevokeGroupAccessToken(gid interface{}, 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) }
// // 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" ) // 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"` 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/ee/api/group_badges.html#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/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(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/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(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/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"` Name *string `url:"name,omitempty" json:"name,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(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/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"` Name *string `url:"name,omitempty" json:"name,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(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/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(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/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"` 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/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(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 }
// // 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" ) // GroupIssueBoardsService handles communication with the group issue board // related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_boards.html type GroupIssueBoardsService struct { client *Client } // GroupIssueBoard represents a GitLab group issue board. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_boards.html 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/ee/api/group_boards.html#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/ee/api/group_boards.html#list-all-group-issue-boards-in-a-group 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(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/ee/api/group_boards.html#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/ee/api/group_boards.html#create-a-group-issue-board 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(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/ee/api/group_boards.html#single-group-issue-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(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/ee/api/group_boards.html#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/ee/api/group_boards.html#update-a-group-issue-board 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(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/ee/api/group_boards.html#delete-a-group-issue-board 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(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/ee/api/group_boards.html#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/ee/api/group_boards.html#list-group-issue-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(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/ee/api/group_boards.html#single-group-issue-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(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/ee/api/group_boards.html#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/ee/api/group_boards.html#new-group-issue-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(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/ee/api/group_boards.html#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/ee/api/group_boards.html#edit-group-issue-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(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/ee/api/group_boards.html#delete-a-group-issue-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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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. // 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" ) // 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 } // GroupCluster represents a GitLab Group Cluster. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_clusters.html 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"` ClusterType string `json:"cluster_type"` User *User `json:"user"` PlatformKubernetes *PlatformKubernetes `json:"platform_kubernetes"` ManagementProject *ManagementProject `json:"management_project"` Group *Group `json:"group"` } func (v GroupCluster) String() string { return Stringify(v) } // ListClusters gets a list of all clusters in a group. // // 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) { group, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("groups/%s/clusters", PathEscape(group)) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var pcs []*GroupCluster resp, err := s.client.Do(req, &pcs) if err != nil { return nil, resp, err } return pcs, resp, nil } // GetCluster gets a cluster. // // 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) { group, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } gc := new(GroupCluster) resp, err := s.client.Do(req, &gc) if err != nil { return nil, resp, err } return gc, resp, nil } // AddGroupClusterOptions represents the available AddCluster() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_clusters.html#add-existing-cluster-to-group type AddGroupClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"` Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` Managed *bool `url:"managed,omitempty" json:"managed,omitempty"` EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` PlatformKubernetes *AddGroupPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"` } // AddGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for adding. type AddGroupPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"` Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` AuthorizationType *string `url:"authorization_type,omitempty" json:"authorization_type,omitempty"` } // AddCluster adds an existing cluster to the group. // // 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) { group, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("groups/%s/clusters/user", PathEscape(group)) req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } gc := new(GroupCluster) resp, err := s.client.Do(req, gc) if err != nil { return nil, resp, err } return gc, resp, nil } // EditGroupClusterOptions represents the available EditCluster() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_clusters.html#edit-group-cluster type EditGroupClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` PlatformKubernetes *EditGroupPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"` ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"` } // EditGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for editing. type EditGroupPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"` } // EditCluster updates an existing group cluster. // // 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) { group, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } gc := new(GroupCluster) resp, err := s.client.Do(req, gc) if err != nil { return nil, resp, err } return gc, resp, nil } // DeleteCluster deletes an existing group cluster. // // 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) { group, err := parseID(pid) if err != nil { return nil, err } u := fmt.Sprintf("groups/%s/clusters/%d", PathEscape(group), cluster) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // GroupEpicBoardsService handles communication with the group epic board // related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_epic_boards.html type GroupEpicBoardsService struct { client *Client } // GroupEpicBoard represents a GitLab group epic board. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_epic_boards.html 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/ee/api/group_epic_boards.html#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/ee/api/group_epic_boards.html#list-all-epic-boards-in-a-group func (s *GroupEpicBoardsService) ListGroupEpicBoards(gid interface{}, 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/ee/api/group_epic_boards.html#single-group-epic-board func (s *GroupEpicBoardsService) GetGroupEpicBoard(gid interface{}, 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 }
// // 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/ee/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"` PushEventsBranchFilter string `json:"push_events_branch_filter"` 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"` DeploymentEvents bool `json:"deployment_events"` ReleasesEvents bool `json:"releases_events"` SubGroupEvents bool `json:"subgroup_events"` MemberEvents bool `json:"member_events"` EnableSSLVerification bool `json:"enable_ssl_verification"` AlertStatus string `json:"alert_status"` CreatedAt *time.Time `json:"created_at"` CustomWebhookTemplate string `json:"custom_webhook_template"` ResourceAccessTokenEvents bool `json:"resource_access_token_events"` CustomHeaders []*HookCustomHeader `url:"custom_headers,omitempty" json:"custom_headers,omitempty"` } // ListGroupHooksOptions represents the available ListGroupHooks() options. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#list-group-hooks type ListGroupHooksOptions ListOptions // ListGroupHooks gets a list of group hooks. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#list-group-hooks func (s *GroupsService) ListGroupHooks(gid interface{}, 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/ee/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(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 } // 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"` 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"` 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"` DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_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 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(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/ee/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"` 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"` 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"` DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_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"` } // EditGroupHook edits a hook for a specified group. // // Gitlab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(http.MethodDelete, 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/ee/api/groups.html#set-a-custom-header func (s *GroupsService) SetGroupCustomHeader(gid interface{}, 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/ee/api/groups.html#delete-a-custom-header func (s *GroupsService) DeleteGroupCustomHeader(gid interface{}, 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) }
// // 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" ) // GroupImportExportService handles communication with the group import export // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_import_export.html type GroupImportExportService struct { client *Client } // ScheduleExport starts a new group export. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_import_export.html#schedule-new-export func (s *GroupImportExportService) ScheduleExport(gid interface{}, 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/ee/api/group_import_export.html#export-download func (s *GroupImportExportService) ExportDownload(gid interface{}, 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/ee/api/group_import_export.html#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/ee/api/group_import_export.html#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) }
// // 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" ) // IterationsAPI handles communication with the iterations related methods // of the GitLab API // // GitLab API docs: https://docs.gitlab.com/ee/api/group_iterations.html type GroupIterationsService struct { client *Client } // GroupInteration represents a GitLab iteration. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_iterations.html 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/ee/api/group_iterations.html#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/ee/api/group_iterations.html#list-group-iterations func (s *GroupIterationsService) ListGroupIterations(gid interface{}, 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 }
// // 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" ) // GroupLabelsService handles communication with the label related methods of the // GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_labels.html type GroupLabelsService struct { client *Client } // GroupLabel represents a GitLab group label. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/api/group_labels.html#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/ee/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(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/ee/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), 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/ee/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/ee/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(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/ee/api/group_labels.html#delete-a-group-label type DeleteGroupLabelOptions DeleteLabelOptions // DeleteGroupLabel deletes a group label given by its name or ID. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_labels.html#delete-a-group-label func (s *GroupLabelsService) DeleteGroupLabel(gid interface{}, lid 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)) 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/ee/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/ee/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(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/ee/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), 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/ee/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), PathEscape(label)) req, err := s.client.NewRequest(http.MethodPost, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // GroupMembersService handles communication with the group members // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/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"` 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"` } // ListGroupMembersOptions represents the available ListGroupMembers() and // ListAllGroupMembers() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/members.html#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/ee/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(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/ee/api/members.html#list-all-members-of-a-group-or-project-including-inherited-and-invited-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(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/ee/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"` 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/ee/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(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/ee/api/members.html#get-a-member-of-a-group-or-project-including-inherited-and-invited-members func (s *GroupMembersService) GetInheritedGroupMember(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/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 } // BillableGroupMember represents a GitLab billable group member. // // GitLab API docs: https://docs.gitlab.com/ee/api/members.html#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"` } // ListBillableGroupMembersOptions represents the available ListBillableGroupMembers() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/members.html#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/ee/api/members.html#list-all-billable-members-of-a-group func (s *GroupsService) ListBillableGroupMembers(gid interface{}, 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 } // RemoveBillableGroupMember removes a given group members that count as billable. // // GitLab API docs: // https://docs.gitlab.com/ee/api/members.html#remove-a-billable-member-from-a-group func (s *GroupsService) RemoveBillableGroupMember(gid interface{}, 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/ee/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(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/ee/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(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/ee/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(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/ee/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,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/ee/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(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/ee/api/members.html#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/ee/api/members.html#remove-a-member-from-a-group-or-project func (s *GroupMembersService) RemoveGroupMember(gid interface{}, 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) }
// // 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" ) // GroupMilestonesService handles communication with the milestone related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_milestones.html type GroupMilestonesService struct { client *Client } // GroupMilestone represents a GitLab milestone. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/api/group_milestones.html#delete-group-milestone func (s *GroupMilestonesService) DeleteGroupMilestone(pid interface{}, 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/ee/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/ee/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(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/ee/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/ee/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(http.MethodGet, 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, nil } // BurndownChartEvent reprensents a burnout chart event // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_milestones.html#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/ee/api/group_milestones.html#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/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone 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(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 }
// // 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" ) // GroupProtectedEnvironmentsService handles communication with the group-level // protected environment methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_protected_environments.html type GroupProtectedEnvironmentsService struct { client *Client } // GroupProtectedEnvironment represents a group-level protected environment. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_protected_environments.html 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/ee/api/group_protected_environments.html 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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#list-group-level-protected-environments func (s *GroupProtectedEnvironmentsService) ListGroupProtectedEnvironments(gid interface{}, 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/ee/api/group_protected_environments.html#get-a-single-protected-environment func (s *GroupProtectedEnvironmentsService) GetGroupProtectedEnvironment(gid interface{}, 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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#protect-a-single-environment func (s *GroupProtectedEnvironmentsService) ProtectGroupEnvironment(gid interface{}, 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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#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/ee/api/group_protected_environments.html#update-a-protected-environment func (s *GroupProtectedEnvironmentsService) UpdateGroupProtectedEnvironment(gid interface{}, 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/ee/api/group_protected_environments.html#unprotect-a-single-environment func (s *GroupProtectedEnvironmentsService) UnprotectGroupEnvironment(gid interface{}, 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) }
// // 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" ) // GroupRepositoryStorageMoveService handles communication with the // group repositories related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_repository_storage_moves.html type GroupRepositoryStorageMoveService struct { client *Client } // GroupRepositoryStorageMove represents the status of a repository move. // // GitLab API docs: // https://docs.gitlab.com/ee/api/group_repository_storage_moves.html 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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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/ee/api/group_repository_storage_moves.html#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) }
// // 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/ee/api/groups.html#create-service-account-user type GroupServiceAccount struct { ID int `json:"id"` Name string `json:"name"` UserName string `json:"username"` } // CreateServiceAccount create a new service account user for a group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#create-service-account-user func (s *GroupsService) CreateServiceAccount(gid interface{}, 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, nil, 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 } // CreateServiceAccountPersonalAccessTokenOptions represents the available // CreateServiceAccountPersonalAccessToken() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#create-personal-access-token-for-service-account-user type CreateServiceAccountPersonalAccessTokenOptions struct { Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"` Name *string `url:"name,omitempty" json:"name,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/ee/api/groups.html#create-personal-access-token-for-service-account-user func (s *GroupsService) CreateServiceAccountPersonalAccessToken(gid interface{}, 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 } // RotateServiceAccountPersonalAccessToken rotates a Personal Access Token for a // service account user for a group. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#create-personal-access-token-for-service-account-user func (s *GroupsService) RotateServiceAccountPersonalAccessToken(gid interface{}, serviceAccount, token int, 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, 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 }
package gitlab import ( "fmt" "net/http" "time" ) // GroupSSHCertificatesService handles communication with the group // SSH certificate related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_ssh_certificates.html type GroupSSHCertificatesService struct { client *Client } // GroupSSHCertificate represents a GitLab Group SSH certificate. // // GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html 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/ee/api/group_ssh_certificates.html#get-all-ssh-certificates-for-a-particular-group func (s *GroupSSHCertificatesService) ListGroupSSHCertificates(gid interface{}, 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/ee/api/group_ssh_certificates.html#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/ee/api/group_ssh_certificates.html#create-ssh-certificate func (s *GroupSSHCertificatesService) CreateGroupSSHCertificate(gid interface{}, 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/ee/api/group_ssh_certificates.html#delete-group-ssh-certificate func (s *GroupSSHCertificatesService) DeleteGroupSSHCertificate(gid interface{}, 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) }
// // 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" ) // 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"` 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/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(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 } // 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(http.MethodGet, 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, nil } // 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"` 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"` 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/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(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/ee/api/group_level_variables.html#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"` 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/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(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 } // 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // GroupWikisService handles communication with the group wikis related methods of // the Gitlab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_wikis.html type GroupWikisService struct { client *Client } // GroupWiki represents a GitLab groups wiki. // // GitLab API docs: https://docs.gitlab.com/ee/api/group_wikis.html 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/ee/api/group_wikis.html#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/ee/api/group_wikis.html#list-wiki-pages func (s *GroupWikisService) ListGroupWikis(gid interface{}, 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/ee/api/group_wikis.html#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/ee/api/group_wikis.html#get-a-wiki-page func (s *GroupWikisService) GetGroupWikiPage(gid interface{}, 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/ee/api/group_wikis.html#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/ee/api/group_wikis.html#create-a-new-wiki-page func (s *GroupWikisService) CreateGroupWikiPage(gid interface{}, 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/ee/api/group_wikis.html#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/ee/api/group_wikis.html#edit-an-existing-wiki-page func (s *GroupWikisService) EditGroupWikiPage(gid interface{}, 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/ee/api/group_wikis.html#delete-a-wiki-page func (s *GroupWikisService) DeleteGroupWikiPage(gid interface{}, 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) }
// // 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" ) // GroupsService handles communication with the group related methods of // the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html type GroupsService struct { client *Client } // Group represents a GitLab group. // // GitLab API docs: https://docs.gitlab.com/ee/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"` DefaultBranchProtectionDefaults struct { AllowedToPush []*GroupAccessLevel `json:"allowed_to_push"` AllowForcePush bool `json:"allow_force_push"` AllowedToMerge []*GroupAccessLevel `json:"allowed_to_merge"` DeveloperCanInitialPush bool `json:"developer_can_initial_push"` } `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"` Projects []*Project `json:"projects"` 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"` SharedProjects []*Project `json:"shared_projects"` SharedRunnersSetting SharedRunnersSettingValue `json:"shared_runners_setting"` 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"` 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"` WikiAccessLevel AccessControlValue `json:"wiki_access_level"` // Deprecated: Use EmailsEnabled instead EmailsDisabled bool `json:"emails_disabled"` // Deprecated: Use DefaultBranchProtectionDefaults instead DefaultBranchProtection int `json:"default_branch_protection"` } // GroupAccessLevel represents default branch protection defaults access levels. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#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/ee/api/groups.html 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/ee/api/groups.html#ldap-group-links type LDAPGroupLink struct { CN string `json:"cn"` Filter string `json:"filter"` GroupAccess AccessLevelValue `json:"group_access"` Provider string `json:"provider"` } // SAMLGroupLink represents a GitLab SAML group link. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#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/ee/api/groups.html#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/ee/api/groups.html#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/ee/api/groups.html#list-a-groups-subgroups type ListSubGroupsOptions ListGroupsOptions // ListSubGroups gets a list of subgroups for a given group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#list-a-groups-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(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/ee/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/ee/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(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/ee/api/groups.html#list-a-groups-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/ee/api/groups.html#list-a-groups-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(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/ee/api/groups.html#details-of-a-group type GetGroupOptions struct { ListOptions WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"` WithProjects *bool `url:"with_projects,omitempty" json:"with_projects,omitempty"` } // GetGroup gets all details of a group. // // GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#details-of-a-group func (s *GroupsService) GetGroup(gid interface{}, 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/ee/api/groups.html#download-a-group-avatar func (s *GroupsService) DownloadAvatar(gid interface{}, 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/ee/api/groups.html#new-group type CreateGroupOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Path *string `url:"path,omitempty" json:"path,omitempty"` Avatar *GroupAvatar `url:"-" json:"-"` 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"` IPRestrictionRanges *string `url:"ip_restriction_ranges,omitempty" json:"ip_restriction_ranges,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/ee/api/groups.html#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/ee/api/groups.html#new-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/ee/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(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/ee/api/groups.html#transfer-a-group-to-a-new-parent-group--turn-a-subgroup-to-a-top-level-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/ee/api/groups.html#transfer-a-group-to-a-new-parent-group--turn-a-subgroup-to-a-top-level-group func (s *GroupsService) TransferSubGroup(gid interface{}, 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/ee/api/groups.html#update-group 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"` 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"` 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/ee/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)) 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/ee/api/groups.html#upload-a-group-avatar func (s *GroupsService) UploadAvatar(gid interface{}, 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/ee/api/groups.html#update-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/ee/api/groups.html#remove-group func (s *GroupsService) DeleteGroup(gid interface{}, 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/ee/api/groups.html#restore-group-marked-for-deletion func (s *GroupsService) RestoreGroup(gid interface{}, 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/ee/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(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/ee/api/groups.html#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/ee/api/groups.html#list-provisioned-users func (s *GroupsService) ListProvisionedUsers(gid interface{}, 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/ee/api/groups.html#list-ldap-group-links 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(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/ee/api/groups.html#add-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"` } // DeleteGroupLDAPLinkWithCNOrFilterOptions represents the available DeleteGroupLDAPLinkWithCNOrFilter() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#delete-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"` } // 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-with-cn-or-filter 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(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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteGroupLDAPLinkWithCNOrFilter 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-with-cn-or-filter func (s *GroupsService) DeleteGroupLDAPLinkWithCNOrFilter(gid interface{}, 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/ee/api/groups.html#delete-ldap-group-link 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(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/ee/api/groups.html#list-saml-group-links func (s *GroupsService) ListGroupSAMLLinks(gid interface{}, 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 } // GetGroupSAMLLink get a specific group SAML link. Available only for users who // can edit groups. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#get-saml-group-link func (s *GroupsService) GetGroupSAMLLink(gid interface{}, 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/ee/api/groups.html#add-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/ee/api/groups.html#add-saml-group-link func (s *GroupsService) AddGroupSAMLLink(gid interface{}, 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/ee/api/groups.html#delete-saml-group-link func (s *GroupsService) DeleteGroupSAMLLink(gid interface{}, 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/ee/api/groups.html#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"` } // ShareGroupWithGroup shares a group with another group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#create-a-link-to-share-a-group-with-another-group func (s *GroupsService) ShareGroupWithGroup(gid interface{}, 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/ee/api/groups.html#delete-link-sharing-group-with-another-group func (s *GroupsService) UnshareGroupFromGroup(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(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/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"` 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/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(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/ee/api/groups.html#add-group-push-rule 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/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(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/ee/api/groups.html#edit-group-push-rule 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/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(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/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // ImportService handles communication with the import // related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/import.html type ImportService struct { client *Client } // GitHubImport represents the response from an import from GitHub. // // GitLab API docs: // https://docs.gitlab.com/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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/ee/api/import.html#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 }
// // 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. // 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" ) // 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 } // InstanceCluster represents a GitLab Instance Cluster. // // GitLab API docs: https://docs.gitlab.com/ee/api/instance_clusters.html type InstanceCluster struct { ID int `json:"id"` Name string `json:"name"` Domain string `json:"domain"` Managed bool `json:"managed"` CreatedAt *time.Time `json:"created_at"` ProviderType string `json:"provider_type"` PlatformType string `json:"platform_type"` EnvironmentScope string `json:"environment_scope"` ClusterType string `json:"cluster_type"` User *User `json:"user"` PlatformKubernetes *PlatformKubernetes `json:"platform_kubernetes"` ManagementProject *ManagementProject `json:"management_project"` } func (v InstanceCluster) String() string { return Stringify(v) } // ListClusters gets a list of all instance clusters. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_clusters.html#list-instance-clusters func (s *InstanceClustersService) ListClusters(options ...RequestOptionFunc) ([]*InstanceCluster, *Response, error) { u := "admin/clusters" req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var ics []*InstanceCluster resp, err := s.client.Do(req, &ics) if err != nil { return nil, resp, err } return ics, resp, nil } // GetCluster gets an instance cluster. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_clusters.html#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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } ic := new(InstanceCluster) resp, err := s.client.Do(req, &ic) if err != nil { return nil, resp, err } return ic, resp, nil } // AddCluster adds an existing cluster to the instance. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_clusters.html#add-existing-instance-cluster func (s *InstanceClustersService) AddCluster(opt *AddClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) { u := "admin/clusters/add" req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } ic := new(InstanceCluster) resp, err := s.client.Do(req, ic) if err != nil { return nil, resp, err } return ic, resp, nil } // EditCluster updates an existing instance cluster. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_clusters.html#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(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } ic := new(InstanceCluster) resp, err := s.client.Do(req, ic) if err != nil { return nil, resp, err } return ic, resp, nil } // DeleteCluster deletes an existing instance cluster. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_clusters.html#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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // 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 } // InstanceVariable represents a GitLab instance level CI Variable. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_level_ci_variables.html 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 { return Stringify(v) } // ListInstanceVariablesOptions represents the available options for listing variables // for an instance. // // GitLab API docs: // https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#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 func (s *InstanceVariablesService) ListVariables(opt *ListInstanceVariablesOptions, options ...RequestOptionFunc) ([]*InstanceVariable, *Response, error) { u := "admin/ci/variables" req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } var vs []*InstanceVariable resp, err := s.client.Do(req, &vs) if err != nil { return nil, 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 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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } v := new(InstanceVariable) resp, err := s.client.Do(req, v) if err != nil { return nil, 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 type CreateInstanceVariableOptions 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"` 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 func (s *InstanceVariablesService) CreateVariable(opt *CreateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) { u := "admin/ci/variables" req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } v := new(InstanceVariable) resp, err := s.client.Do(req, v) if err != nil { return nil, 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 type UpdateInstanceVariableOptions struct { Value *string `url:"value,omitempty" json:"value,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 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(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } v := new(InstanceVariable) resp, err := s.client.Do(req, v) if err != nil { return nil, 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 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // InvitesService handles communication with the invitation related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/invitations.html type InvitesService struct { client *Client } // PendingInvite represents a pending invite. // // GitLab API docs: https://docs.gitlab.com/ee/api/invitations.html 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/ee/api/invitations.html#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/ee/api/invitations.html#list-all-invitations-pending-for-a-group-or-project func (s *InvitesService) ListPendingGroupInvitations(gid interface{}, 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/ee/api/invitations.html#list-all-invitations-pending-for-a-group-or-project func (s *InvitesService) ListPendingProjectInvitations(pid interface{}, 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/ee/api/invitations.html#add-a-member-to-a-group-or-project type InvitesOptions struct { ID interface{} `url:"id,omitempty" json:"id,omitempty"` Email *string `url:"email,omitempty" json:"email,omitempty"` UserID interface{} `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/ee/api/invitations.html#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/ee/api/invitations.html#add-a-member-to-a-group-or-project func (s *InvitesService) GroupInvites(gid interface{}, 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/ee/api/invitations.html#add-a-member-to-a-group-or-project func (s *InvitesService) ProjectInvites(pid interface{}, 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 }
// // 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" ) // 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"` LinkType string `json:"link_type"` } // IssueRelation gets a relation between two issues. // // GitLab API docs: // https://docs.gitlab.com/ee/api/issue_links.html#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/ee/api/issue_links.html#list-issue-relations func (s *IssueLinksService) ListIssueRelations(pid interface{}, 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/ee/api/issue_links.html#get-an-issue-link func (s *IssueLinksService) GetIssueLink(pid interface{}, 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/ee/api/issue_links.html#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/ee/api/issue_links.html#create-an-issue-link func (s *IssueLinksService) CreateIssueLink(pid interface{}, 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/ee/api/issue_links.html#delete-an-issue-link func (s *IssueLinksService) DeleteIssueLink(pid interface{}, 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 }
// // 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" "time" ) // IssuesService handles communication with the issue related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/api/issues.html 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"` 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"` 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"` } 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]interface{}) 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"].([]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 { 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)) } // 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/ee/api/issues.html#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/ee/api/issues.html#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/ee/api/issues.html#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 *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"` 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/ee/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(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/ee/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 *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"` 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/ee/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(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/ee/api/issues.html#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/ee/api/issues.html#single-project-issue 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(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/ee/api/issues.html#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/ee/api/issues.html#new-issue 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(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. // // 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 *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"` } // UpdateIssue 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#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(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/ee/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(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/ee/api/issues.html#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/ee/api/issues.html#reorder-an-issue func (s *IssuesService) ReorderIssue(pid interface{}, 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/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(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/ee/api/issues.html#subscribe-to-an-issue 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(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/ee/api/issues.html#unsubscribe-from-an-issue 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(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/ee/api/issues.html#create-a-to-do-item func (s *IssuesService) CreateTodo(pid interface{}, 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/ee/api/issues.html#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/ee/api/issues.html#list-merge-requests-that-close-a-particular-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(http.MethodGet, 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, nil } // ListMergeRequestsRelatedToIssueOptions represents the available // ListMergeRequestsRelatedToIssue() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(http.MethodGet, 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, nil } // SetTimeEstimate sets the time estimate for a single project issue. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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/ee/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/ee/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/ee/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/ee/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(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 }
// // 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" ) // 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 *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/ee/api/issues_statistics.html#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/ee/api/issues_statistics.html#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/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(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/ee/api/issues_statistics.html#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/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(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 }
// 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" ) // JobTokenScopeService handles communication with project CI settings // such as token permissions. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_job_token_scopes.html type JobTokenScopeService struct { client *Client } // JobTokenAccessSettings represents job token access attributes for this project. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_job_token_scopes.html type JobTokenAccessSettings struct { InboundEnabled bool `json:"inbound_enabled"` OutboundEnabled bool `json:"outbound_enabled"` } // GetProjectJobTokenAccessSettings fetch the CI/CD job token access settings (job token scope) of a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-access-settings func (j *JobTokenScopeService) GetProjectJobTokenAccessSettings(pid interface{}, 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/ee/api/project_job_token_scopes.html#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/ee/api/project_job_token_scopes.html#patch-a-projects-cicd-job-token-access-settings func (j *JobTokenScopeService) PatchProjectJobTokenAccessSettings(pid interface{}, 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/ee/api/project_job_token_scopes.html 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/ee/api/project_job_token_scopes.html#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/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-inbound-allowlist func (j *JobTokenScopeService) GetProjectJobTokenInboundAllowList(pid interface{}, 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/ee/api/project_job_token_scopes.html#create-a-new-project-to-a-projects-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/ee/api/project_job_token_scopes.html#create-a-new-project-to-a-projects-cicd-job-token-inbound-allowlist func (j *JobTokenScopeService) AddProjectToJobScopeAllowList(pid interface{}, 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/ee/api/project_job_token_scopes.html#remove-a-project-from-a-projects-cicd-job-token-inbound-allowlist func (j *JobTokenScopeService) RemoveProjectFromJobScopeAllowList(pid interface{}, 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/ee/api/project_job_token_scopes.html 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/ee/api/project_job_token_scopes.html#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/ee/api/project_job_token_scopes.html#get-a-projects-cicd-job-token-allowlist-of-groups func (j *JobTokenScopeService) GetJobTokenAllowlistGroups(pid interface{}, 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/ee/api/project_job_token_scopes.html#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/ee/api/project_job_token_scopes.html#add-a-group-to-a-cicd-job-token-allowlist func (j *JobTokenScopeService) AddGroupToJobTokenAllowlist(pid interface{}, 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/ee/api/project_job_token_scopes.html#remove-a-group-from-a-cicd-job-token-allowlist func (j *JobTokenScopeService) RemoveGroupFromJobTokenAllowlist(pid interface{}, 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) }
// // 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" ) // JobsService handles communication with the ci builds related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/jobs.html type JobsService struct { client *Client } // Job represents a ci build. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/api/jobs.html#list-pipeline-bridges 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/ee/api/jobs.html#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/ee/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(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/ee/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(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/ee/api/jobs.html#list-pipeline-jobs func (s *JobsService) ListPipelineBridges(pid interface{}, 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/ee/api/jobs.html#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/ee/api/jobs.html#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/ee/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(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/ee/api/job_artifacts.html#get-job-artifacts func (s *JobsService) GetJobArtifacts(pid interface{}, 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/ee/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/ee/api/job_artifacts.html#download-the-artifacts-archive func (s *JobsService) DownloadArtifactsFile(pid interface{}, 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/ee/api/job_artifacts.html#download-a-single-artifact-file-by-job-id func (s *JobsService) DownloadSingleArtifactsFile(pid interface{}, 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/ee/api/job_artifacts.html#download-a-single-artifact-file-from-specific-tag-or-branch func (s *JobsService) DownloadSingleArtifactsFileByTagOrBranch(pid interface{}, 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/ee/api/jobs.html#get-a-log-file func (s *JobsService) GetTraceFile(pid interface{}, 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/ee/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(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/ee/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(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/ee/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(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/ee/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(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/ee/api/jobs.html#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/ee/api/jobs.html#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/ee/api/jobs.html#run-a-job func (s *JobsService) PlayJob(pid interface{}, 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/ee/api/job_artifacts.html#delete-job-artifacts func (s *JobsService) DeleteArtifacts(pid interface{}, 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/ee/api/job_artifacts.html#delete-project-artifacts func (s *JobsService) DeleteProjectArtifacts(pid interface{}, 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) }
// // 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" ) // 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(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/ee/api/keys.html#get-user-by-fingerprint-of-ssh-key // https://docs.gitlab.com/ee/api/keys.html#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/ee/api/keys.html#get-user-by-fingerprint-of-ssh-key // https://docs.gitlab.com/ee/api/keys.html#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 }
// // 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" ) // LabelsService handles communication with the label related methods of the // GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/labels.html type LabelsService struct { client *Client } // Label represents a GitLab label. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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"` Search *string `url:"search,omitempty" json:"search,omitempty"` } // ListLabels gets all labels for given project. // // GitLab API docs: https://docs.gitlab.com/ee/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(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/ee/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), 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/ee/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"` 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/ee/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(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/ee/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 or ID. // // GitLab API docs: https://docs.gitlab.com/ee/api/labels.html#delete-a-label func (s *LabelsService) DeleteLabel(pid interface{}, lid 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)) 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/ee/api/labels.html#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/ee/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(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/ee/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), 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/ee/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), 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/ee/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), PathEscape(label)) req, err := s.client.NewRequest(http.MethodPut, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // 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 } // License represents a GitLab license. // // GitLab API docs: // https://docs.gitlab.com/ee/api/license.html type License struct { ID int `json:"id"` Plan string `json:"plan"` CreatedAt *time.Time `json:"created_at"` StartsAt *ISOTime `json:"starts_at"` ExpiresAt *ISOTime `json:"expires_at"` HistoricalMax int `json:"historical_max"` MaximumUserCount int `json:"maximum_user_count"` Expired bool `json:"expired"` Overage int `json:"overage"` UserLimit int `json:"user_limit"` ActiveUsers int `json:"active_users"` Licensee struct { Name string `json:"Name"` Company string `json:"Company"` Email string `json:"Email"` } `json:"licensee"` // Add on codes that may occur in legacy licenses that don't have a plan yet. // https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/models/license.rb AddOns struct { GitLabAuditorUser int `json:"GitLab_Auditor_User"` GitLabDeployBoard int `json:"GitLab_DeployBoard"` GitLabFileLocks int `json:"GitLab_FileLocks"` GitLabGeo int `json:"GitLab_Geo"` GitLabServiceDesk int `json:"GitLab_ServiceDesk"` } `json:"add_ons"` } func (l License) String() string { return Stringify(l) } // 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(options ...RequestOptionFunc) (*License, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "license", nil, options) if err != nil { return nil, nil, err } l := new(License) resp, err := s.client.Do(req, l) if err != nil { return nil, resp, err } return l, resp, nil } // AddLicenseOptions represents the available AddLicense() options. // // https://docs.gitlab.com/ee/api/license.html#add-a-new-license type AddLicenseOptions struct { License *string `url:"license" json:"license"` } // AddLicense adds a new license. // // GitLab API docs: // https://docs.gitlab.com/ee/api/license.html#add-a-new-license func (s *LicenseService) AddLicense(opt *AddLicenseOptions, options ...RequestOptionFunc) (*License, *Response, error) { req, err := s.client.NewRequest(http.MethodPost, "license", opt, options) if err != nil { return nil, nil, err } l := new(License) resp, err := s.client.Do(req, l) if err != nil { return nil, resp, err } return l, resp, nil } // DeleteLicense deletes an existing license. // // GitLab API docs: // https://docs.gitlab.com/ee/api/license.html#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) }
// // 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/ee/api/templates/licenses.html type LicenseTemplate struct { Key string `json:"key"` Name string `json:"name"` Nickname string `json:"nickname"` Featured bool `json:"featured"` 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"` } // LicenseTemplatesService handles communication with the license templates // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/templates/licenses.html type LicenseTemplatesService struct { client *Client } // ListLicenseTemplatesOptions represents the available // ListLicenseTemplates() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/licenses.html#list-license-templates type ListLicenseTemplatesOptions struct { ListOptions Popular *bool `url:"popular,omitempty" json:"popular,omitempty"` } // ListLicenseTemplates get all license templates. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/licenses.html#list-license-templates func (s *LicenseTemplatesService) ListLicenseTemplates(opt *ListLicenseTemplatesOptions, options ...RequestOptionFunc) ([]*LicenseTemplate, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "templates/licenses", opt, options) if err != nil { return nil, nil, err } var lts []*LicenseTemplate resp, err := s.client.Do(req, <s) if err != nil { return nil, resp, err } return lts, resp, nil } // GetLicenseTemplateOptions represents the available // GetLicenseTemplate() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/licenses.html#single-license-template type GetLicenseTemplateOptions struct { Project *string `url:"project,omitempty" json:"project,omitempty"` Fullname *string `url:"fullname,omitempty" json:"fullname,omitempty"` } // GetLicenseTemplate get a single license template. You can pass parameters // to replace the license placeholder. // // GitLab API docs: // https://docs.gitlab.com/ee/api/templates/licenses.html#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(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } lt := new(LicenseTemplate) resp, err := s.client.Do(req, lt) if err != nil { return nil, resp, err } return lt, resp, nil }
package gitlab import "net/http" // MarkdownService handles communication with the markdown related methods of // the GitLab API. // // Gitlab API docs: https://docs.gitlab.com/ee/api/markdown.html type MarkdownService struct { client *Client } // Markdown represents a markdown document. // // Gitlab API docs: https://docs.gitlab.com/ee/api/markdown.html type Markdown struct { HTML string `json:"html"` } // RenderOptions represents the available Render() options. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/markdown.html#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/ee/api/markdown.html#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 }
package gitlab import ( "fmt" "net/http" ) // MemberRolesService handles communication with the member roles related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html type MemberRolesService struct { client *Client } // MemberRole represents a GitLab member role. // // GitLab API docs: https://docs.gitlab.com/ee/api/member_roles.html 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"` AdminMergeRequests bool `json:"admin_merge_request,omitempty"` AdminTerraformState bool `json:"admin_terraform_state,omitempty"` AdminVulnerability bool `json:"admin_vulnerability,omitempty"` ReadCode bool `json:"read_code,omitempty"` ReadDependency bool `json:"read_dependency,omitempty"` ReadVulnerability bool `json:"read_vulnerability,omitempty"` AdminGroupMembers bool `json:"admin_group_member,omitempty"` ManageProjectAccessToken bool `json:"manage_project_access_tokens,omitempty"` ArchiveProject bool `json:"archive_project,omitempty"` RemoveProject bool `json:"remove_project,omitempty"` ManageGroupAccesToken bool `json:"manage_group_access_tokens,omitempty"` } // ListMemberRoles gets a list of member roles for a specified group. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/member_roles.html#list-all-member-roles-of-a-group func (s *MemberRolesService) ListMemberRoles(gid interface{}, 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 } // CreateMemberRoleOptions represents the available CreateMemberRole() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/member_roles.html#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"` AdminMergeRequest *bool `url:"admin_merge_request,omitempty" json:"admin_merge_request,omitempty"` AdminVulnerability *bool `url:"admin_vulnerability,omitempty" json:"admin_vulnerability,omitempty"` ReadCode *bool `url:"read_code,omitempty" json:"read_code,omitempty"` ReadDependency *bool `url:"read_dependency,omitempty" json:"read_dependency,omitempty"` ReadVulnerability *bool `url:"read_vulnerability,omitempty" json:"read_vulnerability,omitempty"` } // CreateMemberRole creates a new member role for a specified group. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/member_roles.html#add-a-member-role-to-a-group func (s *MemberRolesService) CreateMemberRole(gid interface{}, 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/ee/api/member_roles.html#remove-member-role-of-a-group func (s *MemberRolesService) DeleteMemberRole(gid interface{}, 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) }
// // 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" ) // 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"` 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/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"` 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/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(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/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(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/ee/api/merge_request_approvals.html#reset-approvals-of-a-merge-request func (s *MergeRequestApprovalsService) ResetApprovalsOfMergeRequest(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/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) } // ChangeMergeRequestApprovalConfigurationOptions represents the available // ChangeMergeRequestApprovalConfiguration() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration-deprecated 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(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 } // 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-deprecated 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(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 } // 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(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 } // 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(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/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(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/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(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/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(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/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" "time" ) // MergeRequestsService handles communication with the merge requests related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/merge_requests.html type MergeRequestsService struct { client *Client timeStats *timeStatsService } // MergeRequest represents a GitLab merge request. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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"` WorkInProgress bool `json:"work_in_progress"` Milestone *Milestone `json:"milestone"` MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"` DetailedMergeStatus string `json:"detailed_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"` AllowCollaboration bool `json:"allow_collaboration"` WebURL string `json:"web_url"` References *IssueReferences `json:"references"` DiscussionLocked bool `json:"discussion_locked"` Changes []*MergeRequestDiff `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"` FirstContribution bool `json:"first_contribution"` TaskCompletionStatus *TasksCompletionStatus `json:"task_completion_status"` HasConflicts bool `json:"has_conflicts"` BlockingDiscussionsResolved bool `json:"blocking_discussions_resolved"` Overflow bool `json:"overflow"` // Deprecated: This parameter is replaced by DetailedMergeStatus in GitLab 15.6. MergeStatus string `json:"merge_status"` } func (m MergeRequest) String() string { return Stringify(m) } func (m *MergeRequest) UnmarshalJSON(data []byte) error { type alias MergeRequest 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)(m)) } 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)(m)) } // MergeRequestDiff represents Gitlab merge request diff. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/merge_requests.html#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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#list-merge-requests func (s *MergeRequestsService) ListMergeRequests(opt *ListMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "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, nil } // ListProjectMergeRequestsOptions represents the available ListMergeRequests() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/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 *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/ee/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(http.MethodGet, 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, nil } // ListGroupMergeRequestsOptions represents the available ListGroupMergeRequests() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/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 *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/ee/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(http.MethodGet, 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, nil } // GetMergeRequestsOptions represents the available GetMergeRequests() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(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/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(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/ee/api/merge_requests.html#get-single-merge-request-commits type GetMergeRequestCommitsOptions ListOptions // GetMergeRequestCommits gets a list of merge request commits. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-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(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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_requests.html#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/ee/api/merge_requests.html#get-single-merge-request-changes func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, 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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#list-merge-request-diffs func (s *MergeRequestsService) ListMergeRequestDiffs(pid interface{}, 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 } // GetMergeRequestParticipants gets a list of merge request participants. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_requests.html#get-single-merge-request-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(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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#get-single-merge-request-reviewers func (s *MergeRequestsService) GetMergeRequestReviewers(pid interface{}, 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/ee/api/merge_requests.html#list-merge-request-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(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/ee/api/merge_requests.html#create-merge-request-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(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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#list-issues-that-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(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/ee/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 *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"` 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/ee/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(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/ee/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"` 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/ee/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(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/ee/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(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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#merge-a-merge-request 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(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/ee/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(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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#rebase-a-merge-request func (s *MergeRequestsService) RebaseMergeRequest(pid interface{}, 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/ee/api/merge_requests.html#get-merge-request-diff-versions type GetMergeRequestDiffVersionsOptions ListOptions // GetMergeRequestDiffVersions get a list of merge request diff versions. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_requests.html#get-merge-request-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(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/ee/api/merge_requests.html#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/ee/api/merge_requests.html#get-a-single-merge-request-diff-version func (s *MergeRequestsService) GetSingleMergeRequestDiffVersion(pid interface{}, 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/ee/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(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/ee/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(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/ee/api/merge_requests.html#create-a-to-do-item 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(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/ee/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/ee/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/ee/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/ee/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/ee/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...) }
package gitlab import ( "fmt" "net/http" "time" ) // MergeTrainsService handles communication with the merge trains related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/merge_trains.html type MergeTrainsService struct { client *Client } // MergeTrain represents a Gitlab merge train. // // GitLab API docs: https://docs.gitlab.com/ee/api/merge_trains.html 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/ee/api/merge_trains.html 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/ee/api/merge_trains.html#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/ee/api/merge_trains.html#list-merge-trains-for-a-project func (s *MergeTrainsService) ListProjectMergeTrains(pid interface{}, 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/ee/api/merge_trains.html#list-merge-requests-in-a-merge-train func (s *MergeTrainsService) ListMergeRequestInMergeTrain(pid interface{}, 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/ee/api/merge_trains.html#get-the-status-of-a-merge-request-on-a-merge-train func (s *MergeTrainsService) GetMergeRequestOnAMergeTrain(pid interface{}, 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/ee/api/merge_trains.html#add-a-merge-request-to-a-merge-train type AddMergeRequestToMergeTrainOptions struct { WhenPipelineSucceeds *bool `url:"when_pipeline_succeeds,omitempty" json:"when_pipeline_succeeds,omitempty"` SHA *string `url:"sha,omitempty" json:"sha,omitempty"` Squash *bool `url:"squash,omitempty" json:"squash,omitempty"` } // AddMergeRequestToMergeTrain Add a merge request to the merge train targeting // the merge request’s target branch. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_trains.html#add-a-merge-request-to-a-merge-train func (s *MergeTrainsService) AddMergeRequestToMergeTrain(pid interface{}, 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 }
// // Copyright 2022, Timo Furrer <tuxtimo@gmail.com> // // 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" // MetadataService handles communication with the GitLab server instance to // retrieve its metadata information via the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/metadata.html type MetadataService struct { client *Client } // Metadata represents a GitLab instance version. // // GitLab API docs: https://docs.gitlab.com/ee/api/metadata.html type Metadata struct { Version string `json:"version"` Revision string `json:"revision"` KAS struct { Enabled bool `json:"enabled"` ExternalURL string `json:"externalUrl"` 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/ee/api/metadata.html 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 }
// // 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" ) // MilestonesService handles communication with the milestone related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/milestones.html type MilestonesService struct { client *Client } // Milestone represents a GitLab milestone. // // GitLab API docs: https://docs.gitlab.com/ee/api/milestones.html 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/ee/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"` 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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(http.MethodGet, 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, nil }
// // 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" ) // NamespacesService handles communication with the namespace related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/namespaces.html type NamespacesService struct { client *Client } // Namespace represents a GitLab namespace. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/api/namespaces.html#list-namespaces type ListNamespacesOptions struct { ListOptions Search *string `url:"search,omitempty" json:"search,omitempty"` OwnedOnly *bool `url:"owned_only,omitempty" json:"owned_only,omitempty"` } // ListNamespaces gets a list of projects accessible by the authenticated user. // // GitLab API docs: https://docs.gitlab.com/ee/api/namespaces.html#list-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/ee/api/namespaces.html#list-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/ee/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", 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/ee/api/namespaces.html#get-existence-of-a-namespace type NamespaceExistance struct { Exists bool `json:"exists"` Suggests []string `json:"suggests"` } // NamespaceExistsOptions represents the available NamespaceExists() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/namespaces.html#get-existence-of-a-namespace 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/ee/api/namespaces.html#get-existence-of-a-namespace func (s *NamespacesService) NamespaceExists(id interface{}, 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 }
// // 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" ) // NotesService handles communication with the notes related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/notes.html type NotesService struct { client *Client } // Note represents a GitLab note. // // GitLab API docs: https://docs.gitlab.com/ee/api/notes.html 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 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"` 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"` Confidential bool `json:"confidential"` Internal bool `json:"internal"` } // 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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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/ee/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(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/ee/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(http.MethodDelete, 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(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. // // 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(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. // // 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(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. // // 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(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. // // 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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // NotificationSettingsService handles communication with the notification settings // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/notification_settings.html type NotificationSettingsService struct { client *Client } // NotificationSettings represents the Gitlab notification setting. // // GitLab API docs: // https://docs.gitlab.com/ee/api/notification_settings.html#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/ee/api/notification_settings.html#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/ee/api/notification_settings.html#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/ee/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(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/ee/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(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/ee/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(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/ee/api/notification_settings.html#update-groupproject-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(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/ee/api/notification_settings.html#update-groupproject-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(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 }
// // 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" ) // PackagesService handles communication with the packages related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/packages.html type PackagesService struct { client *Client } // Package represents a GitLab package. // // GitLab API docs: https://docs.gitlab.com/ee/api/packages.html 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/ee/api/packages.html 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/ee/api/packages.html 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/ee/api/packages.html#within-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/ee/api/packages.html#within-a-project func (s *PackagesService) ListProjectPackages(pid interface{}, 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/ee/api/packages.html#within-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/ee/api/packages.html#within-a-group func (s *PackagesService) ListGroupPackages(gid interface{}, 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/ee/api/packages.html#list-package-files type ListPackageFilesOptions ListOptions // ListPackageFiles gets a list of files that are within a package // // GitLab API docs: // https://docs.gitlab.com/ee/api/packages.html#list-package-files func (s *PackagesService) ListPackageFiles(pid interface{}, 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/ee/api/packages.html#delete-a-project-package func (s *PackagesService) DeleteProjectPackage(pid interface{}, 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/ee/api/packages.html#delete-a-package-file func (s *PackagesService) DeletePackageFile(pid interface{}, 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) }
// // 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 PagesService struct { client *Client } // UnpublishPages unpublished pages. The user must have admin privileges. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pages.html#unpublish-pages func (s *PagesService) UnpublishPages(gid interface{}, 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) }
// // 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" ) // PagesDomainsService handles communication with the pages domains // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/pages_domains.html type PagesDomainsService struct { client *Client } // PagesDomain represents a pages domain. // // GitLab API docs: https://docs.gitlab.com/ee/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 { 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/ee/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/ee/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(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/ee/api/pages_domains.html#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/ee/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(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/ee/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:"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/ee/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(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/ee/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:"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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // Copyright 2022, Ryan Glab <ryan.j.glab@gmail.com> // // 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" ) // PersonalAccessTokensService handles communication with the personal access // tokens related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/personal_access_tokens.html type PersonalAccessTokensService struct { client *Client } // PersonalAccessToken represents a personal access token. // // GitLab API docs: https://docs.gitlab.com/ee/api/personal_access_tokens.html type PersonalAccessToken struct { ID int `json:"id"` Name string `json:"name"` Revoked bool `json:"revoked"` CreatedAt *time.Time `json:"created_at"` 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"` } func (p PersonalAccessToken) String() string { return Stringify(p) } // ListPersonalAccessTokensOptions represents the available // ListPersonalAccessTokens() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/personal_access_tokens.html#list-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/ee/api/personal_access_tokens.html#list-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/ee/api/personal_access_tokens.html#using-a-personal-access-token-id 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/ee/api/personal_access_tokens.html#using-a-request-header 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/ee/api/personal_access_tokens.html#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/ee/api/personal_access_tokens.html#use-a-personal-access-token-id 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/ee/api/personal_access_tokens.html#use-a-request-header 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/ee/api/personal_access_tokens.html#using-a-personal-access-token-id-1 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/ee/api/personal_access_tokens.html#using-a-request-header-1 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) }
// // 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" ) // PipelineSchedulesService handles communication with the pipeline // schedules related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/pipeline_schedules.html type PipelineSchedulesService struct { client *Client } // PipelineSchedule represents a pipeline schedule. // // GitLab API docs: // https://docs.gitlab.com/ee/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 *LastPipeline `json:"last_pipeline"` Variables []*PipelineVariable `json:"variables"` } // 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/ee/api/pipeline_schedules.html#get-all-pipeline-schedules type ListPipelineSchedulesOptions ListOptions // ListPipelineSchedules gets a list of project triggers. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pipeline_schedules.html#get-all-pipeline-schedules 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(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/ee/api/pipeline_schedules.html#get-a-single-pipeline-schedule 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(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/ee/api/pipeline_schedules.html#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/ee/api/pipeline_schedules.html#get-all-pipelines-triggered-by-a-pipeline-schedule func (s *PipelineSchedulesService) ListPipelinesTriggeredBySchedule(pid interface{}, 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/ee/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/ee/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(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/ee/api/pipeline_schedules.html#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"` } // EditPipelineSchedule edits a pipeline schedule. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(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/ee/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(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/ee/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(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/ee/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 *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` } // CreatePipelineScheduleVariable creates a pipeline schedule variable. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/api/pipeline_schedules.html#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/ee/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(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/ee/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(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 }
// // 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" ) // PipelineTriggersService handles Project pipeline triggers. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pipeline_triggers.html type PipelineTriggersService struct { client *Client } // PipelineTrigger represents a project pipeline trigger. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pipeline_triggers.html 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/ee/api/pipeline_triggers.html#list-project-trigger-tokens type ListPipelineTriggersOptions ListOptions // ListPipelineTriggers gets a list of project triggers. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pipeline_triggers.html#list-project-trigger-tokens 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(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/ee/api/pipeline_triggers.html#get-trigger-token-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(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/ee/api/pipeline_triggers.html#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/ee/api/pipeline_triggers.html#create-a-trigger-token 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(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/ee/api/pipeline_triggers.html#update-a-project-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/ee/api/pipeline_triggers.html#update-a-project-trigger-token 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(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 } // TakeOwnershipOfPipelineTrigger sets the owner of the specified // pipeline trigger to the user issuing the request. // // GitLab API docs: // https://docs.gitlab.com/ee/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(http.MethodPost, 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 } // DeletePipelineTrigger removes a trigger from a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/pipeline_triggers.html#remove-a-project-trigger-token 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(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/ee/api/pipeline_triggers.html#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/ee/api/pipeline_triggers.html#trigger-a-pipeline-with-a-token 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(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 }
// // 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" ) // PipelinesService handles communication with the repositories related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/pipelines.html type PipelinesService struct { client *Client } // PipelineVariable represents a pipeline variable. // // GitLab API docs: https://docs.gitlab.com/ee/api/pipelines.html type PipelineVariable struct { Key string `json:"key"` Value string `json:"value"` VariableType VariableTypeValue `json:"variable_type"` } // Pipeline represents a GitLab pipeline. // // GitLab API docs: https://docs.gitlab.com/ee/api/pipelines.html type Pipeline 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"` 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 interface{} `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"` 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/ee/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"` 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/ee/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(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/ee/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(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/ee/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(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/ee/api/pipelines.html#get-a-pipelines-test-report func (s *PipelinesService) GetPipelineTestReport(pid interface{}, 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/ee/api/pipelines.html#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/ee/api/pipelines.html#get-the-latest-pipeline func (s *PipelinesService) GetLatestPipeline(pid interface{}, 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/ee/api/pipelines.html#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/ee/api/pipelines.html#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/ee/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(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/ee/api/pipelines.html#retry-jobs-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(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/ee/api/pipelines.html#cancel-a-pipelines-jobs 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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" // PlanLimitsService handles communication with the repositories related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/plan_limits.html type PlanLimitsService struct { client *Client } // PlanLimit represents a GitLab pipeline. // // GitLab API docs: https://docs.gitlab.com/ee/api/plan_limits.html 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/ee/api/plan_limits.html#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/ee/api/plan_limits.html#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/ee/api/plan_limits.html#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/ee/api/plan_limits.html#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 }
// // 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" ) // ProjectAccessTokensService handles communication with the // project access tokens related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_access_tokens.html type ProjectAccessTokensService struct { client *Client } // ProjectAccessToken represents a GitLab project access token. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_access_tokens.html type ProjectAccessToken struct { ID int `json:"id"` UserID int `json:"user_id"` Name string `json:"name"` Scopes []string `json:"scopes"` CreatedAt *time.Time `json:"created_at"` LastUsedAt *time.Time `json:"last_used_at"` ExpiresAt *ISOTime `json:"expires_at"` Active bool `json:"active"` Revoked bool `json:"revoked"` Token string `json:"token"` AccessLevel AccessLevelValue `json:"access_level"` } func (v ProjectAccessToken) String() string { return Stringify(v) } // ListProjectAccessTokensOptions represents the available // ListProjectAccessTokens() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_access_tokens.html#list-project-access-tokens type ListProjectAccessTokensOptions ListOptions // ListProjectAccessTokens gets a list of all project access tokens in a // project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_access_tokens.html#list-project-access-tokens func (s *ProjectAccessTokensService) ListProjectAccessTokens(pid interface{}, 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/ee/api/project_access_tokens.html#get-a-project-access-token func (s *ProjectAccessTokensService) GetProjectAccessToken(pid interface{}, 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/ee/api/project_access_tokens.html#create-a-project-access-token type CreateProjectAccessTokenOptions struct { Name *string `url:"name,omitempty" json:"name,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/ee/api/project_access_tokens.html#create-a-project-access-token func (s *ProjectAccessTokensService) CreateProjectAccessToken(pid interface{}, 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/ee/api/project_access_tokens.html#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/ee/api/project_access_tokens.html#rotate-a-project-access-token func (s *ProjectAccessTokensService) RotateProjectAccessToken(pid interface{}, 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 } // RevokeProjectAccessToken revokes a project access token. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_access_tokens.html#revoke-a-project-access-token func (s *ProjectAccessTokensService) RevokeProjectAccessToken(pid interface{}, 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) }
// // 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" ) // 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"` 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"` } // 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 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/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(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/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(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/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"` Name *string `url:"name,omitempty" json:"name,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(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/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"` Name *string `url:"name,omitempty" json:"name,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(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/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(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/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(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 }
// // 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. // 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" ) // 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 } // ProjectCluster represents a GitLab Project Cluster. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_clusters.html type ProjectCluster struct { ID int `json:"id"` Name string `json:"name"` Domain string `json:"domain"` CreatedAt *time.Time `json:"created_at"` ProviderType string `json:"provider_type"` PlatformType string `json:"platform_type"` EnvironmentScope string `json:"environment_scope"` ClusterType string `json:"cluster_type"` User *User `json:"user"` PlatformKubernetes *PlatformKubernetes `json:"platform_kubernetes"` ManagementProject *ManagementProject `json:"management_project"` Project *Project `json:"project"` } func (v ProjectCluster) String() string { return Stringify(v) } // PlatformKubernetes represents a GitLab Project Cluster PlatformKubernetes. type PlatformKubernetes struct { APIURL string `json:"api_url"` Token string `json:"token"` CaCert string `json:"ca_cert"` Namespace string `json:"namespace"` AuthorizationType string `json:"authorization_type"` } // ManagementProject represents a GitLab Project Cluster management_project. type ManagementProject 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"` } // ListClusters gets a list of all clusters in a project. // // 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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/clusters", PathEscape(project)) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var pcs []*ProjectCluster resp, err := s.client.Do(req, &pcs) if err != nil { return nil, resp, err } return pcs, resp, nil } // GetCluster gets a cluster. // // 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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } pc := new(ProjectCluster) resp, err := s.client.Do(req, &pc) if err != nil { return nil, resp, err } return pc, resp, nil } // AddClusterOptions represents the available AddCluster() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_clusters.html#add-existing-cluster-to-project type AddClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"` Managed *bool `url:"managed,omitempty" json:"managed,omitempty"` EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` PlatformKubernetes *AddPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"` ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"` } // AddPlatformKubernetesOptions represents the available PlatformKubernetes options for adding. type AddPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"` Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` AuthorizationType *string `url:"authorization_type,omitempty" json:"authorization_type,omitempty"` } // AddCluster adds an existing cluster to the project. // // 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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/clusters/user", PathEscape(project)) req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } pc := new(ProjectCluster) resp, err := s.client.Do(req, pc) if err != nil { return nil, resp, err } return pc, resp, nil } // EditClusterOptions represents the available EditCluster() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_clusters.html#edit-project-cluster type EditClusterOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` Domain *string `url:"domain,omitempty" json:"domain,omitempty"` EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"` ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"` PlatformKubernetes *EditPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"` } // EditPlatformKubernetesOptions represents the available PlatformKubernetes options for editing. type EditPlatformKubernetesOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"` Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"` } // EditCluster updates an existing project cluster. // // 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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, nil, err } pc := new(ProjectCluster) resp, err := s.client.Do(req, pc) if err != nil { return nil, resp, err } return pc, resp, nil } // DeleteCluster deletes an existing project cluster. // // 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) { project, err := parseID(pid) if err != nil { return nil, err } u := fmt.Sprintf("projects/%s/clusters/%d", PathEscape(project), cluster) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
package gitlab import ( "fmt" "net/http" "time" ) // ProjectFeatureFlagService handles operations on gitlab project feature // flags using the following api: // // GitLab API docs: https://docs.gitlab.com/ee/api/feature_flags.html type ProjectFeatureFlagService struct { client *Client } // ProjectFeatureFlag represents a GitLab project iteration. // // GitLab API docs: https://docs.gitlab.com/ee/api/feature_flags.html 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/ee/api/feature_flags.html 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/ee/api/feature_flags.html 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/ee/api/feature_flags.html 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/ee/api/feature_flags.html#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/ee/api/feature_flags.html#list-feature-flags-for-a-project func (s *ProjectFeatureFlagService) ListProjectFeatureFlags(pid interface{}, 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/ee/api/feature_flags.html#get-a-single-feature-flag func (s *ProjectFeatureFlagService) GetProjectFeatureFlag(pid interface{}, 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/ee/api/feature_flags.html#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/ee/api/feature_flags.html#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/ee/api/feature_flags.html#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/ee/api/feature_flags.html#create-a-feature-flag func (s *ProjectFeatureFlagService) CreateProjectFeatureFlag(pid interface{}, 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/ee/api/feature_flags.html#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/ee/api/feature_flags.html#update-a-feature-flag func (s *ProjectFeatureFlagService) UpdateProjectFeatureFlag(pid interface{}, 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/ee/api/feature_flags.html#delete-a-feature-flag func (s *ProjectFeatureFlagService) DeleteProjectFeatureFlag(pid interface{}, 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) }
// // 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" ) // ProjectImportExportService handles communication with the project // import/export related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_import_export.html type ProjectImportExportService struct { client *Client } // ImportStatus represents a project import status. // // GitLab API docs: // https://docs.gitlab.com/ee/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"` 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/ee/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/ee/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/ee/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(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/ee/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(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/ee/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(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/ee/api/project_import_export.html#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/ee/api/project_import_export.html#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/ee/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(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 }
// // 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" ) // IterationsAPI handles communication with the project iterations related // methods of the GitLab API // // GitLab API docs: https://docs.gitlab.com/ee/api/iterations.html type ProjectIterationsService struct { client *Client } // ProjectIteration represents a GitLab project iteration. // // GitLab API docs: https://docs.gitlab.com/ee/api/iterations.html 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/ee/api/iterations.html#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/ee/api/iterations.html#list-project-iterations func (i *ProjectIterationsService) ListProjectIterations(pid interface{}, 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 }
// // Copyright 2021, Andrea Perizzato // // 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" ) // ManagedLicensesService handles communication with the managed licenses // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/managed_licenses.html type ManagedLicensesService struct { client *Client } // ManagedLicense represents a managed license. // // GitLab API docs: https://docs.gitlab.com/ee/api/managed_licenses.html type ManagedLicense struct { ID int `json:"id"` Name string `json:"name"` ApprovalStatus LicenseApprovalStatusValue `json:"approval_status"` } // ListManagedLicenses returns a list of managed licenses from a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#list-managed-licenses func (s *ManagedLicensesService) ListManagedLicenses(pid interface{}, options ...RequestOptionFunc) ([]*ManagedLicense, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/managed_licenses", PathEscape(project)) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } var mls []*ManagedLicense resp, err := s.client.Do(req, &mls) if err != nil { return nil, resp, err } return mls, resp, nil } // GetManagedLicense returns an existing managed license. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#show-an-existing-managed-license func (s *ManagedLicensesService) GetManagedLicense(pid, mlid interface{}, options ...RequestOptionFunc) (*ManagedLicense, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } license, err := parseID(mlid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/managed_licenses/%s", PathEscape(project), PathEscape(license)) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } ml := new(ManagedLicense) resp, err := s.client.Do(req, ml) if err != nil { return nil, resp, err } return ml, resp, nil } // AddManagedLicenseOptions represents the available AddManagedLicense() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#create-a-new-managed-license type AddManagedLicenseOptions struct { Name *string `url:"name,omitempty" json:"name,omitempty"` ApprovalStatus *LicenseApprovalStatusValue `url:"approval_status,omitempty" json:"approval_status,omitempty"` } // AddManagedLicense adds a managed license to a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#create-a-new-managed-license func (s *ManagedLicensesService) AddManagedLicense(pid interface{}, opt *AddManagedLicenseOptions, options ...RequestOptionFunc) (*ManagedLicense, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/managed_licenses", PathEscape(project)) req, err := s.client.NewRequest(http.MethodPost, u, opt, options) if err != nil { return nil, nil, err } ml := new(ManagedLicense) resp, err := s.client.Do(req, ml) if err != nil { return nil, resp, err } return ml, resp, nil } // DeleteManagedLicense deletes a managed license with a given ID. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#delete-a-managed-license func (s *ManagedLicensesService) DeleteManagedLicense(pid, mlid interface{}, options ...RequestOptionFunc) (*Response, error) { project, err := parseID(pid) if err != nil { return nil, err } license, err := parseID(mlid) if err != nil { return nil, err } u := fmt.Sprintf("projects/%s/managed_licenses/%s", PathEscape(project), PathEscape(license)) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // EditManagedLicenceOptions represents the available EditManagedLicense() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#edit-an-existing-managed-license type EditManagedLicenceOptions struct { ApprovalStatus *LicenseApprovalStatusValue `url:"approval_status,omitempty" json:"approval_status,omitempty"` } // EditManagedLicense updates an existing managed license with a new approval // status. // // GitLab API docs: // https://docs.gitlab.com/ee/api/managed_licenses.html#edit-an-existing-managed-license func (s *ManagedLicensesService) EditManagedLicense(pid, mlid interface{}, opt *EditManagedLicenceOptions, options ...RequestOptionFunc) (*ManagedLicense, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } license, err := parseID(mlid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/managed_licenses/%s", PathEscape(project), PathEscape(license)) req, err := s.client.NewRequest(http.MethodPatch, u, opt, options) if err != nil { return nil, nil, err } ml := new(ManagedLicense) resp, err := s.client.Do(req, ml) if err != nil { return nil, resp, err } return ml, resp, nil }
// // 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" ) // ProjectMembersService handles communication with the project members // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/members.html type ProjectMembersService struct { client *Client } // ListProjectMembersOptions represents the available ListProjectMembers() and // ListAllProjectMembers() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/members.html#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/ee/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(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/ee/api/members.html#list-all-members-of-a-group-or-project-including-inherited-and-invited-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(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/ee/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(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/ee/api/members.html#get-a-member-of-a-group-or-project-including-inherited-and-invited-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(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/ee/api/members.html#add-a-member-to-a-group-or-project type AddProjectMemberOptions struct { UserID interface{} `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"` 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/ee/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(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/ee/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,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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // ProjectMirrorService handles communication with the project mirror // related methods of the GitLab API. // // GitLAb API docs: https://docs.gitlab.com/ee/api/remote_mirrors.html type ProjectMirrorService struct { client *Client } // ProjectMirror represents a project mirror configuration. // // GitLAb API docs: https://docs.gitlab.com/ee/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"` 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"` } // 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/ee/api/remote_mirrors.html#list-a-projects-remote-mirrors func (s *ProjectMirrorService) ListProjectMirror(pid interface{}, 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/ee/api/remote_mirrors.html#get-a-single-projects-remote-mirror func (s *ProjectMirrorService) GetProjectMirror(pid interface{}, 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 } // AddProjectMirrorOptions contains the properties requires to create // a new project mirror. // // GitLab API docs: // https://docs.gitlab.com/ee/api/remote_mirrors.html#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"` } // AddProjectMirror creates a new mirror on the project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/remote_mirrors.html#create-a-push-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(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/ee/api/remote_mirrors.html#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"` } // EditProjectMirror updates a project team member to a specified access level.. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/api/remote_mirrors.html#delete-a-remote-mirror func (s *ProjectMirrorService) DeleteProjectMirror(pid interface{}, 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) }
// // 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" ) // ProjectRepositoryStorageMoveService handles communication with the // repositories related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html type ProjectRepositoryStorageMoveService struct { client *Client } // ProjectRepositoryStorageMove represents the status of a repository move. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html 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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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/ee/api/project_repository_storage_moves.html#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) }
// // 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" ) // ProjectSnippetsService handles communication with the project snippets // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_snippets.html type ProjectSnippetsService struct { client *Client } // ListProjectSnippetsOptions represents the available ListSnippets() options. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_snippets.html#list-snippets type ListProjectSnippetsOptions ListOptions // ListSnippets gets a list of project snippets. // // GitLab API docs: https://docs.gitlab.com/ee/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(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/ee/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(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/ee/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"` Files *[]*CreateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` } // CreateSnippet creates a new project snippet. The user must have permission // to create new snippets. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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"` Files *[]*UpdateSnippetFileOptions `url:"files,omitempty" json:"files,omitempty"` } // UpdateSnippet updates an existing project snippet. The user must have // permission to change an existing snippet. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(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/ee/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(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 }
// // 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" ) // ProjectTemplatesService handles communication with the project templates // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_templates.html type ProjectTemplatesService struct { client *Client } // ProjectTemplate represents a GitLab ProjectTemplate. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_templates.html 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/ee/api/project_templates.html#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/ee/api/project_templates.html#get-all-templates-of-a-particular-type func (s *ProjectTemplatesService) ListTemplates(pid interface{}, 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/ee/api/project_templates.html#get-one-template-of-a-particular-type func (s *ProjectTemplatesService) GetProjectTemplate(pid interface{}, 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 }
// // 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" ) // 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"` 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/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(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/ee/api/project_level_variables.html#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/ee/api/project_level_variables.html#get-a-single-variable func (s *ProjectVariablesService) GetVariable(pid interface{}, 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/ee/api/project_level_variables.html#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"` 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/ee/api/project_level_variables.html#create-a-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(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/ee/api/project_level_variables.html#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/ee/api/project_level_variables.html#update-a-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(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/ee/api/project_level_variables.html#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/ee/api/project_level_variables.html#delete-a-variable func (s *ProjectVariablesService) RemoveVariable(pid interface{}, 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) }
// // 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" ) // ProjectVulnerabilitiesService handles communication with the projects // vulnerabilities related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_vulnerabilities.html type ProjectVulnerabilitiesService struct { client *Client } // Project represents a GitLab project vulnerability. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_vulnerabilities.html 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. // // GitLab API docs: https://docs.gitlab.com/ee/api/project_vulnerabilities.html 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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_vulnerabilities.html#list-project-vulnerabilities type ListProjectVulnerabilitiesOptions struct { ListOptions } // ListProjectVulnerabilities gets a list of all project vulnerabilities. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_vulnerabilities.html#list-project-vulnerabilities func (s *ProjectVulnerabilitiesService) ListProjectVulnerabilities(pid interface{}, 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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_vulnerabilities.html#new-vulnerability type CreateVulnerabilityOptions struct { FindingID *int `url:"finding_id,omitempty" json:"finding_id,omitempty"` } // CreateVulnerability creates a new vulnerability on the selected project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/project_vulnerabilities.html#new-vulnerability func (s *ProjectVulnerabilitiesService) CreateVulnerability(pid interface{}, 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 }
// // 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" "time" "github.com/hashicorp/go-retryablehttp" ) // ProjectsService handles communication with the repositories related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html type ProjectsService struct { client *Client } // Project represents a GitLab project. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html 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"` TagList []string `json:"tag_list"` 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"` 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"` ContainerExpirationPolicy *ContainerExpirationPolicy `json:"container_expiration_policy,omitempty"` ContainerRegistryEnabled bool `json:"container_registry_enabled"` ContainerRegistryAccessLevel AccessControlValue `json:"container_registry_access_level"` ContainerRegistryImagePrefix string `json:"container_registry_image_prefix,omitempty"` CreatedAt *time.Time `json:"created_at,omitempty"` LastActivityAt *time.Time `json:"last_activity_at,omitempty"` CreatorID int `json:"creator_id"` Namespace *ProjectNamespace `json:"namespace"` Permissions *Permissions `json:"permissions"` MarkedForDeletionAt *ISOTime `json:"marked_for_deletion_at"` 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"` 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"` CIForwardDeploymentEnabled bool `json:"ci_forward_deployment_enabled"` CIForwardDeploymentRollbackAllowed bool `json:"ci_forward_deployment_rollback_allowed"` 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"` RestrictUserDefinedVariables bool `json:"restrict_user_defined_variables"` 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"` // 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"` NameRegex string `json:"name_regex"` NameRegexDelete string `json:"name_regex_delete"` NameRegexKeep string `json:"name_regex_keep"` Enabled bool `json:"enabled"` NextRunAt *time.Time `json:"next_run_at"` } // 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/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"` 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/ee/api/projects.html#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/ee/api/projects.html#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/ee/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(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/ee/api/projects.html#list-projects-a-user-has-contributed-to func (s *ProjectsService) ListUserContributedProjects(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/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/ee/api/projects.html#list-projects-starred-by-a-user func (s *ProjectsService) ListUserStarredProjects(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/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/ee/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/ee/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(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. 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/ee/api/projects.html#list-a-projects-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/ee/api/projects.html#list-a-projects-groups func (s *ProjectsService) ListProjectsGroups(pid interface{}, 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/ee/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/ee/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(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/ee/api/projects.html#get-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/ee/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(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/ee/api/projects.html#create-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"` ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,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"` PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,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"` PreReceiveSecretDetectionEnabled *bool `url:"pre_receive_secret_detection_enabled,omitempty" json:"pre_receive_secret_detection_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"` 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: 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/ee/api/projects.html#create-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/ee/api/projects.html#create-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/ee/api/projects.html#create-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/ee/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/ee/api/projects.html#create-project-for-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/ee/api/projects.html#edit-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"` ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,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"` 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"` 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"` 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"` PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,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"` RestrictUserDefinedVariables *bool `url:"restrict_user_defined_variables,omitempty" json:"restrict_user_defined_variables,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 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/ee/api/projects.html#edit-project func (s *ProjectsService) EditProject(pid interface{}, 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/ee/api/projects.html#fork-project type ForkProjectOptions struct { 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/ee/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(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/ee/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(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 } // UnstarProject unstars a given project. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(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/ee/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(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 } // DeleteProject removes a project including all associated resources // (issues, merge requests etc.) // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#delete-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(http.MethodDelete, 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/ee/api/projects.html#share-project-with-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/ee/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(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/ee/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(http.MethodDelete, 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/ee/api/members.html#list-all-members-of-a-group-or-project 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"` } // 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/ee/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"` DeploymentEvents bool `json:"deployment_events"` ReleasesEvents bool `json:"releases_events"` EnableSSLVerification bool `json:"enable_ssl_verification"` 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/ee/api/projects.html#list-project-hooks type ListProjectHooksOptions ListOptions // ListProjectHooks gets a list of project hooks. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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(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/ee/api/projects.html#add-project-hook type AddProjectHookOptions struct { 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/ee/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(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/ee/api/projects.html#edit-project-hook type EditProjectHookOptions struct { 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/ee/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(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/ee/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(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/ee/api/projects.html#trigger-a-test-project-hook func (s *ProjectsService) TriggerTestProjectHook(pid interface{}, 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 a project or group hook custom header. // If the header isn't present, it will be created. // // GitLab API docs: // https://docs.gitlab.com/ee/api/projects.html#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/ee/api/projects.html#set-a-custom-header func (s *ProjectsService) SetProjectCustomHeader(pid interface{}, 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/ee/api/projects.html#delete-a-custom-header func (s *ProjectsService) DeleteProjectCustomHeader(pid interface{}, 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/ee/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/ee/api/projects.html#create-a-forked-fromto-relation-between-existing-projects. func (s *ProjectsService) CreateProjectForkRelation(pid interface{}, 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/ee/api/projects.html#delete-an-existing-forked-from-relationship func (s *ProjectsService) DeleteProjectForkRelation(pid interface{}, 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) } // ProjectFile represents an uploaded project file. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#upload-a-file type ProjectFile struct { Alt string `json:"alt"` URL string `json:"url"` FullPath string `json:"full_path"` Markdown string `json:"markdown"` } // UploadFile uploads a file. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#upload-a-file func (s *ProjectsService) UploadFile(pid interface{}, content io.Reader, filename 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)) req, err := s.client.UploadRequest( http.MethodPost, u, content, filename, UploadFile, nil, options, ) if err != nil { return nil, nil, err } pf := new(ProjectFile) resp, err := s.client.Do(req, pf) if err != nil { return nil, resp, err } return pf, resp, nil } // UploadAvatar uploads an avatar. // // GitLab API docs: // https://docs.gitlab.com/ee/api/projects.html#upload-a-project-avatar func (s *ProjectsService) UploadAvatar(pid interface{}, 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 } // ListProjectForks gets a list of project forks. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/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"` 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/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(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/ee/api/projects.html#add-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/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(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/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"` 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/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(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/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(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/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"` RequirePasswordToApprove bool `json:"require_password_to_approve"` SelectiveCodeOwnerRemovals bool `json:"selective_code_owner_removals,omitempty"` } // 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(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/ee/api/merge_request_approvals.html#change-configuration type ChangeApprovalConfigurationOptions struct { ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,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"` 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"` } // 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(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/ee/api/merge_request_approvals.html#get-project-level-rules type GetProjectApprovalRulesListsOptions ListOptions // GetProjectApprovalRules looks up the list of project level approver rules. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_request_approvals.html#get-project-level-rules func (s *ProjectsService) GetProjectApprovalRules(pid interface{}, 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/ee/api/merge_request_approvals.html#get-a-single-project-level-rule func (s *ProjectsService) GetProjectApprovalRule(pid interface{}, 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/ee/api/merge_request_approvals.html#create-project-level-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"` } // CreateProjectApprovalRule creates a new project-level approval rule. // // GitLab API docs: // https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-project-level-rule 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(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/ee/api/merge_request_approvals.html#update-project-level-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"` } // 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-rule 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(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/ee/api/merge_request_approvals.html#delete-project-level-rule 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(http.MethodDelete, 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 { ApproverGroupIDs *[]int `url:"approver_group_ids,omitempty" json:"approver_group_ids,omitempty"` ApproverIDs *[]int `url:"approver_ids,omitempty" json:"approver_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(http.MethodPut, 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 } // ProjectPullMirrorDetails represent the details of the configuration pull // mirror and its update status. // // GitLab API docs: // https://docs.gitlab.com/ee/api/projects.html#get-a-projects-pull-mirror-details 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/ee/api/projects.html#get-a-projects-pull-mirror-details func (s *ProjectsService) GetProjectPullMirrorDetails(pid interface{}, 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 } // 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 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(http.MethodPost, u, nil, options) if err != nil { return nil, err } resp, err := s.client.Do(req, nil) if err != nil { return resp, err } return resp, nil } // TransferProjectOptions represents the available TransferProject() options. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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(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/ee/api/projects.html#start-the-housekeeping-task-for-a-project func (s *ProjectsService) StartHousekeepingProject(pid interface{}, 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/ee/api/projects.html#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"` } func (s *ProjectsService) GetRepositoryStorage(pid interface{}, 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 }
// // 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" ) // ProtectedBranchesService handles communication with the protected branch // related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_branches.html type ProtectedBranchesService struct { client *Client } // ProtectedBranch represents a protected branch. // // GitLab API docs: // https://docs.gitlab.com/ee/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"` 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/ee/api/protected_branches.html#list-protected-branches type BranchAccessDescription 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"` } // ListProtectedBranchesOptions represents the available ListProtectedBranches() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_branches.html#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/ee/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(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/ee/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(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/ee/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"` 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/ee/api/protected_branches.html#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/ee/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(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/ee/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(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/ee/api/protected_branches.html#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/ee/api/protected_branches.html#update-a-protected-branch func (s *ProtectedBranchesService) UpdateProtectedBranch(pid interface{}, 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 } // RequireCodeOwnerApprovalsOptions represents the available // RequireCodeOwnerApprovals() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_branches.html#update-a-protected-branch type RequireCodeOwnerApprovalsOptions struct { CodeOwnerApprovalRequired *bool `url:"code_owner_approval_required,omitempty" json:"code_owner_approval_required,omitempty"` } // RequireCodeOwnerApprovals updates the code owner approval option. // // Deprecated: Use UpdateProtectedBranch() instead. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/protected_branches.html#update-a-protected-branch func (s *ProtectedBranchesService) RequireCodeOwnerApprovals(pid interface{}, branch string, opt *RequireCodeOwnerApprovalsOptions, options ...RequestOptionFunc) (*Response, error) { updateOptions := &UpdateProtectedBranchOptions{ CodeOwnerApprovalRequired: opt.CodeOwnerApprovalRequired, } _, req, err := s.UpdateProtectedBranch(pid, branch, updateOptions, options...) return req, err }
// // 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" ) // ProtectedEnvironmentsService handles communication with the protected // environment methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_environments.html type ProtectedEnvironmentsService struct { client *Client } // ProtectedEnvironment represents a protected environment. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_environments.html 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/ee/api/protected_environments.html 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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#list-protected-environments type ListProtectedEnvironmentsOptions ListOptions // ListProtectedEnvironments returns a list of protected environments from a // project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_environments.html#list-protected-environments func (s *ProtectedEnvironmentsService) ListProtectedEnvironments(pid interface{}, 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/ee/api/protected_environments.html#get-a-single-protected-environment func (s *ProtectedEnvironmentsService) GetProtectedEnvironment(pid interface{}, 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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#protect-a-single-environment func (s *ProtectedEnvironmentsService) ProtectRepositoryEnvironments(pid interface{}, 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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#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/ee/api/protected_environments.html#update-a-protected-environment func (s *ProtectedEnvironmentsService) UpdateProtectedEnvironments(pid interface{}, 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/ee/api/protected_environments.html#unprotect-a-single-environment func (s *ProtectedEnvironmentsService) UnprotectEnvironment(pid interface{}, 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) }
// // 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" ) // 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 { 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/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(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/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(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/ee/api/protected_tags.html#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/ee/api/protected_tags.html#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/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(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/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // 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"` 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/ee/api/releases/links.html#list-links-of-a-release type ListReleaseLinksOptions ListOptions // ListReleaseLinks gets assets as links from a Release. // // GitLab API docs: https://docs.gitlab.com/ee/api/releases/links.html#list-links-of-a-release 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), 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/ee/api/releases/links.html#get-a-release-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), 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/ee/api/releases/links.html#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/ee/api/releases/links.html#create-a-release-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), 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/ee/api/releases/links.html#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/ee/api/releases/links.html#update-a-release-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), 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/ee/api/releases/links.html#delete-a-release-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), 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 }
// // 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" ) // ReleasesService handles communication with the releases methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/releases/index.html type ReleasesService struct { client *Client } // Release represents a project release. // // GitLab API docs: // https://docs.gitlab.com/ee/api/releases/index.html#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"` 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"` } `json:"assets"` 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"` } // ListReleasesOptions represents ListReleases() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/releases/index.html#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/ee/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(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/ee/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), 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/ee/api/releases/#get-the-latest-release func (s *ReleasesService) GetLatestRelease(pid interface{}, 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/ee/api/releases/index.html#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/ee/api/releases/index.html#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/ee/api/releases/index.html#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/ee/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(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/ee/api/releases/index.html#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/ee/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), 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/ee/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), 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 }
// // 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" ) // RepositoriesService handles communication with the repositories related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/repositories.html type RepositoriesService struct { client *Client } // TreeNode represents a GitLab repository file or directory. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/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(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/ee/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(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/ee/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(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/ee/api/repositories.html#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/ee/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(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/ee/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(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/ee/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/ee/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"` Unidiff *bool `url:"unidiff,omitempty" json:"unidiff,omitempty"` } // Compare compares branches, tags or commits. // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/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/ee/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/ee/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(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/ee/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/ee/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(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/ee/api/repositories.html#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/ee/api/repositories.html#add-changelog-data-to-a-changelog-file func (s *RepositoriesService) AddChangelog(pid interface{}, 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/ee/api/repositories.html#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/ee/api/repositories.html#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/ee/api/repositories.html#generate-changelog-data func (s *RepositoriesService) GenerateChangelogData(pid interface{}, 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 }
// // 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" ) // RepositoryFilesService handles communication with the repository files // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/repository_files.html type RepositoryFilesService struct { client *Client } // File represents a GitLab repository file. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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/ee/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/ee/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), 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/ee/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/ee/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), 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 } f := &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 != "" { f.Size, err = strconv.Atoi(sizeString) if err != nil { return nil, resp, err } } return f, resp, nil } // FileBlameRange represents one item of blame information. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/api/repository_files.html#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/ee/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), 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/ee/api/repository_files.html#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 allows you to receive the raw file in repository. // // GitLab API docs: // https://docs.gitlab.com/ee/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), 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 } // FileInfo represents file details of a GitLab repository file. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/api/repository_files.html#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/ee/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), 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/ee/api/repository_files.html#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/ee/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), 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/ee/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/ee/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), PathEscape(fileName), ) req, err := s.client.NewRequest(http.MethodDelete, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // RepositorySubmodulesService handles communication with the repository // submodules related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/repository_submodules.html type RepositorySubmodulesService struct { client *Client } // SubmoduleCommit represents a GitLab submodule commit. // // GitLab API docs: https://docs.gitlab.com/ee/api/repository_submodules.html 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/ee/api/repository_submodules.html#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/ee/api/repository_submodules.html#update-existing-submodule-reference-in-repository func (s *RepositorySubmodulesService) UpdateSubmodule(pid interface{}, 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 }
// // 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" 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 { *req = *req.WithContext(ctx) return nil } } // 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 } } // 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 } } // 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 } }
// // 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" ) // ResourceGroupService handles communication with the resource // group related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/resource_groups.html type ResourceGroupService struct { client *Client } // ResourceGrouop represents a GitLab Project Resource Group. // // GitLab API docs: // https://docs.gitlab.com/ee/api/resource_groups.html 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/ee/api/resource_groups.html 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/ee/api/resource_groups.html#get-all-resource-groups-for-a-project func (s *ResourceGroupService) GetAllResourceGroupsForAProject(pid interface{}, 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/ee/api/resource_groups.html#get-a-specific-resource-group func (s *ResourceGroupService) GetASpecificResourceGroup(pid interface{}, 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/ee/api/resource_groups.html#list-upcoming-jobs-for-a-specific-resource-group func (s *ResourceGroupService) ListUpcomingJobsForASpecificResourceGroup(pid interface{}, 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/ee/api/resource_groups.html#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/ee/api/resource_groups.html#edit-an-existing-resource-group func (s *ResourceGroupService) EditAnExistingResourceGroup(pid interface{}, 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 }
// // 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" ) // ResourceIterationEventsService handles communication with the event related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_iteration_events.html type ResourceIterationEventsService struct { client *Client } // IterationEvent represents a resource iteration event. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_iteration_events.html 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/ee/api/resource_iteration_events.html 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/ee/api/resource_iteration_events.html#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/ee/api/resource_iteration_events.html#list-project-issue-iteration-events func (s *ResourceIterationEventsService) ListIssueIterationEvents(pid interface{}, 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/ee/api/resource_iteration_events.html#get-single-issue-iteration-event func (s *ResourceIterationEventsService) GetIssueIterationEvent(pid interface{}, 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 }
// // 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" ) // 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 } // LabelEvent represents a resource label event. // // GitLab API docs: // https://docs.gitlab.com/ee/api/resource_label_events.html#get-single-issue-label-event type LabelEvent struct { ID int `json:"id"` Action string `json:"action"` CreatedAt *time.Time `json:"created_at"` ResourceType string `json:"resource_type"` ResourceID int `json:"resource_id"` User 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:"user"` Label struct { ID int `json:"id"` Name string `json:"name"` Color string `json:"color"` TextColor string `json:"text_color"` Description string `json:"description"` } `json:"label"` } // ListLabelEventsOptions represents the options for all resource label events // list methods. // // GitLab API docs: // https://docs.gitlab.com/ee/api/resource_label_events.html#list-project-issue-label-events type ListLabelEventsOptions struct { ListOptions } // ListIssueLabelEvents retrieves resource label events for the // 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) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/issues/%d/resource_label_events", PathEscape(project), issue) req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } var ls []*LabelEvent resp, err := s.client.Do(req, &ls) if err != nil { return nil, 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) { 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) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } l := new(LabelEvent) resp, err := s.client.Do(req, l) if err != nil { return nil, resp, err } return l, resp, nil } // ListGroupEpicLabelEvents retrieves resource label events for the specified // group and epic. // // 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) { group, err := parseID(gid) if err != nil { return nil, nil, err } u := fmt.Sprintf("groups/%s/epics/%d/resource_label_events", PathEscape(group), epic) req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } var ls []*LabelEvent resp, err := s.client.Do(req, &ls) if err != nil { return nil, resp, err } return ls, resp, nil } // GetGroupEpicLabelEvent gets a single group epic label event. // // 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) { 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) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } l := new(LabelEvent) resp, err := s.client.Do(req, l) if err != nil { return nil, resp, err } return l, resp, nil } // 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) ListMergeRequestsLabelEvents(pid interface{}, 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) req, err := s.client.NewRequest(http.MethodGet, u, opt, options) if err != nil { return nil, nil, err } var ls []*LabelEvent resp, err := s.client.Do(req, &ls) if err != nil { return nil, 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) { 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) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } l := new(LabelEvent) resp, err := s.client.Do(req, l) if err != nil { return nil, resp, err } return l, resp, nil }
// // 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" ) // ResourceMilestoneEventsService handles communication with the event related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_milestone_events.html type ResourceMilestoneEventsService struct { client *Client } // MilestoneEvent represents a resource milestone event. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_milestone_events.html 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/ee/api/resource_milestone_events.html#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/ee/api/resource_milestone_events.html#list-project-issue-milestone-events func (s *ResourceMilestoneEventsService) ListIssueMilestoneEvents(pid interface{}, 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/ee/api/resource_milestone_events.html#get-single-issue-milestone-event func (s *ResourceMilestoneEventsService) GetIssueMilestoneEvent(pid interface{}, 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/ee/api/resource_milestone_events.html#list-project-merge-request-milestone-events func (s *ResourceMilestoneEventsService) ListMergeMilestoneEvents(pid interface{}, 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/ee/api/resource_milestone_events.html#get-single-merge-request-milestone-event func (s *ResourceMilestoneEventsService) GetMergeRequestMilestoneEvent(pid interface{}, 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 }
// // 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" ) // ResourceStateEventsService handles communication with the event related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_state_events.html type ResourceStateEventsService struct { client *Client } // StateEvent represents a resource state event. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_state_events.html 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/ee/api/resource_state_events.html#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/ee/api/resource_state_events.html#list-project-issue-state-events func (s *ResourceStateEventsService) ListIssueStateEvents(pid interface{}, 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/ee/api/resource_state_events.html#get-single-issue-state-event func (s *ResourceStateEventsService) GetIssueStateEvent(pid interface{}, 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/ee/api/resource_state_events.html#list-project-merge-request-state-events func (s *ResourceStateEventsService) ListMergeStateEvents(pid interface{}, 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/ee/api/resource_state_events.html#get-single-merge-request-state-event func (s *ResourceStateEventsService) GetMergeRequestStateEvent(pid interface{}, 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 }
// // 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" ) // ResourceWeightEventsService handles communication with the event related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_weight_events.html type ResourceWeightEventsService struct { client *Client } // WeightEvent represents a resource weight event. // // GitLab API docs: https://docs.gitlab.com/ee/api/resource_weight_events.html 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/ee/api/resource_weight_events.html#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/ee/api/resource_weight_events.html#list-project-issue-weight-events func (s *ResourceWeightEventsService) ListIssueWeightEvents(pid interface{}, 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 }
// // 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" ) // RunnersService handles communication with the runner related methods of the // GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/runners.html type RunnersService struct { client *Client } // Runner represents a GitLab CI Runner. // // GitLab API docs: https://docs.gitlab.com/ee/api/runners.html type Runner struct { ID int `json:"id"` Description string `json:"description"` Active bool `json:"active"` Paused bool `json:"paused"` IsShared bool `json:"is_shared"` IPAddress string `json:"ip_address"` 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"` } // RunnerDetails represents the GitLab CI runner details. // // GitLab API docs: https://docs.gitlab.com/ee/api/runners.html type RunnerDetails struct { Paused bool `json:"paused"` Architecture string `json:"architecture"` Description string `json:"description"` ID int `json:"id"` IPAddress string `json:"ip_address"` IsShared bool `json:"is_shared"` RunnerType string `json:"runner_type"` 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"` RunUntagged bool `json:"run_untagged"` 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"` // Deprecated: Use Paused instead. (Deprecated in GitLab 14.8) Active bool `json:"active"` } // ListRunnersOptions represents the available ListRunners() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#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/ee/api/runners.html#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/ee/api/runners.html#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/ee/api/runners.html#get-runners-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(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/ee/api/runners.html#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"` // Deprecated: Use Paused instead. (Deprecated in GitLab 14.8) Active *bool `url:"active,omitempty" json:"active,omitempty"` } // UpdateRunnerDetails updates details for a given runner. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#update-runners-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(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/ee/api/runners.html#delete-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(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/ee/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/ee/api/runners.html#list-runners-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(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/ee/api/runners.html#list-projects-runners type ListProjectRunnersOptions ListRunnersOptions // ListProjectRunners gets a list of runners accessible by the authenticated user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#list-projects-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(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/ee/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/ee/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(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/ee/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(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/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(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/ee/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 *RegisterNewRunnerInfoOptions `url:"info,omitempty" json:"info,omitempty"` Active *bool `url:"active,omitempty" json:"active,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"` } // RegisterNewRunnerInfoOptions represents the info hashmap parameter in // RegisterNewRunnerOptions. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#register-a-new-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/ee/api/runners.html#register-a-new-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/ee/api/runners.html#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/ee/api/runners.html#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/ee/api/runners.html#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/ee/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/ee/api/runners.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#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. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#reset-groups-runner-registration-token func (s *RunnersService) ResetGroupRunnerRegistrationToken(gid interface{}, 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 } // ResetGroupRunnerRegistrationToken resets a projects's runner registration token. // // GitLab API docs: // https://docs.gitlab.com/ee/api/runners.html#reset-projects-runner-registration-token func (s *RunnersService) ResetProjectRunnerRegistrationToken(pid interface{}, 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/ee/api/runners.html#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 }
// // 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" ) // SearchService handles communication with the search related methods of the // GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/search.html type SearchService struct { client *Client } // SearchOptions represents the available options for all search methods. // // GitLab API docs: https://docs.gitlab.com/ee/api/search.html 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/ee/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/ee/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/ee/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/ee/api/search.html#scope-issues-1 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/ee/api/search.html#scope-issues-2 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/ee/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/ee/api/search.html#scope-merge_requests-1 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/ee/api/search.html#scope-merge_requests-2 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/ee/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/ee/api/search.html#scope-milestones-1 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/ee/api/search.html#scope-milestones-2 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/ee/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/ee/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/ee/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/ee/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/ee/api/search.html#scope-wiki_blobs-premium-1 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/ee/api/search.html#scope-wiki_blobs-premium-2 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/ee/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/ee/api/search.html#scope-commits-premium-1 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/ee/api/search.html#scope-commits-premium-2 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"` 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/ee/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/ee/api/search.html#scope-blobs-premium-1 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/ee/api/search.html#scope-blobs-premium-2 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(http.MethodGet, "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(http.MethodGet, 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(http.MethodGet, u, opts, options) if err != nil { return nil, err } return s.client.Do(req, result) }
// // 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" ) // ServicesService handles communication with the services related methods of // the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/integrations.html type ServicesService struct { client *Client } // Service represents a GitLab service. // // GitLab API docs: https://docs.gitlab.com/ee/api/integrations.html 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"` PushEvents bool `json:"push_events"` IssuesEvents bool `json:"issues_events"` AlertEvents bool `json:"alert_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"` VulnerabilityEvents bool `json:"vulnerability_events"` DeploymentEvents bool `json:"deployment_events"` } // ListServices gets a list of all active services. // // GitLab API docs: https://docs.gitlab.com/ee/api/integrations.html#list-all-active-integrations 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(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/ee/api/integrations.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/ee/api/integrations.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/ee/api/integrations.html#get-custom-issue-tracker-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(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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-a-custom-issue-tracker 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(http.MethodPut, 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/ee/api/integrations.html#disable-a-custom-issue-tracker 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(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/ee/api/integrations.html#datadog type DataDogService struct { Service Properties *DataDogServiceProperties `json:"properties"` } // DataDogServiceProperties represents DataDog specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-datadog-settings func (s *ServicesService) GetDataDogService(pid interface{}, 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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-datadog func (s *ServicesService) SetDataDogService(pid interface{}, opt *SetDataDogServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteDataDogService deletes the DataDog service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-datadog func (s *ServicesService) DeleteDataDogService(pid interface{}, 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/ee/api/integrations.html#discord-notifications type DiscordService struct { Service Properties *DiscordServiceProperties `json:"properties"` } // DiscordServiceProperties represents Discord specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-discord-notifications-settings func (s *ServicesService) GetDiscordService(pid interface{}, 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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-discord-notifications func (s *ServicesService) SetDiscordService(pid interface{}, opt *SetDiscordServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteDiscordService deletes Discord service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-discord-notifications func (s *ServicesService) DeleteDiscordService(pid interface{}, 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/ee/api/integrations.html#drone type DroneCIService struct { Service Properties *DroneCIServiceProperties `json:"properties"` } // DroneCIServiceProperties represents Drone CI specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-drone-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(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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-drone 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(http.MethodPut, 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/ee/api/integrations.html#disable-drone 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(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/ee/api/integrations.html#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/ee/api/integrations.html#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/ee/api/integrations.html#get-emails-on-push-integration-settings func (s *ServicesService) GetEmailsOnPushService(pid interface{}, 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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-emails-on-push func (s *ServicesService) SetEmailsOnPushService(pid interface{}, opt *SetEmailsOnPushServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteEmailsOnPushService deletes Emails on Push service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-emails-on-push func (s *ServicesService) DeleteEmailsOnPushService(pid interface{}, 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/ee/api/integrations.html#external-wiki type ExternalWikiService struct { Service Properties *ExternalWikiServiceProperties `json:"properties"` } // ExternalWikiServiceProperties represents External Wiki specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.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/ee/api/integrations.html#get-external-wiki-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(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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-an-external-wiki 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(http.MethodPut, 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/ee/api/integrations.html#disable-an-external-wiki 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(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/ee/api/integrations.html#github type GithubService struct { Service Properties *GithubServiceProperties `json:"properties"` } // GithubServiceProperties represents Github specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-github-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(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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-github 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(http.MethodPut, 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/ee/api/integrations.html#disable-github 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(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/ee/api/integrations.html#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/ee/api/integrations.html#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"` AlertEvents bool `json:"alert_events"` IssuesEvents bool `json:"issues_events"` ConfidentialIssuesEvents bool `json:"confidential_issues_events"` MergeRequestsEvents bool `json:"merge_requests_events"` NoteEvents bool `json:"note_events"` ConfidentialNoteEvents bool `json:"confidential_note_events"` DeploymentEvents bool `json:"deployment_events"` IncidentsEvents bool `json:"incidents_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"` // 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/ee/api/integrations.html#get-gitlab-for-slack-app-settings func (s *ServicesService) GetSlackApplication(pid interface{}, 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/ee/api/integrations.html#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"` // 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/ee/api/integrations.html#set-up-gitlab-for-slack-app func (s *ServicesService) SetSlackApplication(pid interface{}, opt *SetSlackApplicationOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DisableSlackApplication disable the GitLab for Slack app integration for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-gitlab-for-slack-app func (s *ServicesService) DisableSlackApplication(pid interface{}, 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) } // SetGitLabCIServiceOptions represents the available SetGitLabCIService() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.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/ee/api/integrations.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(http.MethodPut, 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/ee/api/integrations.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(http.MethodDelete, 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/ee/api/integrations.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/ee/api/integrations.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(http.MethodPut, 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/ee/api/integrations.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(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/ee/api/integrations.html#jenkins type JenkinsCIService struct { Service Properties *JenkinsCIServiceProperties `json:"properties"` } // JenkinsCIServiceProperties represents Jenkins CI specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-jenkins-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(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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-jenkins 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(http.MethodPut, 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/ee/api/integrations.html#disable-jenkins 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(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/ee/api/integrations.html#jira type JiraService struct { Service Properties *JiraServiceProperties `json:"properties"` } // JiraServiceProperties represents Jira specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#jira type JiraServiceProperties struct { URL string `json:"url"` APIURL string `json:"api_url"` ProjectKeys []string `json:"project_keys" ` Username string `json:"username" ` Password string `json:"password" ` JiraIssueTransitionID string `json:"jira_issue_transition_id"` // Deprecated: This parameter was removed in GitLab 17.0 ProjectKey string `json:"project_key" ` } // 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/ee/api/integrations.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(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/ee/api/integrations.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"` 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"` // Deprecated: This parameter was removed in GitLab 17.0 ProjectKey *string `url:"project_key,omitempty" json:"project_key,omitempty" ` } // SetJiraService sets Jira service for a project // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.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(http.MethodPut, 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/ee/api/integrations.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(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/ee/api/integrations.html#mattermost-notifications type MattermostService struct { Service Properties *MattermostServiceProperties `json:"properties"` } // MattermostServiceProperties represents Mattermost specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-slack-service-settings func (s *ServicesService) GetMattermostService(pid interface{}, 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/ee/api/integrations.html#createedit-mattermost-notifications-service 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"` } // MattermostSlashCommandsService represents Mattermost slash commands settings. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#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/ee/api/integrations.html#get-mattermost-slash-command-integration-settings func (s *ServicesService) GetMattermostSlashCommandsService(pid interface{}, 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/ee/api/integrations.html#get-mattermost-slash-command-integration-settings 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/ee/api/integrations.html#createedit-mattermost-slash-command-integration func (s *ServicesService) SetMattermostSlashCommandsService(pid interface{}, opt *SetMattermostSlashCommandsServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteMattermostSlashCommandsService deletes Mattermost slash commands service for project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-mattermost-slash-command-integration func (s *ServicesService) DeleteMattermostSlashCommandsService(pid interface{}, 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) } // SetMattermostService sets Mattermost service for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#createedit-mattermost-notifications-service func (s *ServicesService) SetMattermostService(pid interface{}, opt *SetMattermostServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteMattermostService deletes Mattermost service for project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#delete-mattermost-notifications-service func (s *ServicesService) DeleteMattermostService(pid interface{}, 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) } // MicrosoftTeamsService represents Microsoft Teams service settings. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#microsoft-teams type MicrosoftTeamsService struct { Service Properties *MicrosoftTeamsServiceProperties `json:"properties"` } // MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.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/ee/api/integrations.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(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/ee/api/integrations.html#create-edit-microsoft-teams-service 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/ee/api/integrations.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(http.MethodPut, 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/ee/api/integrations.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(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/ee/api/integrations.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/integrations.html#pipeline-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/ee/api/integrations.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(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/ee/api/integrations.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/integrations.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(http.MethodPut, 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/integrations.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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // PrometheusService represents Prometheus service settings. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#prometheus type PrometheusService struct { Service Properties *PrometheusServiceProperties `json:"properties"` } // PrometheusServiceProperties represents Prometheus specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#prometheus type PrometheusServiceProperties struct { APIURL string `json:"api_url"` GoogleIAPAudienceClientID string `json:"google_iap_audience_client_id"` GoogleIAPServiceAccountJSON string `json:"google_iap_service_account_json"` } // GetPrometheusService gets Prometheus service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#get-prometheus-service-settings func (s *ServicesService) GetPrometheusService(pid interface{}, options ...RequestOptionFunc) (*PrometheusService, *Response, error) { project, err := parseID(pid) if err != nil { return nil, nil, err } u := fmt.Sprintf("projects/%s/services/prometheus", PathEscape(project)) req, err := s.client.NewRequest(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } svc := new(PrometheusService) resp, err := s.client.Do(req, svc) if err != nil { return nil, resp, err } return svc, resp, nil } // SetPrometheusServiceOptions represents the available SetPrometheusService() // options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#createedit-prometheus-service type SetPrometheusServiceOptions struct { APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"` GoogleIAPAudienceClientID *string `url:"google_iap_audience_client_id,omitempty" json:"google_iap_audience_client_id,omitempty"` GoogleIAPServiceAccountJSON *string `url:"google_iap_service_account_json,omitempty" json:"google_iap_service_account_json,omitempty"` } // SetPrometheusService sets Prometheus service for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#createedit-prometheus-service func (s *ServicesService) SetPrometheusService(pid interface{}, opt *SetPrometheusServiceOptions, options ...RequestOptionFunc) (*Response, error) { project, err := parseID(pid) if err != nil { return nil, err } u := fmt.Sprintf("projects/%s/services/prometheus", PathEscape(project)) req, err := s.client.NewRequest(http.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeletePrometheusService deletes Prometheus service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#delete-prometheus-service func (s *ServicesService) DeletePrometheusService(pid interface{}, options ...RequestOptionFunc) (*Response, error) { project, err := parseID(pid) if err != nil { return nil, err } u := fmt.Sprintf("projects/%s/services/prometheus", 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/ee/api/integrations.html#slack type SlackService struct { Service Properties *SlackServiceProperties `json:"properties"` } // SlackServiceProperties represents Slack specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#slack 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/ee/api/integrations.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(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/ee/api/integrations.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"` 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/ee/api/integrations.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(http.MethodPut, 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/ee/api/integrations.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(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/ee/api/integrations.html#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/ee/api/integrations.html#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/ee/api/integrations.html#get-slack-slash-command-integration-settings func (s *ServicesService) GetSlackSlashCommandsService(pid interface{}, 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/ee/api/integrations.html#createedit-slack-slash-command-service 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/13.12/ee/api/integrations.html#createedit-slack-slash-command-service func (s *ServicesService) SetSlackSlashCommandsService(pid interface{}, opt *SetSlackSlashCommandsServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteSlackSlashCommandsService deletes Slack slash commands service for project. // // GitLab API docs: // https://docs.gitlab.com/13.12/ee/api/integrations.html#delete-slack-slash-command-service func (s *ServicesService) DeleteSlackSlashCommandsService(pid interface{}, 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/ee/api/integrations.html#telegram type TelegramService struct { Service Properties *TelegramServiceProperties `json:"properties"` } // TelegramServiceProperties represents Telegram specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-telegram-settings func (s *ServicesService) GetTelegramService(pid interface{}, 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/ee/api/integrations.html#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/ee/api/integrations.html#set-up-telegram func (s *ServicesService) SetTelegramService(pid interface{}, opt *SetTelegramServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteTelegramService deletes Telegram service for project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#disable-telegram func (s *ServicesService) DeleteTelegramService(pid interface{}, 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/ee/api/integrations.html#youtrack type YouTrackService struct { Service Properties *YouTrackServiceProperties `json:"properties"` } // YouTrackServiceProperties represents YouTrack specific properties. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#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/ee/api/integrations.html#get-youtrack-service-settings func (s *ServicesService) GetYouTrackService(pid interface{}, 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/ee/api/integrations.html#createedit-youtrack-service 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/ee/api/integrations.html#createedit-youtrack-service func (s *ServicesService) SetYouTrackService(pid interface{}, opt *SetYouTrackServiceOptions, 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.MethodPut, u, opt, options) if err != nil { return nil, err } return s.client.Do(req, nil) } // DeleteYouTrackService deletes YouTrack service settings for a project. // // GitLab API docs: // https://docs.gitlab.com/ee/api/integrations.html#delete-youtrack-service func (s *ServicesService) DeleteYouTrackService(pid interface{}, 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) }
// // 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" ) // SettingsService handles communication with the application SettingsService // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/settings.html type SettingsService struct { client *Client } // Settings represents the GitLab application settings. // // GitLab API docs: https://docs.gitlab.com/ee/api/settings.html // // 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"` 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"` 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"` CIMaxIncludes int `json:"ci_max_includes"` CIMaxTotalYAMLSizeBytes int `json:"ci_max_total_yaml_size_bytes"` 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"` DefaultBranchProtection int `json:"default_branch_protection"` DefaultCiConfigPath string `json:"default_ci_config_path"` DefaultGroupVisibility VisibilityValue `json:"default_group_visibility"` 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"` DelayedGroupDeletion bool `json:"delayed_group_deletion"` DelayedProjectDeletion bool `json:"delayed_project_deletion"` DeleteInactiveProjects bool `json:"delete_inactive_projects"` DeletionAdjournedPeriod int `json:"deletion_adjourned_period"` DiffMaxFiles int `json:"diff_max_files"` DiffMaxLines int `json:"diff_max_lines"` DiffMaxPatchBytes int `json:"diff_max_patch_bytes"` DisableFeedToken bool `json:"disable_feed_token"` DisableOverridingApproversPerMergeRequest bool `json:"disable_overriding_approvers_per_merge_request"` DisabledOauthSignInSources []string `json:"disabled_oauth_sign_in_sources"` DomainAllowlist []string `json:"domain_allowlist"` DomainDenylist []string `json:"domain_denylist"` DomainDenylistEnabled bool `json:"domain_denylist_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"` 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"` ElasticsearchSearch bool `json:"elasticsearch_search"` ElasticsearchShards int `json:"elasticsearch_shards"` ElasticsearchURL []string `json:"elasticsearch_url"` ElasticsearchUsername string `json:"elasticsearch_username"` EmailAdditionalText string `json:"email_additional_text"` EmailAuthorInBody bool `json:"email_author_in_body"` EmailRestrictions string `json:"email_restrictions"` EmailRestrictionsEnabled bool `json:"email_restrictions_enabled"` EnabledGitAccessProtocol string `json:"enabled_git_access_protocol"` 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"` 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"` 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"` GitpodEnabled bool `json:"gitpod_enabled"` GitpodURL string `json:"gitpod_url"` GitRateLimitUsersAllowlist []string `json:"git_rate_limit_users_allowlist"` 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"` 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"` 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"` InProductMarketingEmailsEnabled bool `json:"in_product_marketing_emails_enabled"` InvisibleCaptchaEnabled bool `json:"invisible_captcha_enabled"` IssuesCreateLimit int `json:"issues_create_limit"` 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"` 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"` MaxArtifactsSize int `json:"max_artifacts_size"` MaxAttachmentSize int `json:"max_attachment_size"` MaxExportSize int `json:"max_export_size"` MaxImportSize int `json:"max_import_size"` 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"` OutboundLocalRequestsAllowlistRaw string `json:"outbound_local_requests_allowlist_raw"` OutboundLocalRequestsWhitelist []string `json:"outbound_local_requests_whitelist"` 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"` PerformanceBarAllowedGroupID int `json:"performance_bar_allowed_group_id"` PerformanceBarAllowedGroupPath string `json:"performance_bar_allowed_group_path"` PerformanceBarEnabled bool `json:"performance_bar_enabled"` 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"` ProjectRunnerTokenExpirationInterval int `json:"project_runner_token_expiration_interval"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` UniqueIPsLimitEnabled bool `json:"unique_ips_limit_enabled"` UniqueIPsLimitPerUser int `json:"unique_ips_limit_per_user"` UniqueIPsLimitTimeWindow int `json:"unique_ips_limit_time_window"` 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"` UserDeactivationEmailsEnabled bool `json:"user_deactivation_emails_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"` UsersGetByIDLimit int `json:"users_get_by_id_limit"` UsersGetByIDLimitAllowlistRaw string `json:"users_get_by_id_limit_allowlist_raw"` 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 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]interface{}) 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/ee/api/settings.html#get-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/ee/api/settings.html#change-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"` 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"` AllowAccountDeletion *bool `url:"allow_account_deletion,omitempty" json:"allow_account_deletion,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"` 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"` AssetProxyWhitelist *[]string `url:"asset_proxy_whitelist,omitempty" json:"asset_proxy_whitelist,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"` 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"` 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"` 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"` DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,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"` 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"` 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"` DeletionAdjournedPeriod *int `url:"deletion_adjourned_period,omitempty" json:"deletion_adjourned_period,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"` DisableOverridingApproversPerMergeRequest *bool `url:"disable_overriding_approvers_per_merge_request,omitempty" json:"disable_overriding_approvers_per_merge_request,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"` 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"` 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"` 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"` 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"` EmailRestrictions *string `url:"email_restrictions,omitempty" json:"email_restrictions,omitempty"` EmailRestrictionsEnabled *bool `url:"email_restrictions_enabled,omitempty" json:"email_restrictions_enabled,omitempty"` EnabledGitAccessProtocol *string `url:"enabled_git_access_protocol,omitempty" json:"enabled_git_access_protocol,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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` MaxArtifactsSize *int `url:"max_artifacts_size,omitempty" json:"max_artifacts_size,omitempty"` MaxAttachmentSize *int `url:"max_attachment_size,omitempty" json:"max_attachment_size,omitempty"` MaxExportSize *int `url:"max_export_size,omitempty" json:"max_export_size,omitempty"` MaxImportSize *int `url:"max_import_size,omitempty" json:"max_import_size,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"` 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"` 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"` PerformanceBarAllowedGroupID *int `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"` 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"` ProjectRunnerTokenExpirationInterval *int `url:"project_runner_token_expiration_interval,omitempty" json:"project_runner_token_expiration_interval,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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` ThrottleUnauthenticatedEnabled *bool `url:"throttle_unauthenticated_enabled,omitempty" json:"throttle_unauthenticated_enabled,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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` } // UpdateSettings updates the application settings. // // GitLab API docs: // https://docs.gitlab.com/ee/api/settings.html#change-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 }
// // 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" ) // SidekiqService handles communication with the sidekiq service // // GitLab API docs: https://docs.gitlab.com/ee/api/sidekiq_metrics.html type SidekiqService struct { client *Client } // QueueMetrics represents the GitLab sidekiq queue metrics. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-queue-metrics type QueueMetrics struct { Queues map[string]struct { Backlog int `json:"backlog"` Latency int `json:"latency"` } `json:"queues"` } // GetQueueMetrics lists information about all the registered queues, // their backlog and their latency. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-queue-metrics func (s *SidekiqService) GetQueueMetrics(options ...RequestOptionFunc) (*QueueMetrics, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/queue_metrics", nil, options) if err != nil { return nil, nil, err } q := new(QueueMetrics) resp, err := s.client.Do(req, q) if err != nil { return nil, resp, err } return q, resp, nil } // ProcessMetrics represents the GitLab sidekiq process metrics. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-process-metrics type ProcessMetrics struct { Processes []struct { Hostname string `json:"hostname"` Pid int `json:"pid"` Tag string `json:"tag"` StartedAt *time.Time `json:"started_at"` Queues []string `json:"queues"` Labels []string `json:"labels"` Concurrency int `json:"concurrency"` Busy int `json:"busy"` } `json:"processes"` } // GetProcessMetrics lists information about all the Sidekiq workers registered // to process your queues. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-process-metrics func (s *SidekiqService) GetProcessMetrics(options ...RequestOptionFunc) (*ProcessMetrics, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/process_metrics", nil, options) if err != nil { return nil, nil, err } p := new(ProcessMetrics) resp, err := s.client.Do(req, p) if err != nil { return nil, resp, err } return p, resp, nil } // JobStats represents the GitLab sidekiq job stats. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-job-statistics type JobStats struct { Jobs struct { Processed int `json:"processed"` Failed int `json:"failed"` Enqueued int `json:"enqueued"` } `json:"jobs"` } // GetJobStats list information about the jobs that Sidekiq has performed. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-the-current-job-statistics func (s *SidekiqService) GetJobStats(options ...RequestOptionFunc) (*JobStats, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/job_stats", nil, options) if err != nil { return nil, nil, err } j := new(JobStats) resp, err := s.client.Do(req, j) if err != nil { return nil, resp, err } return j, resp, nil } // CompoundMetrics represents the GitLab sidekiq compounded stats. // // GitLab API docs: // https://docs.gitlab.com/ee/api/sidekiq_metrics.html#get-a-compound-response-of-all-the-previously-mentioned-metrics type CompoundMetrics struct { QueueMetrics ProcessMetrics JobStats } // 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/ee/api/sidekiq_metrics.html#get-a-compound-response-of-all-the-previously-mentioned-metrics func (s *SidekiqService) GetCompoundMetrics(options ...RequestOptionFunc) (*CompoundMetrics, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "/sidekiq/compound_metrics", nil, options) if err != nil { return nil, nil, err } c := new(CompoundMetrics) resp, err := s.client.Do(req, c) if err != nil { return nil, resp, err } return c, resp, nil }
// // 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" ) // SnippetRepositoryStorageMoveService handles communication with the // snippets related methods of the GitLab API. // // GitLab API docs: // https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html type SnippetRepositoryStorageMoveService struct { client *Client } // SnippetRepositoryStorageMove represents the status of a repository move. // // GitLab API docs: // https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html 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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#retrieve-all-repository-storage-moves-for-a-snippet 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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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/ee/api/snippet_repository_storage_moves.html#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) }
// // 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" ) // SnippetsService handles communication with the snippets // related methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/snippets.html type SnippetsService struct { client *Client } // Snippet represents a GitLab snippet. // // GitLab API docs: https://docs.gitlab.com/ee/api/snippets.html 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/ee/api/snippets.html#list-all-snippets-for-a-user type ListSnippetsOptions ListOptions // ListSnippets gets a list of snippets. // // GitLab API docs: // https://docs.gitlab.com/ee/api/snippets.html#list-all-snippets-for-a-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/ee/api/snippets.html#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/ee/api/snippets.html#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/ee/api/snippets.html#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/ee/api/snippets.html#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/ee/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"` 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/ee/api/snippets.html#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/ee/api/snippets.html#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/ee/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"` 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/ee/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(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/ee/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(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/ee/api/snippets.html#list-all-public-snippets type ExploreSnippetsOptions ListOptions // ExploreSnippets gets the list of public snippets. // // GitLab API docs: // https://docs.gitlab.com/ee/api/snippets.html#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/ee/api/snippets.html#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/ee/api/snippets.html#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 }
// // 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" "reflect" ) // Stringify attempts to create a reasonable string representation of types in // the Gitlab library. It does things like resolve pointers to their values // and omits struct fields with nil values. func Stringify(message interface{}) string { var buf bytes.Buffer v := reflect.ValueOf(message) stringifyValue(&buf, v) return buf.String() } // stringifyValue was heavily inspired by the goprotobuf library. func stringifyValue(buf *bytes.Buffer, val reflect.Value) { if val.Kind() == reflect.Ptr && val.IsNil() { buf.WriteString("<nil>") return } v := reflect.Indirect(val) switch v.Kind() { case reflect.String: fmt.Fprintf(buf, `"%s"`, v) case reflect.Slice: buf.WriteByte('[') for i := 0; i < v.Len(); i++ { if i > 0 { buf.WriteByte(' ') } stringifyValue(buf, v.Index(i)) } buf.WriteByte(']') return case reflect.Struct: if v.Type().Name() != "" { buf.WriteString(v.Type().String()) } buf.WriteByte('{') var sep bool for i := 0; i < v.NumField(); i++ { fv := v.Field(i) if fv.Kind() == reflect.Ptr && fv.IsNil() { continue } if fv.Kind() == reflect.Slice && fv.IsNil() { continue } if sep { buf.WriteString(", ") } else { sep = true } buf.WriteString(v.Type().Field(i).Name) buf.WriteByte(':') stringifyValue(buf, fv) } buf.WriteByte('}') default: if v.CanInterface() { fmt.Fprint(buf, v.Interface()) } } }
// // 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" ) // SystemHooksService handles communication with the system hooks related // methods of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/system_hooks.html type SystemHooksService struct { client *Client } // Hook represents a GitLap system hook. // // GitLab API docs: https://docs.gitlab.com/ee/api/system_hooks.html type Hook struct { 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 { return Stringify(h) } // ListHooks gets a list of system hooks. // // GitLab API docs: // https://docs.gitlab.com/ee/api/system_hooks.html#list-system-hooks func (s *SystemHooksService) ListHooks(options ...RequestOptionFunc) ([]*Hook, *Response, error) { req, err := s.client.NewRequest(http.MethodGet, "hooks", 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 } // GetHook get a single system hook. // // GitLab API docs: // https://docs.gitlab.com/ee/api/system_hooks.html#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/ee/api/system_hooks.html#add-new-system-hook type AddHookOptions struct { URL *string `url:"url,omitempty" json:"url,omitempty"` Token *string `url:"token,omitempty" json:"token,omitempty"` PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"` TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"` MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` RepositoryUpdateEvents *bool `url:"repository_update_events,omitempty" json:"repository_update_events,omitempty"` EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"` } // AddHook adds a new system hook hook. // // GitLab API docs: // https://docs.gitlab.com/ee/api/system_hooks.html#add-new-system-hook func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...RequestOptionFunc) (*Hook, *Response, error) { req, err := s.client.NewRequest(http.MethodPost, "hooks", opt, options) if err != nil { return nil, nil, err } h := new(Hook) resp, err := s.client.Do(req, h) if err != nil { return nil, resp, err } return h, resp, nil } // HookEvent represents an event trigger by a GitLab system hook. // // GitLab API docs: https://docs.gitlab.com/ee/api/system_hooks.html type HookEvent struct { EventName string `json:"event_name"` Name string `json:"name"` Path string `json:"path"` ProjectID int `json:"project_id"` OwnerName string `json:"owner_name"` OwnerEmail string `json:"owner_email"` } func (h HookEvent) String() string { return Stringify(h) } // TestHook tests a system hook. // // GitLab API docs: // https://docs.gitlab.com/ee/api/system_hooks.html#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(http.MethodGet, u, nil, options) if err != nil { return nil, nil, err } h := new(HookEvent) resp, err := s.client.Do(req, h) if err != nil { return nil, resp, err } return h, resp, nil } // DeleteHook deletes a system hook. This is an idempotent API function and // returns 200 OK even if the hook is not available. If the hook is deleted it // is also returned as JSON. // // GitLab API docs: // https://docs.gitlab.com/ee/api/system_hooks.html#delete-system-hook func (s *SystemHooksService) DeleteHook(hook int, options ...RequestOptionFunc) (*Response, error) { u := fmt.Sprintf("hooks/%d", hook) req, err := s.client.NewRequest(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }
// // 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" ) // TagsService handles communication with the tags related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/tags.html type TagsService struct { client *Client } // Tag represents a GitLab tag. // // GitLab API docs: https://docs.gitlab.com/ee/api/tags.html 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"` } // ReleaseNote represents a GitLab version release. // // GitLab API docs: https://docs.gitlab.com/ee/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/ee/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/ee/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(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/ee/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(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 } // CreateTagOptions represents the available CreateTag() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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"` // Deprecated: Use the Releases API instead. (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/ee/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(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/ee/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(http.MethodDelete, 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/ee/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/ee/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(http.MethodPost, 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, nil } // UpdateReleaseNoteOptions represents the available UpdateReleaseNote() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(http.MethodPut, 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, nil }
// // 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/ee/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/ee/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/ee/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/ee/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(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/ee/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(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/ee/workflow/time_tracking.html 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/ee/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(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/ee/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(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/ee/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(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 }
// // 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" ) // TodosService handles communication with the todos related methods of // the Gitlab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/todos.html type TodosService struct { client *Client } // Todo represents a GitLab todo. // // GitLab API docs: https://docs.gitlab.com/ee/api/todos.html 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 interface{} `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/ee/api/todos.html#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"` 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/ee/api/todos.html#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/ee/api/todos.html#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/ee/api/todos.html#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) }
// // 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" ) // TopicsService handles communication with the topics related methods // of the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/topics.html type TopicsService struct { client *Client } // Topic represents a GitLab project topic. // // GitLab API docs: https://docs.gitlab.com/ee/api/topics.html 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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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/ee/api/topics.html#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) }
// // 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/ee/api/projects.html type AccessControlValue string // List of available access control values. // // GitLab API docs: https://docs.gitlab.com/ee/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. // // Deprecated: Please use Ptr instead. func AccessControl(v AccessControlValue) *AccessControlValue { return Ptr(v) } // AccessLevelValue represents a permission level within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/user/permissions.html type AccessLevelValue int // List of available access levels. // // GitLab API docs: https://docs.gitlab.com/ee/user/permissions.html const ( NoPermissions AccessLevelValue = 0 MinimalAccessPermissions AccessLevelValue = 5 GuestPermissions AccessLevelValue = 10 ReporterPermissions AccessLevelValue = 20 DeveloperPermissions AccessLevelValue = 30 MaintainerPermissions AccessLevelValue = 40 OwnerPermissions AccessLevelValue = 50 AdminPermissions AccessLevelValue = 60 // Deprecated: Renamed to MaintainerPermissions in GitLab 11.0. MasterPermissions AccessLevelValue = 40 // Deprecated: Renamed to OwnerPermissions. OwnerPermission AccessLevelValue = 50 ) // AccessLevel is a helper routine that allocates a new AccessLevelValue // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func AccessLevel(v AccessLevelValue) *AccessLevelValue { return Ptr(v) } // 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 interface{} } // ApproverIDs is a helper routine that creates a new ApproverIDsValue. func ApproverIDs(v interface{}) *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 interface{} } // AssigneeID is a helper routine that creates a new AssigneeIDValue. func AssigneeID(v interface{}) *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 interface{} } // ReviewerID is a helper routine that creates a new ReviewerIDValue. func ReviewerID(v interface{}) *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" ) // Availability is a helper routine that allocates a new AvailabilityValue // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func Availability(v AvailabilityValue) *AvailabilityValue { return Ptr(v) } // 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" ) // BuildState is a helper routine that allocates a new BuildStateValue // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func BuildState(v BuildStateValue) *BuildStateValue { return Ptr(v) } // CommentEventAction identifies if a comment has been newly created or updated. // // GitLab API docs: // https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#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/ee/api/container_registry.html#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" ) // 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" ) // DeploymentStatus is a helper routine that allocates a new // DeploymentStatusValue to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func DeploymentStatus(v DeploymentStatusValue) *DeploymentStatusValue { return Ptr(v) } // DORAMetricType represents all valid DORA metrics types. // // GitLab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html type DORAMetricType string // List of available DORA metric type names. // // GitLab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html 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/ee/api/dora/metrics.html type DORAMetricInterval string // List of available DORA metric interval types. // // GitLab API docs: https://docs.gitlab.com/ee/api/dora/metrics.html 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/ee/user/profile/contributions_calendar.html#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/ee/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" ) // FileActionValue represents the available actions that can be performed on a file. // // GitLab API docs: // https://docs.gitlab.com/ee/api/commits.html#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" ) // FileAction is a helper routine that allocates a new FileActionValue value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func FileAction(v FileActionValue) *FileActionValue { return Ptr(v) } // GenericPackageSelectValue represents a generic package select value. type GenericPackageSelectValue string // The available generic package select values. const ( SelectPackageFile GenericPackageSelectValue = "package_file" ) // GenericPackageSelect is a helper routine that allocates a new // GenericPackageSelectValue value to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func GenericPackageSelect(v GenericPackageSelectValue) *GenericPackageSelectValue { return Ptr(v) } // GenericPackageStatusValue represents a generic package status. type GenericPackageStatusValue string // The available generic package statuses. const ( PackageDefault GenericPackageStatusValue = "default" PackageHidden GenericPackageStatusValue = "hidden" ) // GenericPackageStatus is a helper routine that allocates a new // GenericPackageStatusValue value to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func GenericPackageStatus(v GenericPackageStatusValue) *GenericPackageStatusValue { return Ptr(v) } // 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 = []byte(fmt.Sprintf("[%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/ee/api/releases/links.html#create-a-release-link const ( ImageLinkType LinkTypeValue = "image" OtherLinkType LinkTypeValue = "other" PackageLinkType LinkTypeValue = "package" RunbookLinkType LinkTypeValue = "runbook" ) // LinkType is a helper routine that allocates a new LinkType value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func LinkType(v LinkTypeValue) *LinkTypeValue { return Ptr(v) } // LicenseApprovalStatusValue describe the approval statuses of a license. // // GitLab API docs: https://docs.gitlab.com/ee/api/managed_licenses.html type LicenseApprovalStatusValue string // List of available license approval statuses. const ( LicenseApproved LicenseApprovalStatusValue = "approved" LicenseBlacklisted LicenseApprovalStatusValue = "blacklisted" LicenseAllowed LicenseApprovalStatusValue = "allowed" LicenseDenied LicenseApprovalStatusValue = "denied" ) // LicenseApprovalStatus is a helper routine that allocates a new license // approval status value to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func LicenseApprovalStatus(v LicenseApprovalStatusValue) *LicenseApprovalStatusValue { return Ptr(v) } // MergeMethodValue represents a project merge type within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#project-merge-method type MergeMethodValue string // List of available merge type // // GitLab API docs: https://docs.gitlab.com/ee/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 store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func MergeMethod(v MergeMethodValue) *MergeMethodValue { return Ptr(v) } // 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" ) // NoteType is a helper routine that allocates a new NoteTypeValue to // store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func NoteType(v NoteTypeValue) *NoteTypeValue { return Ptr(v) } // 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. // // Deprecated: Please use Ptr instead. func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue { return Ptr(v) } // ProjectCreationLevelValue represents a project creation level within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/api/ type ProjectCreationLevelValue string // List of available project creation levels. // // GitLab API docs: https://docs.gitlab.com/ee/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. // Please use Ptr instead. func ProjectCreationLevel(v ProjectCreationLevelValue) *ProjectCreationLevelValue { return Ptr(v) } // ProjectHookEvent represents a project hook event. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#hook-events type ProjectHookEvent string // List of available project hook events. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#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/ee/ci/resource_groups/index.html#process-modes type ResourceGroupProcessMode string // List of available resource group process modes. // // GitLab API docs: // https://docs.gitlab.com/ee/ci/resource_groups/index.html#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/ee/api/groups.html#options-for-shared_runners_setting type SharedRunnersSettingValue string // List of available shared runner setting levels. // // GitLab API docs: // https://docs.gitlab.com/ee/api/groups.html#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" ) // SharedRunnersSetting is a helper routine that allocates a new SharedRunnersSettingValue // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func SharedRunnersSetting(v SharedRunnersSettingValue) *SharedRunnersSettingValue { return Ptr(v) } // SubGroupCreationLevelValue represents a sub group creation level within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/api/ type SubGroupCreationLevelValue string // List of available sub group creation levels. // // GitLab API docs: https://docs.gitlab.com/ee/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. // // Deprecated: Please use Ptr instead. func SubGroupCreationLevel(v SubGroupCreationLevelValue) *SubGroupCreationLevelValue { return Ptr(v) } // SquashOptionValue represents a squash optional level within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#create-project type SquashOptionValue string // List of available squash options. // // GitLab API docs: https://docs.gitlab.com/ee/api/projects.html#create-project const ( SquashOptionNever SquashOptionValue = "never" SquashOptionAlways SquashOptionValue = "always" SquashOptionDefaultOff SquashOptionValue = "default_off" SquashOptionDefaultOn SquashOptionValue = "default_on" ) // SquashOption is a helper routine that allocates a new SquashOptionValue // to store s and returns a pointer to it. // // Deprecated: Please use Ptr instead. func SquashOption(s SquashOptionValue) *SquashOptionValue { return Ptr(s) } // 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/ee/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" ) // TodoTargetType represents the available target that can be linked to a todo. // // GitLab API docs: https://docs.gitlab.com/ee/api/todos.html 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/ee/api/ type VariableTypeValue string // List of available variable types. // // GitLab API docs: https://docs.gitlab.com/ee/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. // // Deprecated: Please use Ptr instead. func VariableType(v VariableTypeValue) *VariableTypeValue { return Ptr(v) } // VisibilityValue represents a visibility level within GitLab. // // GitLab API docs: https://docs.gitlab.com/ee/api/ type VisibilityValue string // List of available visibility levels. // // GitLab API docs: https://docs.gitlab.com/ee/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. // // Deprecated: Please use Ptr instead. func Visibility(v VisibilityValue) *VisibilityValue { return Ptr(v) } // WikiFormatValue represents the available wiki formats. // // GitLab API docs: https://docs.gitlab.com/ee/api/wikis.html type WikiFormatValue string // The available wiki formats. const ( WikiFormatMarkdown WikiFormatValue = "markdown" WikiFormatRDoc WikiFormatValue = "rdoc" WikiFormatASCIIDoc WikiFormatValue = "asciidoc" WikiFormatOrg WikiFormatValue = "org" ) // WikiFormat is a helper routine that allocates a new WikiFormatValue // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func WikiFormat(v WikiFormatValue) *WikiFormatValue { return Ptr(v) } // Bool is a helper routine that allocates a new bool value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func Bool(v bool) *bool { return Ptr(v) } // Int is a helper routine that allocates a new int value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func Int(v int) *int { return Ptr(v) } // String is a helper routine that allocates a new string value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func String(v string) *string { return Ptr(v) } // Time is a helper routine that allocates a new time.Time value // to store v and returns a pointer to it. // // Deprecated: Please use Ptr instead. func Time(v time.Time) *time.Time { return Ptr(v) } // 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 } }
// // 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" "time" "github.com/hashicorp/go-retryablehttp" ) // 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") ) // UsersService handles communication with the user related methods of // the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/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"` 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"` } // 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/ee/api/users.html 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/ee/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"` ExcludeInternal *bool `url:"exclude_internal,omitempty" json:"exclude_internal,omitempty"` ExcludeExternal *bool `url:"exclude_external,omitempty" json:"exclude_external,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/ee/api/users.html#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/ee/api/users.html#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/ee/api/users.html#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/ee/api/users.html#user-creation 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/ee/api/users.html#user-creation 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/ee/api/users.html#user-modification 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/ee/api/users.html#user-modification 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/ee/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(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/ee/api/users.html#list-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/ee/api/users.html#user-status type UserStatus struct { Emoji string `json:"emoji"` Availability AvailabilityValue `json:"availability"` Message string `json:"message"` MessageHTML string `json:"message_html"` } // CurrentUserStatus retrieves the user status // // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#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 // // GitLab API docs: // https://docs.gitlab.com/ee/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(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/ee/api/users.html#set-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"` } // SetUserStatus sets the user's status // // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#set-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/ee/api/users.html#list-associations-count-for-user 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/ee/api/users.html#list-associations-count-for-user 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/ee/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"` ExpiresAt *time.Time `json:"expires_at"` } // ListSSHKeysOptions represents the available ListSSHKeys options. // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#list-ssh-keys type ListSSHKeysOptions ListOptions // ListSSHKeys gets a list of currently authenticated user's SSH keys. // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#list-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/ee/api/users.html#list-ssh-keys-for-user type ListSSHKeysForUserOptions ListOptions // ListSSHKeysForUser gets a list of a specified user's SSH keys. // // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#list-ssh-keys-for-user func (s *UsersService) ListSSHKeysForUser(uid interface{}, 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/ee/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(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/ee/api/users.html#single-ssh-key-for-given-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/ee/api/users.html#add-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"` } // AddSSHKey creates a new key owned by the currently authenticated user. // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#add-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/ee/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(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/ee/api/users.html#delete-ssh-key-for-current-user 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/ee/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(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/ee/api/users.html#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/ee/api/users.html#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/ee/api/users.html#get-a-specific-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/ee/api/users.html#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/ee/api/users.html#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/ee/api/users.html#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/ee/api/users.html#list-all-gpg-keys-for-given-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/ee/api/users.html#get-a-specific-gpg-key-for-a-given-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/ee/api/users.html#add-a-gpg-key-for-a-given-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/ee/api/users.html#delete-a-gpg-key-for-a-given-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/ee/api/users.html#list-emails 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/ee/api/users.html#list-emails 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/ee/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/ee/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(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/ee/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(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/ee/api/users.html#add-email 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/ee/api/users.html#add-email 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/ee/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(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/ee/api/users.html#delete-email-for-current-user 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/ee/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(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/ee/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(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/ee/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(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/ee/api/users.html#ban-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/ee/api/users.html#unban-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/ee/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(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/ee/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(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/ee/api/users.html#approve-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/ee/api/users.html#reject-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/ee/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"` LastUsedAt *time.Time `json:"last_used_at"` } // GetAllImpersonationTokensOptions represents the available // GetAllImpersonationTokens() options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(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/ee/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(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/ee/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/ee/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(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/ee/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(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/ee/api/users.html#create-a-personal-access-token type CreatePersonalAccessTokenOptions struct { Name *string `url:"name,omitempty" json:"name,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/ee/api/users.html#create-a-personal-access-token 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/ee/api/users.html#create-a-personal-access-token-with-limited-scopes-for-the-currently-authenticated-user type CreatePersonalAccessTokenForCurrentUserOptions 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"` } // CreatePersonalAccessTokenForCurrentUser creates a personal access token with limited scopes for the currently authenticated user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#create-a-personal-access-token-with-limited-scopes-for-the-currently-authenticated-user 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/ee/api/users.html#get-user-activities 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/ee/api/users.html#get-user-activities 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/ee/api/users.html#get-user-activities 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/ee/api/users.html#user-memberships 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: // ohttps://docs.gitlab.com/ee/api/users.html#user-memberships 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 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/ee/api/users.html#disable-two-factor-authentication 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/ee/api/users.html#create-a-runner 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/ee/api/users.html#create-a-runner 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/ee/api/users.html#create-a-runner 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 } // CreateServiceAccountUser creates a new service account user. Note only administrators can create new service account users. // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#create-service-account-user func (s *UsersService) CreateServiceAccountUser(options ...RequestOptionFunc) (*User, *Response, error) { req, err := s.client.NewRequest(http.MethodPost, "service_accounts", 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 } // UploadAvatar uploads an avatar to the current user. // // GitLab API docs: // https://docs.gitlab.com/ee/api/users.html#upload-a-current-user-avatar 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 }
// // 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" ) // ValidateService handles communication with the validation related methods of // the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/lint.html type ValidateService struct { client *Client } // LintResult represents the linting results. // // GitLab API docs: https://docs.gitlab.com/ee/api/lint.html 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/ee/api/lint.html#validate-a-projects-ci-configuration type ProjectLintResult struct { Valid bool `json:"valid"` Errors []string `json:"errors"` Warnings []string `json:"warnings"` MergedYaml string `json:"merged_yaml"` } // LintOptions represents the available Lint() options. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/lint.html#validate-the-ci-yaml-configuration type LintOptions struct { Content string `url:"content,omitempty" json:"content,omitempty"` IncludeMergedYAML bool `url:"include_merged_yaml,omitempty" json:"include_merged_yaml,omitempty"` IncludeJobs bool `url:"include_jobs,omitempty" json:"include_jobs,omitempty"` } // Lint validates .gitlab-ci.yml content. // Deprecated: This endpoint was removed in GitLab 16.0. // // Gitlab API docs: // https://docs.gitlab.com/ee/api/lint.html#validate-the-ci-yaml-configuration-deprecated func (s *ValidateService) Lint(opts *LintOptions, options ...RequestOptionFunc) (*LintResult, *Response, error) { req, err := s.client.NewRequest(http.MethodPost, "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 } // ProjectNamespaceLintOptions represents the available ProjectNamespaceLint() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/lint.html#validate-a-ci-yaml-configuration-with-a-namespace 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/ee/api/lint.html#validate-a-ci-yaml-configuration-with-a-namespace func (s *ValidateService) ProjectNamespaceLint(pid interface{}, 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/ee/api/lint.html#validate-a-projects-ci-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/ee/api/lint.html#validate-a-projects-ci-configuration func (s *ValidateService) ProjectLint(pid interface{}, 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 }
// // 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. // 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" // VersionService handles communication with the GitLab server instance to // retrieve its version information via the GitLab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/version.html type VersionService struct { client *Client } // Version represents a GitLab instance version. // // GitLab API docs: https://docs.gitlab.com/ee/api/version.html type Version struct { Version string `json:"version"` Revision string `json:"revision"` } func (s Version) String() string { return Stringify(s) } // GetVersion gets a GitLab server instance version; it is only available to // authenticated users. // // GitLab API docs: https://docs.gitlab.com/ee/api/version.html 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 } v := new(Version) resp, err := s.client.Do(req, v) if err != nil { return nil, resp, err } return v, resp, nil }
// // 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" "net/http" "net/url" ) // WikisService handles communication with the wikis related methods of // the Gitlab API. // // GitLab API docs: https://docs.gitlab.com/ee/api/wikis.html type WikisService struct { client *Client } // Wiki represents a GitLab wiki. // // GitLab API docs: https://docs.gitlab.com/ee/api/wikis.html 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) } // ListWikisOptions represents the available ListWikis options. // // GitLab API docs: // https://docs.gitlab.com/ee/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/ee/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(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/ee/api/wikis.html#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/ee/api/wikis.html#get-a-wiki-page func (s *WikisService) GetWikiPage(pid interface{}, 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/ee/api/wikis.html#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/ee/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(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/ee/api/wikis.html#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/ee/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(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/ee/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(http.MethodDelete, u, nil, options) if err != nil { return nil, err } return s.client.Do(req, nil) }