Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/trigger-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run: |
gh workflow run update-cli-docs.yml \
-R temporalio/documentation \
-r cli-docs-autoupdate \
-r main \
-f cli_release_tag="${{ github.ref_name }}" \
-f commit_author="${{ steps.get_user.outputs.GIT_NAME }}" \
-f commit_author_email="${{ steps.get_user.outputs.GIT_EMAIL }}" \
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
/temporal
/temporal.exe

# Goreleaser output
/dist

# Used by IDE
/.idea
/.vscode
Expand Down
15 changes: 15 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,18 @@ Note that inclusion of space characters in the value supplied via `-ldflags` is
Here's an example that adds branch info from a local repo to the version string, and includes a space character:

go build -ldflags "-X 'github.com/temporalio/cli/temporalcli.buildInfo=ServerBranch $(git -C ../temporal rev-parse --abbrev-ref HEAD)'" -o temporal ./cmd/temporal/main.go

## Building Docker image

Docker image build requires [Goreleaser](https://goreleaser.com/) to build the binaries first, although it doesn't use
Goreleaser for the Docker image itself.

First, run the Goreleaser build:

goreleaser build --snapshot --clean

Then, run the Docker build using the following command:

docker build --tag temporalio/temporal:snapshot --platform=<platform> .

Currently only `linux/amd64` and `linux/arm64` platforms are supported.
33 changes: 12 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
FROM golang:1.24-bookworm AS builder

WORKDIR /app

# Copy everything
COPY . ./

# Build
RUN go build ./cmd/temporal

# Use slim container for running
FROM debian:bookworm-slim
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
ca-certificates && \
rm -rf /var/lib/apt/lists/*

# Copy binary
COPY --from=builder /app/temporal /app/temporal

# Set CLI as primary entrypoint
ENTRYPOINT ["/app/temporal"]
FROM --platform=$BUILDARCH scratch AS dist
COPY ./dist/nix_linux_amd64_v1/temporal /dist/amd64/temporal
COPY ./dist/nix_linux_arm64/temporal /dist/arm64/temporal

FROM alpine:3.22
ARG TARGETARCH
RUN apk add --no-cache ca-certificates
COPY --from=dist /dist/$TARGETARCH/temporal /usr/local/bin/temporal
RUN adduser -u 1000 -D temporal
USER temporal

ENTRYPOINT ["temporal"]
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ Reference [the documentation](https://docs.temporal.io/cli) for detailed install
2. Extract the downloaded archive.
3. Add the `temporal` binary to your `PATH` (`temporal.exe` for Windows).

### Run via Docker

[Temporal CLI on DockerHub](https://hub.docker.com/r/temporalio/temporal)

docker run --rm temporalio/temporal --help

Note that for dev server to be accessible from host system, it needs to listen on external IP and the ports need to be forwarded:

docker run --rm -p 7233:7233 -p 8233:8233 temporalio/temporal:latest server start-dev --ip 0.0.0.0
# UI is now accessible from host at http://localhost:8233/

### Build

1. Install [Go](https://go.dev/)
Expand Down
11 changes: 7 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ require (
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
github.com/temporalio/ui-server/v2 v2.39.0
go.temporal.io/api v1.50.0
go.temporal.io/api v1.51.1-0.20250725211336-3d6e39249ecf
go.temporal.io/sdk v1.35.0
go.temporal.io/sdk/contrib/envconfig v0.1.0
go.temporal.io/server v1.28.0
google.golang.org/grpc v1.71.0
go.temporal.io/server v1.29.0-135.0.0.20250729005252-42e640c619f8
google.golang.org/grpc v1.72.2
google.golang.org/protobuf v1.36.6
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.34.1
Expand Down Expand Up @@ -121,6 +121,7 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sony/gobreaker v1.0.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/temporalio/ringpop-go v0.0.0-20250130211428-b97329e994f7 // indirect
github.com/temporalio/sqlparser v0.0.0-20231115171017-f4060bcfa6cb // indirect
Expand All @@ -130,6 +131,7 @@ require (
github.com/uber-go/tally/v4 v4.1.17 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/zeebo/errs v1.4.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect
Expand All @@ -144,7 +146,6 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.temporal.io/version v0.3.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/dig v1.18.1 // indirect
go.uber.org/fx v1.23.0 // indirect
Expand Down Expand Up @@ -174,3 +175,5 @@ require (
modernc.org/strutil v1.2.1 // indirect
modernc.org/token v1.1.0 // indirect
)

replace go.temporal.io/api => ../api-go
24 changes: 16 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
Expand Down Expand Up @@ -254,6 +256,10 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
Expand Down Expand Up @@ -320,6 +326,8 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
Expand Down Expand Up @@ -360,8 +368,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/collector/pdata v1.34.0 h1:2vwYftckXe7pWxI9mfSo+tw3wqdGNrYpMbDx/5q6rw8=
go.opentelemetry.io/collector/pdata v1.34.0/go.mod h1:StPHMFkhLBellRWrULq0DNjv4znCDJZP6La4UuC+JHI=
go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA=
go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw=
Expand Down Expand Up @@ -390,16 +402,12 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.temporal.io/api v1.50.0 h1:7s8Cn+fKfNx9G0v2Ge9We6X2WiCA3JvJ9JryeNbx1Bc=
go.temporal.io/api v1.50.0/go.mod h1:iaxoP/9OXMJcQkETTECfwYq4cw/bj4nwov8b3ZLVnXM=
go.temporal.io/sdk v1.35.0 h1:lRNAQ5As9rLgYa7HBvnmKyzxLcdElTuoFJ0FXM/AsLQ=
go.temporal.io/sdk v1.35.0/go.mod h1:1q5MuLc2MEJ4lneZTHJzpVebW2oZnyxoIOWX3oFVebw=
go.temporal.io/sdk/contrib/envconfig v0.1.0 h1:s+G/Ujph+Xl2jzLiiIm2T1vuijDkUL4Kse49dgDVGBE=
go.temporal.io/sdk/contrib/envconfig v0.1.0/go.mod h1:FQEO3C56h9C7M6sDgSanB8HnBTmopw9qgVx4F1S6pJk=
go.temporal.io/server v1.28.0 h1:1rLPrT21ZwpsRjElJqSgThj1NZSAtAPyi8nKX+EAkgo=
go.temporal.io/server v1.28.0/go.mod h1:yri8PdZoAtwI9p65hzvABf11WqXelHl/HabbrnJSu+g=
go.temporal.io/version v0.3.0 h1:dMrei9l9NyHt8nG6EB8vAwDLLTwx2SvRyucCSumAiig=
go.temporal.io/version v0.3.0/go.mod h1:UA9S8/1LaKYae6TyD9NaPMJTZb911JcbqghI2CBSP78=
go.temporal.io/server v1.29.0-135.0.0.20250729005252-42e640c619f8 h1:/TKIH0T3HEicYLAgaNucr6xZPRh9JowLWbIhefRv8C4=
go.temporal.io/server v1.29.0-135.0.0.20250729005252-42e640c619f8/go.mod h1:RGikKuGPvR29D5YkZuJkRI1o9SD+ws6Zx4YsQezMmd0=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
Expand Down Expand Up @@ -569,8 +577,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
25 changes: 12 additions & 13 deletions temporalcli/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ func (c *ClientOptions) dialClient(cctx *CommandContext) (client.Client, error)
return nil, fmt.Errorf("root command unexpectedly missing when dialing client")
}

if c.Identity == "" {
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown-host"
}
username := "unknown-user"
if u, err := user.Current(); err == nil {
username = u.Username
}
c.Identity = "temporal-cli:" + username + "@" + hostname
}

// Load a client config profile
var clientProfile envconfig.ClientConfigProfile
if !cctx.RootCommand.DisableConfigFile || !cctx.RootCommand.DisableConfigEnv {
Expand Down Expand Up @@ -173,7 +185,6 @@ func (c *ClientOptions) dialClient(cctx *CommandContext) (client.Client, error)
return nil, fmt.Errorf("failed creating client options: %w", err)
}
clientOptions.Logger = log.NewStructuredLogger(cctx.Logger)
clientOptions.Identity = clientIdentity()
// We do not put codec on data converter here, it is applied via
// interceptor. Same for failure conversion.
// XXX: If this is altered to be more dynamic, have to also update
Expand Down Expand Up @@ -255,18 +266,6 @@ func payloadCodecInterceptor(
)
}

func clientIdentity() string {
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown-host"
}
username := "unknown-user"
if u, err := user.Current(); err == nil {
username = u.Username
}
return "temporal-cli:" + username + "@" + hostname
}

var DataConverterWithRawValue = converter.NewCompositeDataConverter(
rawValuePayloadConverter{},
converter.NewNilPayloadConverter(),
Expand Down
Loading
Loading