- Überblick
- Erste Schritte
- Konzepte
- Using UiPath CLI
- Anleitungen
- CI/CD recipes
- Azure DevOps
- GitHub Actions
- Jenkins
- GitLab CI
- Befehlsreferenz
- Überblick
- Exitcodes
- Global options
- uip codedagent
- uip docsai
- add-test-data-entity
- add-test-data-queue
- add-test-data-variation
- analyze
- build
- Ein Projekt erstellen
- 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 gives you a complete azure-pipelines.yml that installs the CLI, authenticates with an External Application, packs and publishes a UiPath Solution, deploys it to Orchestrator, and runs a Test Manager suite against the deployment. The pipeline is self-contained: copy it into the root of your repo, wire two secrets, and it runs.
For the underlying principles — auth, caching, tool pre-install, version pinning — see How-to: deploy to Orchestrator from CI. This page focuses on the Azure Pipelines syntax.
Voraussetzungen
Before copying the YAML below:
- Create an External Application in UiPath with the
OR.*scopes your pipeline needs. See Authentication — Flow 2. - Store the secrets in an Azure DevOps variable group:
- Project Settings → Pipelines → Library → New variable group (for example,
uipath-prod). - Add
UIPATH_CLIENT_IDandUIPATH_CLIENT_SECRET— mark both as secret (padlock icon). - Optionally add
UIPATH_TENANT(not a secret).
- Project Settings → Pipelines → Library → New variable group (for example,
- Link the variable group to the pipeline (see the
variablesblock below). - Provision a Test Manager project and test set (if you want the test stage). You will need the
TEST_SET_KEY(formatPROJECT:42) andPROJECT_KEY. See How-to: run tests from the CLI.
azure-pipelines.yml
trigger:
branches:
include: [ main ]
pr:
branches:
include: [ main ]
variables:
- group: uipath-prod # contains UIPATH_CLIENT_ID, UIPATH_CLIENT_SECRET
- name: CLI_VERSION
value: '1.0.0'
- name: NODE_VERSION
value: '20.x'
- name: SOLUTION_NAME
value: 'my-solution'
- name: SOLUTION_DIR
value: '$(Build.SourcesDirectory)/my-solution'
- name: OUTPUT_DIR
value: '$(Build.ArtifactStagingDirectory)'
- name: SOLUTION_VERSION
value: '1.2.0-ci.$(Build.BuildId)'
# Path where npm places globally-installed packages. Used to cache the CLI + tools.
- name: NPM_GLOBAL_CACHE
value: '$(HOME)/.npm-global/lib/node_modules'
stages:
- stage: Build
displayName: 'Pack the Solution'
jobs:
- job: pack
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
uip --version
displayName: 'Install UiPath CLI and tools'
- script: |
set -euo pipefail
uip solution pack "$(SOLUTION_DIR)" "$(OUTPUT_DIR)" \
--name "$(SOLUTION_NAME)" \
--version "$(SOLUTION_VERSION)"
displayName: 'Pack Solution'
- publish: '$(OUTPUT_DIR)/$(SOLUTION_NAME).$(SOLUTION_VERSION).zip'
artifact: solution-zip
displayName: 'Publish artifact'
- stage: Deploy
displayName: 'Publish to feed and deploy to Orchestrator'
dependsOn: Build
jobs:
- deployment: deploy
environment: 'uipath-prod' # Azure DevOps environment — gates / approvals live here
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
displayName: 'Install UiPath CLI and tools'
- script: |
set -euo pipefail
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- download: current
artifact: solution-zip
- script: |
set -euo pipefail
uip solution publish \
"$(Pipeline.Workspace)/solution-zip/$(SOLUTION_NAME).$(SOLUTION_VERSION).zip"
displayName: 'Publish to tenant feed'
- script: |
set -euo pipefail
uip solution deploy run \
--name "$(SOLUTION_NAME)-$(Build.BuildId)" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(SOLUTION_VERSION)" \
--folder-name MySolution \
--folder-path Shared
displayName: 'Deploy to Orchestrator'
- stage: Test
displayName: 'Run Test Manager suite'
dependsOn: Deploy
condition: and(succeeded(), ne(variables['TEST_SET_KEY'], ''))
jobs:
- job: test
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Install + authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- script: |
set -euo pipefail
EXECUTION_ID=$(uip tm testset execute \
--test-set-key "$TEST_SET_KEY" \
--output-filter "Data.ExecutionId" \
--output plain)
echo "started execution $EXECUTION_ID"
if ! uip tm wait \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY" \
--timeout 1800; then
code=$?
case "$code" in
2) echo "##vso[task.logissue type=error]test run did not finish within 30 minutes"; exit 2 ;;
*) echo "##vso[task.logissue type=error]wait failed (exit $code)"; exit "$code" ;;
esac
fi
uip tm report get \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY"
FAILED=$(uip tm report get \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY" \
--output-filter "Data.Failed" \
--output plain)
if [ "$FAILED" -gt 0 ]; then
echo "##vso[task.logissue type=error]$FAILED test case(s) failed"
exit 1
fi
displayName: 'Launch, wait, verify'
env:
TEST_SET_KEY: $(TEST_SET_KEY)
PROJECT_KEY: $(PROJECT_KEY)
trigger:
branches:
include: [ main ]
pr:
branches:
include: [ main ]
variables:
- group: uipath-prod # contains UIPATH_CLIENT_ID, UIPATH_CLIENT_SECRET
- name: CLI_VERSION
value: '1.0.0'
- name: NODE_VERSION
value: '20.x'
- name: SOLUTION_NAME
value: 'my-solution'
- name: SOLUTION_DIR
value: '$(Build.SourcesDirectory)/my-solution'
- name: OUTPUT_DIR
value: '$(Build.ArtifactStagingDirectory)'
- name: SOLUTION_VERSION
value: '1.2.0-ci.$(Build.BuildId)'
# Path where npm places globally-installed packages. Used to cache the CLI + tools.
- name: NPM_GLOBAL_CACHE
value: '$(HOME)/.npm-global/lib/node_modules'
stages:
- stage: Build
displayName: 'Pack the Solution'
jobs:
- job: pack
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
uip --version
displayName: 'Install UiPath CLI and tools'
- script: |
set -euo pipefail
uip solution pack "$(SOLUTION_DIR)" "$(OUTPUT_DIR)" \
--name "$(SOLUTION_NAME)" \
--version "$(SOLUTION_VERSION)"
displayName: 'Pack Solution'
- publish: '$(OUTPUT_DIR)/$(SOLUTION_NAME).$(SOLUTION_VERSION).zip'
artifact: solution-zip
displayName: 'Publish artifact'
- stage: Deploy
displayName: 'Publish to feed and deploy to Orchestrator'
dependsOn: Build
jobs:
- deployment: deploy
environment: 'uipath-prod' # Azure DevOps environment — gates / approvals live here
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
displayName: 'Install UiPath CLI and tools'
- script: |
set -euo pipefail
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- download: current
artifact: solution-zip
- script: |
set -euo pipefail
uip solution publish \
"$(Pipeline.Workspace)/solution-zip/$(SOLUTION_NAME).$(SOLUTION_VERSION).zip"
displayName: 'Publish to tenant feed'
- script: |
set -euo pipefail
uip solution deploy run \
--name "$(SOLUTION_NAME)-$(Build.BuildId)" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(SOLUTION_VERSION)" \
--folder-name MySolution \
--folder-path Shared
displayName: 'Deploy to Orchestrator'
- stage: Test
displayName: 'Run Test Manager suite'
dependsOn: Deploy
condition: and(succeeded(), ne(variables['TEST_SET_KEY'], ''))
jobs:
- job: test
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
uip tools install @uipath/orchestrator-tool @uipath/solution-tool @uipath/test-manager-tool
fi
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Install + authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- script: |
set -euo pipefail
EXECUTION_ID=$(uip tm testset execute \
--test-set-key "$TEST_SET_KEY" \
--output-filter "Data.ExecutionId" \
--output plain)
echo "started execution $EXECUTION_ID"
if ! uip tm wait \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY" \
--timeout 1800; then
code=$?
case "$code" in
2) echo "##vso[task.logissue type=error]test run did not finish within 30 minutes"; exit 2 ;;
*) echo "##vso[task.logissue type=error]wait failed (exit $code)"; exit "$code" ;;
esac
fi
uip tm report get \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY"
FAILED=$(uip tm report get \
--execution-id "$EXECUTION_ID" \
--project-key "$PROJECT_KEY" \
--output-filter "Data.Failed" \
--output plain)
if [ "$FAILED" -gt 0 ]; then
echo "##vso[task.logissue type=error]$FAILED test case(s) failed"
exit 1
fi
displayName: 'Launch, wait, verify'
env:
TEST_SET_KEY: $(TEST_SET_KEY)
PROJECT_KEY: $(PROJECT_KEY)
Walkthrough
Stage 1 — Build
NodeTool@0pins Node.js to version 20. Pin to a major; the CLI requires 18+.Cache@2caches the npm globalnode_modulesdirectory. The cache key includes$(CLI_VERSION)so a version bump invalidates cleanly.- Install step switches npm's global prefix to
$HOME/.npm-global(nosudoneeded), prepends it to the PATH, and — only if the cache missed — installs@uipath/cliand pre-installs the three tools used in this pipeline. See Installing UiPath CLI — CI/CD and Scripting patterns — pinning versions. - Pack step invokes
uip solution packwith an explicit--version(never rely on the1.0.0default in CI). publish: ...uploads the.zipas a pipeline artifact namedsolution-zipso the Deploy stage can consume it.
Stage 2 — Deploy
Uses a deployment job bound to a named environment. Environments are where you configure gates and approvals in Azure DevOps — the YAML itself stays simple.
- Re-installs the CLI (the cache should hit on the second stage of the same run).
uip loginuses theenv.VAR_NAMEprefix for both the client ID and secret. Theenv:block at the step level maps$(UIPATH_CLIENT_ID)(from the variable group) to the actual environment variableUIPATH_CLIENT_IDthat the flag resolves. Do not pass the secret literally on the command line (--client-secret "$(UIPATH_CLIENT_SECRET)") — that leaks it into the build log andpsoutput. Theenv.prefix feature is documented in Authentication — the env.VAR_NAME prefix.download: currentpulls thesolution-zipartifact from Stage 1 into$(Pipeline.Workspace)/solution-zip.uip solution publishuploads the.zipto the tenant feed.uip solution deploy runcreates the deployment.--nameuses$(Build.BuildId)so each run is identifiable and re-deploys do not clobber each other's deployment record.
Stage 3 — Test
Only runs if TEST_SET_KEY is set at the variable-group level — the condition: guard skips the stage cleanly if you don't have a test suite configured.
The shell block is the canonical launch → wait → verify flow from How-to: run tests from the CLI:
uip tm testset executelaunches the run and returns anExecutionId.uip tm waitblocks until the execution reaches a terminal state (exit2means timeout, not auth failure — a domain-specific reuse of the exit-code slot).uip tm report getreadsData.Failed; the step fails with##vso[task.logissue type=error]so the outcome surfaces cleanly in the Azure DevOps UI.
Common variations
Pin tool versions too
By default, uip tools install resolves to the latest tool version in the CLI's MAJOR.MINOR line. For strict patch-level reproducibility:
- script: |
uip tools install \
@uipath/orchestrator-tool@1.0.2 \
@uipath/solution-tool@1.0.2 \
@uipath/test-manager-tool@1.0.2
displayName: 'Install pinned tools'
- script: |
uip tools install \
@uipath/orchestrator-tool@1.0.2 \
@uipath/solution-tool@1.0.2 \
@uipath/test-manager-tool@1.0.2
displayName: 'Install pinned tools'
Promote across environments
Link two variable groups — uipath-stage and uipath-prod — and turn each into a separate deployment: job. Use environment-specific gates/approvals to decide when prod runs:
- stage: DeployStage
dependsOn: Build
jobs:
- deployment: deploy-stage
variables: [ { group: uipath-stage } ]
environment: 'uipath-stage'
# …same steps as above, but with stage's tenant
- stage: DeployProd
dependsOn: DeployStage
jobs:
- deployment: deploy-prod
variables: [ { group: uipath-prod } ]
environment: 'uipath-prod' # attach a manual approval gate here
# …same steps as above
- stage: DeployStage
dependsOn: Build
jobs:
- deployment: deploy-stage
variables: [ { group: uipath-stage } ]
environment: 'uipath-stage'
# …same steps as above, but with stage's tenant
- stage: DeployProd
dependsOn: DeployStage
jobs:
- deployment: deploy-prod
variables: [ { group: uipath-prod } ]
environment: 'uipath-prod' # attach a manual approval gate here
# …same steps as above
Deeper coverage in How-to: pack and publish a Solution — promote one package across tenants.
Rollback
Azure DevOps does not roll back automatically; add a manual stage that re-deploys the previous version:
- stage: Rollback
dependsOn: [] # run on demand, not from Deploy
jobs:
- job: rollback
pool: { vmImage: 'ubuntu-latest' }
steps:
# …install + auth…
- script: |
uip solution deploy run \
--name "$(SOLUTION_NAME)-rollback" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(ROLLBACK_VERSION)" \
--folder-name MySolution \
--folder-path Shared
displayName: 'Re-deploy previous version'
- stage: Rollback
dependsOn: [] # run on demand, not from Deploy
jobs:
- job: rollback
pool: { vmImage: 'ubuntu-latest' }
steps:
# …install + auth…
- script: |
uip solution deploy run \
--name "$(SOLUTION_NAME)-rollback" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(ROLLBACK_VERSION)" \
--folder-name MySolution \
--folder-path Shared
displayName: 'Re-deploy previous version'
Pass ROLLBACK_VERSION at queue time. For destructive rollback (uninstall + delete artifact), see How-to: pack and publish a Solution — rollback.
Skipping tests
To run without the test stage, delete the Test stage block (or leave TEST_SET_KEY unset — the condition: on the stage will skip it).
Common pitfalls
env.prefix vs literal secret. Always--client-secret env.UIPATH_CLIENT_SECRET, never--client-secret "$(UIPATH_CLIENT_SECRET)". The literal form embeds the value into the rendered command line. See the auth warning.##vso[task.setvariable]is not needed forenv.resolution —env:on the step exposes the variable directly.- Multi-line bash needs
set -euo pipefailat the top of everyscript:block. Without it,packcan fail while later steps keep running. See Scripting patterns — strict shell options. - Cache hits are not guaranteed. Always wrap the install commands in
if ! command -v uipso the pipeline self-heals when the cache is cold.
Siehe auch
- How-to: deploy to Orchestrator from CI — platform-agnostic guidance.
- How-to: pack and publish a Solution — versioning and rollback.
- How-to: run tests from the CLI — the launch → wait → verify pattern in depth.
- CI/CD recipe: GitHub Actions, Jenkins, GitLab CI — the same pipeline in other platforms.