Skip to content

Commit 91feae8

Browse files
Capture repo info (#571)
* fix gitlab approvers format in pr v2 payload * capture repo info for attestation commands * capture repo info for beging trail and attest artifact * send empty list of approvers for v1 gitlab pr attestation since old evidence api does not accept none for approvers.
1 parent 20e76df commit 91feae8

6 files changed

Lines changed: 111 additions & 9 deletions

File tree

cmd/kosli/attestArtifact.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type AttestArtifactPayload struct {
2929
Filename string `json:"filename"`
3030
GitCommit string `json:"git_commit"`
3131
GitCommitInfo *gitview.BasicCommitInfo `json:"git_commit_info"`
32+
GitRepoInfo *gitview.GitRepoInfo `json:"repo_info"`
3233
BuildUrl string `json:"build_url"`
3334
CommitUrl string `json:"commit_url"`
3435
RepoUrl string `json:"repo_url"`
@@ -188,6 +189,10 @@ func (o *attestArtifactOptions) run(args []string) error {
188189
if err != nil {
189190
return err
190191
}
192+
o.payload.GitRepoInfo, err = getGitRepoInfoFromEnvironment()
193+
if err != nil {
194+
logger.Warn("failed to get git repo info. %s", err.Error())
195+
}
191196
o.payload.GitCommit = commitInfo.Sha1
192197
o.payload.GitCommitInfo = &commitInfo.BasicCommitInfo
193198

cmd/kosli/attestation.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"os"
56
"regexp"
67
"strings"
78

@@ -22,6 +23,7 @@ type URLInfo struct {
2223
type CommonAttestationPayload struct {
2324
ArtifactFingerprint string `json:"artifact_fingerprint,omitempty"`
2425
Commit *gitview.BasicCommitInfo `json:"git_commit_info,omitempty"`
26+
GitRepoInfo *gitview.GitRepoInfo `json:"repo_info,omitempty"`
2527
AttestationName string `json:"attestation_name"`
2628
TargetArtifacts []string `json:"target_artifacts,omitempty"`
2729
ExternalURLs map[string]*URLInfo `json:"external_urls,omitempty"`
@@ -79,6 +81,11 @@ func (o *CommonAttestationOptions) run(args []string, payload *CommonAttestation
7981
payload.Commit = &commitInfo.BasicCommitInfo
8082
}
8183

84+
payload.GitRepoInfo, err = getGitRepoInfoFromEnvironment()
85+
if err != nil {
86+
logger.Warn("failed to get git repo info. %s", err.Error())
87+
}
88+
8289
payload.UserData, err = LoadJsonData(o.userDataFilePath)
8390
if err != nil {
8491
return fmt.Errorf("failed to load user data. %s", err)
@@ -174,3 +181,70 @@ func wrapAttestationError(err error) error {
174181
}
175182
return err
176183
}
184+
185+
func getGitRepoInfoFromEnvironment() (*gitview.GitRepoInfo, error) {
186+
ci := WhichCI()
187+
switch ci {
188+
case github:
189+
return getGitRepoInfoFromGitHub(), nil
190+
case gitlab:
191+
return getGitRepoInfoFromGitLab(), nil
192+
case bitbucket:
193+
return getGitRepoInfoFromBitbucket(), nil
194+
case azureDevops:
195+
return getGitRepoInfoFromAzureDevops(), nil
196+
case circleci:
197+
return getGitRepoInfoFromCircleci(), nil
198+
case codeBuild:
199+
return getGitRepoInfoFromCodeBuild(), nil
200+
case unknown:
201+
return nil, nil
202+
}
203+
return nil, fmt.Errorf("unsupported CI: %s", ci)
204+
}
205+
206+
func getGitRepoInfoFromGitHub() *gitview.GitRepoInfo {
207+
return &gitview.GitRepoInfo{
208+
URL: fmt.Sprintf("%s/%s", os.Getenv("GITHUB_SERVER_URL"), os.Getenv("GITHUB_REPOSITORY")),
209+
Name: os.Getenv("GITHUB_REPOSITORY"),
210+
ID: os.Getenv("GITHUB_REPOSITORY_ID"),
211+
}
212+
}
213+
214+
func getGitRepoInfoFromGitLab() *gitview.GitRepoInfo {
215+
return &gitview.GitRepoInfo{
216+
URL: os.Getenv("CI_PROJECT_URL"),
217+
Name: os.Getenv("CI_PROJECT_PATH"),
218+
ID: os.Getenv("CI_PROJECT_ID"),
219+
Description: os.Getenv("CI_PROJECT_DESCRIPTION"),
220+
}
221+
}
222+
223+
func getGitRepoInfoFromBitbucket() *gitview.GitRepoInfo {
224+
return &gitview.GitRepoInfo{
225+
URL: os.Getenv("BITBUCKET_GIT_HTTP_ORIGIN"),
226+
Name: os.Getenv("BITBUCKET_REPO_FULL_NAME"),
227+
ID: os.Getenv("BITBUCKET_REPO_UUID"),
228+
}
229+
}
230+
231+
func getGitRepoInfoFromAzureDevops() *gitview.GitRepoInfo {
232+
return &gitview.GitRepoInfo{
233+
URL: os.Getenv("BUILD_REPOSITORY_URI"),
234+
Name: os.Getenv("BUILD_REPOSITORY_NAME"),
235+
ID: os.Getenv("BUILD_REPOSITORY_ID"),
236+
}
237+
}
238+
239+
func getGitRepoInfoFromCircleci() *gitview.GitRepoInfo {
240+
return &gitview.GitRepoInfo{
241+
URL: os.Getenv("CIRCLE_REPOSITORY_URL"),
242+
Name: os.Getenv("CIRCLE_PROJECT_REPONAME"),
243+
}
244+
}
245+
246+
func getGitRepoInfoFromCodeBuild() *gitview.GitRepoInfo {
247+
return &gitview.GitRepoInfo{
248+
URL: os.Getenv("CODEBUILD_SOURCE_REPO_URL"),
249+
}
250+
}

cmd/kosli/beginTrail.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type TrailPayload struct {
4848
Description string `json:"description"`
4949
UserData interface{} `json:"user_data"`
5050
Commit *gitview.BasicCommitInfo `json:"git_commit_info,omitempty"`
51+
GitRepoInfo *gitview.GitRepoInfo `json:"repo_info,omitempty"`
5152
ExternalURLs map[string]*URLInfo `json:"external_urls,omitempty"`
5253
OriginURL string `json:"origin_url,omitempty"`
5354
}
@@ -122,6 +123,11 @@ func (o *beginTrailOptions) run(args []string) error {
122123
o.payload.Commit = &commitInfo.BasicCommitInfo
123124
}
124125

126+
o.payload.GitRepoInfo, err = getGitRepoInfoFromEnvironment()
127+
if err != nil {
128+
logger.Warn("failed to get git repo info. %s", err.Error())
129+
}
130+
125131
// process external urls
126132
o.payload.ExternalURLs, err = processExternalURLs(o.externalURLs, o.externalFingerprints)
127133
if err != nil {

internal/gitlab/gitlab.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55

66
"github.com/kosli-dev/cli/internal/types"
7-
"github.com/kosli-dev/cli/internal/utils"
87
gitlab "gitlab.com/gitlab-org/api/client-go"
98
)
109

@@ -79,11 +78,14 @@ func (c *GitlabConfig) newPRGitlabEvidenceV1(mr *gitlab.BasicMergeRequest) (*typ
7978
MergeCommit: mr.MergeCommitSHA,
8079
State: mr.State,
8180
}
82-
approvers, err := c.GetMergeRequestApprovers(mr.IID)
81+
approvers, err := c.GetMergeRequestApprovers(mr.IID, 1)
8382
if err != nil {
8483
return evidence, err
8584
}
86-
evidence.Approvers = utils.ConvertStringListToInterfaceList(approvers)
85+
if approvers == nil {
86+
approvers = []any{}
87+
}
88+
evidence.Approvers = approvers
8789
return evidence, nil
8890
}
8991

@@ -98,11 +100,11 @@ func (c *GitlabConfig) newPRGitlabEvidenceV2(mr *gitlab.BasicMergeRequest) (*typ
98100
Title: mr.Title,
99101
HeadRef: mr.SourceBranch,
100102
}
101-
approvers, err := c.GetMergeRequestApprovers(mr.IID)
103+
approvers, err := c.GetMergeRequestApprovers(mr.IID, 2)
102104
if err != nil {
103105
return evidence, err
104106
}
105-
evidence.Approvers = utils.ConvertStringListToInterfaceList(approvers)
107+
evidence.Approvers = approvers
106108
commits, err := c.GetMergeRequestCommits(mr)
107109
if err != nil {
108110
return evidence, err
@@ -127,8 +129,8 @@ func (c *GitlabConfig) MergeRequestsForCommit(commit string) ([]*gitlab.BasicMer
127129
}
128130

129131
// GetMergeRequestApprovers returns a list of users (name and username) who approved an MR
130-
func (c *GitlabConfig) GetMergeRequestApprovers(mrIID int) ([]string, error) {
131-
approvers := []string{}
132+
func (c *GitlabConfig) GetMergeRequestApprovers(mrIID, version int) ([]any, error) {
133+
var approvers []any
132134
client, err := c.NewGitlabClientFromToken()
133135
if err != nil {
134136
return approvers, err
@@ -137,8 +139,16 @@ func (c *GitlabConfig) GetMergeRequestApprovers(mrIID int) ([]string, error) {
137139
if err != nil {
138140
return approvers, err
139141
}
142+
140143
for _, approver := range approvals.ApprovedBy {
141-
approvers = append(approvers, fmt.Sprintf("%s (@%s)", approver.User.Name, approver.User.Username))
144+
approverName := fmt.Sprintf("%s (@%s)", approver.User.Name, approver.User.Username)
145+
if version == 1 {
146+
approvers = append(approvers, approverName)
147+
} else {
148+
approvers = append(approvers, types.PRApprovals{
149+
Username: approverName,
150+
})
151+
}
142152
}
143153
return approvers, nil
144154
}

internal/gitlab/gitlab_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func (suite *GitlabTestSuite) TestGetMergeRequestApprovers() {
288288
testHelpers.SkipIfEnvVarUnset(suite.Suite.T(), []string{"KOSLI_GITLAB_TOKEN"})
289289
t.gitlabConfig.Token = os.Getenv("KOSLI_GITLAB_TOKEN")
290290
}
291-
approvers, err := t.gitlabConfig.GetMergeRequestApprovers(t.mrIID)
291+
approvers, err := t.gitlabConfig.GetMergeRequestApprovers(t.mrIID, 1)
292292
if t.result.wantError {
293293
require.Error(suite.Suite.T(), err)
294294
} else {

internal/gitview/gitView.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ type CommitInfo struct {
2828
Parents []string `json:"parents"`
2929
}
3030

31+
type GitRepoInfo struct {
32+
URL string `json:"url,omitempty"`
33+
Name string `json:"name,omitempty"`
34+
ID string `json:"id,omitempty"`
35+
Description string `json:"description,omitempty"`
36+
}
37+
3138
// GitView
3239
// A read-only view of a git repository.
3340
type GitView struct {

0 commit comments

Comments
 (0)