ข้ามไปยังเนื้อหาหลัก

Pipelines

A pipeline is the work that runs when a trigger fires: a push, a pull request, or a manual run. You define it in a .loha.yml file at the root of your repository. The pipeline lives in your repo, versioned alongside your code, reviewed in the same pull requests.

A pipeline is made of jobs. Each job is made of steps. That's the whole shape.

A minimal pipeline​

version: 1

on:
push:
branches: [main]

jobs:
test:
steps:
- name: Checkout
uses: loha/git-clone@v1
- name: Test
uses: loha/run-tests@v1
with:
TEST_COMMAND: pnpm test

One trigger, one job, two steps. Push to main and Loha clones the repo and runs your tests.

Jobs​

A job is an independent unit of work. It runs in its own isolated environment with its own filesystem, its own environment variables, and its own resource budget.

A pipeline can have 1–20 jobs. By default, every job runs in parallel. To make one job wait for another, use needs::

jobs:
lint:
steps: [...]

test:
steps: [...]

build:
needs: [lint, test]
steps: [...]

Here lint and test run at the same time. build waits for both to succeed before starting. If either fails, build is skipped.

A job that has no needs: is a leaf in the dependency graph and runs immediately.

Steps​

A step is the smallest unit of execution. Steps in a job run sequentially and share the same workspace, so files written by one step are visible to the next.

Two kinds of steps:

  • uses:: reference an official task from the catalog. The task is pinned, signed, and version-locked.

    - name: Build image
    uses: loha/buildah-build@v1
    with:
    IMAGE: registry.example.com/myorg/web:${COMMIT_SHA}

    Each task defines its own parameters: a with: key the task doesn't declare is silently ignored, so check the catalog page for the task you're using.

  • run:: a shell command in a container of your choice.

    - name: Install dependencies
    run: pnpm install --frozen-lockfile
    image: node:20

Every step needs a name.

If a step fails (non-zero exit), the job stops and is marked failed. Subsequent steps in that job don't run; jobs that depend on it via needs: are skipped.

Resource classes​

A pipeline declares a default resource class (the compute budget for CPU and memory), which each job can override individually:

ClassUse case
microNotifications, tiny scripts
smallLinting, type-checking, lightweight scripts
mediumMost test suites, small builds
largeBigger builds, heavy compilation, monorepo-scale work
version: '1'
resource_class: large

on:
push:
branches: [main]

jobs:
build:
steps:
- name: Checkout
uses: loha/git-clone@v1
- name: Build
run: make build

notify:
resource_class: micro
needs: [build]
steps:
- name: Announce
run: ./scripts/announce.sh

The top-level resource_class is the default for every job; a job can set its own resource_class to run heavier or lighter than the rest of the pipeline. The classes available to your workspace depend on your plan: every job's class, whether inherited or overridden, must be one your plan allows, and requesting a class outside your plan is rejected with a job-named error when the build is triggered.

What you get back​

Every pipeline run produces one build: a record with live logs, status, timing, and any artifacts or container images the jobs produced. You can watch it live in the dashboard, retry it, or cancel it mid-flight.

Where to go next​