Commands
Every hushrun command, grouped by what it's for, with its usage, the flags that matter, their defaults and an example. hushrun <command> --help prints every flag.
In a repository that npx hushrun init set up, hushrun is in devDependencies, so package.json scripts call it as hushrun. Anywhere else, npx hushrun <command> runs it.
Everyday
hushrun run
Runs a check's command unless this exact code already passed it, and records the result. How skipping works explains the key and every line it prints, and Where results go where it records.
Usage: hushrun run [NAME] -- COMMAND
| Argument or flag | Default | What it does |
|---|---|---|
NAME | The package. script that runs it, else the program's name | The check's name, part of its key |
COMMAND | Required | Everything after -, run as it is, argument by argument |
- | Off | Runs the command even after a pass, and records the result |
- | The only scope | The scope whose files make the key. Needed when hushrun. has several |
- | The files as they are now | Hashes a commit's files instead |
- | Computed | Uses this source digest instead of hashing |
- | Off | Silences hushrun's own lines |
- hushrun's lines go to stderr and start with
hushrun:. Stdout is the command's. - It exits with the command's exit code, or 0 when it skips: see its exit codes.
--all,--isolated,--timeout,--environment-imageand--planneed--stage, and exit 2 without it. With--stage,runruns a promotion stage's checks instead: see hushrun run --stage.
$ hushrun run unit -- sleep 2 hushrun: unit running: no pass yet for this exact code hushrun: unit passed in 2s; it won't run again on this code $ hushrun run unit -- sleep 2 hushrun: unit skipped: this exact code passed just now (saves 2s)
hushrun init
Sets up hushrun run in the git repository it runs in. It finds the checks among package.json's scripts and the GitHub Actions jobs that run them, signs you in, shows each change it would make, and makes them once you agree:
- wraps each check as
hushrun run -- …, keeping the rest of each file as it was; - names your organization's backend in
package.json, and addshushruntodevDependencieswith the repository's package manager; - gives the GitHub Actions jobs that run those checks
id-token: write, so that CI records results with no secret; - connects a repository on github.com, so that its CI records results with its own ID token; when an admin or owner of the organization runs it, also adds the repository to the organization for promoting its builds, and writes
hushrun.yamlwith its URL on hushrun; - runs a check twice, to show the second run skip.
Usage: hushrun init [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
-, - | Off | Applies the changes without asking. Without a terminal, init needs it |
- | Off | Shows what init would change, and changes nothing: no sign-in, no files, no install |
- | Off | Prints the sign-in page's address instead of opening a browser |
- | Off | Doesn't end by running a check twice |
- | Off | With -, still ends by running a check twice |
- | Off | Writes a starter hushrun. for a promotion pipeline instead |
- | Off | With -: replaces an existing hushrun. |
- | From the origin remote | With -: the repository id, such as github. |
- | develop | With -: the staging stage's branch |
- | main | With -: the production stage's branch |
- | registry. | With -: the staging image repository |
- | registry. | With -: the production image repository |
The last six flags imply --pipeline, and none of the pipeline flags go with --yes, --dry-run, --no-browser, --run or --no-run. init exits 0 when it's done, when there is nothing to do, and when you answer no; 2 for usage errors, such as running outside a git repository or without a terminal and without --yes; and 1 when a file can't be written or the install fails.
$ hushrun init --dry-run Looking at /Users/ana/shop repository github.com/acme/shop packages npm (no lockfile) checks lint, test, typecheck workflows .github/workflows/ci.yml runs test, lint (job test) hushrun init will change: package.json "lint": "eslint ." → "hushrun run -- eslint ." "test": "vitest" → "hushrun run -- vitest run" (vitest alone watches on a terminal) "typecheck": "tsc --noEmit" → "hushrun run -- tsc --noEmit" "hushrun": {"backend": "<your org's URL, once you sign in>"}, where CI, teammates and agents share results devDependencies: "hushrun": "^0.1.0" .github/workflows/ci.yml job test: adds permissions contents: read and id-token: write. The job's token then has only these two: add any other it needs your org connects github.com/acme/shop, so that its CI records results with its own ID token adds github.com/acme/shop to your org, for promoting its builds, unless it is there already hushrun.yaml a new file: repository github.com/acme/shop, the URL the org gives it, and its log key Nothing changed (--dry-run).
hushrun login
Signs in to a backend, so that hushrun run shares results with your organization. hushrun shows a code and opens the page that approves it, where you pick the organization. Once you approve, it saves a token only you can read, registers this machine, and makes the organization's URL the backend hushrun run uses when nothing else names one.
Usage: hushrun login [OPTIONS] [URL]
| Argument or flag | Default | What it does |
|---|---|---|
URL | HUSHRUN_, else the backend in the repository's package., else the last one you signed in to, else https:// | Your organization's URL, such as https://, or a server's address |
- | Off | Prints the approval page's address instead of opening a browser |
URL must use https://, or http:// on localhost, or hushrun exits 2. A server that can't be reached exits 6. HUSHRUN_HOST names another hosted server than https://api.hushrun.com.
Signing in on a machine revoked for going 90 days unused, or by hushrun logout, brings it back. The server can refuse to register the machine, and then hushrun saves nothing and exits 1: when you already have 20 machines in the organization, its message links to your machines page, where you revoke one; when you or an admin revoked this machine in the dashboard, hushrun says to remove its key file, so that it makes a new key.
npx hushrun login
hushrun login https://hushrun.example/o/acmehushrun logout
Revokes the token hushrun login saved for a server, and forgets it, along with the saved backend when it's on that server. hushrun forgets the token even when the server doesn't answer.
Usage: hushrun logout [OPTIONS] [URL]
| Argument | Default | What it does |
|---|---|---|
URL | The server hushrun login would sign in to | The backend, or its host, to sign out of |
hushrun logouthushrun whoami
Shows where hushrun run records results here and what named that backend, the credential that goes there, and who the backend says you are: your organization, and for an agent token its agent, repository, expiry and rate limit. It also shows this machine's key id.
Usage: hushrun whoami [OPTIONS]
It exits 0 when the backend answered, or when results stay on this machine or are off; 1 when the backend refused the credential; and 6 when it couldn't be reached. --format json prints hushrun.whoami/v1.
$ hushrun whoami backend this machine only, in /Users/ana/Library/Caches/hushrun/results share sign in with hushrun login, or name a backend in package.json
Agent tokens
An agent token, which starts with hra_, lets an agent in a sandbox, or CI outside GitHub, record and read results without a browser. Its results record as agent:NAME, for one repository or the whole organization, until it expires or someone revokes it. Each token comes with the agent's key, its one machine, which signs what it records. The sandbox gets them as HUSHRUN_TOKEN and HUSHRUN_MACHINE_KEY: see Agents and sandboxes.
The hushrun token commands are for organization admins, and use their hushrun login, never HUSHRUN_TOKEN. Their backend is --backend, else HUSHRUN_BACKEND, else the backend in the repository's package.json, else the one hushrun login saved. It must be an organization's URL, such as https://api.hushrun.com/o/acme. They exit 2 without a login on that server or when the server answers 400; 1 when it answers 401, 403 or 404; and 6 when it can't be reached or fails.
hushrun token create
Creates an agent token and the agent's key, and shows both once.
Usage: hushrun token create [OPTIONS] --agent <NAME>
| Flag | Default | What it does |
|---|---|---|
- | Required | The agent's name, such as claude-, fleet- or gitlab-. Its results record as agent:NAME |
- | The repository hushrun runs in | host/ of the repository whose results it records and reads |
- | Off | For every repository of the organization instead |
- | 30d | How long it lasts, in whole hours: 12h, 30d, 8w; at most 365d |
- | The server's, 300 on hushrun's hosted service | The most results it records a minute, 1 to 10000 |
- | See above | The organization's backend |
The token goes alone to stdout, so $(hushrun token create …) holds it. Stderr says what it is and which variables to give the sandbox: HUSHRUN_TOKEN, HUSHRUN_PROVIDER=local, and HUSHRUN_BACKEND when the backend isn't on hushrun's hosted service; then the agent's key, a P-256 key hushrun makes and registers with the token, to set as HUSHRUN_MACHINE_KEY, or to keep in a file that HUSHRUN_MACHINE_KEY_FILE names, as a GitLab File variable does. Every sandbox or pipeline of the agent signs as that one machine, and the server records the agent's results only with its signature. Outside a repository, it needs --repository or --org-wide. --format json prints hushrun.token/v1, with the token and the key.
hushrun token create --agent fleet-a
hushrun token create --agent gitlab-ci --org-wide --expires 365dhushrun token list
Lists the organization's agent tokens that aren't revoked, expired ones included: each one's prefix, agent, repository or whole organization, expiry, last use and creator.
Usage: hushrun token list [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | See above | The organization's backend |
hushrun token revoke
Revokes an agent token: anything that uses it is refused from then on.
Usage: hushrun token revoke [OPTIONS] <TOKEN>
| Argument or flag | Default | What it does |
|---|---|---|
TOKEN | Required | The token's id, the prefix hushrun token list shows (hra_ and 6 characters), the token itself, or its agent's name when only one token has it |
- | See above | The organization's backend |
An agent name that more than one token has exits 2 and lists them.
hushrun token revoke hra_AbC123Promotion
These commands run a promotion pipeline: source digests, plans, signed evidence and artifact promotion by digest. Most need hushrun.yaml and the repository's URL on hushrun: see Promotion and Configuration. In a pull request's pipeline, the commands that read or write the repository's events need --config-ref naming the branch it merges into.
Many of them take the same options for the content they work on:
| Option | Default | What it does |
|---|---|---|
- | The only scope | A scope to work on. Repeatable where a command takes several |
- | Off | Every scope |
- | HEAD | The revision |
- | Off | The files as git add - would record them now: what you are about to commit |
- | Computed | Uses this source digest instead of computing it, for one scope only |
hushrun digest
Prints the source digest of each scope. It needs no repository URL, key or server, and without hushrun.yaml the one scope, default, covers every file.
Usage: hushrun digest [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
-, - | Every scope | The scopes to digest |
- | HEAD | The revision to digest |
- | Off | Digests the files as git add - would record them now |
- | Off | Digests a plain directory, such as a clean export |
- | Off | Lists every entry, its kind, hash and path, and the pattern that decided its scope |
- | Off | Writes the exact manifest bytes, for one scope; sha256sum of the file is the digest |
$ hushrun digest sha256:79a343b4…921d api sha256:83bc69ea…7273 web
hushrun plan
Decides what a stage does with the digest, and exits 3 when it's blocked:
| Mode | What the pipeline does |
|---|---|
promote | Deploys the artifact an earlier stage built and validated, copied by digest |
refresh | Runs only the checks whose evidence is missing, expired or failed, then promotes |
full | Builds, runs the checks that lack valid evidence, and deploys |
wait | Nothing yet: an upstream run for this digest is still going |
skip | Nothing: this stage already runs this digest |
blocked | Nothing, and the run fails: the upstream failed this digest, or evidence is missing that this stage can't produce |
Usage: hushrun plan [OPTIONS] --stage <STAGE>
| Flag | Default | What it does |
|---|---|---|
- | Required | The stage to plan |
-, - | The only scope | The scopes to plan |
- | HEAD | The revision |
- | Off | Plans for the files as git add - would record them now |
- | From the CI provider, else manual | What started this run: push, upstream, manual or schedule |
- | From the CI provider, else one more than recorded | This run's attempt |
- | Off, or HUSHRUN_ | Builds and runs every check, whatever the evidence. A stage with allow_ is blocked instead |
- | Off | Records started for every scope that deploys |
- | The stage's lease | The lease - records |
- | None | While the decision is wait, asks again every 15 seconds for up to DURATION |
- | Off | Writes the plan as JSON, for later jobs' - |
- | Off | Writes the planner's full input and output |
hushrun plan --stage staging --start --out plan.jsonhushrun guard
Refuses to deploy a revision that is no longer the head of the stage's branch. When the branch moved on, it records superseded, then outputs HUSHRUN_STALE=true and exits 0, or exits 4 with --on-stale fail. When it can't resolve the branch's head, it exits 1 and records nothing.
Usage: hushrun guard [OPTIONS] --stage <STAGE>
| Flag | Default | What it does |
|---|---|---|
- | Required | The stage being deployed |
- | The stage's branch | The branch whose head the revision must be |
- | origin | The git remote whose branch head it reads |
- | skip | skip: record superseded, output stale= and exit 0. fail: record superseded and exit 4 |
It also takes the content options above.
hushrun --plan plan.json guard --stage productionhushrun status
Shows each stage's requirements and evidence for the current digest.
Usage: hushrun status [OPTIONS]
It takes --scope, --all-scopes, --rev and --worktree (see above).
hushrun status --worktreehushrun run --stage
Runs a stage's checks and records their evidence with the repository. Without names it runs the plan's checks to run; without a plan, every source check the stage requires that lacks valid evidence. It exits 8 when a check fails, once its evidence is recorded.
Usage: hushrun run --stage <STAGE> [OPTIONS] [CHECK]... [-- <COMMAND>...]
| Argument or flag | Default | What it does |
|---|---|---|
- | Required | The stage the evidence is for |
CHECK | The plan's checks to run; without a plan, every source check the stage requires that lacks valid evidence | The checks to run |
COMMAND | The check's run | After -: the command of a check that has no run in hushrun. |
- | Off | Every source check the stage requires, skipping those with valid evidence |
- | Off | Runs checks whose evidence is valid too |
- | Off | Runs each check in its pinned image and platform, with Docker or Podman, on an export of exactly the digested files, with no network unless the check declares one, and only its env variables |
- | The check's timeout, else none | Each check's time limit |
- | None | The image this job runs in, pinned by digest. Checks that pin image need it |
It also takes the content options above.
hushrun run --all --stage staging --isolated --worktreehushrun attest
Records evidence other tools produced: check results, artifacts and reports.
Usage: hushrun attest [OPTIONS] --stage <STAGE>
| Flag | Default | What it does |
|---|---|---|
- | Required | The stage the evidence belongs to |
- | None | A check's result, pass or fail. Repeatable |
- | None | An artifact this run built, at its location for the stage. A tag is resolved to its digest. Repeatable |
- | None | A report the checks produced, recorded by digest. Repeatable |
- | 0s | How long the checks ran |
- | 1 | The attempts the checks took |
- | None | The image the checks ran in, pinned by digest. Checks that pin image need it |
It also takes the content options above.
hushrun attest --stage staging --check unit=pass --duration 95shushrun mark
Records a lifecycle event: started, deployed, passed, failed or superseded.
Usage: hushrun mark [OPTIONS] --stage <STAGE> <KIND>
| Argument or flag | Default | What it does |
|---|---|---|
KIND | Required | started, deployed, passed, failed or superseded |
- | Required | The stage |
- | None | Why it failed, for failed; stale or cancelled, for superseded |
- | None | An artifact deployed or passed, at its location for the stage. A tag is resolved to its digest. Repeatable |
- | None | Where it was deployed, for deployed |
- | None | The revision that took over, for superseded |
It also takes the content options above.
hushrun --plan plan.json mark deployed --stage productionhushrun approve
Records your signed approval of an approval check, for a digest and a stage. It shows what you approve, and signs it, by default with this machine's key. Approvals are people's: in CI, or signing as an agent, it exits 2 and records nothing.
Usage: hushrun approve [OPTIONS] --stage <STAGE> <CHECK>
| Argument or flag | Default | What it does |
|---|---|---|
CHECK | Required | The approval check, as hushrun. names it |
- | Required | The stage that requires the approval |
- | None | Why, recorded with the approval, up to 1000 characters |
- | Off | Writes the signed event to FILE instead of recording it, to upload elsewhere, such as the dashboard |
It also takes the content options above.
hushrun approve release --stage production --comment "QA signed off"hushrun verify
Verifies events and shows who signed them. It exits 5 when verification fails.
Usage: hushrun verify [OPTIONS] [FILES]...
| Argument or flag | Default | What it does |
|---|---|---|
FILES | None | Event files to verify |
- | None | Verifies every event the repository holds for this digest instead |
- | Asks the repository's server | The signers hushrun repository signers - saved, to verify files offline |
hushrun verify --scope default --digest sha256:…hushrun artifact resolve
Outputs the reference to deploy for the plan's decision, and copies the artifact to this stage's location by digest when it lives elsewhere. When the copy fails, it falls back to a build, with HUSHRUN_BUILD=true and a warning that says why. With --no-fallback, or for a stage that requires deployment checks, it exits 7 instead.
Usage: hushrun artifact resolve [OPTIONS] --stage <STAGE>
| Flag | Default | What it does |
|---|---|---|
- | Required | The stage being deployed |
- | The only scope | The scope |
- | Off | Without a plan, decides for the files as git add - would record them now |
- | The revision | The tag written next to the digest |
- | Off | Exits 7 when the copy fails, instead of falling back to a build |
Registry credentials come from the Docker configuration, so docker login and gcloud auth configure-docker work as they are.
hushrun --plan plan.json artifact resolve --stage productionhushrun artifact copy
Copies an image or index to another repository by digest, and exits 7 when the transfer fails.
Usage: hushrun artifact copy [OPTIONS] <SOURCE> <DESTINATION>
| Argument | What it does |
|---|---|
SOURCE | The source, pinned by digest or tagged; a tag is resolved first |
DESTINATION | The destination repository, REPOSITORY or REPOSITORY:TAG |
hushrun artifact copy us-docker.pkg.dev/acme/staging/api@sha256:… us-docker.pkg.dev/acme/prod/api:v1hushrun artifact digest
Prints the digest a reference points to.
Usage: hushrun artifact digest [OPTIONS] <REFERENCE>
hushrun artifact digest us-docker.pkg.dev/acme/staging/api:v1hushrun policy validate
Validates hushrun.yaml, and exits 2 at an error, which names the file, line and column. It reads the working tree's file and needs no server; in a pull request's pipeline, it reads the pull request's own file.
Usage: hushrun policy validate [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | The working tree | Validates hushrun. at this revision instead |
$ hushrun policy validate hushrun.yaml is valid: 2 scope(s), 3 check(s), 1 artifact(s), 2 stage(s)
hushrun policy explain
Shows a stage's requirements, whose events count for each, and whether hushrun's server makes the stage CI-only. Without a repository URL, or when the server doesn't answer within 15 seconds, it shows the rest and says that CI-only stages weren't checked.
Usage: hushrun policy explain [OPTIONS] --stage <STAGE>
| Flag | Default | What it does |
|---|---|---|
- | Required | The stage |
- | Asks the repository's server | The signers hushrun repository signers - saved, to tell offline whether the stage is CI-only |
hushrun policy explain --stage productionhushrun adopt
Writes a starter hushrun.yaml and GitHub Actions workflows that call hushrun's reusable deploy workflow, and prints the next steps.
Usage: hushrun adopt [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | The CI provider's, else the origin remote's | The repository id, such as github. |
- | staging=, production= | A stage and its branch, in delivery order. Repeatable |
- | None | A stage's image repository. Repeatable |
- | HUSHRUN_ | The organization's base URL, under which each repository's URL is <base>/ |
- | This release's | The reusable workflow to call, pinned by commit |
- | This one's | The hushrun version the workflows install |
- | Off | Prints what it would write, and writes nothing |
- | Off | Replaces files that differ from what adopt writes |
hushrun adopt --dry-runServer and setup
hushrun repository ls
Lists the repository's events on hushrun's server.
Usage: hushrun repository ls [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | All | Events of this scope |
- | All | Events of this digest; needs - |
- | All | Events of this stage |
hushrun repository show
Shows one event.
Usage: hushrun repository show [OPTIONS] <KEY>
hushrun repository signers
Shows the signers whose events count for the repository, as its server names them, with the server's signed statement over them.
Usage: hushrun repository signers [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | Off | Saves the answer, for hushrun verify - and hushrun policy explain - |
hushrun repository signers --out signers.jsonhushrun repository gc
Deletes events older than a duration, except the newest deployment of each scope and stage and the events of its digest. For organization admins.
Usage: hushrun repository gc [OPTIONS] --older-than <DURATION>
| Flag | Default | What it does |
|---|---|---|
- | Required | Deletes what was written more than this long ago, such as 180d |
- | Off | Lists what it would delete, and deletes nothing |
- | The command's signer | The key that signs each deletion, on a server that keeps a transparency log |
hushrun repository gc --older-than 180d --dry-runhushrun repository monitor
Replays the repository's transparency log on hushrun's server, and checks every checkpoint, and every listing that plans recorded against it. It exits 5 when the server contradicts its own log, and needs transparency_log in hushrun.yaml.
Usage: hushrun repository monitor [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | Off | Remembers the newest checkpoint in FILE, and checks the next run against it |
hushrun repository monitor --state monitor.jsonhushrun repository usage
Shows the organization's plan and the checks recorded this period, against what the plan includes and its limit, with this repository's share. It asks the backend hushrun run records to, as hushrun whoami shows it, with the same credential. Results kept on this machine aren't metered. It exits 0, or 6 when the server can't be reached, refuses the credential or answers something else. See Plans and limits.
Usage: hushrun repository usage [OPTIONS]
$ hushrun repository usage backend this machine only, in /Users/ana/Library/Caches/hushrun/results usage results stay on this machine, so nothing is metered
hushrun repository stats
Counts what hushrun recorded, to share volume without telemetry, and prints what you may choose to paste. It sends nothing else anywhere.
Usage: hushrun repository stats [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | 30d | Counts what was recorded in this long, such as 7d or 12w |
- | Off | Counts this machine's hushrun run results, in hushrun's cache directory, instead of the repository's events on the server: by verdict, by check, distinct run keys and the time skips saved |
Without --local, it reads one listing of the repository's events, and no event: events by kind, distinct digests, and check events by stage.
$ hushrun repository stats --local hushrun run's results on this machine in the last 30d (since 2026-09-27 16:51 UTC), in /Users/ana/Library/Caches/hushrun/results total 11 by verdict skip 5, pass 4, fail 2 run keys 5 by check unit 7, lint 4 saved by skips 4s
hushrun sigstore refresh
Updates the Sigstore trust root, which verifies keyless signatures and timestamps, from its TUF repository. hushrun verifies what it gets, and caches it for offline verification. It exits 9 when the TUF repository can't be reached.
Usage: hushrun sigstore refresh [OPTIONS]
hushrun keys generate
Generates a signing key, PKCS#8 PEM with mode 0600. It never overwrites a key file.
Usage: hushrun keys generate [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | Stdout | Writes the private key to FILE |
- | ed25519 | ed25519, or ecdsa-, which hardware keys use |
$ hushrun keys generate --out signing.pem public key: ed25519:e2iTpmZCZRojWi76uPqruO7B6y5vW26tItDTBpv6Mh0= key id: sha256:0c33bcfe…1a97 private key: signing.pem (mode 0600)
hushrun keys public
Prints the public key and key id of a private key.
Usage: hushrun keys public [OPTIONS]
| Flag | Default | What it does |
|---|---|---|
- | The key this command would sign with: HUSHRUN_, HUSHRUN_ or this machine's | The private key |
hushrun doctor
Checks the setup and says what to fix: git, the CI provider, where results go, hushrun.yaml, the repository's URL, server and signers, its transparency log, the clock, the signer, the timestamp authorities and the Sigstore trust root, registry access, the deploy workflow, configuration baked into the source, and the default branch, or on GitLab its API, protected branches and who may set pipeline variables. It exits 2 when any check fails; warnings don't change the exit code. --format json prints hushrun.doctor/v1.
Usage: hushrun doctor [OPTIONS]
hushrun doctor --repository-url https://api.hushrun.com/l/acme/shopGlobal options
Every command takes these, before or after its name. A flag wins over its variable.
| Option | Variable | Default | What it does |
|---|---|---|---|
-, - | None | The current directory | Runs as if hushrun started in DIR |
- | HUSHRUN_ | hushrun. in the content being evaluated | The path of hushrun. |
- | None | None | Reads hushrun. from this git ref, such as origin/. A pull request's pipeline must name the branch it merges into. Doesn't go with - |
- | HUSHRUN_ | hushrun.'s repository_ | The repository's URL on hushrun. In CI only HUSHRUN_ counts, and a different - exits 2 |
- | HUSHRUN_, which holds the plan itself | None | The plan this command carries out: a file, or - for stdin |
- | HUSHRUN_ | text | The output format on stdout: text, json, env or dotenv |
- | None | None | Also writes the outputs to FILE in dotenv form, for GitLab |
- | HUSHRUN_ | Off | Writes no CI outputs, step summaries or annotations |
-, - | HUSHRUN_ | Warnings | More logging on stderr: - info, - debug, - trace |
-, - | None | Off | Errors only on stderr. In hushrun run without a stage, none of hushrun's lines |
- | NO_ | auto | Colored logs: auto, always or never. auto colors them when stderr is a terminal and NO_ isn't set |
-, - | None | The available cores | Threads that hash files |
-, - | None | None | Prints help. - says more than - |
-, - | None | None | Prints the version |
Environment variables has every variable, and Configuration the order in which hushrun reads them.
Output formats
--format decides what a command prints on stdout. Logs and messages always go to stderr.
| Format | What stdout gets |
|---|---|
text | Lines for people. The default |
json | One JSON object on one line, whose schema field names its shape, such as hushrun. |
env | HUSHRUN_ lines, quoted for a POSIX shell's eval |
dotenv | The same lines unquoted, as GitLab's dotenv reports read them. hushrun refuses values of several lines, more than 20 variables, or 5 KiB or more, and leaves out HUSHRUN_ |
--dotenv FILEwrites the dotenv form to FILE as well, whatever--formatis, fordigest,plan,guard,attest,markandartifact.- A command without outputs prints text for
envanddotenv. - On GitHub Actions,
plan,digest,guard,attestandartifactalso append their outputs to$GITHUB_OUTPUTunder their lowercase names, such asmodeanddigest, write a step summary, and annotate the run, unless--no-ci-outputis given. - Keep the output in a variable before you
evalit:out=$(hushrun guard --stage production --format env) && eval "$out".eval "$(hushrun …)"succeeds even when hushrun fails.
The outputs, by command, with <SCOPE> and <ARTIFACT> uppercased and - written as _:
| Command | Outputs |
|---|---|
hushrun digest | HUSHRUN_, or HUSHRUN_ for each of several scopes; HUSHRUN_ |
hushrun plan, one scope | HUSHRUN_, HUSHRUN_, HUSHRUN_, HUSHRUN_, HUSHRUN_, HUSHRUN_, HUSHRUN_, HUSHRUN_ (JSON), HUSHRUN_ and HUSHRUN_ (names separated by spaces), HUSHRUN_ (the whole plan) |
hushrun plan, several scopes | HUSHRUN_, HUSHRUN_, HUSHRUN_ (JSON), HUSHRUN_ |
hushrun guard | HUSHRUN_ (true or false), HUSHRUN_ |
hushrun attest | HUSHRUN_, HUSHRUN_, HUSHRUN_ for a single artifact, HUSHRUN_ |
hushrun mark | HUSHRUN_, HUSHRUN_ |
hushrun artifact resolve | HUSHRUN_, HUSHRUN_ and HUSHRUN_ for a single artifact, HUSHRUN_ |
hushrun artifact copy, hushrun artifact digest | HUSHRUN_, HUSHRUN_ |
hushrun keys generate, hushrun keys public | HUSHRUN_, HUSHRUN_ |
$ hushrun digest --format env HUSHRUN_DIGEST_API=sha256:79a343b4…921d HUSHRUN_DIGEST_WEB=sha256:83bc69ea…7273 HUSHRUN_REVISION=c3b57fb1add5a62e13a97fa1324e083067bc48c1 $ hushrun digest --scope api --format json {"canonicalization":"hushrun-source-v1","schema":"hushrun.digest/v1","scopes":[{"bytes":13,"digest":"sha256:79a343b4…921d","files":1,"scope":"api"}],"source":{"objectFormat":"sha1","ref":"refs/heads/main","revision":"c3b57fb1add5a62e13a97fa1324e083067bc48c1","tree":"bc00258b51f36ddfe425f303ce7239b69fb1b29d","vcs":"git"},"stats":{"cacheHits":1,"elapsedMs":1,"entries":3,"hashed":0,"hashedBytes":0}}
Exit codes
Every command
| Code | Meaning | Where |
|---|---|---|
| 0 | Success | Every command. plan: any decision but blocked. guard: a stale revision with - |
| 1 | An unexpected error | Every command. whoami: the backend refused the credential. token: the server answered 401, 403 or 404. init: a file couldn't be written, or the install failed. guard: the branch's head can't be resolved |
| 2 | A usage or configuration error | Every command: a flag or variable hushrun can't take, a hushrun. that doesn't validate, a missing repository URL, or one that doesn't match in CI. doctor: a check failed. init: no terminal and no -. approve: run in CI |
| 3 | Blocked | plan |
| 4 | Stale | guard -: the revision is no longer the head of the stage's branch |
| 5 | Verification failed | verify. repository monitor: the server contradicts its own log |
| 6 | The server is unavailable or refused access | Commands that read or write the repository's events, and a write refused for the organization's plan, other than a check result. whoami, login, token and repository usage when the server can't be reached |
| 7 | The transfer failed | artifact copy. artifact resolve with -, or for a stage that requires deployment checks |
| 8 | A check failed, and its evidence was recorded | run - |
| 9 | The signer is unavailable or refused | Commands that sign: the CI's ID token, Fulcio, or every timestamp authority. sigstore refresh: the TUF repository |
hushrun run without a stage
hushrun run [NAME] -- COMMAND ends as the command does, so a script or CI job reads the check's own result:
| Code | When |
|---|---|
| The command's | It ran. A code outside 0 to 255 becomes 1 |
| 0 | It skipped: this exact code already passed |
| 2 | A usage error: no command after -, more than one NAME, no NAME when the program gives none, or a flag that needs -. The command doesn't run |
| 126 | The command was found but can't start, such as a file without execute permission |
| 127 | The command wasn't found |
| 128 + N | The command was stopped by signal N, such as 143 after SIGTERM. Nothing is recorded |
Results being off, a backend that can't be reached, one that refuses the credential, or a variable hushrun can't read never change the exit code: the command runs, and its code is hushrun's.