UiPath Documentation
uipath-cli
latest
false

UiPath CLI user guide

Last updated May 7, 2026

Your first pipeline

This page shows how to take a UiPath Solution on disk and ship it to Orchestrator end-to-end: pack it locally, publish it to your tenant's solution feed, and deploy it to a folder. It uses the solution tool, which works the same from a developer laptop and from a CI pipeline.

What you need

  • UiPath CLI installed and a logged-in session. See Installing UiPath CLI and Authentication.
  • A UiPath Solution on disk. uip solution pack accepts either of two shapes (matching the CLI's own solution pack --help):
    • a solution directory containing a .uipx solution descriptor (the common case — what Studio writes and what uip solution new creates), or
    • a standalone .uis file (a pre-bundled Solution artifact).
  • An Orchestrator folder path where you want the Solution deployed (for example, Shared/MySolutionFolder).

The flow

Three commands, each a separate step so you can run them independently in a CI pipeline:

  1. uip solution pack — produce a versioned .zip package from the solution directory.
  2. uip solution publish — upload the .zip to the tenant's solution feed.
  3. uip solution deploy run — create a folder and deploy the published package into Orchestrator.

Step 1. Pack the Solution

uip solution pack ./my-solution ./dist \
  --name my-solution \
  --version 1.0.0
uip solution pack ./my-solution ./dist \
  --name my-solution \
  --version 1.0.0

Arguments:

  • The first positional argument is the solution directory (or a .uis file).
  • The second is the output directory. uip creates it if missing.

Flags:

  • --name overrides the package name (default: the solution directory name).
  • --version sets the package version (default: 1.0.0). Use semantic versioning for readability and to let Orchestrator sort versions correctly.

On success, ./dist/my-solution.1.0.0.zip is written. The JSON response returns Data.Package (formatted as name@version) and Data.Packages (the inner .nupkg filenames). The .zip path itself follows the convention {outputDir}/{name}.{version}.zip, so pipelines can construct it without parsing JSON:

NAME=my-solution
VERSION=1.0.0
uip solution pack ./my-solution ./dist --name "$NAME" --version "$VERSION"
PACKAGE="./dist/${NAME}.${VERSION}.zip"
NAME=my-solution
VERSION=1.0.0
uip solution pack ./my-solution ./dist --name "$NAME" --version "$VERSION"
PACKAGE="./dist/${NAME}.${VERSION}.zip"

Step 2. Publish to the tenant

uip solution publish ./dist/my-solution.1.0.0.zip
uip solution publish ./dist/my-solution.1.0.0.zip

The package is uploaded to the tenant's solution feed. Orchestrator assigns a PackageVersionKey — the identity of this specific version on the tenant. publish is idempotent per (name, version) — re-running it with the same version returns the existing version instead of duplicating.

Tip:

If you are running against a specific tenant from a multi-tenant org, pass --tenant <tenant-name> to publish, pack is tenant-agnostic. When in doubt, uip login status shows the tenant the CLI is currently bound to.

Step 3. Deploy to Orchestrator

uip solution deploy run \
  --name MyFirstDeployment \
  --package-name my-solution \
  --package-version 1.0.0 \
  --folder-name MySolutionFolder \
  --folder-path Shared
uip solution deploy run \
  --name MyFirstDeployment \
  --package-name my-solution \
  --package-version 1.0.0 \
  --folder-name MySolutionFolder \
  --folder-path Shared

Flags (required unless stated):

  • --name — the deployment name (not the package name). Use something meaningful; this identifies the deployment for future deploy status / deploy activate calls.
  • --package-name, --package-version — match what you published in Step 2.
  • --folder-name — the Orchestrator folder to create for this deployment.
  • --folder-path — the parent folder path. Shared is the tenant root.
  • --folder-key — the parent folder GUID; use this instead of --folder-path if you prefer to bind by ID.

deploy run polls Orchestrator until the deployment reaches a terminal state (default poll timeout 360 seconds, adjustable with --timeout). The response carries the new folder's path and the deployment key.

Note:

--name and --folder-name are two different things. --name names the deployment record; --folder-name names the new Orchestrator folder that the deployment creates. Picking the same value for both is fine and common.

Putting it together in CI

#!/usr/bin/env bash
set -euo pipefail

uip login \
  --client-id env.UIPATH_CLIENT_ID \
  --client-secret env.UIPATH_CLIENT_SECRET \
  --tenant "$UIPATH_TENANT"

uip solution pack ./my-solution ./dist --version "$BUILD_VERSION"
uip solution publish "./dist/my-solution.$BUILD_VERSION.zip"
uip solution deploy run \
  --name "my-solution-$GIT_SHA" \
  --package-name my-solution \
  --package-version "$BUILD_VERSION" \
  --folder-name MySolutionFolder \
  --folder-path Shared
#!/usr/bin/env bash
set -euo pipefail

uip login \
  --client-id env.UIPATH_CLIENT_ID \
  --client-secret env.UIPATH_CLIENT_SECRET \
  --tenant "$UIPATH_TENANT"

uip solution pack ./my-solution ./dist --version "$BUILD_VERSION"
uip solution publish "./dist/my-solution.$BUILD_VERSION.zip"
uip solution deploy run \
  --name "my-solution-$GIT_SHA" \
  --package-name my-solution \
  --package-version "$BUILD_VERSION" \
  --folder-name MySolutionFolder \
  --folder-path Shared

The script exits on the first non-zero status, so a failure in any step aborts the build. uip returns 0 on success and 1 on failure; commands with domain-specific semantics (for example uip tm wait, which reuses 2 for timeout) may return other codes — see Exit codes.

After deployment

With the Solution deployed, Orchestrator has a folder (Shared/MySolutionFolder), a process per deployable project in the Solution, and all associated resources (assets, queues, triggers). You can now:

# confirm the folder exists
uip or folders list --all --path "Shared/MySolutionFolder"

# find the processes that were created
uip or processes list --folder-path "Shared/MySolutionFolder"

# start a job
uip or jobs start <process-key>

# inspect the deployment
uip solution deploy status --deployment-key <deployment-key>
# confirm the folder exists
uip or folders list --all --path "Shared/MySolutionFolder"

# find the processes that were created
uip or processes list --folder-path "Shared/MySolutionFolder"

# start a job
uip or jobs start <process-key>

# inspect the deployment
uip solution deploy status --deployment-key <deployment-key>

What about a single Studio project?

For a single Studio project (a directory with project.jsonnot a Solution), the classic pipeline is pack a .nupkgupload to a feedcreate a process. That flow uses commands from the rpa and or tools:

uip rpa pack ./MyStudioProject ./dist
uip or packages upload ./dist/MyStudioProject.1.0.0.nupkg
uip or processes create \
  --name MyProcess \
  --package-key MyStudioProject \
  --package-version 1.0.0 \
  --folder-path Shared
uip rpa pack ./MyStudioProject ./dist
uip or packages upload ./dist/MyStudioProject.1.0.0.nupkg
uip or processes create \
  --name MyProcess \
  --package-key MyStudioProject \
  --package-version 1.0.0 \
  --folder-path Shared

See uip rpa and the Orchestrator packages and processes references for full flag lists.

Next steps

Was this page helpful?

Connect

Need help? Support

Want to learn? UiPath Academy

Have questions? UiPath Forum

Stay updated