syntax = "proto3";

package temporal.api.deployment.v1;

option go_package = "go.temporal.io/api/deployment/v1;deployment";
option java_package = "io.temporal.api.deployment.v1";
option java_multiple_files = true;
option java_outer_classname = "MessageProto";
option ruby_package = "Temporalio::Api::Deployment::V1";
option csharp_namespace = "Temporalio.Api.Deployment.V1";

import "google/protobuf/timestamp.proto";

import "temporal/api/enums/v1/workflow.proto";
import "temporal/api/enums/v1/deployment.proto";
import "temporal/api/enums/v1/task_queue.proto";
import "temporal/api/common/v1/message.proto";
import "temporal/api/compute/v1/config.proto";

// Worker Deployment options set in SDK that need to be sent to server in every poll.
message WorkerDeploymentOptions {
    // Required when `worker_versioning_mode==VERSIONED`.
    string deployment_name = 1;
    // The Build ID of the worker. Required when `worker_versioning_mode==VERSIONED`, in which case,
    // the worker will be part of a Deployment Version.
    string build_id = 2;
    // Required. Versioning Mode for this worker. Must be the same for all workers with the
    // same `deployment_name` and `build_id` combination, across all Task Queues.
    // When `worker_versioning_mode==VERSIONED`, the worker will be part of a Deployment Version.
    temporal.api.enums.v1.WorkerVersioningMode worker_versioning_mode = 3;
}

// `Deployment` identifies a deployment of Temporal workers. The combination of deployment series
// name + build ID serves as the identifier. User can use `WorkerDeploymentOptions` in their worker
// programs to specify these values.
// Deprecated.
message Deployment {
    // Different versions of the same worker service/application are related together by having a
    // shared series name.
    // Out of all deployments of a series, one can be designated as the current deployment, which
    // receives new workflow executions and new tasks of workflows with
    // `VERSIONING_BEHAVIOR_AUTO_UPGRADE` versioning behavior.
    string series_name = 1;
    // Build ID changes with each version of the worker when the worker program code and/or config
    // changes.
    string build_id = 2;
}

// `DeploymentInfo` holds information about a deployment. Deployment information is tracked
// automatically by server as soon as the first poll from that deployment reaches the server. There
// can be multiple task queue workers in a single deployment which are listed in this message.
// Deprecated.
message DeploymentInfo {
    Deployment deployment = 1;
    google.protobuf.Timestamp create_time = 2;
    repeated TaskQueueInfo task_queue_infos = 3;
    // A user-defined set of key-values. Can be updated as part of write operations to the
    // deployment, such as `SetCurrentDeployment`.
    map<string, temporal.api.common.v1.Payload> metadata = 4;
    // If this deployment is the current deployment of its deployment series.
    bool is_current = 5;

    message TaskQueueInfo {
        string name = 1;
        temporal.api.enums.v1.TaskQueueType type = 2;
        // When server saw the first poller for this task queue in this deployment.
        google.protobuf.Timestamp first_poller_time = 3;
    }
}

// Used as part of Deployment write APIs to update metadata attached to a deployment.
// Deprecated.
message UpdateDeploymentMetadata {
    map<string, temporal.api.common.v1.Payload> upsert_entries = 1;
    // List of keys to remove from the metadata.
    repeated string remove_entries = 2;
}

// DeploymentListInfo is an abbreviated set of fields from DeploymentInfo that's returned in
// ListDeployments.
// Deprecated.
message DeploymentListInfo {
    deployment.v1.Deployment deployment = 1;
    google.protobuf.Timestamp create_time = 2;
    // If this deployment is the current deployment of its deployment series.
    bool is_current = 3;
}


// A Worker Deployment Version (Version, for short) represents all workers of the same
// code and config within a Deployment. Workers of the same Version are expected to
// behave exactly the same so when executions move between them there are no
// non-determinism issues.
// Worker Deployment Versions are created in Temporal server automatically when
// their first poller arrives to the server.
message WorkerDeploymentVersionInfo {
    // Deprecated. Use `deployment_version`.
    string version = 1 [deprecated = true];

    // The status of the Worker Deployment Version.
    temporal.api.enums.v1.WorkerDeploymentVersionStatus status = 14;

    // Required.
    WorkerDeploymentVersion deployment_version = 11;
    // Deprecated. User deployment_version.deployment_name.
    string deployment_name = 2;
    google.protobuf.Timestamp create_time = 3;

    // Last time `current_since_time`, `ramping_since_time, or `ramp_percentage` of this version changed.
    google.protobuf.Timestamp routing_changed_time = 4;

    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: 'Since' captures the field semantics despite being a preposition. --)
    // Unset if not current.
    google.protobuf.Timestamp current_since_time = 5;

    // (-- api-linter: core::0140::prepositions=disabled
    //     aip.dev/not-precedent: 'Since' captures the field semantics despite being a preposition. --)
    // Unset if not ramping. Updated when the version first starts ramping, not on each ramp change.
    google.protobuf.Timestamp ramping_since_time = 6;

    // Timestamp when this version first became current or ramping.
    google.protobuf.Timestamp first_activation_time = 12;

    // Timestamp when this version last became current.
    // Can be used to determine whether a version has ever been Current.
    google.protobuf.Timestamp last_current_time = 15;

    // Timestamp when this version last stopped being current or ramping.
    // Cleared if the version becomes current or ramping again.
    google.protobuf.Timestamp last_deactivation_time = 13;

    // Range: [0, 100]. Must be zero if the version is not ramping (i.e. `ramping_since_time` is nil).
    // Can be in the range [0, 100] if the version is ramping.
    float ramp_percentage = 7;

    // All the Task Queues that have ever polled from this Deployment version.
    // Deprecated. Use `version_task_queues` in DescribeWorkerDeploymentVersionResponse instead.
    repeated VersionTaskQueueInfo task_queue_infos = 8;
    message VersionTaskQueueInfo {
        string name = 1;
        temporal.api.enums.v1.TaskQueueType type = 2;
    }

    // Helps user determine when it is safe to decommission the workers of this
    // Version. Not present when version is current or ramping.
    // Current limitations:
    // - Not supported for Unversioned mode.
    // - Periodically refreshed, may have delays up to few minutes (consult the
    //   last_checked_time value).
    // - Refreshed only when version is not current or ramping AND the status is not
    //   "drained" yet.
    // - Once the status is changed to "drained", it is not changed until the Version
    //   becomes Current or Ramping again, at which time the drainage info is cleared.
    //   This means if the Version is "drained" but new workflows are sent to it via
    //   Pinned Versioning Override, the status does not account for those Pinned-override
    //   executions and remains "drained".
    VersionDrainageInfo drainage_info = 9;

    // Arbitrary user-provided metadata attached to this version.
    VersionMetadata metadata = 10;

    // Optional. Contains the new worker compute configuration for the Worker
    // Deployment. Used for worker scale management.
    temporal.api.compute.v1.ComputeConfig compute_config = 16;

    // Identity of the last client who modified the configuration of this Version.
    // As of now, this field only covers changes through the following APIs:
    // - `CreateWorkerDeploymentVersion`
    // - `UpdateWorkerDeploymentVersionComputeConfig`
    // - `UpdateWorkerDeploymentVersionMetadata`
    string last_modifier_identity = 17;
}

// Information about workflow drainage to help the user determine when it is safe
// to decommission a Version. Not present while version is current or ramping.
message VersionDrainageInfo {
    // Set to DRAINING when the version first stops accepting new executions (is no longer current or ramping).
    // Set to DRAINED when no more open pinned workflows exist on this version.
    enums.v1.VersionDrainageStatus status = 1;
    // Last time the drainage status changed.
    google.protobuf.Timestamp last_changed_time = 2;
    // Last time the system checked for drainage of this version.
    google.protobuf.Timestamp last_checked_time = 3;
}

// A Worker Deployment (Deployment, for short) represents all workers serving
// a shared set of Task Queues. Typically, a Deployment represents one service or
// application.
// A Deployment contains multiple Deployment Versions, each representing a different
// version of workers. (see documentation of WorkerDeploymentVersionInfo)
// Deployment records are created in Temporal server automatically when their
// first poller arrives to the server.
message WorkerDeploymentInfo {
    // Identifies a Worker Deployment. Must be unique within the namespace.
    string name = 1;

    // Deployment Versions that are currently tracked in this Deployment. A DeploymentVersion will be
    // cleaned up automatically if all the following conditions meet:
    // - It does not receive new executions (is not current or ramping)
    // - It has no active pollers (see WorkerDeploymentVersionInfo.pollers_status)
    // - It is drained (see WorkerDeploymentVersionInfo.drainage_status)
    repeated WorkerDeploymentVersionSummary version_summaries = 2;

    google.protobuf.Timestamp create_time = 3;

    RoutingConfig routing_config = 4;

    // Identity of the last client who modified the configuration of this Deployment. Set to the
    // `identity` value sent by APIs such as `SetWorkerDeploymentCurrentVersion` and
    // `SetWorkerDeploymentRampingVersion`.
    string last_modifier_identity = 5;

    // Identity of the client that has the exclusive right to make changes to this Worker Deployment.
    // Empty by default.
    // If this is set, clients whose identity does not match `manager_identity` will not be able to make changes
    // to this Worker Deployment. They can either set their own identity as the manager or unset the field to proceed.
    string manager_identity = 6;

    // Indicates whether the routing_config has been fully propagated to all
    // relevant task queues and their partitions.
    temporal.api.enums.v1.RoutingConfigUpdateState routing_config_update_state = 7;

    message WorkerDeploymentVersionSummary {
        // Deprecated. Use `deployment_version`.
        string version = 1 [deprecated = true];

        // The status of the Worker Deployment Version.
        temporal.api.enums.v1.WorkerDeploymentVersionStatus status = 11;

        // Required.
        WorkerDeploymentVersion deployment_version = 4;
        google.protobuf.Timestamp create_time = 2;
        // Deprecated. Use `drainage_info` instead.
        enums.v1.VersionDrainageStatus drainage_status = 3;
        // Information about workflow drainage to help the user determine when it is safe
        // to decommission a Version. Not present while version is current or ramping
        VersionDrainageInfo drainage_info = 5;
        // Unset if not current.
        // (-- api-linter: core::0140::prepositions=disabled
        //     aip.dev/not-precedent: 'Since' captures the field semantics despite being a preposition. --)
        google.protobuf.Timestamp current_since_time = 6;
        // Unset if not ramping. Updated when the version first starts ramping, not on each ramp change.
        // (-- api-linter: core::0140::prepositions=disabled
        //     aip.dev/not-precedent: 'Since' captures the field semantics despite being a preposition. --)
        google.protobuf.Timestamp ramping_since_time = 7;
        // Last time `current_since_time`, `ramping_since_time, or `ramp_percentage` of this version changed.
        google.protobuf.Timestamp routing_update_time = 8;
        // Timestamp when this version first became current or ramping.
        google.protobuf.Timestamp first_activation_time = 9;
        // Timestamp when this version last became current.
        // Can be used to determine whether a version has ever been Current.
        google.protobuf.Timestamp last_current_time = 12;
        // Timestamp when this version last stopped being current or ramping.
        // Cleared if the version becomes current or ramping again.
        google.protobuf.Timestamp last_deactivation_time = 10;
        temporal.api.compute.v1.ComputeConfigSummary compute_config = 13;
    }
}

// A Worker Deployment Version (Version, for short) represents a
// version of workers within a Worker Deployment. (see documentation of WorkerDeploymentVersionInfo)
// Version records are created in Temporal server automatically when their
// first poller arrives to the server.
// Experimental. Worker Deployment Versions are experimental and might significantly change in the future.
message WorkerDeploymentVersion {
    // A unique identifier for this Version within the Deployment it is a part of.
    // Not necessarily unique within the namespace.
    // The combination of `deployment_name` and `build_id` uniquely identifies this
    // Version within the namespace, because Deployment names are unique within a namespace.
    string build_id = 1;

    // Identifies the Worker Deployment this Version is part of.
    string deployment_name = 2;
}

message VersionMetadata {
    // Arbitrary key-values.
    map<string, temporal.api.common.v1.Payload> entries = 1;
}

message RoutingConfig {
    // Specifies which Deployment Version should receive new workflow executions and tasks of
    // existing unversioned or AutoUpgrade workflows.
    // Nil value means no Version in this Deployment (except Ramping Version, if present) receives traffic other than tasks of previously Pinned workflows. In absence of a Current Version, remaining traffic after any ramp (if set)  goes to unversioned workers (those with `UNVERSIONED` (or unspecified) `WorkerVersioningMode`.).
    // Note: Current Version is overridden by the Ramping Version for a portion of traffic when ramp percentage
    // is non-zero (see `ramping_deployment_version` and `ramping_version_percentage`).
    temporal.api.deployment.v1.WorkerDeploymentVersion current_deployment_version = 7;
    // Deprecated. Use `current_deployment_version`.
    string current_version = 1 [deprecated = true];

    // When ramp percentage is non-zero, that portion of traffic is shifted from the Current Version to the Ramping Version.
    // Must always be different from `current_deployment_version` unless both are nil.
    // Nil value represents all the unversioned workers (those with `UNVERSIONED` (or unspecified) `WorkerVersioningMode`.)
    // Note that it is possible to ramp from one Version to another Version, or from unversioned
    // workers to a particular Version, or from a particular Version to unversioned workers.
    temporal.api.deployment.v1.WorkerDeploymentVersion ramping_deployment_version = 9;
    // Deprecated. Use `ramping_deployment_version`.
    string ramping_version = 2 [deprecated = true];

    // Percentage of tasks that are routed to the Ramping Version instead of the Current Version.
    // Valid range: [0, 100]. A 100% value means the Ramping Version is receiving full traffic but
    // not yet "promoted" to be the Current Version, likely due to pending validations.
    // A 0% value means the Ramping Version is receiving no traffic.
    float ramping_version_percentage = 3;
    // Last time current version was changed.
    google.protobuf.Timestamp current_version_changed_time = 4;
    // Last time ramping version was changed. Not updated if only the ramp percentage changes.
    google.protobuf.Timestamp ramping_version_changed_time = 5;
    // Last time ramping version percentage was changed.
    // If ramping version is changed, this is also updated, even if the percentage stays the same.
    google.protobuf.Timestamp ramping_version_percentage_changed_time = 6;
    // Monotonically increasing value which is incremented on every mutation
    // to any field of this message to achieve eventual consistency between task queues and their partitions.
    int64 revision_number = 10;
}

// Used as part of WorkflowExecutionStartedEventAttributes to pass down the AutoUpgrade behavior and source deployment version
// to a workflow execution whose parent/previous workflow has an AutoUpgrade behavior.
// Also used for Upgrade-on-CaN behaviors AutoUpgrade and UseRampingVersion.
message InheritedAutoUpgradeInfo {
    // The source deployment version of the parent/previous workflow.
    temporal.api.deployment.v1.WorkerDeploymentVersion source_deployment_version = 1;
    // The revision number of the source deployment version of the parent/previous workflow.
    int64 source_deployment_revision_number = 2;
    // Experimental.
    // If this workflow is the result of a continue-as-new, this field is set to the initial_versioning_behavior
    // specified in that command.
    // Only used for the initial task of this run and the initial task of any retries of this run.
    // Not passed to children or to future continue-as-new.
    //
    // Note: In the first release of Upgrade-on-CaN, when the only ContinueAsNewVersioningBehavior was AutoUpgrade,
    // a non-empty InheritedAutoUpgradeInfo meant that the workflow should start as AutoUpgrade. So for compatibility
    // with history events generated during that time, know that an UNSPECIFIED value here is equivalent to AutoUpgrade
    // value if the InheritedAutoUpgradeInfo is non-empty.
    temporal.api.enums.v1.ContinueAsNewVersioningBehavior continue_as_new_initial_versioning_behavior = 3;
}
