From b8a73a1f05b28a4f294264fe029467a7bfd1357a Mon Sep 17 00:00:00 2001 From: Michael Sverdlov Date: Mon, 22 Jul 2024 11:29:53 +0300 Subject: [PATCH] Unite all common GitHub action steps (#68) --- .github/workflows/analysis.yml | 27 ++++--------- .github/workflows/cla.yml | 26 +++---------- .../workflows/frogbot-scan-pull-request.yml | 3 ++ .github/workflows/frogbot-scan-repository.yml | 3 ++ .github/workflows/test.yml | 15 +------- crypto/checksum.go | 3 +- fanout/reader_test.go | 4 +- io/fileutils.go | 20 +++++----- lru/lru_base.go | 38 ++++++++++++------- parallel/bounded_runner_test.go | 21 ++++++++-- parallel/runner_test.go | 7 +++- 11 files changed, 82 insertions(+), 85 deletions(-) diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index 4820c18..a8d82a9 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -13,30 +13,19 @@ jobs: - name: Checkout Source uses: actions/checkout@v4 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 1.22.x - - - name: Static Code Analysis - uses: golangci/golangci-lint-action@v3 - with: - args: | - --timeout 5m --out-${NO_FUTURE}format colored-line-number --enable errcheck,gosimple,govet,ineffassign,staticcheck,typecheck,unused,gocritic,asasalint,asciicheck,errchkjson,exportloopref,makezero,nilerr,unparam,unconvert,wastedassign,usestdlibvars - + - name: Setup Go with cache + uses: jfrog/.github/actions/install-go-with-cache@main + - name: Run golangci lint + uses: jfrog/.github/actions/golangci-lint@main Go-Sec: runs-on: ubuntu-latest steps: - name: Checkout Source uses: actions/checkout@v4 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 1.22.x + - name: Setup Go with cache + uses: jfrog/.github/actions/install-go-with-cache@main - - name: Run Gosec Security Scanner - uses: securego/gosec@master - with: - args: -exclude G204,G304,G404,G401,G505 -tests -exclude-dir \.*test\.* ./... \ No newline at end of file + - name: Run Go-Sec scanner + uses: jfrog/.github/actions/gosec-scanner@main \ No newline at end of file diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 541512e..8096e39 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -10,26 +10,10 @@ jobs: CLAssistant: runs-on: ubuntu-latest steps: - - uses: actions-ecosystem/action-regex-match@v2 - id: sign-or-recheck + - name: Run CLA Check + uses: jfrog/.github/actions/cla@main with: - text: ${{ github.event.comment.body }} - regex: '\s*(I have read the CLA Document and I hereby sign the CLA)|(recheck)\s*' - - - name: "CLA Assistant" - if: ${{ steps.sign-or-recheck.outputs.match != '' || github.event_name == 'pull_request_target' }} - # Alpha Release - uses: cla-assistant/github-action@v2.3.0 - env: - # Generated and maintained by GitHub + event_comment_body: ${{ github.event.comment.body }} + event_name: ${{ github.event_name }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # JFrog's organization secret - PERSONAL_ACCESS_TOKEN : ${{ secrets.CLA_SIGN_TOKEN }} - with: - path-to-signatures: 'signed_clas.json' - path-to-document: 'https://jfrog.com/cla/' - remote-organization-name: 'jfrog' - remote-repository-name: 'jfrog-signed-clas' - # branch should not be protected - branch: 'master' - allowlist: bot* + CLA_SIGN_TOKEN: ${{ secrets.CLA_SIGN_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/frogbot-scan-pull-request.yml b/.github/workflows/frogbot-scan-pull-request.yml index 998c8c9..6479787 100644 --- a/.github/workflows/frogbot-scan-pull-request.yml +++ b/.github/workflows/frogbot-scan-pull-request.yml @@ -12,6 +12,9 @@ jobs: # "frogbot" GitHub environment can approve the pull request to be scanned. environment: frogbot steps: + - name: Setup Go with cache + uses: jfrog/.github/actions/install-go-with-cache@main + - uses: jfrog/frogbot@v2 env: JFROG_CLI_LOG_LEVEL: "DEBUG" diff --git a/.github/workflows/frogbot-scan-repository.yml b/.github/workflows/frogbot-scan-repository.yml index 2342d4d..9a230bb 100644 --- a/.github/workflows/frogbot-scan-repository.yml +++ b/.github/workflows/frogbot-scan-repository.yml @@ -16,6 +16,9 @@ jobs: # The repository scanning will be triggered periodically on the following branches. branch: [ "master" ] steps: + - name: Setup Go with cache + uses: jfrog/.github/actions/install-go-with-cache@main + - uses: jfrog/frogbot@v2 env: JFROG_CLI_LOG_LEVEL: "DEBUG" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e5aa357..95f199b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,19 +17,8 @@ jobs: - name: Checkout Source uses: actions/checkout@v4 - - name: Go Cache - uses: actions/cache@v4 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: 1.22.x - cache: false + - name: Setup Go with cache + uses: jfrog/.github/actions/install-go-with-cache@main - name: Tests run: go test -v -race -covermode atomic -coverprofile=covprofile ./... diff --git a/crypto/checksum.go b/crypto/checksum.go index 9f08666..9bbe84b 100644 --- a/crypto/checksum.go +++ b/crypto/checksum.go @@ -27,7 +27,8 @@ const ( var algorithmFunc = map[Algorithm]func() hash.Hash{ // Go native crypto algorithms: - MD5: md5.New, + MD5: md5.New, + //#nosec G401 -- Sha1 is supported by Artifactory. SHA1: sha1.New, // sha256-simd algorithm: SHA256: sha256.New, diff --git a/fanout/reader_test.go b/fanout/reader_test.go index cbe6b25..449867e 100644 --- a/fanout/reader_test.go +++ b/fanout/reader_test.go @@ -2,6 +2,7 @@ package fanout import ( "bytes" + //#nosec G505 -- Sha1 is supported by Artifactory. "crypto/sha1" "crypto/sha256" "encoding/hex" @@ -66,6 +67,7 @@ func TestFanoutRead(t *testing.T) { } func TestFanoutProgressiveRead(t *testing.T) { + //#nosec G401 -- Sha1 is supported by Artifactory. hash1 := sha1.New() proc1 := func(p []byte) (err error) { if _, err := hash1.Write(p); err != nil { @@ -104,7 +106,7 @@ func TestFanoutProgressiveRead(t *testing.T) { func TestFanoutProgressiveReadError(t *testing.T) { const errmsg = "ERRSHA1" - + //#nosec G401 -- Sha1 is supported by Artifactory. hash1 := sha1.New() proc1 := func(p []byte) (err error) { return errors.New(errmsg) diff --git a/io/fileutils.go b/io/fileutils.go index 53b4776..fba95af 100644 --- a/io/fileutils.go +++ b/io/fileutils.go @@ -2,12 +2,13 @@ package io import ( "bufio" + "crypto/rand" cr "crypto/rand" "encoding/json" "errors" "fmt" "io" - "math/rand" + "math/big" "net/http" "os" "path" @@ -35,16 +36,15 @@ type RandFile struct { const buflen = 4096 -var src = rand.NewSource(time.Now().UnixNano()) - -// #nosec G404 - No cryptographic level encryption is needed in random file -var rnd = rand.New(src) - // Create a temp file with the requested prefix at the provided dir. File length and contents are random, up to the requested max length. func CreateRandomLenFile(maxLen int, filesDir string, prefix string) string { file, _ := os.CreateTemp(filesDir, prefix) fname := file.Name() - len := rnd.Intn(maxLen) + n, err := rand.Int(rand.Reader, big.NewInt(int64(maxLen))) + if err != nil { + panic(fmt.Errorf("failed to generate random number: %w", err)) + } + len := int(n.Int64()) created, err := CreateRandFile(fname, len) if err != nil { panic(err) @@ -127,7 +127,7 @@ func walk(path string, info os.FileInfo, walkFn WalkFunc, visitedDirSymlinks map } err = walkFn(path, info, nil) if err != nil { - if info.IsDir() && err == ErrSkipDir { + if info.IsDir() && errors.Is(err, ErrSkipDir) { return nil } return err @@ -161,13 +161,13 @@ func walk(path string, info os.FileInfo, walkFn WalkFunc, visitedDirSymlinks map } fileInfo, err := fileHandler(filename) if err != nil { - if err := walkFn(filename, fileInfo, err); err != nil && err != ErrSkipDir { + if err := walkFn(filename, fileInfo, err); err != nil && !errors.Is(err, ErrSkipDir) { return err } } else { err = walk(filename, fileInfo, walkFn, visitedDirSymlinks, walkIntoDirSymlink) if err != nil { - if !fileInfo.IsDir() || err != ErrSkipDir { + if !fileInfo.IsDir() || !errors.Is(err, ErrSkipDir) { return err } } diff --git a/lru/lru_base.go b/lru/lru_base.go index 8522b51..737dbac 100644 --- a/lru/lru_base.go +++ b/lru/lru_base.go @@ -56,13 +56,17 @@ func (c *cacheBase) Get(key string) (value interface{}, ok bool) { if c.Expiry != time.Duration(0) { unixNow := time.Now().UnixNano() / int64(time.Millisecond) unixExpiry := int64(c.Expiry / time.Millisecond) - if (unixNow - ele.Value.(*entry).timeInsert) > unixExpiry { - c.removeElement(ele) - return nil, false + if ent, ok := ele.Value.(*entry); ok { + if (unixNow - ent.timeInsert) > unixExpiry { + c.removeElement(ele) + return nil, false + } } } c.ll.MoveToFront(ele) - return ele.Value.(*entry).value, true + if ent, ok := ele.Value.(*entry); ok { + return ent.value, true + } } return nil, false } @@ -70,8 +74,10 @@ func (c *cacheBase) Get(key string) (value interface{}, ok bool) { // Updates element's value without updating its "Least-Recently-Used" status func (c *cacheBase) UpdateElement(key string, value interface{}) { if ee, ok := c.cache[key]; ok { - ee.Value.(*entry).value = value - return + if ent, ok := ee.Value.(*entry); ok { + ent.value = value + return + } } } @@ -90,10 +96,12 @@ func (c *cacheBase) RemoveOldest() { func (c *cacheBase) removeElement(e *list.Element) { c.ll.Remove(e) - kv := e.Value.(*entry) - delete(c.cache, kv.key) - if c.OnEvicted != nil { - c.OnEvicted(kv.key, kv.value) + kv, ok := e.Value.(*entry) + if ok { + delete(c.cache, kv.key) + if c.OnEvicted != nil { + c.OnEvicted(kv.key, kv.value) + } } } @@ -105,11 +113,13 @@ func (c *cacheBase) Len() int { // Clear purges all stored items from the cache. func (c *cacheBase) Clear() { for _, e := range c.cache { - kv := e.Value.(*entry) - if c.OnEvicted != nil { - c.OnEvicted(kv.key, kv.value) + kv, ok := e.Value.(*entry) + if ok { + if c.OnEvicted != nil { + c.OnEvicted(kv.key, kv.value) + } + delete(c.cache, kv.key) } - delete(c.cache, kv.key) } c.ll.Init() } diff --git a/parallel/bounded_runner_test.go b/parallel/bounded_runner_test.go index 0126dca..0bbc5c1 100644 --- a/parallel/bounded_runner_test.go +++ b/parallel/bounded_runner_test.go @@ -1,8 +1,9 @@ package parallel import ( + "crypto/rand" "fmt" - "math/rand" + "math/big" "strconv" "strings" "sync" @@ -199,7 +200,11 @@ func produceTasks(runner *runner, results chan int, errorsQueue *ErrorsQueue, ta func createSuccessfulFlowTaskFunc(num int, result chan int) TaskFunc { return func(threadId int) error { result <- num - time.Sleep(time.Millisecond * time.Duration(rand.Intn(50))) + n, err := rand.Int(rand.Reader, big.NewInt(50)) + if err != nil { + return err + } + time.Sleep(time.Millisecond * time.Duration(n.Int64())) return nil } } @@ -210,7 +215,11 @@ func createTaskWithErrorFunc(num int, result chan int) TaskFunc { return fmt.Errorf("num: %d, above 50 going to stop", num) } result <- num - time.Sleep(time.Millisecond * time.Duration(rand.Intn(50))) + n, err := rand.Int(rand.Reader, big.NewInt(50)) + if err != nil { + return err + } + time.Sleep(time.Millisecond * time.Duration(n.Int64())) return nil } } @@ -221,7 +230,11 @@ func createTaskWithIntAsErrorFunc(num int, result chan int) TaskFunc { return fmt.Errorf("%d", num) } result <- num - time.Sleep(time.Millisecond * time.Duration(rand.Intn(50))) + n, err := rand.Int(rand.Reader, big.NewInt(50)) + if err != nil { + return err + } + time.Sleep(time.Millisecond * time.Duration(n.Int64())) return nil } } diff --git a/parallel/runner_test.go b/parallel/runner_test.go index bf2433a..4036641 100644 --- a/parallel/runner_test.go +++ b/parallel/runner_test.go @@ -1,9 +1,10 @@ package parallel import ( + "crypto/rand" "errors" "fmt" - "math/rand" + "math/big" "sync" "testing" "time" @@ -40,7 +41,9 @@ func TestAddTask(t *testing.T) { x := i _, err := runner.AddTask(func(int) error { results <- x - time.Sleep(time.Millisecond * time.Duration(rand.Intn(50))) + n, err := rand.Int(rand.Reader, big.NewInt(50)) + assert.NoError(t, err) + time.Sleep(time.Millisecond * time.Duration(n.Int64())) if float64(x) > float64(count)/2 { return fmt.Errorf("second half value %d not counted", x) }