Skip to content

Add artifact trigger automation: TYPE_ARTIFACT + ArtifactTrigger - #7749

Merged
kumare3 merged 4 commits into
mainfrom
artifact-trigger-protos
Aug 4, 2026
Merged

Add artifact trigger automation: TYPE_ARTIFACT + ArtifactTrigger#7749
kumare3 merged 4 commits into
mainfrom
artifact-trigger-protos

Conversation

@kumare3

@kumare3 kumare3 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the third TriggerAutomationSpec automation type for artifact triggers: fire a run when a new version of a named artifact is created.

  • TriggerAutomationSpecType.TYPE_ARTIFACT = 3
  • ArtifactTrigger{artifact_name, version, input_arg} in the TriggerAutomationSpec.automation oneof — version optionally pins an exact version (empty = any new version); input_arg names the task input that receives the triggering artifact's value at fire time, mirroring Schedule.kickoff_time_input_arg
  • RunSource.RUN_SOURCE_ARTIFACT_TRIGGER = 4 so artifact-triggered runs carry their provenance

Backend consumption lands separately (union cloud); the SDK side adds flyte.OnArtifact(...) + a flyte.TriggeredArtifact input sentinel on top of these protos.

🤖 Generated with Claude Code

Third TriggerAutomationSpec automation type: fire a run when a new version of
the named artifact is created. ArtifactTrigger carries the watched artifact
name, an optional exact-version pin, and the task input the artifact's value
binds to at fire time (mirroring Schedule.kickoff_time_input_arg). Also adds
RUN_SOURCE_ARTIFACT_TRIGGER so artifact-triggered runs carry their provenance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 04:35
@github-actions github-actions Bot added the flyte2 label Aug 3, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends Flyte’s IDL surface to represent artifact-triggered automations (triggering a run when a new version of an artifact is created) and to record run provenance for artifact-triggered runs, then regenerates Go/Python/TS bindings accordingly.

Changes:

  • Add TriggerAutomationSpecType.TYPE_ARTIFACT = 3 plus ArtifactTrigger{artifact_name, version, input_arg} under TriggerAutomationSpec.automation (oneof).
  • Add RunSource.RUN_SOURCE_ARTIFACT_TRIGGER = 4 to identify artifact-triggered runs.
  • Regenerate Go/Python/TS generated code for the updated protos.

Reviewed changes

Copilot reviewed 6 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
flyteidl2/task/common.proto Introduces ArtifactTrigger message and TYPE_ARTIFACT automation type; extends TriggerAutomationSpec oneof.
flyteidl2/workflow/run_definition.proto Adds RUN_SOURCE_ARTIFACT_TRIGGER to RunSource.
gen/go/flyteidl2/task/common.pb.go Regenerated Go bindings for the new ArtifactTrigger message and updated oneof/enum wiring.
gen/go/flyteidl2/task/common.pb.validate.go Regenerated validation stubs for ArtifactTrigger and updated oneof validation handling.
gen/go/flyteidl2/workflow/run_definition.pb.go Regenerated Go bindings for the new RunSource enum value.
gen/python/flyteidl2/task/common_pb2.py Regenerated Python runtime module for new automation type/message.
gen/python/flyteidl2/task/common_pb2.pyi Regenerated Python type stubs for new automation type/message.
gen/python/flyteidl2/workflow/run_definition_pb2.py Regenerated Python runtime module for new RunSource value.
gen/python/flyteidl2/workflow/run_definition_pb2.pyi Regenerated Python type stubs for new RunSource value.
gen/ts/flyteidl2/task/common_pb.ts Regenerated TS bindings for ArtifactTrigger, updated oneof union, and new enum value.
gen/ts/flyteidl2/workflow/run_definition_pb.ts Regenerated TS bindings for the new RunSource enum value.
Files not reviewed (5)
  • gen/go/flyteidl2/task/common.pb.go: Generated file
  • gen/go/flyteidl2/task/common.pb.validate.go: Generated file
  • gen/go/flyteidl2/workflow/run_definition.pb.go: Generated file
  • gen/python/flyteidl2/task/common_pb2.py: Generated file
  • gen/python/flyteidl2/workflow/run_definition_pb2.py: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +618 to +629
func (m *ArtifactTrigger) validate(all bool) error {
if m == nil {
return nil
}

var errors []error

// no validation rules for ArtifactName

// no validation rules for Version

// no validation rules for InputArg
…ifacts (#7760)

Replaces the implicit metadata-key contract (magic "_ua"/"_uap" keys in
Literal.metadata carrying JSON payloads that SDKs and backends had to keep in
sync) with typed fields, split by lifecycle:

- core.ArtifactVersionId (ArtifactKey + version), core.ArtifactCard (hoisted
  from artifact.Card, same shape), and core.ArtifactInfo (description,
  user_metadata, card) — the descriptive payload shared by the production
  declaration and the stored spec, deliberately excluding identity so the two
  can never drift.
- core.Literal.artifact_id: the value's artifact identity, stamped once at
  registration and on artifact-bound inputs; travels with the value through
  every copy and participates in cache-key hashing by design.
- task.ProducedArtifact + Outputs.produced_artifacts: the transient
  registration declaration (output name, artifact name, optional version,
  info, declared type) — an action-scoped instruction that never enters the
  value stream. Field 3 on Outputs because outputs.pb blobs are sometimes
  cross-decoded as task.Inputs, where field 2 is context.
- artifact.ArtifactSpec now nests the descriptive payload as core.ArtifactInfo
  (value/type/source stay top-level); artifact.Card is removed in favor of
  core.ArtifactCard.

Co-authored-by: Ketan Umare <kumare3@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 4, 2026 01:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 34 changed files in this pull request and generated no new comments.

Files not reviewed (14)
  • gen/go/flyteidl2/artifact/artifact.pb.go: Generated file
  • gen/go/flyteidl2/artifact/artifact.pb.validate.go: Generated file
  • gen/go/flyteidl2/core/artifact_id.pb.go: Generated file
  • gen/go/flyteidl2/core/artifact_id.pb.validate.go: Generated file
  • gen/go/flyteidl2/core/literals.pb.go: Generated file
  • gen/go/flyteidl2/core/literals.pb.validate.go: Generated file
  • gen/go/flyteidl2/task/common.pb.go: Generated file
  • gen/go/flyteidl2/task/common.pb.validate.go: Generated file
  • gen/go/flyteidl2/workflow/run_definition.pb.go: Generated file
  • gen/python/flyteidl2/artifact/artifact_pb2.py: Generated file
  • gen/python/flyteidl2/core/artifact_id_pb2.py: Generated file
  • gen/python/flyteidl2/core/literals_pb2.py: Generated file
  • gen/python/flyteidl2/task/common_pb2.py: Generated file
  • gen/python/flyteidl2/workflow/run_definition_pb2.py: Generated file
Suppressed comments (3)

flyteidl2/artifact/artifact.proto:96

  • ArtifactSpec reuses tag number 3 with a different wire type: it used to be string description = 3 (and tags 4/5 for metadata/card), but is now core.ArtifactInfo info = 3. Reusing a tag with a different type breaks protobuf wire compatibility (old data will be mis-decoded, and old clients won’t understand new payloads). Consider reserving the removed tags (3–5) and adding info under a new, unused tag number (e.g. 7), keeping source = 6.
// User-provided specification of an artifact.
message ArtifactSpec {
  // The typed value of the artifact. Offloaded data (files, directories,
  // dataframes) must already reside in blob storage; the literal references
  // it by uri.
  core.Literal value = 1 [(buf.validate.field).required = true];

  // The Flyte type of the value.
  core.LiteralType type = 2 [(buf.validate.field).required = true];

  // Descriptive payload (description, user metadata, card). Shared with the
  // production declaration (task.ProducedArtifact.info), so task-produced
  // artifacts carry it verbatim.
  core.ArtifactInfo info = 3;

  // Optional provenance: what produced this artifact. Clients (including the
  // SDK, which stamps this automatically when publishing from inside a
  // running task) declare it at creation time; it is immutable afterwards.
  ArtifactSource source = 6;
}

flyteidl2/core/artifact_id.proto:24

  • ArtifactVersionId is intended to be the minimal identity for an artifact version (and is embedded in core.Literal.artifact_id), but it has no validation constraints. As written, it allows an empty version and a missing key, which undermines the “identity” semantics and can propagate partially-specified IDs through cache hashing and APIs. Consider adding (buf.validate.field).required = true on key and (buf.validate.field).string.min_len = 1 (and possibly a max_len consistent with other version fields) on version.
// Identity of one artifact version. Unlike the legacy ArtifactID below, this
// carries no partition machinery — it is the minimal identity stamped onto
// values (core.Literal.artifact_id) and referenced by v2 artifact APIs.
message ArtifactVersionId {
  ArtifactKey key = 1;
  string version = 2;
}

flyteidl2/task/common.proto:152

  • ProducedArtifact’s comment says the producing SDK is authoritative for the output’s declared Flyte type and that it’s copied into ArtifactSpec.type to make the declaration self-contained, but type = 5 is not marked required (and is generated as optional in TS/Python). This allows ProducedArtifact declarations without a type, which defeats the stated self-contained contract. Consider adding (buf.validate.field).required = true to type (and possibly clarifying whether info is optional) so backends/consumers can rely on the presence of the declared type.
// Declares that a named output of the producing action is a new artifact
// version. The output's literal (in Outputs.literals) is the artifact's value;
// org/project/domain come from the producing action's scope at registration.
message ProducedArtifact {
  // Name of the NamedLiteral in Outputs.literals this declaration refers to.
  string output = 1 [(buf.validate.field).string.min_len = 1];

  // Artifact name to register under.
  string name = 2 [(buf.validate.field).string.min_len = 1];

  // Optional explicit version. Empty means the backend derives one
  // (<run>-<action>-<attempt>).
  string version = 3;

  // Descriptive payload, copied verbatim into ArtifactSpec.info.
  flyteidl2.core.ArtifactInfo info = 4;

  // The declared Flyte type of the output, copied into ArtifactSpec.type.
  // The producing SDK is authoritative for this.
  flyteidl2.core.LiteralType type = 5;
}

wild-endeavor
wild-endeavor previously approved these changes Aug 4, 2026
string artifact_name = 1 [(buf.validate.field).string.min_len = 1];

// Optional: fire only when exactly this version is created. Empty means any new version.
string version = 2;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it this really needed?

kumare3 added 2 commits August 3, 2026 18:05
# Conflicts:
#	flyteidl2/workflow/run_definition.proto
#	gen/go/flyteidl2/workflow/run_definition.pb.go
#	gen/python/flyteidl2/workflow/run_definition_pb2.py
#	gen/python/flyteidl2/workflow/run_definition_pb2.pyi
#	gen/rust/src/flyteidl2.workflow.rs
#	gen/ts/flyteidl2/workflow/run_definition_pb.ts
Copilot AI review requested due to automatic review settings August 4, 2026 01:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 34 changed files in this pull request and generated no new comments.

Files not reviewed (14)
  • gen/go/flyteidl2/artifact/artifact.pb.go: Generated file
  • gen/go/flyteidl2/artifact/artifact.pb.validate.go: Generated file
  • gen/go/flyteidl2/core/artifact_id.pb.go: Generated file
  • gen/go/flyteidl2/core/artifact_id.pb.validate.go: Generated file
  • gen/go/flyteidl2/core/literals.pb.go: Generated file
  • gen/go/flyteidl2/core/literals.pb.validate.go: Generated file
  • gen/go/flyteidl2/task/common.pb.go: Generated file
  • gen/go/flyteidl2/task/common.pb.validate.go: Generated file
  • gen/go/flyteidl2/workflow/run_definition.pb.go: Generated file
  • gen/python/flyteidl2/artifact/artifact_pb2.py: Generated file
  • gen/python/flyteidl2/core/artifact_id_pb2.py: Generated file
  • gen/python/flyteidl2/core/literals_pb2.py: Generated file
  • gen/python/flyteidl2/task/common_pb2.py: Generated file
  • gen/python/flyteidl2/workflow/run_definition_pb2.py: Generated file
Suppressed comments (3)

gen/go/flyteidl2/task/common.pb.validate.go:629

  • ArtifactTrigger.artifact_name is marked with (buf.validate.field).string.min_len = 1 in the proto, but the generated ArtifactTrigger.Validate() implementation currently has no field-level validation (it explicitly says "no validation rules for ArtifactName"). If server-side request validation relies on these generated Validate() methods, empty artifact_name values could be accepted and lead to triggers that never match. Consider ensuring buf.validate rules are actually enforced in Go (e.g. via protovalidate runtime validation or by fixing the validation codegen).
    flyteidl2/workflow/run_definition.proto:486
  • The PR description states RunSource.RUN_SOURCE_ARTIFACT_TRIGGER = 4, but the proto defines RUN_SOURCE_LOCAL = 4 and the newly added RUN_SOURCE_ARTIFACT_TRIGGER = 5. This should be reconciled (most likely update the PR description/docs) to avoid consumers implementing the wrong numeric value.
  // The run is orchestrated outside the platform (e.g. on a user's machine) and its state is
  // reported via LocalRunService.
  RUN_SOURCE_LOCAL = 4;

  RUN_SOURCE_ARTIFACT_TRIGGER = 5;
}

gen/go/flyteidl2/task/common.pb.validate.go:1326

  • ProducedArtifact.output and ProducedArtifact.name are marked with (buf.validate.field).string.min_len = 1 in the proto, but the generated ProducedArtifact.Validate() does not enforce any field-level rules ("no validation rules for Output/Name"). If these Validate() methods are used for request validation, invalid artifact declarations (empty output/name) may be accepted and fail later in registration/consumption.

@kumare3
kumare3 merged commit 96e732b into main Aug 4, 2026
25 checks passed
@kumare3
kumare3 deleted the artifact-trigger-protos branch August 4, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants