Skip to content

Fix: Freight should manage its own discoveryTimestamp, not rely on cr…#6133

Open
2003Aditya wants to merge 1 commit intoakuity:mainfrom
2003Aditya:add-discovery-timestamp
Open

Fix: Freight should manage its own discoveryTimestamp, not rely on cr…#6133
2003Aditya wants to merge 1 commit intoakuity:mainfrom
2003Aditya:add-discovery-timestamp

Conversation

@2003Aditya
Copy link
Copy Markdown

…eationTimestamp akuity#5855

Signed-off-by: Aditya Mishra <mishraaditya675@gmail.com>
@2003Aditya 2003Aditya requested a review from a team as a code owner April 21, 2026 02:21
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 21, 2026

Deploy Preview for docs-kargo-io ready!

Name Link
🔨 Latest commit 5d8d499
🔍 Latest deploy log https://app.netlify.com/projects/docs-kargo-io/deploys/69e6df46e0bc3f0008b7b776
😎 Deploy Preview https://deploy-preview-6133.docs.kargo.io
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

// DiscoveryTimestamp is the time at which the Freight was first discovered
// from its source. This is distinct from metadata.creationTimestamp, which is
// set by Kubernetes and cannot be controlled by users.
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty" protobuf:"bytes,11,opt,name=discoveryTimestamp"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It appears codegen wasn't run after this change. Among many other things, codegen will also set the protobuf struct tag for you (making it harder to get wrong).

I would suggest this change:

Suggested change
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty" protobuf:"bytes,11,opt,name=discoveryTimestamp"`
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty"`

When you run codegen (make hack-codegen), which you will need to do for reasons other than just this, it will probably put it back to exactly as you had it here, but it may do something slightly different. Better safe than sorry.

// DiscoveryTimestamp is the time at which the Promotion was created.
// This is distinct from metadata.creationTimestamp, which is
// set by Kubernetes and cannot be controlled by users.
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty" protobuf:"bytes,4,opt,name=discoveryTimestamp"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we call this startedAt? That's the field name we use in stepExecutionMetadata, and "discovery" is more of a freight thing.

apiVersion: kargo.akuity.io/v1alpha1
kind: Promotion
metadata:
  creationTimestamp: 2026-04-08T15:50:21Z
  name: dev.01knpwk5z8ngczawgqctc79w39.efe1b47
status:
  startedAt: 2026-04-08T15:40:22Z   # <<<<< my preference
  finishedAt: 2026-04-08T15:51:10Z
  phase: Succeeded
  stepExecutionMetadata:
    - alias: task-1::step-1
      finishedAt: 2026-04-08T15:50:24Z
      startedAt: 2026-04-08T15:50:22Z
      status: Succeeded

Copy link
Copy Markdown
Member

@jessesuen jessesuen Apr 21, 2026

Choose a reason for hiding this comment

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

Also, unlike Freight, for the promotion object, this needs to be under status. Not a top-level field.

Comment on lines +1727 to +1732
lhsTime := lhs.DiscoveryTimestamp
rhsTime := rhs.DiscoveryTimestamp
if lhsTime == nil || rhsTime == nil {
return rhs.CreationTimestamp.Compare(lhs.CreationTimestamp.Time)
}
return rhsTime.Time.Compare(lhsTime.Time)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This was really smart to fall back on CreationTimestamp since existing Freight will obviously not already have a DiscoveryTimestamp.

I might suggest a small improvement though. Instead of falling back on CreationTimestamp for both when either doesn't have a DiscoveryTimestamp, I would let each of them fall back individually like this:

Suggested change
lhsTime := lhs.DiscoveryTimestamp
rhsTime := rhs.DiscoveryTimestamp
if lhsTime == nil || rhsTime == nil {
return rhs.CreationTimestamp.Compare(lhs.CreationTimestamp.Time)
}
return rhsTime.Time.Compare(lhsTime.Time)
lhsTime := lhs.DiscoveryTimestamp
if lhsTime == nil {
lhsTime = lhs.CreationTimestamp.Time
}
rhsTime := rhs.DiscoveryTimestamp
if rhsTime == nil {
rhsTime = rhs.CreationTimestamp.Time
}
return rhsTime.Time.Compare(lhsTime.Time)

Comment on lines +1820 to +1827
// Sort the terminal Promotions by discovery time in descending order
slices.SortFunc(promotions.Items, func(lhs, rhs kargoapi.Promotion) int {
lhsTime := lhs.DiscoveryTimestamp
rhsTime := rhs.DiscoveryTimestamp
if lhsTime == nil || rhsTime == nil {
return rhs.CreationTimestamp.Compare(lhs.CreationTimestamp.Time)
})
}
return rhsTime.Time.Compare(lhsTime.Time)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment as here: https://github.com/akuity/kargo/pull/6133/changes#r3118278060

I start to wonder whether we should include a generic SortByDiscoveryDate() helper somewhere.

Comment on lines +295 to +300
lhsTime := lhs.DiscoveryTimestamp
rhsTime := rhs.DiscoveryTimestamp
if lhsTime == nil || rhsTime == nil {
return lhs.CreationTimestamp.Time.Compare(rhs.CreationTimestamp.Time)
}
return rhsTime.Time.Compare(lhsTime.Time)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as here: https://github.com/akuity/kargo/pull/6133/changes#r3118302803

Another point in favor of a generic helper.

@krancour
Copy link
Copy Markdown
Member

This looks pretty good overall @2003Aditya. Thank you for doing this.

One spot(s) I think may have been overlooked for sorting would be any API endpoints that return a list of Promotions.

// DiscoveryTimestamp is the time at which the Promotion was created.
// This is distinct from metadata.creationTimestamp, which is
// set by Kubernetes and cannot be controlled by users.
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty" protobuf:"bytes,4,opt,name=discoveryTimestamp"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we call this startedAt? That's the field name we use in stepExecutionMetadata, and "discovery" is more of a freight thing.

apiVersion: kargo.akuity.io/v1alpha1
kind: Promotion
metadata:
  creationTimestamp: 2026-04-08T15:50:21Z
  name: dev.01knpwk5z8ngczawgqctc79w39.efe1b47
status:
  startedAt: 2026-04-08T15:40:22Z   # <<<<< my preference
  finishedAt: 2026-04-08T15:51:10Z
  phase: Succeeded
  stepExecutionMetadata:
    - alias: task-1::step-1
      finishedAt: 2026-04-08T15:50:24Z
      startedAt: 2026-04-08T15:50:22Z
      status: Succeeded

// DiscoveryTimestamp is the time at which the Promotion was created.
// This is distinct from metadata.creationTimestamp, which is
// set by Kubernetes and cannot be controlled by users.
DiscoveryTimestamp *metav1.Time `json:"discoveryTimestamp,omitempty" protobuf:"bytes,4,opt,name=discoveryTimestamp"`
Copy link
Copy Markdown
Member

@jessesuen jessesuen Apr 21, 2026

Choose a reason for hiding this comment

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

Also, unlike Freight, for the promotion object, this needs to be under status. Not a top-level field.

@2003Aditya
Copy link
Copy Markdown
Author

2003Aditya commented Apr 22, 2026

@jessesuen @krancour Okay, I will change discovery to startAt and make the rest of the changes as well.

Namespace: stage.Namespace,
Annotations: annotations,
},
DiscoveryTimestamp: &metav1.Time{Time: time.Now()},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since I'm asking for StartedAt timestamp to be a status thing, this will no longer be appropriate to set here. It's also something that the controller would need to set when it transitions the Promotion from Pending to Running.

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.

3 participants