Skip to content

Commit 0c755da

Browse files
authored
Merge pull request #11733 from JoelSpeed/add-api-linter
🌱 Add KAL linter for linting API conventions
2 parents 8cf4b86 + 49f8a9a commit 0c755da

File tree

5 files changed

+88
-1
lines changed

5 files changed

+88
-1
lines changed

.github/workflows/pr-golangci-lint.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ jobs:
3333
version: v1.63.4
3434
args: --out-format=colored-line-number
3535
working-directory: ${{matrix.working-directory}}
36+
- name: Lint API
37+
run: GOLANGCI_LINT_EXTRA_ARGS=--out-format=colored-line-number make lint-api

.golangci-kal.yml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
run:
2+
timeout: 10m
3+
go: "1.23"
4+
allow-parallel-runners: true
5+
6+
linters:
7+
disable-all: true
8+
enable:
9+
- kal # linter for Kube API conventions
10+
11+
linters-settings:
12+
custom:
13+
kal:
14+
type: "module"
15+
description: KAL is the Kube-API-Linter and lints Kube like APIs based on API conventions and best practices.
16+
settings:
17+
linters:
18+
enable:
19+
# Per discussion in July 2024, we are keeping phase fields for now.
20+
# See https://github.com/kubernetes-sigs/cluster-api/pull/10897#discussion_r1685929508
21+
# and https://github.com/kubernetes-sigs/cluster-api/pull/10897#discussion_r1685919394.
22+
# - "nophase" # Phase fields are discouraged by the Kube API conventions, use conditions instead.
23+
24+
# Linters below this line are disabled, pending conversation on how and when to enable them.
25+
# - "conditions" # Ensure conditions have the correct json tags and markers.
26+
# - "commentstart" # Ensure comments start with the serialized version of the field name.
27+
# - "integers" # Ensure only int32 and int64 are used for integers.
28+
# - "jsontags" # Ensure every field has a json tag.
29+
# - "maxlength" # Ensure all strings and arrays have maximum lengths/maximum items.
30+
# - "nobools" # Bools do not evolve over time, should use enums instead.
31+
# - "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
32+
# - "requiredfields" # Required fields should not be pointers, and should not have `omitempty`.
33+
# - "statussubresource" # All root objects that have a `status` field should have a status subresource.
34+
disable:
35+
- "*" # We will manually enable new linters after understanding the impact. Disable all by default.
36+
lintersConfig:
37+
conditions:
38+
isFirstField: Warn # Require conditions to be the first field in the status struct.
39+
usePatchStrategy: Forbid # Conditions should not use the patch strategy on CRDs.
40+
useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required.
41+
# jsonTags:
42+
# jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case.
43+
# optionalOrRequired:
44+
# preferredOptionalMarker: optional | kubebuilder:validation:Optional # The preferred optional marker to use, fixes will suggest to use this marker. Defaults to `optional`.
45+
# preferredRequiredMarker: required | kubebuilder:validation:Required # The preferred required marker to use, fixes will suggest to use this marker. Defaults to `required`.
46+
# requiredFields:
47+
# pointerPolicy: Warn | SuggestFix # Defaults to `SuggestFix`. We want our required fields to not be pointers.
48+
49+
issues:
50+
exclude-files:
51+
- "zz_generated.*\\.go$"
52+
- "vendored_openapi\\.go$"
53+
# We don't want to invest time to fix new linter findings in old API types.
54+
- "internal/apis/.*"
55+
- ".*_test.go" # Exclude test files.
56+
max-same-issues: 0
57+
max-issues-per-linter: 0
58+
exclude-rules:
59+
# KAL should only run on API folders.
60+
- path-except: "api/*"
61+
linters:
62+
- kal

.golangci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ linters-settings:
226226
- name: constant-logical-expr
227227
goconst:
228228
ignore-tests: true
229+
229230
issues:
230231
exclude-files:
231232
- "zz_generated.*\\.go$"

Makefile

+17-1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ GOLANGCI_LINT_VER := $(shell cat .github/workflows/pr-golangci-lint.yaml | grep
164164
GOLANGCI_LINT := $(abspath $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER))
165165
GOLANGCI_LINT_PKG := github.com/golangci/golangci-lint/cmd/golangci-lint
166166

167+
GOLANGCI_LINT_KAL_BIN := golangci-lint-kal
168+
GOLANGCI_LINT_KAL_VER := $(shell cat ./hack/tools/.custom-gcl.yaml | grep name: | sed 's/name: golangci-lint-kal-//')
169+
GOLANGCI_LINT_KAL := $(abspath $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_KAL_BIN)-$(GOLANGCI_LINT_KAL_VER))
170+
167171
GOVULNCHECK_BIN := govulncheck
168172
GOVULNCHECK_VER := v1.1.4
169173
GOVULNCHECK := $(abspath $(TOOLS_BIN_DIR)/$(GOVULNCHECK_BIN)-$(GOVULNCHECK_VER))
@@ -653,11 +657,12 @@ generate-test-infra-prowjobs: $(PROWJOB_GEN) ## Generates the prowjob configurat
653657
##@ lint and verify:
654658

655659
.PHONY: lint
656-
lint: $(GOLANGCI_LINT) ## Lint the codebase
660+
lint: $(GOLANGCI_LINT) $(GOLANGCI_LINT_KAL) ## Lint the codebase
657661
$(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS)
658662
cd $(TEST_DIR); $(GOLANGCI_LINT) run --path-prefix $(TEST_DIR) --config $(ROOT_DIR)/.golangci.yml -v $(GOLANGCI_LINT_EXTRA_ARGS)
659663
cd $(TOOLS_DIR); $(GOLANGCI_LINT) run --path-prefix $(TOOLS_DIR) --config $(ROOT_DIR)/.golangci.yml -v $(GOLANGCI_LINT_EXTRA_ARGS)
660664
./scripts/lint-dockerfiles.sh $(HADOLINT_VER) $(HADOLINT_FAILURE_THRESHOLD)
665+
$(GOLANGCI_LINT_KAL) run -v --config $(ROOT_DIR)/.golangci-kal.yml $(GOLANGCI_LINT_EXTRA_ARGS)
661666

662667
.PHONY: lint-dockerfiles
663668
lint-dockerfiles:
@@ -667,6 +672,14 @@ lint-dockerfiles:
667672
lint-fix: $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linter
668673
GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint
669674

675+
.PHONY: lint-api
676+
lint-api: $(GOLANGCI_LINT_KAL)
677+
$(GOLANGCI_LINT_KAL) run -v --config $(ROOT_DIR)/.golangci-kal.yml $(GOLANGCI_LINT_EXTRA_ARGS)
678+
679+
.PHONY: lint-api-fix
680+
lint-api-fix: $(GOLANGCI_LINT_KAL)
681+
GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint-api
682+
670683
.PHONY: tiltfile-fix
671684
tiltfile-fix: ## Format the Tiltfile
672685
TRACE=$(TRACE) ./hack/verify-starlark.sh fix
@@ -1492,6 +1505,9 @@ $(GINKGO): # Build ginkgo from tools folder.
14921505
$(GOLANGCI_LINT): # Build golangci-lint from tools folder.
14931506
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOLANGCI_LINT_PKG) $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER)
14941507

1508+
$(GOLANGCI_LINT_KAL): $(GOLANGCI_LINT) # Build golangci-lint-kal from custom configuration.
1509+
cd $(TOOLS_DIR); $(GOLANGCI_LINT) custom
1510+
14951511
$(GOVULNCHECK): # Build govulncheck.
14961512
GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOVULNCHECK_PKG) $(GOVULNCHECK_BIN) $(GOVULNCHECK_VER)
14971513

hack/tools/.custom-gcl.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: v1.63.4
2+
name: golangci-lint-kal-v1.63.4
3+
destination: ./bin
4+
plugins:
5+
- module: 'github.com/JoelSpeed/kal'
6+
version: v0.0.0-20250208110507-b94e5ede1177

0 commit comments

Comments
 (0)