Skip to content

feat: add ModelArtifact CRD and related API definitions - #24

Merged
iasthc merged 1 commit into
mainfrom
model-artifact
Feb 28, 2026
Merged

feat: add ModelArtifact CRD and related API definitions#24
iasthc merged 1 commit into
mainfrom
model-artifact

Conversation

@iasthc

@iasthc iasthc commented Feb 28, 2026

Copy link
Copy Markdown
Member
  • Introduced the ModelArtifact Custom Resource Definition (CRD) to manage model artifacts.
  • Added API schema definitions for ModelArtifact, including specifications for source, target, format, and storage.
  • Updated kustomization.yaml to include the new ModelArtifact CRD resource.
  • Implemented deepcopy functions for the new API types to ensure compatibility.

- Introduced the ModelArtifact Custom Resource Definition (CRD) to manage model artifacts.
- Added API schema definitions for ModelArtifact, including specifications for source, target, format, and storage.
- Updated kustomization.yaml to include the new ModelArtifact CRD resource.
- Implemented deepcopy functions for the new API types to ensure compatibility.
Copilot AI review requested due to automatic review settings February 28, 2026 13:25
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new ModelArtifact Custom Resource Definition (CRD) and its associated API definitions, enabling Kubernetes users to declare and manage the lifecycle of machine learning model artifacts. It streamlines the process of importing models from sources like HuggingFace, packaging them into OCI-compliant formats, and pushing them to OCI registries, thereby automating the model artifact pipeline within a Kubernetes environment.

Highlights

  • New ModelArtifact CRD: Introduced the ModelArtifact Custom Resource Definition (CRD) to manage model artifacts within Kubernetes, enabling declarative management of model lifecycle.
  • API Schema Definitions: Defined comprehensive API schemas for ModelArtifact, including specifications for model source (e.g., HuggingFace), OCI target registry, packaging format (ModelPack/ModelKit), and temporary storage.
  • Kustomization Update: Updated the Kustomization configuration to include the newly added ModelArtifact CRD, making it discoverable and deployable.
  • Deepcopy Functions: Implemented autogenerated deepcopy functions for the new ModelArtifact API types to ensure proper Kubernetes object handling and immutability.
Changelog
  • config/crd/bases/model.otterscale.io_modelartifacts.yaml
    • Added the full CustomResourceDefinition (CRD) manifest for ModelArtifact, detailing its schema, versions, and additional printer columns.
  • config/crd/kustomization.yaml
    • Added a new resource entry to include the modelartifacts.model.otterscale.io CRD.
  • model/v1alpha1/groupversion_info.go
    • Added the v1alpha1 API group version information for model.otterscale.io, including ModelArtifact and ModelArtifactList types.
  • model/v1alpha1/modelartifact_types.go
    • Defined the Go types for ModelArtifactSpec, ModelArtifactStatus, ModelSource, OCITarget, StorageSpec, SecretReference, SecretKeySelector, and ResourceReference, along with their respective fields and validation rules.
  • model/v1alpha1/zz_generated.deepcopy.go
    • Added autogenerated DeepCopyInto and DeepCopy methods for all new ModelArtifact related types, ensuring proper handling of Kubernetes objects.
Activity
  • No specific activity (comments, reviews, progress updates) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@iasthc
iasthc merged commit 68d9d14 into main Feb 28, 2026
7 checks passed
@iasthc
iasthc deleted the model-artifact branch February 28, 2026 13:26

Copilot AI 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.

Pull request overview

This PR introduces a new model.otterscale.io/v1alpha1 API group with a ModelArtifact CustomResourceDefinition to represent importing a model from a source, packaging it as an OCI artifact, and pushing it to a registry.

Changes:

  • Added ModelArtifact API types (spec/status) and group registration for model.otterscale.io/v1alpha1.
  • Generated deepcopy implementations for the new API types.
  • Added the generated ModelArtifact CRD to the CRD kustomization resources.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
model/v1alpha1/modelartifact_types.go Defines the ModelArtifact CRD Go types (spec/status, source/target/storage structs, enums).
model/v1alpha1/groupversion_info.go Registers ModelArtifact and ModelArtifactList with the scheme for the new API group.
model/v1alpha1/zz_generated.deepcopy.go Controller-gen generated deepcopy methods for the new types.
config/crd/bases/model.otterscale.io_modelartifacts.yaml Generated CRD manifest for ModelArtifact including schema and printer columns.
config/crd/kustomization.yaml Includes the new CRD base in the CRD kustomization.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Name string `json:"name"`

// Key is the key within the Secret data. If omitted, defaults to "token".
// +optional

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

The key field comment says it defaults to "token", but the CRD does not specify a default and there is no defaulting webhook. This makes the API documentation inaccurate and forces every user to set the key explicitly. Consider adding +kubebuilder:default=token or updating the comment and handling empty string in the controller.

Suggested change
// +optional
// +optional
// +kubebuilder:default=token

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +82
// ModelSource defines the origin of the model to be packaged.
// Exactly one source type must be specified.
// +kubebuilder:validation:XValidation:rule="has(self.huggingFace)",message="at least one source must be specified"
type ModelSource struct {
// HuggingFace specifies a HuggingFace Hub repository as the model source.
// +optional
HuggingFace *HuggingFaceSource `json:"huggingFace,omitempty"`
}

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

ModelSource is documented as "Exactly one source type must be specified", but the current validation rule/message only enforces that huggingFace is present ("at least one source"). Please align the docs and validation (e.g., change the comment to "At least one source must be specified" for now, or implement an XOR-style validation if/when multiple sources are supported).

Copilot uses AI. Check for mistakes.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Phase is the high-level summary of the artifact lifecycle.
// +optional

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

status.phase is typed as ArtifactPhase, but the generated CRD schema does not restrict it to the allowed values (Pending/Running/Succeeded/Failed). If clients can set arbitrary strings, it weakens the contract and makes kubectl output/UX less predictable. Add a +kubebuilder:validation:Enum=Pending;Running;Succeeded;Failed marker on the Phase field (or equivalent) so the CRD enforces the enum.

Suggested change
// +optional
// +optional
// +kubebuilder:validation:Enum=Pending;Running;Succeeded;Failed

Copilot uses AI. Check for mistakes.
Repository string `json:"repository"`

// Tag is the image tag to push. Defaults to "latest" if not specified.
// +kubebuilder:validation:MaxLength=128

Copilot AI Feb 28, 2026

Copy link

Choose a reason for hiding this comment

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

The tag field comment states it defaults to "latest", but there is no CRD default (no +kubebuilder:default=latest) and no defaulting webhook in the repo. As-is, omitting spec.target.tag results in an empty string, which contradicts the API docs and may break consumers expecting "latest". Either add a kubebuilder default for this field or update the comment and ensure the controller handles the empty-string case explicitly.

Suggested change
// +kubebuilder:validation:MaxLength=128
// +kubebuilder:validation:MaxLength=128
// +kubebuilder:default=latest

Copilot uses AI. Check for mistakes.

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces a new ModelArtifact Custom Resource Definition (CRD) and its associated API types. The changes are well-structured and include the CRD YAML, Go type definitions, and updates to the build configuration. My review found a minor but important issue in the Go type definitions where an incorrect JSON tag omitzero was used instead of omitempty. This could lead to incorrect JSON serialization. I have provided suggestions to correct this. With these changes, the PR will be in great shape.


// Standard object's metadata.
// +optional
metav1.ObjectMeta `json:"metadata,omitzero"`

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.

high

The JSON tag omitzero is not a valid option in Go's encoding/json package. This should be omitempty to ensure that this field is omitted from the JSON output when it is empty. Using an incorrect tag can lead to unexpected serialization behavior.

Suggested change
metav1.ObjectMeta `json:"metadata,omitzero"`
metav1.ObjectMeta `json:"metadata,omitempty"`


// Status represents the current state of the model artifact pipeline.
// +optional
Status ModelArtifactStatus `json:"status,omitzero"`

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.

high

The JSON tag omitzero is not a valid option. It should be omitempty.

Suggested change
Status ModelArtifactStatus `json:"status,omitzero"`
Status ModelArtifactStatus `json:"status,omitempty"`

// ModelArtifactList contains a list of ModelArtifact resources.
type ModelArtifactList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitzero"`

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.

high

The JSON tag omitzero is not a valid option. It should be omitempty.

Suggested change
metav1.ListMeta `json:"metadata,omitzero"`
metav1.ListMeta `json:"metadata,omitempty"`

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants