Skip to content

Commit

Permalink
feat(RELEASE-1053): add support for final pipeline
Browse files Browse the repository at this point in the history
Added support for the final pipeline to run immediately after all other pipelines in the tenant workspace.
The final pipeline now receives references to the same resources as the tenant pipeline, including the Release resource.
A release is marked as failed if the final pipeline fails.

Signed-off-by: Sean Conroy <[email protected]>
  • Loading branch information
seanconroy2021 committed Sep 30, 2024
1 parent 9d2ba52 commit 175eb87
Show file tree
Hide file tree
Showing 18 changed files with 1,151 additions and 412 deletions.
6 changes: 3 additions & 3 deletions api/v1alpha1/release_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package v1alpha1
import "github.com/konflux-ci/operator-toolkit/conditions"

const (
// finalProcessedConditionType is the type used to track the status of a Release Final Pipeline processing
finalProcessedConditionType conditions.ConditionType = "FinalPipelineProcessed"

// managedProcessedConditionType is the type used to track the status of a Release Managed Pipeline processing
managedProcessedConditionType conditions.ConditionType = "ManagedPipelineProcessed"

// postActionsExecutedConditionType is the type used to track the status of Release post-actions
postActionsExecutedConditionType conditions.ConditionType = "PostActionsExecuted"

// tenantProcessedConditionType is the type used to track the status of a Release Tenant Pipeline processing
tenantProcessedConditionType conditions.ConditionType = "TenantPipelineProcessed"

Expand Down
148 changes: 83 additions & 65 deletions api/v1alpha1/release_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ type ReleaseStatus struct {
// +optional
Conditions []metav1.Condition `json:"conditions"`

// ManagedProcessing contains information about the release managed processing
// FinalProcessing contains information about the release final processing
// +optional
ManagedProcessing PipelineInfo `json:"managedProcessing,omitempty"`
FinalProcessing PipelineInfo `json:"finalProcessing,omitempty"`

// PostActionsExecution contains information about the post-actions execution
// ManagedProcessing contains information about the release managed processing
// +optional
PostActionsExecution PipelineInfo `json:"postActionsExecution,omitempty"`
ManagedProcessing PipelineInfo `json:"managedProcessing,omitempty"`

// TenantProcessing contains information about the release tenant processing
// +optional
Expand Down Expand Up @@ -165,10 +165,9 @@ type Release struct {
Status ReleaseStatus `json:"status,omitempty"`
}

// HasEveryPostActionExecutionFinished checks whether the Release post-actions execution has finished,
// regardless of the result.
func (r *Release) HasEveryPostActionExecutionFinished() bool {
return r.hasPhaseFinished(postActionsExecutedConditionType)
// Has FinalPipelineProcessingFinished checks whether the Release Final Pipeline processing has finished, regardless of the result.
func (r *Release) HasFinalPipelineProcessingFinished() bool {
return r.hasPhaseFinished(finalProcessedConditionType)
}

// HasManagedPipelineProcessingFinished checks whether the Release Managed Pipeline processing has finished, regardless of the result.
Expand Down Expand Up @@ -196,14 +195,9 @@ func (r *Release) IsAutomated() bool {
return r.Status.Automated
}

// IsEveryPostActionExecuted checks whether the Release post-actions were successfully executed.
func (r *Release) IsEveryPostActionExecuted() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, postActionsExecutedConditionType.String())
}

// IsEachPostActionExecuting checks whether the Release post-actions are in progress.
func (r *Release) IsEachPostActionExecuting() bool {
return r.isPhaseProgressing(postActionsExecutedConditionType)
// IsFinalPipelineProcessed checks whether the Release Final Pipeline was successfully processed.
func (r *Release) IsFinalPipelineProcessed() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, finalProcessedConditionType.String())
}

// IsManagedPipelineProcessed checks whether the Release Managed Pipeline was successfully processed.
Expand All @@ -216,6 +210,11 @@ func (r *Release) IsTenantPipelineProcessed() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, tenantProcessedConditionType.String())
}

// IsFinalPipelineProcessing checks whether the Release Final Pipeline processing is in progress.
func (r *Release) IsFinalPipelineProcessing() bool {
return r.isPhaseProgressing(finalProcessedConditionType)
}

// IsManagedPipelineProcessing checks whether the Release Managed Pipeline processing is in progress.
func (r *Release) IsManagedPipelineProcessing() bool {
return r.isPhaseProgressing(managedProcessedConditionType)
Expand All @@ -241,6 +240,24 @@ func (r *Release) IsValid() bool {
return meta.IsStatusConditionTrue(r.Status.Conditions, validatedConditionType.String())
}

// MarkFinalPipelineProcessed marks the Release Final Pipeline as processed.
func (r *Release) MarkFinalPipelineProcessed() {
if !r.IsFinalPipelineProcessing() || r.HasFinalPipelineProcessingFinished() {
return
}

r.Status.FinalProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetCondition(&r.Status.Conditions, finalProcessedConditionType, metav1.ConditionTrue, SucceededReason)

go metrics.RegisterCompletedReleasePipelineProcessing(
r.Status.FinalProcessing.StartTime,
r.Status.FinalProcessing.CompletionTime,
SucceededReason.String(),
r.Status.Target,
metadata.FinalPipelineType,
)
}

// MarkManagedPipelineProcessed marks the Release Managed Pipeline as processed.
func (r *Release) MarkManagedPipelineProcessed() {
if !r.IsManagedPipelineProcessing() || r.HasManagedPipelineProcessingFinished() {
Expand Down Expand Up @@ -277,6 +294,27 @@ func (r *Release) MarkTenantPipelineProcessed() {
)
}

// MarkFinalPipelineProcessing marks the Release Final Pipeline as processing.
func (r *Release) MarkFinalPipelineProcessing() {
if r.HasFinalPipelineProcessingFinished() {
return
}

if !r.IsFinalPipelineProcessing() {
r.Status.FinalProcessing.StartTime = &metav1.Time{Time: time.Now()}
}

conditions.SetCondition(&r.Status.Conditions, finalProcessedConditionType, metav1.ConditionFalse, ProgressingReason)

go metrics.RegisterNewReleasePipelineProcessing(
r.Status.FinalProcessing.StartTime,
r.Status.StartTime,
ProgressingReason.String(),
r.Status.Target,
metadata.FinalPipelineType,
)
}

// MarkManagedPipelineProcessing marks the Release Managed Pipeline as processing.
func (r *Release) MarkManagedPipelineProcessing() {
if r.HasManagedPipelineProcessingFinished() {
Expand Down Expand Up @@ -319,6 +357,24 @@ func (r *Release) MarkTenantPipelineProcessing() {
)
}

// MarkFinalPipelineProcessingFailed marks the Release Final Pipeline processing as failed.
func (r *Release) MarkFinalPipelineProcessingFailed(message string) {
if !r.IsFinalPipelineProcessing() || r.HasFinalPipelineProcessingFinished() {
return
}

r.Status.FinalProcessing.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetConditionWithMessage(&r.Status.Conditions, finalProcessedConditionType, metav1.ConditionFalse, FailedReason, message)

go metrics.RegisterCompletedReleasePipelineProcessing(
r.Status.FinalProcessing.StartTime,
r.Status.FinalProcessing.CompletionTime,
FailedReason.String(),
r.Status.Target,
metadata.FinalPipelineType,
)
}

// MarkManagedPipelineProcessingFailed marks the Release Managed Pipeline processing as failed.
func (r *Release) MarkManagedPipelineProcessingFailed(message string) {
if !r.IsManagedPipelineProcessing() || r.HasManagedPipelineProcessingFinished() {
Expand Down Expand Up @@ -355,6 +411,15 @@ func (r *Release) MarkTenantPipelineProcessingFailed(message string) {
)
}

// MarkFinalPipelineProcessingSkipped marks the Release Final Pipeline processing as skipped.
func (r *Release) MarkFinalPipelineProcessingSkipped() {
if r.HasFinalPipelineProcessingFinished() {
return
}

conditions.SetCondition(&r.Status.Conditions, finalProcessedConditionType, metav1.ConditionTrue, SkippedReason)
}

// MarkManagedPipelineProcessingSkipped marks the Release Managed Pipeline processing as skipped.
func (r *Release) MarkManagedPipelineProcessingSkipped() {
if r.HasManagedPipelineProcessingFinished() {
Expand All @@ -373,53 +438,6 @@ func (r *Release) MarkTenantPipelineProcessingSkipped() {
conditions.SetCondition(&r.Status.Conditions, tenantProcessedConditionType, metav1.ConditionTrue, SkippedReason)
}

// MarkPostActionsExecuted marks the Release post-actions as executed.
func (r *Release) MarkPostActionsExecuted() {
if !r.IsEachPostActionExecuting() || r.HasEveryPostActionExecutionFinished() {
return
}

r.Status.PostActionsExecution.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetCondition(&r.Status.Conditions, postActionsExecutedConditionType, metav1.ConditionTrue, SucceededReason)

go metrics.RegisterCompletedReleasePostActionsExecuted(
r.Status.PostActionsExecution.StartTime,
r.Status.PostActionsExecution.CompletionTime,
SucceededReason.String(),
)
}

// MarkPostActionsExecuting marks the Release post-actions as executing.
func (r *Release) MarkPostActionsExecuting(message string) {
if r.HasEveryPostActionExecutionFinished() {
return
}

if !r.IsEachPostActionExecuting() {
r.Status.PostActionsExecution.StartTime = &metav1.Time{Time: time.Now()}
}

conditions.SetConditionWithMessage(&r.Status.Conditions, postActionsExecutedConditionType, metav1.ConditionFalse, ProgressingReason, message)

go metrics.RegisterNewReleasePostActionsExecution()
}

// MarkPostActionsExecutionFailed marks the Release post-actions execution as failed.
func (r *Release) MarkPostActionsExecutionFailed(message string) {
if !r.IsEachPostActionExecuting() || r.HasEveryPostActionExecutionFinished() {
return
}

r.Status.PostActionsExecution.CompletionTime = &metav1.Time{Time: time.Now()}
conditions.SetConditionWithMessage(&r.Status.Conditions, postActionsExecutedConditionType, metav1.ConditionFalse, FailedReason, message)

go metrics.RegisterCompletedReleasePostActionsExecuted(
r.Status.PostActionsExecution.StartTime,
r.Status.PostActionsExecution.CompletionTime,
FailedReason.String(),
)
}

// MarkReleased marks the Release as released.
func (r *Release) MarkReleased() {
if !r.IsReleasing() || r.HasReleaseFinished() {
Expand All @@ -433,10 +451,10 @@ func (r *Release) MarkReleased() {
r.Status.StartTime,
r.Status.CompletionTime,
r.getPhaseReason(managedProcessedConditionType),
r.getPhaseReason(postActionsExecutedConditionType),
SucceededReason.String(),
r.Status.Target,
r.getPhaseReason(tenantProcessedConditionType),
r.getPhaseReason(finalProcessedConditionType),
r.getPhaseReason(validatedConditionType),
)
}
Expand Down Expand Up @@ -468,9 +486,9 @@ func (r *Release) MarkReleaseFailed(message string) {
go metrics.RegisterCompletedRelease(
r.Status.StartTime,
r.Status.CompletionTime,
r.getPhaseReason(postActionsExecutedConditionType),
r.getPhaseReason(tenantProcessedConditionType),
r.getPhaseReason(managedProcessedConditionType),
r.getPhaseReason(finalProcessedConditionType),
FailedReason.String(),
r.Status.Target,
r.getPhaseReason(validatedConditionType),
Expand Down
Loading

0 comments on commit 175eb87

Please sign in to comment.