Skip to content
Docs

'hyve workflow'

The hyve workflow command group manages automated workflows for task execution on Kubernetes clusters. Workflows are defined in YAML files and can include multiple jobs with dependencies, requirements validation, and step-by-step execution.

Overview

Workflows enable you to automate deployments, configuration management, and operational tasks. Each workflow consists of jobs that contain steps to execute commands, scripts, or predefined actions.

In addition to local workflows in workflows/, templates and cluster definitions can reference workflows hosted in external Git repositories — see Remote Workflow References below.

Remote Workflow References

Templates and cluster definitions can reference workflows from external Git repositories the same way modules are referenced via spec.driver.source. This lets you share common workflows (monitoring setup, backup jobs, etc.) across repositories without copying files.

Source format

github.com/<org>/<repo>[//<path>][@<version>]
ComponentRequiredDescription
github.com/<org>/<repo>YesThe repository hosting the workflow file(s)
//<path>NoPath within the repository — see Path resolution below
@<version>NoA tag, branch, or commit SHA. Omit to track the latest commit on the default branch — Hyve resolves it once and locks the SHA, the same way an unversioned hyve module add works.

Path resolution

File vs. directory is explicit, never inferred from what happens to exist:

Path formResolves toInstalls
path/to/file.yaml (.yaml/.yml suffix)A single fileOne workflow
path/to/dir/ (trailing /)A directoryEvery *.yaml file found directly inside it (shallow — not recursive)
(omitted)Repository rootEvery *.yaml file at the repo root (shallow)
anything elseError: add a .yaml/.yml extension for a file, or a trailing / for a directory

A path: field is equivalent to the inline //path form — use whichever reads more clearly at the call site. If both are supplied, path: wins.

Referencing a remote workflow

# templates/prod.yaml or clusters/production.yaml
spec:
workflows:
onCreate:
# local (unchanged)
- pre-flight-checks
# remote — pinned to a tag
- source: github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0
# remote — no version; Hyve resolves latest and locks the SHA
- source: github.com/myorg/shared-workflows//setup-monitoring.yaml
# remote — path field instead of inline "//"
- source: github.com/myorg/shared-workflows
path: deploy-base-apps.yaml

Name resolution for hyve workflow run

When you run hyve workflow run <name> with a bare name (not a full source string):

  1. Look for an exact match in the local workflows/ directory.
  2. If not found, search locked remote workflows in hyve.lock by name.
  3. No match in either place → error, suggesting hyve workflow install or the full source string.
  4. More than one match among locked remote entries → error listing every matching source; re-run with the full source string to disambiguate.

Running a full source string that isn’t installed fetches, verifies, and executes it in one step, without writing to hyve.lock — the same “not saved unless you ask” behavior as npx vs. npm install.

Commands

hyve workflow create

Create a new workflow from a template or file.

Terminal window
hyve workflow create [workflow-name] [flags]
workflow-name string

Name of the workflow to create (required when using —template)

--template, -t boolean default: false

Create from default template

--description, -d string

Workflow description

--file, -f string

Create workflow from existing YAML file

Examples:

Terminal window
# Create from template
hyve workflow create deploy-app --template --description "Deploy application to cluster"
# Create from existing file
hyve workflow create my-workflow --file ./workflow.yaml

Output:

✅ Created workflow template 'deploy-app'
📁 Location: /Users/username/.hyve/repositories/production/workflows/deploy-app.yaml
🔧 Edit the file to customize your workflow

hyve workflow list

List all available workflows in the current repository.

Terminal window
hyve workflow list

Example:

Terminal window
hyve workflow list

Output:

📋 Workflows in repository (4):
NAME DESCRIPTION JOBS CREATED
deploy-app Deploy application to cluster 2 2024-01-15
setup-monitoring Install Prometheus and Grafana 3 2024-01-14
backup-etcd Backup etcd database 1 2024-01-13
update-certs Update TLS certificates 2 2024-01-12
💡 Commands:
hyve workflow show <name> # Show workflow details
hyve workflow run <name> # Run workflow
hyve workflow delete <name> # Delete workflow

hyve workflow show

Display detailed information about a specific workflow.

Terminal window
hyve workflow show [workflow-name]
workflow-name string required

Name of the workflow to display

Example:

Terminal window
hyve workflow show deploy-app

Output:

📋 Workflow: deploy-app
📝 Description: Deploy application to production cluster
📅 Created: 2024-01-15 10:30:45
📅 Updated: 2024-01-15 14:20:10
🏷️ Labels:
environment: production
team: platform
🌍 Environment Variables:
APP_VERSION: v1.2.3
NAMESPACE: production
🚀 Jobs (2):
1. pre-deployment
📝 Pre-deployment checks and setup
📋 Steps (2):
1. check-namespace
🔧 Command: kubectl get namespace production
2. create-secrets
🔧 Command: kubectl apply -f secrets.yaml
2. deploy
📝 Deploy application manifests
🔗 Depends on: pre-deployment
📋 Steps (3):
1. apply-deployment
⚡ Action: kubectl-apply
2. wait-ready
🔧 Command: kubectl rollout status deployment/app
3. verify
📜 Script: verify-deployment.sh
💡 Run with: hyve workflow run deploy-app

hyve workflow run

Execute a workflow on a cluster. Accepts a local workflow name or a remote source string.

Terminal window
hyve workflow run [workflow-name-or-source] [flags]
workflow-name-or-source string required

A local workflow name (resolved against workflows/, then against hyve.lock by name), or a full remote source string (github.com/org/repo//path.yaml@version). Any / in the argument is treated as a source string — local workflow names can never contain one.

--cluster, -c string

Cluster to run workflow on. If not specified, runs locally without cluster context.

--logs, -l boolean default: true

Show execution logs

--output, -o boolean default: false

Show step outputs

--path string

Override/supply the source’s path component for a remote source string, equivalent to path: in YAML. Ignored for local workflow names.

--set string[]

Set a workflow input variable in KEY=VALUE format. Repeatable. Use this to supply values declared in the workflow’s spec.inputs section when running ad-hoc (outside a cluster lifecycle). Values set here take highest priority and override any automatically derived variables.

Terminal window
hyve workflow run provision-network \
--set HYVE_CLUSTER_NAME=my-cluster \
--set HYVE_CLUSTER_REGION=eastus

Examples:

Terminal window
# Run on specific cluster
hyve workflow run deploy-app --cluster production
# Run locally without cluster context
hyve workflow run local-setup
# Run with detailed output
hyve workflow run deploy-app --cluster staging --output
# Supply required inputs for an infrastructure workflow
hyve workflow run provision-network \
--set HYVE_CLUSTER_NAME=my-cluster \
--set HYVE_CLUSTER_REGION=eastus \
--set HYVE_CLUSTER_PROVIDER=azure
# Run a workflow already locked in hyve.lock, by name
hyve workflow run setup-monitoring
# Run a remote workflow by full source string (fetches if not installed,
# does not write to hyve.lock)
hyve workflow run github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0
# Same, using --path instead of an inline "//path"
hyve workflow run github.com/myorg/shared-workflows --path setup-monitoring.yaml

Output:

🚀 Starting workflow 'deploy-app'
🎯 Target cluster: production
[10:30:45][INFO][pre-deployment] Starting job 'pre-deployment'
[10:30:46][INFO][pre-deployment][check-namespace] Executing step 'check-namespace'
[10:30:47][INFO][pre-deployment][check-namespace] Step completed successfully
[10:30:47][INFO][pre-deployment][create-secrets] Executing step 'create-secrets'
[10:30:48][INFO][pre-deployment][create-secrets] Step completed successfully
[10:30:48][INFO][pre-deployment] Job completed successfully
[10:30:48][INFO][deploy] Starting job 'deploy'
[10:30:49][INFO][deploy][apply-deployment] Executing step 'apply-deployment'
[10:30:51][INFO][deploy][apply-deployment] Step completed successfully
[10:30:51][INFO][deploy][wait-ready] Executing step 'wait-ready'
[10:31:15][INFO][deploy][wait-ready] Step completed successfully
[10:31:15][INFO][deploy][verify] Executing step 'verify'
[10:31:16][INFO][deploy][verify] Step completed successfully
[10:31:16][INFO][deploy] Job completed successfully
✅ Workflow 'deploy-app' completed successfully
⏱️ Duration: 31.2s
📊 Execution Summary:
════════════════════════════════════════════════════════════
🆔 Execution ID: exec-a1b2c3d4
🕐 Start Time: 2024-01-15 10:30:45
🕐 End Time: 2024-01-15 10:31:16
⏱️ Duration: 31.2s
📊 Status: completed
📋 Job Results:
JOB STATUS DURATION STEPS
pre-deployment completed 3.2s 2/2
deploy completed 28.0s 3/3

hyve workflow install

Resolve every remote workflow reference found in templates and cluster definitions into hyve.lock.

Terminal window
hyve workflow install

Scans all template YAMLs in templates/ and all cluster YAMLs in clusters/, finds every {source, path} workflow reference, resolves and content-hashes each file, and writes any new or changed entries to hyve.lock. Entries whose content hasn’t changed are left untouched, so re-running with nothing new is a no-op — no empty commit.

Terminal window
# Run after cloning a repository, or after adding a new remote workflow reference
hyve workflow install

Output:

Resolving github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0 ...
Locked github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0 (name=setup-monitoring, sha256=abc123...)
✅ hyve.lock updated

hyve workflow update

Re-resolve a remote workflow reference to its latest version and refresh its hyve.lock entry (or entries, for a directory source).

Terminal window
hyve workflow update <source> [flags]
source string required

Workflow source, e.g. github.com/myorg/shared-workflows//setup-monitoring.yaml. Unlike hyve module update, version is part of the source string — there’s no separate version argument.

--path string

Supply or override the source’s path component, equivalent to path: in YAML.

Example:

Terminal window
hyve workflow update github.com/myorg/shared-workflows//setup-monitoring.yaml
# Resolves latest version, updates hyve.lock

hyve workflow verify

Verify that every workflow locked in hyve.lock still matches its recorded SHA256 in the local cache.

Terminal window
hyve workflow verify

Output (success):

✅ github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0 (name=setup-monitoring)
✅ github.com/myorg/shared-workflows//deploy-base-apps.yaml (name=deploy-base-apps)
✅ All locked workflows verified

Output (failure):

❌ github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0 (name=setup-monitoring): not cached — run `hyve workflow install`
1 workflow(s) failed verification

hyve workflow delete

Remove a workflow definition from the repository.

Terminal window
hyve workflow delete [workflow-name] [flags]
workflow-name string required

Name of the workflow to delete

--force, -f boolean default: false

Delete without confirmation

Example:

Terminal window
# Delete with confirmation
hyve workflow delete old-workflow
# Force delete
hyve workflow delete old-workflow --force

Output:

Are you sure you want to delete workflow 'old-workflow'? (y/N): y
✅ Deleted workflow 'old-workflow'

hyve workflow validate

Validate the syntax and structure of a workflow definition.

Terminal window
hyve workflow validate [workflow-name]
workflow-name string required

Name of the workflow to validate

Example:

Terminal window
hyve workflow validate deploy-app

Output (Success):

🔍 Validating workflow 'deploy-app'...
✅ Workflow is valid
📋 Jobs: 2
📋 Total steps: 5
✨ No warnings

Output (Errors):

🔍 Validating workflow 'broken-workflow'...
❌ Validation Failed
Errors:
• Job 'deploy' has no steps
• Job 'cleanup' depends on non-existent job 'backup'
• Job 'build', step 'compile' has no command, script, or action
• Circular dependency detected in job dependencies
⚠️ Warnings:
• Job 'test', step 'run-tests': unknown action 'custom-action'

Validation Checks:

  • Required fields (apiVersion, kind, metadata.name)
  • Job names are unique
  • Jobs have steps
  • Dependencies reference existing jobs
  • No circular dependencies
  • Steps have execution method (command, script, or action)
  • Action parameters are valid

Workflow Definition Format

Workflows are defined in YAML format and stored in the workflows/ directory.

Basic Structure

apiVersion: v1
kind: Workflow
metadata:
name: deploy-app
description: Deploy application to cluster
labels:
environment: production
team: platform
created: "2024-01-15T10:30:45Z"
updated: "2024-01-15T14:20:10Z"
spec:
env:
APP_VERSION: v1.2.3
NAMESPACE: production
jobs:
- name: pre-deployment
description: Pre-deployment checks
steps:
- name: check-namespace
command: kubectl get namespace ${NAMESPACE}
- name: deploy
description: Deploy application
dependsOn:
- pre-deployment
steps:
- name: apply-manifests
action: kubectl-apply
with:
file: manifests/

Field Reference

apiVersion string required

API version of the workflow definition (currently v1)

kind string required

Resource kind (must be Workflow)

metadata.name string required

Unique name for the workflow

metadata.description string

Human-readable description of the workflow

metadata.labels object

Key-value pairs for organizing workflows

spec.env object

Environment variables available to all jobs

spec.jobs array required

Array of jobs to execute


Job Fields

name string required

Unique name for the job

description string

Description of what the job does

dependsOn string[]

Names of jobs that must complete before this job runs

cluster string

Cluster context to use for this job (overrides workflow-level cluster)

if string

Conditional expression to determine if job should run

steps array required

Array of steps to execute in order


Step Fields

name string required

Name of the step

command string

Shell command to execute (mutually exclusive with script and action)

script string

Path to script file to execute (mutually exclusive with command and action)

action string

Predefined action to run (mutually exclusive with command and script)

with object

Parameters for the action

env object

Environment variables for this step

continueOnError boolean default: false

Continue workflow execution if this step fails


Built-in Actions

kubectl-apply

Apply Kubernetes manifests from a file or directory.

- name: apply-manifests
action: kubectl-apply
with:
file: manifests/deployment.yaml

Parameters:

  • file (required): Path to manifest file or directory

kubectl-delete

Delete Kubernetes resources from a file or directory.

- name: delete-old-resources
action: kubectl-delete
with:
file: old-manifests/

Parameters:

  • file (required): Path to manifest file or directory

Variable Substitution

Workflows support variable substitution using shell syntax:

spec:
env:
NAMESPACE: production
APP_VERSION: v1.2.3
jobs:
- name: deploy
steps:
- name: deploy-app
command: kubectl apply -f manifests/${APP_VERSION}/ -n ${NAMESPACE}

Variables are resolved from:

  1. Step-level environment variables
  2. Job-level environment variables
  3. Workflow-level environment variables
  4. System environment variables

Requirements Validation

Workflows can specify requirements that are validated before execution:

apiVersion: v1
kind: Workflow
metadata:
name: deploy-with-requirements
spec:
requirements:
tools:
- name: kubectl
version: "1.28"
- name: helm
version: "3.12"
secrets:
- name: DOCKER_TOKEN
provider: docker
jobs:
# ... jobs here
requirements.tools array

Required CLI tools with optional version constraints

requirements.secrets array

Required secrets that must be available


Job Dependencies

Jobs can depend on other jobs to enforce execution order:

spec:
jobs:
- name: build
steps:
- name: compile
command: go build -o app
- name: test
dependsOn:
- build
steps:
- name: run-tests
command: go test ./...
- name: deploy
dependsOn:
- build
- test
steps:
- name: deploy-app
command: kubectl apply -f deployment.yaml

Execution Order:

  1. build runs first (no dependencies)
  2. test runs after build completes
  3. deploy runs after both build and test complete

Conditional Execution

Jobs can include conditional expressions:

- name: deploy-to-production
if: ${{ env.ENVIRONMENT == 'production' }}
steps:
- name: deploy
command: kubectl apply -f prod-manifests/

Common Use Cases

Application Deployment

apiVersion: v1
kind: Workflow
metadata:
name: deploy-app
description: Deploy application with rolling update
spec:
env:
NAMESPACE: production
IMAGE_TAG: latest
jobs:
- name: pre-check
steps:
- name: verify-namespace
command: kubectl get namespace ${NAMESPACE}
- name: check-cluster
command: kubectl cluster-info
- name: deploy
dependsOn:
- pre-check
steps:
- name: update-deployment
command: |
kubectl set image deployment/app \
app=myapp:${IMAGE_TAG} \
-n ${NAMESPACE}
- name: wait-rollout
command: kubectl rollout status deployment/app -n ${NAMESPACE}
- name: verify
dependsOn:
- deploy
steps:
- name: check-pods
command: kubectl get pods -n ${NAMESPACE} -l app=myapp
- name: test-endpoint
command: curl https://app.example.com/health

Setup Monitoring Stack

apiVersion: v1
kind: Workflow
metadata:
name: setup-monitoring
description: Install Prometheus and Grafana
spec:
requirements:
tools:
- name: helm
version: "3.12"
jobs:
- name: install-prometheus
steps:
- name: add-repo
command: helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
- name: update-repo
command: helm repo update
- name: install
command: |
helm install prometheus prometheus-community/kube-prometheus-stack \
-n monitoring --create-namespace
- name: install-grafana
dependsOn:
- install-prometheus
steps:
- name: install
command: |
helm install grafana grafana/grafana \
-n monitoring \
--set adminPassword=admin123
- name: expose-services
dependsOn:
- install-grafana
steps:
- name: apply-ingress
action: kubectl-apply
with:
file: monitoring-ingress.yaml

Database Backup

apiVersion: v1
kind: Workflow
metadata:
name: backup-database
description: Backup PostgreSQL database
spec:
env:
DB_NAME: production
BACKUP_BUCKET: s3://backups
jobs:
- name: backup
steps:
- name: create-backup
command: |
kubectl exec -n ${NAMESPACE} postgres-0 -- \
pg_dump ${DB_NAME} > backup-$(date +%Y%m%d).sql
- name: upload-backup
command: |
aws s3 cp backup-$(date +%Y%m%d).sql ${BACKUP_BUCKET}/
- name: cleanup
command: rm backup-$(date +%Y%m%d).sql
continueOnError: true

Storage

Workflow definitions are stored in:

~/.hyve/repositories/<repository-name>/
└── workflows/
├── deploy-app.yaml
├── setup-monitoring.yaml
└── backup-database.yaml

Remote workflows resolved via hyve workflow install/run are cached separately, keyed by content hash, at ~/.hyve/workflow-cache/<sha256> — they are never written into the local workflows/ directory.


hyve.lock format

Remote workflow references are locked in hyve.lock, in a workflows map alongside the existing modules map:

version: 1
modules:
github.com/hyve-modules/civo@v1.0.0:
source: github.com/hyve-modules/civo@v1.0.0
resolved: https://github.com/hyve-modules/civo/archive/v1.0.0.tar.gz
sha256: "abc123..."
workflows:
github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0:
name: setup-monitoring
source: github.com/myorg/shared-workflows//setup-monitoring.yaml@v1.2.0
resolved: https://raw.githubusercontent.com/myorg/shared-workflows/v1.2.0/setup-monitoring.yaml
sha256: "def456..."

The workflows key is entirely absent from hyve.lock for repositories that only use local workflows — there’s nothing to opt into.


  • hyve module - Modules share hyve.lock with remote workflows
  • hyve cluster - Manage clusters where workflows run, including auth/deauth for cluster access
  • hyve template - Templates can include workflows