# Pipeline file reference
Source: https://docs.infraista.com/en/developer-tools/pipelines/pipeline-file-reference



A pipeline is defined by `.infraista/pipeline.yml` in your repository (the path is set per pipeline).
The editor checks the file as you type and shows errors on their lines; a file with errors starts no
jobs.

## A complete example [#a-complete-example]

```yaml
name: web-app
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  manual: true

env:
  NODE_ENV: production

stages:
  - name: test
    jobs:
      - name: unit-tests
        image: node:20
        steps:
          - uses: infraista/checkout@v1
          - uses: infraista/cache@v1
            with:
              key: npm-v1
              path: ~/.npm
          - run: npm ci
          - run: npm test

  - name: build
    jobs:
      - name: image
        steps:
          - uses: infraista/checkout@v1
          - uses: infraista/docker-build-push@v1
            with:
              registry: infraista
              image: registry.infraista.cloud/northwind/web-app
              tags: $GIT_SHORT_SHA

  - name: deploy
    jobs:
      - name: production
        environment: production
        if: branch == main
        steps:
          - uses: infraista/deploy-docker@v1
            with:
              target: web-servers
              registry: infraista
              image: registry.infraista.cloud/northwind/web-app:$GIT_SHORT_SHA
              env_from: pipeline
              containers:
                - name: web
                  ports: ["80:3000"]
```

## Top-level keys [#top-level-keys]

| Key        | Required | What it does                                                                                                 |
| ---------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `name`     | No       | A name for the file, up to 100 characters                                                                    |
| `on`       | No       | When the pipeline runs. Without it, only manual runs. See [Triggers](/en/developer-tools/pipelines/triggers) |
| `inputs`   | No       | Values asked for when someone starts a run by hand or through the webhook                                    |
| `defaults` | No       | Defaults for every job: `runner`, `image`, `timeout`                                                         |
| `env`      | No       | Environment variables for every job (`NAME: value`)                                                          |
| `stages`   | Yes      | The stages, in order, each with its jobs                                                                     |

Any other top-level key is an error.

### `inputs` [#inputs]

```yaml
inputs:
  target:
    type: choice        # boolean, choice or string
    options: [staging, production]
    default: staging
  dry_run:
    type: boolean
```

Input names use letters, digits and `_`. A `choice` needs `options`, and its `default` must be one of
them. Jobs read inputs as `$inputs.NAME`.

## Stages and jobs [#stages-and-jobs]

```yaml
stages:
  - name: test
    jobs:
      - name: lint
        steps: [...]
      - name: unit-tests
        steps: [...]
```

* Stage names use letters, digits, spaces and `- _ .`; job names letters, digits and `- _ .`.
  Job names must be unique in the pipeline.
* **Stages run in order; the jobs in a stage run in parallel.** By default a job waits for every job
  of the earlier stages. Use `needs` to wait only for specific jobs.
* A pipeline can have up to 50 jobs, and a job up to 50 steps.

### Job keys [#job-keys]

| Key           | What it does                                                                                                                                                                                                                   |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`        | Required                                                                                                                                                                                                                       |
| `runner`      | A managed size (`linux-small`, `linux-medium`, `linux-large`, `arm-medium`, `gpu-rtx3090`), or your own machines: `self-hosted` or `[self-hosted, gpu]` (a runner with every label). Defaults to the pipeline's default runner |
| `image`       | The container image the job runs in, such as `node:20`. Default `ubuntu:24.04`                                                                                                                                                 |
| `needs`       | Job names to wait for, instead of the whole earlier stages. `needs: []` starts right away                                                                                                                                      |
| `environment` | Deploys to this environment: its rules apply and it gets its secrets. See [Environments](/en/developer-tools/pipelines/environments-and-deployments)                                                                           |
| `if`          | A condition; the job is skipped when it's false (below)                                                                                                                                                                        |
| `timeout`     | Like `10m`, `2h` or `1h30m`, from 1 minute to 72 hours. Default 60 minutes, or the pipeline's setting                                                                                                                          |
| `retry`       | Re-run a failed job up to this many times (0 to 3)                                                                                                                                                                             |
| `env`         | Environment variables for this job                                                                                                                                                                                             |
| `steps`       | Required: the list of steps                                                                                                                                                                                                    |

## Steps [#steps]

Each step is either a shell command (`run:`) or a built-in action (`uses:`), never both:

```yaml
steps:
  - run: npm ci                      # a command
  - name: Run the tests              # optional label in the log
    run: |
      npm run lint
      npm test
    env:
      CI_SHARD: "1"
  - uses: infraista/checkout@v1      # an action
```

Commands run with `bash` if the image has it, otherwise `sh`, and stop at the first failing line
(`set -e`). The job starts in `/workspace`; use `infraista/checkout` to get your code there.

## Conditions (`if`) [#conditions-if]

```yaml
if: branch == main
if: event == pull_request && branch != main
if: failure()
if: always()
```

| You can use                                               | Meaning                                                        |
| --------------------------------------------------------- | -------------------------------------------------------------- |
| `success()`                                               | The jobs it needs succeeded (the default when there's no `if`) |
| `failure()`                                               | One of the jobs it needs failed                                |
| `cancelled()`                                             | The run was cancelled                                          |
| `always()`                                                | Run whatever happened                                          |
| `branch`, `event`, `tag`, `environment` with `==` or `!=` | Compare with a value, quoted or not                            |
| `&&`, `\|\|`                                              | Combine conditions                                             |

## Expressions and variables [#expressions-and-variables]

| Write                      | Becomes                                                                                                                                                                            |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `$GIT_SHA`, `$GIT_BRANCH`… | Built-in variables (below), in commands and in `with:`                                                                                                                             |
| `$secrets.NAME`            | A secret. In commands and `env`, it's passed as a shell variable so the value never appears on the command line; in an action's `with:`, the value is filled in and masked in logs |
| `$vars.NAME`               | A variable (not secret)                                                                                                                                                            |
| `$inputs.NAME`             | A run input                                                                                                                                                                        |

Values come from [Secrets and variables](/en/developer-tools/pipelines/secrets-and-variables).

### Built-in variables [#built-in-variables]

Every job gets these:

| Variable                                  | Value                                                               |
| ----------------------------------------- | ------------------------------------------------------------------- |
| `CI`, `INFRAISTA`                         | `true`                                                              |
| `GIT_SHA`, `GIT_SHORT_SHA`                | The commit, in full and its first 7 characters                      |
| `GIT_BRANCH`, `GIT_TAG`                   | The branch, or the tag for tag runs                                 |
| `GIT_REPOSITORY`                          | For example `northwind/web-app`                                     |
| `RUN_NUMBER`, `RUN_ATTEMPT`               | The run number and the job's attempt                                |
| `PIPELINE_NAME`, `STAGE_NAME`, `JOB_NAME` | Names from the file                                                 |
| `ENVIRONMENT`                             | The job's environment, if any                                       |
| `EVENT`                                   | What started the run: `push`, `pull_request`, `manual`, `schedule`… |
| `PULL_REQUEST`                            | The pull request number, for pull request runs                      |

Variables from `env:` are applied in order: the file's, then the job's, then the step's.

## Built-in actions [#built-in-actions]

Actions are written `uses: infraista/<name>@v1`, with their options under `with:`.

### Code, tools and files [#code-tools-and-files]

| Action              | Options                                                                                                                                    |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `checkout`          | Fetches the run's commit into the workspace                                                                                                |
| `setup-node`        | `node`: the version (default `20`). Installs it when the image doesn't have it                                                             |
| `setup-python`      | `python`: the version the image must have                                                                                                  |
| `cache`             | `key` and `path` (required, a list), `restore-keys` (prefixes to fall back to). Restores at the step, saves at the end of a successful job |
| `upload-artifact`   | `name`, `path` (required), `retention-days` (1 to 90)                                                                                      |
| `download-artifact` | `name` (required), `path`: files an earlier job of the same run uploaded                                                                   |

Caches belong to the pipeline and branch; a branch without one falls back to the default branch, then
to `restore-keys`. Pull requests read their base branch's cache but write their own.

### Images [#images]

`docker-build-push` builds an image and pushes it:

```yaml
- uses: infraista/docker-build-push@v1
  with:
    registry: infraista                  # your Container Registry, or a registry deploy target
    image: registry.infraista.cloud/northwind/web-app
    tags: $GIT_SHORT_SHA
    context: .                           # optional
    file: Dockerfile                     # optional
    build_args:                          # optional
      NODE_VERSION: "20"
    push: true                           # optional; pull requests never push
```

The build runs in a throwaway Docker of its own, never the runner's.

**Settings your app needs at build time** (for example `NEXT_PUBLIC_*` or `VITE_*` values): add
`env_from: pipeline` to pass the job's **variables** (never secrets) as build arguments, and
`environment: <name>` to choose whose values. Add `env_file: .env` to write them to that file in the
build context instead of build arguments. Secrets never become build arguments, because build
arguments stay in the image's history.

### Deploying [#deploying]

| Action                | Required options                                                                             | Other options                                                                                    |
| --------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `deploy-instance`     | `instance` (an Infraista server's name), `key` (a secret with the SSH private key), `script` | `user` (default `root`), `port`, `upload` + `to`, `registry: infraista`                          |
| `deploy-ssh`          | `target` (an SSH deploy target), `script`                                                    | `upload` + `to`, `registry: infraista`                                                           |
| `deploy-agent`        | `target` (a deploy agent), `script`                                                          | `upload`, `env`, `registry: infraista`                                                           |
| `deploy-docker`       | `target` (a deploy agent or SSH server), `image`, `containers`                               | `env_file`, `env_from: pipeline`, `registry: infraista`, `pull`, `prune`                         |
| `deploy-kubernetes`   | `cluster`, and `manifests` or `chart`                                                        | `namespace` (default `default`), `release`, `values`, `set`, `deployment` (wait for its rollout) |
| `sync-object-storage` | `bucket`                                                                                     | `path` (default `.`), `prefix`, `delete`                                                         |
| `cloud-login`         | `target` (a cloud account)                                                                   | Short-lived cloud credentials for the following steps                                            |

`registry: infraista` signs the server in to your Container Registry before the script, so it can pull
your images. See [Deploy targets](/en/developer-tools/pipelines/deploy-targets) for examples.

#### Containers on a server (`deploy-docker`) [#containers-on-a-server-deploy-docker]

```yaml
- uses: infraista/deploy-docker@v1
  with:
    target: web-servers
    registry: infraista
    image: registry.infraista.cloud/northwind/web-app:$GIT_SHORT_SHA
    env_from: pipeline          # the job's secrets and variables as the containers' environment
    containers:
      - name: api
        ports: ["9090:80"]
        after_start: [php artisan migrate --force]
      - name: worker
        command: php artisan queue:work
```

Each container takes `name` (required), `ports`, `command`, `after_start`, `env`, `volumes`,
`network` and `restart`. The step pulls the image, replaces the old containers (workers first, then the
ones with ports), starts each one, checks it stays up (showing its last logs if not), runs its
`after_start` commands inside it, and prunes old images. Up to 20 containers per step. Deploy a tag
like `$GIT_SHORT_SHA`, so a rollback runs the image that was deployed.

### Gates and checks [#gates-and-checks]

| Action          | Options                                                                                                                                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `approval`      | `approvers` (emails or names), `min` (how many). A job made only of approval steps pauses the run until someone approves                                                                               |
| `security-scan` | `wait` (default `true`), `fail_on` (for example `[critical, high]`), `timeout` (default `15m`). Scans the commit with [Code Security](/en/developer-tools/code-security) and fails when the gate fails |
| `notify`        | `channel` (a notification channel's name), `message`, `severity`                                                                                                                                       |

### Not available yet [#not-available-yet]

`deploy-containers`, `deploy-app-platform` and `terraform` are accepted in the file but fail with a
clear message when they run.

## Limits [#limits]

* The file can be up to 256 KB, with up to 50 jobs and 50 steps per job.
* Job timeouts go from 1 minute to 72 hours.
* Paste carefully: invisible characters copied from web pages and chat apps are removed before the
  file is read, so line numbers in errors stay right.

## Related [#related]

* [Triggers](/en/developer-tools/pipelines/triggers)
* [Secrets and variables](/en/developer-tools/pipelines/secrets-and-variables)
* [Deploy targets](/en/developer-tools/pipelines/deploy-targets)
