Skip to content
Go to console
Go to console

Run the action yourself

The scan found no stacks yet: Penny stands beside an empty channelThe scan found no stacks yet: Penny stands beside an empty channel

The action runs on its own, with no app installed and nothing hosted: the same scans, the same ticks and the same deploys, in your runners with your credentials, and the dashboard issue is the only dashboard. It is the path for a team that grants no third-party app, or that wants to set every step up by hand.

With the app, one pull request holds the workflow and a first sluiceway.yaml, and the console guides the rest. How the app and the action work together says what the app adds and what stays the same.

The workflow file

This is all the action needs: one job with one Sluiceway step, in .github/workflows/deploy-dashboard.yml on the default branch. The comments mark where your own steps go. Read it now, and merge it at the end of the steps below.

name: deploy-dashboard
on:
push:
branches: [main]
schedule:
- cron: "0 6 * * *" # keep this: a push previews only some stacks, this scan all
workflow_dispatch:
issues:
types: [edited]
# This block is everything Sluiceway can do in your repo.
permissions:
contents: read # check out the code
issues: write # write the dashboard and its comments
deployments: write # record who deployed what, and when
actions: write # the rescan box and settle start this workflow again
pull-requests: read # name the pull requests behind a row
checks: write # a preview page per pending stack
jobs:
sluiceway:
runs-on: ubuntu-latest
# One run at a time, and none is dropped. An edit of any other issue gets
# a group of its own, so it never waits for a scan or a deploy.
concurrency:
group: sluiceway-${{ github.event.issue.number }}
queue: max
steps:
- uses: actions/checkout@v7
# This installs Pulumi. For OpenTofu, Terraform, Helm or kubectl, install
# that tool here instead (see Requirements).
- uses: pulumi/actions@v7 # without a command this only installs the CLI
with:
pulumi-version: ^3.229.0
# Install what your programs need, once, for example: npm ci
# Load your credentials and your state backend settings into the job
# environment here. They preview and deploy, so they must be able to
# change things. Sluiceway passes the environment to the tool and never
# looks inside. Whatever loads a secret must also mask it. Or name a
# file of NAME=value lines with the env-file input on the step below,
# and Sluiceway loads it for the tool and masks every value itself.
- uses: sluiceway/sluiceway@v0

Requirements

  • A GitHub repo with issues turned on. The dashboard is an issue.
  • GitHub Actions runners with runner version 2.328.0 or newer. Hosted runners qualify. Self-hosted runners need that version at least, and ARM32 is not supported.
  • Pulumi CLI 3.229.0 or newer on the runners that preview and deploy, for Pulumi stacks. pulumi/actions installs it. With an older one every preview fails, and the job log says which version is needed.
  • OpenTofu 1.11.0 or newer, for OpenTofu stacks, installed without a wrapper (credentials). A repo with only Pulumi stacks never needs it.
  • Terraform 1.14.0 or newer, for Terraform stacks, installed without a wrapper, Terragrunt 1.0.0 or newer for Terragrunt units, and cdktf 0.21.0 for the stacks of a CDK for Terraform app (credentials). A repo without them never needs them.
  • Helm 3.18.0 or newer and the helm-diff plugin 3.15.11 or newer, for Helm releases, with a kubeconfig for the cluster (credentials). A repo without Helm releases never needs them.
  • kubectl 1.34.0 or newer and a kubeconfig, for Kubernetes manifests stacks (credentials). A repo without them never needs it.
  • Conftest 0.50.0 or newer, only for a repo that names policies, installed in a step before the scan (policies). Without it the policies do not run, the rows say so and keep their boxes, and the run carries a warning.
  • The Infracost CLI, its open source 0.10 line, only for a repo that sets cost.enabled, installed in a step before the scan with a key from your secrets. Without it no row shows a cost line, the run says so, and nothing else changes. The 2.x line drops the command Sluiceway runs and is not supported.
  • Node 22 or newer on your own machine, only for npx sluiceway init and npx sluiceway check (init), or one of the binaries a release carries (the command line). The workflow needs none: the runner starts the action.
  • Your programs’ own needs: a language runtime, dependencies, credentials. The workflow installs and loads them, the same way your own CI or laptop does.

The steps

1. Check your setup

In your clone, npx sluiceway check says which stacks Sluiceway finds and whether its settings are valid, and npx sluiceway init (or bunx sluiceway init) writes the workflow and a first sluiceway.yaml from them, and commits nothing (start with init). The same check runs on every pull request. It needs no credentials, no tool and no write access, so start with it before anything can deploy. Put the check workflow in .github/workflows/deploy-dashboard-check.yml and open a pull request with it. The summary of its run lists every stack it found, with its tick rule, and which credentials each stack needs, as names, and which of them nothing in the workflow provides. To see your dashboard first with nothing that can deploy, start read only.

2. Decide who may deploy

A tick asks for a deploy of that stack, production included. Without sluiceway.yaml, anyone with write access to the repo can tick, and without a GitHub Environment with required reviewers on the job that deploys, a tick is enough to deploy. Decide this before the workflow reaches the default branch: make the people who may deploy the reviewers of that environment, which needs the split workflow, or narrow who may tick with a tick rule in sluiceway.yaml at the repo root, such as tickers: maintain (who can tick). The same file leaves stacks out, names the files outside a stack’s directory that it reads, and declares the stacks discovery does not find from files: Helm releases, Kubernetes manifests, and the OpenTofu and Terraform root modules that discovery leaves out. For Pulumi stacks and the root modules discovery finds, the file is optional. Configuration has every key.

3. Load your credentials

The workflow gives the tool what it needs. For GitHub secrets, put them as env: on Sluiceway’s own step, so no other step sees them. For a cloud with OIDC or a secret manager, add a loading step right before Sluiceway’s, after every install step. Sluiceway passes that environment to the tool as it is and never reads a credential by name. Or name a file of NAME=value lines with the env-file input, and Sluiceway reads it for the tool and masks every value itself. A repo whose stacks live in different places names a file per stack with envFile in sluiceway.yaml, and each stack’s tool gets its own on top. Credentials has recipes for GitHub secrets, an env file, a cloud with OIDC, a secret manager and private registries.

4. Add the workflow

This is the whole loop: one job with one Sluiceway step, and no if: anywhere. The step reads the event of the run and does what it asks for: a push or the schedule scans, a tick deploys, an edit of any other issue ends with a notice. GitHub starts the job for an edit of any issue in the repo, so that run also installs your tools and loads your credentials before it ends, and it runs only code from the default branch. The split workflow keeps credentials out of the job an issue edit starts. The file goes in .github/workflows/deploy-dashboard.yml on the default branch, and the comments mark where your own steps go. Merge it once the steps above are in place. The push of that merge starts the first scan. A scan only previews: it writes the dashboard issue with one row per stack, and nothing deploys until someone ticks a box. The workflow explains every part, and what merge and deploy, stack dependencies, self-hosted runners and GitHub Environments add. Example workflows has it complete for common setups, and init writes a first version from what it finds in your repo.

The file is at the top of this page.

When the first scan is red

Two red rows are the ones new users met first. A Pulumi stack config file with no stack in the backend is still a stack, and its preview fails: leave it out with ignore and its full stack id, <path>:<name>, such as apps/web:dev, never apps/web, or let the scan create the stack with createInBackend: true on its entry in sluiceway.yaml. A program that pulls from a private registry works on your laptop and fails on the runner until a step of the workflow logs in to that registry.