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: alwaysMulti-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