sluiceway.yaml
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.
- Type: boolean
- Default:
true - In the guide: dashboard.pin
dashboard.redact
Keep resource types, resource names and property names out of the issue. The summary stays full. Not access control.
- Type: boolean
- Default:
false - In the guide: dashboard.redact
dashboard.personality
Show the header image and use the voice. false removes both.
- Type: boolean
- Default:
true - In the guide: dashboard.personality
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.
- Type: boolean
- Default:
false - In the guide: dashboard.readOnly
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.
- Type: whole number
- Default:
10 - The value is at least 0.
- The value is at most 50.
- In the guide: dashboard.recentlyDeployed
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.
- Type: string
- Default:
UTC - In the guide: dashboard.timeZone
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.
- Type: boolean
- Default:
true - In the guide: dashboard.deployingSection
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.
- Type: boolean
- Default:
true - In the guide: dashboard.driftedSection
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.
- Type: string
- Default:
fold - Allowed values:
fold,list,off - In the guide: dashboard.inSyncSection
dashboard.zeroCounts
false leaves a count of 0 out of the counts line. The pending count always stays.
- Type: boolean
- Default:
true - In the guide: dashboard.zeroCounts
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.
- Type: string
- Default:
destroys - Allowed values:
destroys,always - In the guide: dashboard.destroyAlert
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.
- Type: string
- Default:
full - Allowed values:
full,compact,names - In the guide: dashboard.pendingDetail
dashboard.deployAll
false draws no deploy all box under the pending rows.
- Type: boolean
- Default:
true - In the guide: dashboard.deployAll
dashboard.repairAll
false draws no repair all box under the drifted rows.
- Type: boolean
- Default:
true - In the guide: dashboard.repairAll
dashboard.rescanBox
false draws no rescan box. A full scan is then started with Run workflow or the schedule.
- Type: boolean
- Default:
true - In the guide: dashboard.rescanBox
dashboard.footer
false leaves out the small line with the version and the docs link.
- Type: boolean
- Default:
true - In the guide: dashboard.footer
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
daysandfromandto.
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
fromandto.
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
globandreason. - 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.
- Type: boolean
- Default:
false - In the guide: scan.logDiff
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.
- Type: boolean
- Default:
false - In the guide: drift.enabled
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.
- Type: boolean
- Default:
true - In the guide: valueFingerprint
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.
- Type: boolean
- Default:
false - In the guide: cost.enabled
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.
- Type: number
- The value is at least 0.
- In the guide: cost.threshold
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.
opentofuandterraform: 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.
- Type: string
- The value is at least 1 character long.
- In the guide: stacks[].environment
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.
- Type: whole number
- The value is at least 1.
- In the guide: stacks[].previewTimeout
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:
autoor 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
daysandfromandto.
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.
- Type: string
- Required: yes
- The value matches
^(?:([01]\d|2[0-3]):[0-5]\d|24:00)$. - In the guide: stacks[].deployWindows[].from
stacks[].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: stacks[].deployWindows[].to
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.
- Type: boolean
- Required: yes
- In the guide: stacks[].drift.enabled
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.
- Type: boolean
- In the guide: stacks[].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.
- Type: boolean
- In the guide: stacks[].createInBackend
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.
- Type: boolean
- In the guide: stacks[].cost.enabled
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.
- Type: number
- The value is at least 0.
- In the guide: stacks[].cost.threshold
stacks[].options
Named adapter options of the tool. Only an entry with tool takes them.
- Type: mapping
stacks[].options.workspace
opentofuandterraform: The workspace of the stack, selected with TF_WORKSPACE for every command. Without it, the one the environment selects, which is default.
- Type: string
- The value is at least 1 character long.
- In the guide: stacks[].options.workspace
stacks[].options.varFiles
opentofuandterraform: Var files, relative to the directory of the stack, passed with-var-filein this order to every plan. Not with a wrapper.
- Type: list of string
- Default:
[] - Each entry is at least 1 character long.
- In the guide: stacks[].options.varFiles
stacks[].options.wrapper
opentofuandterraform: 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.
- Type: string
- Allowed values:
terragrunt,cdktf - In the guide: stacks[].options.wrapper
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--namespaceto every command.kubectl: The namespace of objects that name none, passed with--namespaceto 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--valuesin this order to every command.
- Type: list of string
- Default:
[] - Each entry is at least 1 character long.
- In the guide: stacks[].options.valuesFiles
stacks[].options.createNamespace
helm: Create the namespace of the release when it is not there, with--create-namespaceon the deploy. The preview works without it.
- Type: boolean
- Default:
false - In the guide: stacks[].options.createNamespace
stacks[].options.context
kubectl: The kubeconfig context of the stack, passed with--contextto every command. Without it, the current context of the kubeconfig.
- Type: string
- The value is at least 1 character long.
- In the guide: stacks[].options.context
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.
- Type: boolean
- In the guide: stacks[].options.recursive
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.
- Type: boolean
- In the guide: stacks[].options.prune
stacks[].options.forceConflicts
kubectl: Take a field that another field manager holds, with--force-conflictson the preview and the deploy. Without it such a field fails the preview. Default false.
- Type: boolean
- In the guide: stacks[].options.forceConflicts
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.
- Type: boolean
- Default:
true - In the guide: discovery.rootModules
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.
- Type: list of string
- Each entry matches
^[A-Za-z0-9_-]+(\[bot\])?$. - In the guide: mergeAndDeploy.authors
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.
- Type: boolean
- Default:
false - In the guide: mergeAndDeploy.preview
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