The GitHub Action
The sealup action runs the same code as the CLI, in the same process, from the bundle in the release: nothing is downloaded when the job runs. Add it after your build step:
- uses: sealup/sealup@v0.2.1 id: sealup env: SEALUP_PASSWORD: ${{ secrets.SEALUP_PASSWORD }}sealup init writes a whole workflow around this step (see Getting started):
on every push to main, it checks out the code, builds the site, and deploys it.
Pin it to a version
Section titled “Pin it to a version”The step above names a release by its full version. sealup’s GitHub releases are immutable: once
a release is out, its tag cannot be moved or deleted while the release exists, and its name can
never be used again. So @v0.x.y runs the code released as v0.x.y, or nothing at all. sealup init writes the
step for the version you run, each release’s notes on GitHub give the line for that release, and
Dependabot updates it like any other action.
The step needs that version. Without an @, GitHub refuses the step. @main runs whatever is on
main that day: code not yet released, which can change between two runs. sealup has no moving
tag such as @v0.
The other steps of init’s workflow, actions/checkout and actions/setup-node, stay pinned to
a full commit SHA with their version in a comment: nothing locks their tags.
If your policy asks for every action pinned to a commit (zizmor, or OpenSSF Scorecard’s pinned dependencies check), use the release’s commit, shown on its release page, with the version in a comment. It runs the same code as the tag:
- uses: sealup/sealup@<commit SHA> # v0.x.ySecrets
Section titled “Secrets”Secrets go to the step through env:, never through with:: sealup.yml reads them as
${NAME}, as on your computer. Add each one under Settings › Secrets and variables ›
Actions, or in a GitHub environment to keep production’s apart. Before its first line of
output, sealup asks GitHub to mask each secret (each line of a key), and it never prints them.
In a public repository, the server and the host key can be secrets too, and are masked in the
log like one: sealup init offers it (see A public repository).
That hides them from strangers. It does not stop someone who can push from pointing
sealup.yml at another server in the same change: keep the password in an environment that
only main may use, and require review on main.
Inputs
Section titled “Inputs”| Input | Default | What it does |
|---|---|---|
target |
The target to deploy. Needed when sealup.yml has several: CI never shows a picker |
|
config |
Path to sealup.yml. Empty: searched from working-directory up to the repo root |
|
dry-run |
false |
Show every change, change nothing. Writes the plan as JSON and sets status to dry-run |
working-directory |
. |
The folder to run in: where the search for sealup.yml starts |
Outputs
Section titled “Outputs”| Output | What it holds |
|---|---|
status |
deployed, unchanged, dry-run, partial, failed, blocked (a safety net, exit 6) or cancelled. The step fails on the last four |
url |
The target’s url from sealup.yml: use it for environment.url |
uploaded |
Files uploaded (or that would be, on a dry run) |
deleted |
Files deleted (or that would be, on a dry run) |
unchanged |
Files already up to date |
bytes |
Bytes uploaded |
duration |
The whole run, in seconds |
plan |
The path to the plan’s JSON, on a dry run only |
Several targets
Section titled “Several targets”Name the target with with:. A staging deploy on every push and production on a tag, for
example, are two jobs, each with its own environment and secrets:
- uses: sealup/sealup@v0.x.y id: sealup with: target: staging env: STAGING_PASSWORD: ${{ secrets.STAGING_PASSWORD }}A dry run on pull requests
Section titled “A dry run on pull requests”With dry-run: true, the step plans and changes nothing; its job summary lists every change.
Run it on pull requests to review a deploy before it happens. A dry run still logs in to compare
with the server, so it needs the secrets too, and GitHub gives none to pull requests from forks.
One deploy at a time
Section titled “One deploy at a time”init’s workflow sets a concurrency group: a newer push waits for the running deploy, which
is never cancelled half-way. sealup’s own lock covers deploys GitHub cannot see (a laptop,
another workflow): see One deploy at a time.
The log and the summary
Section titled “The log and the summary”The job’s log shows the same lines as a terminal, with the list of changes in a collapsed group. The job summary gets a table of the target, the counts, the timing, and the changes. A stop is an error annotation with its reason and a link to its page here; plain FTP and a dropped connection get their own annotation.
Without the action
Section titled “Without the action”The action is a convenience: in any CI, npx sealup@<version> deploy does the same, with the
variables in the job’s environment.