Skip to main content

Workflows

JJHub workflows are TSX files that define automated tasks for your repository. They use Smithers JSX components wrapped by the @jjhub-ai/workflow package. There is no distinction between CI workflows and AI workflows — a workflow task can run tests, deploy code, or invoke an AI agent. They are all just code running in the same sandboxed environment. Workflows live in your repository under .jjhub/workflows/ and are triggered by events like pushes, landing request activity, schedules, or manual dispatch.

Workflow Basics

A workflow is a TSX file that default-exports a function returning a <Workflow> component with a name, triggers, and child tasks.

Minimal Example

This workflow runs bun test every time code is pushed to the main bookmark.

Workflow Structure

Every workflow has three parts:

Component Reference

Directory Layout

Workflows must be placed in the .jjhub/workflows/ directory at the repository root:
Each .tsx file in the workflows/ directory is discovered automatically. The filename (without extension) becomes the workflow ID used in CLI commands like jjhub workflow run ci. The .jjhub/ directory is a Bun workspace member with its own package.json and tsconfig.json, giving full LSP support (autocomplete, type checking, go-to-definition) when editing workflows. See Your First Workflow for the complete setup.

Triggers & Events

Triggers define when a workflow runs. A workflow can have multiple triggers, and will run when any of them fire.

Push

Run when code is pushed to matching bookmarks:
You can match multiple bookmarks or use glob patterns:
Ignore paths to skip runs for certain changes:

Landing Request

Run when landing request activity occurs:
You can combine multiple landing request events:

Issue

Run when issue activity occurs:

Schedule

Run on a CRON schedule (all times UTC):
CRON syntax uses five fields:
Common patterns:

Manual Dispatch

Run when triggered manually via CLI or API, with optional typed inputs:
Input types: Trigger manually from the CLI:
Or via the API:

Combining Triggers

A workflow can have any combination of triggers. It runs whenever any trigger fires:

Workflow Run

Run when another workflow completes (for chaining workflows like CI -> Build -> Deploy):
The workflows array lists workflow names to watch. The types array filters by outcome: "completed", "success", or "failure".

Webhook Trigger

Run when an external webhook event is received:

Tasks

Tasks are the units of work a workflow executes. Children of <Workflow> run sequentially by default. Use <Parallel> to run tasks concurrently.

Compute Tasks

A compute task runs an async function. Use Bun’s $ template literal for shell commands:
Each task has an id (used in logs and status checks) and an async function child.

Agent Tasks

An agent task invokes an AI agent by passing a string prompt as the child and an agent prop. The agent runs in the same sandboxed environment and can read/write files, execute commands, and interact with the JJHub API:
To use agent tasks, configure your AI API key as a repository secret:

Schema-Driven Tasks

For AI workflows where tasks pass structured data to each other, use createSmithers to define Zod output schemas. This gives you type-safe ctx.output() and automatic persistence:
Key differences from compute tasks: Use the simple compute pattern for CI tasks (lint, test, build, deploy). Use createSmithers when AI agents need to pass structured results between tasks.

Parallel Tasks

Use <Parallel> to run tasks concurrently:
Tasks inside <Parallel> start at the same time. The workflow continues to the next sibling only after all parallel tasks complete.

Context Object

Every workflow receives a ctx object via the function export:

Task Failure

If any task fails (non-zero exit code or thrown error), the workflow run is marked as failed and subsequent tasks are skipped. The commit status on the associated change is set to failure.

Secrets & Variables

Workflows often need credentials (API keys, deploy tokens) and configuration values. JJHub provides two mechanisms:

Secrets

Secrets are encrypted values injected as environment variables into workflow runs. They are never exposed in logs or API responses.
Access secrets in workflow tasks via environment variables:
Secrets are encrypted at rest and only injected into workflow runs. They are never visible in API responses, CLI output, or logs. If a workflow task prints a secret value to stdout, JJHub automatically redacts it in the log output.

Variables

Variables are non-secret configuration values. Unlike secrets, variable values are visible in API responses and CLI output.
Variables are also injected as environment variables into workflow runs.

Secrets vs Variables

Workflow Examples

CI Pipeline

A standard CI workflow that runs on pushes and landing requests:

Deploy Workflow with Inputs

A deploy workflow triggered manually with environment selection:

AI Issue Triage

Automatically label and assign new issues using an AI agent:

AI Code Review

Review landing requests with an AI agent after CI passes:

Programmable Landing Queue

Customize the landing queue behavior with a workflow:

Nightly Dependency Check

Scan for outdated or vulnerable dependencies on a schedule:

Chained Build & Deploy

Chain workflows using on.workflowRun() — build after CI passes, deploy after build succeeds:

Combined CI + AI Workflow

A single workflow that runs tests and invokes an AI agent to analyze failures:

Managing Workflows

List Workflows

Trigger a Workflow

View Runs

Commit Statuses

Workflow runs automatically create commit statuses on the associated changes. You can also manage statuses directly:

API Endpoints

Next Steps