• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mindersec / minder / 15722245274

18 Jun 2025 02:10AM UTC coverage: 57.198% (+0.02%) from 57.181%
15722245274

push

github

web-flow
build(deps): bump github/codeql-action from 3.28.19 to 3.29.0 (#5695)

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.28.19 to 3.29.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/fca7ace96...ce28f5bb4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.29.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

18472 of 32295 relevant lines covered (57.2%)

37.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/internal/providers/gitlab/pull_request_properties.go
1
// SPDX-FileCopyrightText: Copyright 2024 The Minder Authors
2
// SPDX-License-Identifier: Apache-2.0
3

4
package gitlab
5

6
import (
7
        "context"
8
        "encoding/json"
9
        "fmt"
10
        "net/http"
11
        "net/url"
12

13
        gitlab "gitlab.com/gitlab-org/api/client-go"
14

15
        pbinternal "github.com/mindersec/minder/internal/proto"
16
        "github.com/mindersec/minder/pkg/entities/properties"
17
        provifv1 "github.com/mindersec/minder/pkg/providers/v1"
18
)
19

20
// FormatPullRequestUpstreamID returns the upstream ID for a gitlab merge request
21
// This is done so we don't have to deal with conversions in the provider
22
// when dealing with entities
23
func FormatPullRequestUpstreamID(id int) string {
×
24
        return fmt.Sprintf("%d", id)
×
25
}
×
26

27
//nolint:gocyclo // TODO: Refactor to reduce complexity
28
func (c *gitlabClient) getPropertiesForPullRequest(
29
        ctx context.Context, getByProps *properties.Properties,
30
) (*properties.Properties, error) {
×
31
        uid, err := getByProps.GetProperty(properties.PropertyUpstreamID).AsString()
×
32
        if err != nil {
×
33
                return nil, fmt.Errorf("upstream ID not found or invalid: %w", err)
×
34
        }
×
35

36
        iid, err := getByProps.GetProperty(PullRequestNumber).AsString()
×
37
        if err != nil {
×
38
                return nil, fmt.Errorf("merge request number not found or invalid: %w", err)
×
39
        }
×
40

41
        pid, err := getByProps.GetProperty(PullRequestProjectID).AsString()
×
42
        if err != nil {
×
43
                return nil, fmt.Errorf("project ID not found or invalid: %w", err)
×
44
        }
×
45

46
        mrURLPath, err := url.JoinPath("projects", pid, "merge_requests", iid)
×
47
        if err != nil {
×
48
                return nil, fmt.Errorf("failed to join URL path for merge request using upstream ID: %w", err)
×
49
        }
×
50

51
        // NOTE: We're not using github.com/xanzy/go-gitlab to do the actual
52
        // request here because of the way they form authentication for requests.
53
        // It would be ideal to use it, so we should consider contributing and making
54
        // that part more pluggable.
55
        req, err := c.NewRequest("GET", mrURLPath, nil)
×
56
        if err != nil {
×
57
                return nil, fmt.Errorf("failed to create request: %w", err)
×
58
        }
×
59

60
        resp, err := c.Do(ctx, req)
×
61
        if err != nil {
×
62
                return nil, fmt.Errorf("failed to get merge request: %w", err)
×
63
        }
×
64

65
        defer resp.Body.Close()
×
66

×
67
        if resp.StatusCode != http.StatusOK {
×
68
                if resp.StatusCode == http.StatusNotFound {
×
69
                        return nil, provifv1.ErrEntityNotFound
×
70
                }
×
71

72
                return nil, fmt.Errorf("failed to get merge request: %s", resp.Status)
×
73
        }
74

75
        mr := &gitlab.MergeRequest{}
×
76
        if err := json.NewDecoder(resp.Body).Decode(mr); err != nil {
×
77
                return nil, fmt.Errorf("failed to decode response: %w", err)
×
78
        }
×
79

80
        // Validate - merge request upstream ID must match the one we requested
81
        if res := FormatPullRequestUpstreamID(mr.ID); res != uid {
×
82
                return nil, fmt.Errorf("merge request ID mismatch: %s != %s", res, uid)
×
83
        }
×
84

85
        proj, err := c.getGitLabProject(ctx, pid)
×
86
        if err != nil {
×
87
                return nil, fmt.Errorf("failed to get project: %w", err)
×
88
        }
×
89

90
        targetproj := proj
×
91
        if mr.SourceProjectID != 0 && mr.SourceProjectID != proj.ID {
×
92
                targetproj, err = c.getGitLabProject(ctx, FormatRepositoryUpstreamID(mr.SourceProjectID))
×
93
                if err != nil {
×
94
                        return nil, fmt.Errorf("failed to get target project: %w", err)
×
95
                }
×
96
        }
97

98
        outProps, err := gitlabMergeRequestToProperties(mr, proj, targetproj)
×
99
        if err != nil {
×
100
                return nil, fmt.Errorf("failed to convert merge request to properties: %w", err)
×
101
        }
×
102

103
        return outProps, nil
×
104
}
105

106
func gitlabMergeRequestToProperties(
107
        mr *gitlab.MergeRequest, proj *gitlab.Project, targetproj *gitlab.Project) (*properties.Properties, error) {
×
108
        ns, err := getGitlabProjectNamespace(proj)
×
109
        if err != nil {
×
110
                return nil, fmt.Errorf("failed to get namespace: %w", err)
×
111
        }
×
112

113
        projName := proj.Name
×
114

×
115
        outProps := properties.NewProperties(map[string]any{
×
116
                // Unique upstream ID for the merge request
×
117
                properties.PropertyUpstreamID:           FormatPullRequestUpstreamID(mr.ID),
×
118
                properties.PropertyName:                 formatPullRequestName(ns, projName, FormatPullRequestUpstreamID(mr.IID)),
×
119
                properties.PullRequestCommitSHA:         mr.SHA,
×
120
                properties.PullRequestBaseCloneURL:      proj.HTTPURLToRepo,
×
121
                properties.PullRequestBaseBranch:        mr.TargetBranch,
×
122
                properties.PullRequestBaseDefaultBranch: mr.TargetBranch,
×
123
                properties.PullRequestTargetCloneURL:    targetproj.HTTPURLToRepo,
×
124
                properties.PullRequestTargetBranch:      mr.SourceBranch,
×
125
                properties.PullRequestUpstreamURL:       mr.WebURL,
×
126
                RepoPropertyNamespace:                   ns,
×
127
                RepoPropertyProjectName:                 projName,
×
128
                // internal ID of the merge request
×
129
                PullRequestNumber:    FormatPullRequestUpstreamID(mr.IID),
×
130
                PullRequestProjectID: FormatRepositoryUpstreamID(proj.ID),
×
131
                PullRequestAuthor:    int64(mr.Author.ID),
×
132
        })
×
133

×
134
        return outProps, nil
×
135
}
136

137
func pullRequestV1FromProperties(prProps *properties.Properties) (*pbinternal.PullRequest, error) {
×
138
        _, err := prProps.GetProperty(properties.PropertyUpstreamID).AsString()
×
139
        if err != nil {
×
140
                return nil, fmt.Errorf("failed to get upstream ID: %w", err)
×
141
        }
×
142

143
        id := prProps.GetProperty(PullRequestNumber).GetInt64()
×
144
        if id == 0 {
×
145
                return nil, fmt.Errorf("failed to get merge request number: %w", provifv1.ErrEntityNotFound)
×
146
        }
×
147

148
        ns, err := getStringProp(prProps, RepoPropertyNamespace)
×
149
        if err != nil {
×
150
                return nil, fmt.Errorf("failed to get namespace: %w", err)
×
151
        }
×
152

153
        projName, err := getStringProp(prProps, RepoPropertyProjectName)
×
154
        if err != nil {
×
155
                return nil, fmt.Errorf("failed to get project name: %w", err)
×
156
        }
×
157

158
        commitSha, err := getStringProp(prProps, properties.PullRequestCommitSHA)
×
159
        if err != nil {
×
160
                return nil, fmt.Errorf("failed to get commit SHA: %w", err)
×
161
        }
×
162

163
        mrURL, err := getStringProp(prProps, properties.PullRequestUpstreamURL)
×
164
        if err != nil {
×
165
                return nil, fmt.Errorf("failed to get merge request URL: %w", err)
×
166
        }
×
167

168
        authorID, err := prProps.GetProperty(PullRequestAuthor).AsInt64()
×
169
        if err != nil {
×
170
                return nil, fmt.Errorf("failed to get author ID: %w", err)
×
171
        }
×
172

173
        basecloneurl := prProps.GetProperty(properties.PullRequestBaseCloneURL).GetString()
×
174
        targetcloneurl := prProps.GetProperty(properties.PullRequestTargetCloneURL).GetString()
×
175
        basebranch := prProps.GetProperty(properties.PullRequestBaseDefaultBranch).GetString()
×
176
        targetbranch := prProps.GetProperty(properties.PullRequestTargetBranch).GetString()
×
177

×
178
        pbPR := &pbinternal.PullRequest{
×
179
                Number:         id,
×
180
                RepoOwner:      ns,
×
181
                RepoName:       projName,
×
182
                CommitSha:      commitSha,
×
183
                AuthorId:       authorID,
×
184
                Url:            mrURL,
×
185
                BaseCloneUrl:   basecloneurl,
×
186
                TargetCloneUrl: targetcloneurl,
×
187
                BaseRef:        basebranch,
×
188
                TargetRef:      targetbranch,
×
189
                Properties:     prProps.ToProtoStruct(),
×
190
        }
×
191

×
192
        return pbPR, nil
×
193
}
194

195
func getPullRequestNameFromProperties(props *properties.Properties) (string, error) {
×
196
        groupName, err := getStringProp(props, RepoPropertyNamespace)
×
197
        if err != nil {
×
198
                return "", err
×
199
        }
×
200

201
        projectName, err := getStringProp(props, RepoPropertyProjectName)
×
202
        if err != nil {
×
203
                return "", err
×
204
        }
×
205

206
        iid, err := getStringProp(props, PullRequestNumber)
×
207
        if err != nil {
×
208
                return "", err
×
209
        }
×
210

211
        return formatPullRequestName(groupName, projectName, iid), nil
×
212
}
213

214
func formatPullRequestName(groupName, projectName, iid string) string {
×
215
        return fmt.Sprintf("%s/%s/%s", groupName, projectName, iid)
×
216
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc