diff --git a/.github/workflows/sanity.yaml b/.github/workflows/sanity.yaml index 55487ab1e..e3f6cb4dc 100644 --- a/.github/workflows/sanity.yaml +++ b/.github/workflows/sanity.yaml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + fetch-depth: 0 - uses: actions/setup-go@v6 with: @@ -23,6 +25,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + fetch-depth: 0 # Fetch all history for all branches (needed for API diff) - uses: actions/setup-go@v6 with: diff --git a/Makefile b/Makefile index f84bafb90..b52f03abd 100644 --- a/Makefile +++ b/Makefile @@ -118,7 +118,7 @@ help-extended: #HELP Display extended help. #SECTION Development .PHONY: lint -lint: lint-custom $(GOLANGCI_LINT) #HELP Run golangci linter. +lint: lint-custom lint-api-diff $(GOLANGCI_LINT) #HELP Run golangci linter. $(GOLANGCI_LINT) run --build-tags $(GO_BUILD_TAGS) $(GOLANGCI_LINT_ARGS) .PHONY: lint-helm @@ -149,6 +149,10 @@ custom-linter-build: #EXHELP Build custom linter lint-custom: custom-linter-build #EXHELP Call custom linter for the project go vet -tags=$(GO_BUILD_TAGS) -vettool=./bin/custom-linter ./... +.PHONY: lint-api-diff +lint-api-diff: $(GOLANGCI_LINT) #HELP Validate API changes using kube-api-linter with diff-aware analysis + bash hack/api-lint-diff/run.sh + .PHONY: k8s-pin k8s-pin: #EXHELP Pin k8s staging modules based on k8s.io/kubernetes version (in go.mod or from K8S_IO_K8S_VERSION env var) and run go mod tidy. K8S_IO_K8S_VERSION='$(K8S_IO_K8S_VERSION)' go run hack/tools/k8smaintainer/main.go @@ -198,7 +202,7 @@ generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyI $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) object:headerFile="hack/boilerplate.go.txt" paths="./..." .PHONY: verify -verify: k8s-pin kind-verify-versions fmt generate manifests update-tls-profiles crd-ref-docs verify-bingo #HELP Verify all generated code is up-to-date. Runs k8s-pin instead of just tidy. +verify: k8s-pin kind-verify-versions fmt generate manifests update-tls-profiles crd-ref-docs verify-bingo lint-api-diff #HELP Verify all generated code is up-to-date. Runs k8s-pin instead of just tidy. git diff --exit-code .PHONY: verify-bingo diff --git a/hack/api-lint-diff/run.sh b/hack/api-lint-diff/run.sh index 993ec9052..a5e08eb9b 100755 --- a/hack/api-lint-diff/run.sh +++ b/hack/api-lint-diff/run.sh @@ -196,7 +196,36 @@ check_linter_support() { # Find golangci-lint binary find_golangci_lint() { - # Check for custom build first + # Check if Variables.mk exists and extract golangci-lint path + if [[ -f ".bingo/Variables.mk" ]]; then + # Extract version from GOLANGCI_LINT variable + # Format: GOLANGCI_LINT := $(GOBIN)/golangci-lint-v2.7.2 + local version + version=$(grep '^GOLANGCI_LINT' .bingo/Variables.mk | sed -E 's/.*golangci-lint-(v[0-9]+\.[0-9]+\.[0-9]+).*/\1/') + + if [[ -n "${version}" ]]; then + # Use go env to get the actual GOBIN/GOPATH + local gobin + gobin=$(go env GOBIN) + + # If GOBIN is empty, use GOPATH/bin + if [[ -z "${gobin}" ]]; then + local gopath + gopath=$(go env GOPATH) + # Take first entry if GOPATH has multiple paths (colon-separated) + gobin="${gopath%%:*}/bin" + fi + + # Check if the versioned binary exists + local bingo_path="${gobin}/golangci-lint-${version}" + if [[ -f "${bingo_path}" ]]; then + echo "${bingo_path}" + return 0 + fi + fi + fi + + # Check for custom build if [[ -f ".bingo/golangci-lint" ]]; then echo ".bingo/golangci-lint" return 0 @@ -216,6 +245,7 @@ find_golangci_lint() { echo -e "${RED}Error: golangci-lint not found.${NC}" >&2 echo -e "${RED}Searched for:${NC}" >&2 + echo -e " - .bingo/Variables.mk (bingo-managed versioned binary)" >&2 echo -e " - .bingo/golangci-lint" >&2 echo -e " - bin/golangci-lint" >&2 echo -e " - golangci-lint on your \$PATH" >&2 @@ -482,6 +512,23 @@ main() { # Create temporary config create_temp_config + # Ensure baseline branch is available (important for CI environments like GitHub Actions) + if ! git rev-parse --verify "${BASELINE_BRANCH}" &> /dev/null; then + echo -e "${YELLOW}Baseline branch '${BASELINE_BRANCH}' not found locally. Fetching from origin...${NC}" >&2 + + # Fetch the baseline branch from origin + if ! git fetch origin "${BASELINE_BRANCH}:${BASELINE_BRANCH}" 2>&1; then + # If direct fetch fails, try fetching with remote tracking + if ! git fetch origin "${BASELINE_BRANCH}" 2>&1; then + echo -e "${RED}Error: Failed to fetch baseline branch '${BASELINE_BRANCH}' from origin${NC}" >&2 + echo -e "${RED}Please ensure the branch exists in the remote repository.${NC}" >&2 + exit 1 + fi + # Use the remote tracking branch + BASELINE_BRANCH="origin/${BASELINE_BRANCH}" + fi + fi + # Get changed files get_changed_files > "${TEMP_DIR}/changed_files.txt"