← Pipelines

Pipeline examples

Real .gittan.yaml patterns for common project types.

Node.js API with tests

Install, test, and build run as a DAG. Tests and build depend on install but run in parallel with each other. The container is only published from main.

steps:
  - name: install
    run: pnpm install --frozen-lockfile
    cache: [node_modules]

  - name: lint
    run: pnpm lint
    needs: [install]

  - name: test
    run: |
      export DATABASE_URL=postgres://test:test@localhost:5432/test
      pnpm test
    needs: [install]

  - name: build
    run: pnpm build
    needs: [install]

  - name: publish
    publish:
      image: my-api
    needs: [lint, test, build]

publish steps default to only: main — feature branches run lint, test, and build but never push an image.

npm library

Libraries don't build containers. They test and publish to the package registry.

steps:
  - name: install
    run: pnpm install --frozen-lockfile
    cache: [node_modules]

  - name: test
    run: pnpm test
    needs: [install]

  - name: build
    run: pnpm build
    needs: [install]

  - name: publish-npm
    run: |
      echo "//npm.gittan.eu/${GITTAN_ORG_SLUG}/:_authToken=${GITTAN_WORKLOAD_TOKEN}" >> .npmrc
      pnpm publish --no-git-checks
    needs: [test, build]
    only: main

Multi-image service

A repo with multiple Dockerfiles — an API and a worker, each published as a separate image.

steps:
  - name: install
    run: pnpm install --frozen-lockfile
    cache: [node_modules]

  - name: test
    run: pnpm test
    needs: [install]

  - name: publish-api
    publish:
      image: my-service-api
      dockerfile: Dockerfile.api
    needs: [test]

  - name: publish-worker
    publish:
      image: my-service-worker
      dockerfile: Dockerfile.worker
    needs: [test]

Both images publish in parallel after tests pass.

Using shared steps

Shared steps are defined in your org's pipeline config repo. Reference them with use instead of writing image and run inline.

steps:
  - name: lint
    use: eslint

  - name: test
    use: vitest
    with:
      coverage: "true"

  - name: publish
    publish:
      image: my-service
    needs: [lint, test]

The shared step provides the image and run command. You just pass parameters via with.

With code review

Add a review step to gate deployment on human approval. Tests must pass before the review opens.

steps:
  - name: test
    run: pnpm test

  - name: build
    run: pnpm build

  - name: review
    require: 1
    from: writers
    autoAssign: blame
    needs: [test, build]

  - name: publish
    publish:
      image: my-api
    needs: [review]

The push lands immediately but the image won't publish until a teammate approves the diff. See code review.

Static site (no container)

Build static assets and publish them as artifacts. No Docker involved.

steps:
  - name: install
    run: pnpm install --frozen-lockfile
    cache: [node_modules]

  - name: build
    run: pnpm build
    needs: [install]
    artifacts: [dist]

  - name: deploy
    run: pnpm run deploy
    needs: [build]
    only: main
    secrets: [DEPLOY_TOKEN]

DAG tips

Steps without needs run in parallel. Use needs only for real dependencies — the fewer edges in the DAG, the more parallelism you get.

PatternWhen to use
needs: [install]Step uses files from install (node_modules, venv)
needs: [test, build]Gate publish on multiple checks passing
(no needs)Independent checks — lint, type-check, test in parallel