diff --git a/go.mod b/go.mod index 4e52038..899b61e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/sj14/review-bot require ( github.com/google/go-github/v25 v25.1.3 github.com/stretchr/testify v1.9.0 - github.com/xanzy/go-gitlab v0.106.0 + github.com/xanzy/go-gitlab v0.107.0 golang.org/x/oauth2 v0.21.0 ) diff --git a/go.sum b/go.sum index 5ec75ad..4db810c 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xanzy/go-gitlab v0.106.0 h1:EDfD03K74cIlQo2EducfiupVrip+Oj02bq9ofw5F8sA= -github.com/xanzy/go-gitlab v0.106.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/xanzy/go-gitlab v0.107.0 h1:P2CT9Uy9yN9lJo3FLxpMZ4xj6uWcpnigXsjvqJ6nd2Y= +github.com/xanzy/go-gitlab v0.107.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/vendor/github.com/xanzy/go-gitlab/group_members.go b/vendor/github.com/xanzy/go-gitlab/group_members.go index cc7bbd6..cdf225c 100644 --- a/vendor/github.com/xanzy/go-gitlab/group_members.go +++ b/vendor/github.com/xanzy/go-gitlab/group_members.go @@ -158,6 +158,32 @@ func (s *GroupMembersService) GetGroupMember(gid interface{}, user int, options 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 diff --git a/vendor/github.com/xanzy/go-gitlab/groups.go b/vendor/github.com/xanzy/go-gitlab/groups.go index 00c36c3..abad280 100644 --- a/vendor/github.com/xanzy/go-gitlab/groups.go +++ b/vendor/github.com/xanzy/go-gitlab/groups.go @@ -39,37 +39,42 @@ type GroupsService struct { // // 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"` - DefaultBranchProtection int `json:"default_branch_protection"` - 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 { + 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"` @@ -90,6 +95,17 @@ type Group struct { // 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. @@ -339,31 +355,46 @@ func (s *GroupsService) DownloadAvatar(gid interface{}, options ...RequestOption // // 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"` - DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection"` - 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"` + 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 @@ -468,34 +499,37 @@ func (s *GroupsService) TransferSubGroup(gid interface{}, opt *TransferSubGroupO // // 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"` - DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,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"` + 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 diff --git a/vendor/github.com/xanzy/go-gitlab/jobs.go b/vendor/github.com/xanzy/go-gitlab/jobs.go index 9ad0066..f25c020 100644 --- a/vendor/github.com/xanzy/go-gitlab/jobs.go +++ b/vendor/github.com/xanzy/go-gitlab/jobs.go @@ -516,9 +516,9 @@ type PlayJobOptions struct { // 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 *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` + 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. diff --git a/vendor/github.com/xanzy/go-gitlab/personal_access_tokens.go b/vendor/github.com/xanzy/go-gitlab/personal_access_tokens.go index 55bf330..e2ea2f5 100644 --- a/vendor/github.com/xanzy/go-gitlab/personal_access_tokens.go +++ b/vendor/github.com/xanzy/go-gitlab/personal_access_tokens.go @@ -129,12 +129,17 @@ type RotatePersonalAccessTokenOptions struct { ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"` } -// RotatePersonalAccessToken revokes a token and returns a new token that +// 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#rotate-a-personal-access-token -func (s *PersonalAccessTokensService) RotatePersonalAccessToken(token int, opt *RotatePersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) { +// 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) @@ -151,11 +156,38 @@ func (s *PersonalAccessTokensService) RotatePersonalAccessToken(token int, opt * return pat, resp, nil } -// RevokePersonalAccessToken revokes a personal access token. +// 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#revoke-a-personal-access-token +// 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) @@ -165,3 +197,19 @@ func (s *PersonalAccessTokensService) RevokePersonalAccessToken(token int, optio 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) +} diff --git a/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go b/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go index 85f32c3..51477f2 100644 --- a/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go +++ b/vendor/github.com/xanzy/go-gitlab/pipeline_schedules.go @@ -294,9 +294,9 @@ func (s *PipelineSchedulesService) RunPipelineSchedule(pid interface{}, schedule // 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 *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` + 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. @@ -330,8 +330,8 @@ func (s *PipelineSchedulesService) CreatePipelineScheduleVariable(pid interface{ // 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 *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` + Value *string `url:"value" json:"value"` + VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"` } // EditPipelineScheduleVariable creates a pipeline schedule variable. diff --git a/vendor/github.com/xanzy/go-gitlab/pipelines.go b/vendor/github.com/xanzy/go-gitlab/pipelines.go index 6dee9df..3f24484 100644 --- a/vendor/github.com/xanzy/go-gitlab/pipelines.go +++ b/vendor/github.com/xanzy/go-gitlab/pipelines.go @@ -34,9 +34,9 @@ type PipelinesService struct { // // GitLab API docs: https://docs.gitlab.com/ee/api/pipelines.html type PipelineVariable struct { - Key string `json:"key"` - Value string `json:"value"` - VariableType string `json:"variable_type"` + Key string `json:"key"` + Value string `json:"value"` + VariableType VariableTypeValue `json:"variable_type"` } // Pipeline represents a GitLab pipeline. @@ -309,9 +309,9 @@ type CreatePipelineOptions struct { // // 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 *string `url:"variable_type,omitempty" json:"variable_type,omitempty"` + 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. diff --git a/vendor/github.com/xanzy/go-gitlab/projects.go b/vendor/github.com/xanzy/go-gitlab/projects.go index 1b60129..cd69ae4 100644 --- a/vendor/github.com/xanzy/go-gitlab/projects.go +++ b/vendor/github.com/xanzy/go-gitlab/projects.go @@ -1411,6 +1411,33 @@ func (s *ProjectsService) DeleteProjectHook(pid interface{}, hook int, options . 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. // @@ -1521,6 +1548,7 @@ func (s *ProjectsService) DeleteProjectForkRelation(pid interface{}, options ... type ProjectFile struct { Alt string `json:"alt"` URL string `json:"url"` + FullPath string `json:"full_path"` Markdown string `json:"markdown"` } diff --git a/vendor/github.com/xanzy/go-gitlab/repository_files.go b/vendor/github.com/xanzy/go-gitlab/repository_files.go index 2f58b39..7ffaa93 100644 --- a/vendor/github.com/xanzy/go-gitlab/repository_files.go +++ b/vendor/github.com/xanzy/go-gitlab/repository_files.go @@ -215,6 +215,7 @@ func (s *RepositoryFilesService) GetFileBlame(pid interface{}, file string, opt // 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. diff --git a/vendor/github.com/xanzy/go-gitlab/services.go b/vendor/github.com/xanzy/go-gitlab/services.go index f630661..a7eeb72 100644 --- a/vendor/github.com/xanzy/go-gitlab/services.go +++ b/vendor/github.com/xanzy/go-gitlab/services.go @@ -1174,16 +1174,22 @@ func (s *ServicesService) GetJiraService(pid interface{}, options ...RequestOpti // 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"` - ProjectKeys *[]string `url:"project_keys,comma,omitempty" json:"project_keys,omitempty" ` - Username *string `url:"username,omitempty" json:"username,omitempty" ` - Password *string `url:"password,omitempty" json:"password,omitempty" ` - Active *bool `url:"active,omitempty" json:"active,omitempty"` - JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"` - CommitEvents *bool `url:"commit_events,omitempty" json:"commit_events,omitempty"` - MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"` - CommentOnEventEnabled *bool `url:"comment_on_event_enabled,omitempty" json:"comment_on_event_enabled,omitempty"` + 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" ` diff --git a/vendor/github.com/xanzy/go-gitlab/types.go b/vendor/github.com/xanzy/go-gitlab/types.go index 5f0e98b..9ce13d7 100644 --- a/vendor/github.com/xanzy/go-gitlab/types.go +++ b/vendor/github.com/xanzy/go-gitlab/types.go @@ -697,6 +697,29 @@ func ProjectCreationLevel(v ProjectCreationLevelValue) *ProjectCreationLevelValu 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. // diff --git a/vendor/github.com/xanzy/go-gitlab/users.go b/vendor/github.com/xanzy/go-gitlab/users.go index 5ad87ca..224dc42 100644 --- a/vendor/github.com/xanzy/go-gitlab/users.go +++ b/vendor/github.com/xanzy/go-gitlab/users.go @@ -17,11 +17,15 @@ package gitlab import ( + "encoding/json" "errors" "fmt" + "io" "net" "net/http" "time" + + "github.com/hashicorp/go-retryablehttp" ) // List a couple of standard errors. @@ -112,6 +116,23 @@ type UserIdentity struct { 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 @@ -188,37 +209,53 @@ func (s *UsersService) GetUser(user int, opt GetUsersOptions, options ...Request // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#user-creation type CreateUserOptions struct { - Email *string `url:"email,omitempty" json:"email,omitempty"` - Password *string `url:"password,omitempty" json:"password,omitempty"` - ResetPassword *bool `url:"reset_password,omitempty" json:"reset_password,omitempty"` - ForceRandomPassword *bool `url:"force_random_password,omitempty" json:"force_random_password,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Skype *string `url:"skype,omitempty" json:"skype,omitempty"` - Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` - Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` - WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` - Organization *string `url:"organization,omitempty" json:"organization,omitempty"` - JobTitle *string `url:"job_title,omitempty" json:"job_title,omitempty"` - ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` - ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` - Bio *string `url:"bio,omitempty" json:"bio,omitempty"` - Location *string `url:"location,omitempty" json:"location,omitempty"` - Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` - CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` - SkipConfirmation *bool `url:"skip_confirmation,omitempty" json:"skip_confirmation,omitempty"` - External *bool `url:"external,omitempty" json:"external,omitempty"` - PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` - Note *string `url:"note,omitempty" json:"note,omitempty"` - ThemeID *int `url:"theme_id,omitempty" json:"theme_id,omitempty"` + 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) { - req, err := s.client.NewRequest(http.MethodPost, "users", opt, options) + 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 } @@ -236,30 +273,31 @@ func (s *UsersService) CreateUser(opt *CreateUserOptions, options ...RequestOpti // // GitLab API docs: https://docs.gitlab.com/ee/api/users.html#user-modification type ModifyUserOptions struct { - Email *string `url:"email,omitempty" json:"email,omitempty"` - Password *string `url:"password,omitempty" json:"password,omitempty"` - Username *string `url:"username,omitempty" json:"username,omitempty"` - Name *string `url:"name,omitempty" json:"name,omitempty"` - Skype *string `url:"skype,omitempty" json:"skype,omitempty"` - Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"` - Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"` - WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"` - Organization *string `url:"organization,omitempty" json:"organization,omitempty"` - JobTitle *string `url:"job_title,omitempty" json:"job_title,omitempty"` - ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"` - ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"` - Provider *string `url:"provider,omitempty" json:"provider,omitempty"` - Bio *string `url:"bio,omitempty" json:"bio,omitempty"` - Location *string `url:"location,omitempty" json:"location,omitempty"` - Admin *bool `url:"admin,omitempty" json:"admin,omitempty"` - CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"` - SkipReconfirmation *bool `url:"skip_reconfirmation,omitempty" json:"skip_reconfirmation,omitempty"` - External *bool `url:"external,omitempty" json:"external,omitempty"` - PrivateProfile *bool `url:"private_profile,omitempty" json:"private_profile,omitempty"` - Note *string `url:"note,omitempty" json:"note,omitempty"` - ThemeID *int `url:"theme_id,omitempty" json:"theme_id,omitempty"` - PublicEmail *string `url:"public_email,omitempty" json:"public_email,omitempty"` - CommitEmail *string `url:"commit_email,omitempty" json:"commit_email,omitempty"` + 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 @@ -267,9 +305,23 @@ type ModifyUserOptions struct { // // 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) - req, err := s.client.NewRequest(http.MethodPut, u, opt, options) + 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 } @@ -1507,3 +1559,32 @@ func (s *UsersService) CreateServiceAccountUser(options ...RequestOptionFunc) (* 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 +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 16b5259..67a1660 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -20,7 +20,7 @@ github.com/pmezard/go-difflib/difflib ## explicit; go 1.17 github.com/stretchr/testify/assert github.com/stretchr/testify/require -# github.com/xanzy/go-gitlab v0.106.0 +# github.com/xanzy/go-gitlab v0.107.0 ## explicit; go 1.19 github.com/xanzy/go-gitlab # golang.org/x/oauth2 v0.21.0