diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 2bb9b7b795e..68f100507d3 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -46,7 +46,7 @@ jobs: node-version: "20" - name: Install golangci-lint - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.10.1 + run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v2.11.4/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.11.4 - name: Install cspell run: npm install -g cspell@8.13.1 diff --git a/.github/workflows/lint-go.yml b/.github/workflows/lint-go.yml index ed96fe8a993..77f0d101c38 100644 --- a/.github/workflows/lint-go.yml +++ b/.github/workflows/lint-go.yml @@ -16,7 +16,7 @@ on: description: "GolangCI-Lint version to use" required: false type: string - default: "v2.10.1" + default: "v2.11.4" permissions: contents: read diff --git a/cli/azd/.golangci.yaml b/cli/azd/.golangci.yaml index 000b4285ec7..c490d9c149d 100644 --- a/cli/azd/.golangci.yaml +++ b/cli/azd/.golangci.yaml @@ -39,6 +39,7 @@ linters: - G304 # TODO: Potential file inclusion via variable - G104 # TODO: Errors unhandled - G117 # Exported struct fields matching secret patterns (false positives on field names) + - G122 # TODO: Filesystem operation in filepath.Walk/WalkDir callback uses race-prone path formatters: enable: - gofmt diff --git a/cli/azd/internal/repository/initializer_test.go b/cli/azd/internal/repository/initializer_test.go index f3b704f2613..56b48a7a7ba 100644 --- a/cli/azd/internal/repository/initializer_test.go +++ b/cli/azd/internal/repository/initializer_test.go @@ -802,6 +802,7 @@ func createLocalTemplateDir(t *testing.T, sourceTestData string) string { if err != nil { return err } + //nolint:gosec // G703: test paths are controlled return os.WriteFile(filepath.Join(dir, relTarget), content, 0600) }) require.NoError(t, err) diff --git a/cli/azd/internal/vsrpc/server.go b/cli/azd/internal/vsrpc/server.go index 3666af3cbac..592c0deb0b4 100644 --- a/cli/azd/internal/vsrpc/server.go +++ b/cli/azd/internal/vsrpc/server.go @@ -90,7 +90,7 @@ func (s *Server) Serve(l net.Listener) error { } // Run upload periodically in the background while the server is running. - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(context.Background()) //nolint:gosec // G118: cancel stored in s.cancelTelemetryUpload ts := telemetry.GetTelemetrySystem() backgroundTelemetry := func() { ticker := time.NewTicker(5 * time.Second) @@ -213,6 +213,7 @@ func serveRpc(w http.ResponseWriter, r *http.Request, handlers map[string]Handle call, isCall := req.(*jsonrpc2.Call) if isCall { span.SetAttributes(fields.JsonRpcId.String(fmt.Sprint(call.ID()))) + //nolint:gosec // G118: cancel stored in cancelers map and called on completion ctx, cancel := context.WithCancel(ctx) childCtx = ctx cancelersMu.Lock() diff --git a/cli/azd/magefile.go b/cli/azd/magefile.go index bc5ee7994b2..88e47063d59 100644 --- a/cli/azd/magefile.go +++ b/cli/azd/magefile.go @@ -158,7 +158,7 @@ func Preflight() error { // Check required tools are installed before running anything. if err := requireTool("golangci-lint", - "go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.10.1"); err != nil { + "go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.11.4"); err != nil { return err } if err := requireTool("cspell", "npm install -g cspell@8.13.1"); err != nil { diff --git a/cli/azd/pkg/infra/provisioning/terraform/terraform_provider.go b/cli/azd/pkg/infra/provisioning/terraform/terraform_provider.go index 87718099505..ae60883cfa8 100644 --- a/cli/azd/pkg/infra/provisioning/terraform/terraform_provider.go +++ b/cli/azd/pkg/infra/provisioning/terraform/terraform_provider.go @@ -748,6 +748,7 @@ func (t *TerraformProvider) createInputParametersFile( } log.Printf("Writing parameters file to: %s", inputFilePath) + //nolint:gosec // G703: path derived from infra config, not user input err = os.WriteFile(inputFilePath, []byte(replaced), 0600) if err != nil { return fmt.Errorf("writing parameter file: %w", err) diff --git a/cli/azd/pkg/infra/provisioning/terraform/terraform_provider_test.go b/cli/azd/pkg/infra/provisioning/terraform/terraform_provider_test.go index 14fc2ee6674..4b6520b72c0 100644 --- a/cli/azd/pkg/infra/provisioning/terraform/terraform_provider_test.go +++ b/cli/azd/pkg/infra/provisioning/terraform/terraform_provider_test.go @@ -305,6 +305,7 @@ func TestIsRemoteBackendConfig(t *testing.T) { require.NoError(t, err) // #nosec G306 -- test file permissions are intentionally readable + //nolint:gosec // G703: test paths are controlled err = os.WriteFile(filepath.Join(infraDir, "main.tf"), testContent, 0644) require.NoError(t, err) diff --git a/cli/azd/pkg/tools/dotnet/dotnet.go b/cli/azd/pkg/tools/dotnet/dotnet.go index cf9a5182526..2b5f6856940 100644 --- a/cli/azd/pkg/tools/dotnet/dotnet.go +++ b/cli/azd/pkg/tools/dotnet/dotnet.go @@ -163,7 +163,7 @@ func (cli *Cli) PublishAppHostManifest( ) } - return os.WriteFile(manifestPath, m, osutil.PermissionFile) + return os.WriteFile(manifestPath, m, osutil.PermissionFile) //nolint:gosec // G703: path from known project structure } // For single-file apphost, we need to use the .cs file directly diff --git a/cli/azd/pkg/update/manager_test.go b/cli/azd/pkg/update/manager_test.go index 1c5b0ae58fd..88894daf458 100644 --- a/cli/azd/pkg/update/manager_test.go +++ b/cli/azd/pkg/update/manager_test.go @@ -641,7 +641,10 @@ type urlRewriteTransport struct { func (t *urlRewriteTransport) RoundTrip(req *http.Request) (*http.Response, error) { // Rewrite the request URL to the test server, preserving path newURL := t.targetURL + req.URL.Path - newReq, err := http.NewRequestWithContext(req.Context(), req.Method, newURL, req.Body) + //nolint:gosec // G704: URL from test server, not user input + newReq, err := http.NewRequestWithContext( + req.Context(), req.Method, newURL, req.Body, + ) if err != nil { return nil, err } diff --git a/cli/azd/pkg/ux/spinner.go b/cli/azd/pkg/ux/spinner.go index 9237f514349..7770e3f2d5d 100644 --- a/cli/azd/pkg/ux/spinner.go +++ b/cli/azd/pkg/ux/spinner.go @@ -76,7 +76,7 @@ func (s *Spinner) Start(ctx context.Context) error { } // Use a context to determine when to stop the spinner - cancelCtx, cancel := context.WithCancel(ctx) + cancelCtx, cancel := context.WithCancel(ctx) //nolint:gosec // G118: cancel stored in s.cancel and called in Stop() s.cancel = cancel s.clear = false diff --git a/cli/azd/test/internal/tfoidc/main.go b/cli/azd/test/internal/tfoidc/main.go index 22c38219ca4..f7c51dfdb12 100644 --- a/cli/azd/test/internal/tfoidc/main.go +++ b/cli/azd/test/internal/tfoidc/main.go @@ -170,13 +170,15 @@ func fetchOIDCToken(ctx context.Context) (string, error) { return "", err } + //nolint:gosec // G704: URL is constructed from a trusted OIDC endpoint tokenReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) if err != nil { return "", err } tokenReq.Header.Set("Authorization", "Bearer "+os.Getenv("SYSTEM_ACCESSTOKEN")) - tokenRes, err := http.DefaultClient.Do(tokenReq) //nolint:gosec // G704: URL is constructed from a trusted OIDC endpoint + //nolint:gosec // G704: URL is constructed from a trusted OIDC endpoint + tokenRes, err := http.DefaultClient.Do(tokenReq) if err != nil { return "", err }