mirror of
https://github.com/ossf/scorecard.git
synced 2024-09-20 13:37:13 +03:00
fa42daff71
* doc: Updating gitlab support validation status Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * bug: Updated logic for gitlab to prevent exceptions based on releases Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * test: Added initial tests for gitlab branches Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * doc: Updated general README Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * refactor: Cleaned up the query for pipelines to be focused on the commitID Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * feat: Allowed for a non-graphql method of retrieving MRs associated to a commit Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * doc: Updated status for the CI-Tests Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> * bug: Updated the host url for graphql querying. This enabled the removal of the code added for handling empty returns when executing against a non-gitlab.com repository. Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> --------- Signed-off-by: Robison, Jim B <jim.b.robison@lmco.com> Co-authored-by: Raghav Kaul <8695110+raghavkaul@users.noreply.github.com>
144 lines
3.8 KiB
Go
144 lines
3.8 KiB
Go
// Copyright 2023 OpenSSF Scorecard Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package gitlabrepo
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/shurcooL/graphql"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
//nolint:govet
|
|
type graphqlHandler struct {
|
|
err error
|
|
client *http.Client
|
|
graphClient *graphql.Client
|
|
ctx context.Context
|
|
repourl *repoURL
|
|
}
|
|
|
|
func (handler *graphqlHandler) init(ctx context.Context, repourl *repoURL) {
|
|
handler.ctx = ctx
|
|
handler.repourl = repourl
|
|
handler.err = nil
|
|
|
|
src := oauth2.StaticTokenSource(
|
|
&oauth2.Token{AccessToken: os.Getenv("GITLAB_AUTH_TOKEN")},
|
|
)
|
|
handler.client = oauth2.NewClient(context.Background(), src)
|
|
handler.graphClient = graphql.NewClient(fmt.Sprintf("%s/api/graphql", repourl.Host()), handler.client)
|
|
}
|
|
|
|
//nolint:govet
|
|
type graphqlData struct {
|
|
Project struct {
|
|
MergeRequests struct {
|
|
Nodes []graphqlMergeRequestNode `graphql:"nodes"`
|
|
} `graphql:"mergeRequests(sort: MERGED_AT_DESC, state: merged, mergedBefore: $mergedBefore)"`
|
|
} `graphql:"project(fullPath: $fullPath)"`
|
|
QueryComplexity struct {
|
|
Limit int `graphql:"limit"`
|
|
Score int `graphql:"score"`
|
|
} `graphql:"queryComplexity"`
|
|
}
|
|
|
|
//nolint:govet
|
|
type graphqlMergeRequestNode struct {
|
|
ID GitlabGID `graphql:"id"`
|
|
IID string `graphql:"iid"`
|
|
MergedAt time.Time `graphql:"mergedAt"`
|
|
Author struct {
|
|
Username string `graphql:"username"`
|
|
ID GitlabGID `graphql:"id"`
|
|
} `graphql:"author"`
|
|
MergedBy struct {
|
|
Username string `graphql:"username"`
|
|
ID GitlabGID `graphql:"id"`
|
|
} `graphql:"mergeUser"`
|
|
Commits struct {
|
|
Nodes []struct {
|
|
SHA string `graphql:"sha"`
|
|
} `graphql:"nodes"`
|
|
} `graphql:"commits"`
|
|
Reviewers struct {
|
|
Nodes []struct {
|
|
Username string `graphql:"username"`
|
|
ID GitlabGID `graphql:"id"`
|
|
MergeRequestInteraction struct {
|
|
ReviewState string `graphql:"reviewState"`
|
|
} `graphql:"mergeRequestInteraction"`
|
|
} `graphql:"nodes"`
|
|
} `graphql:"reviewers"`
|
|
Approvers struct {
|
|
Nodes []struct {
|
|
Username string `graphql:"username"`
|
|
ID GitlabGID `graphql:"id"`
|
|
} `graphql:"nodes"`
|
|
} `graphql:"approvedBy"`
|
|
MergeCommitSHA string `graphql:"mergeCommitSha"`
|
|
// Labels struct {
|
|
// Nodes []struct {
|
|
// Title string `graphql:"title"`
|
|
// } `graphql:"nodes"`
|
|
// } `graphql:"labels"`
|
|
}
|
|
|
|
type GitlabGID struct {
|
|
Type string
|
|
ID int
|
|
}
|
|
|
|
var errGitlabID = errors.New("failed to parse gitlab id")
|
|
|
|
func (g *GitlabGID) UnmarshalJSON(data []byte) error {
|
|
re := regexp.MustCompile(`gid:\/\/gitlab\/(\w+)\/(\d+)`)
|
|
m := re.FindStringSubmatch(string(data))
|
|
if len(m) < 3 {
|
|
return fmt.Errorf("%w: %s", errGitlabID, string(data))
|
|
}
|
|
g.Type = m[1]
|
|
|
|
id, err := strconv.Atoi(m[2])
|
|
if err != nil {
|
|
return fmt.Errorf("gid parse error: %w", err)
|
|
}
|
|
g.ID = id
|
|
|
|
return nil
|
|
}
|
|
|
|
func (handler *graphqlHandler) getMergeRequestsDetail(before *time.Time) (graphqlData, error) {
|
|
data := graphqlData{}
|
|
path := fmt.Sprintf("%s/%s", handler.repourl.owner, handler.repourl.project)
|
|
params := map[string]interface{}{
|
|
"fullPath": path,
|
|
"mergedBefore": before,
|
|
}
|
|
err := handler.graphClient.Query(context.Background(), &data, params)
|
|
if err != nil {
|
|
return graphqlData{}, fmt.Errorf("couldn't query gitlab graphql for merge requests: %w", err)
|
|
}
|
|
|
|
return data, nil
|
|
}
|