• 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

29.91
/internal/providers/github/properties/pull_request.go
1
// SPDX-FileCopyrightText: Copyright 2024 The Minder Authors
2
// SPDX-License-Identifier: Apache-2.0
3

4
// Package properties provides utility functions for fetching and managing properties
5
package properties
6

7
import (
8
        "context"
9
        "fmt"
10
        "math"
11
        "net/http"
12
        "strconv"
13
        "strings"
14

15
        go_github "github.com/google/go-github/v63/github"
16

17
        pbinternal "github.com/mindersec/minder/internal/proto"
18
        "github.com/mindersec/minder/pkg/entities/properties"
19
        v1 "github.com/mindersec/minder/pkg/providers/v1"
20
)
21

22
const (
23
        // PullPropertyURL is the URL of the pull request
24
        PullPropertyURL = "github/pull_url"
25
        // PullPropertyNumber is the number of the pull request
26
        PullPropertyNumber = "github/pull_number"
27
        // PullPropertySha is the sha of the pull request
28
        PullPropertySha = "github/pull_sha"
29
        // PullPropertyRepoOwner is the owner of the repository
30
        PullPropertyRepoOwner = "github/repo_owner"
31
        // PullPropertyRepoName is the name of the repository
32
        PullPropertyRepoName = "github/repo_name"
33
        // PullPropertyAuthorID is the ID of the author of the pull request
34
        PullPropertyAuthorID = "github/pull_author_id"
35
        // PullPropertyAuthorLogin is the login of the author of the pull request
36
        PullPropertyAuthorLogin = "github/pull_author_login"
37
        // PullPropertyAction is an operational property that represents the action that was taken on the pull request
38
        PullPropertyAction = "github/pull_action"
39
        // PullPropertyBaseCloneURL is the URL used to clone the repository
40
        PullPropertyBaseCloneURL = "github/clone_url"
41
        // PullPropertyTargetCloneURL is the URL used to clone the target repository
42
        PullPropertyTargetCloneURL = "github/target_url"
43
        // PullPropertyBaseRef is the base ref of the pull request
44
        PullPropertyBaseRef = "github/base_ref"
45
        // PullPropertyTargetRef is the target ref of the pull request
46
        PullPropertyTargetRef = "github/pull_ref"
47
)
48

49
var prPropertyDefinitions = []propertyOrigin{
50
        {
51
                keys: []string{
52
                        // general entity
53
                        properties.PropertyName,
54
                        properties.PropertyUpstreamID,
55
                        properties.PullRequestCommitSHA,
56
                        properties.PullRequestBaseCloneURL,
57
                        properties.PullRequestBaseDefaultBranch,
58
                        properties.PullRequestTargetCloneURL,
59
                        properties.PullRequestTargetBranch,
60
                        properties.PullRequestUpstreamURL,
61
                        // github-specific
62
                        PullPropertyURL,
63
                        PullPropertyNumber,
64
                        PullPropertySha,
65
                        PullPropertyRepoOwner,
66
                        PullPropertyRepoName,
67
                        PullPropertyAuthorID,
68
                        PullPropertyAuthorLogin,
69
                        PullPropertyAction,
70
                        PullPropertyBaseCloneURL,
71
                        PullPropertyTargetCloneURL,
72
                        PullPropertyBaseRef,
73
                        PullPropertyTargetRef,
74
                },
75
                wrapper: getPrWrapper,
76
        },
77
}
78

79
var prOperationalProperties = []string{
80
        PullPropertyAction,
81
}
82

83
// PullRequestFetcher is a property fetcher for github repositories
84
type PullRequestFetcher struct {
85
        propertyFetcherBase
86
}
87

88
// NewPullRequestFetcher creates a new PullRequestFetcher
89
func NewPullRequestFetcher() *PullRequestFetcher {
5✔
90
        return &PullRequestFetcher{
5✔
91
                propertyFetcherBase: propertyFetcherBase{
5✔
92
                        operationalProperties: prOperationalProperties,
5✔
93
                        propertyOrigins:       prPropertyDefinitions,
5✔
94
                },
5✔
95
        }
5✔
96
}
5✔
97

98
// GetName returns the name of the pull request
99
func (*PullRequestFetcher) GetName(props *properties.Properties) (string, error) {
5✔
100
        prOwner, err := props.GetProperty(PullPropertyRepoOwner).AsString()
5✔
101
        if err != nil {
5✔
102
                return "", fmt.Errorf("error fetching pr owner property: %w", err)
×
103
        }
×
104

105
        prName, err := props.GetProperty(PullPropertyRepoName).AsString()
5✔
106
        if err != nil {
5✔
107
                return "", fmt.Errorf("error fetching pr name property: %w", err)
×
108
        }
×
109

110
        prID, err := props.GetProperty(PullPropertyNumber).AsInt64()
5✔
111
        if err != nil {
5✔
112
                return "", fmt.Errorf("error fetching pr id property: %w", err)
×
113
        }
×
114

115
        return fmt.Sprintf("%s/%s/%d", prOwner, prName, prID), nil
5✔
116
}
117

118
func parsePrName(input string) (string, string, int64, error) {
×
119
        parts := strings.Split(input, "/")
×
120
        if len(parts) != 3 {
×
121
                return "", "", 0, fmt.Errorf("invalid input format")
×
122
        }
×
123

124
        repoOwner := parts[0]
×
125
        repoName := parts[1]
×
126
        prNumber, err := strconv.ParseInt(parts[2], 10, 64)
×
127
        if err != nil {
×
128
                return "", "", 0, fmt.Errorf("invalid prNumber: %w", err)
×
129
        }
×
130

131
        return repoOwner, repoName, prNumber, nil
×
132
}
133

134
func getPrWrapper(
135
        ctx context.Context, ghCli *go_github.Client, isOrg bool, getByProps *properties.Properties,
136
) (map[string]any, error) {
×
137
        _ = isOrg
×
138

×
139
        owner, name, id64, err := getPrWrapperAttrsFromProps(getByProps)
×
140
        if err != nil {
×
141
                return nil, fmt.Errorf("error getting pr wrapper attributes: %w", err)
×
142
        }
×
143

144
        if id64 > math.MaxInt {
×
145
                return nil, fmt.Errorf("pr number is too large")
×
146
        }
×
147
        intId := int(id64)
×
148

×
149
        prReply, result, err := ghCli.PullRequests.Get(ctx, owner, name, intId)
×
150
        if err != nil {
×
151
                if result != nil && result.StatusCode == http.StatusNotFound {
×
152
                        return nil, v1.ErrEntityNotFound
×
153
                }
×
154
                return nil, err
×
155
        }
156

157
        prProps := map[string]any{
×
158
                // general entity
×
159
                properties.PropertyUpstreamID:           properties.NumericalValueToUpstreamID(prReply.GetID()),
×
160
                properties.PropertyName:                 fmt.Sprintf("%s/%s/%d", owner, name, intId),
×
161
                properties.PullRequestCommitSHA:         prReply.GetHead().GetSHA(),
×
162
                properties.PullRequestBaseCloneURL:      prReply.GetBase().GetRepo().GetCloneURL(),
×
163
                properties.PullRequestBaseBranch:        prReply.GetBase().GetRef(),
×
164
                properties.PullRequestBaseDefaultBranch: prReply.GetBase().GetRepo().GetDefaultBranch(),
×
165
                properties.PullRequestTargetCloneURL:    prReply.GetHead().GetRepo().GetCloneURL(),
×
166
                properties.PullRequestTargetBranch:      prReply.GetHead().GetRef(),
×
167
                properties.PullRequestUpstreamURL:       prReply.GetHTMLURL(),
×
168
                // github-specific (mostly legacy, prefer common properties) above where supported.
×
169
                PullPropertyURL: prReply.GetHTMLURL(), // prefer upstream_url
×
170
                // our proto representation uses int64 for the number but GH uses int
×
171
                PullPropertyNumber:         int64(prReply.GetNumber()),
×
172
                PullPropertySha:            prReply.GetHead().GetSHA(), // prefer commit_sha
×
173
                PullPropertyRepoOwner:      owner,
×
174
                PullPropertyRepoName:       name,
×
175
                PullPropertyAuthorID:       prReply.GetUser().GetID(),
×
176
                PullPropertyAuthorLogin:    prReply.GetUser().GetLogin(),
×
177
                PullPropertyBaseCloneURL:   prReply.GetBase().GetRepo().GetCloneURL(), // prefer base_clone_url
×
178
                PullPropertyTargetCloneURL: prReply.GetHead().GetRepo().GetCloneURL(), // prefer target_clone_url
×
179
                PullPropertyBaseRef:        prReply.GetBase().GetRef(),                // prefer base_branch
×
180
                PullPropertyTargetRef:      prReply.GetHead().GetRef(),                // prefer target_branch
×
181
        }
×
182

×
183
        return prProps, nil
×
184
}
185

186
func getPrWrapperAttrsFromProps(props *properties.Properties) (string, string, int64, error) {
×
187
        repoOwnerP := props.GetProperty(PullPropertyRepoOwner)
×
188
        repoNameP := props.GetProperty(PullPropertyRepoName)
×
189
        repoIdP := props.GetProperty(PullPropertyNumber)
×
190
        if repoOwnerP != nil && repoNameP != nil && repoIdP != nil {
×
191
                return repoOwnerP.GetString(), repoNameP.GetString(), repoIdP.GetInt64(), nil
×
192
        }
×
193

194
        prNameP := props.GetProperty(properties.PropertyName)
×
195
        if prNameP != nil {
×
196
                return parsePrName(prNameP.GetString())
×
197
        }
×
198

199
        return "", "", 0, fmt.Errorf("missing required properties")
×
200
}
201

202
// PullRequestV1FromProperties creates a PullRequestV1 from a properties object
203
func PullRequestV1FromProperties(props *properties.Properties) (*pbinternal.PullRequest, error) {
1✔
204
        return &pbinternal.PullRequest{
1✔
205
                Url:            props.GetProperty(properties.PullRequestUpstreamURL).GetString(),
1✔
206
                CommitSha:      props.GetProperty(properties.PullRequestCommitSHA).GetString(),
1✔
207
                TargetRef:      props.GetProperty(properties.PullRequestTargetBranch).GetString(),
1✔
208
                BaseRef:        props.GetProperty(properties.PullRequestBaseBranch).GetString(),
1✔
209
                Number:         props.GetProperty(PullPropertyNumber).GetInt64(),
1✔
210
                RepoOwner:      props.GetProperty(PullPropertyRepoOwner).GetString(),
1✔
211
                RepoName:       props.GetProperty(PullPropertyRepoName).GetString(),
1✔
212
                AuthorId:       props.GetProperty(PullPropertyAuthorID).GetInt64(),
1✔
213
                Action:         props.GetProperty(PullPropertyAction).GetString(),
1✔
214
                BaseCloneUrl:   props.GetProperty(properties.PullRequestBaseCloneURL).GetString(),
1✔
215
                TargetCloneUrl: props.GetProperty(properties.PullRequestTargetCloneURL).GetString(),
1✔
216
                Properties:     props.ToProtoStruct(),
1✔
217
        }, nil
1✔
218
}
1✔
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

© 2025 Coveralls, Inc