-
Notifications
You must be signed in to change notification settings - Fork 113
fix: Annotate PLR when when started status is reported #2208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -176,14 +176,10 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi | |||
p.logger.Errorf("Error adding labels/annotations to PipelineRun '%s' in namespace '%s': %v", match.PipelineRun.GetName(), match.Repo.GetNamespace(), err) | ||||
} | ||||
|
||||
// if concurrency is defined then start the pipelineRun in pending state and | ||||
// state as queued | ||||
// if concurrency is defined then start the pipelineRun in pending state | ||||
if match.Repo.Spec.ConcurrencyLimit != nil && *match.Repo.Spec.ConcurrencyLimit != 0 { | ||||
// pending status | ||||
match.PipelineRun.Spec.Status = tektonv1.PipelineRunSpecStatusPending | ||||
// pac state as queued | ||||
match.PipelineRun.Labels[keys.State] = kubeinteraction.StateQueued | ||||
match.PipelineRun.Annotations[keys.State] = kubeinteraction.StateQueued | ||||
} | ||||
|
||||
// Create the actual pipelineRun | ||||
|
@@ -240,23 +236,31 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi | |||
OriginalPipelineRunName: pr.GetAnnotations()[keys.OriginalPRName], | ||||
} | ||||
|
||||
// Patch the pipelineRun with the appropriate annotations and labels. | ||||
// Set the state so the watcher will continue with reconciling the pipelineRun | ||||
// The watcher reconciles only pipelineRuns that has the state annotation. | ||||
patchAnnotations := map[string]string{} | ||||
patchLabels := map[string]string{} | ||||
whatPatching := "" | ||||
// if pipelineRun is in pending state then report status as queued | ||||
// The pipelineRun can be pending because of PAC's concurrency limit or because of an external mutatingwebhook | ||||
if pr.Spec.Status == tektonv1.PipelineRunSpecStatusPending { | ||||
status.Status = queuedStatus | ||||
if status.Text, err = mt.MakeTemplate(p.vcx.GetTemplate(provider.QueueingPipelineType)); err != nil { | ||||
return nil, fmt.Errorf("cannot create message template: %w", err) | ||||
} | ||||
// If the PipelineRun is in the "queued" state, add the appropriate label and annotation. | ||||
// These are later used by the watcher to determine whether the PipelineRun status | ||||
// should be reported back to the Git provider. We do add the `state` annotations and label when | ||||
// concurrency is enabled but this would happen when PipelineRun's status has been changed by | ||||
// the other controller and PaC is not aware of that change. | ||||
whatPatching = "annotations.state and labels.state" | ||||
patchAnnotations[keys.State] = kubeinteraction.StateQueued | ||||
patchLabels[keys.State] = kubeinteraction.StateQueued | ||||
} else { | ||||
// Mark that the start will be reported to the Git provider | ||||
patchAnnotations[keys.SCMReportingPLRStarted] = "true" | ||||
patchAnnotations[keys.State] = kubeinteraction.StateStarted | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to set the state here? I see it is otherwise the reconciler setting the state label and annotation. I understand why the SCMReportingPLRStarted was added here, but why change the existing behavior by also setting state here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the plr isn't getting created with the state anymore, it should be set here as well to support plrs which are not pending. The reconciler won't reconcile plrs without the state annotation
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I see. |
||||
patchLabels[keys.State] = kubeinteraction.StateStarted | ||||
whatPatching = fmt.Sprintf( | ||||
"annotation.%s and annotations.state and labels.state", | ||||
keys.SCMReportingPLRStarted, | ||||
) | ||||
} | ||||
|
||||
if err := p.vcx.CreateStatus(ctx, p.event, status); err != nil { | ||||
|
@@ -278,6 +282,20 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi | |||
// unneeded SIGSEGV's | ||||
return pr, fmt.Errorf("cannot patch pipelinerun %s: %w", pr.GetGenerateName(), err) | ||||
} | ||||
currentReason := "" | ||||
if len(pr.Status.GetConditions()) > 0 { | ||||
currentReason = pr.Status.GetConditions()[0].GetReason() | ||||
} | ||||
|
||||
p.logger.Infof("PipelineRun %s/%s patched successfully - Spec.Status: %s, State annotation: '%s', SCMReportingPLRStarted annotation: '%s', Status reason: '%s', Git provider status: '%s', Patched: %s", | ||||
pr.GetNamespace(), | ||||
pr.GetName(), | ||||
pr.Spec.Status, | ||||
pr.GetAnnotations()[keys.State], | ||||
pr.GetAnnotations()[keys.SCMReportingPLRStarted], | ||||
currentReason, | ||||
status.Status, | ||||
whatPatching) | ||||
} | ||||
|
||||
return pr, nil | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,20 @@ var ( | |
func (r *Reconciler) ReconcileKind(ctx context.Context, pr *tektonv1.PipelineRun) pkgreconciler.Event { | ||
ctx = info.StoreNS(ctx, system.Namespace()) | ||
logger := logging.FromContext(ctx).With("namespace", pr.GetNamespace()) | ||
|
||
logger.Debugf("reconciling pipelineRun %s/%s", pr.GetNamespace(), pr.GetName()) | ||
|
||
// make sure we have the latest pipelinerun to reconcile, since there is something updating at the same time | ||
lpr, err := r.run.Clients.Tekton.TektonV1().PipelineRuns(pr.GetNamespace()).Get(ctx, pr.GetName(), metav1.GetOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("cannot get pipelineRun: %w", err) | ||
} | ||
|
||
if lpr.GetResourceVersion() != pr.GetResourceVersion() { | ||
logger.Debugf("Skipping reconciliation, pipelineRun was updated (cached version %s vs fresh version %s)", pr.GetResourceVersion(), lpr.GetResourceVersion()) | ||
return nil | ||
} | ||
|
||
// if pipelineRun is in completed or failed state then return | ||
state, exist := pr.GetAnnotations()[keys.State] | ||
if exist && (state == kubeinteraction.StateCompleted || state == kubeinteraction.StateFailed) { | ||
|
@@ -69,14 +83,20 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, pr *tektonv1.PipelineRun | |
// another controller outside PaC). To maintain consistency between the PipelineRun | ||
// status and the Git provider status, we update both the PipelineRun resource and | ||
// the corresponding status on the Git provider here. | ||
if reason == string(tektonv1.PipelineRunReasonRunning) && state == kubeinteraction.StateQueued { | ||
scmReportingPLRStarted, exist := pr.GetAnnotations()[keys.SCMReportingPLRStarted] | ||
startReported := exist && scmReportingPLRStarted == "true" | ||
logger.Debugf("pipelineRun %s/%s scmReportingPLRStarted=%v, exist=%v", pr.GetNamespace(), pr.GetName(), startReported, exist) | ||
|
||
if reason == string(tektonv1.PipelineRunReasonRunning) && !startReported { | ||
logger.Infof("pipelineRun %s/%s is running but not yet reported to provider, updating status", pr.GetNamespace(), pr.GetName()) | ||
repoName := pr.GetAnnotations()[keys.Repository] | ||
repo, err := r.repoLister.Repositories(pr.Namespace).Get(repoName) | ||
if err != nil { | ||
return fmt.Errorf("failed to get repository CR: %w", err) | ||
} | ||
return r.updatePipelineRunToInProgress(ctx, logger, repo, pr) | ||
} | ||
logger.Debugf("pipelineRun %s/%s condition not met: reason='%s', startReported=%v", pr.GetNamespace(), pr.GetName(), reason, startReported) | ||
|
||
// if its a GitHub App pipelineRun PR then process only if check run id is added otherwise wait | ||
if _, ok := pr.Annotations[keys.InstallationID]; ok { | ||
|
@@ -95,16 +115,6 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, pr *tektonv1.PipelineRun | |
return nil | ||
} | ||
|
||
// make sure we have the latest pipelinerun to reconcile, since there is something updating at the same time | ||
lpr, err := r.run.Clients.Tekton.TektonV1().PipelineRuns(pr.GetNamespace()).Get(ctx, pr.GetName(), metav1.GetOptions{}) | ||
if err != nil { | ||
return fmt.Errorf("cannot get pipelineRun: %w", err) | ||
} | ||
|
||
if lpr.GetResourceVersion() != pr.GetResourceVersion() { | ||
return nil | ||
} | ||
|
||
// If we have a controllerInfo annotation, then we need to get the | ||
// configmap configuration for it | ||
// | ||
|
@@ -343,16 +353,24 @@ func (r *Reconciler) updatePipelineRunToInProgress(ctx context.Context, logger * | |
} | ||
|
||
func (r *Reconciler) updatePipelineRunState(ctx context.Context, logger *zap.SugaredLogger, pr *tektonv1.PipelineRun, state string) (*tektonv1.PipelineRun, error) { | ||
currentState := pr.GetAnnotations()[keys.State] | ||
logger.Infof("updating pipelineRun %v/%v state from %s to %s", pr.GetNamespace(), pr.GetName(), currentState, state) | ||
annotations := map[string]string{ | ||
keys.State: state, | ||
} | ||
if state == kubeinteraction.StateStarted { | ||
annotations[keys.SCMReportingPLRStarted] = "true" | ||
} | ||
Comment on lines
+356
to
+363
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of setting the Consider setting the annotation like this: annotations[keys.SCMReportingPLRStarted] = "true" annotations[keys.SCMReportingPLRStarted] = "true" |
||
|
||
mergePatch := map[string]any{ | ||
"metadata": map[string]any{ | ||
"labels": map[string]string{ | ||
keys.State: state, | ||
}, | ||
"annotations": map[string]string{ | ||
keys.State: state, | ||
}, | ||
"annotations": annotations, | ||
}, | ||
} | ||
|
||
// if state is started then remove pipelineRun pending status | ||
if state == kubeinteraction.StateStarted { | ||
mergePatch["spec"] = map[string]any{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gbenhaim shouldn't this be on line no 63 above? grouped with other annotation keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done