stackatdocs

.stackat.yml / option

environments

On this page

Move each upgrade through your environments in order (dev, then staging, then production) instead of everywhere at once. Production only ever gets a version the earlier environments ran.

What it does#

Without environments, Stackat treats every pin of a tool in a repository as one upgrade: one issue, and one pull request that bumps them all. With it, each upgrade becomes a train: one target version, moved through your environments one at a time.

  • One parent issue per upgrade: "Upgrade cert-manager to 1.19.1 in every environment". It shows the environments in order, what each runs now and the soak time between them. GitHub counts its sub-issues as they close.
  • One sub-issue per environment that is behind: "Upgrade cert-manager 1.17.2 → 1.19.1 in staging". It has that environment's own verdict and checklist (its values and feature flags can differ from the others), the file and line of its pins, and its pull request. It closes when the environment runs the target, which dates each step for your change records.
  • Pull requests one environment at a time. The first environment's opens first. The next one's opens once the previous environment has run the target for its soak time. With auto_pr off, /stackpaw pr on a sub-issue opens that environment's pull request.
  • The target stays fixed. A newer release that comes out mid-way does not change the train (see Newer releases).
  • The parent closes when the last environment runs the target, listing the date each one got there.

Environments can be folders on one branch (paths) or a branch each (branches).

Folders#

.stackat.ymlyaml
environments:
  order: [dev, staging, production]
  paths:
    dev: [clusters/dev/]
    staging: [clusters/staging/]
    production: [clusters/production/]
  soak: 2d

Each installation belongs to the environment whose folders hold its file (the Argo CD Application, Flux HelmRelease, helmfile release or Terraform file that pins it). Paths and globs work as in scan: a folder covers everything below it, and ** crosses folders.

A tool pinned in a file outside every environment's folders (a shared base, say) is upgraded in one go, as without environments.

Branches#

.stackat.yml (on the default branch)yaml
environments:
  order: [dev, staging, production]
  branches:
    dev: dev
    staging: staging
    production: main
  soak: {dev: 1d, staging: 3d}

Stackat reads each environment's branch at its latest commit. Each environment's pull request goes against its own branch and changes only the version there. Stackat never merges branches into each other: if you promote by merging dev into staging, keep doing that, and Stackat sees the new version on its next scan.

Stackat reads .stackat.yml from the default branch. A branch that cannot be read (deleted or renamed) is reported as a problem on the dashboard, and the other environments go on.

Newer releases#

on_new_releaseA newer release comes out while the train is on its way
keep (default)The train finishes on its target. One comment on the parent says the newer release is queued; it starts as the next train, at the first environment, once the last environment runs the current target.
restartThe train is replaced: its open issues close as not planned, and a new train with the newer release starts at the first environment.

Under keep, a newer release that fixes a vulnerability being exploited now (or with patch urgency 90 or more) gets a comment on the parent offering /stackpaw retarget. Stackat never retargets on its own.

Commands on a train#

CommandWhat it does
/stackpaw promote stagingOpens staging's pull request now, without waiting for the soak or for the environment before it. Also releases a hold.
/stackpaw hold productionStops the train before production: no automatic pull request there until /stackpaw promote production.
/stackpaw retargetMoves the train to the newest release and starts again at the first environment.
/stackpaw pr (on a sub-issue)Opens that environment's pull request now.

Reply on the parent issue or on any of its sub-issues. Who may use them is set by commands: all three follow commands.pr.

Type and values#

KeyTypeDefault
orderA list of 2 to 10 environment names (lower-case letters, digits, - and _), in the order an upgrade movesRequired
pathsEach environment's folders, files or globsSet paths or branches, not both
branchesEach environment's branchSet paths or branches, not both
soakDays on an environment before the next one's pull request: one value for all (2d, 1w), or per environment ({dev: 1d, staging: 3d}), at most 901d
on_new_releasekeep or restartkeep

An environment in order without paths or a branch is left out. The last environment's soak is never used.

Organisation and repository#

Set it in the organisation's file to give every repository the same environments, or in a repository's own file. A repository's environments block replaces the organisation's as a whole.

When you add it to a repository#

The issue each tool had before is closed with a link to its new parent issue. Open pull requests that bumped every environment at once are replaced by pull requests per environment. Nothing else in the repository changes.

Problems you may see#

.stackat.yml: environments: an upgrade needs at least two environments to move through
.stackat.yml: environments: set paths (folders) or branches, not both
.stackat.yml: environments.paths: no folders for qa, so it is left out
.stackat.yml: environments.branches.staging: '../x' is not a branch name
.stackat.yml: environments.on_new_release: 'later' is not keep or restart, so keep is used
environments.branches.staging: branch staging could not be read

A block that cannot be used applies nothing: the repository is upgraded in one go, as without it.