diff --git a/Makefile b/Makefile index e82a9d3..92bfc1e 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,11 @@ GO_IMAGE = golang:1.10.3 MODD_VERSION = 0.5 GO_PKG_SRC_PATH = "github.com/plouc/go-gitlab-client" -SHA1 = $(shell git rev-parse HEAD) OS = $(shell uname) +GIT_SHA = $(shell git rev-parse HEAD) +GIT_REF ?= $(shell git symbolic-ref -q --short HEAD) + #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- # # HELP diff --git a/gitlab/badges.go b/gitlab/badges.go index 174f6b0..68be8ef 100644 --- a/gitlab/badges.go +++ b/gitlab/badges.go @@ -2,12 +2,11 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - projectBadgesUrl = "/projects/:id/badges" - projectBadgeUrl = "/projects/:id/badges/:badge_id" + ProjectBadgesApiPath = "/projects/:id/badges" + ProjectBadgeApiPath = "/projects/:id/badges/:badge_id" ) type Badge struct { @@ -20,20 +19,7 @@ type Badge struct { } func (g *Gitlab) ProjectBadges(projectId string, o *PaginationOptions) ([]*Badge, *ResponseMeta, error) { - u := g.ResourceUrl(projectBadgesUrl, map[string]string{":id": projectId}) - - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(ProjectBadgesApiPath, map[string]string{":id": projectId}, o) var badges []*Badge @@ -46,7 +32,7 @@ func (g *Gitlab) ProjectBadges(projectId string, o *PaginationOptions) ([]*Badge } func (g *Gitlab) ProjectBadge(projectId, badgeId string) (*Badge, *ResponseMeta, error) { - u := g.ResourceUrl(projectBadgeUrl, map[string]string{ + u := g.ResourceUrl(ProjectBadgeApiPath, map[string]string{ ":id": projectId, ":badge_id": badgeId, }) @@ -62,7 +48,7 @@ func (g *Gitlab) ProjectBadge(projectId, badgeId string) (*Badge, *ResponseMeta, } func (g *Gitlab) AddProjectBadge(projectId string, badge *Badge) (*Badge, *ResponseMeta, error) { - u := g.ResourceUrl(projectBadgesUrl, map[string]string{":id": projectId}) + u := g.ResourceUrl(ProjectBadgesApiPath, map[string]string{":id": projectId}) badgeJson, err := json.Marshal(badge) if err != nil { @@ -79,7 +65,7 @@ func (g *Gitlab) AddProjectBadge(projectId string, badge *Badge) (*Badge, *Respo } func (g *Gitlab) RemoveProjectBadge(projectId, badgeId string) (*ResponseMeta, error) { - u := g.ResourceUrl(projectBadgeUrl, map[string]string{ + u := g.ResourceUrl(ProjectBadgeApiPath, map[string]string{ ":id": projectId, ":badge_id": badgeId, }) diff --git a/gitlab/branches.go b/gitlab/branches.go index 68429dd..54724cd 100644 --- a/gitlab/branches.go +++ b/gitlab/branches.go @@ -2,13 +2,12 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - projectBranchesUrl = "/projects/:id/repository/branches" // List repository branches. - projectBranchUrl = "/projects/:id/repository/branches/:branch" // Get a specific branch of a project. - projectMergedBranchesUrl = "/projects/:id/repository/merged_branches" + ProjectBranchesApiPath = "/projects/:id/repository/branches" + ProjectBranchApiPath = "/projects/:id/repository/branches/:branch" + ProjectMergedBranchesApiPath = "/projects/:id/repository/merged_branches" ) type BranchCommit struct { @@ -32,27 +31,14 @@ type Branch struct { type BranchesOptions struct { PaginationOptions - Search string // Return list of branches matching the search criteria + SortOptions + + // Return list of branches matching the search criteria + Search string `url:"search,omitempty"` } func (g *Gitlab) ProjectBranches(projectId string, o *BranchesOptions) ([]*Branch, *ResponseMeta, error) { - u := g.ResourceUrl(projectBranchesUrl, map[string]string{":id": projectId}) - - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Search != "" { - q.Set("search", o.Search) - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(ProjectBranchesApiPath, map[string]string{":id": projectId}, o) var branches []*Branch @@ -65,7 +51,7 @@ func (g *Gitlab) ProjectBranches(projectId string, o *BranchesOptions) ([]*Branc } func (g *Gitlab) ProjectBranch(projectId, branchName string) (*Branch, *ResponseMeta, error) { - u := g.ResourceUrl(projectBranchUrl, map[string]string{ + u := g.ResourceUrl(ProjectBranchApiPath, map[string]string{ ":id": projectId, ":branch": branchName, }) @@ -81,7 +67,8 @@ func (g *Gitlab) ProjectBranch(projectId, branchName string) (*Branch, *Response } func (g *Gitlab) AddProjectBranch(projectId string, branchName, ref string) (*Branch, *ResponseMeta, error) { - u := g.ResourceUrl(projectBranchesUrl, map[string]string{":id": projectId}) + u := g.ResourceUrl(ProjectBranchesApiPath, map[string]string{":id": projectId}) + q := u.Query() q.Set("branch", branchName) q.Set("ref", ref) @@ -97,7 +84,7 @@ func (g *Gitlab) AddProjectBranch(projectId string, branchName, ref string) (*Br } func (g *Gitlab) RemoveProjectBranch(projectId, branchName string) (*ResponseMeta, error) { - u := g.ResourceUrl(projectBranchUrl, map[string]string{ + u := g.ResourceUrl(ProjectBranchApiPath, map[string]string{ ":id": projectId, ":branch": branchName, }) @@ -109,7 +96,7 @@ func (g *Gitlab) RemoveProjectBranch(projectId, branchName string) (*ResponseMet } func (g *Gitlab) RemoveProjectMergedBranches(projectId string) (string, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergedBranchesUrl, map[string]string{":id": projectId}) + u := g.ResourceUrl(ProjectMergedBranchesApiPath, map[string]string{":id": projectId}) var responseWithMessage *ResponseWithMessage contents, meta, err := g.buildAndExecRequest("DELETE", u.String(), nil) diff --git a/gitlab/builds.go b/gitlab/builds.go index 2ad3017..d3ab7fb 100644 --- a/gitlab/builds.go +++ b/gitlab/builds.go @@ -6,8 +6,8 @@ import ( ) const ( - projectCommitBuildsUrl = "/projects/:id/repository/commits/:sha/builds" - projectBuildArtifactsUrl = "/projects/:id/builds/:build_id/artifacts" + ProjectCommitBuildsApiPath = "/projects/:id/repository/commits/:sha/builds" + ProjectBuildArtifactsApiPath = "/projects/:id/builds/:build_id/artifacts" ) type ArtifactsFile struct { @@ -34,7 +34,7 @@ type Build struct { } func (g *Gitlab) ProjectCommitBuilds(id, sha1 string) ([]*Build, *ResponseMeta, error) { - u := g.ResourceUrl(projectCommitBuildsUrl, map[string]string{ + u := g.ResourceUrl(ProjectCommitBuildsApiPath, map[string]string{ ":id": id, ":sha": sha1, }) @@ -52,7 +52,7 @@ func (g *Gitlab) ProjectCommitBuilds(id, sha1 string) ([]*Build, *ResponseMeta, } func (g *Gitlab) ProjectBuildArtifacts(id, buildId string) (io.ReadCloser, error) { - u := g.ResourceUrl(projectBuildArtifactsUrl, map[string]string{ + u := g.ResourceUrl(ProjectBuildArtifactsApiPath, map[string]string{ ":id": id, ":build_id": buildId, }) diff --git a/gitlab/commits.go b/gitlab/commits.go index 7b20423..2a8b7f5 100644 --- a/gitlab/commits.go +++ b/gitlab/commits.go @@ -6,7 +6,7 @@ import ( ) const ( - projectCommitStatusesUrl = "/projects/:id/repository/commits/:sha/statuses" + ProjectCommitStatusesApiPath = "/projects/:id/repository/commits/:sha/statuses" ) type CommitStatus struct { @@ -25,7 +25,7 @@ type CommitStatus struct { } func (g *Gitlab) ProjectCommitStatuses(id, sha1 string) ([]*CommitStatus, *ResponseMeta, error) { - u := g.ResourceUrl(projectCommitStatusesUrl, map[string]string{ + u := g.ResourceUrl(ProjectCommitStatusesApiPath, map[string]string{ ":id": id, ":sha": sha1, }) diff --git a/gitlab/deploy_keys.go b/gitlab/deploy_keys.go index 7960800..769e3ed 100644 --- a/gitlab/deploy_keys.go +++ b/gitlab/deploy_keys.go @@ -6,8 +6,8 @@ import ( ) const ( - projectDeployKeysUrl = "/projects/:id/keys" - projectDeployKeyUrl = "/projects/:id/keys/:key_id" + ProjectDeployKeysApiPath = "/projects/:id/keys" + ProjectDeployKeyApiPath = "/projects/:id/keys/:key_id" ) /* @@ -21,7 +21,7 @@ Parameters: */ func (g *Gitlab) ProjectDeployKeys(id string) ([]*PublicKey, *ResponseMeta, error) { - u := g.ResourceUrl(projectDeployKeysUrl, map[string]string{":id": id}) + u := g.ResourceUrl(ProjectDeployKeysApiPath, map[string]string{":id": id}) var deployKeys []*PublicKey @@ -45,7 +45,7 @@ Parameters: */ func (g *Gitlab) ProjectDeployKey(id, keyId string) (*PublicKey, *ResponseMeta, error) { - u := g.ResourceUrl(projectDeployKeyUrl, map[string]string{ + u := g.ResourceUrl(ProjectDeployKeyApiPath, map[string]string{ ":id": id, ":key_id": keyId, }) @@ -73,7 +73,7 @@ Parameters: */ func (g *Gitlab) AddProjectDeployKey(id, title, key string) (*ResponseMeta, error) { - u := g.ResourceUrl(projectDeployKeysUrl, map[string]string{":id": id}) + u := g.ResourceUrl(ProjectDeployKeysApiPath, map[string]string{":id": id}) var err error @@ -100,7 +100,7 @@ Parameters: */ func (g *Gitlab) RemoveProjectDeployKey(id, keyId string) (*ResponseMeta, error) { - u := g.ResourceUrl(projectDeployKeyUrl, map[string]string{ + u := g.ResourceUrl(ProjectDeployKeyApiPath, map[string]string{ ":id": id, ":key_id": keyId, }) diff --git a/gitlab/events.go b/gitlab/events.go index 714bb88..881fab7 100644 --- a/gitlab/events.go +++ b/gitlab/events.go @@ -35,8 +35,7 @@ type FeedCommit struct { } func (g *Gitlab) Activity() (ActivityFeed, error) { - url := g.BaseUrl + dashboardFeedPath + "?private_token=" + g.Token - fmt.Println(url) + url := g.BaseUrl + DashboardFeedPath + "?private_token=" + g.Token contents, _, err := g.buildAndExecRequest("GET", url, nil) if err != nil { diff --git a/gitlab/gitlab.go b/gitlab/gitlab.go index c2c902d..2c21d5b 100644 --- a/gitlab/gitlab.go +++ b/gitlab/gitlab.go @@ -11,10 +11,12 @@ import ( "net/url" "strconv" "strings" + + "github.com/google/go-querystring/query" ) const ( - dashboardFeedPath = "/dashboard.atom" + DashboardFeedPath = "/dashboard.atom" ) type Gitlab struct { @@ -26,8 +28,8 @@ type Gitlab struct { } type PaginationOptions struct { - Page int - PerPage int + Page int `url:"page,omitempty"` + PerPage int `url:"per_page,omitempty"` } type SortDirection string @@ -37,6 +39,11 @@ const ( SortDirectionDesc SortDirection = "desc" ) +type SortOptions struct { + OrderBy string `url:"order_by,omitempty"` + Sort SortDirection `url:"sort,omitempty"` +} + type ResponseWithMessage struct { Message string `json:"message"` } @@ -64,6 +71,7 @@ var ( `If set to true, gitlab client will skip certificate checking for https, possibly exposing your system to MITM attack.`) ) +// NewGitlab generates a new gitlab service func NewGitlab(baseUrl, apiPath, token string) *Gitlab { config := &tls.Config{InsecureSkipVerify: *skipCertVerify} tr := &http.Transport{ @@ -80,16 +88,38 @@ func NewGitlab(baseUrl, apiPath, token string) *Gitlab { } } -func (g *Gitlab) ResourceUrl(p string, params map[string]string) *url.URL { +// ResourceUrl builds an url for given resource path. +// +// It replaces path placeholders with values from `params`: +// +// /whatever/:id => /whatever/1 +// +func (g *Gitlab) ResourceUrl(path string, params map[string]string) *url.URL { if params != nil { for key, val := range params { - p = strings.Replace(p, key, val, -1) + path = strings.Replace(path, key, val, -1) } } - u, err := url.Parse(g.BaseUrl + g.ApiPath + p) + u, err := url.Parse(g.BaseUrl + g.ApiPath + path) if err != nil { - panic("Error while building gitlab url") + panic("Error while building gitlab url, unable to parse generated url") + } + + return u +} + +// ResourceUrlQ generates an url and appends a query string to it if available +func (g *Gitlab) ResourceUrlQ(path string, params map[string]string, qs interface{}) *url.URL { + u := g.ResourceUrl(path, params) + + if qs != nil { + v, err := query.Values(qs) + if err != nil { + panic("Error while building gitlab url, unable to set query string") + } + + u.RawQuery = v.Encode() } return u diff --git a/gitlab/gitlab_test.go b/gitlab/gitlab_test.go index ad61a7e..144aa39 100644 --- a/gitlab/gitlab_test.go +++ b/gitlab/gitlab_test.go @@ -10,12 +10,12 @@ func TestResourceUrl(t *testing.T) { assert.Equal( t, - gitlab.ResourceUrl(projectsUrl, nil).String(), + gitlab.ResourceUrl(ProjectsApiPath, nil).String(), "http://base_url/api_path/projects", ) assert.Equal( t, - gitlab.ResourceUrl(projectUrl, map[string]string{":id": "123"}).String(), + gitlab.ResourceUrl(ProjectApiPath, map[string]string{":id": "123"}).String(), "http://base_url/api_path/projects/123", ) } diff --git a/gitlab/groups.go b/gitlab/groups.go index 48ac029..3c87d19 100644 --- a/gitlab/groups.go +++ b/gitlab/groups.go @@ -2,14 +2,12 @@ package gitlab import ( "encoding/json" - "strconv" - "strings" ) const ( - groupsUrl = "/groups" - groupUrl = "/groups/:id" - groupProjectsUrl = "/groups/:id/projects" + GroupsApiPath = "/groups" + GroupApiPath = "/groups/:id" + GroupProjectsApiPath = "/groups/:id/projects" ) type Group struct { @@ -36,48 +34,30 @@ type GroupWithDetails struct { type GroupsOptions struct { PaginationOptions - SkipGroups []string // Skip the group IDs passed - AllAvailable bool //Show all the groups you have access to (defaults to false for authenticated users, true for admin) - Search string // Return the list of authorized groups matching the search criteria - Statistics bool // Include group statistics (admins only) - WithCustomAttributes bool // Include custom attributes in response (admins only) - Owned bool // Limit to groups owned by the current user - // order_by string no Order groups by name, path or id. Default is name - // sort string no Order groups in asc or desc order. Default is asc + SortOptions + + // Skip the group IDs passed + SkipGroups []string `url:"skip_groups,omitempty,comma"` + + // Show all the groups you have access to + // (defaults to false for authenticated users, true for admin) + AllAvailable bool `url:"all_available,omitempty"` + + // Return the list of authorized groups matching the search criteria + Search string `url:"search,omitempty"` + + // Include group statistics (admins only) + Statistics bool `url:"statistics,omitempty"` + + // Include custom attributes in response (admins only) + WithCustomAttributes bool `url:"with_custom_attributes,omitempty"` + + // Limit to groups owned by the current user + Owned bool `url:"owned,omitempty"` } func (g *Gitlab) Groups(o *GroupsOptions) ([]*Group, *ResponseMeta, error) { - u := g.ResourceUrl(groupsUrl, nil) - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if len(o.SkipGroups) > 0 { - q.Set("skip_groups", strings.Join(o.SkipGroups, ",")) - } - if o.AllAvailable { - q.Set("all_available", "true") - } - if o.Search != "" { - q.Set("search", o.Search) - } - if o.Statistics { - q.Set("statistics", "true") - } - if o.WithCustomAttributes { - q.Set("with_custom_attributes", "true") - } - if o.Owned { - q.Set("owned", "true") - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(GroupsApiPath, nil, o) var groups []*Group @@ -90,7 +70,7 @@ func (g *Gitlab) Groups(o *GroupsOptions) ([]*Group, *ResponseMeta, error) { } func (g *Gitlab) Group(id string, withCustomAttributes bool) (*GroupWithDetails, *ResponseMeta, error) { - u := g.ResourceUrl(groupUrl, map[string]string{":id": id}) + u := g.ResourceUrl(GroupApiPath, map[string]string{":id": id}) q := u.Query() if withCustomAttributes { @@ -121,7 +101,7 @@ type GroupAddPayload struct { } func (g *Gitlab) AddGroup(group *GroupAddPayload) (*GroupWithDetails, *ResponseMeta, error) { - u := g.ResourceUrl(groupsUrl, nil) + u := g.ResourceUrl(GroupsApiPath, nil) encodedRequest, err := json.Marshal(group) if err != nil { @@ -151,7 +131,7 @@ type GroupUpdatePayload struct { } func (g *Gitlab) UpdateGroup(id string, group *GroupUpdatePayload) (*GroupWithDetails, error) { - u := g.ResourceUrl(groupUrl, map[string]string{":id": id}) + u := g.ResourceUrl(GroupApiPath, map[string]string{":id": id}) encodedRequest, err := json.Marshal(group) if err != nil { @@ -168,7 +148,7 @@ func (g *Gitlab) UpdateGroup(id string, group *GroupUpdatePayload) (*GroupWithDe } func (g *Gitlab) RemoveGroup(id string) (string, *ResponseMeta, error) { - u := g.ResourceUrl(groupUrl, map[string]string{":id": id}) + u := g.ResourceUrl(GroupApiPath, map[string]string{":id": id}) var responseWithMessage *ResponseWithMessage contents, meta, err := g.buildAndExecRequest("DELETE", u.String(), nil) @@ -182,7 +162,7 @@ func (g *Gitlab) RemoveGroup(id string) (string, *ResponseMeta, error) { } func (g *Gitlab) GroupProjects(id string) ([]*Project, *ResponseMeta, error) { - u := g.ResourceUrl(groupProjectsUrl, map[string]string{":id": id}) + u := g.ResourceUrl(GroupProjectsApiPath, map[string]string{":id": id}) var projects []*Project diff --git a/gitlab/hooks.go b/gitlab/hooks.go index 56edb17..91c67a6 100644 --- a/gitlab/hooks.go +++ b/gitlab/hooks.go @@ -5,8 +5,8 @@ import ( ) const ( - projectHooksUrl = "/projects/:id/hooks" - projectHookUrl = "/projects/:id/hooks/:hook_id" + ProjectHooksApiPath = "/projects/:id/hooks" + ProjectHookApiPath = "/projects/:id/hooks/:hook_id" ) type HookAddPayload struct { @@ -32,7 +32,7 @@ type Hook struct { } func (g *Gitlab) ProjectHooks(projectId string) ([]*Hook, *ResponseMeta, error) { - u := g.ResourceUrl(projectHooksUrl, map[string]string{":id": projectId}) + u := g.ResourceUrl(ProjectHooksApiPath, map[string]string{":id": projectId}) var err error var hooks []*Hook @@ -48,7 +48,7 @@ func (g *Gitlab) ProjectHooks(projectId string) ([]*Hook, *ResponseMeta, error) } func (g *Gitlab) ProjectHook(projectId, hookId string) (*Hook, *ResponseMeta, error) { - u := g.ResourceUrl(projectHookUrl, map[string]string{ + u := g.ResourceUrl(ProjectHookApiPath, map[string]string{ ":id": projectId, ":hook_id": hookId, }) @@ -67,7 +67,7 @@ func (g *Gitlab) ProjectHook(projectId, hookId string) (*Hook, *ResponseMeta, er } func (g *Gitlab) AddProjectHook(projectId string, hook *HookAddPayload) (*Hook, *ResponseMeta, error) { - u := g.ResourceUrl(projectHooksUrl, map[string]string{":id": projectId}) + u := g.ResourceUrl(ProjectHooksApiPath, map[string]string{":id": projectId}) hookJson, err := json.Marshal(hook) if err != nil { @@ -85,7 +85,7 @@ func (g *Gitlab) AddProjectHook(projectId string, hook *HookAddPayload) (*Hook, /* func (g *Gitlab) UpdateProjectHook(id, hook_id, hook_url string, push_events, issues_events, merge_requests_events bool) (*ResponseMeta, error) { - u := g.ResourceUrl(projectHookUrl, map[string]string{ + u := g.ResourceUrl(ProjectHookApiPath, map[string]string{ ":id": id, ":hook_id": hook_id, }) @@ -100,7 +100,7 @@ func (g *Gitlab) UpdateProjectHook(id, hook_id, hook_url string, push_events, is */ func (g *Gitlab) RemoveProjectHook(projectId, hookId string) (*ResponseMeta, error) { - u := g.ResourceUrl(projectHookUrl, map[string]string{ + u := g.ResourceUrl(ProjectHookApiPath, map[string]string{ ":id": projectId, ":hook_id": hookId, }) diff --git a/gitlab/issue.go b/gitlab/issues.go similarity index 93% rename from gitlab/issue.go rename to gitlab/issues.go index 98c535b..7ec30a6 100644 --- a/gitlab/issue.go +++ b/gitlab/issues.go @@ -5,7 +5,7 @@ import ( ) const ( - projectIssuesUrl = "/projects/:id/issues" + ProjectIssuesApiPath = "/projects/:id/issues" ) type Issue struct { @@ -35,7 +35,7 @@ func (g *Gitlab) AddIssue(projectId string, req *IssueRequest) (issue *Issue, me params := map[string]string{ ":id": projectId, } - u := g.ResourceUrl(projectIssuesUrl, params) + u := g.ResourceUrl(ProjectIssuesApiPath, params) encodedRequest, err := json.Marshal(req) if err != nil { diff --git a/gitlab/jobs.go b/gitlab/jobs.go index 09ad80d..1ac4f3b 100644 --- a/gitlab/jobs.go +++ b/gitlab/jobs.go @@ -5,17 +5,16 @@ import ( "fmt" "net/url" "strconv" - "strings" ) const ( - projectJobsUrl = "/projects/:id/jobs" - projectPipelineJobsUrl = "/projects/:id/pipelines/:pipeline_id/jobs" - projectJobUrl = "/projects/:id/jobs/:job_id" - projectJobTraceUrl = "/projects/:id/jobs/:job_id/trace" - cancelProjectJobUrl = "/projects/:id/jobs/:job_id/cancel" - retryProjectJobUrl = "/projects/:id/jobs/:job_id/retry" - eraseProjectJobUrl = "/projects/:id/jobs/:job_id/erase" + ProjectJobsApiPath = "/projects/:id/jobs" + ProjectPipelineJobsApiPath = "/projects/:id/pipelines/:pipeline_id/jobs" + ProjectJobApiPath = "/projects/:id/jobs/:job_id" + ProjectJobTraceApiPath = "/projects/:id/jobs/:job_id/trace" + CancelProjectJobApiPath = "/projects/:id/jobs/:job_id/cancel" + RetryProjectJobApiPath = "/projects/:id/jobs/:job_id/retry" + EraseProjectJobApiPath = "/projects/:id/jobs/:job_id/erase" ) type Job struct { @@ -81,29 +80,15 @@ type Job struct { type JobsOptions struct { PaginationOptions + SortOptions + // The scope of jobs to show, one or array of: // created, pending, running, failed, success, canceled, skipped, manual; // showing all jobs if none provided - Scope []string + Scope []string `url:"scope,omitempty"` } -func (g *Gitlab) getJobs(u *url.URL, o *JobsOptions) ([]*Job, *ResponseMeta, error) { - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if len(o.Scope) > 0 { - q.Set("scope", strings.Join(o.Scope, ",")) - } - - u.RawQuery = q.Encode() - } - +func (g *Gitlab) getJobs(u *url.URL) ([]*Job, *ResponseMeta, error) { jobs := make([]*Job, 0) contents, meta, err := g.buildAndExecRequest("GET", u.String(), nil) @@ -117,24 +102,24 @@ func (g *Gitlab) getJobs(u *url.URL, o *JobsOptions) ([]*Job, *ResponseMeta, err } func (g *Gitlab) ProjectJobs(projectId string, o *JobsOptions) ([]*Job, *ResponseMeta, error) { - u := g.ResourceUrl(projectJobsUrl, map[string]string{ + u := g.ResourceUrlQ(ProjectJobsApiPath, map[string]string{ ":id": projectId, - }) + }, o) - return g.getJobs(u, o) + return g.getJobs(u) } func (g *Gitlab) ProjectPipelineJobs(projectId string, pipelineId int, o *JobsOptions) ([]*Job, *ResponseMeta, error) { - u := g.ResourceUrl(projectPipelineJobsUrl, map[string]string{ + u := g.ResourceUrlQ(ProjectPipelineJobsApiPath, map[string]string{ ":id": projectId, ":pipeline_id": fmt.Sprintf("%d", pipelineId), - }) + }, o) - return g.getJobs(u, o) + return g.getJobs(u) } func (g *Gitlab) ProjectJob(projectId string, jobId int) (*Job, *ResponseMeta, error) { - u := g.ResourceUrl(projectJobUrl, map[string]string{ + u := g.ResourceUrl(ProjectJobApiPath, map[string]string{ ":id": projectId, ":job_id": strconv.Itoa(jobId), }) @@ -152,7 +137,7 @@ func (g *Gitlab) ProjectJob(projectId string, jobId int) (*Job, *ResponseMeta, e } func (g *Gitlab) ProjectJobTrace(projectId string, jobId int) (string, *ResponseMeta, error) { - u := g.ResourceUrl(projectJobTraceUrl, map[string]string{ + u := g.ResourceUrl(ProjectJobTraceApiPath, map[string]string{ ":id": projectId, ":job_id": strconv.Itoa(jobId), }) @@ -184,15 +169,15 @@ func (g *Gitlab) projectJobAction(path, projectId string, jobId int) (*Job, *Res } func (g *Gitlab) CancelProjectJob(projectId string, jobId int) (*Job, *ResponseMeta, error) { - return g.projectJobAction(cancelProjectJobUrl, projectId, jobId) + return g.projectJobAction(CancelProjectJobApiPath, projectId, jobId) } func (g *Gitlab) RetryProjectJob(projectId string, jobId int) (*Job, *ResponseMeta, error) { - return g.projectJobAction(retryProjectJobUrl, projectId, jobId) + return g.projectJobAction(RetryProjectJobApiPath, projectId, jobId) } func (g *Gitlab) EraseProjectJob(projectId string, jobId int) (*Job, *ResponseMeta, error) { - return g.projectJobAction(eraseProjectJobUrl, projectId, jobId) + return g.projectJobAction(EraseProjectJobApiPath, projectId, jobId) } // Aggregate jobs by: diff --git a/gitlab/members.go b/gitlab/members.go index 6621458..3b25420 100644 --- a/gitlab/members.go +++ b/gitlab/members.go @@ -2,12 +2,11 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - membersUrl = "/:type/:id/members" // List group or project team members - memberUrl = "/:type/:id/members/:user_id" // Get group or project team member + MambersApiPath = "/:type/:id/members" // List group or project team members + MamberApiPath = "/:type/:id/members/:user_id" // Get group or project team member ) type Member struct { @@ -24,29 +23,15 @@ type Member struct { type MembersOptions struct { PaginationOptions - Query string + + Query string `url:"query,omitempty"` } func (g *Gitlab) getResourceMembers(resourceType, projectId string, o *MembersOptions) ([]*Member, *ResponseMeta, error) { - u := g.ResourceUrl(membersUrl, map[string]string{ + u := g.ResourceUrlQ(MambersApiPath, map[string]string{ ":type": resourceType, ":id": projectId, - }) - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Query != "" { - q.Set("query", o.Query) - } - - u.RawQuery = q.Encode() - } + }, o) var members []*Member diff --git a/gitlab/merge_requests.go b/gitlab/merge_requests.go index 1434fbd..fe59952 100644 --- a/gitlab/merge_requests.go +++ b/gitlab/merge_requests.go @@ -8,15 +8,15 @@ import ( ) const ( - mergeRequestsUrl = "/merge_requests" - projectMergeRequestsUrl = "/projects/:id/merge_requests" - groupMergeRequestsUrl = "/groups/:id/merge_requests" - projectMergeRequestUrl = "/projects/:id/merge_requests/:merge_request_id" // Get information about a single merge request - projectMergeRequestCommitsUrl = "/projects/:id/merge_requests/:merge_request_id/commits" // Get a list of merge request commits - projectMergeRequestChangesUrl = "/projects/:id/merge_requests/:merge_request_id/changes" // Shows information about the merge request including its files and changes - projectMergeRequestMergeUrl = "/projects/:id/merge_requests/:merge_request_id/merge" // Merge changes submitted with MR - projectMergeRequestCancelMergeUrl = "/projects/:id/merge_requests/:merge_request_id/cancel_merge_when_build_succeeds" // Cancel Merge When Build Succeeds - projectMergeRequestCommentsUrl = "/projects/:id/merge_requests/:merge_request_id/comments" // Lists all comments associated with a merge request + MergeRequestsApiPath = "/merge_requests" + ProjectMergeRequestsApiPath = "/projects/:id/merge_requests" + GroupMergeRequestsApiPath = "/groups/:id/merge_requests" + ProjectMergeRequestApiPath = "/projects/:id/merge_requests/:merge_request_id" // Get information about a single merge request + ProjectMergeRequestCommitsApiPath = "/projects/:id/merge_requests/:merge_request_id/commits" // Get a list of merge request commits + ProjectMergeRequestChangesApiPath = "/projects/:id/merge_requests/:merge_request_id/changes" // Shows information about the merge request including its files and changes + ProjectMergeRequestMergeApiPath = "/projects/:id/merge_requests/:merge_request_id/merge" // Merge changes submitted with MR + ProjectMergeRequestCancelMergeApiPath = "/projects/:id/merge_requests/:merge_request_id/cancel_merge_when_build_succeeds" // Cancel Merge When Build Succeeds + ProjectMergeRequestCommentsApiPath = "/projects/:id/merge_requests/:merge_request_id/comments" // Lists all comments associated with a merge request ) type MergeRequest struct { @@ -184,20 +184,7 @@ type MergeRequestsOptions struct { Scope MergeRequestScope } -func (g *Gitlab) getMergeRequests(u *url.URL, o *MergeRequestsOptions) ([]*MergeRequest, *ResponseMeta, error) { - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - - u.RawQuery = q.Encode() - } - +func (g *Gitlab) getMergeRequests(u *url.URL) ([]*MergeRequest, *ResponseMeta, error) { var err error var mergeRequests []*MergeRequest @@ -210,25 +197,25 @@ func (g *Gitlab) getMergeRequests(u *url.URL, o *MergeRequestsOptions) ([]*Merge } func (g *Gitlab) MergeRequests(o *MergeRequestsOptions) ([]*MergeRequest, *ResponseMeta, error) { - u := g.ResourceUrl(mergeRequestsUrl, nil) + u := g.ResourceUrlQ(MergeRequestsApiPath, nil, o) - return g.getMergeRequests(u, o) + return g.getMergeRequests(u) } func (g *Gitlab) ProjectMergeRequests(projectId string, o *MergeRequestsOptions) ([]*MergeRequest, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergeRequestsUrl, map[string]string{":id": projectId}) + u := g.ResourceUrlQ(ProjectMergeRequestsApiPath, map[string]string{":id": projectId}, o) - return g.getMergeRequests(u, o) + return g.getMergeRequests(u) } func (g *Gitlab) GroupMergeRequests(groupId int, o *MergeRequestsOptions) ([]*MergeRequest, *ResponseMeta, error) { - u := g.ResourceUrl(groupMergeRequestsUrl, map[string]string{":id": strconv.Itoa(groupId)}) + u := g.ResourceUrlQ(GroupMergeRequestsApiPath, map[string]string{":id": strconv.Itoa(groupId)}, o) - return g.getMergeRequests(u, o) + return g.getMergeRequests(u) } func (g *Gitlab) ProjectMergeRequest(projectId string, mergeRequestId int) (*MergeRequest, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergeRequestUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestApiPath, map[string]string{ ":id": projectId, ":merge_request_id": strconv.Itoa(mergeRequestId), }) @@ -256,7 +243,7 @@ Parameters: */ func (g *Gitlab) ProjectMergeRequestCommits(id, merge_request_id string) ([]*Commit, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergeRequestCommitsUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestCommitsApiPath, map[string]string{ ":id": id, ":merge_request_id": merge_request_id, }) @@ -290,7 +277,7 @@ Parameters: */ func (g *Gitlab) ProjectMergeRequestChanges(id, merge_request_id string) (*MergeRequestChanges, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergeRequestChangesUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestChangesApiPath, map[string]string{ ":id": id, ":merge_request_id": merge_request_id, }) @@ -317,7 +304,7 @@ Parameters: */ func (g *Gitlab) AddMergeRequest(req *AddMergeRequestRequest) (*MergeRequest, error) { - u := g.ResourceUrl(projectMergeRequestsUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestsApiPath, map[string]string{ ":id": string(req.TargetProjectId), }) @@ -350,7 +337,7 @@ Parameters: */ func (g *Gitlab) EditMergeRequest(mr *MergeRequest) error { - u := g.ResourceUrl(projectMergeRequestUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestApiPath, map[string]string{ ":id": string(mr.ProjectId), ":merge_request_id": string(mr.Id), }) @@ -385,7 +372,7 @@ Parameters: */ func (g *Gitlab) ProjectMergeRequestAccept(id, merge_request_id string, req *AcceptMergeRequestRequest) (*MergeRequest, error) { - u := g.ResourceUrl(projectMergeRequestMergeUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestMergeApiPath, map[string]string{ ":id": id, ":merge_request_id": merge_request_id, }) @@ -420,7 +407,7 @@ Parameters: */ func (g *Gitlab) ProjectMergeRequestCancelMerge(id, merge_request_id string) (*MergeRequest, *ResponseMeta, error) { - u := g.ResourceUrl(projectMergeRequestCancelMergeUrl, map[string]string{ + u := g.ResourceUrl(ProjectMergeRequestCancelMergeApiPath, map[string]string{ ":id": id, ":merge_request_id": merge_request_id, }) diff --git a/gitlab/namespaces.go b/gitlab/namespaces.go index a4f9471..e04fa28 100644 --- a/gitlab/namespaces.go +++ b/gitlab/namespaces.go @@ -2,12 +2,11 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - namespacesUrl = "/namespaces" - namespaceUrl = "/namespaces/:id" + NamespacesApiPath = "/namespaces" + NamespaceApiPath = "/namespaces/:id" ) type Namespace struct { @@ -27,27 +26,15 @@ type Namespace struct { type NamespacesOptions struct { PaginationOptions - Search string // Returns a list of namespaces the user is authorized to see based on the search criteria + SortOptions + + // Returns a list of namespaces the user is authorized to see + // based on the search criteria + Search string `url:"search,omitempty"` } func (g *Gitlab) Namespaces(o *NamespacesOptions) ([]*Namespace, *ResponseMeta, error) { - u := g.ResourceUrl(namespacesUrl, nil) - - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Search != "" { - q.Set("search", o.Search) - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(NamespacesApiPath, nil, o) var namespaces []*Namespace @@ -60,7 +47,7 @@ func (g *Gitlab) Namespaces(o *NamespacesOptions) ([]*Namespace, *ResponseMeta, } func (g *Gitlab) Namespace(id string) (*Namespace, *ResponseMeta, error) { - u := g.ResourceUrl(namespaceUrl, map[string]string{":id": id}) + u := g.ResourceUrl(NamespaceApiPath, map[string]string{":id": id}) var namespace *Namespace diff --git a/gitlab/pipelines.go b/gitlab/pipelines.go index dbbf5a2..b6c722d 100644 --- a/gitlab/pipelines.go +++ b/gitlab/pipelines.go @@ -2,12 +2,11 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - projectPipelinesUrl = "/projects/:id/pipelines" - projectPipelineUrl = "/projects/:id/pipelines/:pipeline_id" + ProjectPipelinesApiPath = "/projects/:id/pipelines" + ProjectPipelineApiPath = "/projects/:id/pipelines/:pipeline_id" ) type Pipeline struct { @@ -41,32 +40,34 @@ type PipelineWithDetails struct { type PipelinesOptions struct { PaginationOptions - Scope string // The scope of pipelines, one of: running, pending, finished, branches, tags - Status string // The status of pipelines, one of: running, pending, success, failed, canceled, skipped - Ref string // The ref of pipelines - Sha string // The sha or pipelines - YamlErrors bool // Returns pipelines with invalid configurations - Name string // The name of the user who triggered pipelines - Username string // The username of the user who triggered pipelines - OrderBy string // Order pipelines by id, status, ref, or user_id (default: id) - Sort string // Sort pipelines in asc or desc order (default: desc) -} + SortOptions -func (g *Gitlab) ProjectPipelines(projectId string, o *PipelinesOptions) ([]*Pipeline, *ResponseMeta, error) { - u := g.ResourceUrl(projectPipelinesUrl, map[string]string{":id": projectId}) + // The scope of pipelines, one of: + // running, pending, finished, branches, tags + Scope string `url:"scope,omitempty"` - if o != nil { - q := u.Query() + // The status of pipelines, one of: + // running, pending, success, failed, canceled, skipped + Status string `url:"status,omitempty"` - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } + // The ref of pipelines + Ref string `url:"ref,omitempty"` - u.RawQuery = q.Encode() - } + // The sha or pipelines + Sha string `url:"sha,omitempty"` + + // Returns pipelines with invalid configurations + YamlErrors bool `url:"yaml_errors,omitempty"` + + // The name of the user who triggered pipelines + Name string `url:"name,omitempty"` + + // The username of the user who triggered pipelines + Username string `url:"username,omitempty"` +} + +func (g *Gitlab) ProjectPipelines(projectId string, o *PipelinesOptions) ([]*Pipeline, *ResponseMeta, error) { + u := g.ResourceUrlQ(ProjectPipelinesApiPath, map[string]string{":id": projectId}, o) var pipelines []*Pipeline @@ -79,7 +80,7 @@ func (g *Gitlab) ProjectPipelines(projectId string, o *PipelinesOptions) ([]*Pip } func (g *Gitlab) ProjectPipeline(projectId, pipelineId string) (*PipelineWithDetails, *ResponseMeta, error) { - u := g.ResourceUrl(projectPipelineUrl, map[string]string{ + u := g.ResourceUrl(ProjectPipelineApiPath, map[string]string{ ":id": projectId, ":pipeline_id": pipelineId, }) diff --git a/gitlab/projects.go b/gitlab/projects.go index 328db1f..10cee9e 100644 --- a/gitlab/projects.go +++ b/gitlab/projects.go @@ -2,15 +2,14 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - projectsUrl = "/projects" // Get a list of projects owned by the authenticated user - projectUrl = "/projects/:id" // Get a specific project, identified by project ID or NAME - starProjectUrl = "/projects/:id/star" // Stars a given project. Returns status code 304 if the project is already starred - unstarProjectUrl = "/projects/:id/unstar" // Unstars a given project. Returns status code 304 if the project is not starred - projectUrlEvents = "/projects/:id/events" // Get project events + ProjectsApiPath = "/projects" // Get a list of projects owned by the authenticated user + ProjectApiPath = "/projects/:id" // Get a specific project, identified by project ID or NAME + StarProjectApiPath = "/projects/:id/star" // Stars a given project. Returns status code 304 if the project is already starred + UnstarProjectApiPath = "/projects/:id/unstar" // Unstars a given project. Returns status code 304 if the project is not starred + ProjectEventsApiPath = "/projects/:id/events" // Get project events ) type Visibility string @@ -89,68 +88,48 @@ type Project struct { type ProjectsOptions struct { PaginationOptions - Archived bool // Limit by archived status - Visibility Visibility // Limit by visibility public, internal, or private - OrderBy ProjectsOrder // Return projects ordered by id, name, path, created_at, updated_at, or last_activity_at fields. Default is created_at - Sort SortDirection // Return projects sorted in asc or desc order. Default is desc - Search string // Return list of projects matching the search criteria - Simple bool // Return only the ID, URL, name, and path of each project - Owned bool // Limit by projects owned by the current user - Membership bool // Limit by projects that the current user is a member of - Starred bool // Limit by projects starred by the current user - Statistics bool // Include project statistics - WithCustomAttributes bool // Include custom attributes in response (admins only) - WithIssuesEnabled bool // Limit by enabled issues feature - WithMergeRequestsEnabled bool // Limit by enabled merge requests feature + SortOptions + + // Limit by archived status + Archived bool `url:"archived,omitempty"` + + // Limit by visibility public, internal, or private + Visibility Visibility `url:"visibility,omitempty"` + + // Return projects ordered by id, name, path, created_at, updated_at, + // or last_activity_at fields. Default is created_at + OrderBy ProjectsOrder `url:"order_by,omitempty"` + + // Return list of projects matching the search criteria + Search string `url:"search,omitempty"` + + // Return only the ID, URL, name, and path of each project + Simple bool `url:"simple,omitempty"` + + // Limit by projects owned by the current user + Owned bool `url:"owned,omitempty"` + + // Limit by projects that the current user is a member of + Membership bool `url:"membership,omitempty"` + + // Limit by projects starred by the current user + Starred bool `url:"starred,omitempty"` + + // Include project statistics + Statistics bool `url:"statistics,omitempty"` + + // Include custom attributes in response (admins only) + WithCustomAttributes bool `url:"with_custom_attributes,omitempty"` + + // Limit by enabled issues feature + WithIssuesEnabled bool `url:"with_issues_enabled,omitempty"` + + // Limit by enabled merge requests feature + WithMergeRequestsEnabled bool `url:"with_merge_requests_enabled,omitempty"` } func (g *Gitlab) Projects(o *ProjectsOptions) ([]*Project, *ResponseMeta, error) { - u := g.ResourceUrl(projectsUrl, nil) - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Archived { - q.Set("archived", "true") - } - // @todo Visibility - // @todo OrderBy - // @todo Sort - if o.Search != "" { - q.Set("search", o.Search) - } - if o.Simple { - q.Set("simple", "true") - } - if o.Owned { - q.Set("owned", "true") - } - if o.Membership { - q.Set("membership", "true") - } - if o.Starred { - q.Set("starred", "true") - } - if o.Statistics { - q.Set("statistics", "true") - } - if o.WithCustomAttributes { - q.Set("with_custom_attributes", "true") - } - if o.WithIssuesEnabled { - q.Set("with_issues_enabled", "true") - } - if o.WithMergeRequestsEnabled { - q.Set("with_merge_requests_enabled", "true") - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(ProjectsApiPath, nil, o) var projects []*Project @@ -168,7 +147,7 @@ type ProjectAddPayload struct { } func (g *Gitlab) AddProject(project *ProjectAddPayload) (*Project, *ResponseMeta, error) { - u := g.ResourceUrl(projectsUrl, nil) + u := g.ResourceUrl(ProjectsApiPath, nil) projectJson, err := json.Marshal(project) if err != nil { @@ -185,7 +164,7 @@ func (g *Gitlab) AddProject(project *ProjectAddPayload) (*Project, *ResponseMeta } func (g *Gitlab) RemoveProject(id string) (string, *ResponseMeta, error) { - u := g.ResourceUrl(projectUrl, map[string]string{":id": id}) + u := g.ResourceUrl(ProjectApiPath, map[string]string{":id": id}) var responseWithMessage *ResponseWithMessage contents, meta, err := g.buildAndExecRequest("DELETE", u.String(), nil) @@ -199,7 +178,7 @@ func (g *Gitlab) RemoveProject(id string) (string, *ResponseMeta, error) { } func (g *Gitlab) Project(id string, withStatistics bool) (*Project, *ResponseMeta, error) { - u := g.ResourceUrl(projectUrl, map[string]string{":id": id}) + u := g.ResourceUrl(ProjectApiPath, map[string]string{":id": id}) q := u.Query() if withStatistics { @@ -219,7 +198,7 @@ func (g *Gitlab) Project(id string, withStatistics bool) (*Project, *ResponseMet } func (g *Gitlab) UpdateProject(id string, project *Project) (*Project, *ResponseMeta, error) { - u := g.ResourceUrl(projectUrl, map[string]string{":id": id}) + u := g.ResourceUrl(ProjectApiPath, map[string]string{":id": id}) encodedRequest, err := json.Marshal(project) if err != nil { @@ -236,7 +215,7 @@ func (g *Gitlab) UpdateProject(id string, project *Project) (*Project, *Response } func (g *Gitlab) StarProject(id string) (*Project, *ResponseMeta, error) { - u := g.ResourceUrl(starProjectUrl, map[string]string{":id": id}) + u := g.ResourceUrl(StarProjectApiPath, map[string]string{":id": id}) contents, meta, err := g.buildAndExecRequest("POST", u.String(), nil) if err != nil { @@ -252,7 +231,7 @@ func (g *Gitlab) StarProject(id string) (*Project, *ResponseMeta, error) { } func (g *Gitlab) UnstarProject(id string) (*Project, *ResponseMeta, error) { - u := g.ResourceUrl(unstarProjectUrl, map[string]string{":id": id}) + u := g.ResourceUrl(UnstarProjectApiPath, map[string]string{":id": id}) contents, meta, err := g.buildAndExecRequest("POST", u.String(), nil) if err != nil { diff --git a/gitlab/protected_branches.go b/gitlab/protected_branches.go index f123e51..58e5a4f 100644 --- a/gitlab/protected_branches.go +++ b/gitlab/protected_branches.go @@ -2,13 +2,12 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - protectedBranchesUrl = "/projects/:id/protected_branches" // Gets a list of protected branches from a project. - protectBranchUrl = "/projects/:id/repository/branches/:branch/protect" // Protects a single project repository branch. - unprotectBranchUrl = "/projects/:id/repository/branches/:branch/unprotect" // Unprotects a single project repository branch. + ProtectedBranchesApiPath = "/projects/:id/protected_branches" // Gets a list of protected branches from a project. + ProtectBranchApiPath = "/projects/:id/repository/branches/:branch/protect" // Protects a single project repository branch. + UnprotectBranchApiPath = "/projects/:id/repository/branches/:branch/unprotect" // Unprotects a single project repository branch. ) type AccessLevelInfo struct { @@ -25,20 +24,7 @@ type ProtectedBranch struct { } func (g *Gitlab) ProtectedBranches(projectId string, o *PaginationOptions) ([]*ProtectedBranch, *ResponseMeta, error) { - u := g.ResourceUrl(protectedBranchesUrl, map[string]string{":id": projectId}) - - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(ProtectedBranchesApiPath, map[string]string{":id": projectId}, o) var protectedBranches []*ProtectedBranch @@ -51,7 +37,7 @@ func (g *Gitlab) ProtectedBranches(projectId string, o *PaginationOptions) ([]*P } func (g *Gitlab) ProtectBranch(projectId, branchName string) (*ResponseMeta, error) { - u := g.ResourceUrl(protectBranchUrl, map[string]string{ + u := g.ResourceUrl(ProtectBranchApiPath, map[string]string{ ":id": projectId, ":branch": branchName, }) @@ -64,7 +50,7 @@ func (g *Gitlab) ProtectBranch(projectId, branchName string) (*ResponseMeta, err } func (g *Gitlab) UnprotectBranch(projectId, branchName string) (*ResponseMeta, error) { - u := g.ResourceUrl(unprotectBranchUrl, map[string]string{ + u := g.ResourceUrl(UnprotectBranchApiPath, map[string]string{ ":id": projectId, ":branch": branchName, }) diff --git a/gitlab/public_keys.go b/gitlab/public_keys.go index 8730fc1..db39692 100644 --- a/gitlab/public_keys.go +++ b/gitlab/public_keys.go @@ -6,11 +6,9 @@ import ( ) const ( - // ID - user_keys = "/user/keys" // Get current user keys - user_key = "/user/keys/:id" // Get user key by id - list_keys = "/users/:uid/keys" // Get keys for the user id - custom_user_keys = "/user/:id/keys" // Create key for user with :id + CurrentUserKeysApiPath = "/user/keys" + CurrentUserKeyApiPath = "/user/keys/:id" + UserKeysApiPath = "/users/:id/keys" ) type PublicKey struct { @@ -20,8 +18,8 @@ type PublicKey struct { CreatedAtRaw string `json:"created_at,omitempty"` } -func (g *Gitlab) UserKeys() ([]*PublicKey, *ResponseMeta, error) { - u := g.ResourceUrl(user_keys, nil) +func (g *Gitlab) UserKeys(userId string) ([]*PublicKey, *ResponseMeta, error) { + u := g.ResourceUrl(UserKeysApiPath, map[string]string{":id": userId}) var keys []*PublicKey @@ -33,8 +31,8 @@ func (g *Gitlab) UserKeys() ([]*PublicKey, *ResponseMeta, error) { return keys, meta, err } -func (g *Gitlab) ListKeys(id string) ([]*PublicKey, *ResponseMeta, error) { - u := g.ResourceUrl(list_keys, map[string]string{":uid": id}) +func (g *Gitlab) CurrentUserKeys() ([]*PublicKey, *ResponseMeta, error) { + u := g.ResourceUrl(CurrentUserKeysApiPath, nil) var keys []*PublicKey @@ -46,8 +44,8 @@ func (g *Gitlab) ListKeys(id string) ([]*PublicKey, *ResponseMeta, error) { return keys, meta, err } -func (g *Gitlab) UserKey(id string) (*PublicKey, *ResponseMeta, error) { - u := g.ResourceUrl(user_key, map[string]string{":id": id}) +func (g *Gitlab) CurrentUserKey(id string) (*PublicKey, *ResponseMeta, error) { + u := g.ResourceUrl(CurrentUserKeyApiPath, map[string]string{":id": id}) var key *PublicKey @@ -59,9 +57,7 @@ func (g *Gitlab) UserKey(id string) (*PublicKey, *ResponseMeta, error) { return key, meta, err } -func (g *Gitlab) AddKey(title, key string) (*ResponseMeta, error) { - u := g.ResourceUrl(user_keys, nil) - +func (g *Gitlab) addKey(u *url.URL, title, key string) (*ResponseMeta, error) { var err error v := url.Values{} @@ -75,25 +71,24 @@ func (g *Gitlab) AddKey(title, key string) (*ResponseMeta, error) { return meta, err } -func (g *Gitlab) AddUserKey(id, title, key string) (*ResponseMeta, error) { - u := g.ResourceUrl(user_keys, map[string]string{":id": id}) - - var err error +func (g *Gitlab) AddUserKey(userId, title, key string) (*ResponseMeta, error) { + u := g.ResourceUrl(UserKeysApiPath, map[string]string{":id": userId}) - v := url.Values{} - v.Set("title", title) - v.Set("key", key) + return g.addKey(u, title, key) +} - body := v.Encode() +func (g *Gitlab) AddCurrentUserKey(title, key string) (*ResponseMeta, error) { + u := g.ResourceUrl(CurrentUserKeysApiPath, nil) - _, meta, err := g.buildAndExecRequest("POST", u.String(), []byte(body)) + return g.addKey(u, title, key) - return meta, err } -func (g *Gitlab) DeleteKey(id string) error { - u := g.ResourceUrl(user_key, map[string]string{":id": id}) +func (g *Gitlab) DeleteCurrentUserKey(id string) error { + u := g.ResourceUrl(CurrentUserKeyApiPath, map[string]string{":id": id}) + var err error _, _, err = g.buildAndExecRequest("DELETE", u.String(), nil) + return err } diff --git a/gitlab/repositories.go b/gitlab/repositories.go index 0a55b28..bb5f0ac 100644 --- a/gitlab/repositories.go +++ b/gitlab/repositories.go @@ -6,10 +6,10 @@ import ( ) const ( - repo_url_tags = "/projects/:id/repository/tags" // List project repository tags - repo_url_commits = "/projects/:id/repository/commits" // List repository commits - repo_url_tree = "/projects/:id/repository/tree" // List repository tree - repo_url_raw_file = "/projects/:id/repository/blobs/:sha" // Get raw file content for specific commit/branch + RepositoryTagsApiPath = "/projects/:id/repository/tags" // List project repository tags + RepositoryCommitsApiPath = "/projects/:id/repository/commits" // List repository commits + RepositoryTreeApiPath = "/projects/:id/repository/tree" // List repository tree + RawRepositoryFileApiPath = "/projects/:id/repository/blobs/:sha" // Get raw file content for specific commit/branch ) type TreeNode struct { @@ -51,7 +51,7 @@ Usage: pass nil when not using optional parameters */ func (g *Gitlab) RepoTree(id, path, refName string) ([]*TreeNode, *ResponseMeta, error) { - u := g.ResourceUrl(repo_url_tree, map[string]string{":id": id}) + u := g.ResourceUrl(RepositoryTreeApiPath, map[string]string{":id": id}) q := u.Query() q.Set("path", path) @@ -88,7 +88,7 @@ Usage: } */ func (g *Gitlab) RepoTags(id string) ([]*Tag, *ResponseMeta, error) { - u := g.ResourceUrl(repo_url_tags, map[string]string{":id": id}) + u := g.ResourceUrl(RepositoryTagsApiPath, map[string]string{":id": id}) var tags []*Tag @@ -121,7 +121,7 @@ Usage: } */ func (g *Gitlab) RepoCommits(id string) ([]*Commit, *ResponseMeta, error) { - u := g.ResourceUrl(repo_url_commits, map[string]string{":id": id}) + u := g.ResourceUrl(RepositoryCommitsApiPath, map[string]string{":id": id}) var commits []*Commit @@ -143,7 +143,7 @@ func (g *Gitlab) RepoCommits(id string) ([]*Commit, *ResponseMeta, error) { Get Raw file content */ func (g *Gitlab) RepoRawFile(id, sha, filepath string) ([]byte, *ResponseMeta, error) { - u := g.ResourceUrl(repo_url_raw_file, map[string]string{ + u := g.ResourceUrl(RawRepositoryFileApiPath, map[string]string{ ":id": id, ":sha": sha, }) diff --git a/gitlab/runners.go b/gitlab/runners.go index 2d783de..634b284 100644 --- a/gitlab/runners.go +++ b/gitlab/runners.go @@ -2,16 +2,15 @@ package gitlab import ( "encoding/json" - "fmt" "strconv" ) const ( - runnersUrl = "/runners" // Get current users runner list. - allRunnersUrl = "/runners/all" // Get ALL runners list. - runnerUrl = "/runners/:id" // Get a single runner. - projectRunnersUrl = "/projects/:project_id/runners" // Get ALL project runners. - projectRunnerUrl = "/projects/:project_id/runners/:id" // Get a single project runner. + RunnersApiPath = "/runners" // Get current users runner list. + AllRunnersApiPath = "/runners/all" // Get ALL runners list. + RunnerApiPath = "/runners/:id" // Get a single runner. + ProjectRunnersApiPath = "/projects/:project_id/runners" // Get ALL project runners. + ProjectRunnerApiPath = "/projects/:project_id/runners/:id" // Get a single project runner. ) type Runner struct { @@ -51,31 +50,23 @@ const ( type RunnersOptions struct { PaginationOptions - All bool // Get a list of all runners in the GitLab instance (specific and shared). Access is restricted to users with admin privileges - Scope RunnerScope // The scope of runners to show, one of: specific, shared, active, paused, online; showing all runners if none provided + SortOptions + + // Get a list of all runners in the GitLab instance (specific and shared). + // Access is restricted to users with admin privileges + All bool `url:"-"` + + // The scope of runners to show, one of: specific, shared, active, paused, online; + // showing all runners if none provided + Scope RunnerScope `url:"scope,omitempty"` } func (g *Gitlab) Runners(o *RunnersOptions) ([]*Runner, *ResponseMeta, error) { - p := runnersUrl + p := RunnersApiPath if o != nil && o.All { - p = allRunnersUrl - } - u := g.ResourceUrl(p, nil) - if o != nil { - q := u.Query() - - if o.Page > 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Scope != "" { - q.Set("scope", fmt.Sprintf("%s", o.Scope)) - } - - u.RawQuery = q.Encode() + p = AllRunnersApiPath } + u := g.ResourceUrlQ(p, nil, o) var runners []*Runner @@ -88,7 +79,7 @@ func (g *Gitlab) Runners(o *RunnersOptions) ([]*Runner, *ResponseMeta, error) { } func (g *Gitlab) Runner(id int) (*RunnerWithDetails, *ResponseMeta, error) { - u := g.ResourceUrl(runnerUrl, map[string]string{":id": strconv.Itoa(id)}) + u := g.ResourceUrl(RunnerApiPath, map[string]string{":id": strconv.Itoa(id)}) runner := new(RunnerWithDetails) @@ -101,7 +92,7 @@ func (g *Gitlab) Runner(id int) (*RunnerWithDetails, *ResponseMeta, error) { } func (g *Gitlab) ProjectRunners(projectId string, page, per_page int) ([]*Runner, *ResponseMeta, error) { - u := g.ResourceUrl(projectRunnersUrl, map[string]string{":project_id": projectId, + u := g.ResourceUrl(ProjectRunnersApiPath, map[string]string{":project_id": projectId, ":page": strconv.Itoa(page), ":per_page": strconv.Itoa(per_page), }) @@ -117,7 +108,7 @@ func (g *Gitlab) ProjectRunners(projectId string, page, per_page int) ([]*Runner } func (g *Gitlab) UpdateRunner(id int, runner *Runner) (*Runner, *ResponseMeta, error) { - u := g.ResourceUrl(runnerUrl, map[string]string{":id": strconv.Itoa(id)}) + u := g.ResourceUrl(RunnerApiPath, map[string]string{":id": strconv.Itoa(id)}) encodedRequest, err := json.Marshal(runner) if err != nil { @@ -135,7 +126,7 @@ func (g *Gitlab) UpdateRunner(id int, runner *Runner) (*Runner, *ResponseMeta, e } func (g *Gitlab) EnableProjectRunner(projectId string, id int) (*Runner, *ResponseMeta, error) { - u := g.ResourceUrl(projectRunnerUrl, map[string]string{":project_id": projectId, ":id": strconv.Itoa(id)}) + u := g.ResourceUrl(ProjectRunnerApiPath, map[string]string{":project_id": projectId, ":id": strconv.Itoa(id)}) request := map[string]int{"runner_id": id} @@ -154,7 +145,7 @@ func (g *Gitlab) EnableProjectRunner(projectId string, id int) (*Runner, *Respon } func (g *Gitlab) DisableProjectRunner(projectId string, id int) (*Runner, *ResponseMeta, error) { - u := g.ResourceUrl(projectRunnerUrl, map[string]string{":project_id": projectId, ":id": strconv.Itoa(id)}) + u := g.ResourceUrl(ProjectRunnerApiPath, map[string]string{":project_id": projectId, ":id": strconv.Itoa(id)}) var result *Runner @@ -167,7 +158,7 @@ func (g *Gitlab) DisableProjectRunner(projectId string, id int) (*Runner, *Respo } func (g *Gitlab) DeleteRunner(id int) (*Runner, *ResponseMeta, error) { - u := g.ResourceUrl(runnerUrl, map[string]string{":id": strconv.Itoa(id)}) + u := g.ResourceUrl(RunnerApiPath, map[string]string{":id": strconv.Itoa(id)}) var result *Runner diff --git a/gitlab/runners_test.go b/gitlab/runners_test.go index c3d1e3d..9fb8d77 100644 --- a/gitlab/runners_test.go +++ b/gitlab/runners_test.go @@ -9,6 +9,7 @@ import ( func TestRunners(t *testing.T) { g := NewGitlab(testsHost, "/api/v4", "") o := RunnersOptions{} + o.Page = 1 o.PerPage = 10 runners, meta, err := g.Runners(&o) diff --git a/gitlab/users.go b/gitlab/users.go index 3b9c251..0da5707 100644 --- a/gitlab/users.go +++ b/gitlab/users.go @@ -2,13 +2,12 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - usersUrl = "/users" // Get users list - userUrl = "/users/:id" // Get a single user. - currentUserUrl = "/user" // Get current user + UsersApiPath = "/users" // Get users list + UserApiPath = "/users/:id" // Get a single user. + CurrentUserApiPath = "/user" // Get current user ) type UserIdentity struct { @@ -49,38 +48,22 @@ type User struct { type UsersOptions struct { PaginationOptions - Search string // Search users by email or username - Username string // Search users by username - Active bool // Limit to active users - Blocked bool // Limit to blocked users + + // Search users by email or username + Search string `url:"search,omitempty"` + + // Search users by username + Username string `url:"username,omitempty"` + + // Limit to active users + Active bool `url:"active,omitempty"` + + // Limit to blocked users + Blocked bool `url:"blocked,omitempty"` } func (g *Gitlab) Users(o *UsersOptions) ([]*User, *ResponseMeta, error) { - u := g.ResourceUrl(usersUrl, nil) - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - if o.Search != "" { - q.Set("search", o.Search) - } - if o.Username != "" { - q.Set("username", o.Username) - } - if o.Active { - q.Set("active", "true") - } - if o.Blocked { - q.Set("blocked", "true") - } - - u.RawQuery = q.Encode() - } + u := g.ResourceUrlQ(UsersApiPath, nil, o) var users []*User @@ -93,7 +76,7 @@ func (g *Gitlab) Users(o *UsersOptions) ([]*User, *ResponseMeta, error) { } func (g *Gitlab) User(id string) (*User, *ResponseMeta, error) { - u := g.ResourceUrl(userUrl, map[string]string{":id": id}) + u := g.ResourceUrl(UserApiPath, map[string]string{":id": id}) user := new(User) @@ -106,7 +89,7 @@ func (g *Gitlab) User(id string) (*User, *ResponseMeta, error) { } func (g *Gitlab) CurrentUser() (*User, *ResponseMeta, error) { - u := g.ResourceUrl(currentUserUrl, nil) + u := g.ResourceUrl(CurrentUserApiPath, nil) user := new(User) @@ -119,7 +102,7 @@ func (g *Gitlab) CurrentUser() (*User, *ResponseMeta, error) { } func (g *Gitlab) RemoveUser(id string) (*ResponseMeta, error) { - u := g.ResourceUrl(userUrl, map[string]string{":id": id}) + u := g.ResourceUrl(UserApiPath, map[string]string{":id": id}) _, meta, err := g.buildAndExecRequest("DELETE", u.String(), nil) diff --git a/gitlab/variables.go b/gitlab/variables.go index a89a055..b90b82c 100644 --- a/gitlab/variables.go +++ b/gitlab/variables.go @@ -2,12 +2,11 @@ package gitlab import ( "encoding/json" - "strconv" ) const ( - variablesUrl = "/:type/:id/variables" // Get list of a project/group variables. - variableUrl = "/:type/:id/variables/:key" // Get detail of project/group variable. + VariablesApiPath = "/:type/:id/variables" + VariableApiPath = "/:type/:id/variables/:key" ) type Variable struct { @@ -18,22 +17,10 @@ type Variable struct { } func (g *Gitlab) getVariables(resourceType, id string, o *PaginationOptions) ([]*Variable, *ResponseMeta, error) { - u := g.ResourceUrl(variablesUrl, map[string]string{ + u := g.ResourceUrlQ(VariablesApiPath, map[string]string{ ":type": resourceType, ":id": id, - }) - if o != nil { - q := u.Query() - - if o.Page != 1 { - q.Set("page", strconv.Itoa(o.Page)) - } - if o.PerPage != 0 { - q.Set("per_page", strconv.Itoa(o.PerPage)) - } - - u.RawQuery = q.Encode() - } + }, o) var variables []*Variable @@ -54,7 +41,7 @@ func (g *Gitlab) GroupVariables(groupId string, o *PaginationOptions) ([]*Variab } func (g *Gitlab) getVariable(resourceType, projectId, varKey string) (*Variable, *ResponseMeta, error) { - u := g.ResourceUrl(variableUrl, map[string]string{ + u := g.ResourceUrl(VariableApiPath, map[string]string{ ":type": "projects", ":id": projectId, ":key": varKey, @@ -79,7 +66,7 @@ func (g *Gitlab) GroupVariable(groupId, varKey string) (*Variable, *ResponseMeta } func (g *Gitlab) addVariable(resourceType, id string, variable *Variable) (*Variable, *ResponseMeta, error) { - u := g.ResourceUrl(variablesUrl, map[string]string{ + u := g.ResourceUrl(VariablesApiPath, map[string]string{ ":type": resourceType, ":id": id, }) @@ -107,7 +94,7 @@ func (g *Gitlab) AddGroupVariable(groupId string, variable *Variable) (*Variable } func (g *Gitlab) removeVariable(resourceType, id, varKey string) (*ResponseMeta, error) { - u := g.ResourceUrl(variableUrl, map[string]string{ + u := g.ResourceUrl(VariableApiPath, map[string]string{ ":type": resourceType, ":id": id, ":key": varKey, diff --git a/integration/snapshots/ls_groups_verbose.snap b/integration/snapshots/ls_groups_verbose.snap index 3931b7c..6e7476d 100644 --- a/integration/snapshots/ls_groups_verbose.snap +++ b/integration/snapshots/ls_groups_verbose.snap @@ -9,7 +9,7 @@ Fetching groups… Response meta Method GET - Url http://wiremock:8080/api/v4/groups?per_page=10 + Url http://wiremock:8080/api/v4/groups?page=1&per_page=10 StatusCode 200 Request id Runtime 0.000000 diff --git a/integration/snapshots/ls_namespaces_verbose.snap b/integration/snapshots/ls_namespaces_verbose.snap index eae5f5c..ad08ed0 100644 --- a/integration/snapshots/ls_namespaces_verbose.snap +++ b/integration/snapshots/ls_namespaces_verbose.snap @@ -10,7 +10,7 @@ Fetching namespaces… Response meta Method GET - Url http://wiremock:8080/api/v4/namespaces?per_page=10 + Url http://wiremock:8080/api/v4/namespaces?page=1&per_page=10 StatusCode 200 Request id Runtime 0.000000 diff --git a/integration/snapshots/ls_projects_verbose.snap b/integration/snapshots/ls_projects_verbose.snap index d4662c1..1b134d7 100644 --- a/integration/snapshots/ls_projects_verbose.snap +++ b/integration/snapshots/ls_projects_verbose.snap @@ -9,7 +9,7 @@ Fetching projects… Response meta Method GET - Url http://wiremock:8080/api/v4/projects?per_page=10 + Url http://wiremock:8080/api/v4/projects?page=1&per_page=10 StatusCode 200 Request id Runtime 0.000000 diff --git a/integration/snapshots/ls_runners_verbose.snap b/integration/snapshots/ls_runners_verbose.snap index d281421..fe35d62 100644 --- a/integration/snapshots/ls_runners_verbose.snap +++ b/integration/snapshots/ls_runners_verbose.snap @@ -9,7 +9,7 @@ Fetching runners… Response meta Method GET - Url http://wiremock:8080/api/v4/runners?per_page=10 + Url http://wiremock:8080/api/v4/runners?page=1&per_page=10 StatusCode 200 Request id Runtime 0.000000 diff --git a/integration/snapshots/ls_users_verbose.snap b/integration/snapshots/ls_users_verbose.snap index a6ae68e..a1ba3fb 100644 --- a/integration/snapshots/ls_users_verbose.snap +++ b/integration/snapshots/ls_users_verbose.snap @@ -9,7 +9,7 @@ Fetching users… Response meta Method GET - Url http://wiremock:8080/api/v4/users?per_page=10 + Url http://wiremock:8080/api/v4/users?page=1&per_page=10 StatusCode 200 Request id Runtime 0.000000 diff --git a/mocks/mappings/groups/groups.json b/mocks/mappings/groups/groups.json index 9869200..975b972 100644 --- a/mocks/mappings/groups/groups.json +++ b/mocks/mappings/groups/groups.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/groups?per_page=10", + "url": "/api/v4/groups?page=1&per_page=10", "method": "GET" }, "response": { diff --git a/mocks/mappings/namespaces/namespaces.json b/mocks/mappings/namespaces/namespaces.json index 7ca9885..78dabd6 100644 --- a/mocks/mappings/namespaces/namespaces.json +++ b/mocks/mappings/namespaces/namespaces.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/namespaces?per_page=10", + "url": "/api/v4/namespaces?page=1&per_page=10", "method": "GET" }, "response": { diff --git a/mocks/mappings/namespaces/namespaces_search.json b/mocks/mappings/namespaces/namespaces_search.json index 0f00d76..ebe3505 100644 --- a/mocks/mappings/namespaces/namespaces_search.json +++ b/mocks/mappings/namespaces/namespaces_search.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/namespaces?per_page=10&search=twitter", + "url": "/api/v4/namespaces?page=1&per_page=10&search=twitter", "method": "GET" }, "response": { diff --git a/mocks/mappings/projects/projects.json b/mocks/mappings/projects/projects.json index d533572..98bc4e7 100644 --- a/mocks/mappings/projects/projects.json +++ b/mocks/mappings/projects/projects.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/projects?per_page=10", + "url": "/api/v4/projects?page=1&per_page=10", "method": "GET" }, "response": { diff --git a/mocks/mappings/runners/runners.json b/mocks/mappings/runners/runners.json index c55525b..675dcb3 100644 --- a/mocks/mappings/runners/runners.json +++ b/mocks/mappings/runners/runners.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/runners?per_page=10", + "url": "/api/v4/runners?page=1&per_page=10", "method": "GET" }, "response": { diff --git a/mocks/mappings/users/users.json b/mocks/mappings/users/users.json index f9e7ee2..534db10 100644 --- a/mocks/mappings/users/users.json +++ b/mocks/mappings/users/users.json @@ -1,6 +1,6 @@ { "request": { - "url": "/api/v4/users?per_page=10", + "url": "/api/v4/users?page=1&per_page=10", "method": "GET" }, "response": {