Skip to content

Add GCP min/max scaling options for worker deployment version - #1135

Open
zainawaisn wants to merge 5 commits into
mainfrom
zain/gcp-scaling
Open

Add GCP min/max scaling options for worker deployment version#1135
zainawaisn wants to merge 5 commits into
mainfrom
zain/gcp-scaling

Conversation

@zainawaisn

@zainawaisn zainawaisn commented Jul 22, 2026

Copy link
Copy Markdown

Related issues

What changed?

Adds four new (optional) flags gcp-cloud-run-min-instances, gcp-cloud-run-max-instances, gcp-cloud-run-initial-instances, and gcp-cloud-run-utilization-target to create-version and update-version-compute-config.

temporal worker deployment create-version \
    --deployment-name YourDeployment \
    --build-id YourBuildID \
    --gcp-cloud-run-project YourProject \
    --gcp-cloud-run-region us-central1 \
    --gcp-cloud-run-worker-pool YourWorkerPool \
    --gcp-cloud-run-service-account customer-sa@proj.iam.gserviceaccount.com \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 5 \
    --gcp-cloud-run-utilization-target 0.5
temporal worker deployment update-version-compute-config \
    --deployment-name YourDeployment \
    --build-id YourBuildID \
    --gcp-cloud-run-project YourProject \
    --gcp-cloud-run-region us-central1 \
    --gcp-cloud-run-worker-pool YourWorkerPool \
    --gcp-cloud-run-service-account customer-sa@proj.iam.gserviceaccount.com \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 5 \
    --gcp-cloud-run-utilization-target 0.5

Changes

  • commands.yaml / commands.gen.go: four new flags
    (--gcp-cloud-run-min-instances, --gcp-cloud-run-max-instances,
    --gcp-cloud-run-initial-instances, --gcp-cloud-run-utilization-target) on
    create-version and update-version-compute-config, plus help text and usage
    examples.

  • commands.worker.deployment.go: a new gcpCloudRunScalerDetails helper turns
    the flags into the scaling settings sent to the server, and rejects bad input
    early. All four settings are GCP-only and form a single all-or-none group —
    setting any one requires all four — with min <= initial <= max and
    utilization-target a fraction in (0, 1]. Both commands use it, and
    describe-version now shows the settings back in its JSON and summary output.

  • tests: unit tests cover the helper's accept/reject cases and the
    describe-version display; command-level error cases were added to
    TestCreateWorkerDeploymentVersion_Errors. The end-to-end GCP test stays
    skipped (needs real GCP resources).

Checklist

Stability

  • Breaking changes are marked with 💥 in the PR title and release notes
  • Changes to JSON output (-o json / -o jsonl) are treated as breaking changes

Design

  • This feature does not depend on Cloud-only APIs or behavior (it works against an OSS server)
  • New commands follow temporal <noun> <verb> structure (e.g. temporal workflow start)
  • New flags are named after the API concept, not the implementation mechanism (good: --search-attribute, bad: --index-field)
  • New flags don't duplicate an existing flag that serves the same purpose
  • New flags do not have short aliases without strong justification
  • Experimental features are marked with (Experimental) in commands.yaml

Help text (see style guide at the top of commands.yaml)

  • All flags shown in help text and examples are implemented and functional
  • Summaries use sentence case and have no trailing period
  • Long descriptions end with a period and include at least one example invocation
  • Examples use long flags (--namespace, not -n), one flag per line
  • Placeholder values use YourXxx form (YourWorkflowId, YourNamespace)

Behavior

  • Results go to stdout; errors and warnings go to stderr
  • Error messages are lowercase with no trailing punctuation

Tests

  • Added functional test(s) (SharedServerSuite)
  • Added unit test(s) (func TestXxx) where applicable

Manual tests

Creation:

./temporal --profile "ns-cloud-run-test" worker deployment create-version \
    --deployment-name "zain-cloud-run-deployment" \
    --build-id "1.0" \
    --gcp-cloud-run-project "compute-team-sandbox" \
    --gcp-cloud-run-region "us-west1" \
    --gcp-cloud-run-worker-pool "omes-worker-pool" \
    --gcp-cloud-run-service-account "wci-invocation-sa@compute-team-sandbox.iam.gserviceaccount.com" \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 5 \
    --gcp-cloud-run-utilization-target 0.5
Successfully created worker deployment version

./temporal --profile "ns-cloud-run-test" worker deployment describe-version \
    --deployment-name "zain-cloud-run-deployment" \
    --build-id "1.0" \
    --output json
...
        "scaler": {
          "type": "rate-based",
          "minInstances": 0,
          "maxInstances": 10,
          "initialInstances": 5,
          "utilizationTarget": 0.5
        }
...

Update existing:

./temporal --profile "ns-cloud-run-test" worker deployment update-version-compute-config \
    --deployment-name "zain-cloud-run-deployment" \
    --build-id "1.0" \
    --gcp-cloud-run-project "compute-team-sandbox" \
    --gcp-cloud-run-region "us-west1" \
    --gcp-cloud-run-worker-pool "omes-worker-pool" \
    --gcp-cloud-run-service-account "wci-invocation-sa@compute-team-sandbox.iam.gserviceaccount.com" \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 20 \
    --gcp-cloud-run-initial-instances 10 \
    --gcp-cloud-run-utilization-target 0.5
Successfully updated worker deployment version compute config

./temporal --profile "ns-cloud-run-test" worker deployment describe-version \
    --deployment-name "zain-cloud-run-deployment" \
    --build-id "1.0" \
    --output json
{
...
        "scaler": {
          "type": "rate-based",
          "minInstances": 0,
          "maxInstances": 20,
          "initialInstances": 10,
          "utilizationTarget": 0.5
        }
...

Error checks:

./temporal --profile "ns-cloud-run-test" worker deployment create-version \
    --deployment-name "zain-cloud-run-deployment" \
    --build-id "1.0" \
    --gcp-cloud-run-project "compute-team-sandbox" \
    --gcp-cloud-run-region "us-west1" \
    --gcp-cloud-run-worker-pool "omes-worker-pool" \
    --gcp-cloud-run-service-account "wci-invocation-sa@compute-team-sandbox.iam.gserviceaccount.com" \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 5
Error: --gcp-cloud-run-min-instances, --gcp-cloud-run-max-instances, --gcp-cloud-run-initial-instances, and --gcp-cloud-run-utilization-target must be set together
./temporal --profile "ns-cloud-run-test" worker deployment create-version \
    --deployment-name "cli-cloud-run-deployment" \
    --build-id "1.0" \
    --gcp-cloud-run-project "compute-team-sandbox" \
    --gcp-cloud-run-region "us-west1" \
    --gcp-cloud-run-worker-pool "omes-worker-pool" \
    --gcp-cloud-run-service-account "wci-invocation-sa@compute-team-sandbox.iam.gserviceaccount.com" \
    --gcp-cloud-run-min-instances 5 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 0 \
    --gcp-cloud-run-utilization-target 0.5
Error: --gcp-cloud-run-initial-instances must be between --gcp-cloud-run-min-instances and --gcp-cloud-run-max-instances
./temporal --profile "ns-cloud-run-test" worker deployment create-version \
    --deployment-name my-deploy --build-id v1 \
    --aws-lambda-function-arn arn:aws:lambda:us-east-1:123:function:F:1 \
    --aws-lambda-assume-role-arn arn:aws:iam::123:role/R \
    --aws-lambda-assume-role-external-id x \
    --gcp-cloud-run-min-instances 0 \
    --gcp-cloud-run-max-instances 10 \
    --gcp-cloud-run-initial-instances 5 \
    --gcp-cloud-run-utilization-target 0.5
Error: the Cloud Run scaling flags are only valid with --gcp-cloud-run-worker-pool

@zainawaisn
zainawaisn requested a review from a team as a code owner July 22, 2026 22:11
@CLAassistant

CLAassistant commented Jul 22, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@ericbriffa

Copy link
Copy Markdown

Are more coming? or did we agree on just these?

Previous discussion was https://temporaltechnologies.slack.com/archives/C05L7RUSK6E/p1784055551940739

I updated https://temporalio.atlassian.net/browse/COM-222 with that data once I found it.

@zainawaisn

zainawaisn commented Jul 23, 2026

Copy link
Copy Markdown
Author

synced with george on this, i believe min/max is fine for now.

scratch that, initial_count must not be lower than min_count, we should expose that as well. currently initial_count is a default 0 and cannot be changed via cli.

@chaptersix

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2fe58cf3d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if err != nil {
return err
}
scalerDetails, err := gcpCloudRunScalerDetails(providerType, c.gcpScalerFlags())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject scaler flags alongside --remove

When update-version-compute-config is invoked with --remove plus any of the four new scaler flags, execution takes the remove branch, whose conflict check only covers the pre-existing provider flags, so this validation is never reached and the supplied scaler values are silently ignored while the config is removed. Include c.gcpScalerFlags().anySet() in the --remove conflict check so contradictory input is rejected consistently.

Useful? React with 👍 / 👎.

Comment thread internal/temporalcli/commands.yaml Outdated
Comment on lines +1505 to +1506
--gcp-cloud-run-utilization-target must all be set together. Defaults
to 0 when unset. Only valid with --gcp-cloud-run-worker-pool.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Correct update help for omitted scaler flags

For update-version-compute-config, this claims an omitted flag defaults to the documented WCI value, but the implementation deliberately excludes scaler.details from the update mask when the scaler flags are omitted, preserving any existing custom bounds and utilization instead. A user updating the Cloud Run provider without these flags can therefore retain materially different scaling settings than the help promises; describe them as unchanged on update and reserve the stated defaults for creation or configurations without existing details.

Useful? React with 👍 / 👎.

@chaptersix chaptersix left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Two brief follow-ups.

// Only touch scaler.details when the user supplied instance bounds;
// otherwise leave any existing scaler config untouched rather than
// clearing it.
if scalerDetails != nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Switching GCP → AWS changes the scaler type but leaves the GCP scaler details in place, which WCI rejects under no-sync. Please clear or replace scaler.details when the scaler type changes.

if err != nil {
return err
}
scalerDetails, err := gcpCloudRunScalerDetails(providerType, c.gcpScalerFlags())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Should scaler-only updates work? Supplying all four scaler flags without repeating the provider fields returns missing configuration for compute provider, even though scaler.details can be updated independently. If full provider config is required, please document that.

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.

4 participants