mirror of https://github.com/dapr/go-sdk.git
feat: add golangci-lint (local) version check (#467)
* feat: add golangci-lint version check Add golangci-lint version check to compare the local version against the workflow version. Adds associated test workflow for mac, ubuntu and windows. Signed-off-by: mikeee <hey@mike.ee> * fix: add install linter step Signed-off-by: mikeee <hey@mike.ee> * fix: return the raw output of the command run Signed-off-by: mikeee <hey@mike.ee> * fix: change regex to pick up versions not prefixed Signed-off-by: mikeee <hey@mike.ee> * formatting: gofumpt'ed workspace Signed-off-by: mikeee <hey@mike.ee> * fix: convert line endings to LF on checkout Signed-off-by: mikeee <hey@mike.ee> * fix: encapsulate any spaces in the argument Signed-off-by: mikeee <hey@mike.ee> --------- Signed-off-by: mikeee <hey@mike.ee>
This commit is contained in:
parent
30a51be967
commit
57466dd68e
|
|
@ -0,0 +1 @@
|
|||
*.go text eol=lf
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
name: Test Tooling
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: # Explicitly declare which paths
|
||||
- ".github/workflows/test-tooling.yml"
|
||||
- "tools/*"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths: # Explicitly declare which paths
|
||||
- ".github/workflows/test-tooling.yml"
|
||||
- "tools/*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Test (${{ matrix.os}}) go ${{ matrix.gover }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
gover:
|
||||
- "1.21"
|
||||
os:
|
||||
- "ubuntu-latest"
|
||||
- "windows-latest"
|
||||
- "macos-latest"
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
GOVER: ${{ matrix.gover }}
|
||||
GOLANGCILINT_VER: v1.54.2 # Make sure to bump /tools/check-lint-version/main_test.go
|
||||
|
||||
steps:
|
||||
- name: Setup
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ${{ env.GOVER }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tidy
|
||||
working-directory: ./tools/check-lint-version
|
||||
run: make tidy
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: ${{ env.GOLANGCILINT_VER }}
|
||||
working-directory: ./tools/check-lint-version
|
||||
skip-cache: true
|
||||
args: --timeout=10m0s --config ../../.golangci.yml
|
||||
|
||||
- name: Install Linter
|
||||
run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin" ${{ env.GOLANGCILINT_VER }}
|
||||
|
||||
- name: Test
|
||||
working-directory: ./tools/check-lint-version
|
||||
run: make test
|
||||
8
Makefile
8
Makefile
|
|
@ -29,9 +29,15 @@ cover: ## Displays test coverage in the client and service packages
|
|||
go test -coverprofile=cover-http.out ./service/http && go tool cover -html=cover-http.out
|
||||
|
||||
.PHONY: lint
|
||||
lint: ## Lints the entire project
|
||||
lint: check-lint ## Lints the entire project
|
||||
golangci-lint run --timeout=3m
|
||||
|
||||
.PHONY: check-lint
|
||||
check-lint: ## Compares the locally installed linter with the workflow version
|
||||
cd ./tools/check-lint-version && \
|
||||
go mod tidy && \
|
||||
go run main.go
|
||||
|
||||
.PHONY: tag
|
||||
tag: ## Creates release tag
|
||||
git tag $(RELEASE_VERSION)
|
||||
|
|
|
|||
|
|
@ -256,16 +256,16 @@ func (mr *MockServerContextMockRecorder) Type() *gomock.Call {
|
|||
}
|
||||
|
||||
func (mr *MockServerContextMockRecorder) Invoke(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invoke", reflect.TypeOf((*MockServerContext)(nil).Invoke), arg0, arg1)
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invoke", reflect.TypeOf((*MockServerContext)(nil).Invoke), arg0, arg1)
|
||||
}
|
||||
|
||||
func (m *MockServerContext) Invoke(ctx context.Context, input string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Invoke", ctx, input)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Invoke", ctx, input)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// MockReminderCallee is a mock of ReminderCallee interface.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
.PHONY: cover
|
||||
cover:
|
||||
go test -coverprofile=cover.out ./ && go tool cover -html=cover.out
|
||||
|
||||
.PHONY: tidy
|
||||
tidy: ## Updates the go modules
|
||||
go mod tidy
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -count=1 \
|
||||
-race \
|
||||
-coverprofile=coverage.txt \
|
||||
-covermode=atomic \
|
||||
./...
|
||||
|
||||
.PHONY: lint
|
||||
lint: check-lint-version
|
||||
golangci-lint run --timeout=3m --config ../../.golangci.yml
|
||||
|
||||
check-lint-version: tidy
|
||||
go run main.go
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Check Lint Version
|
||||
|
||||
This package is designed to check the local golangci-lint version against that of the current github workflow.
|
||||
|
||||
## Usage
|
||||
|
||||
In the repo root, you can use the `make lint` command which makes use of this to verify the golangci-lint version and
|
||||
run the linter.
|
||||
|
||||
## Workflow
|
||||
|
||||
The `test-tooling` workflow is responsible for testing this package.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
module github.com/dapr/go-sdk/tools/check-lint-version
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/mod v0.13.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type GHWorkflow struct {
|
||||
Jobs struct {
|
||||
Build struct {
|
||||
Env struct {
|
||||
GOVER string `yaml:"GOVER"`
|
||||
GOLANGCILINTVER string `yaml:"GOLANGCILINT_VER"`
|
||||
} `yaml:"env"`
|
||||
} `yaml:"build"`
|
||||
} `yaml:"jobs"`
|
||||
}
|
||||
|
||||
func parseWorkflowVersionFromFile(path string) (string, error) {
|
||||
var ghWorkflow GHWorkflow
|
||||
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = yaml.Unmarshal(raw, &ghWorkflow)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ghWorkflow.Jobs.Build.Env.GOLANGCILINTVER, err
|
||||
}
|
||||
|
||||
func getCurrentVersion() (string, error) {
|
||||
out, err := exec.Command("golangci-lint", "--version").Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
regex, err := regexp.Compile(`golangci-lint\shas\sversion\sv?([\d+.]+[\d])`)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
matches := regex.FindStringSubmatch(string(out))
|
||||
|
||||
if matches == nil {
|
||||
return "", fmt.Errorf("no version found: %v", string(out))
|
||||
}
|
||||
return fmt.Sprintf("v%s", matches[1]), err
|
||||
}
|
||||
|
||||
func isVersionValid(workflowVersion, currentVersion string) bool {
|
||||
res := semver.MajorMinor(workflowVersion) == semver.MajorMinor(currentVersion)
|
||||
return res
|
||||
}
|
||||
|
||||
func compareVersions(path string) string {
|
||||
workflowVersion, err := parseWorkflowVersionFromFile(path)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Error parsing workflow version: %v", err)
|
||||
}
|
||||
currentVersion, err := getCurrentVersion()
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Error getting current version: %v", err)
|
||||
}
|
||||
validVersion := isVersionValid(workflowVersion, currentVersion)
|
||||
if !validVersion {
|
||||
return fmt.Sprintf("Invalid version, expected: %s, current: %s - See: https://golangci-lint.run/usage/install/ for instructions to update", workflowVersion, currentVersion)
|
||||
}
|
||||
return fmt.Sprintf("Linter version is valid (MajorMinor): %s", currentVersion)
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(compareVersions("../../.github/workflows/test-on-push.yaml"))
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseWorkflow(t *testing.T) {
|
||||
t.Run("parse invalid workflow file", func(t *testing.T) {
|
||||
parsedVersion, err := parseWorkflowVersionFromFile("../../.github/workflows/invalid.yaml")
|
||||
assert.Equal(t, "", parsedVersion)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("parse workflow file with a missing key", func(t *testing.T) {
|
||||
parsedVersion, err := parseWorkflowVersionFromFile("./testing/invalid-test.yml")
|
||||
assert.Equal(t, "", parsedVersion)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("parse an invalid workflow file", func(t *testing.T) {
|
||||
parsedVersion, err := parseWorkflowVersionFromFile("./testing/invalid-yaml.yml")
|
||||
assert.Equal(t, "", parsedVersion)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("parse testing workflow file", func(t *testing.T) {
|
||||
parsedVersion, err := parseWorkflowVersionFromFile("../../.github/workflows/test-tooling.yml")
|
||||
assert.Equal(t, "v1.54.2", parsedVersion)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCurrentVersion(t *testing.T) {
|
||||
t.Run("get current version from system", func(t *testing.T) {
|
||||
currentVersion, err := getCurrentVersion()
|
||||
assert.Equal(t, "v1.54.2", currentVersion)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
// TODO: test failure to detect current version
|
||||
|
||||
// TODO: test failure to compile regex expression
|
||||
|
||||
// TODO: test failure finding matches
|
||||
}
|
||||
|
||||
func TestIsVersionValid(t *testing.T) {
|
||||
t.Run("compare versions - exactly equal to", func(t *testing.T) {
|
||||
assert.Equal(t, true, isVersionValid("v1.54.2", "v1.54.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - patch version greater (workflow)", func(t *testing.T) {
|
||||
assert.Equal(t, true, isVersionValid("v1.54.3", "v1.54.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - patch version greater (installed)", func(t *testing.T) {
|
||||
assert.Equal(t, true, isVersionValid("v1.54.2", "v1.54.3"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - invalid (installed)", func(t *testing.T) {
|
||||
assert.Equal(t, false, isVersionValid("v1.54.2", "v1.52.2"))
|
||||
})
|
||||
|
||||
t.Run("compare versions - invalid (workflow)", func(t *testing.T) {
|
||||
assert.Equal(t, false, isVersionValid("v1.52.2", "v1.54.2"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompareVersions(t *testing.T) {
|
||||
t.Run("Valid comparison", func(t *testing.T) {
|
||||
res := compareVersions("../../.github/workflows/test-on-push.yaml")
|
||||
assert.Contains(t, res, "Linter version is valid")
|
||||
})
|
||||
|
||||
t.Run("Invalid comparison", func(t *testing.T) {
|
||||
res := compareVersions("./testing/invalid-test.yml")
|
||||
assert.Contains(t, res, "Invalid version")
|
||||
})
|
||||
|
||||
// TODO: test function for failure to get the current version using getCurrentVersion()
|
||||
|
||||
t.Run("Invalid path for comparison", func(t *testing.T) {
|
||||
res := compareVersions("./testing/invalid-test-incorrect-path.yml")
|
||||
assert.Contains(t, res, "Error parsing workflow")
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
NOGOLANGCILINT_VER: "123.123.123"
|
||||
|
|
@ -0,0 +1 @@
|
|||
testfile
|
||||
Loading…
Reference in New Issue