Skip to content

Commit 06bdd44

Browse files
committed
feat: add ComponentGroup CRD (STONEINTG-1348)
Implements ComponentGroup CRD per STONEINTG-1302 design doc. - Add ComponentGroup types with Components, Dependents, TestGraph fields - Add GCL tracking(lastPromotedImage,lastPromotedCommit,lastBuildTime) - Add 8 unit tests (all passing) - Generate CRD manifest and DeepCopy methods - Add RBAC roles (admin, editor, viewer) - Update kustomization files Signed-off-by: Kasem Alem <kalem@redhat.com>
1 parent 4583feb commit 06bdd44

12 files changed

Lines changed: 1198 additions & 0 deletions
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
Copyright 2024 Red Hat Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1beta2
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
const (
24+
// ComponentGroupLabelPrefix contains the prefix applied to labels and annotations related to component groups.
25+
ComponentGroupLabelPrefix = "appstudio.openshift.io/component-group"
26+
27+
// ParentSnapshotAnnotation contains the name of the parent snapshot that triggered this snapshot creation
28+
ParentSnapshotAnnotation = TestLabelPrefix + "/parent-snapshot"
29+
30+
// OriginSnapshotAnnotation contains the name of the original snapshot that started the snapshot chain
31+
OriginSnapshotAnnotation = TestLabelPrefix + "/origin-snapshot"
32+
33+
// MissingComponentVersionsAnnotation contains a list of ComponentVersions that cannot be found
34+
MissingComponentVersionsAnnotation = TestLabelPrefix + "/missing-componentversions"
35+
)
36+
37+
// ComponentGroupSpec defines the desired state of ComponentGroup
38+
type ComponentGroupSpec struct {
39+
// Components is a list of Components (name and branch) that belong to the ComponentGroup.
40+
// This is the source of truth for logical groupings of versioned Components.
41+
// +required
42+
Components []ComponentReference `json:"components"`
43+
44+
// Dependents is a list of ComponentGroup names that are dependent on this ComponentGroup.
45+
// When a snapshot is created for this ComponentGroup, snapshots will also be created for all dependents.
46+
// +optional
47+
Dependents []string `json:"dependents,omitempty"`
48+
49+
// TestGraph describes the desired order in which tests associated with the ComponentGroup should be executed.
50+
// If not specified, all tests will run in parallel.
51+
// The map key is the test scenario name, and the value is a list of parent test scenarios it depends on.
52+
// +optional
53+
TestGraph map[string][]TestGraphNode `json:"testGraph,omitempty"`
54+
55+
// SnapshotCreator is an optional field that allows custom logic for Snapshot creation.
56+
// This field is reserved for future implementation and should not be used yet.
57+
// +optional
58+
SnapshotCreator *SnapshotCreatorSpec `json:"snapshotCreator,omitempty"`
59+
}
60+
61+
// ComponentReference references a Component and its specific branch/version
62+
type ComponentReference struct {
63+
// Name is the name of the Component
64+
// +kubebuilder:validation:Pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
65+
// +required
66+
Name string `json:"name"`
67+
68+
// ComponentBranch references the ComponentBranch for this Component.
69+
// The ComponentBranch CRD will be implemented by the build team as part of STONEBLD-3604.
70+
// For now, this contains the branch name and GCL (Global Candidate List) information.
71+
// +required
72+
ComponentBranch ComponentBranchReference `json:"componentBranch"`
73+
}
74+
75+
// ComponentBranchReference contains information about a Component's branch and its latest promoted image
76+
type ComponentBranchReference struct {
77+
// Name is the name of the ComponentBranch (typically the branch name like "main", "v1", etc.)
78+
// This will reference the ComponentBranch CRD once it's implemented.
79+
// +required
80+
Name string `json:"name"`
81+
82+
// LastPromotedImage is the latest "good" container image for this ComponentBranch.
83+
// This is part of the Global Candidate List (GCL) tracking.
84+
// Example: quay.io/sampleorg/first-component@sha256:1b29...
85+
// +optional
86+
LastPromotedImage string `json:"lastPromotedImage,omitempty"`
87+
88+
// LastPromotedCommit is the git commit SHA of the last promoted image.
89+
// Example: 6a7c81802e785aa869f82301afe61f4e9775772b
90+
// +optional
91+
LastPromotedCommit string `json:"lastPromotedCommit,omitempty"`
92+
93+
// LastBuildTime is the timestamp when the last build was completed.
94+
// Format: RFC3339 (e.g., "2025-08-13T12:00:00Z")
95+
// +optional
96+
LastBuildTime *metav1.Time `json:"lastBuildTime,omitempty"`
97+
}
98+
99+
// TestGraphNode represents a node in the test serialization graph
100+
type TestGraphNode struct {
101+
// Name is the name of the IntegrationTestScenario
102+
// +required
103+
Name string `json:"name"`
104+
105+
// OnFail defines how to behave if this IntegrationTestScenario fails.
106+
// Options: "run" (default) - continue running dependent tests, "skip" - skip dependent tests
107+
// +kubebuilder:validation:Enum=run;skip
108+
// +kubebuilder:default=run
109+
// +optional
110+
OnFail string `json:"onFail,omitempty"`
111+
}
112+
113+
// SnapshotCreatorSpec defines custom logic for creating snapshots.
114+
// This is reserved for future implementation and should not be used yet.
115+
type SnapshotCreatorSpec struct {
116+
// TaskRef references a Tekton Task that will create the Snapshot CR.
117+
// This field is reserved for future use.
118+
// +optional
119+
TaskRef *TaskRef `json:"taskRef,omitempty"`
120+
}
121+
122+
// TaskRef references a Tekton Task using a resolver
123+
type TaskRef struct {
124+
// Resolver is the name of the resolver (e.g., "git", "bundle")
125+
// +required
126+
Resolver string `json:"resolver"`
127+
128+
// Params contains the parameters used to identify the referenced Task
129+
// +required
130+
Params []ResolverParameter `json:"params"`
131+
}
132+
133+
// ComponentGroupStatus defines the observed state of ComponentGroup
134+
type ComponentGroupStatus struct {
135+
// Conditions is an array of the ComponentGroup's status conditions
136+
Conditions []metav1.Condition `json:"conditions"`
137+
}
138+
139+
// +kubebuilder:object:root=true
140+
// +kubebuilder:resource:shortName=cg
141+
// +kubebuilder:subresource:status
142+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
143+
// +kubebuilder:storageversion
144+
145+
// ComponentGroup is the Schema for the componentgroups API.
146+
// ComponentGroup serves as the replacement for the Application CR in the new application/component model.
147+
// It groups Components together for testing and releasing, supports test serialization,
148+
// ComponentGroup dependencies, and tracks the Global Candidate List (GCL) for each Component.
149+
type ComponentGroup struct {
150+
metav1.TypeMeta `json:",inline"`
151+
metav1.ObjectMeta `json:"metadata,omitempty"`
152+
153+
Spec ComponentGroupSpec `json:"spec,omitempty"`
154+
Status ComponentGroupStatus `json:"status,omitempty"`
155+
}
156+
157+
// +kubebuilder:object:root=true
158+
159+
// ComponentGroupList contains a list of ComponentGroups
160+
type ComponentGroupList struct {
161+
metav1.TypeMeta `json:",inline"`
162+
metav1.ListMeta `json:"metadata,omitempty"`
163+
Items []ComponentGroup `json:"items"`
164+
}
165+
166+
func init() {
167+
SchemeBuilder.Register(&ComponentGroup{}, &ComponentGroupList{})
168+
}

0 commit comments

Comments
 (0)