Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .common-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ stages:
# https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines
workflow:
rules:
- if: $CI_COMMIT_TAG =~ /^api\/v/
when: never
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
Expand Down
8 changes: 7 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ version: 2
updates:
- package-ecosystem: "gomod"
target-branch: main
directory: "/"
directories:
- "/"
- "/api"
schedule:
interval: "daily"
cooldown:
Expand All @@ -20,6 +22,10 @@ updates:
- k8s.io/*
exclude-patterns:
- k8s.io/klog/*
cross-directory:
patterns:
- "*"
group-by: dependency-name

- package-ecosystem: "gomod"
target-branch: main
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/api-post-tag-validation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: API Post-Tag Validation

on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
workflow_dispatch:
inputs:
operator_tag:
description: "Operator tag to validate"
required: true
type: string

permissions:
contents: read

jobs:
validate-api-module:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout tagged code
uses: actions/checkout@v7
with:
ref: ${{ github.event.inputs.operator_tag || github.ref }}
fetch-depth: 0
persist-credentials: false

- name: Get Golang version
run: |
GOLANG_VERSION=$(grep "GOLANG_VERSION ?=" versions.mk)
echo "GOLANG_VERSION=${GOLANG_VERSION##GOLANG_VERSION ?= }" >> "${GITHUB_ENV}"

- name: Install Go
uses: actions/setup-go@v7
with:
go-version: ${{ env.GOLANG_VERSION }}

- name: Validate published API module
env:
OPERATOR_TAG: ${{ github.event.inputs.operator_tag || github.ref_name }}
run: make validate-published-api-module OPERATOR_TAG="${OPERATOR_TAG}"
53 changes: 53 additions & 0 deletions .github/workflows/api-release-checks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: API Release Checks

on:
pull_request:
types:
- opened
- synchronize
- reopened
- edited

permissions:
contents: read

jobs:
api-version-unpublished:
if: |
contains(github.event.pull_request.title, 'operator') &&
contains(github.event.pull_request.title, 'version') &&
contains(github.event.pull_request.title, 'bump')
Comment on lines +31 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

sed -n '1,120p' .github/workflows/api-release-checks.yaml
rg -n --glob '!vendor/**' 'validate-api-version-unpublished|API Release Checks|operator.*version.*bump|OPERATOR_VERSION|api/v' .github Makefile hack versions.mk . 2>/dev/null | head -240

Repository: NVIDIA/gpu-operator

Length of output: 10771


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- validator ---'
sed -n '1,220p' hack/validate-api-version-unpublished.sh
printf '%s\n' '--- make/version definitions ---'
sed -n '220,265p' Makefile
sed -n '1,180p' versions.mk
printf '%s\n' '--- release/version references ---'
rg -n -i --glob '!vendor/**' --glob '!third_party/**' '(version bump|bump.*version|release.*version|operator.*version|api.*tag|unpublished|pull request.*title|title.*operator)' .github README.md CONTRIBUTING.md AGENTS.md PROJECT Makefile hack versions.mk 2>/dev/null | head -300
printf '%s\n' '--- release workflow/template filenames ---'
git ls-files '.github' | rg -i '(release|pull|pr|version|api)'

Repository: NVIDIA/gpu-operator

Length of output: 15870


🤖 get_repo_knowledge executed:

get_repo_knowledge NVIDIA/gpu-operator /tmp/coderabbit-repo-knowledge/nvidia-gpu-operator-eed98df4/conventions

Length of output: 4401


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- pull request template ---'
sed -n '1,220p' .github/PULL_REQUEST_TEMPLATE.md
printf '%s\n' '--- contributing release guidance ---'
sed -n '45,75p' CONTRIBUTING.md
printf '%s\n' '--- API post-tag validation workflow ---'
sed -n '1,110p' .github/workflows/api-post-tag-validation.yaml
printf '%s\n' '--- release workflow triggers and version inputs ---'
sed -n '1,75p' .github/workflows/release.yaml
sed -n '1,55p' .github/workflows/release-rc-assets.yaml

Repository: NVIDIA/gpu-operator

Length of output: 8575


Run the API-tag check for version changes.

If a PR changes the API module version but its title does not contain all three required substrings, GitHub skips api-version-unpublished. The validator then does not check whether api/<version> already exists, so a title such as Release v25.3.0 can bypass this release check. The PR template does not require the current title format.

Gate the job on changed API version metadata, or use a required release signal that cannot be omitted by changing the title.

runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
persist-credentials: false

- name: Get Golang version
run: |
GOLANG_VERSION=$(grep "GOLANG_VERSION ?=" versions.mk)
echo "GOLANG_VERSION=${GOLANG_VERSION##GOLANG_VERSION ?= }" >> "${GITHUB_ENV}"

- name: Install Go
uses: actions/setup-go@v7
with:
go-version: ${{ env.GOLANG_VERSION }}

- name: Check that API version is unpublished
run: make validate-api-version-unpublished
7 changes: 1 addition & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ linters:
rules:
- linters:
- staticcheck
path: (.+)\.go$
text: 'SA1019: \(github.com/NVIDIA/gpu-operator/api/nvidia/v1.DriverLicensingConfigSpec\).ConfigMapName is deprecated(.+)'
- linters:
- staticcheck
path: (.+)\.go$
text: 'SA1019: \(github.com/NVIDIA/gpu-operator/api/nvidia/v1alpha1.DriverLicensingConfigSpec\).Name is deprecated(.+)'
text: 'SA1019: .*\.(ConfigMapName|Name) is deprecated: ConfigMapName has been deprecated in favour of SecretName(.+)'
formatters:
enable:
- gofmt
Expand Down
4 changes: 4 additions & 0 deletions .nvidia-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ update-nspect:
extends:
- .update-nspect
rules:
- if: $CI_COMMIT_TAG =~ /^api\/v/
when: never
- if: $CI_COMMIT_TAG
variables:
OSRB_BUG_ID: "${OSRB_BUG_ID}"
Expand All @@ -180,6 +182,8 @@ ngc-image-publish:
extends:
- .publish-images
rules:
- if: $CI_COMMIT_TAG =~ /^api\/v/
when: never
- if: $CI_COMMIT_TAG
needs:
- job: update-nspect
Expand Down
54 changes: 43 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
include $(CURDIR)/versions.mk

MODULE := github.com/NVIDIA/gpu-operator
API_DIR := $(PROJECT_DIR)/api
API_MODULE := $(MODULE)/api
GOPROXY ?= https://proxy.golang.org,direct

ifeq ($(IMAGE_NAME),)
Expand Down Expand Up @@ -102,20 +104,23 @@ undeploy:
$(KUSTOMIZE) build config/default | kubectl delete -f -

# Generate manifests e.g. CRD, RBAC etc.
.PHONY: manifests
manifests: install-tools
@echo "- Generating CRDs from the codebase"
$(CONTROLLER_GEN) rbac:roleName=gpu-operator-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) rbac:roleName=gpu-operator-role webhook paths="./..."
cd $(API_DIR) && $(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=$(PROJECT_DIR)/config/crd/bases

# Generate code
.PHONY: generate generate-clientset
generate: install-tools
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
cd $(API_DIR) && $(CONTROLLER_GEN) object:headerFile="$(PROJECT_DIR)/hack/boilerplate.go.txt" paths="./..."

generate-clientset: install-tools
$(CLIENT_GEN) --go-header-file=$(CURDIR)/hack/boilerplate.go.txt \
cd $(API_DIR) && $(CLIENT_GEN) --go-header-file=$(CURDIR)/hack/boilerplate.go.txt \
--clientset-name "versioned" \
--output-dir $(CURDIR)/api \
--output-pkg $(MODULE)/api \
--input-base $(CURDIR)/api \
--output-dir $(API_DIR) \
--output-pkg $(API_MODULE) \
--input-base $(API_DIR) \
--input nvidia/v1,nvidia/v1alpha1

# Generate bundle manifests and metadata, then validate generated files.
Expand Down Expand Up @@ -143,7 +148,7 @@ push-bundle-image: build-bundle-image
CMDS := $(patsubst ./cmd/%/,%,$(sort $(dir $(wildcard ./cmd/*/))))
CMD_TARGETS := $(patsubst %,cmd-%, $(CMDS))

CHECK_TARGETS := lint license-check validate-modules validate-generated-assets
CHECK_TARGETS := lint license-check validate-shared-dependencies validate-modules validate-generated-assets
MAKE_TARGETS := build check coverage cmds $(CMD_TARGETS) $(CHECK_TARGETS)
DOCKER_TARGETS := $(patsubst %,docker-%, $(MAKE_TARGETS))
.PHONY: $(MAKE_TARGETS) $(DOCKER_TARGETS)
Expand Down Expand Up @@ -206,6 +211,8 @@ check-third-party-notices: third-party-notices
fmt:
go list -f '{{.Dir}}' $(MODULE)/... \
| xargs gofmt -s -l -d
go -C $(API_DIR) list -f '{{.Dir}}' ./... \
| xargs gofmt -s -l -d

# Apply goimports -local github.com/NVIDIA/gpu-operator to the codebase
goimports:
Expand All @@ -214,10 +221,12 @@ goimports:

lint:
golangci-lint run ./...
cd $(API_DIR) && golangci-lint run --config $(PROJECT_DIR)/.golangci.yml ./...

BUILD_FLAGS = -ldflags "-s -w -X $(VERSION_PKG).gitCommit=$(GIT_COMMIT) -X $(VERSION_PKG).version=$(VERSION)"
build:
build: update-vendor
go build $(BUILD_FLAGS) ./...
go -C $(API_DIR) build ./...

cmds: $(CMD_TARGETS)
$(CMD_TARGETS): cmd-%:
Expand All @@ -230,14 +239,33 @@ sync-crds:

TOOLS_DIR := $(PROJECT_DIR)/tools
E2E_TESTS_DIR := $(PROJECT_DIR)/tests/e2e

validate-shared-dependencies:
@bash hack/validate-shared-dependencies.sh

validate-api-version-unpublished:
@bash hack/validate-api-version-unpublished.sh

validate-published-api-module:
@OPERATOR_VERSION="$(VERSION)" bash hack/validate-published-api-module.sh "$(OPERATOR_TAG)"

.PHONY: update-vendor
update-vendor:
go mod vendor

validate-modules:
@echo "- [api] Verifying that the dependencies have expected content..."
go -C $(API_DIR) mod verify
@echo "- [api] Checking for any unused/missing packages in go.mod..."
go -C $(API_DIR) mod tidy
@git diff --exit-code -- $(API_DIR)/go.sum $(API_DIR)/go.mod
@echo "- Verifying that the dependencies have expected content..."
go mod verify
@echo "- Checking for any unused/missing packages in go.mod..."
go mod tidy
@git diff --exit-code -- go.sum go.mod
@echo "- Checking if the vendor dir is in sync..."
go mod vendor
$(MAKE) update-vendor
@git diff --exit-code -- vendor
@echo "- [tools] Verifying that the dependencies have expected content..."
go -C $(TOOLS_DIR) mod verify
Expand Down Expand Up @@ -276,13 +304,17 @@ COVERAGE_FILE := coverage.out
unit-test: build
go list -f {{.Dir}} $(MODULE)/... | grep -v /tests/e2e \
| xargs go test -v -coverprofile=$(COVERAGE_FILE)
go -C $(API_DIR) test -v -coverprofile=$(PROJECT_DIR)/$(COVERAGE_FILE).api ./...
{ head -n1 $(COVERAGE_FILE); tail -n+2 $(COVERAGE_FILE); tail -n+2 $(COVERAGE_FILE).api; } > $(COVERAGE_FILE).tmp
mv $(COVERAGE_FILE).tmp $(COVERAGE_FILE)
rm -f $(COVERAGE_FILE).api

coverage: unit-test
cat $(COVERAGE_FILE) | grep -v "_mock.go" > $(COVERAGE_FILE).no-mocks
go tool cover -func=$(COVERAGE_FILE).no-mocks
GOFLAGS=-mod=readonly go tool cover -func=$(COVERAGE_FILE).no-mocks

cov-report: coverage install-tools
$(GCOV2LCOV) -infile $(COVERAGE_FILE) -outfile lcov.info
GOFLAGS=-mod=readonly $(GCOV2LCOV) -infile $(COVERAGE_FILE) -outfile lcov.info

##### Public rules #####
PUSH_TARGETS := push-image
Expand Down
61 changes: 61 additions & 0 deletions api/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module github.com/NVIDIA/gpu-operator/api

go 1.26.3

require (
github.com/NVIDIA/k8s-kata-manager v0.2.3
github.com/NVIDIA/k8s-operator-libs v0.0.0-20260629200812-d720f2557494
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.94.0
github.com/regclient/regclient v0.11.5
github.com/stretchr/testify v1.12.1
golang.org/x/mod v0.41.0
k8s.io/api v0.37.0
k8s.io/apimachinery v0.37.0
k8s.io/client-go v0.37.0
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.3 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/swag v0.27.1 // indirect
github.com/go-openapi/swag/cmdutils v0.27.1 // indirect
github.com/go-openapi/swag/conv v0.27.1 // indirect
github.com/go-openapi/swag/fileutils v0.27.1 // indirect
github.com/go-openapi/swag/jsonutils v0.27.1 // indirect
github.com/go-openapi/swag/loading v0.27.1 // indirect
github.com/go-openapi/swag/mangling v0.27.1 // indirect
github.com/go-openapi/swag/netutils v0.27.1 // indirect
github.com/go-openapi/swag/pools v0.27.1 // indirect
github.com/go-openapi/swag/stringutils v0.27.1 // indirect
github.com/go-openapi/swag/typeutils v0.27.1 // indirect
github.com/go-openapi/swag/yamlutils v0.27.1 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
k8s.io/kube-openapi v0.0.0-20260821135717-be32def86098 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
Loading
Loading