# Environments and deploys

> How versions reach environments — declaring environments and their order, AWS access per environment, deploying every version, on a schedule after a soak, or by hand, and rolling back.

A **deploy** is a component's `deploy` section, run once for each
**environment** the file declares. Environments are where versions go — dev,
staging, prod — each with its own AWS access, in an order you choose.

```yaml
# yaml-language-server: $schema=https://squidci.com/schema/pipelines.json
environments:
  dev:
    aws: {profile: dev, region: eu-west-2}
    trigger: every-version
  prod:
    aws: {profile: prod, region: eu-west-2}
    after: dev

api:
  test:
    - pnpm: test
  build:
    - pnpm: build
  deploy:
    - pnpm: run deploy -- --stage $SQUIDCI_ENVIRONMENT
```

That is two deploy jobs, `api / deploy dev` and `api / deploy prod`. Each runs the
same steps with `$SQUIDCI_ENVIRONMENT` set to its environment's name.

## Versions

A push to the default branch whose checks, tests, builds and publishes have
all passed is a **version**: something that may be deployed. A deploy waits
for every check, test and build in its run, whichever component they belong
to, and for its own component's publish: nothing ships from a commit with
anything red.

## The order: after

`after: dev` means a version reaches prod only once its every deploy to dev
has succeeded — a list, `after: [dev, staging]`, needs all of them. Within
one environment, a component's deploy waits for the deploys of the components
it `needs` or comes `after`, so an `infra` component deploys before the `api`
on top of it.

## What deploys: triggers

- **`trigger: every-version`** deploys each version as it comes, in commit
  order.
- **A schedule** deploys at set times: the newest version allowed there, never
  one older than what it runs. With `soaked`, only a version that reached
  another environment at least that many hours ago.

  ```yaml
  prod:
    after: staging
    trigger:
      schedule: "0 22 * * 1-5"      # weekdays at 22:00
      timezone: Europe/London       # UTC when left out
      soaked: {in: staging, hours: 12}
  ```

- **No trigger**: deployed only by hand.

## By hand

The **deploy** page lists each repository's environments — what each runs,
how far behind the default branch it is, and any deploy going — and its
versions. An organization admin can **deploy** any version to any
environment it may go to, **redeploy** the one there, or **roll back** to an
earlier one. By hand, a version may skip a schedule's soak; the page warns
when it has not soaked.

## AWS access

An environment's `aws` is what its deploys may reach, in place of the
component's own `aws` — wholly: its profiles, and its region, which is the
plane's when the environment names none. See
[AWS access for jobs](/docs/pipelines/aws/).

## One at a time

Deploys to an environment go one at a time, in commit order, per repository:
a deploy starts only once every earlier one to that environment has finished,
so an older commit can never land after a newer one. Deploys never run on spot instances, and are never
skipped as unchanged.
