Workflows and Sources¶
These two sections of scripthut.yaml configure task generators — mechanisms for telling ScriptHut "here's a way to get a list of tasks to run".
- Workflows — a fixed SSH command (optionally inside a cloned git repo) that prints task JSON
- Sources — a git repo or backend filesystem path containing one or more workflow JSON files, discovered via glob
The legacy
projects:section was removed in scripthut 0.6.0. Convert any project entry to an equivalentsources:entry (typepathfor a directory on a backend, typegitfor a remote repo).
See Task JSON Format for the JSON shape every generator must emit.
Workflows¶
Workflows are the primary mechanism for submitting batch jobs. A workflow defines an SSH command that runs on a backend and returns a JSON list of tasks.
Basic Workflow¶
workflows:
- name: ml-training
backend: hpc-cluster
command: "python /shared/scripts/get_training_tasks.py"
max_concurrent: 5
description: "ML model training pipeline"
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique identifier for this workflow. Shown in the UI. |
backend |
string | required | Name of a backend defined in the backends section. |
command |
string | required | Shell command executed via SSH that must print JSON to stdout. |
max_concurrent |
integer | null |
Max concurrent tasks per run. If null, only the backend-level limit applies. |
description |
string | "" |
Human-readable description shown in the UI. |
git |
object | null |
Optional git repository to clone on the backend before running the command. |
env |
list | [] |
Workflow-level env rules applied to every task in the workflow. See Environments. |
env_groups |
object | {} |
Named, reusable env-rule lists local to this workflow (also visible to its tasks). |
Git Workflows¶
Git workflows clone a repository on the remote backend before executing the command. The command runs inside the cloned directory. This is useful when your task generator script lives in a repository.
workflows:
- name: ml-training-git
backend: hpc-cluster
git:
repo: git@github.com:your-org/ml-pipelines.git
branch: main
deploy_key: ~/.ssh/ml-deploy-key
clone_dir: ~/scripthut-repos
postclone: "rm -rf large_files"
command: "python get_tasks.py"
max_concurrent: 5
description: "ML training from git repo"
Git Config Fields:
| Field | Type | Default | Description |
|---|---|---|---|
repo |
string | required | Git repository URL. SSH format recommended. |
branch |
string | "main" |
Branch to clone. |
deploy_key |
path | null |
Path to deploy key on the local machine. It is uploaded to the backend temporarily during the clone operation. |
clone_dir |
string | "~/scripthut-repos" |
Parent directory on the backend. The repo is cloned into <clone_dir>/<commit_hash>/. |
postclone |
string | null |
Shell command to run in the clone directory after cloning (e.g., to remove large files or install dependencies). |
When using a git workflow:
- The
commandruns with the clone directory as its working directory. - Task
working_dirvalues using~or relative paths are resolved relative to the clone directory. - Git metadata is injected as environment variables into every task (see Environments →
SCRIPTHUT_*runtime seed).
Sources¶
Sources are git repositories or backend filesystem paths containing workflow definitions. ScriptHut discovers workflow JSON files using the workflows_glob pattern (default: .hut/workflows/*.json). You can use glob wildcards like **/*.hut.json to match files recursively across any subdirectory. Each matched JSON file appears as a triggerable workflow on the Sources page.
For git sources, the repository is cloned locally for workflow discovery, and also cloned on the backend when a workflow is triggered (tasks run inside the cloned directory, just like git-based workflows).
For git sources with local_path — a repo already on the machine running ScriptHut — neither clone happens: workflows are read from that working tree, and the commit is pushed to the backend over the SSH connection ScriptHut already holds. No deploy key, no git remote, no network. See Local git source.
For path sources, workflows are discovered via SSH on the backend, and tasks run with working_dir resolved relative to the source path.
Git Source¶
sources:
- name: ml-jobs
type: git
url: git@github.com:your-org/ml-pipelines.git
branch: main
deploy_key: ~/.ssh/ml-jobs-deploy-key
backend: hpc-cluster
# workflows_glob: "**/*.hut.json" # default: .hut/workflows/*.json
# clone_dir: ~/scripthut-repos # default
# postclone: "rm -rf large_files" # optional
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique identifier for this source. |
type |
string | required | Must be "git". |
url |
string | required unless local_path is set |
Git repository URL. SSH format recommended. |
branch |
string | "main" |
Branch to track. |
deploy_key |
path | null |
Path to deploy key for this repository. |
backend |
string | required | Backend to submit discovered workflow tasks to. |
workflows_glob |
string | ".hut/workflows/*.json" |
Glob pattern to find workflow JSON files (supports ** for recursive matching). |
clone_dir |
string | "~/scripthut-repos" |
Parent directory on the backend. The repo is cloned into <clone_dir>/<commit_hash>/. |
postclone |
string | null |
Shell command to run in the clone directory after cloning. |
Local Git Source¶
When the repo is already on the machine running ScriptHut, set local_path instead of (or alongside) url. ScriptHut then reads that working tree directly and pushes the commit to the backend itself:
sources:
- name: my-project
type: git
local_path: ~/git/my-project
branch: main
# url: git@github.com:me/my-project.git # optional; only coding agents need it
# clone_dir: ~/scripthut-repos
# postclone: "uv sync"
local_path replaces deploy_key rather than complementing it — there is no remote to authenticate to. A source must declare url or local_path (or both); declaring neither is a config error.
How the code reaches the backend. On submit, ScriptHut resolves the branch tip locally, ensures a shared bare mirror at <clone_dir>/.mirror.git on the backend, pushes that commit to it as refs/heads/sh-<commit>, then clones that ref into <clone_dir>/<commit>/ — the same content-addressed layout a url source uses, so re-running a commit reuses the existing directory and skips postclone. Only the first push carries history; later ones send just the new objects. The clone out of the mirror is local to the backend, so git hardlinks the objects and it costs almost no time or disk.
What is read versus what runs. Workflow JSON and the repo's own scripthut.yaml are read from the working tree, so edits take effect immediately without a commit. The code the backend runs is the branch tip. Those differ whenever the tree is dirty, so scripthut source view <name> and the Sources page warn when it is:
$ scripthut source view my-project
Source 'my-project' (type: git)
local_path: /home/me/git/my-project (pushed to the backend)
url: <none>
branch: main
warning: working tree has uncommitted changes; the backend runs committed HEAD (a1b2c3d)
Commit before submitting if you meant those changes to run. Files ignored by .gitignore never count as dirty.
Supported backends. SSH backends (slurm, pbs) and the local backend. AWS Batch and EC2 run containers that clone a URL themselves and have no route back to your machine's disk, so a local_path-only source is refused there with an error saying so — give the source a url to use those.
Coding agents still require a url: an agent commits and pushes a branch, and needs a remote to push it to.
| Field | Type | Default | Description |
|---|---|---|---|
local_path |
path | null |
Path to a git repo on the ScriptHut host. When set, workflows are read from this working tree and the resolved commit is pushed to the backend instead of cloned from url. |
url |
string | "" |
Optional once local_path is set. Still used for coding-agent runs and shown as run metadata. |
Path Source¶
sources:
- name: shared-workflows
type: path
path: /shared/project-workflows
backend: hpc-cluster
# workflows_glob: "**/*.hut.json" # default: .hut/workflows/*.json
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique identifier for this source. |
type |
string | required | Must be "path". |
path |
string | required | Directory on the backend filesystem. |
backend |
string | required | Backend where this path exists and where tasks are submitted. |
workflows_glob |
string | ".hut/workflows/*.json" |
Glob pattern to find workflow JSON files (supports ** for recursive matching). |