From 1ed6081364ec0f19f42eb7d0ed687daa75207b4b Mon Sep 17 00:00:00 2001 From: Jean Viaene Date: Fri, 25 Nov 2022 10:43:56 +0100 Subject: [PATCH 1/2] permission should run on all platforms --- .github/workflows/go_tests.yml | 49 +++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/.github/workflows/go_tests.yml b/.github/workflows/go_tests.yml index 75dd20265..51f240b71 100644 --- a/.github/workflows/go_tests.yml +++ b/.github/workflows/go_tests.yml @@ -8,7 +8,12 @@ on: jobs: permission: - runs-on: ubuntu-latest + strategy: + matrix: + platform: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{matrix.platform}} + steps: - name: Add comment if PR permission failed if: ${{ !contains(github.event.pull_request.labels.*.name, 'safe PR') }} @@ -28,13 +33,9 @@ jobs: echo "::error:: Could not start CI tests due to missing *safe PR* label." exit 1 - test: + coverage: needs: permission - strategy: - matrix: - platform: [ubuntu-latest, macos-latest, windows-latest] - - runs-on: ${{matrix.platform}} + runs-on: ubuntu-latest steps: - name: Setup go ^1.13 @@ -48,16 +49,11 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - - name: Test without coverage - if: matrix.platform == 'macos-latest' || matrix.platform == 'windows-latest' - run: go test ./... - - name: Test with coverage - if: matrix.platform == 'ubuntu-latest' + # running 'go test' requires permission run: go test -json -covermode=count -coverprofile=profile.cov ./... > report.json - name: Sonarcloud scan - if: matrix.platform == 'ubuntu-latest' uses: sonarsource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -76,15 +72,38 @@ jobs: -Dsonar.pullrequest.base=${{ github.event.pull_request.base }} - name: Send coverage - if: matrix.platform == 'ubuntu-latest' uses: shogo82148/actions-goveralls@v1 with: path-to-profile: profile.cov parallel: true + + test: + needs: permission + strategy: + matrix: + platform: [macos-latest, windows-latest] + + runs-on: ${{matrix.platform}} + + steps: + - name: Setup go ^1.13 + uses: actions/setup-go@v3 + with: + go-version: ^1.13 + + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: Test without coverage + # running 'go test' requires permission + run: go test ./... + # notifies that all test jobs are finished. finish: - needs: test + needs: [coverage, test] runs-on: ubuntu-latest steps: - uses: shogo82148/actions-goveralls@v1 From 8364eed419e86e3d9356dfc89095607f1d3d4b22 Mon Sep 17 00:00:00 2001 From: Jean Viaene Date: Mon, 28 Nov 2022 14:59:40 +0100 Subject: [PATCH 2/2] fix CI to allow forked PR --- .github/workflows/go_tests.yml | 111 ------------- .github/workflows/test_on_pr.yml | 78 +++++++++ .github/workflows/test_on_push.yml | 59 +++++++ .golangci.yml | 248 +++++++++++++++++++++++++++++ Makefile | 30 +++- 5 files changed, 407 insertions(+), 119 deletions(-) delete mode 100644 .github/workflows/go_tests.yml create mode 100644 .github/workflows/test_on_pr.yml create mode 100644 .github/workflows/test_on_push.yml create mode 100644 .golangci.yml diff --git a/.github/workflows/go_tests.yml b/.github/workflows/go_tests.yml deleted file mode 100644 index 51f240b71..000000000 --- a/.github/workflows/go_tests.yml +++ /dev/null @@ -1,111 +0,0 @@ -name: Go test - -on: - push: - branches: [ master ] - pull_request_target: - types: [opened, synchronize, reopened, labeled] - -jobs: - permission: - strategy: - matrix: - platform: [ubuntu-latest, macos-latest, windows-latest] - - runs-on: ${{matrix.platform}} - - steps: - - name: Add comment if PR permission failed - if: ${{ !contains(github.event.pull_request.labels.*.name, 'safe PR') }} - uses: actions/github-script@v3 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - github.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: '🔒 Could not start CI tests due to missing *safe PR* label. Please contact one of the repo maintainers.' - }) - - name: Check permission - if: ${{ !contains(github.event.pull_request.labels.*.name, 'safe PR') }} - run: | - echo "::error:: Could not start CI tests due to missing *safe PR* label." - exit 1 - - coverage: - needs: permission - runs-on: ubuntu-latest - - steps: - - name: Setup go ^1.13 - uses: actions/setup-go@v3 - with: - go-version: ^1.13 - - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Test with coverage - # running 'go test' requires permission - run: go test -json -covermode=count -coverprofile=profile.cov ./... > report.json - - - name: Sonarcloud scan - uses: sonarsource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - with: - args: > - -Dsonar.organization=dedis - -Dsonar.projectKey=dedis_kyber - -Dsonar.go.tests.reportPaths=report.json - -Dsonar.go.coverage.reportPaths=profile.cov - -Dsonar.c.file.suffixes=- - -Dsonar.cpp.file.suffixes=- - -Dsonar.objc.file.suffixes=- - -Dsonar.pullrequest.key=${{ github.event.number }} - -Dsonar.pullrequest.branch=${{ github.head_ref }} - -Dsonar.pullrequest.base=${{ github.event.pull_request.base }} - - - name: Send coverage - uses: shogo82148/actions-goveralls@v1 - with: - path-to-profile: profile.cov - parallel: true - - test: - needs: permission - strategy: - matrix: - platform: [macos-latest, windows-latest] - - runs-on: ${{matrix.platform}} - - steps: - - name: Setup go ^1.13 - uses: actions/setup-go@v3 - with: - go-version: ^1.13 - - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Test without coverage - # running 'go test' requires permission - run: go test ./... - - # notifies that all test jobs are finished. - finish: - needs: [coverage, test] - runs-on: ubuntu-latest - steps: - - uses: shogo82148/actions-goveralls@v1 - with: - parallel-finished: true diff --git a/.github/workflows/test_on_pr.yml b/.github/workflows/test_on_pr.yml new file mode 100644 index 000000000..8bcbab55e --- /dev/null +++ b/.github/workflows/test_on_pr.yml @@ -0,0 +1,78 @@ +name: Test on PR + +on: + pull_request_target: + types: [opened, synchronize, reopened, labeled] + +jobs: + permission: + strategy: + matrix: + platform: [macos-latest, windows-latest, ubuntu-latest] + runs-on: ${{matrix.platform}} + steps: + - name: Add comment if PR permission failed + if: ${{ !contains(github.event.pull_request.labels.*.name, 'safe PR') }} + uses: actions/github-script@v3 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + github.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: '🔒 Could not start CI tests due to missing *safe PR* label. Please contact a DEDIS maintainer.' + }) + - name: Check permission + if: ${{ !contains(github.event.pull_request.labels.*.name, 'safe PR') }} + run: | + echo "::error:: Could not start CI tests due to missing *safe PR* label." + exit 1 + + test: + needs: permission + strategy: + matrix: + platform: [macos-latest, windows-latest, ubuntu-latest] + runs-on: ${{matrix.platform}} + env: + DBGSYNCLOG: trace + DBGSYNCON: true + steps: + - name: Set up Go ^1.13 + uses: actions/setup-go@v3 + with: + go-version: ^1.13 + + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Test without coverage + if: matrix.platform == 'macos-latest' || matrix.platform == 'windows-latest' + run: make test + + - name: Test with coverage + if: matrix.platform == 'ubuntu-latest' + run: make coverage + + - name: SonarCloud scan + if: matrix.platform == 'ubuntu-latest' + uses: sonarsource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.organization=dedis + -Dsonar.projectKey=dedis_kyber + -Dsonar.go.tests.reportPaths=report.json + -Dsonar.go.coverage.reportPaths=profile.cov + -Dsonar.pullrequest.key=${{ github.event.number }} + -Dsonar.pullrequest.branch=${{ github.head_ref }} + -Dsonar.pullrequest.base=${{ github.event.pull_request.base }} + -Dsonar.c.file.suffixes=- + -Dsonar.cpp.file.suffixes=- + -Dsonar.objc.file.suffixes=- diff --git a/.github/workflows/test_on_push.yml b/.github/workflows/test_on_push.yml new file mode 100644 index 000000000..d2eacfc8e --- /dev/null +++ b/.github/workflows/test_on_push.yml @@ -0,0 +1,59 @@ +name: Test on push + +on: + push: + branches: [ master ] + +jobs: + test_and_coverage: + strategy: + matrix: + platform: [macos-latest, windows-latest, ubuntu-latest] + runs-on: ${{matrix.platform}} + env: + DBGSYNCLOG: trace + DBGSYNCON: true + steps: + - name: Set up Go ^1.13 + uses: actions/setup-go@v3 + with: + go-version: ^1.13 + + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Test without coverage + if: matrix.platform == 'macos-latest' || matrix.platform == 'windows-latest' + run: make test + + - name: Test with coverage + if: matrix.platform == 'ubuntu-latest' + run: make coverage + + - name: SonarCloud scan + if: matrix.platform == 'ubuntu-latest' + uses: sonarsource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + with: + args: > + -Dsonar.organization=dedis + -Dsonar.projectKey=dedis_kyber + -Dsonar.go.tests.reportPaths=report.json + -Dsonar.go.coverage.reportPaths=profile.cov + -Dsonar.pullrequest.key=${{ github.event.number }} + -Dsonar.pullrequest.branch=${{ github.head_ref }} + -Dsonar.pullrequest.base=${{ github.event.pull_request.base }} + -Dsonar.c.file.suffixes=- + -Dsonar.cpp.file.suffixes=- + -Dsonar.objc.file.suffixes=- + + - name: Send coverage + if: matrix.platform == 'ubuntu-latest' + uses: shogo82148/actions-goveralls@v1 + with: + path-to-profile: profile.cov diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..e2a66021d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,248 @@ +# This code is licensed under the terms of the MIT license. + +run: + # Timeout for analysis, e.g. 30s, 5m. + # Default: 1m + timeout: 3m + +# This file contains only configs which differ from defaults. +# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml +linters-settings: + cyclop: + # The maximal code complexity to report. + # Default: 10 + max-complexity: 30 + # The maximal average package complexity. + # If it's higher than 0.0 (float) the check is enabled + # Default: 0.0 + package-average: 10.0 + + errcheck: + # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. + # Such cases aren't reported by default. + # Default: false + check-type-assertions: true + + funlen: + # Checks the number of lines in a function. + # If lower than 0, disable the check. + # Default: 60 + lines: 100 + # Checks the number of statements in a function. + # If lower than 0, disable the check. + # Default: 40 + statements: 50 + + gocognit: + # Minimal code complexity to report + # Default: 30 (but we recommend 10-20) + min-complexity: 20 + + gomnd: + # List of function patterns to exclude from analysis. + # Values always ignored: `time.Date` + # Default: [] + ignored-functions: + - os.Chmod + - os.Mkdir + - os.MkdirAll + - os.OpenFile + - os.WriteFile + - strconv.FormatFloat + - strconv.FormatInt + - strconv.FormatUint + - strconv.ParseFloat + - strconv.ParseInt + - strconv.ParseUint + + govet: + # Enable all analyzers. + # Default: false + enable-all: true + # Disable analyzers by name. + # Run `go tool vet help` to see all analyzers. + # Default: [] + disable: + - fieldalignment # too strict + - shadow # too many false positives + + nakedret: + # Make an issue if func has more lines of code than this setting, and it has naked returns. + # Default: 30 + max-func-lines: 10 + + nolintlint: + # Exclude following linters from requiring an explanation. + # Default: [] + allow-no-explanation: [ funlen, gocognit, lll ] + # Enable to require an explanation of nonzero length after each nolint directive. + # Default: false + require-explanation: true + # Enable to require nolint directives to mention the specific linter being suppressed. + # Default: false + require-specific: true + + tenv: + # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures. + # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked. + # Default: false + all: true + + gosec: + excludes: + - G107 # variables in URLs + - G404 # use of weak random generator + +linters: + disable-all: true + enable: + ## enabled by default + - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases + - gosimple # specializes in simplifying a code + - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - ineffassign # detects when assignments to existing variables are not used + - staticcheck # is a go vet on steroids, applying a ton of static analysis checks + - typecheck # like the front-end of a Go compiler, parses and type-checks Go code + - unused # checks for unused constants, variables, functions and types + ## disabled by default + - asasalint # checks for pass []any as any in variadic func(...any) + - asciicheck # checks that your code does not contain non-ASCII identifiers + - bidichk # checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + #- contextcheck # checks the function whether use a non-inherited context # TODO: enable after golangci-lint uses https://github.com/sylvia7788/contextcheck/releases/tag/v1.0.7 + - cyclop # checks function and package cyclomatic complexity + - dupl # tool for code clone detection + - durationcheck # checks for two durations multiplied together + - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error + - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 + - execinquery # checks query string in Query function which reads your Go src files and warning it finds + - exhaustive # checks exhaustiveness of enum switch statements + - exportloopref # checks for pointers to enclosing loop variables + - forbidigo # forbids identifiers + - funlen # tool for detection of long functions + #- gochecknoglobals # checks that no global variables exist + #- gochecknoinits # checks that no init functions are present in Go code + - gocognit # computes and checks the cognitive complexity of functions + - goconst # finds repeated strings that could be replaced by a constant + - gocritic # provides diagnostics that check for bugs, performance and style issues + - gocyclo # computes and checks the cyclomatic complexity of functions + #- godot # checks if comments end in a period + #- goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt + #- gomnd # detects magic numbers - ENABLE LATER + - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod + - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations + - goprintffuncname # checks that printf-like functions are named with f at the end + - gosec # inspects source code for security problems + - lll # reports long lines + #- makezero # finds slice declarations with non-zero initial length + - nakedret # finds naked returns in functions greater than a specified function length + - nestif # reports deeply nested if statements + - nilerr # finds the code that returns nil even if it checks that the error is not nil + - nilnil # checks that there is no simultaneous return of nil error and an invalid value + #- noctx # finds sending http request without context.Context + - nolintlint # reports ill-formed or insufficient nolint directives + #- nonamedreturns # reports all named returns + - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL + - predeclared # finds code that shadows one of Go's predeclared identifiers + #- promlinter # checks Prometheus metrics naming via promlint + - reassign # checks that package variables are not reassigned + - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint + #- rowserrcheck # checks whether Err of rows is checked successfully + #- sqlclosecheck # checks that sql.Rows and sql.Stmt are closed + - stylecheck # is a replacement for golint + - tenv # detects using os.Setenv instead of t.Setenv since Go1.17 + #- testpackage # makes you use a separate _test package + - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes + #- unconvert # removes unnecessary type conversions + - unparam # reports unused function parameters + - usestdlibvars # detects the possibility to use variables/constants from the Go standard library + #- wastedassign # finds wasted assignment statements + #- whitespace # detects leading and trailing whitespace + + ## you may want to enable + #- decorder # checks declaration order and count of types, constants, variables and functions + #- exhaustruct # checks if all structure fields are initialized + #- gci # controls golang package import order and makes it always deterministic + - godox # detects FIXME, TODO and other comment keywords + #- goheader # checks is file header matches to pattern + - interfacebloat # checks the number of methods inside an interface + #- ireturn # accept interfaces, return concrete types + #- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated + #- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope + #- wrapcheck # checks that errors returned from external packages are wrapped + + ## disabled + #- containedctx # detects struct contained context.Context field + #- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages + #- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + #- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted + #- forcetypeassert # [replaced by errcheck] finds forced type assertions + #- goerr113 # [too strict] checks the errors handling expressions + #- gofmt # [replaced by goimports] checks whether code was gofmt-ed + #- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed + #- grouper # analyzes expression groups + #- importas # enforces consistent import aliases + #- logrlint # [owner archived repository] checks logr arguments + #- maintidx # measures the maintainability index of each function + #- misspell # [useless] finds commonly misspelled English words in comments + #- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity + #- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test + #- tagliatelle # checks the struct tags + #- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers + #- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines + + ## deprecated + #- deadcode # [deprecated, replaced by unused] finds unused code + #- exhaustivestruct # [deprecated, replaced by exhaustruct] checks if all struct's fields are initialized + #- golint # [deprecated, replaced by revive] golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes + #- ifshort # [deprecated] checks that your code uses short syntax for if-statements whenever possible + #- interfacer # [deprecated] suggests narrower interface types + #- maligned # [deprecated, replaced by govet fieldalignment] detects Go structs that would take less memory if their fields were sorted + #- nosnakecase # [deprecated, replaced by revive var-naming] detects snake case of variable naming and function name + #- scopelint # [deprecated, replaced by exportloopref] checks for unpinned variables in go programs + #- structcheck # [deprecated, replaced by unused] finds unused struct fields + #- varcheck # [deprecated, replaced by unused] finds unused global variables and constants + + +issues: + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + max-same-issues: 50 + + exclude-rules: + - source: "^//\\s*go:generate\\s" + linters: [ lll ] + - source: "(noinspection|TODO)" + linters: [ godot ] + - source: "//noinspection" + linters: [ gocritic ] + - source: "^\\s+if _, ok := err\\.\\([^.]+\\.InternalError\\); ok {" + linters: [ errorlint ] + - path: ".skeleton" + linters: + - unused + - unparam + - path: ".*_test.go" + linters: + - bodyclose + - dupl + - errcheck + - funlen + - gochecknoglobals + - gocognit + - goconst + - gosec + - lll + - noctx + - unparam + - wrapcheck + - linters: + - gocritic + text: "appendAssign:" + - linters: + - revive + text: "unexported-return:" + - linters: + - govet + text: "shadow: declaration of \"err\" shadows declaration" diff --git a/Makefile b/Makefile index 7f96089b4..f5b2c46aa 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,27 @@ -lint: - # Coding style static check. - @go install honnef.co/go/tools/cmd/staticcheck@latest - @go mod tidy - #staticcheck `go list ./...` +tidy: + #go install honnef.co/go/tools/cmd/staticcheck@latest + go mod tidy -vet: +generate: tidy + go generate ./... + +# Coding style static check. +lint: tidy + @echo "Please setup a linter!" + #golangci-lint run + #staticcheck go list ./... + + +vet: tidy go vet ./... +test: tidy + go test ./... + +coverage: tidy + go test -json -covermode=count -coverprofile=profile.cov ./... > report.json + # target to run all the possible checks; it's a good habit to run it before # pushing code -check: lint vet - go test ./... +check: lint vet test + echo "check done"