Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
197f3bb
chore: pin alpine docker image to 3.23.4 (#1015)
chaptersix Apr 29, 2026
5973314
Fix help with value flags (#1006)
kevinawoo Apr 30, 2026
13d21da
Fix flakey test by disabling EC2 metadata lookup in test case (#1005)
kevinawoo Apr 30, 2026
039a4d0
Sort output of listing search attributes (#1016)
rodrigozhou May 1, 2026
aaa7221
Refresh Nexus endpoints on read in dev-server (#1025)
stephanos May 15, 2026
9c0abe7
:boom: Workflow delete now prompts for confirmation (#1029)
jiechenz May 19, 2026
edc4c1f
VLN-1350: remediate missing-dependency-cooldown (#1024)
picatz May 21, 2026
3895e2c
Bump actions/upload-artifact from 4 to 7 (#1034)
dependabot[bot] May 21, 2026
21ad19e
chore: add PR template (#1045)
chaptersix May 26, 2026
8ecade9
chore: improve dependabot config (#1044)
chaptersix May 29, 2026
4dbfdbe
Fix task-queue config set help: use real fairness weight flag names (…
jpvotta May 29, 2026
08eb77d
VLN-1354: pin and bump GitHub Actions to latest versions (#1054)
picatz May 29, 2026
9ea8ccd
Add temporal schedule list-matching-times command …
NasitSony May 30, 2026
e7b4e05
Remove time.Sleep() in commands.taskqueue_test.go (#1020)
hussam-salah May 30, 2026
286129f
Add persistence info to start-dev banner (#1033)
SAY-5 May 30, 2026
441d92b
fix: skip CountWorkflow in batch operations when --yes is set (#1012)
bitalizer May 31, 2026
a38aef4
fix: use allow instead of ignore for dependency-type in dependabot co…
chaptersix Jun 2, 2026
fc2ab38
Bump the github-actions group with 2 updates (#1080)
dependabot[bot] Jun 3, 2026
664b7a4
Prefix dev server cluster ID with 'dev-server-' (#1059)
NasitSony Jun 4, 2026
ba84527
feat: auto-generate deprecation warnings from YAML config (#941)
chaptersix Jun 4, 2026
69b2a24
fix: tls is not added for profiles without tls (#1089)
spkane31 Jun 15, 2026
fc67a99
Clarify activity pause timeout behavior (#1099)
JLDLaughlin Jun 25, 2026
7095f12
ci: update API key test endpoint to ca-central-1
chaptersix Jul 2, 2026
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
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: weekly
cooldown:
default-days: 14
allow:
- dependency-type: direct
ignore:
# Temporal dependencies are managed manually to ensure coordinated upgrades across all temporal packages
- dependency-name: "go.temporal.io/*"

- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
cooldown:
default-days: 14
groups:
github-actions:
patterns:
- "*"
74 changes: 74 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
## Related issues

<!-- Closes #123 -->

## What changed?

<!-- Describe what this PR does at a high level. -->

## Checklist

<!-- Your PR should satisfy all these requirements. However, feel free to remove items that don't apply to the PR. Consider giving this checklist to an AI agent before opening your PR. -->

**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

<!-- Edit the code samples below to provide setup and happy-path and error-path testing instructions. -->

**Setup**
```
temporal server start-dev --headless
temporal workflow start \
--type YourWorkflowType \
--task-queue YourTaskQueue \
--workflow-id YourWorkflowId
```

**Happy path**
```
$ temporal <command> \
--flag value
<expected output>
```

**Error case**
```
$ temporal <command> \
--invalid-combination
Error: <expected error message>
$ echo $?
1
```

**Composition** <!-- How might a user combine this with existing commands? e.g. using the output of one command as input to another -->
```
$ temporal <command-one> ...
$ temporal <command-two> --flag <value-from-above>
<expected output>
```
10 changes: 5 additions & 5 deletions .github/workflows/build-and-publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

Expand All @@ -36,7 +36,7 @@ jobs:
env:
INPUT_VERSION: ${{ inputs.version }}
INPUT_TAG_LATEST: ${{ inputs.tag_latest }}
uses: actions/github-script@v8
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const inputVersion = process.env.INPUT_VERSION;
Expand Down Expand Up @@ -82,14 +82,14 @@ jobs:
ls -lh dist/arm64/temporal

- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

- name: Log in to Docker Hub
if: inputs.publish
uses: docker/login-action@v3
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod

Expand Down Expand Up @@ -53,12 +53,12 @@ jobs:
HAS_SECRETS: ${{ secrets.TEMPORAL_CLIENT_CERT != '' && secrets.TEMPORAL_CLIENT_KEY != '' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive

- name: Setup Go
uses: actions/setup-go@v5
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod

Expand All @@ -72,7 +72,7 @@ jobs:
run: gotestsum --junitfile junit-xml/${{matrix.os}}.xml -- ./...

- name: Upload junit-xml artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: junit-xml--${{github.run_id}}--${{github.run_attempt}}--${{matrix.os}}
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- name: Test cloud API key env var
if: ${{ matrix.cloudTestTarget && env.HAS_SECRETS == 'true' }}
env:
TEMPORAL_ADDRESS: us-east-1.aws.api.temporal.io:7233
TEMPORAL_ADDRESS: ca-central-1.aws.api.temporal.io:7233
TEMPORAL_NAMESPACE: ${{ vars.TEMPORAL_CLIENT_NAMESPACE }}
TEMPORAL_API_KEY: ${{ secrets.TEMPORAL_CLIENT_CLOUD_API_KEY }}
shell: bash
Expand All @@ -117,7 +117,7 @@ jobs:
- name: Test cloud API key arg
if: ${{ matrix.cloudTestTarget && env.HAS_SECRETS == 'true' }}
env:
TEMPORAL_ADDRESS: us-east-1.aws.api.temporal.io:7233
TEMPORAL_ADDRESS: ca-central-1.aws.api.temporal.io:7233
TEMPORAL_NAMESPACE: ${{ vars.TEMPORAL_CLIENT_NAMESPACE }}
shell: bash
run: go run ./cmd/temporal workflow list --limit 2 --api-key ${{ secrets.TEMPORAL_CLIENT_CLOUD_API_KEY }}
4 changes: 2 additions & 2 deletions .github/workflows/govulncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ jobs:
name: Govulncheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: go.mod
- uses: temporalio/public-actions/golang/govulncheck@main
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v6
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: "go.mod"
check-latest: true
Expand All @@ -47,7 +47,7 @@ jobs:
run: echo "go=$(go version | cut -d ' ' -f 3)" >> "$GITHUB_OUTPUT"

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
with:
version: v2.12.7
args: release
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/trigger-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

- name: Generate token
id: generate_token
uses: actions/create-github-app-token@v2
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
app-id: ${{ secrets.TEMPORAL_CICD_APP_ID }}
private-key: ${{ secrets.TEMPORAL_CICD_PRIVATE_KEY }}
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/validate-dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Validate Dependabot Config
on:
pull_request:
paths:
- '.github/dependabot.yml'
push:
branches:
- main
paths:
- '.github/dependabot.yml'

permissions:
contents: read

jobs:
validate:
name: Validate Dependabot Config
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.12'

- name: Validate dependabot.yml
run: |
pip install check-jsonschema==0.37.2
check-jsonschema --builtin-schema vendor.dependabot .github/dependabot.yml
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.23
FROM alpine:3.23.4

ARG TARGETARCH

Expand Down
18 changes: 14 additions & 4 deletions internal/commandsgen/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,22 @@ func (c *Command) writeCode(w *codeWriter) error {
} else {
w.writeLinef("s.Command.Args = %v.NoArgs", w.importCobra())
}
if c.IgnoreMissingEnv {
if c.IgnoreMissingEnv || c.Deprecated {
w.writeLinef("s.Command.Annotations = make(map[string]string)")
w.writeLinef("s.Command.Annotations[\"ignoresMissingEnv\"] = \"true\"")
if c.IgnoreMissingEnv {
w.writeLinef("s.Command.Annotations[\"ignoresMissingEnv\"] = \"true\"")
}
}
if c.Deprecated != "" {
w.writeLinef("s.Command.Deprecated = %q", c.Deprecated)
// Note: We intentionally don't set s.Command.Deprecated here because Cobra
// prints deprecation warnings to stdout, which breaks JSON output. Instead,
// the deprecation warning is prepended to the description/help text and
// printed to stderr via the annotation below.
if c.Deprecated {
msg := c.DeprecationMessage
if msg == "" {
msg = defaultDeprecationMessage
}
w.writeLinef("s.Command.Annotations[\"deprecationWarning\"] = %q", msg)
}
// Add subcommands
for _, subCommand := range subCommands {
Expand Down
28 changes: 26 additions & 2 deletions internal/commandsgen/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ type (
Description string `yaml:"description"`
DescriptionPlain string
DescriptionHighlighted string
Deprecated string `yaml:"deprecated"`
HasInit bool `yaml:"has-init"`
Deprecated bool `yaml:"deprecated"`
DeprecationMessage string `yaml:"deprecation-message"`
HasInit bool `yaml:"has-init"`
ExactArgs int `yaml:"exact-args"`
MaximumArgs int `yaml:"maximum-args"`
IgnoreMissingEnv bool `yaml:"ignores-missing-env"`
Expand Down Expand Up @@ -137,6 +138,22 @@ var markdownInlineCodeRegex = regexp.MustCompile("`([^`]+)`")
const ansiReset = "\033[0m"
const ansiBold = "\033[1m"

const defaultDeprecationMessage = "This command is deprecated and will be removed in a later release."

// generateDeprecationBox creates a formatted CAUTION box for deprecated commands.
// If message is empty, uses the default deprecation message.
func generateDeprecationBox(message string) string {
if message == "" {
message = defaultDeprecationMessage
}
content := "CAUTION: " + message
// Calculate box width (content + 2 spaces padding + 2 border chars)
boxWidth := len(content) + 4
border := "+" + strings.Repeat("-", boxWidth-2) + "+"
middle := "| " + content + " |"
return "```\n" + border + "\n" + middle + "\n" + border + "\n```\n\n"
}

func (o OptionSets) processSection() error {
if o.Name == "" {
return fmt.Errorf("missing option set name")
Expand Down Expand Up @@ -172,6 +189,13 @@ func (c *Command) processSection() error {
return fmt.Errorf("missing description for command: %s", c.FullName)
}

// Auto-handle deprecation: prepend warning box to description and append
// "(Deprecated)" to summary.
if c.Deprecated {
c.Description = generateDeprecationBox(c.DeprecationMessage) + c.Description
c.Summary += " (Deprecated)"
}

if len(c.NamePath) == 2 {
if c.Docs.Keywords == nil {
return fmt.Errorf("missing keywords for root command: %s", c.FullName)
Expand Down
48 changes: 48 additions & 0 deletions internal/commandsgen/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package commandsgen

import "testing"

func TestGenerateDeprecationBox(t *testing.T) {
tests := []struct {
name string
message string
expected string
}{
{
name: "default message when empty",
message: "",
expected: "```\n" +
"+-----------------------------------------------------------------------------+\n" +
"| CAUTION: This command is deprecated and will be removed in a later release. |\n" +
"+-----------------------------------------------------------------------------+\n" +
"```\n\n",
},
{
name: "custom message",
message: "Use the new API instead.",
expected: "```\n" +
"+-----------------------------------+\n" +
"| CAUTION: Use the new API instead. |\n" +
"+-----------------------------------+\n" +
"```\n\n",
},
{
name: "short custom message",
message: "Removed.",
expected: "```\n" +
"+-------------------+\n" +
"| CAUTION: Removed. |\n" +
"+-------------------+\n" +
"```\n\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := generateDeprecationBox(tt.message)
if got != tt.expected {
t.Errorf("generateDeprecationBox(%q) =\n%q\nwant:\n%q", tt.message, got, tt.expected)
}
})
}
}
Loading
Loading