|
8 | 8 | "strings" |
9 | 9 | "time" |
10 | 10 |
|
| 11 | + retryablehttp "github.com/hashicorp/go-retryablehttp" |
11 | 12 | log "github.com/sirupsen/logrus" |
12 | 13 | goGitlab "github.com/xanzy/go-gitlab" |
13 | 14 | "go.opentelemetry.io/otel" |
@@ -86,6 +87,103 @@ func (c *Client) GetProjectPipelines( |
86 | 87 | return pipelines, resp, nil |
87 | 88 | } |
88 | 89 |
|
| 90 | +// ListProjectMergeRequests .. |
| 91 | +func (c *Client) ListProjectMergeRequests( |
| 92 | + ctx context.Context, |
| 93 | + projectName string, |
| 94 | + options *goGitlab.ListProjectMergeRequestsOptions, |
| 95 | +) ( |
| 96 | + []*goGitlab.MergeRequest, |
| 97 | + *goGitlab.Response, |
| 98 | + error, |
| 99 | +) { |
| 100 | + ctx, span := otel.Tracer(tracerName).Start(ctx, "gitlab:ListProjectMergeRequests") |
| 101 | + defer span.End() |
| 102 | + span.SetAttributes(attribute.String("project_name", projectName)) |
| 103 | + |
| 104 | + fields := log.Fields{ |
| 105 | + "project-name": projectName, |
| 106 | + } |
| 107 | + |
| 108 | + if options.Page == 0 { |
| 109 | + options.Page = 1 |
| 110 | + } |
| 111 | + |
| 112 | + if options.PerPage == 0 { |
| 113 | + options.PerPage = 100 |
| 114 | + } |
| 115 | + |
| 116 | + fields["page"] = options.Page |
| 117 | + log.WithFields(fields).Trace("listing project merge requests") |
| 118 | + |
| 119 | + c.rateLimit(ctx) |
| 120 | + |
| 121 | + mrs, resp, err := c.MergeRequests.ListProjectMergeRequests(projectName, options, goGitlab.WithContext(ctx)) |
| 122 | + if err != nil { |
| 123 | + return nil, resp, fmt.Errorf("error listing project merge requests for project %s: %s", projectName, err.Error()) |
| 124 | + } |
| 125 | + |
| 126 | + c.requestsRemaining(resp) |
| 127 | + |
| 128 | + return mrs, resp, nil |
| 129 | +} |
| 130 | + |
| 131 | +// GetMergeRequestPipelines .. |
| 132 | +func (c *Client) GetMergeRequestPipelines( |
| 133 | + ctx context.Context, |
| 134 | + projectName string, |
| 135 | + mergeRequest int, |
| 136 | + options *goGitlab.ListOptions, |
| 137 | +) ( |
| 138 | + []*goGitlab.PipelineInfo, |
| 139 | + *goGitlab.Response, |
| 140 | + error, |
| 141 | +) { |
| 142 | + ctx, span := otel.Tracer(tracerName).Start(ctx, "gitlab:GetMergeRequestPipelines") |
| 143 | + defer span.End() |
| 144 | + span.SetAttributes(attribute.String("project_name", projectName)) |
| 145 | + |
| 146 | + fields := log.Fields{ |
| 147 | + "project-name": projectName, |
| 148 | + } |
| 149 | + |
| 150 | + if options.Page == 0 { |
| 151 | + options.Page = 1 |
| 152 | + } |
| 153 | + |
| 154 | + if options.PerPage == 0 { |
| 155 | + options.PerPage = 100 |
| 156 | + } |
| 157 | + |
| 158 | + fields["page"] = options.Page |
| 159 | + log.WithFields(fields).Trace("listing merge request pipelines") |
| 160 | + |
| 161 | + params := map[string]string{ |
| 162 | + "page": fmt.Sprint(options.Page), |
| 163 | + "per_page": fmt.Sprint(options.PerPage), |
| 164 | + } |
| 165 | + optionFunc := func(req *retryablehttp.Request) error { |
| 166 | + for k, v := range params { |
| 167 | + q := req.URL.Query() |
| 168 | + q.Add(k, v) |
| 169 | + req.URL.RawQuery = q.Encode() |
| 170 | + } |
| 171 | + |
| 172 | + return nil |
| 173 | + } |
| 174 | + |
| 175 | + c.rateLimit(ctx) |
| 176 | + |
| 177 | + pipelines, resp, err := c.MergeRequests.ListMergeRequestPipelines(projectName, mergeRequest, optionFunc, goGitlab.WithContext(ctx)) |
| 178 | + if err != nil { |
| 179 | + return nil, resp, fmt.Errorf("error merge request project pipelines for project %s!%d: %s", projectName, mergeRequest, err.Error()) |
| 180 | + } |
| 181 | + |
| 182 | + c.requestsRemaining(resp) |
| 183 | + |
| 184 | + return pipelines, resp, nil |
| 185 | +} |
| 186 | + |
89 | 187 | // GetRefPipelineVariablesAsConcatenatedString .. |
90 | 188 | func (c *Client) GetRefPipelineVariablesAsConcatenatedString(ctx context.Context, ref schemas.Ref) (string, error) { |
91 | 189 | ctx, span := otel.Tracer(tracerName).Start(ctx, "gitlab:GetRefPipelineVariablesAsConcatenatedString") |
@@ -292,6 +390,108 @@ func (c *Client) GetRefsFromPipelines(ctx context.Context, p schemas.Project, re |
292 | 390 | return |
293 | 391 | } |
294 | 392 |
|
| 393 | +// GetMergeRequestRefsFromPipelines .. |
| 394 | +func (c *Client) GetMergeRequestRefsFromPipelines(ctx context.Context, p schemas.Project) (refs schemas.Refs, err error) { |
| 395 | + ctx, span := otel.Tracer(tracerName).Start(ctx, "gitlab:GetMergeRequestRefsFromPipelines") |
| 396 | + defer span.End() |
| 397 | + span.SetAttributes(attribute.String("project_name", p.Name)) |
| 398 | + span.SetAttributes(attribute.String("ref_kind", "merge-request")) |
| 399 | + |
| 400 | + refs = make(schemas.Refs) |
| 401 | + |
| 402 | + options := &goGitlab.ListProjectMergeRequestsOptions{ |
| 403 | + ListOptions: goGitlab.ListOptions{ |
| 404 | + Page: 1, |
| 405 | + PerPage: 100, |
| 406 | + }, |
| 407 | + OrderBy: goGitlab.String("updated_at"), |
| 408 | + } |
| 409 | + |
| 410 | + var ( |
| 411 | + mostRecent, maxAgeSeconds uint |
| 412 | + limitToMostRecent bool |
| 413 | + ) |
| 414 | + |
| 415 | + maxAgeSeconds = p.Pull.Refs.MergeRequests.MaxAgeSeconds |
| 416 | + mostRecent = p.Pull.Refs.MergeRequests.MostRecent |
| 417 | + |
| 418 | + if mostRecent > 0 { |
| 419 | + limitToMostRecent = true |
| 420 | + } |
| 421 | + |
| 422 | + if maxAgeSeconds > 0 { |
| 423 | + t := time.Now().Add(-time.Second * time.Duration(maxAgeSeconds)) |
| 424 | + options.UpdatedAfter = &t |
| 425 | + } |
| 426 | + |
| 427 | + for { |
| 428 | + var ( |
| 429 | + mrs []*goGitlab.MergeRequest |
| 430 | + resp *goGitlab.Response |
| 431 | + ) |
| 432 | + |
| 433 | + mrs, resp, err = c.ListProjectMergeRequests(ctx, p.Name, options) |
| 434 | + if err != nil { |
| 435 | + return |
| 436 | + } |
| 437 | + |
| 438 | + for _, mr := range mrs { |
| 439 | + var refName string |
| 440 | + |
| 441 | + refName = fmt.Sprint(mr.IID) |
| 442 | + |
| 443 | + ref := schemas.NewRef( |
| 444 | + p, |
| 445 | + schemas.RefKindMergeRequest, |
| 446 | + refName, |
| 447 | + ) |
| 448 | + |
| 449 | + if mr.SourceProjectID == mr.TargetProjectID { |
| 450 | + ref.SourceProject = &p |
| 451 | + } else { |
| 452 | + var ( |
| 453 | + goProject *goGitlab.Project |
| 454 | + sourceProject schemas.Project |
| 455 | + ) |
| 456 | + |
| 457 | + goProject, err = c.GetProjectByID(ctx, mr.SourceProjectID) |
| 458 | + if err != nil { |
| 459 | + return |
| 460 | + } |
| 461 | + sourceProject = p |
| 462 | + sourceProject.Name = goProject.PathWithNamespace |
| 463 | + |
| 464 | + ref.SourceProject = &sourceProject |
| 465 | + } |
| 466 | + |
| 467 | + if _, ok := refs[ref.Key()]; !ok { |
| 468 | + log.WithFields(log.Fields{ |
| 469 | + "project-name": ref.Project.Name, |
| 470 | + "ref": ref.Name, |
| 471 | + "ref-kind": ref.Kind, |
| 472 | + }).Trace("found ref") |
| 473 | + |
| 474 | + refs[ref.Key()] = ref |
| 475 | + |
| 476 | + if limitToMostRecent { |
| 477 | + mostRecent-- |
| 478 | + if mostRecent <= 0 { |
| 479 | + return |
| 480 | + } |
| 481 | + } |
| 482 | + } |
| 483 | + } |
| 484 | + |
| 485 | + if resp.CurrentPage >= resp.NextPage { |
| 486 | + break |
| 487 | + } |
| 488 | + |
| 489 | + options.Page = resp.NextPage |
| 490 | + } |
| 491 | + |
| 492 | + return |
| 493 | +} |
| 494 | + |
295 | 495 | // GetRefPipelineTestReport .. |
296 | 496 | func (c *Client) GetRefPipelineTestReport(ctx context.Context, ref schemas.Ref) (schemas.TestReport, error) { |
297 | 497 | ctx, span := otel.Tracer(tracerName).Start(ctx, "gitlab:GetRefPipelineTestReport") |
|
0 commit comments