- Vue d'ensemble (Overview)
- Démarrer
- Concepts
- Using UiPath CLI
- Guides pratiques
- CI/CD recipes
- Référence de commande
- Vue d'ensemble (Overview)
- Codes de sortie
- Global options
- uip codedagent
- uip docsai
- add-test-data-entity
- add-test-data-queue
- add-test-data-variation
- analyze
- build
- créer-projet
- diff
- find-activities
- get-analyzer-rules
- get-default-activity-xaml
- get-errors
- get-manual-test-cases
- get-manual-test-steps
- get-versions
- get-workflow-example
- indicate-application
- indicate-element
- inspect-package
- install-data-fabric-entities
- install-or-update-packages
- list-data-fabric-entities
- list-workflow-examples
- pack
- restore
- run-file
- search-templates
- start-studio
- stop-execution
- uia
- uip traces
- Migration
- Reference & support
UiPath CLI user guide
This page picks up where Your first pipeline stops. It assumes you already have the three-command flow working on a single tenant and now want to ship the same Solution across dev → stage → prod, pin versions for reproducibility, and know exactly how to back out a bad release.
If you have not yet packed a Solution end-to-end, read Your first pipeline first — everything here builds on uip solution pack / publish / deploy run.
What this guide covers
- A versioning discipline that plays well with the Orchestrator feed.
- Promoting the same package through multiple tenants without repacking.
- Pinning the CLI and its tools so every build is reproducible.
- Rolling back a broken release with
uip solution packages deleteanduip solution deploy uninstall.
Pick a version, then freeze it
uip solution pack --version controls both the .zip filename and the packageVersion that every downstream step consumes. The default is 1.0.0; a real pipeline should pass it explicitly.
Semantic versioning (MAJOR.MINOR.PATCH) is the scheme the Orchestrator feed sorts best. Two concrete rules make the difference between a clean history and an unsortable one:
- Never reuse a version.
uip solution publishrejects aname+versionpair that already exists in the feed. Treat a rejected publish as a build bug, not as something to "fix" by re-runningpack. - Use build metadata, not timestamps in the version core. Prefer
1.2.0-rc.3over1.2.0.20260424. The former sorts correctly in the feed; the latter is technically valid semver but harder to read at a glance.
A typical CI configuration:
# Build number from the pipeline, tag from git, combined for a valid pre-release
VERSION="1.2.0-ci.${BUILD_NUMBER}"
uip solution pack ./my-solution ./dist \
--name my-solution \
--version "$VERSION"
uip solution publish "./dist/my-solution.${VERSION}.zip"
# Build number from the pipeline, tag from git, combined for a valid pre-release
VERSION="1.2.0-ci.${BUILD_NUMBER}"
uip solution pack ./my-solution ./dist \
--name my-solution \
--version "$VERSION"
uip solution publish "./dist/my-solution.${VERSION}.zip"
The .zip path is deterministic (<outputDir>/<name>.<version>.zip) — see uip solution pack — so scripts can compute it without parsing JSON.
Promote one package across tenants
Pack and publish once per version, then re-deploy the same artifact into each tenant. Re-packing per environment risks drift; re-publishing the same version is also idempotent per (name, version), so if you publish twice by mistake, nothing breaks. Even so, one build = one publish is the cleanest contract.
uip solution publish and every uip solution deploy * subcommand accept --tenant <tenant-name> (short: -t) to override the tenant selected by the active session. For a CI promotion job:
VERSION="$1" # e.g. 1.2.0-ci.456
for tenant in dev stage prod; do
uip solution publish "./dist/my-solution.${VERSION}.zip" --tenant "$tenant"
uip solution deploy run \
--name "my-solution-${tenant}" \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--tenant "$tenant"
done
VERSION="$1" # e.g. 1.2.0-ci.456
for tenant in dev stage prod; do
uip solution publish "./dist/my-solution.${VERSION}.zip" --tenant "$tenant"
uip solution deploy run \
--name "my-solution-${tenant}" \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--tenant "$tenant"
done
Two notes:
publishis idempotent per tenant. Publishing the same(name, version)twice returns the existingPackageVersionKeyinstead of duplicating — seeuip solution publish.- Deployment names should be tenant-scoped. Using
my-solution-prodrather thanmy-solutionmakesuip solution deploy listreadable and prevents accidental cross-environmentdeploy uninstallcalls.--nameidentifies the deployment record, not the folder.
Parameterizing per-environment config
If your Solution has resources (queues, assets) that differ per tenant, generate the config file once and edit it per environment with deploy config set:
uip solution deploy config get my-solution --package-version "$VERSION" -d ./deploy-config.json
# Production uses a bigger retry count
uip solution deploy config set ./deploy-config.json MyQueue maxNumberOfRetries 5
uip solution deploy run \
--name my-solution-prod \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--config-file ./deploy-config.json \
--tenant prod
uip solution deploy config get my-solution --package-version "$VERSION" -d ./deploy-config.json
# Production uses a bigger retry count
uip solution deploy config set ./deploy-config.json MyQueue maxNumberOfRetries 5
uip solution deploy run \
--name my-solution-prod \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--config-file ./deploy-config.json \
--tenant prod
Pass an existing Orchestrator resource instead of a freshly-created one with deploy config link:
uip solution deploy config link ./deploy-config.json MyQueue \
--name SharedProductionQueue \
--folder-path "Shared/Production"
uip solution deploy config link ./deploy-config.json MyQueue \
--name SharedProductionQueue \
--folder-path "Shared/Production"
Pin the CLI and its tools
Reproducible pipelines pin every tool they depend on. The CLI is distributed on npm as @uipath/cli; uip solution … is provided by @uipath/solution-tool. Both follow semver.
# Pin the CLI exactly
npm install -g @uipath/cli@1.0.0
# Pre-install tools explicitly so the first command is not slower than the rest
uip tools install @uipath/solution-tool @uipath/orchestrator-tool
# Pin the CLI exactly
npm install -g @uipath/cli@1.0.0
# Pre-install tools explicitly so the first command is not slower than the rest
uip tools install @uipath/solution-tool @uipath/orchestrator-tool
Tool versions default to tracking the CLI's MAJOR.MINOR line, so pinning the CLI alone usually suffices. For strict per-patch reproducibility, pin the tool too:
uip tools install @uipath/solution-tool@1.0.2
uip tools install @uipath/solution-tool@1.0.2
See Scripting patterns — pinning versions in CI and Installing UiPath CLI — CI/CD for the full story.
Restaurer (Rollback)
Breaking production is rare; rolling back when you do matters. There are two levels of rollback — redeploy a known-good version (fast) and delete the bad artifact (clean).
Fast: re-deploy the previous version
If the bad deployment is live, install the previous version over it instead of uninstalling first. The deployment name stays the same; only --package-version changes:
uip solution deploy run \
--name my-solution-prod \
--package-name my-solution \
--package-version 1.1.9 \
--folder-name MySolution \
--folder-path Shared \
--tenant prod
uip solution deploy run \
--name my-solution-prod \
--package-name my-solution \
--package-version 1.1.9 \
--folder-name MySolution \
--folder-path Shared \
--tenant prod
This is the common case. Orchestrator re-activates the new deployment for the configuration key and leaves the folder's resources intact.
Clean: uninstall the deployment
If the Solution provisioned resources (queues, assets, triggers) that you do not want, call uip solution deploy uninstall:
uip solution deploy uninstall my-solution-prod --tenant prod
uip solution deploy uninstall my-solution-prod --tenant prod
This removes all provisioned resources and the Solution folder. It is a destructive operation — confirm the deployment name with deploy list before running it, especially in a loop over tenants.
Retire the artifact
Once nothing references a bad version, remove it from the tenant feed with uip solution packages delete:
uip solution packages delete my-solution 1.2.0-ci.456 --tenant prod
uip solution packages delete my-solution 1.2.0-ci.456 --tenant prod
There is no soft-delete; this is permanent. Keep the deletion to a small window — the command accepts exactly one packageVersion at a time, so scripting bulk cleanups requires a list → filter → xargs pattern. See the packages delete reference for a full example.
Checking what you have
Before any of the above, get the ground truth:
# What is in the feed?
uip solution packages list --take 50 \
--output-filter "Data[?packageName=='my-solution']"
# What is deployed?
uip solution deploy list --folder-path Shared --take 50
# What is in the feed?
uip solution packages list --take 50 \
--output-filter "Data[?packageName=='my-solution']"
# What is deployed?
uip solution deploy list --folder-path Shared --take 50
CI-ready snippet
Combining the steps — a shell script that any CI system can run as-is:
#!/usr/bin/env bash
set -euo pipefail
VERSION="$1" # e.g. 1.2.0-ci.456
SOLUTION_DIR="./my-solution"
OUT_DIR="./dist"
# 1. Log in (External App in CI)
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT_DEV"
# 2. Pack once
uip solution pack "$SOLUTION_DIR" "$OUT_DIR" \
--name my-solution \
--version "$VERSION"
PKG="${OUT_DIR}/my-solution.${VERSION}.zip"
# 3. Publish + deploy to each tenant
for env_name in dev stage prod; do
tenant_var="UIPATH_TENANT_$(echo "$env_name" | tr a-z A-Z)"
tenant="${!tenant_var}"
uip solution publish "$PKG" --tenant "$tenant"
uip solution deploy run \
--name "my-solution-${env_name}" \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--tenant "$tenant"
done
#!/usr/bin/env bash
set -euo pipefail
VERSION="$1" # e.g. 1.2.0-ci.456
SOLUTION_DIR="./my-solution"
OUT_DIR="./dist"
# 1. Log in (External App in CI)
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT_DEV"
# 2. Pack once
uip solution pack "$SOLUTION_DIR" "$OUT_DIR" \
--name my-solution \
--version "$VERSION"
PKG="${OUT_DIR}/my-solution.${VERSION}.zip"
# 3. Publish + deploy to each tenant
for env_name in dev stage prod; do
tenant_var="UIPATH_TENANT_$(echo "$env_name" | tr a-z A-Z)"
tenant="${!tenant_var}"
uip solution publish "$PKG" --tenant "$tenant"
uip solution deploy run \
--name "my-solution-${env_name}" \
--package-name my-solution \
--package-version "$VERSION" \
--folder-name MySolution \
--folder-path Shared \
--tenant "$tenant"
done
With set -euo pipefail, any failure aborts the loop at the failing tenant. Later tenants are unaffected — the partial promotion can then be re-run or rolled back explicitly.
Prochaines étapes
- How-to: deploy to Orchestrator from CI — platform-agnostic deep-dive on auth, caching, and tool pre-install.
- CI/CD recipes — copy-pasteable pipelines for Azure DevOps, GitHub Actions, Jenkins, GitLab.
uip solutionreference — every subcommand.- Scripting patterns — exit-code branching, idempotent pipelines, auth retry.
- What this guide covers
- Pick a version, then freeze it
- Promote one package across tenants
- Parameterizing per-environment config
- Pin the CLI and its tools
- Restaurer (Rollback)
- Fast: re-deploy the previous version
- Clean: uninstall the deployment
- Retire the artifact
- Checking what you have
- CI-ready snippet
- Prochaines étapes