mirror of
https://github.com/ossf/scorecard.git
synced 2024-09-11 17:07:53 +03:00
✨ Add checks for workflow action pinning (#466)
Patch by Laurent Simon <laurentsimon@google.com> Co-authored-by: Laurent Simon <laurentsimon@google.com>
This commit is contained in:
parent
9281d1ddd9
commit
5f82d2b9c0
@ -14,6 +14,8 @@
|
||||
|
||||
package checker
|
||||
|
||||
import "errors"
|
||||
|
||||
const MaxResultConfidence = 10
|
||||
|
||||
type CheckResult struct {
|
||||
@ -25,11 +27,12 @@ type CheckResult struct {
|
||||
ShouldRetry bool `json:"-"`
|
||||
}
|
||||
|
||||
func MakeInconclusiveResult(name string) CheckResult {
|
||||
func MakeInconclusiveResult(name string, err error) CheckResult {
|
||||
return CheckResult{
|
||||
Name: name,
|
||||
Pass: false,
|
||||
Confidence: 0,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +56,7 @@ func MakeRetryResult(name string, err error) CheckResult {
|
||||
func MakeProportionalResult(name string, numerator int, denominator int,
|
||||
threshold float32) CheckResult {
|
||||
if denominator == 0 {
|
||||
return MakeInconclusiveResult(name)
|
||||
return MakeInconclusiveResult(name, errors.New("internal error: denominator is 0"))
|
||||
}
|
||||
if numerator == 0 {
|
||||
return CheckResult{
|
||||
|
@ -62,7 +62,8 @@ func Bool2int(b bool) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func MultiCheck(fns ...CheckFn) CheckFn {
|
||||
// Returns the best check result out of several ones performed.
|
||||
func MultiCheckOr(fns ...CheckFn) CheckFn {
|
||||
return func(c *CheckRequest) CheckResult {
|
||||
var maxResult CheckResult
|
||||
|
||||
@ -81,3 +82,26 @@ func MultiCheck(fns ...CheckFn) CheckFn {
|
||||
return maxResult
|
||||
}
|
||||
}
|
||||
|
||||
// All checks must succeed. This returns a conservative result
|
||||
// where the worst result is returned.
|
||||
func MultiCheckAnd(fns ...CheckFn) CheckFn {
|
||||
return func(c *CheckRequest) CheckResult {
|
||||
minResult := CheckResult{
|
||||
Pass: true,
|
||||
Confidence: MaxResultConfidence,
|
||||
}
|
||||
|
||||
for _, fn := range fns {
|
||||
result := fn(c)
|
||||
if len(minResult.Name) == 0 {
|
||||
minResult.Name = result.Name
|
||||
}
|
||||
if Bool2int(result.Pass) < Bool2int(minResult.Pass) ||
|
||||
result.Confidence < MaxResultConfidence {
|
||||
minResult = result
|
||||
}
|
||||
}
|
||||
return minResult
|
||||
}
|
||||
}
|
||||
|
133
checks/checkforcontent.go
Normal file
133
checks/checkforcontent.go
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright 2020 Security 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 checks
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/ossf/scorecard/checker"
|
||||
)
|
||||
|
||||
// CheckFilesContent downloads the tar of the repository and calls the onFileContent() function
|
||||
// shellPathFnPattern is used for https://golang.org/pkg/path/#Match
|
||||
func CheckFilesContent(checkName, shellPathFnPattern string, c *checker.CheckRequest,
|
||||
onFileContent func(path string, content []byte, Logf func(s string, f ...interface{})) (bool, error)) checker.CheckResult {
|
||||
r, _, err := c.Client.Repositories.Get(c.Ctx, c.Owner, c.Repo)
|
||||
if err != nil {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
}
|
||||
url := r.GetArchiveURL()
|
||||
url = strings.Replace(url, "{archive_format}", "tarball/", 1)
|
||||
url = strings.Replace(url, "{/ref}", r.GetDefaultBranch(), 1)
|
||||
|
||||
// Using the http.get instead of the lib httpClient because
|
||||
// the default checker.HTTPClient caches everything in the memory and it causes oom.
|
||||
|
||||
//https://securego.io/docs/rules/g107.html
|
||||
//nolint
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
gz, err := gzip.NewReader(resp.Body)
|
||||
if err != nil {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
}
|
||||
tr := tar.NewReader(gz)
|
||||
res := true
|
||||
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err != nil && err != io.EOF {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
}
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
// Only consider regular files.
|
||||
if hdr.Typeflag != tar.TypeReg || hdr.Size == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Strip the repo name
|
||||
const splitLength = 2
|
||||
names := strings.SplitN(hdr.Name, "/", splitLength)
|
||||
if len(names) < splitLength {
|
||||
continue
|
||||
}
|
||||
|
||||
name := names[1]
|
||||
// Filter out files based on path.
|
||||
if match, _ := path.Match(shellPathFnPattern, name); !match {
|
||||
continue
|
||||
}
|
||||
|
||||
content := make([]byte, hdr.Size)
|
||||
n, err := tr.Read(content)
|
||||
if err != nil && err != io.EOF {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
}
|
||||
// We should have reached the end of files AND
|
||||
// the number of bytes should be the same as number
|
||||
// indicated in header, unless the file format supports
|
||||
// sparse regions. Only USTAR format does not support
|
||||
// spare regions -- see https://golang.org/pkg/archive/tar/
|
||||
if hdr.Format != tar.FormatUSTAR &&
|
||||
hdr.Format != tar.FormatUnknown &&
|
||||
int64(n) != hdr.Size {
|
||||
return checker.MakeRetryResult(checkName, fmt.Errorf("could not read entire file"))
|
||||
}
|
||||
|
||||
// We truncate the file to remove tailing 0 (sparse format).
|
||||
rr, err := onFileContent(name, content[:n], c.Logf)
|
||||
if err != nil {
|
||||
return checker.CheckResult{
|
||||
Name: checkName,
|
||||
Pass: false,
|
||||
Confidence: 10,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
// We don't return rightway to give the onFileContent()
|
||||
// handler to log.
|
||||
if !rr {
|
||||
res = false
|
||||
}
|
||||
}
|
||||
|
||||
if !res {
|
||||
return checker.CheckResult{
|
||||
Name: checkName,
|
||||
Pass: false,
|
||||
Confidence: 10,
|
||||
}
|
||||
}
|
||||
|
||||
return checker.CheckResult{
|
||||
Name: checkName,
|
||||
Pass: true,
|
||||
Confidence: 10,
|
||||
}
|
||||
}
|
@ -24,10 +24,10 @@ import (
|
||||
"github.com/ossf/scorecard/checker"
|
||||
)
|
||||
|
||||
// CheckIfFileExists downloads the tar of the repository and calls the predicate to check
|
||||
// CheckIfFileExists downloads the tar of the repository and calls the onFile() to check
|
||||
// for the occurrence.
|
||||
func CheckIfFileExists(checkName string, c *checker.CheckRequest, predicate func(name string,
|
||||
Logf func(s string, f ...interface{})) bool) checker.CheckResult {
|
||||
func CheckIfFileExists(checkName string, c *checker.CheckRequest, onFile func(name string,
|
||||
Logf func(s string, f ...interface{})) (bool, error)) checker.CheckResult {
|
||||
r, _, err := c.Client.Repositories.Get(c.Ctx, c.Owner, c.Repo)
|
||||
if err != nil {
|
||||
return checker.MakeRetryResult(checkName, err)
|
||||
@ -69,7 +69,17 @@ func CheckIfFileExists(checkName string, c *checker.CheckRequest, predicate func
|
||||
}
|
||||
|
||||
name := names[1]
|
||||
if predicate(name, c.Logf) {
|
||||
rr, err := onFile(name, c.Logf)
|
||||
if err != nil {
|
||||
return checker.CheckResult{
|
||||
Name: checkName,
|
||||
Pass: false,
|
||||
Confidence: 10,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
||||
if rr {
|
||||
return checker.MakePassResult(checkName)
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ This check tries to determine if a project has a set of contributors from multip
|
||||
|
||||
## Frozen-Deps
|
||||
|
||||
This check tries to determine if a project has declared and pinned its dependencies. It works by looking for the following files in the root directory: go.mod, go.sum (Golang), package-lock.json, npm-shrinkwrap.json (Javascript), requirements.txt, pipfile.lock (Python), gemfile.lock (Ruby), cargo.lock (Rust), yarn.lock (package manager), composer.lock (PHP), vendor/, third_party/, third-party/. If any of these files exists, the check succeeds. This check does not currently look for docker image pinning and shell script pinning.
|
||||
This check tries to determine if a project has declared and pinned its dependencies. It works by (1) looking for the following files in the root directory: go.mod, go.sum (Golang), package-lock.json, npm-shrinkwrap.json (Javascript), requirements.txt, pipfile.lock (Python), gemfile.lock (Ruby), cargo.lock (Rust), yarn.lock (package manager), composer.lock (PHP), vendor/, third_party/, third-party/; (2) look for github actions under .github/workflows/ and verifies they are pinned by hash. If one of the files in (1) AND all the dependencies in (2) are pinned, the check succeds. This check does not currently look for docker image pinning and shell script pinning.
|
||||
|
||||
**Remediation steps**
|
||||
- Declare all your dependencies with specific versions in your package format file (e.g. `package.json` for npm, `requirements.txt` for python). For C/C++, check in the code from a trusted source and add a `README` on the specific version used (and the archive SHA hashes).
|
||||
|
@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
# This is the source of truth for all check descriptions and remediation steps.
|
||||
# Run `cd checks/main && go build && ./main` to generate `checks.json` and `checks.md`.
|
||||
# Run `cd checks/main && go run /main` to generate `checks.json` and `checks.md`.
|
||||
checks:
|
||||
Security-Policy:
|
||||
description: >-
|
||||
@ -45,13 +45,15 @@ checks:
|
||||
Frozen-Deps:
|
||||
description: >-
|
||||
This check tries to determine if a project has declared and pinned its
|
||||
dependencies. It works by looking for the following files in the root
|
||||
dependencies. It works by (1) looking for the following files in the root
|
||||
directory: go.mod, go.sum (Golang), package-lock.json, npm-shrinkwrap.json
|
||||
(Javascript), requirements.txt, pipfile.lock (Python), gemfile.lock
|
||||
(Ruby), cargo.lock (Rust), yarn.lock (package manager), composer.lock
|
||||
(PHP), vendor/, third_party/, third-party/. If any of these files exists,
|
||||
the check succeeds. This check does not currently look for docker image
|
||||
pinning and shell script pinning.
|
||||
(PHP), vendor/, third_party/, third-party/; (2) look for github actions
|
||||
under .github/workflows/ and verifies they are pinned by hash. If one of
|
||||
the files in (1) AND all the dependencies in (2) are pinned, the check
|
||||
succeds. This check does not currently look for docker image pinning and
|
||||
shell script pinning.
|
||||
remediation:
|
||||
- >-
|
||||
Declare all your dependencies with specific versions in your package
|
||||
|
@ -15,6 +15,7 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
@ -33,7 +34,7 @@ func init() {
|
||||
// - Checking if most of the recent merged PRs were "Approved".
|
||||
// - Looking for other well-known review labels.
|
||||
func DoesCodeReview(c *checker.CheckRequest) checker.CheckResult {
|
||||
return checker.MultiCheck(
|
||||
return checker.MultiCheckOr(
|
||||
IsPrReviewRequired,
|
||||
GithubCodeReview,
|
||||
ProwCodeReview,
|
||||
@ -47,7 +48,7 @@ func GithubCodeReview(c *checker.CheckRequest) checker.CheckResult {
|
||||
State: "closed",
|
||||
})
|
||||
if err != nil {
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, err)
|
||||
}
|
||||
|
||||
totalMerged := 0
|
||||
@ -105,7 +106,7 @@ func IsPrReviewRequired(c *checker.CheckRequest) checker.CheckResult {
|
||||
// Check the branch protection rules, we may not be able to get these though.
|
||||
bp, _, err := c.Client.Repositories.GetBranchProtection(c.Ctx, c.Owner, c.Repo, r.GetDefaultBranch())
|
||||
if err != nil {
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, err)
|
||||
}
|
||||
if bp.GetRequiredPullRequestReviews() != nil &&
|
||||
bp.GetRequiredPullRequestReviews().RequiredApprovingReviewCount >= 1 {
|
||||
@ -117,7 +118,7 @@ func IsPrReviewRequired(c *checker.CheckRequest) checker.CheckResult {
|
||||
Confidence: confidence,
|
||||
}
|
||||
}
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, nil)
|
||||
}
|
||||
|
||||
func ProwCodeReview(c *checker.CheckRequest) checker.CheckResult {
|
||||
@ -126,7 +127,7 @@ func ProwCodeReview(c *checker.CheckRequest) checker.CheckResult {
|
||||
State: "closed",
|
||||
})
|
||||
if err != nil {
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, err)
|
||||
}
|
||||
|
||||
totalMerged := 0
|
||||
@ -145,7 +146,7 @@ func ProwCodeReview(c *checker.CheckRequest) checker.CheckResult {
|
||||
}
|
||||
|
||||
if totalReviewed == 0 {
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, errors.New("no reviews found"))
|
||||
}
|
||||
c.Logf("prow code reviews found")
|
||||
return checker.MakeProportionalResult(codeReviewStr, totalReviewed, totalMerged, .75)
|
||||
@ -185,7 +186,7 @@ func CommitMessageHints(c *checker.CheckRequest) checker.CheckResult {
|
||||
}
|
||||
|
||||
if totalReviewed == 0 {
|
||||
return checker.MakeInconclusiveResult(codeReviewStr)
|
||||
return checker.MakeInconclusiveResult(codeReviewStr, errors.New("no reviews found"))
|
||||
}
|
||||
c.Logf("code reviews found")
|
||||
return checker.MakeProportionalResult(codeReviewStr, totalReviewed, total, .75)
|
||||
|
@ -15,9 +15,13 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ossf/scorecard/checker"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
const frozenDepsStr = "Frozen-Deps"
|
||||
@ -28,37 +32,115 @@ func init() {
|
||||
|
||||
// FrozenDeps will check the repository if it contains frozen dependecies.
|
||||
func FrozenDeps(c *checker.CheckRequest) checker.CheckResult {
|
||||
return CheckIfFileExists(frozenDepsStr, c, filePredicate)
|
||||
return checker.MultiCheckAnd(
|
||||
isPackageManagerLockFilePresent,
|
||||
isGitHubActionsWorkflowPinned,
|
||||
)(c)
|
||||
}
|
||||
|
||||
// filePredicate will validate the if frozen dependecies file name exists.
|
||||
func filePredicate(name string, logf func(s string, f ...interface{})) bool {
|
||||
// TODO(laurent): need to support Docker https://github.com/ossf/scorecard/issues/403
|
||||
// TODO(laurent): need to support GCB
|
||||
|
||||
// ============================================================
|
||||
// ===================== Github workflows =====================
|
||||
// ============================================================
|
||||
|
||||
// Check pinning of github actions in workflows.
|
||||
func isGitHubActionsWorkflowPinned(c *checker.CheckRequest) checker.CheckResult {
|
||||
return CheckFilesContent(frozenDepsStr, ".github/workflows/*", c, validateGitHubActionWorkflow)
|
||||
}
|
||||
|
||||
// Check file content
|
||||
func validateGitHubActionWorkflow(path string, content []byte,
|
||||
logf func(s string, f ...interface{})) (bool, error) {
|
||||
|
||||
// Structure for workflow config.
|
||||
// We only retrieve what we need for logging.
|
||||
// Github workflows format: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
|
||||
type GitHubActionWorkflowConfig struct {
|
||||
Name string `yaml:name`
|
||||
Jobs map[string]struct {
|
||||
Name string `yaml:name`
|
||||
Steps []struct {
|
||||
Name string `yaml:name`
|
||||
Id string `yaml:id`
|
||||
Uses string `yaml:uses`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(content) == 0 {
|
||||
return false, errors.New("file has no content")
|
||||
}
|
||||
|
||||
var workflow GitHubActionWorkflowConfig
|
||||
err := yaml.Unmarshal(content, &workflow)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("!! frozen-deps - cannot unmarshal file %v\n%v\n%v: %w", path, content, string(content), err)
|
||||
}
|
||||
|
||||
hashRegex := regexp.MustCompile(`^.*@[a-f\d]{40,}`)
|
||||
r := true
|
||||
for jobName, job := range workflow.Jobs {
|
||||
if len(job.Name) > 0 {
|
||||
jobName = job.Name
|
||||
}
|
||||
for _, step := range job.Steps {
|
||||
if len(step.Uses) > 0 {
|
||||
// Ensure a hash at least as large as SHA1 is used (40 hex characters).
|
||||
// Example: action-name@hash
|
||||
match := hashRegex.Match([]byte(step.Uses))
|
||||
if !match {
|
||||
r = false
|
||||
logf("!! frozen-deps - %v has non-pinned dependency '%v' (job \"%v\")", path, step.Uses, jobName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// ================== Package manager lock files ==============
|
||||
// ============================================================
|
||||
|
||||
// Check presence of lock files thru filePredicate().
|
||||
func isPackageManagerLockFilePresent(c *checker.CheckRequest) checker.CheckResult {
|
||||
return CheckIfFileExists(frozenDepsStr, c, validatePackageManagerFile)
|
||||
}
|
||||
|
||||
// validatePackageManagerFile will validate the if frozen dependecies file name exists.
|
||||
// TODO(laurent): need to differentiate between libraries and programs.
|
||||
func validatePackageManagerFile(name string, logf func(s string, f ...interface{})) (bool, error) {
|
||||
switch strings.ToLower(name) {
|
||||
case "go.mod", "go.sum":
|
||||
logf("go modules found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "vendor/", "third_party/", "third-party/":
|
||||
logf("vendor dir found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "package-lock.json", "npm-shrinkwrap.json":
|
||||
logf("nodejs packages found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
// TODO(laurent): add check for hashbased pinning in requirements.txt - https://davidwalsh.name/hashin
|
||||
case "requirements.txt", "pipfile.lock":
|
||||
logf("python requirements found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "gemfile.lock":
|
||||
logf("ruby gems found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "cargo.lock":
|
||||
logf("rust crates found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "yarn.lock":
|
||||
logf("yarn packages found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
case "composer.lock":
|
||||
logf("composer packages found: %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
default:
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
93
checks/frozen_deps_test.go
Normal file
93
checks/frozen_deps_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2020 Security 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 checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//nolint:dupl // repeating test cases that are slightly different is acceptable
|
||||
func TestGithubWorkflowPinning(t *testing.T) {
|
||||
t.Parallel()
|
||||
type args struct {
|
||||
Filename string
|
||||
Logf func(s string, f ...interface{})
|
||||
}
|
||||
|
||||
type returnValue struct {
|
||||
Result bool
|
||||
Error error
|
||||
}
|
||||
|
||||
l := log{}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want returnValue
|
||||
}{
|
||||
{
|
||||
name: "Zero size content",
|
||||
args: args{
|
||||
Filename: "",
|
||||
Logf: l.Logf,
|
||||
},
|
||||
want: returnValue{false, errors.New("file has no content")},
|
||||
},
|
||||
{
|
||||
name: "Pinned workflow",
|
||||
args: args{
|
||||
Filename: "./testdata/workflow-pinned.yaml",
|
||||
Logf: l.Logf,
|
||||
},
|
||||
want: returnValue{true, nil},
|
||||
},
|
||||
{
|
||||
name: "Non-pinned workflow",
|
||||
args: args{
|
||||
Filename: "./testdata/workflow-not-pinned.yaml",
|
||||
Logf: l.Logf,
|
||||
},
|
||||
want: returnValue{false, nil},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt // Re-initializing variable so it is not changed while executing the closure below
|
||||
l.messages = []string{}
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var content []byte
|
||||
var err error
|
||||
if len(tt.args.Filename) == 0 {
|
||||
content = make([]byte, 0)
|
||||
} else {
|
||||
content, err = ioutil.ReadFile(tt.args.Filename)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot read file: %w", err))
|
||||
}
|
||||
}
|
||||
r, err := validateGitHubActionWorkflow(tt.args.Filename, content, tt.args.Logf)
|
||||
|
||||
if (err != nil && tt.want.Error == nil) ||
|
||||
(err == nil && tt.want.Error != nil) ||
|
||||
(err != nil && tt.want.Error != nil && err.Error() != tt.want.Error.Error()) ||
|
||||
r != tt.want.Result {
|
||||
t.Errorf("TestGithubWorkflowPinning:\"%v\": %v (%v,%v) want (%v, %v)", tt.name, tt.args.Filename, r, err, tt.want.Result, tt.want.Error)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
"github.com/ossf/scorecard/checker"
|
||||
)
|
||||
@ -28,7 +30,7 @@ func init() {
|
||||
}
|
||||
|
||||
func SAST(c *checker.CheckRequest) checker.CheckResult {
|
||||
return checker.MultiCheck(
|
||||
return checker.MultiCheckOr(
|
||||
CodeQLInCheckDefinitions,
|
||||
SASTToolInCheckRuns,
|
||||
)(c)
|
||||
@ -55,7 +57,7 @@ func SASTToolInCheckRuns(c *checker.CheckRequest) checker.CheckResult {
|
||||
return checker.MakeRetryResult(sastStr, err)
|
||||
}
|
||||
if crs == nil {
|
||||
return checker.MakeInconclusiveResult(sastStr)
|
||||
return checker.MakeInconclusiveResult(sastStr, errors.New("no check runs found"))
|
||||
}
|
||||
for _, cr := range crs.CheckRuns {
|
||||
if cr.GetStatus() != "completed" {
|
||||
@ -72,7 +74,7 @@ func SASTToolInCheckRuns(c *checker.CheckRequest) checker.CheckResult {
|
||||
}
|
||||
}
|
||||
if totalTested == 0 {
|
||||
return checker.MakeInconclusiveResult(sastStr)
|
||||
return checker.MakeInconclusiveResult(sastStr, errors.New("no merges found"))
|
||||
}
|
||||
return checker.MakeProportionalResult(sastStr, totalTested, totalMerged, .75)
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ func init() {
|
||||
|
||||
func SecurityPolicy(c *checker.CheckRequest) checker.CheckResult {
|
||||
// check repository for repository-specific policy
|
||||
result := CheckIfFileExists(securityPolicyStr, c, func(name string, logf func(s string, f ...interface{})) bool {
|
||||
result := CheckIfFileExists(securityPolicyStr, c, func(name string, logf func(s string, f ...interface{})) (bool, error) {
|
||||
if strings.EqualFold(name, "security.md") {
|
||||
logf("security policy : %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if result.Pass {
|
||||
@ -45,11 +45,11 @@ func SecurityPolicy(c *checker.CheckRequest) checker.CheckResult {
|
||||
dotGitHub := c
|
||||
dotGitHub.Repo = ".github"
|
||||
|
||||
return CheckIfFileExists(securityPolicyStr, dotGitHub, func(name string, logf func(s string, f ...interface{})) bool {
|
||||
return CheckIfFileExists(securityPolicyStr, dotGitHub, func(name string, logf func(s string, f ...interface{})) (bool, error) {
|
||||
if strings.EqualFold(name, "security.md") {
|
||||
logf("security policy within .github folder : %s", name)
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
@ -74,7 +75,7 @@ func SignedReleases(c *checker.CheckRequest) checker.CheckResult {
|
||||
|
||||
if totalReleases == 0 {
|
||||
c.Logf("no releases found")
|
||||
return checker.MakeInconclusiveResult(signedReleasesStr)
|
||||
return checker.MakeInconclusiveResult(signedReleasesStr, errors.New("no releases found"))
|
||||
}
|
||||
|
||||
c.Logf("found signed artifacts for %d out of %d releases", totalSigned, totalReleases)
|
||||
|
@ -15,6 +15,8 @@
|
||||
package checks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ossf/scorecard/checker"
|
||||
"github.com/shurcooL/githubv4"
|
||||
)
|
||||
@ -72,7 +74,7 @@ func SignedTags(c *checker.CheckRequest) checker.CheckResult {
|
||||
|
||||
if totalTags == 0 {
|
||||
c.Logf("no tags found")
|
||||
return checker.MakeInconclusiveResult(signedTagsStr)
|
||||
return checker.MakeInconclusiveResult(signedTagsStr, errors.New("no signed tags found"))
|
||||
}
|
||||
|
||||
c.Logf("found %d out of %d verified tags", totalSigned, totalTags)
|
||||
|
75
checks/testdata/workflow-not-pinned.yaml
vendored
Normal file
75
checks/testdata/workflow-not-pinned.yaml
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright 2021 Security 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.
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'source/common/**'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get build targets
|
||||
run: |
|
||||
. .github/workflows/get_build_targets.sh
|
||||
echo 'BUILD_TARGETS<<EOF' >> $GITHUB_ENV
|
||||
echo $BUILD_TARGETS_LOCAL >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- name: Install deps
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install libtool cmake automake autoconf make ninja-build curl unzip virtualenv openjdk-11-jdk build-essential libc++1
|
||||
mkdir -p bin/clang11
|
||||
cd bin/clang11
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.1/clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz
|
||||
tar -xf clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz --strip-components 1
|
||||
export PATH=bin/clang11/bin:$PATH
|
||||
- name: Build
|
||||
run: |
|
||||
bazel/setup_clang.sh bin/clang11
|
||||
bazelisk shutdown
|
||||
bazelisk build -c fastbuild --spawn_strategy=local --discard_analysis_cache --nouse_action_cache --config clang --config libc++ $BUILD_TARGETS
|
||||
echo -e "Built targets...\n$BUILD_TARGETS"
|
||||
- name: Clean Artifacts
|
||||
run: |
|
||||
git clean -xdf
|
||||
- name: Perform CodeQL Analysis
|
||||
if: env.BUILD_TARGETS != ''
|
||||
uses: github/codeql-action/analyze@v1
|
75
checks/testdata/workflow-pinned.yaml
vendored
Normal file
75
checks/testdata/workflow-pinned.yaml
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright 2021 Security 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.
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'source/common/**'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get build targets
|
||||
run: |
|
||||
. .github/workflows/get_build_targets.sh
|
||||
echo 'BUILD_TARGETS<<EOF' >> $GITHUB_ENV
|
||||
echo $BUILD_TARGETS_LOCAL >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba # some comment
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
- name: Install deps
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install libtool cmake automake autoconf make ninja-build curl unzip virtualenv openjdk-11-jdk build-essential libc++1
|
||||
mkdir -p bin/clang11
|
||||
cd bin/clang11
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.1/clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz
|
||||
tar -xf clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz --strip-components 1
|
||||
export PATH=bin/clang11/bin:$PATH
|
||||
- name: Build
|
||||
run: |
|
||||
bazel/setup_clang.sh bin/clang11
|
||||
bazelisk shutdown
|
||||
bazelisk build -c fastbuild --spawn_strategy=local --discard_analysis_cache --nouse_action_cache --config clang --config libc++ $BUILD_TARGETS
|
||||
echo -e "Built targets...\n$BUILD_TARGETS"
|
||||
- name: Clean Artifacts
|
||||
run: |
|
||||
git clean -xdf
|
||||
- name: Perform CodeQL Analysis
|
||||
if: env.BUILD_TARGETS != ''
|
||||
uses: github/codeql-action/analyze@daadedc81d5f9d3c06d2c92f49202a3cc2b919ba
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
var _ = Describe("E2E TEST:FrozenDeps", func() {
|
||||
Context("E2E TEST:Validating deps are frozen", func() {
|
||||
It("Should return deps are frozen", func() {
|
||||
It("Should return deps are not frozen", func() {
|
||||
l := log{}
|
||||
checkRequest := checker.CheckRequest{
|
||||
Ctx: context.Background(),
|
||||
@ -38,6 +38,21 @@ var _ = Describe("E2E TEST:FrozenDeps", func() {
|
||||
}
|
||||
result := checks.FrozenDeps(&checkRequest)
|
||||
Expect(result.Error).Should(BeNil())
|
||||
Expect(result.Pass).Should(BeFalse())
|
||||
})
|
||||
It("Should return deps are not frozen", func() {
|
||||
l := log{}
|
||||
checkRequest := checker.CheckRequest{
|
||||
Ctx: context.Background(),
|
||||
Client: ghClient,
|
||||
HTTPClient: client,
|
||||
Owner: "ossf",
|
||||
Repo: "scorecard",
|
||||
GraphClient: graphClient,
|
||||
Logf: l.Logf,
|
||||
}
|
||||
result := checks.FrozenDeps(&checkRequest)
|
||||
Expect(result.Error).Should(BeNil())
|
||||
Expect(result.Pass).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
|
15
go.mod
15
go.mod
@ -3,24 +3,33 @@ module github.com/ossf/scorecard
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.15.0 // indirect
|
||||
github.com/bradleyfalzon/ghinstallation v1.1.1
|
||||
github.com/golangci/golangci-lint v1.40.1
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/jszwec/csvutil v1.5.0
|
||||
github.com/naveensrinivasan/httpcache v1.2.2
|
||||
github.com/onsi/ginkgo v1.16.2
|
||||
github.com/onsi/gomega v1.12.0
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/shurcooL/githubv4 v0.0.0-20200928013246-d292edc3691b
|
||||
github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa
|
||||
github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect
|
||||
github.com/spf13/cobra v1.1.3
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.16.0
|
||||
gocloud.dev v0.22.0
|
||||
golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect
|
||||
google.golang.org/api v0.46.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384 // indirect
|
||||
google.golang.org/grpc v1.37.1 // indirect
|
||||
google.golang.org/protobuf v1.26.0
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
97
go.sum
97
go.sum
@ -20,8 +20,12 @@ cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eA
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
|
||||
cloud.google.com/go v0.72.0 h1:eWRCuwubtDrCJG0oSUMgnsbD4CmPFQF2ei4OFbXvwww=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
@ -45,8 +49,9 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.12.0 h1:4y3gHptW1EHVtcPAVE0eBBlFuGqEejTTG3KdIE0lUX4=
|
||||
cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho=
|
||||
cloud.google.com/go/storage v1.15.0 h1:Ljj+ZXVEhCr/1+4ZhvtteN1ND7UUsNTlduGclLh8GO0=
|
||||
cloud.google.com/go/storage v1.15.0/go.mod h1:mjjQMoxxyGH7Jr8K5qrx6N2O0AHsczI61sMNn03GIZI=
|
||||
contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
|
||||
@ -149,6 +154,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@ -187,6 +193,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/esimonov/ifshort v1.0.2 h1:K5s1W2fGfkoWXsFlxBNqT6J0ZCncPaKrGM5qe0bni68=
|
||||
@ -277,6 +285,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@ -293,6 +302,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@ -330,6 +340,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@ -337,8 +348,9 @@ github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU
|
||||
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/go-replayers/grpcreplay v1.0.0 h1:B5kVOzJ1hBgnevTgIWhSTatQ3608yu/2NnU0Ta1d0kY=
|
||||
github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
|
||||
github.com/google/go-replayers/httpreplay v0.1.2 h1:HCfx+dQzwN9XbGTHF8qJ+67WN8glL9FTWV5rraCJ/jU=
|
||||
@ -360,6 +372,9 @@ github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
|
||||
@ -368,8 +383,9 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.4.0 h1:kXcsA/rIGzJImVqPdhfnr6q0xsS9gU0515q1EPpJ9fE=
|
||||
github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
|
||||
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
@ -682,8 +698,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
|
||||
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
|
||||
github.com/shirou/gopsutil/v3 v3.21.4/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20200928013246-d292edc3691b h1:0/ecDXh/HTHRtSDSFnD2/Ta1yQ5J76ZspVY4u0/jGFk=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20200928013246-d292edc3691b/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa h1:jozR3igKlnYCj9IVHOVump59bp07oIRoLQ/CcjMYIUA=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20201206200315-234843c633fa/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU=
|
||||
@ -796,19 +812,21 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
@ -830,8 +848,9 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -854,8 +873,10 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
@ -912,10 +933,15 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -923,8 +949,14 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19 h1:ZD+2Sd/BnevwJp8PSli8WgGAGzb9IZtxBsv1iZMYeEA=
|
||||
golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c h1:SgVl/sCtkicsS7psKkje4H9YtjdEl3xsYh7N+5TDHqY=
|
||||
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -935,6 +967,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -990,12 +1023,19 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -1106,10 +1146,12 @@ golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201202200335-bef1c476418a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201203202102-a1a1cbeaa516/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2-0.20210512205948-8287d5da45e4 h1:cYSqdOzmV9wJ7lWurRAws06Dmif0Wv6UL4gQLlz+im0=
|
||||
golang.org/x/tools v0.1.2-0.20210512205948-8287d5da45e4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
@ -1139,8 +1181,13 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
|
||||
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
|
||||
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0 h1:l2Nfbl2GPXdWorv+dT2XfinX2jOOw4zv1VhLstx+6rE=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA=
|
||||
google.golang.org/api v0.46.0 h1:jkDWHOBIoNSD0OQpq4rtBVu+Rh325MPjXG1rakAp8JU=
|
||||
google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -1193,8 +1240,19 @@ google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497 h1:jDYzwXmX9tLnuG4sL85HPmE1ruErXOopALp2i/0AHnI=
|
||||
google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384 h1:z+j74wi4yV+P7EtK9gPLGukOk7mFOy9wMQaC0wNb7eY=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@ -1215,8 +1273,13 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
Loading…
Reference in New Issue
Block a user