Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6f41c80
chore: regenerate examples (#3043)
github-actions[bot] Feb 17, 2026
77bf985
chore(deps): bump github.com/mattn/go-runewidth from 0.0.19 to 0.0.20…
dependabot[bot] Feb 18, 2026
238eda7
chore(deps): bump google.golang.org/api from 0.266.0 to 0.267.0 (#3050)
dependabot[bot] Feb 18, 2026
e13721b
chore(deps): bump hatchet-sdk in /examples/python/quickstart (#3051)
dependabot[bot] Feb 18, 2026
73ef474
feat: new search bar component (#2909)
abelanger5 Feb 18, 2026
b2eb5c0
Fix--durable-slot-acquisition (#3048)
grutt Feb 18, 2026
edf1b79
fix: pin redocly version (#3053)
grutt Feb 18, 2026
981c004
fix: restore ctx.taskRunId (#3056)
grutt Feb 18, 2026
1361047
Add upgrading and downgrading guide to self-hosting docs (#3044)
mnafees Feb 19, 2026
0cce1cf
Revert: Cancellation token Python changes (#3061)
mrkaye97 Feb 19, 2026
8c9fa7f
feat: add migration for worker slot config index (#3062)
grutt Feb 19, 2026
9c13ce9
chore(deps): bump hatchet-sdk in /examples/python/quickstart (#3063)
dependabot[bot] Feb 20, 2026
899448d
feat(cli): runs commands (#3058)
abelanger5 Feb 20, 2026
12c5f4c
fix: input in transformer (#3070)
mrkaye97 Feb 21, 2026
30c6209
Fix: Expand long logs on click instead of on hover (#3069)
mrkaye97 Feb 21, 2026
e0f9ae0
feat: shuffle...
grutt Feb 21, 2026
dd48ee1
feat(agents): add new agent instruction tools (#3059)
grutt Feb 21, 2026
4a14588
feat: more shuffles
grutt Feb 21, 2026
8d79c5e
wip: durable structure
grutt Feb 21, 2026
2427a3a
feat: more shuffle
grutt Feb 21, 2026
585774f
feat: simplify running guide
grutt Feb 21, 2026
99fe39f
fix: search
grutt Feb 21, 2026
4fc5904
Merge branch 'main' into gr/docs-overhaul
grutt Feb 21, 2026
61dd481
feat: more shuffles
grutt Feb 21, 2026
4704fef
fix: nav
grutt Feb 21, 2026
d92529e
fix: organiztion
grutt Feb 21, 2026
2a4beb7
fix: copy button
grutt Feb 21, 2026
7b0997c
feat: concepts
grutt Feb 21, 2026
ce134b6
evaluating pages
grutt Feb 21, 2026
bb81357
essentials
grutt Feb 21, 2026
a317722
feat: task concepts
grutt Feb 21, 2026
6b97ea2
feat: dupe some content
grutt Feb 22, 2026
4b8237d
feat: improvements
grutt Feb 22, 2026
8cad351
feat improve task page
grutt Feb 22, 2026
aafd13a
feat: reorg durable
grutt Feb 22, 2026
9146590
simplify slots
grutt Feb 22, 2026
e6f92a4
improved durable pages
grutt Feb 22, 2026
6be5099
simplify essentials
grutt Feb 22, 2026
6d8cdef
chore: lint
grutt Feb 22, 2026
9da3a95
fix: build
grutt Feb 22, 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
28 changes: 24 additions & 4 deletions .github/workflows/cli-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,33 @@ name: cli-e2e-tests
on:
pull_request:
paths:
- ".github/workflows/cli-e2e-tests.yml"
- "cmd/hatchet-cli/cli/templates/**"
- "cmd/hatchet-cli/cli/quickstart.go"
- "cmd/hatchet-cli/cli/internal/templater/**"
- "cmd/hatchet-cli/cli/quickstart_e2e_test.go"
- ".github/workflows/test-templates.yml"
- "cmd/hatchet-cli/cli/*.go"
- "cmd/hatchet-cli/cli/*_e2e_test.go"
- "cmd/hatchet-cli/cli/tui/**"
- "cmd/hatchet-cli/cli/testharness/**"
push:
branches:
- main
paths:
- ".github/workflows/cli-e2e-tests.yml"
- "cmd/hatchet-cli/cli/templates/**"
- "cmd/hatchet-cli/cli/quickstart.go"
- "cmd/hatchet-cli/cli/internal/templater/**"
- "cmd/hatchet-cli/cli/quickstart_e2e_test.go"
- "cmd/hatchet-cli/cli/*.go"
- "cmd/hatchet-cli/cli/*_e2e_test.go"
- "cmd/hatchet-cli/cli/tui/**"
- "cmd/hatchet-cli/cli/testharness/**"

jobs:
test-templates:
runs-on: ubicloud-standard-4
timeout-minutes: 15
timeout-minutes: 30

steps:
- name: Checkout code
Expand All @@ -34,7 +43,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.14"
python-version: "3.13" # pinned because of poetry dependency issue

- name: Set up Node.js
uses: actions/setup-node@v6
Expand All @@ -56,6 +65,9 @@ jobs:
- name: Install Bun
uses: oven-sh/setup-bun@v2

- name: Install tmux
run: sudo apt-get install -y tmux

- name: Build CLI
run: |
cd cmd/hatchet-cli
Expand All @@ -79,9 +91,17 @@ jobs:
cd cmd/hatchet-cli/cli
go test -tags e2e_cli -run TestQuickstartTemplates -v -timeout 15m
env:
# Ensure tests don't try to interact with stdin
CI: true

- name: Run resource E2E tests
run: |
cd cmd/hatchet-cli/cli
go test -tags e2e_cli \
-run 'Test(Runs|Workflows|Worker|RateLimits|Scheduled|Cron|Webhooks)' \
-v -timeout 10m
env:
HATCHET_CLI_PROFILE: local

- name: Show server logs on failure
if: failure()
run: |
Expand Down
25 changes: 19 additions & 6 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,21 @@ tasks:
fmt-docs:
dir: frontend/docs
cmd: pnpm run prettier:fix && pnpm run prettier:check
sync-agent-instructions:
desc: Sync agent-instructions MDX files into hatchet-cli skill-assets references
cmds:
- |
src="frontend/docs/pages/agent-instructions"
dest="cmd/hatchet-cli/cli/skill-assets/hatchet-cli/references"
for f in "$src"/*.mdx; do
name=$(basename "$f" .mdx)
cp "$f" "$dest/$name.md"
done

pre:
aliases: [fmt]
cmds:
- task: sync-agent-instructions
- task: fmt-go
- task: fmt-app
- task: fmt-docs
Expand Down Expand Up @@ -160,11 +172,12 @@ tasks:
- task: generate-api-server
- task: generate-api-client
generate-docs:
deps: [venv]
dir: frontend/snippets
cmds:
- 'source {{.ROOT_DIR}}/.venv/bin/activate && python generate.py'
- task: fmt
deps: [venv]
dir: frontend/snippets
cmds:
- "source {{.ROOT_DIR}}/.venv/bin/activate && python generate.py"
- task: fmt
- task: sync-agent-instructions
generate-certs:
cmds:
- bash ./hack/dev/generate-x509-certs.sh ./hack/dev/certs
Expand Down Expand Up @@ -228,7 +241,7 @@ tasks:
cmd: source .venv/bin/activate && pip install pre-commit && pre-commit install
pre-commit-run:
deps: [venv]
cmd: 'source .venv/bin/activate && pre-commit run --all-files || pre-commit run --all-files'
cmd: "source .venv/bin/activate && pre-commit run --all-files || pre-commit run --all-files"
docs:
cmds:
- |
Expand Down
6 changes: 6 additions & 0 deletions api/v1/server/oas/transformers/workflow_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ func ToCronWorkflowsFromSQLC(cron *sqlcv1.ListCronWorkflowsRow) *gen.CronWorkflo
}
}

input := make(map[string]interface{})
if cron.Input != nil {
json.Unmarshal(cron.Input, &input) //nolint:errcheck
}

res := &gen.CronWorkflows{
Metadata: *toAPIMetadata(cron.ID_2, cron.CreatedAt_2.Time, cron.UpdatedAt_2.Time),
WorkflowVersionId: cron.WorkflowVersionId.String(),
Expand All @@ -78,6 +83,7 @@ func ToCronWorkflowsFromSQLC(cron *sqlcv1.ListCronWorkflowsRow) *gen.CronWorkflo
Enabled: cron.Enabled,
Method: gen.CronWorkflowsMethod(cron.Method),
Priority: &cron.Priority,
Input: &input,
}

return res
Expand Down
24 changes: 8 additions & 16 deletions build/package/servers.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,18 @@ COPY /cmd ./cmd

RUN go generate ./...

# OpenAPI bundle environment
# -------------------------
FROM node:22-alpine as build-openapi
# OpenAPI bundle environment (uses openapi-core only to avoid Redoc/React/styled-components)
# ----------------------------------------------------------------------------------------
FROM node:22-alpine AS build-openapi
WORKDIR /openapi

COPY /api-contracts/openapi ./openapi
COPY /hack/oas/bundle-openapi.mjs ./bundle-openapi.mjs

RUN echo '{ \
"name": "hack-for-redocly-cli-bug", \
"version": "1.0.0", \
"dependencies": { \
"@redocly/cli": "latest" \
}, \
"overrides": { \
"mobx-react": "9.2.0" \
} \
}' > package.json && \
npm install -g npm@8.1 @redocly/cli@latest && \
npx @redocly/cli@latest bundle ./openapi/openapi.yaml --output ./bin/oas/openapi.yaml --ext yaml && \
rm package.json
RUN echo '{ "type": "module", "dependencies": { "@redocly/openapi-core": "2.14.7", "yaml": "2.7.0" } }' > package.json && \
npm install && \
node bundle-openapi.mjs && \
rm -f package.json package-lock.json bundle-openapi.mjs

# Go build environment
# --------------------
Expand Down
62 changes: 59 additions & 3 deletions cmd/hatchet-cli/cli/client.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package cli

import (
"github.com/google/uuid"
openapi_types "github.com/oapi-codegen/runtime/types"
"github.com/rs/zerolog"
"github.com/spf13/cobra"

"github.com/hatchet-dev/hatchet/pkg/client"
"github.com/hatchet-dev/hatchet/cmd/hatchet-cli/cli/internal/config/cli"
"github.com/hatchet-dev/hatchet/pkg/client" //nolint:staticcheck
profileconfig "github.com/hatchet-dev/hatchet/pkg/config/cli"
clientconfig "github.com/hatchet-dev/hatchet/pkg/config/client"
"github.com/hatchet-dev/hatchet/pkg/config/shared"
)

// NewClientFromProfile creates a new Hatchet client from a profile configuration.
// It properly handles TLS settings, host/port, and authentication based on the profile.
func NewClientFromProfile(profile *profileconfig.Profile, logger *zerolog.Logger) (client.Client, error) {
func NewClientFromProfile(profile *profileconfig.Profile, logger *zerolog.Logger) (client.Client, error) { //nolint:staticcheck
// Construct a ClientConfigFile from the profile
configFile := &clientconfig.ClientConfigFile{
TenantId: profile.TenantId,
Expand All @@ -26,5 +30,57 @@ func NewClientFromProfile(profile *profileconfig.Profile, logger *zerolog.Logger
}

// Create client with the config file and logger
return client.NewFromConfigFile(configFile, client.WithLogger(logger))
return client.NewFromConfigFile(configFile, client.WithLogger(logger)) //nolint:staticcheck
}

// clientCmdConfig holds CLI flag values used to create a Hatchet client.
type clientCmdConfig struct {
Profile string
}

// readClientCmdConfig reads client-related flags from a command into a config struct.
func readClientCmdConfig(cmd *cobra.Command) clientCmdConfig {
profile, _ := cmd.Flags().GetString("profile")
return clientCmdConfig{Profile: profile}
}

// clientFromCmd selects a profile and returns a Hatchet client.
// The profile is read from the --profile flag if present, otherwise selected interactively.
func clientFromCmd(cmd *cobra.Command) (string, client.Client) { //nolint:staticcheck
cfg := readClientCmdConfig(cmd)

var selectedProfile string
if cfg.Profile != "" {
selectedProfile = cfg.Profile
} else {
selectedProfile = selectProfileForm(true)
if selectedProfile == "" {
selectedProfile = handleNoProfiles(cmd)
if selectedProfile == "" {
cli.Logger.Fatal("no profile selected or created")
}
}
}

profile, err := cli.GetProfile(selectedProfile)
if err != nil {
cli.Logger.Fatalf("could not get profile '%s': %v", selectedProfile, err)
}

nopLogger := zerolog.Nop()
hatchetClient, err := NewClientFromProfile(profile, &nopLogger)
if err != nil {
cli.Logger.Fatalf("could not create Hatchet client: %v", err)
}

return selectedProfile, hatchetClient
}

// clientTenantUUID parses and returns the tenant UUID from the client configuration.
func clientTenantUUID(hatchetClient client.Client) openapi_types.UUID { //nolint:staticcheck
parsed, err := uuid.Parse(hatchetClient.TenantId())
if err != nil {
cli.Logger.Fatalf("invalid tenant ID: %v", err)
}
return parsed
}
Loading
Loading