Examples

Real-world pipeline configurations to help you get the most out of arrow. These cover common patterns from CI to data processing.

CI Pipeline

A complete CI pipeline that lints, tests, and builds on every push. Parallel test splitting saves time on larger projects.

yaml
# .arrow/ci.yaml
version: "1"
pipelines:
  ci:
    steps:
      - name: install
        run: npm ci --frozen-lockfile
        cache: node_modules
      - name: lint
        run: npm run lint
        needs: [install]
      - name: typecheck
        run: npm run typecheck
        needs: [install]
      - name: test-unit
        run: npm run test:unit -- --shard=1
        needs: [install]
      - name: test-unit-2
        run: npm run test:unit -- --shard=2
        needs: [install]
      - name: test-e2e
        run: npm run test:e2e
        needs: [install]
      - name: build
        run: npm run build
        needs: [lint, typecheck, test-unit, test-unit-2, test-e2e]
      - name: docker
        run: docker build -t app:$COMMIT_SHA .
        needs: [build]
terminal
$ arrow run ci
(1/8) install ........ done (4.2s)
[2/8] lint
[3/8] typecheck
[4/8] test-unit
[5/8] test-unit-2
[6/8] test-e2e
(2/8) lint .......... done (1.1s)
(3/8) typecheck ..... done (1.8s)
(4/8) test-unit ..... done (2.4s)
(5/8) test-unit-2 ... done (2.6s)
(6/8) test-e2e ...... done (3.1s)
[7/8] build
(7/8) build ......... done (5.0s)
[8/8] docker
(8/8) docker ........ done (2.1s)
Completed in 8.3s (parallel savings: 12.4s)

Data Processing Pipeline

Extract, transform, and load data with conditional branching.

yaml
# pipelines/data.yaml
version: "1"
pipelines:
  etl:
    steps:
      - name: extract
        run: python scripts/extract.py --source $SOURCE
        env:
          SOURCE: "{{ .args.source | default "s3://data" }}"
      - name: validate
        run: python scripts/validate.py data/raw
        needs: [extract]
      - name: transform
        run: python scripts/transform.py data/raw data/processed
        needs: [validate]
        retry: 2
      - name: load
        run: python scripts/load.py data/processed
        needs: [transform]
        env:
          DB_URL: "{{ .env.DATABASE_URL }}"
      - name: report
        run: python scripts/generate_report.py
        needs: [load]
        when: always

Multi-Step Build Workflow

A polyglot monorepo build that compiles a Go backend, builds a React frontend, and packages them together.

yaml
# pipelines/release.yaml
version: "1"
pipelines:
  release:
    steps:
      - name: backend-install
        run: cd backend && go mod download
      - name: backend-build
        run: cd backend && go build -o ../dist/server .
        needs: [backend-install]
      - name: frontend-install
        run: cd frontend && npm ci
      - name: frontend-build
        run: cd frontend && npm run build
        needs: [frontend-install]
      - name: package
        run: |
          mkdir -p dist/release
          cp dist/server dist/release/
          cp -r frontend/dist dist/release/static
          cp docker-compose.yml dist/release/
        needs: [backend-build, frontend-build]
      - name: compress
        run: tar -czf release.tar.gz -C dist release
        needs: [package]

Config File with All Features

A comprehensive arrow.yaml demonstrating variables, conditions, and loops.

yaml
# Full-featured arrow.yaml
version: "1"

project:
  name: demo
  language: auto

vars:
  REGISTRY: ghcr.io/myorg
  TAG: "{{ .env.GIT_SHA | default "latest" }}"
  NODE_VER: "20"

hooks:
  pre-run: echo "Starting pipeline {{ .pipeline }}"
  post-run: echo "Finished pipeline {{ .pipeline }}"

pipelines:
  build:
    steps:
      - name: setup
        run: node --version
        env:
          NODE_OPTIONS: --max-old-space-size=4096
      - name: build
        run: docker build -t $REGISTRY/app:$TAG .
        needs: [setup]
        retry:
          attempts: 3
          backoff: exponential
      - name: push
        run: docker push $REGISTRY/app:$TAG
        needs: [build]
        when: success
      - name: cleanup
        run: docker system prune -f
        needs: [push]
        when: always