Skip to content

Integrate models-schema into codegen and fix openapi verify issues#2904

Open
JoelSpeed wants to merge 1 commit into
openshift:masterfrom
JoelSpeed:integrated-models-schema
Open

Integrate models-schema into codegen and fix openapi verify issues#2904
JoelSpeed wants to merge 1 commit into
openshift:masterfrom
JoelSpeed:integrated-models-schema

Conversation

@JoelSpeed

Copy link
Copy Markdown
Contributor

Models schema has historically been a separate step, we often forget about it and this has lead to incomplete verification of the openapi.json schema over time.

This PR integrates the model schema stage directly into codegen, including integrating the verify step. The existing file locations and output for both the Go models and json schema remain as they were.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Hello @JoelSpeed! Some important instructions when contributing to openshift/api:
API design plays an important part in the user experience of OpenShift and as such API PRs are subject to a high level of scrutiny to ensure they follow our best practices. If you haven't already done so, please review the OpenShift API Conventions and ensure that your proposed changes are compliant. Following these conventions will help expedite the api review process for your PR.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 2b03a6db-7ce6-4d84-88dc-effe181e9e9a

📥 Commits

Reviewing files that changed from the base of the PR and between c184ba0 and 7bc1397.

⛔ Files ignored due to path filters (2)
  • openapi/cmd/models-schema/main.go is excluded by !openapi/**
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (4)
  • Makefile
  • hack/update-openapi.sh
  • tools/codegen/pkg/openapi/generator.go
  • tools/codegen/pkg/openapi/openapi.go
✅ Files skipped from review due to trivial changes (1)
  • Makefile
🚧 Files skipped from review as they are similar to previous changes (2)
  • tools/codegen/pkg/openapi/generator.go
  • tools/codegen/pkg/openapi/openapi.go

📝 Walkthrough

Walkthrough

The PR updates the OpenAPI generation workflow to use integrated code generation, changes the default output package path, and stops cleaning models-schema. It also separates generated Go output from JSON schema generation, and splits verification into byte-level Go file comparison plus separate JSON schema comparison. JSON schema generation now runs a temporary Go program via os/exec.

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: integrating models-schema into codegen and addressing OpenAPI verification issues.
Description check ✅ Passed The description is directly related to the changes and accurately explains the codegen and verification integration.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo test titles were added or changed in the PR files; the modified code contains no It/Describe/Context/When calls.
Test Structure And Quality ✅ Passed PR only changes Makefile/scripts and openapi generator/verification code; no Ginkgo test files or test blocks were modified, so the checklist is not applicable.
Microshift Test Compatibility ✅ Passed The PR only changes OpenAPI/codegen files and adds no new Ginkgo e2e tests or MicroShift-unsupported APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e test declarations were added; only Makefile, shell, and codegen files changed.
Topology-Aware Scheduling Compatibility ✅ Passed Only OpenAPI codegen scripts and generators changed; no manifests, controllers, or scheduling constraints were introduced.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were added in the edited Go files; the only os.Stdout use is inside an embedded temp-program string.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; only Makefile and OpenAPI codegen scripts changed, and none contain It/Describe/Context/When.
No-Weak-Crypto ✅ Passed Changed OpenAPI/Makefile scripts contain no crypto imports or weak algorithms; only bytes.Equal on generated file bytes, not secrets/tokens.
Container-Privileges ✅ Passed Changed files are Makefile/shell/Go codegen only; no container/K8s manifests were modified, and privilege keys only appear in existing schema docs.
No-Sensitive-Data-In-Logs ✅ Passed Touched files only emit generic status/path logs; no passwords, tokens, PII, session IDs, or host/customer data are logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented
The command is terminated due to an error: build linters: unable to load custom analyzer "kubeapilinter": tools/_output/bin/kube-api-linter.so, plugin: not implemented


Comment @coderabbitai help to get the list of available commands.

@openshift-ci openshift-ci Bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jun 26, 2026
@openshift-ci openshift-ci Bot requested review from deads2k and everettraven June 26, 2026 11:42
@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign joelspeed for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tools/codegen/pkg/openapi/openapi.go (1)

29-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep verify generation isolated from the checked-in output.

goOutputPackagePath and outputFile are computed before line 42 swaps outputPackagePath to the temp dir, so verify mode still writes into the real openapi/generated_openapi tree. Then line 83 compares that same path as both generated and current output, allowing Go verification to pass after mutating the workspace.

Proposed direction
 	originalOutputPackagePath := outputPackagePath
-	goOutputPackagePath := filepath.Join(outputPackagePath, generatedOpenAPI)
-	outputFile := filepath.Join(goOutputPackagePath, outputFileName)
+	currentGoOutputPackagePath := filepath.Join(originalOutputPackagePath, generatedOpenAPI)
+	currentOutputFile := filepath.Join(currentGoOutputPackagePath, outputFileName)
+	goOutputPackagePath := currentGoOutputPackagePath
 
 	if verify {
 		outputPackageBase := filepath.Base(outputPackagePath)
@@
 
 		outputPackagePath = filepath.Join(tmpDir, outputPackageBase)
+		goOutputPackagePath = filepath.Join(outputPackagePath, generatedOpenAPI)
 	}
 	arguments := args.New()
 	arguments.OutputDir = goOutputPackagePath
-	arguments.OutputPkg = goOutputPackagePath
+	arguments.OutputPkg = currentGoOutputPackagePath
@@
-		if err := verifyGoFile(outputFile, goOutputPackagePath, outputFileName); err != nil {
+		if err := verifyGoFile(currentOutputFile, goOutputPackagePath, outputFileName); err != nil {
 			return fmt.Errorf("error verifying generated openapi Go file: %w", err)
 		}
@@
-		return verifyJSONSchema(goOutputPackagePath, originalOutputPackagePath)
+		return verifyJSONSchema(currentGoOutputPackagePath, originalOutputPackagePath)

Also applies to: 83-88

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/codegen/pkg/openapi/openapi.go` around lines 29 - 46, Verify mode is
still using the checked-in output path because `goOutputPackagePath` and
`outputFile` are computed before `verify` swaps `outputPackagePath` to the temp
directory. Recompute the Go output path and output file after the temp-path
reassignment in the openapi generation flow, and make the later compare step use
the temp-generated path versus the real checked-in path so
`openapi/generated_openapi` is never mutated during verification. Update the
logic around the openapi generation function and the compare section that reads
the generated output to ensure verify mode stays isolated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hack/update-openapi.sh`:
- Line 10: The script invocation in the update-openapi flow leaves the
${SCRIPT_ROOT} path expansion unquoted, which can break when the checkout path
contains spaces. Update the call in hack/update-openapi.sh so the
hack/update-codegen.sh path is quoted while keeping the existing
GENERATOR/openapi and EXTRA_ARGS behavior intact.

In `@tools/codegen/pkg/openapi/openapi.go`:
- Around line 244-252: Both `tidyCmd` and the later `cmd` in the OpenAPI codegen
flow are created with `exec.Command`, so they can hang indefinitely during
module resolution. Update the code that runs `go mod tidy` and `go run .` to use
`exec.CommandContext` with a timeout-backed `context.Context`, and propagate
that context through the surrounding helper/function that contains these
commands so cancellation works cleanly. Also add any needed context-related
import and keep the existing error handling around the `tidyCmd.Run()` and
`cmd.Run()` paths.

---

Outside diff comments:
In `@tools/codegen/pkg/openapi/openapi.go`:
- Around line 29-46: Verify mode is still using the checked-in output path
because `goOutputPackagePath` and `outputFile` are computed before `verify`
swaps `outputPackagePath` to the temp directory. Recompute the Go output path
and output file after the temp-path reassignment in the openapi generation flow,
and make the later compare step use the temp-generated path versus the real
checked-in path so `openapi/generated_openapi` is never mutated during
verification. Update the logic around the openapi generation function and the
compare section that reads the generated output to ensure verify mode stays
isolated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 70d87c72-2f14-497a-9668-510dae24de74

📥 Commits

Reviewing files that changed from the base of the PR and between 39631f4 and c184ba0.

⛔ Files ignored due to path filters (2)
  • openapi/cmd/models-schema/main.go is excluded by !openapi/**
  • openapi/openapi.json is excluded by !openapi/**
📒 Files selected for processing (4)
  • Makefile
  • hack/update-openapi.sh
  • tools/codegen/pkg/openapi/generator.go
  • tools/codegen/pkg/openapi/openapi.go

Comment thread hack/update-openapi.sh

./models-schema | jq '.' > ${output_package}/openapi.json
# Generate both Go and JSON OpenAPI schemas using the integrated codegen tool
GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} ${SCRIPT_ROOT}/hack/update-codegen.sh

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Quote the script path invocation.

Line 10 leaves ${SCRIPT_ROOT} unquoted when invoking hack/update-codegen.sh, so checkouts under paths with spaces can fail before codegen starts.

Proposed fix
-GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} ${SCRIPT_ROOT}/hack/update-codegen.sh
+GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} "${SCRIPT_ROOT}/hack/update-codegen.sh"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} ${SCRIPT_ROOT}/hack/update-codegen.sh
GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} "${SCRIPT_ROOT}/hack/update-codegen.sh"
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 10-10: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hack/update-openapi.sh` at line 10, The script invocation in the
update-openapi flow leaves the ${SCRIPT_ROOT} path expansion unquoted, which can
break when the checkout path contains spaces. Update the call in
hack/update-openapi.sh so the hack/update-codegen.sh path is quoted while
keeping the existing GENERATOR/openapi and EXTRA_ARGS behavior intact.

Source: Linters/SAST tools

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While unlikely to be a major issue, this seems like a reasonable change to make while we are here.

I wouldn't block on this though.

Comment on lines +244 to +252
// Run go mod tidy to fix dependencies
tidyCmd := exec.Command("go", "mod", "tidy")
tidyCmd.Dir = tempDir
if err := tidyCmd.Run(); err != nil {
return nil, fmt.Errorf("failed to run go mod tidy: %w", err)
}

// Run the temporary program and capture its output
cmd := exec.Command("go", "run", ".")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Bound external go commands with a context.

go mod tidy and go run . can block on module/toolchain resolution, which can hang verification indefinitely in CI. Use exec.CommandContext with a timeout. As per path instructions, **/*.go: “context.Context for cancellation and timeouts”.

Proposed fix
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
+	defer cancel()
+
 	// Run go mod tidy to fix dependencies
-	tidyCmd := exec.Command("go", "mod", "tidy")
+	tidyCmd := exec.CommandContext(ctx, "go", "mod", "tidy")
 	tidyCmd.Dir = tempDir
 	if err := tidyCmd.Run(); err != nil {
 		return nil, fmt.Errorf("failed to run go mod tidy: %w", err)
 	}
 
+	runCtx, runCancel := context.WithTimeout(context.Background(), 5*time.Minute)
+	defer runCancel()
+
 	// Run the temporary program and capture its output
-	cmd := exec.Command("go", "run", ".")
+	cmd := exec.CommandContext(runCtx, "go", "run", ".")

Also add the imports:

+	"context"
 	"os/exec"
+	"time"

Also applies to: 260-262

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/codegen/pkg/openapi/openapi.go` around lines 244 - 252, Both `tidyCmd`
and the later `cmd` in the OpenAPI codegen flow are created with `exec.Command`,
so they can hang indefinitely during module resolution. Update the code that
runs `go mod tidy` and `go run .` to use `exec.CommandContext` with a
timeout-backed `context.Context`, and propagate that context through the
surrounding helper/function that contains these commands so cancellation works
cleanly. Also add any needed context-related import and keep the existing error
handling around the `tidyCmd.Run()` and `cmd.Run()` paths.

Source: Path instructions

@JoelSpeed JoelSpeed force-pushed the integrated-models-schema branch from c184ba0 to 7bc1397 Compare June 26, 2026 12:37
@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@JoelSpeed: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Comment thread hack/update-openapi.sh

./models-schema | jq '.' > ${output_package}/openapi.json
# Generate both Go and JSON OpenAPI schemas using the integrated codegen tool
GENERATOR=openapi EXTRA_ARGS=--openapi:output-package-path=${output_path} ${SCRIPT_ROOT}/hack/update-codegen.sh

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While unlikely to be a major issue, this seems like a reasonable change to make while we are here.

I wouldn't block on this though.

packageName := filepath.Base(schemaSourcePackage)

// Create temporary main.go that calls the generated function
tempMainContent := fmt.Sprintf(`package main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we needing to produce this temporary go program to run?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants