Skip to content
Go to console
Go to console

sluiceway.yaml

2 stacks are pending: two crates wait upstream of Penny2 stacks are pending: two crates wait upstream of Penny

Configuration of Sluiceway. The file is optional and sits at the repo root.

Generated from the action’s JSON schema. Configuration explains each key with examples.

dashboard

  • Type: mapping
  • Default: {}

dashboard.title

Title of the dashboard issue. Every scan puts it back when it differs.

  • Type: string
  • Default: Sluiceway dashboard
  • The value is at least 1 character long.
  • In the guide: dashboard.title

dashboard.label

Label the dashboard issue is found by.

  • Type: string
  • Default: sluiceway
  • The value is at least 1 character long.
  • In the guide: dashboard.label

dashboard.pin

Pin the dashboard issue on every scan when it is not pinned, best effort. false keeps it unpinned.

dashboard.redact

Keep resource types, resource names and property names out of the issue. The summary stays full. Not access control.

dashboard.personality

Show the header image and use the voice. false removes both.

dashboard.readOnly

Draw no boxes: pending rows have none, there is no rescan box, and a line under the Pending heading says so. For a workflow that only scans.

dashboard.showValues

Property paths whose old and new value may appear on the dashboard, as “old → new”. Exact paths, or “*” for part of one name. Never a value the tool marks secret, and none at all with redact on.

  • Type: list of string
  • Default: []
  • Each entry is at least 1 character long.
  • In the guide: dashboard.showValues

dashboard.recentlyDeployed

How many deploys the Recently deployed list shows, newest first, failed ones included. 0 leaves the list out.

dashboard.timeZone

The IANA time zone every time on the dashboard is shown in, such as Europe/Brussels. A time that stands alone says its offset from UTC, and the line under Recently deployed names the zone. The markers keep UTC.

dashboard.sections

The order of the sections, top to bottom: deploying, updates, pending, drifted, previewFailed, inSync, recentlyDeployed. The ones named come first in this order, and a section left out follows in the default order. Leaving a section out does not hide it.

  • Type: list of string
  • Default: ["deploying","updates","pending","drifted","previewFailed","inSync","recentlyDeployed"]
  • Allowed values of each entry: deploying, updates, pending, drifted, previewFailed, inSync, recentlyDeployed
  • In the guide: dashboard.sections

dashboard.deployingSection

false takes the Deploying section off the page: its rows move to one closed fold at the end of the sections. The counts line and the header still count them.

dashboard.driftedSection

false takes the Drifted section off the page: its rows move to the closed fold at the end of the sections, with no repair all box. A drifted row with a failure line, or with a resource gone that the destroy alert names, stays open under the Drifted heading.

dashboard.inSyncSection

  • fold: the in sync rows in a fold, the default.
  • list: every in sync row open.
  • off: the section is off the page and its rows move to the closed fold at the end of the sections. A row with a failure line always stays open under the In sync heading.

dashboard.zeroCounts

false leaves a count of 0 out of the counts line. The pending count always stays.

dashboard.destroyAlert

  • destroys: the caution block above the pending rows is drawn when a pending stack deletes or replaces something, or a drifted stack has a resource gone.
  • always: it is drawn on every body, and says so when nothing is destroyed. It cannot be turned off.

dashboard.pendingDetail

How much a pending row shows under its first line.

  • full: everything, the default.
  • compact: the first line, and only the lines no setting hides (the failure line and every delete and replace line) and the ones that say why a row has no box or a tick would not go.
  • names: the stack id and its counts, without the preview link, and only the lines no setting hides.

dashboard.deployAll

false draws no deploy all box under the pending rows.

dashboard.repairAll

false draws no repair all box under the drifted rows.

dashboard.rescanBox

false draws no rescan box. A full scan is then started with Run workflow or the schedule.

dashboard.footer

false leaves out the small line with the version and the docs link.

tickers

Default tick rule: write, maintain, admin, or a list of usernames. A list narrows and never widens: a person on it still needs write access.

  • Type: string or list of string
  • Allowed values: write, maintain, admin
  • A list holds at least 1 entry.
  • Each entry matches ^[A-Za-z0-9_-]+$.
  • In the guide: tickers

deploys

false stops every deploy: resolve clears every ticked box with a note and starts nothing, and apply ends a deploy that was already started before the tool runs. Scans go on.

  • Type: boolean
  • Default: true
  • In the guide: deploys

recordWriters

Logins, an app as name[bot], whose open deployment records that name a dispatched or scheduled run are deployed by that run. The writer is who GitHub records as the creator of the record. Empty hands none on.

  • Type: list of string
  • Each entry matches ^[A-Za-z0-9_-]+(\[bot\])?$.
  • In the guide: recordWriters

deployWindows

When the stacks of this repo may go out, in the dashboard zone: a list of windows, each with days of the week, a start and an end. A tick outside every window waits for the next one to open, and so does a deploy on merge. Empty, the default, is any time. A stacks entry sets its own with stacks[].deployWindows.

  • Type: list of mapping
  • Default: []
  • Each entry needs days and from and to.

deployWindows[].days

The days of the week the window is on, in full and in lower case: monday to sunday.

  • Type: list of string
  • Required: yes
  • Allowed values of each entry: monday, tuesday, wednesday, thursday, friday, saturday, sunday
  • The value holds at least 1 entry.
  • In the guide: deployWindows[].days

deployWindows[].from

When the window opens on each of those days, as HH:MM on a 24 hour clock in the dashboard zone.

  • Type: string
  • Required: yes
  • The value matches ^(?:([01]\d|2[0-3]):[0-5]\d|24:00)$.
  • In the guide: deployWindows[].from

deployWindows[].to

When it closes, as HH:MM, after from. 24:00 is the end of the day.

  • Type: string
  • Required: yes
  • The value matches ^(?:([01]\d|2[0-3]):[0-5]\d|24:00)$.
  • In the guide: deployWindows[].to

freezes

Periods when nothing goes out, in the dashboard zone: each a start and an end as YYYY-MM-DDTHH:MM and an optional reason. A tick, a deploy on merge and a destroy wait for the end, and a deploy window after it, and go out at the first moment both allow. Empty, the default, freezes nothing.

  • Type: list of mapping
  • Default: []
  • Each entry needs from and to.

freezes[].from

When the freeze starts, as YYYY-MM-DDTHH:MM in the dashboard zone, such as 2026-12-20T00:00.

  • Type: string
  • Required: yes
  • The value matches ^\d{4}-\d{2}-\d{2}T([01]\d|2[0-3]):[0-5]\d$.
  • In the guide: freezes[].from

freezes[].to

When it ends, as YYYY-MM-DDTHH:MM, after from. The end is outside it.

  • Type: string
  • Required: yes
  • The value matches ^\d{4}-\d{2}-\d{2}T([01]\d|2[0-3]):[0-5]\d$.
  • In the guide: freezes[].to

freezes[].reason

Why nothing goes out, shown on the dashboard and on every row that waits for it.

  • Type: string
  • The value is at least 1 character long.
  • In the guide: freezes[].reason

ignore

Globs matched against the stack id. An ignored stack has no row. An entry with a reason is listed with it under In sync.

  • Type: list of string or mapping
  • Default: []
  • Each string entry is at least 1 character long.
  • Each mapping entry needs glob and reason.
  • In the guide: ignore

ignore[].glob

Glob matched against the stack id.

  • Type: string
  • Required: yes
  • The value is at least 1 character long.

ignore[].reason

Why these stacks are left out. Shown on the dashboard under In sync.

  • Type: string
  • Required: yes
  • The value is at least 1 character long.

scan

  • Type: mapping
  • Default: {}

scan.unrelated

Globs for files that claim nothing and force nothing, such as **/*.md.

  • Type: list of string
  • Default: []
  • Each entry is at least 1 character long.
  • In the guide: scan.unrelated

scan.logDiff

Print the tool’s own diff of every pending stack, values included, in that stack’s group of the job log and nowhere else. Anyone who can read the repo can read its job logs. Costs one more tool run per pending stack.

drift

  • Type: mapping
  • Default: {}

drift.enabled

Check every stack for drift in each scan that a schedule starts, or that a person starts with Run workflow: changes made to real infrastructure outside the code. A stack with drift gets a row with a box, and a tick deploys the code as it is, which puts it back. Costs one more tool run per stack in those scans.

valueFingerprint

Cover the values a row does not show with a fingerprint on the row, so a tick approves them too: a value that changed between the tick and the deploy stops the deploy, and the row says so without naming the value. A value the tool marks secret never reaches the fingerprint. Turn it off, here or per stack, where a program makes a value that differs on every run.

policies

Directories or files of Rego policies, relative to the repo root, that every pending stack’s preview is tested against with conftest, which the workflow installs. A policy that fails takes the box off the row until it passes and stops a deploy on merge. Empty runs nothing.

  • Type: list of string
  • Each entry is at least 1 character long.
  • In the guide: policies

cost

  • Type: mapping
  • Default: {}

cost.enabled

Estimate what each pending change of an OpenTofu or Terraform stack costs a month, with the Infracost CLI the workflow installs, and show it on the row as a change to the monthly bill. The CLI sends resource types, regions and quantities to its pricing API, never a value or a credential. A Pulumi, Helm or Kubernetes manifests stack gets no estimate. An estimate that fails is a missing line, never a failed scan.

cost.threshold

The change to the monthly bill above which a stack set to deploy on merge waits for a tick instead, and its row says why. In the currency of the estimate, USD unless the workflow sets another. A change whose estimate failed waits too. Needs enabled: true.

attribution

  • Type: mapping
  • Default: {}

attribution.lookback

How many of the newest commits a job walks to say which pull requests made a row pending. A stack whose last deploy lies further back gets a line that says earlier changes exist. Each 100 commits cost one more GraphQL request.

  • Type: whole number
  • Default: 100
  • The value is at least 1.
  • The value is at most 1000.
  • In the guide: attribution.lookback

attribution.names

How many pull requests and direct pushes a row and a line of Recently deployed name, newest first. The rest is a count. 0 names none and always counts.

  • Type: whole number
  • Default: 5
  • The value is at least 0.
  • The value is at most 20.
  • In the guide: attribution.names

phases

Names of the phases stacks deploy in, in order. A stack in a phase depends on every stack in every earlier phase.

  • Type: list of string
  • Default: []
  • Each entry is at least 1 character long.
  • Each entry matches ^[A-Za-z0-9][A-Za-z0-9._-]*$.
  • In the guide: phases

stacks

Settings for stacks that discovery found. An entry never creates a stack, except an entry with tool, which declares one.

  • Type: list of mapping
  • Each entry needs path.

stacks[].path

Directory of the stack, relative to the repo root.

  • Type: string
  • Required: yes
  • The value is at least 1 character long.
  • In the guide: stacks[].path

stacks[].name

Name of the stack. Without it the entry covers every stack in path.

  • Type: string
  • The value is at least 1 character long.
  • In the guide: stacks[].name

stacks[].tool

The tool of a stack that discovery cannot find from files alone. The entry then declares the stack at path.

  • opentofu and terraform: a root module, or with the wrapper option a Terragrunt unit or a CDK for Terraform app.
  • helm: a release in a namespace.
  • kubectl: a directory of Kubernetes manifests or a kustomization.
  • Type: string
  • Allowed values: opentofu, terraform, helm, kubectl
  • In the guide: stacks[].tool

stacks[].id

The id of the one stack this entry covers, in place of the one derived from its path and name. A stack that moved keeps its row and its deploys under it. Unique among every stack id.

  • Type: string
  • The value is at least 1 character long.
  • The value matches ^[A-Za-z0-9][A-Za-z0-9._/:@+-]*$.
  • In the guide: stacks[].id

stacks[].environment

Label on the deployment record, and the GitHub Environment where one is used. Default: sluiceway.

stacks[].tickers

Tick rule for this stack. Default: the top level tickers.

  • Type: string or list of string
  • Allowed values: write, maintain, admin
  • A list holds at least 1 entry.
  • Each entry matches ^[A-Za-z0-9_-]+$.
  • In the guide: stacks[].tickers

stacks[].inputs

Extra globs this stack claims, relative to the repo root.

  • Type: list of string
  • Each entry is at least 1 character long.
  • In the guide: stacks[].inputs

stacks[].previewTimeout

Time limit for one preview of this stack, in whole minutes. Default: the preview-timeout input.

stacks[].dependsOn

Stack ids of the stacks this stack depends on, or auto to read them from the program’s stack references at each preview. A tick on this stack is refused while one of them has a change waiting, and when both are ticked they deploy in order.

  • Type: auto or list of string
  • Each entry is at least 1 character long.
  • In the guide: stacks[].dependsOn

stacks[].phase

The phase of these stacks, one of phases, or from: a key of the project file that names it. A stack in a phase depends on every stack in every earlier phase.

  • Type: string or mapping
  • A string is at least 1 character long.
  • A string matches ^[A-Za-z0-9][A-Za-z0-9._-]*$.
  • A mapping needs from.
  • In the guide: stacks[].phase

stacks[].phase.from

A key of the project file whose text is the phase, under config or at the top level.

  • Type: string
  • Required: yes
  • The value is at least 1 character long.

stacks[].deploy

When these stacks deploy.

  • on-tick: when a person ticks the row, the default.
  • on-merge: by themselves after the scan of a merge that found them pending, through the same fresh preview and hash check as a tick, attributed to whoever merged. A change that deletes or replaces something, drift, and a stack it depends on that waits for a tick still wait for a tick.
  • Type: string
  • Allowed values: on-tick, on-merge
  • In the guide: stacks[].deploy

stacks[].deployWindows

When these stacks may go out, in place of the top level deployWindows. An empty list lets them go out at any time.

  • Type: list of mapping
  • Each entry needs days and from and to.

stacks[].deployWindows[].days

The days of the week the window is on, in full and in lower case: monday to sunday.

  • Type: list of string
  • Required: yes
  • Allowed values of each entry: monday, tuesday, wednesday, thursday, friday, saturday, sunday
  • The value holds at least 1 entry.
  • In the guide: stacks[].deployWindows[].days

stacks[].deployWindows[].from

When the window opens on each of those days, as HH:MM on a 24 hour clock in the dashboard zone.

stacks[].deployWindows[].to

When it closes, as HH:MM, after from. 24:00 is the end of the day.

stacks[].drift

The drift check of these stacks. Default: the top level drift.

  • Type: mapping
  • The value needs enabled.

stacks[].drift.enabled

Check these stacks for drift, or not, whatever drift.enabled at the top level says. The scans that check are the same.

stacks[].valueFingerprint

Cover the values these stacks’ rows do not show with a fingerprint, or not, whatever valueFingerprint at the top level says. Turn it off for a stack whose program makes a value that differs on every run. Default: the top level valueFingerprint.

stacks[].envFile

A file of NAME=value lines, relative to the repo root or absolute, that the tool gets for these stacks alone, on top of the job environment and the step’s env-file input. Every value is masked first. A file that cannot be loaded fails the preview of these stacks and no other.

  • Type: string
  • The value is at least 1 character long.
  • In the guide: stacks[].envFile

stacks[].policies

Directories or files of Rego policies these stacks are tested against, relative to the repo root, on top of the top level policies.

  • Type: list of string
  • Each entry is at least 1 character long.
  • In the guide: stacks[].policies

stacks[].createInBackend

true: a scan creates each Pulumi stack of the entry that the backend lacks, with pulumi stack init right before its first preview, and previews it as all creates. A deploy never creates a stack. Default: false.

stacks[].cost

The cost estimate of these stacks. Default: the top level cost.

  • Type: mapping

stacks[].cost.enabled

Estimate what a change of these stacks costs a month, or not, whatever cost.enabled at the top level says. Only an OpenTofu or Terraform stack gets an estimate.

stacks[].cost.threshold

The change to the monthly bill above which these stacks, when set to deploy on merge, wait for a tick instead, whatever cost.threshold at the top level says. In the currency of the estimate.

stacks[].options

Named adapter options of the tool. Only an entry with tool takes them.

  • Type: mapping

stacks[].options.workspace

  • opentofu and terraform: The workspace of the stack, selected with TF_WORKSPACE for every command. Without it, the one the environment selects, which is default.

stacks[].options.varFiles

  • opentofu and terraform: Var files, relative to the directory of the stack, passed with -var-file in this order to every plan. Not with a wrapper.

stacks[].options.wrapper

  • opentofu and terraform: What stands in front of the tool.
  • terragrunt: path is one Terragrunt unit, and terragrunt runs the tool there.
  • cdktf: path is a CDK for Terraform app, cdktf synth writes its stacks, and name picks the one this entry deploys.

stacks[].options.release

  • helm: The name of the Helm release. Helm’s rule: lower case letters, digits, - and .
  • Type: string
  • The value is at least 1 character long.
  • The value is at most 53 characters long.
  • The value matches ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$.
  • In the guide: stacks[].options.release

stacks[].options.namespace

  • helm: The namespace of the release, passed with --namespace to every command.
  • kubectl: The namespace of objects that name none, passed with --namespace to every command. Without it, the namespace of the context.
  • Type: string
  • The value is at least 1 character long.
  • The value is at most 63 characters long.
  • The value matches ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$.
  • In the guide: stacks[].options.namespace

stacks[].options.chart

  • helm: The chart: a path relative to the directory of the stack that starts with “./” or “../”, or a chart reference such as repo/name or oci://registry/name.
  • Type: string
  • The value is at least 1 character long.
  • The value matches ^\.\.?(\/|$)|^(oci:\/\/|https?:\/\/)[^\s]+$|^[A-Za-z0-9][\w.-]*\/[\w.-]+$.
  • In the guide: stacks[].options.chart

stacks[].options.version

  • helm: The exact version of a chart reference. A local chart takes none.
  • Type: string
  • The value is at least 1 character long.
  • The value matches ^v?\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$.
  • In the guide: stacks[].options.version

stacks[].options.valuesFiles

  • helm: Values files, relative to the directory of the stack, passed with --values in this order to every command.

stacks[].options.createNamespace

  • helm: Create the namespace of the release when it is not there, with --create-namespace on the deploy. The preview works without it.

stacks[].options.context

  • kubectl: The kubeconfig context of the stack, passed with --context to every command. Without it, the current context of the kubeconfig.

stacks[].options.recursive

  • kubectl: Read the manifests of every subdirectory too, as kubectl apply -R does. Only for a directory of manifests. Default false: one level.

stacks[].options.prune

  • kubectl: Delete an object taken out of the manifests when the stack deploys, and show it as a delete on the row. Sluiceway keeps the list of the stack’s objects in a ConfigMap next to them. Default false.

stacks[].options.forceConflicts

  • kubectl: Take a field that another field manager holds, with --force-conflicts on the preview and the deploy. Without it such a field fails the preview. Default false.

stacks[].options.fieldManager

  • kubectl: The field manager of the preview and the deploy, passed with --field-manager. Without it, kubectl’s own, kubectl.
  • Type: string
  • The value is at least 1 character long.
  • The value is at most 128 characters long.
  • The value matches ^[A-Za-z0-9][A-Za-z0-9._-]*$.
  • In the guide: stacks[].options.fieldManager

discovery

Switches for what discovery finds on its own. Pulumi stacks are always found.

  • Type: mapping

discovery.rootModules

Find OpenTofu and Terraform root modules from their files: a directory with a backend or cloud block, a lock file or .tofu files that say which tool runs it, and no other directory using it as a module source. Each is one stack in the default workspace. A directory a stacks entry declares keeps its entry. Default: true.

mergeAndDeploy

  • Type: mapping
  • Default: {}

mergeAndDeploy.authors

Logins whose open pull requests may be merged and deployed with one tick, such as renovate[bot]. Empty turns it off.

mergeAndDeploy.preview

Preview the branch of each update waiting to merge, and show what it would change on its row. One extra preview per update on every scan that lists it.

notify

  • Type: mapping
  • Default: {}

notify.events

The events a notification is sent on, to each channel the step’s inputs name: pending (stacks newly pending after a scan), drift (stacks newly drifted), deployed, failed and refused (a tick that deployed nothing).

  • Type: list of string
  • Allowed values of each entry: pending, drift, deployed, failed, refused
  • In the guide: notify.events