* chore: update repo links Replace links to https://github.com/kubeflow/model-registry with links to https://github.com/kubeflow/hub Signed-off-by: Paul Boyd <paul@pboyd.io> * chore: update project name Updated the project name to Kubeflow Hub in several places. I probably missed some references, but I tried to be conservative since Model Registry is still a component of Hub. Signed-off-by: Paul Boyd <paul@pboyd.io> * chore: regenerate catalog files from the openapi spec Signed-off-by: Paul Boyd <paul@pboyd.io> --------- Signed-off-by: Paul Boyd <paul@pboyd.io>
17 KiB
AGENTS.md — Kubeflow Hub
Who This Is For
- AI agents: Automate bug fixes and repository tasks with minimal context
- Contributors: Humans using AI assistants or working directly on the codebase
- Maintainers: Ensure AI assistants follow project conventions and CI rules
Agent Behavior Policy
AI agents should:
- Make atomic, minimal, and reversible changes.
- Prefer local analysis (
make build,make test,make lint) before proposing commits. - NEVER modify configuration, CI/CD, or release automation unless explicitly requested.
- Use
AGENTS.mdandMakefileas the source of truth for development commands. - Ignore the
clients/ui/directory — it has its own development workflow and is not covered here. - Follow the Kubeflow AI Policy, specifically:
- Include in the commit message:
Assisted-by: [Agent Name], orCo-authored-by: [Agent Name]. - Avoid automated responses/comments to the Pull Requests or Issues on GitHub.
- Include in the commit message:
Agents must NOT:
- Bypass tests or linters
- Introduce dependencies without updating
go.mod/go.sum(Go),pyproject.toml(Python), orpackage.json(TypeScript) - Generate or commit large autogenerated files (use the
gen/*Make targets instead) - Modify OpenAPI specs (
api/openapi/) without regenerating dependent code - Modify CRD schemas or API versions without explicit instruction
Context Awareness
Before writing code, agents should:
- Read existing test cases and source files for pattern alignment
- Match import patterns and error-handling conventions from neighboring files
- Preserve existing logging style (uses
golang/glog) - Understand the module boundary — this is a Go workspace with multiple
go.modfiles - Review OpenAPI specs in
api/openapi/before changing API structures - Call out any breaking changes introduced and follow the deprecation policy
For additional context see the Model Registry documentation.
Repository Map
api/openapi/ # OpenAPI specs (model-registry.yaml, catalog.yaml)
├── src/ # Source YAML files merged into final specs
catalog/ # Catalog service — federated model discovery
├── clients/python/ # Python client for catalog API (Poetry)
├── internal/ # Catalog business logic & server
├── pkg/openapi/ # Generated OpenAPI client for catalog
├── Makefile # Catalog-specific build/test targets
clients/ # Client libraries and UI
├── python/ # Python client for model-registry API (Poetry)
└── ui/ # React UI + Go BFF (separate workflow, see UI Development below)
├── bff/ # Backend-for-Frontend (Go)
└── frontend/ # React/TypeScript frontend
cmd/ # CLI entry points
├── controller/ # Kubernetes controller for ModelRegistry CRDs
├── csi/ # Container Storage Interface (storage-initializer)
internal/ # Core server implementation (NOT importable externally)
├── apiutils/ # API utility functions
├── converter/ # Type converters (generated via goverter)
│ └── generated/ # Auto-generated converter code
├── core/ # Business logic / domain services
├── datastore/ # Database layer
│ └── embedmd/ # Embedded migrations (MySQL & PostgreSQL)
├── db/ # Database service layer & query filtering
│ ├── filter/ # Query filter parser (participle-based)
│ └── service/ # DB-backed service implementations
├── defaults/ # Default value helpers
├── mapper/ # Request/response mappers
├── proxy/ # REST proxy logic
├── server/ # HTTP server setup
│ └── openapi/ # Generated OpenAPI server stubs
├── testutils/ # Shared test utilities
└── tls/ # TLS configuration
pkg/ # Public Go packages (importable by others)
├── api/ # Public API interfaces
├── openapi/ # Generated OpenAPI client for model-registry
└── inferenceservice-controller/ # InferenceService controller logic
jobs/ # Background jobs
└── async-upload/ # Async model upload job (Python, uses Poetry)
manifests/kustomize/ # Kubernetes deployment manifests (Kustomize)
scripts/ # Build and utility scripts
devenv/ # Local development environment (Tilt-based)
docs/ # Documentation (see docs/dev_kind_environment.md for Kind setup)
test/ # Integration/E2E test scripts
Commands
Setup
make deps # Install tool dependencies (golangci-lint, goverter, openapi-generator, envtest)
Building
make build # Full build: generate code, vet, lint, then compile
make build/compile # Compile only (skip generation/lint — useful after a clean build)
make build/csi # Build the CSI storage-initializer binary
make -C catalog build # Build catalog service (if applicable)
The build target runs gen (code generation), vet, and lint before compiling. If you only changed Go source and not OpenAPI specs or converters, make build/compile is faster.
Linting
make lint # Run golangci-lint on all Go code
make vet # Run go vet on all packages
golangci-lint v2.9.0 is used. There is no project-level .golangci.yml config file — the default golangci-lint configuration applies.
Testing
make test # Run all unit tests (internal/... and pkg/..., excludes controller)
make test-nocache # Run tests without cache
make test-cover # Run tests with coverage report (outputs coverage.html)
Controller tests
make controller/test # Run controller tests (requires envtest/kubebuilder assets)
Catalog tests
make -C catalog test # Run catalog unit tests
make -C catalog test-cover # Run catalog tests with coverage
Model Registry Python client tests
cd clients/python
make install # Generate OpenAPI client and install dependencies via Poetry
make test # Run unit tests (pytest)
make lint # Run ruff + mypy
E2E tests (fully automated — creates a KinD cluster, builds and deploys the server image, Minio, OCI registry, runs tests, then cleans up):
cd clients/python
make test-e2e # All-in-one: deploy infra + run E2E + cleanup
If you need to manage the environment manually:
cd clients/python
make deploy-latest-mr # Build image, create KinD cluster, deploy MR, start port-forward
make deploy-test-minio # Deploy Minio for storage tests
make deploy-local-registry # Deploy local OCI registry
make test-e2e-run # Run E2E tests only (infra must already be running)
make test-e2e-cleanup # Cleanup DB and stop port-forwards
Model Catalog Python client tests
cd catalog/clients/python
make install # Generate OpenAPI client and install dependencies via Poetry
make lint # Run ruff + mypy
E2E tests (two-step — deploy, then test):
cd catalog/clients/python
make deploy # All-in-one: KinD cluster + build image + deploy catalog + port-forward
make test-e2e # Run E2E tests (requires catalog already deployed)
make deploy-cleanup # Tear down KinD cluster and port-forwards
If you need finer control over deployment:
cd catalog/clients/python
make deploy-kind # Create KinD cluster
make deploy-build # Build Docker image
make deploy-load # Load image into KinD
make deploy-k8s # Deploy to existing cluster (namespace + kustomize)
make deploy-forward # Start port-forward to catalog service
make deploy-restart # Rebuild and redeploy catalog only (quick dev cycle)
Async upload job tests (Python)
cd jobs/async-upload
make install # Install Python dependencies via Poetry
make test # Run unit tests (pytest)
make test-e2e # Run E2E tests (requires KinD cluster)
Running a single Go test
go test ./internal/core/ -run TestSpecificFunction -v # Run a specific test
go test ./internal/db/service/ -count=1 # Run package tests without cache
Code Generation
make gen # Run all code generation (OpenAPI + converters)
make gen/openapi # Regenerate OpenAPI client (pkg/openapi/)
make gen/openapi-server # Regenerate OpenAPI server stubs (internal/server/openapi/)
make gen/converter # Regenerate type converters (internal/converter/generated/)
make gen/gorm # Regenerate GORM structs from DB schema (requires Docker)
After changing api/openapi/src/*.yaml, run:
make api/openapi/model-registry.yaml # Merge OpenAPI source files
make openapi/validate # Validate merged spec
make gen/openapi gen/openapi-server # Regenerate Go code from spec
Docker / Container Images
make image/build # Build the server container image
make compose/up # Start services with MySQL (pre-built images)
make compose/up/postgres # Start services with PostgreSQL
make compose/local/up # Start services built from source (MySQL)
make compose/local/up/postgres # Start services built from source (PostgreSQL)
make compose/down # Stop services
make compose/clean # Remove all volumes and networks
UI Development
# From clients/ui/
make dev-install-dependencies # Install all UI dependencies
make dev-start # Start BFF + frontend for standalone mode
# Or individually:
cd clients/ui/bff && go run ./cmd --port=4000 --dev-mode --deployment-mode=standalone
cd clients/ui/frontend && DEPLOYMENT_MODE=standalone STYLE_THEME=patternfly npm run start:dev
# UI tests
cd clients/ui/frontend && npm run test:unit
cd clients/ui/frontend && npm run test:type-check
For Kind-based UI development with Tilt, see docs/dev_kind_environment.md.
CI Checks (what runs on PRs)
The following checks run automatically on pull requests:
| Check | Workflow | What it does |
|---|---|---|
| Build + Unit Tests | build.yml |
make build/compile, make test-cover, catalog tests |
| Go Mod Tidy | go-mod-tidy-diff-check.yml |
Ensures go.mod / go.sum are tidy |
| Controller Tests | controller-test.yml |
make controller/test (triggered by controller path changes) |
| CSI Tests | csi-test.yml |
E2E tests on KinD cluster (triggered by CSI path changes) |
| Python Client Tests | python-tests.yml |
Lint, unit tests, E2E on KinD (model-registry + catalog Python clients) |
| Async Upload Tests | async-upload-test.yml |
Python pytest + E2E (triggered by jobs/async-upload/ changes) |
Before submitting a PR, at minimum run:
make build/compile && make test && make lint && make vet
Development Workflow for AI Agents
Before making changes
- Read existing code patterns in the file you're modifying and its neighbors
- Check if the file is auto-generated (look for
.openapi-generatormarkers orgenerateddirectories) — if so, modify the source/template instead - Run
make vetandmake lintto confirm a clean starting state
Validation before proposing changes
make vet # Go vet
make lint # Linter
make test # Unit tests
go mod tidy # Ensure module files are clean
Auto-generated files — do NOT edit directly
The following directories contain auto-generated code. Modify the sources and regenerate instead:
api/openapi/model-registry.yaml— merged output, do NOT edit. Edit source files inapi/openapi/src/model-registry.yamlandapi/openapi/src/lib/*.yaml, then runmake api/openapi/model-registry.yamlapi/openapi/catalog.yaml— merged output, do NOT edit. Edit source files inapi/openapi/src/catalog.yamlandapi/openapi/src/lib/*.yaml, then runmake api/openapi/catalog.yamlpkg/openapi/— generated from the mergedapi/openapi/model-registry.yamlviamake gen/openapicatalog/pkg/openapi/— generated from the mergedapi/openapi/catalog.yamlviamake -C catalog gen/openapiinternal/server/openapi/— generated from OpenAPI specs viamake gen/openapi-serverinternal/converter/generated/— generated from converter interfaces viamake gen/converter
Commit / PR hygiene
- Use DCO sign-off on all commits (
git commit -s) - Keep diffs minimal — only modify files relevant to the task
- Do not push secrets, credentials, or modify git config
- Run
go mod tidyif you changed dependencies - Keep commit messages brief
- Follow the Conventional Commit specification (e.g.
feat(catalog): <description>,fix: some bug)
Core Development Principles
Go conventions
- Follow standard Go conventions:
gofmt,go vet, effective Go patterns - Use
snake_casefor file names,PascalCasefor exported identifiers,camelCasefor unexported - Capitalize acronyms (prefer
parseIPtoparseIp) - Error handling: always check and return errors, no bare
_ignoring errors unless justified - Use the
stretchr/testifypackage for test assertions (already a project dependency) - Use Testcontainers for integration tests that need a real database
TypeScript/React conventions
- Follow existing component patterns in
clients/ui/frontend/src/ - Use PatternFly components for UI elements
- Prefer functional components with hooks
- Write unit tests for new components
Python conventions
- Follow existing patterns in
clients/python/andcatalog/clients/python/ - Use Poetry for dependency management
- Write tests with pytest
Testing requirements
- Bug fixes MUST include a test that reproduces the bug
- Unit tests live alongside source files as
*_test.go(Go),*.test.ts/*.test.tsx(TypeScript),*_test.py/test_*.py(Python) - Integration tests use Testcontainers (MySQL and PostgreSQL) — see
internal/db/service/*_test.gofor patterns - Controller tests use
envtest(kubebuilder test framework) — seecmd/controller/
Security checklist
- No
evalor equivalent dynamic code execution on user-controlled input - Proper error handling — no silently swallowed errors
- No secrets in code, logs, or test fixtures
- Ensure proper resource cleanup (database connections, HTTP clients)
Database changes
When modifying the database schema:
- Add migration files in
internal/datastore/embedmd/{mysql,postgres}/migrations/ - Regenerate GORM structs:
make gen/gorm - Test against both MySQL and PostgreSQL
OpenAPI changes
When modifying the REST API:
- Edit ONLY the source specs in
api/openapi/src/(e.g.,api/openapi/src/model-registry.yaml,api/openapi/src/lib/*.yaml). NEVER edit the merged output filesapi/openapi/model-registry.yamlorapi/openapi/catalog.yamldirectly — they are generated. - Merge sources into the final spec:
make api/openapi/model-registry.yaml(ormake api/openapi/catalog.yaml) - Validate:
make openapi/validate - Regenerate server and client code:
make gen/openapi gen/openapi-server - Update any affected handler logic in
internal/
Additional Resources
- CONTRIBUTING.md — DCO, code of conduct, ARM/Mac setup, Kind deployment
- clients/ui/CONTRIBUTING.md — UI-specific contribution guide
- docs/dev_kind_environment.md — Kind local dev environment setup and troubleshooting
- devenv/README.md — Tilt-based dev environment
- Model Registry documentation