@duabalabs/dps-cli
dps — command-line client for the DPS mobile release infrastructure.
Authenticate with a deploy token, then upload mobile artifacts (.ipa /
.apk / .aab), create / publish / roll back releases, validate a repo for
managed builds, and dispatch remote builds. Designed to run from a terminal or
external CI (GitHub Actions, Bitrise, etc.).
- Source:
apps/dps/dps-cli - Binary:
dps· Version:0.1.0· Requires: Node 18+ (uses globalfetch) - Transport: REST under
/api/v1/*on your DPS server,Authorization: Bearer <token>
Install
npm i -g @duabalabs/dps-cli # or: pnpm add -g @duabalabs/dps-cli
dps --versionFrom inside the monorepo (linked locally):
cd apps/dps/dps-cli
npm install
npm run build
npm link # exposes the `dps` binary globallyAuthenticate
dps login saves your DPS API URL and deploy token to a local config file
(via conf — e.g.
~/Library/Application Support/dps-cli/config.json on macOS).
dps login --url https://api.dps.example.com --token dps_xxxxxxxx
dps whoami # GET /api/v1/whoami — prints the identity for the token
dps logout # removes saved credentialsBoth --url and --token are required on login.
Per-invocation credentials
Environment variables take precedence over the saved config, which is handy in
CI where you don’t want to run login:
export DPS_API_URL=https://api.dps.example.com
export DPS_TOKEN=dps_xxxxxxxx
dps artifact list --app <appId>Generate a deploy token in the dashboard (Settings → Deploy Tokens → New
Token) or via the dps_deployToken_create cloud function. Tokens are shown
exactly once — store them in a secret manager / CI secret.
Artifacts
# Upload a built mobile binary (.ipa / .apk / .aab).
# --type and --platform are auto-detected from the file extension.
dps artifact upload ./build/app.aab \
--app <appId> --version 1.2.3 --build-number 42
# List artifacts for an app
dps artifact list --app <appId> --platform android --status verified
# Register an externally-hosted artifact (no DPS upload)
dps artifact register --app <appId> --platform ios --type ipa \
--url https://cdn.example.com/app.ipa --checksum <sha256> --size <bytes>dps artifact upload runs a three-step flow:
- Computes the file’s SHA-256 locally.
POST /api/v1/artifacts/upload-url→ receives anartifactIdand a presigned URL.- PUTs the file to that URL, then
POST /api/v1/artifacts/{id}/finalizewith the checksum + size so the server verifies the upload and marks the artifactverified.
dps artifact upload flags
| Flag | Required | Notes |
|---|---|---|
--app <appId> | yes | DPS appId (Parse objectId of the mobile app) |
--platform <ios|android> | no | Auto-detected from --type |
--type <ipa|apk|aab> | no | Auto-detected from the file extension |
--version <semver> | no | e.g. 1.2.3 |
--build-number <n> | no | Build number |
--source <source> | no | Source tag (default local) |
dps artifact register requires --app, --platform, --type and --url;
--version, --build-number, --checksum and --size are optional (it tags
the record source: external-ci).
Releases
# Create a release from one or more artifact ids (--artifact is repeatable)
dps release create --app <appId> \
--artifact <iosArtifactId> --artifact <androidArtifactId> \
--version 1.2.3 --channel production --environment production \
--name "Spring release" --notes "Bug fixes"
dps release list --app <appId> --channel production --status published
dps release publish <releaseId> --target play-store
dps release rollback <releaseId> --to <previousReleaseId>| Command | Endpoint | Notes |
|---|---|---|
release create | POST /api/v1/releases | At least one --artifact <id> is required |
release list | GET /api/v1/releases | Filter with --channel, --status |
release publish <id> | POST /api/v1/releases/{id}/publish | --target e.g. app-store, play-store — queues store submission |
release rollback <id> | POST /api/v1/releases/{id}/rollback | --to <previousReleaseId> optional |
release create flags: --app (required), --artifact <id> (repeatable,
required), --name, --version, --channel (e.g. production, beta,
internal), --environment (e.g. production, staging), --notes.
One-shot publish
dps publish ./build/app.aab \
--app <appId> --version 1.2.3 \
--channel production --notes "Bug fixes" --auto-publishdps publish chains the whole flow: upload → finalize → create release →
(optionally) mark it publishing. Pass --auto-publish to immediately queue
the new release for store submission; omit it to stop after the release is
created. Flags mirror artifact upload + release create
(--platform, --type, --build-number, etc.).
Repo validation & remote builds
DPS classifies every connected repo as managed or artifact-only.
| Mode | Required files | Capabilities |
|---|---|---|
| managed | package.json + .dps/config.json + .github/workflows/dps-build.yml | DPS can dispatch builds remotely in the client repo |
| artifact-only | none of the above | upload artifacts manually or via external CI; releases + publishing still work |
# Local check (no server call) — run inside the repo
dps doctor # alias: dps validate
dps doctor --json
dps doctor --cwd ./my-app # check a different repo root
# Server-side check (uses the GitHub App) for a connected app
dps repo check --app <appId> --ref main
dps repo status --app <appId>
# Trigger a managed build (dispatches dps-build.yml in the client repo)
dps build trigger --app <appId> --platform android --profile production --ref maindps doctor inspects the working directory and prints what it detected
(package.json, .dps/config.json, the dps-build.yml workflow, Expo
app.json / eas.json, native android/ or ios/ projects, monorepo
markers, and the package manager). It reports managed when all three
required files are present, otherwise artifact-only, and exits non-zero when
incompatible.
| Command | Endpoint | Notes |
|---|---|---|
doctor / validate | — (local only) | --cwd, --json; non-zero exit if incompatible |
repo check | POST /api/v1/repo/validate | --app required, --ref defaults to main |
repo status | GET /api/v1/repo/status | Cached validation status for --app |
build trigger | POST /api/v1/builds/dispatch | --app, --platform required; --profile default production; --ref optional |
dps build trigger requires the repo to validate as managed; otherwise the
server returns an error explaining which files are missing.
Command summary
dps login --url <url> --token <token> Save API URL + deploy token
dps logout Remove saved credentials
dps whoami Show identity for the saved token
dps artifact upload <file> --app <appId> [--platform] [--type] [--version] [--build-number] [--source]
dps artifact list --app <appId> [--platform] [--status]
dps artifact register --app <appId> --platform --type --url [--version] [--build-number] [--checksum] [--size]
dps release create --app <appId> --artifact <id>... [--name] [--version] [--channel] [--environment] [--notes]
dps release list --app <appId> [--channel] [--status]
dps release publish <releaseId> [--target]
dps release rollback <releaseId> [--to <previousReleaseId>]
dps publish <file> --app <appId> [--platform] [--type] [--version] [--build-number] [--channel] [--notes] [--auto-publish]
dps doctor [--cwd <dir>] [--json] (alias: dps validate)
dps repo check --app <appId> [--ref]
dps repo status --app <appId>
dps build trigger --app <appId> --platform <ios|android> [--profile] [--ref]Environment variables
| Variable | Purpose |
|---|---|
DPS_API_URL | DPS API base URL — overrides the saved apiUrl |
DPS_TOKEN | Deploy token — overrides the saved token, sent as Authorization: Bearer |
Both fall back to the saved login config when unset. If neither is available,
commands that hit the server fail with a “Run dps login first” error.
See also
- Mobile builds — full end-to-end build & publish guide.
- API Reference — the REST endpoints the CLI calls.
@duabalabs/dps-client— the subscription-registry client.