Octopus Deploy CLI (octopus)
Preflight
octopus --version # need >= 2.21.0 for `octopus api`
octopus space list --no-prompt # cheap auth + connectivity check
This skill drives the real binary; it has no other way to reach the server. If
octopus isn't found, stop and point the user at the
installation guide
rather than trying to hand-roll REST calls — they'd have no credentials to use
anyway. On Windows the CLI is often installed but not on PATH; check
C:\Program Files\Octopus CLI\octopus.exe before concluding it's absent.
If the version is below 2.21.0, octopus api doesn't exist and every
diagnostic workflow here needs the raw-HTTP fallback in references/rest-api.md.
Say so rather than silently degrading — upgrading is usually the better fix.
Auth comes from OCTOPUS_URL + OCTOPUS_API_KEY (env wins over the config
file), or octopus login. Config lives at %AppData%\octopus\cli_config.json
on Windows, ~/.config/octopus/cli_config.json elsewhere.
If you are not authenticated, the CLI cannot even show you its own help.
octopus release --help prints an ASCII octopus and exits 3 until a server is
configured. So if help output looks like a splash screen, fix auth first — you
are not looking at a broken command.
Three rules that prevent most failures
1. Always pass --no-prompt. The CLI is interactive by design: omit a
required flag and it opens a picker rather than failing. In a non-interactive
session that either hangs or consumes your next input as a menu selection.
--no-prompt converts "ask the user" into "error out", which is what you want —
a clear error tells you which flag you forgot.
2. Pick the output format for the job.
| Format | Use it for | Why |
|---|---|---|
-f json | reading data you'll filter | machine-parseable, suppresses status chatter |
-f basic | capturing a value into a variable | prints only the value, one per line |
-f table (default) | showing a human the result | adds banners and a web URL that corrupt a capture |
-f basic is the format the CLI was given so its output could be piped:
release create prints just the version, release deploy and runbook run
print just the server task IDs.
3. Name the space explicitly with -s "<name or id>" (or OCTOPUS_SPACE).
Real servers have dozens of spaces — the public samples server has 35 — and a
project name is only unique within one. Without -s the CLI either prompts or
silently uses a default that isn't the one the user meant.
The core workflow: create → deploy → wait
Deployments do not block. The CLI deliberately returns as soon as the server accepts the task ("we are not going to show servertask progress in the CLI"), so you must wait on the task yourself or you'll report success for a deploy that later failed.
VER=$(octopus release create -p "MyProject" -c Default --no-prompt -f basic)
TASK=$(octopus release deploy -p "MyProject" --version "$VER" -e Dev --no-prompt -f basic)
octopus task wait "$TASK" --progress --timeout 1800
PowerShell — same shape, but keep the capture a single string:
$ver = (octopus release create -p "MyProject" -c Default --no-prompt -f basic) -join ''
$task = (octopus release deploy -p "MyProject" --version $ver -e Dev --no-prompt -f basic) -join ''
octopus task wait $task --progress --timeout 1800
task wait takes several IDs separated by spaces, and exits non-zero if any
task failed (one or more deployment tasks failed: ServerTasks-…), so it works
as a CI gate. Raise --timeout — the default is 600 seconds, shorter than plenty
of real deployments, and a timeout looks exactly like a failure if you only check
the exit code.
Check for a manual-intervention step before you promise to wait. If the
deployment process has one scoped to the target environment, the task starts,
reaches that step, and sits in "awaiting manual intervention" until a human
answers in the portal. task wait will block there until it times out — so a
report of "deployed" would be false, and the non-zero exit is indistinguishable
from a real failure. Look before you commit to the wait:
octopus api "/api/$SPACE/deploymentprocesses/deploymentprocess-$PROJECT_ID" \
| jq '.Steps[] | select(.Actions[].ActionType=="Octopus.Manual") | {Name, Environments: .Actions[0].Environments}'
If there is one, tell the user the deploy will pause for their approval rather
than run to completion. The CLI has no approvals command at all — see
references/workflows.md §8.
When the CLI has no command for it
The CLI covers create/list/view/delete of most entities, but octopus task has
exactly one subcommand: wait. There is no task list, no task view, no log
retrieval, no deployment history, no approvals, no artifacts. octopus channel
can only create — it cannot list.
Reach for octopus api rather than concluding it's impossible:
octopus api "/api/Spaces-302/tasks?states=Failed&name=Deploy&take=5"
octopus api /api/tasks/ServerTasks-2545109/raw # plain-text task log
Octopus's API is hypermedia — every resource carries a Links dictionary, so
fetch the resource and read where to go next instead of guessing URLs:
octopus api /api/tasks/ServerTasks-2545109 | jq .Links
# Raw, Details{?verbose,tail,ranges}, Interruptions, Artifacts, Cancel, Web, …
octopus api is GET-only and the path must start with /api. For writes, and on
CLI versions below 2.21, use plain HTTP with an X-Octopus-ApiKey header. Full
details, the verified endpoint table and paging: references/rest-api.md.
Before you change anything
Reads (list, view, api, task wait, config get) are free — run them
freely, they're how you answer questions.
Anything that creates, deploys, deletes, disables, uploads or runs a runbook
goes to the user first: show the exact command plus the resolved space, project,
environment(s) and tenant(s), and wait for a go-ahead. A deployment isn't
revertible the way a file edit is — a wrong -e Production or --tenant-tag
ships code to real customers, and "I'll redeploy the old release" is a second
outage, not an undo. Naming the resolved targets also catches the common failure
where a project name matched in the wrong space.
Once approved, run it with --no-prompt so it can't stall half-configured.
Gotchas
runbook run's own--helpexample is wrong. It shows--runbook "..."; the flag is-n, --name.-vmeans different things. Onrelease createit's--version. Onrelease deployit's--variableand the version flag is the long--versiononly. Getting this wrong sets a prompted variable to your version number and deploys whatever release the server picks.-f jsonis the CLI's own projection, not the API resource, and how thin it is varies per command.environment listgives youIdandNameand nothing else;deployment-target listis generous. Check what you actually got before concluding a field doesn't exist — if it's missing,octopus apihas it.- Key casing is inconsistent across commands —
project listemitsId,release listemitsID. Check before you write a filter. octopus apidoes not scope to your space. It uses the system client, so put the space ID in the path yourself:/api/Spaces-302/tasks, not/api/tasks. Get IDs fromoctopus space list -f json.- Tag flags use
Tag Set Name/Tag Name—--tenant-tag "Regions/South",--runbook-tag. A bare tag name silently matches nothing. release deploy --deploy-atschedules rather than deploys. The task won't start until then, sotask waitwill sit there until it times out.- Config-as-code projects need
--git-refonrelease create(and onrunbook runwhen runbooks live in Git), otherwise you get the default branch.
Command map
| Area | Commands |
|---|---|
| Releases | release create, deploy, list, delete, progression allow/prevent |
| Runbooks | runbook run, list, delete, snapshot |
| Tasks | task wait — everything else is REST |
| Projects | project list/view/create/clone/delete/enable/disable/convert/tag, project branch, project variables |
| Packages | package upload, list, versions, delete, zip create, nuget create |
| Build info | build-information upload, list, view, delete, bulk-delete |
| Infrastructure | deployment-target (kubernetes, ssh, azure-web-app, cloud-region, listening/polling-tentacle), worker, worker-pool, environment, account |
| Tenants | tenant list/view/create/clone/connect/disconnect/tag, tenant variables |
| Spaces / config | space list/view/create/delete, config get/set/list, login, logout |
| Raw REST | api <path> (GET only, 2.21+) |
References
Load these as needed — don't read them upfront.
references/commands.md— every command's verbatim--help(181 commands, ~3500 lines). It's big: grep it for the command you need, don't read it whole. Regenerate after a CLI upgrade withscripts/dump-help.ps1.references/workflows.md— end-to-end recipes: investigating a failed deployment, promoting a release through environments, tenanted deploys, config-as-code, CI package publishing, handling approvals.references/rest-api.md— the escape hatch:octopus apiusage and limits, theLinksdiscovery pattern, verified endpoints, paging, and raw HTTP for writes.