Overview
Kata CI is a container-native CI system that runs every pipeline step inside an isolated container. No shared state between steps, no flaky tests from environment drift, no "works on my machine" failures. Every build is hermetic and reproducible.
Pipelines are defined in a single YAML file (.kata-ci.yaml) at the root of your repo.
Kata CI parses the dependency graph between steps and runs independent steps in parallel,
with content-addressable caching for near-instant reruns when inputs haven't changed.
Architecture
- kata-cli — The command-line interface. Parses config, invokes the engine, streams logs.
- kata-engine — The scheduler. Builds the step DAG, resolves cache hits, dispatches steps to runners.
- runner — Container runtime adapter. Pulls images, mounts artifacts, executes commands, captures output.
- cache — Content-addressable store. Keys are hashed from step inputs (image, commands, dependencies, mounted files).
- triggers — Git-native triggers. Watches branches, tags, and PRs. Filters by path globs.
How It Works
Quickstart
Install Kata CI, add a pipeline config to your repo, and run it.
Create a .kata-ci.yaml in your project root:
pipeline: "my-app" steps: - name: "build" image: "node:20-alpine" commands: - "npm ci" - "npm run build" artifacts: - "dist/" - name: "test" image: "node:20-alpine" depends_on: ["build"] commands: - "npm test" - name: "lint" image: "node:20-alpine" depends_on: ["build"] commands: - "npm run lint"
kata run again — the build step will resolve from cache
instantly if source files haven't changed.
Pipeline Config
The pipeline config lives in .kata-ci.yaml at the root of your repository.
It defines the pipeline name, global settings, and a list of steps.
pipeline: "my-service" settings: timeout: "15m" # Max pipeline duration max_parallel: 4 # Max concurrent steps fail_fast: true # Stop on first failure cache_enabled: true # Enable content-addressable cache env: # Global env vars for all steps NODE_ENV: "ci" CI: "true" steps: # ... step definitions
| Field | Type | Description |
|---|---|---|
| pipeline | string | Pipeline name. Used in logs and cache keys. |
| settings.timeout | duration | Max total pipeline duration. Default: 30m. |
| settings.max_parallel | int | Max steps to run concurrently. Default: CPU count. |
| settings.fail_fast | bool | Cancel remaining steps on first failure. Default: true. |
| settings.cache_enabled | bool | Enable the content-addressable cache. Default: true. |
| env | map | Environment variables injected into every step. |
| steps | list | Ordered list of step definitions. |
Steps
Each step runs in its own container. Define the container image, commands to run, dependencies on other steps, and artifacts to pass between steps.
steps: - name: "build" image: "golang:1.22-alpine" commands: - "go build -o bin/app ./cmd/app" artifacts: - "bin/" env: CGO_ENABLED: "0" timeout: "5m" - name: "unit-test" image: "golang:1.22-alpine" depends_on: ["build"] commands: - "go test -race -cover ./..." - name: "integration-test" image: "golang:1.22-alpine" depends_on: ["build"] services: - name: "postgres" image: "postgres:16-alpine" env: POSTGRES_PASSWORD: "test" commands: - "go test -tags=integration ./..." - name: "deploy" image: "alpine:3.19" depends_on: ["unit-test", "integration-test"] commands: - "./bin/app deploy --env staging" only: branches: ["main"]
| Field | Type | Description |
|---|---|---|
| name | string | Unique step name. Referenced in depends_on. |
| image | string | Container image to run the step in. |
| commands | list | Shell commands to execute sequentially. |
| depends_on | list | Steps that must complete before this step runs. |
| artifacts | list | Paths to persist and pass to dependent steps. |
| services | list | Sidecar containers (databases, queues) available during the step. |
| env | map | Step-specific environment variables (merged with global env). |
| timeout | duration | Max duration for this step. Default: pipeline timeout. |
| only | object | Conditional execution. Filter by branches, tags, or paths. |
Caching
Kata CI uses a content-addressable cache. Each step's cache key is computed from: the container image, commands, environment variables, dependency artifacts, and watched file hashes. If the key matches, the step is skipped and its artifacts are restored from cache.
You can also define explicit cache paths for dependencies like node_modules or Go module cache.
steps: - name: "install" image: "node:20-alpine" commands: - "npm ci" cache: paths: - "node_modules/" key_files: - "package-lock.json" artifacts: - "node_modules/"
| Field | Description |
|---|---|
| cache.paths | Directories to cache between runs. |
| cache.key_files | Files whose content is hashed into the cache key. Changes invalidate the cache. |
Parallel Execution
Kata CI automatically parallelizes steps that don't depend on each other.
The engine builds a directed acyclic graph (DAG) from your depends_on
declarations and schedules independent steps concurrently.
Use settings.max_parallel to cap concurrency. Steps with no depends_on
are eligible to run immediately.
In this example, test and lint run in parallel after build completes.
deploy waits for both to finish.
Secrets
Secrets are injected as environment variables at runtime and are never written to disk or included in cache keys. Define them in your environment or pass them via CLI flags.
steps: - name: "deploy" image: "alpine:3.19" secrets: - "DEPLOY_TOKEN" - "AWS_ACCESS_KEY_ID" - "AWS_SECRET_ACCESS_KEY" commands: - "./deploy.sh"
***.
Triggers
Define when pipelines run. Triggers support branch filters, tag patterns, path globs, and PR events. Combine multiple triggers with AND/OR logic.
triggers: - event: "push" branches: ["main", "release/*"] paths: - "src/**" - "go.mod" - event: "pull_request" actions: ["opened", "synchronize"] - event: "tag" pattern: "v*"
| Field | Description |
|---|---|
| event | Git event type: push, pull_request, tag, schedule. |
| branches | Branch name patterns (glob supported). |
| paths | Only trigger when matching file paths change. |
| actions | PR actions: opened, synchronize, closed. |
| pattern | Tag name pattern (glob). |
CLI Commands
Kata CI provides a minimal CLI for running, validating, and inspecting pipelines.
| Command | Description |
|---|---|
| kata run | Execute the pipeline from .kata-ci.yaml. Use --step <name> to run a single step. |
| kata validate | Validate the pipeline config without executing. Checks YAML syntax, image refs, and DAG cycles. |
| kata graph | Print the step dependency graph. Use --format dot for Graphviz output. |
| kata cache | Manage the local cache. kata cache list, kata cache clear, kata cache stats. |
| kata logs | View logs from the last run. Use --step <name> to filter by step. |
| kata version | Print version, Go version, and platform info. |
Core Concepts
| Concept | Description |
|---|---|
| Pipeline | A named collection of steps defined in .kata-ci.yaml. Pipelines run on triggers or manually. |
| Step | A single unit of work that runs inside a container. Steps declare dependencies, commands, and artifacts. |
| DAG | Directed acyclic graph built from step dependencies. Determines execution order and parallelism. |
| Artifact | Files or directories produced by a step and consumed by dependent steps. |
| Cache Key | Content-addressable hash of step inputs. Used to skip unchanged steps. |
| Service | Sidecar container (e.g. database) available during a step's execution. |
| Trigger | Git event (push, PR, tag) that starts a pipeline run. |