From 10e2f5735b7459bc5a4c1ae515659d0acd38eb8d Mon Sep 17 00:00:00 2001 From: Konstantin Chukhlomin Date: Sat, 20 Apr 2024 21:14:31 -0400 Subject: [PATCH] chore(gha): add test & lint steps, fix lint warnings --- .github/workflows/main.yml | 25 +++++++++++++++++++++++++ .golangci.yml | 4 ++++ Makefile | 21 +++++++++++++++++++++ go.mod | 2 +- main.go | 24 ++++++++++++------------ main_test.go | 10 +++++----- 6 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 .golangci.yml create mode 100644 Makefile diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index eba7a40..7f9116a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,6 +15,31 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.21" + + - name: Go Format + run: gofmt -s -w -l $(find . -type f -name '*.go'| grep -v "/vendor/") && git diff --exit-code + + - name: Go Vet + run: go vet ./... + + - name: Lint + uses: golangci/golangci-lint-action@v4 + with: + version: latest + + - name: Test + run: go test -v -count=1 -race -shuffle=on -coverprofile=coverage.txt -json ./... > test.json + + - name: Annotate tests + if: always() + uses: guyarb/golang-test-annotations@v0.7.0 + with: + test-results: test.json + - name: Build and push Docker image uses: chuhlomin/actions/docker-build-push@main with: diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..612b98c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,4 @@ +linters-settings: + gosec: + excludes: + - G304 # Expect WriteFile permissions to be 0600 or less diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e415bdd --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +.PHONY: help +## help: prints this help message +help: + @echo "Usage: \n" + @sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /' + +.PHONY: vet +## vet: run go vet +vet: + @go vet ./... + +.PHONY: test +## test: run tests +test: vet + @go test -cover ./... + +.PHONY: lint +## lint: run golangci-lint +# Install: https://golangci-lint.run/usage/install/ +lint: + @golangci-lint run ./... --out-format colored-line-number diff --git a/go.mod b/go.mod index 2662fb1..862dd67 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/chuhlomin/render-template -go 1.21.3 +go 1.21 require ( github.com/caarlos0/env/v10 v10.0.0 diff --git a/main.go b/main.go index 557f052..8aa6064 100644 --- a/main.go +++ b/main.go @@ -49,28 +49,28 @@ func run() error { if c.VarsPath != "" { varsFile, err := os.ReadFile(c.VarsPath) if err != nil { - return fmt.Errorf("failed to read vars file %q: %v", c.VarsPath, err) + return fmt.Errorf("failed to read vars file %q: %w", c.VarsPath, err) } var varsFromFile vars if err = yaml.Unmarshal(varsFile, &varsFromFile); err != nil { - return fmt.Errorf("failed to parse vars file %q: %v", c.VarsPath, err) + return fmt.Errorf("failed to parse vars file %q: %w", c.VarsPath, err) } c.Vars = mergeVars(c.Vars, varsFromFile) } output, err := renderTemplate(c.Template, c.Vars) if err != nil { - return fmt.Errorf("failed to render template: %v", err) + return fmt.Errorf("failed to render template: %w", err) } - if err = writeOutput(output); err != nil { + if err := writeOutput(output); err != nil { return err } - if len(c.ResultPath) != 0 { - err := os.WriteFile(c.ResultPath, []byte(output), 0644) + if c.ResultPath != "" { + err := os.WriteFile(c.ResultPath, []byte(output), 0o644) if err != nil { - return fmt.Errorf("failed to write file %q: %v", c.ResultPath, err) + return fmt.Errorf("failed to write file %q: %w", c.ResultPath, err) } } @@ -81,7 +81,7 @@ func varsParser(v string) (interface{}, error) { m := map[string]interface{}{} err := yaml.Unmarshal([]byte(v), &m) if err != nil { - return nil, fmt.Errorf("unable to parse Vars: %v", err) + return nil, fmt.Errorf("unable to parse Vars: %w", err) } return m, nil } @@ -167,7 +167,7 @@ func renderTemplate(templateFilePath string, vars vars) (string, error) { if errors.Is(err, os.ErrPermission) { return "", fmt.Errorf("have no permissions to read template file (%q)", templateFilePath) } - return "", fmt.Errorf("failed to read template %q: %v", templateFilePath, err) + return "", fmt.Errorf("failed to read template %q: %w", templateFilePath, err) } tmpl, err := template. @@ -180,7 +180,7 @@ func renderTemplate(templateFilePath string, vars vars) (string, error) { } var result bytes.Buffer - if err = tmpl.Execute(&result, vars); err != nil { + if err := tmpl.Execute(&result, vars); err != nil { return "", err } @@ -195,7 +195,7 @@ func writeOutput(output string) error { path := os.Getenv("GITHUB_OUTPUT") - f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0644) + f, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0o644) if err != nil { return fmt.Errorf( "failed to open result file %q: %v. "+ @@ -208,7 +208,7 @@ func writeOutput(output string) error { defer f.Close() if _, err = f.WriteString(githubOutput); err != nil { - return fmt.Errorf("failed to write result to file %q: %v", path, err) + return fmt.Errorf("failed to write result to file %q: %w", path, err) } return nil diff --git a/main_test.go b/main_test.go index 7902eb0..21e1ce6 100644 --- a/main_test.go +++ b/main_test.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "errors" - "os" "reflect" "testing" "time" @@ -163,11 +162,12 @@ QUJD }, } - os.Setenv("INPUT_TIMEZONE", "America/New_York") + t.Setenv("INPUT_TIMEZONE", "America/New_York") for _, tt := range tests { output, err := renderTemplate(tt.templateFilePath, tt.vars) - if err != nil { + switch { + case err != nil: if tt.expectedError == nil { t.Errorf("renderTemplate(%q, %v) returned an error, but was expected to succeed: %v", tt.templateFilePath, tt.vars, err) } else if err.Error() != tt.expectedError.Error() { @@ -179,9 +179,9 @@ QUJD err, ) } - } else if tt.expectedError != nil { + case tt.expectedError != nil: t.Errorf("renderTemplate(%q, %v) succeeded, but was expected to fail: %v", tt.templateFilePath, tt.vars, err) - } else if output != tt.expectedOutput { + case output != tt.expectedOutput: t.Errorf( "render(%q, %v) expected output: %q, got: %q", tt.templateFilePath,