Skip to content

Commit 4962b63

Browse files
committed
feat: Added RequiredStatusCheckCommitStatus to surfaced checks enforced by branch protection
Signed-off-by: Alexei Tenitski <[email protected]>
1 parent 1114adc commit 4962b63

16 files changed

+2256
-0
lines changed

api/v1alpha1/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ const ChangeTransferPolicyLabel = "promoter.argoproj.io/change-transfer-policy"
1919
// TimedCommitStatusLabel the timed commit status which the commit status is associated with.
2020
const TimedCommitStatusLabel = "promoter.argoproj.io/timed-commit-status"
2121

22+
// RequiredStatusCheckCommitStatusLabel identifies required status check commit statuses
23+
const RequiredStatusCheckCommitStatusLabel = "promoter.argoproj.io/required-status-check-commit-status"
24+
2225
// PreviousEnvironmentCommitStatusKey the commit status key name used to indicate the previous environment health
2326
const PreviousEnvironmentCommitStatusKey = "promoter-previous-environment"
2427

api/v1alpha1/controllerconfiguration_types.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ type ControllerConfigurationSpec struct {
6464
// including WorkQueue settings that control reconciliation behavior.
6565
// +required
6666
GitCommitStatus GitCommitStatusConfiguration `json:"gitCommitStatus"`
67+
68+
// RequiredStatusCheckCommitStatus contains the configuration for the RequiredStatusCheckCommitStatus controller,
69+
// including WorkQueue settings that control reconciliation behavior.
70+
// +required
71+
RequiredStatusCheckCommitStatus RequiredStatusCheckCommitStatusConfiguration `json:"requiredStatusCheckCommitStatus"`
6772
}
6873

6974
// PromotionStrategyConfiguration defines the configuration for the PromotionStrategy controller.
@@ -156,6 +161,17 @@ type GitCommitStatusConfiguration struct {
156161
WorkQueue WorkQueue `json:"workQueue"`
157162
}
158163

164+
// RequiredStatusCheckCommitStatusConfiguration defines the configuration for the RequiredStatusCheckCommitStatus controller.
165+
//
166+
// This configuration controls how the RequiredStatusCheckCommitStatus controller processes reconciliation
167+
// requests, including requeue intervals, concurrency limits, and rate limiting behavior.
168+
type RequiredStatusCheckCommitStatusConfiguration struct {
169+
// WorkQueue contains the work queue configuration for the RequiredStatusCheckCommitStatus controller.
170+
// This includes requeue duration, maximum concurrent reconciles, and rate limiter settings.
171+
// +required
172+
WorkQueue WorkQueue `json:"workQueue"`
173+
}
174+
159175
// WorkQueue defines the work queue configuration for a controller.
160176
//
161177
// This configuration directly correlates to parameters used with Kubernetes client-go work queues.

api/v1alpha1/promotionstrategy_types.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ type PromotionStrategySpec struct {
5353
// +listMapKey=key
5454
ProposedCommitStatuses []CommitStatusSelector `json:"proposedCommitStatuses"`
5555

56+
// ShowRequiredStatusChecks enables automatic discovery and visibility of GitHub required
57+
// status checks. When enabled, the controller queries GitHub Rulesets API to discover
58+
// required checks and creates CommitStatus resources for each, providing visibility into
59+
// what checks are blocking PR merges. This keeps the PromotionStrategy in "progressing"
60+
// state while waiting on checks, rather than "degraded" from failed merge attempts.
61+
// Defaults to false.
62+
// +kubebuilder:validation:Optional
63+
ShowRequiredStatusChecks *bool `json:"showRequiredStatusChecks,omitempty"`
64+
5665
// Environments is the sequence of environments that a dry commit will be promoted through.
5766
// +kubebuilder:validation:MinItems:=1
5867
// +listType:=map
@@ -89,6 +98,13 @@ type Environment struct {
8998
// +listType:=map
9099
// +listMapKey=key
91100
ProposedCommitStatuses []CommitStatusSelector `json:"proposedCommitStatuses"`
101+
102+
// ExcludedRequiredStatusChecks lists GitHub check contexts to exclude from
103+
// visibility when showRequiredStatusChecks is enabled. These checks will still
104+
// be enforced by GitHub, but won't be surfaced as CommitStatus resources.
105+
// Example: ["ci-tests", "security-scan"]
106+
// +kubebuilder:validation:Optional
107+
ExcludedRequiredStatusChecks []string `json:"excludedRequiredStatusChecks,omitempty"`
92108
}
93109

94110
// GetAutoMerge returns the value of the AutoMerge field, defaulting to true if the field is nil.
@@ -128,6 +144,14 @@ func (ps *PromotionStrategy) GetConditions() *[]metav1.Condition {
128144
return &ps.Status.Conditions
129145
}
130146

147+
// GetShowRequiredStatusChecks returns the value of the ShowRequiredStatusChecks field, defaulting to false if the field is nil.
148+
func (ps *PromotionStrategy) GetShowRequiredStatusChecks() bool {
149+
if ps.Spec.ShowRequiredStatusChecks == nil {
150+
return false
151+
}
152+
return *ps.Spec.ShowRequiredStatusChecks
153+
}
154+
131155
// EnvironmentStatus defines the observed state of an environment in a PromotionStrategy.
132156
type EnvironmentStatus struct {
133157
// Branch is the name of the active branch for the environment.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
Copyright 2024.
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 v1alpha1
18+
19+
import (
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
// RequiredStatusCheckCommitStatusSpec defines the desired state of RequiredStatusCheckCommitStatus
24+
type RequiredStatusCheckCommitStatusSpec struct {
25+
// PromotionStrategyRef references the PromotionStrategy that owns this controller
26+
// +required
27+
PromotionStrategyRef ObjectReference `json:"promotionStrategyRef"`
28+
}
29+
30+
// RequiredStatusCheckCommitStatusStatus defines the observed state of RequiredStatusCheckCommitStatus
31+
type RequiredStatusCheckCommitStatusStatus struct {
32+
// Environments contains status for each environment's branch protection checks
33+
// +listType=map
34+
// +listMapKey=branch
35+
// +optional
36+
Environments []RequiredStatusCheckEnvironmentStatus `json:"environments,omitempty"`
37+
38+
// Conditions represent the latest available observations of the resource's state
39+
// +listType=map
40+
// +listMapKey=type
41+
// +optional
42+
Conditions []metav1.Condition `json:"conditions,omitempty"`
43+
}
44+
45+
// RequiredStatusCheckEnvironmentStatus defines the observed required check status for a specific environment.
46+
type RequiredStatusCheckEnvironmentStatus struct {
47+
// Branch is the target branch being monitored
48+
// +required
49+
Branch string `json:"branch"`
50+
51+
// Sha is the commit SHA being checked
52+
// +required
53+
Sha string `json:"sha"`
54+
55+
// RequiredChecks lists all required checks discovered from GitHub Rulesets
56+
// +listType=map
57+
// +listMapKey=context
58+
// +optional
59+
RequiredChecks []RequiredCheckStatus `json:"requiredChecks,omitempty"`
60+
61+
// Phase is the aggregated phase of all required checks
62+
// +kubebuilder:validation:Enum=pending;success;failure
63+
// +required
64+
Phase CommitStatusPhase `json:"phase"`
65+
}
66+
67+
// RequiredCheckStatus defines the status of a single required check.
68+
type RequiredCheckStatus struct {
69+
// Context is the GitHub check context name
70+
// +required
71+
Context string `json:"context"`
72+
73+
// Phase is the current phase of this check
74+
// +kubebuilder:validation:Enum=pending;success;failure
75+
// +required
76+
Phase CommitStatusPhase `json:"phase"`
77+
78+
// CommitStatusName is the name of the CommitStatus resource created for this check
79+
// +optional
80+
CommitStatusName string `json:"commitStatusName,omitempty"`
81+
}
82+
83+
// +kubebuilder:object:root=true
84+
// +kubebuilder:subresource:status
85+
86+
// RequiredStatusCheckCommitStatus is the Schema for the requiredstatuscheckcommitstatuses API
87+
// +kubebuilder:printcolumn:name="PromotionStrategy",type=string,JSONPath=`.spec.promotionStrategyRef.name`
88+
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
89+
type RequiredStatusCheckCommitStatus struct {
90+
metav1.TypeMeta `json:",inline"`
91+
92+
// metadata is a standard object metadata
93+
// +optional
94+
metav1.ObjectMeta `json:"metadata,omitempty"`
95+
96+
// spec defines the desired state of RequiredStatusCheckCommitStatus
97+
// +required
98+
Spec RequiredStatusCheckCommitStatusSpec `json:"spec"`
99+
100+
// status defines the observed state of RequiredStatusCheckCommitStatus
101+
// +optional
102+
Status RequiredStatusCheckCommitStatusStatus `json:"status,omitempty"`
103+
}
104+
105+
// +kubebuilder:object:root=true
106+
107+
// RequiredStatusCheckCommitStatusList contains a list of RequiredStatusCheckCommitStatus
108+
type RequiredStatusCheckCommitStatusList struct {
109+
metav1.TypeMeta `json:",inline"`
110+
metav1.ListMeta `json:"metadata,omitempty"`
111+
Items []RequiredStatusCheckCommitStatus `json:"items"`
112+
}
113+
114+
// GetConditions returns the conditions of the RequiredStatusCheckCommitStatus.
115+
func (rsccs *RequiredStatusCheckCommitStatus) GetConditions() *[]metav1.Condition {
116+
return &rsccs.Status.Conditions
117+
}
118+
119+
func init() {
120+
SchemeBuilder.Register(&RequiredStatusCheckCommitStatus{}, &RequiredStatusCheckCommitStatusList{})
121+
}

0 commit comments

Comments
 (0)