Share at:

Why does this matter?

Enterprise automation programs depend on repeatable delivery, versioning, approvals, and environment promotion - the same DevOps practices used for applications and APIs. As solutions grow to include multiple projects, dependencies, and assets, they must fit into these pipelines the same way Processes and Libraries already do. Without CLI support, automation teams couldn't integrate Solutions into:

  • Source control workflows,

  • Gated promotions between environments

  • Automated deployment pipelines

  • Change tracking and auditing

By enabling full lifecycle management through UiPath CLI, Solutions now participate naturally in CI/CD, alongside existing assets, using the same mechanisms enterprises already use to deliver software.

Automating solutions with UiPath CLI

Now that UiPath CLI supports Solutions, any CI/CD system—Azure DevOps, GitHub Actions, Jenkins, GitLab CI, Bamboo, or others—can run solution lifecycle operations non-interactively.

Available CLI Operations

Analyze governance/compliance

uipcli solution analyze <solution-folder-or-uipx>

Pack the solution

uipcli solution pack <solution-folder-or-uipx> --output <path> --version <x.y.z>

# ============================================================================

# GITHUB ACTIONS - CLI - MULTISTAGE (Production-Ready, Cross-Platform)

# ============================================================================

# Perfect for: Production deployments, multi-environment

# Method: UiPath CLI (dotnet tool install)

# OS: Windows, Linux, macOS (you choose via matrix or runner)

# Jobs: 2 (Build & Upload → Deploy)

#

# What it does:

# 1. Build & Upload: Installs CLI, packs solution, uploads to Orchestrator

# 2. Deploy: Deploys solution

#

# Setup:

# 1. Copy this file to: .github/workflows/uipath.yml

# 2. Add GitHub Secrets (Settings → Secrets and variables → Actions):

# - UIP_CLIENT_ID (from Orchestrator External App)

# - UIP_CLIENT_SECRET (from Orchestrator External App)

# 3. Add GitHub Variables (Settings → Secrets and variables → Actions → Variables):

# - UIP_URL (e.g., https://cloud.uipath.com/)

# - UIP_TENANT (your tenant name)

# - UIP_ORG (your organization/account name)

# 4. Choose your OS below (see "OS Selection" section)

# 5. Push to main branch

#

# OS Selection:

# Change runs-on below to:

# - windows-latest (Windows, CLI: UiPath.CLI.Windows)

# - ubuntu-latest (Linux, CLI: UiPath.CLI.Linux - cost-effective)

# - macos-latest (macOS, CLI: UiPath.CLI.macOS)

# ============================================================================

name: UiPath-Multistage

on:

push:

branches: [ main ]

workflow_dispatch:

env:

PACKAGE_VERSION: "1.0.${{ github.run_number }}"

UIP_CLI_VERSION: "25.10.8" # Change to match your desired CLI version

DEPLOYMENT_PARENT_FOLDER: "Shared" # Change to your target folder, or remove for Tenant root

# Orchestrator connection details (from GitHub Variables/Secrets)

UIP_URL: ${{ vars.UIP_URL }}

UIP_TENANT: ${{ vars.UIP_TENANT }}

UIP_ORG: ${{ vars.UIP_ORG }}

UIP_CLIENT_ID: ${{ secrets.UIP_CLIENT_ID }}

UIP_CLIENT_SECRET: ${{ secrets.UIP_CLIENT_SECRET }}

jobs:

build:

name: Build & Pack

# ========================================================================

# CHOOSE YOUR OS HERE:

# Change to: windows-latest (Windows) or macos-latest (macOS)

# ========================================================================

runs-on: ubuntu-latest

outputs:

project_name: ${{ steps.pack.outputs.project_name }}

package_file: ${{ steps.pack.outputs.package_file }}

steps:

- uses: actions/checkout@v4

- name: Install UiPath CLI

shell: bash

run: |

# Auto-detect OS and install appropriate CLI

if [ "$RUNNER_OS" == "Windows" ]; then

dotnet tool install --global UiPath.CLI.Windows --version ${{ env.UIP_CLI_VERSION }}

elif [ "$RUNNER_OS" == "macOS" ]; then

dotnet tool install --global UiPath.CLI.macOS --version ${{ env.UIP_CLI_VERSION }}

else

dotnet tool install --global UiPath.CLI.Linux --version ${{ env.UIP_CLI_VERSION }}

fi

uipcli --version

- name: Pack Solution

id: pack

shell: bash

run: |

# STEP 1: Find solution file

solution=$(find . -name "*.uipx" -print -quit)

if [ -z "$solution" ]; then

echo "ERROR: No .uipx file found in repository"

exit 1

fi

echo "Found solution: $solution"

echo "Solution directory: $(dirname "$solution")"

# STEP 2: Pack solution

echo "Packing solution..."

uipcli solution pack "$solution" \

--output "$RUNNER_TEMP" \

--version "${{ env.PACKAGE_VERSION }}"

# STEP 3: Find the actual packed ZIP

package=$(find "$RUNNER_TEMP" -name "*.zip" | head -n 1)

if [ -z "$package" ]; then

echo "ERROR: No package created after packing"

exit 1

fi

# Extract solution name from actual package filename (remove _VERSION.zip)

package_file=$(basename "$package")

project_name="${package_file%_${{ env.PACKAGE_VERSION }}.zip}"

echo "Package created: $package_file"

echo "Detected solution name: $project_name"

# Export for next jobs

echo "project_name=$project_name" >> $GITHUB_OUTPUT

echo "package_file=$package_file" >> $GITHUB_OUTPUT

echo "package_path=$package" >> $GITHUB_OUTPUT

- name: Upload to Orchestrator

shell: bash

run: |

# Use the full path from pack step

package="${{ steps.pack.outputs.package_path }}"

echo "Uploading: $(basename "$package")"

uipcli solution upload-package "$package" \

-U "${{ env.UIP_URL }}" \

-T "${{ env.UIP_TENANT }}" \

-A "${{ env.UIP_ORG }}" \

-I "${{ env.UIP_CLIENT_ID }}" \

-S "${{ env.UIP_CLIENT_SECRET }}"

echo "Upload completed"

deploy:

name: Deploy Solution

needs: build

runs-on: ubuntu-latest

steps:

- name: Install UiPath CLI

run: |

dotnet tool install --global UiPath.CLI.Linux --version ${{ env.UIP_CLI_VERSION }}

uipcli --version

- name: Deploy Solution

run: |

project="${{ needs.build.outputs.project_name }}"

echo "Deploying solution: $project"

echo "Version: ${{ env.PACKAGE_VERSION }}"

# Deploy: -v (version), -d (deployment name), -f (solution folder)

# Note: Remove --deploymentParentFolder to deploy under Tenant root

uipcli solution deploy $project \

-v "${{ env.PACKAGE_VERSION }}" \

-d $project \

-f $project \

--deploymentParentFolder "${{ env.DEPLOYMENT_PARENT_FOLDER }}" \

-U "${{ env.UIP_URL }}" \

-T "${{ env.UIP_TENANT }}" \

-A "${{ env.UIP_ORG }}" \

-I "${{ env.UIP_CLIENT_ID }}" \

-S "${{ env.UIP_CLIENT_SECRET }}"

echo "SUCCESS: Solution deployed successfully"

Get articles from automation experts in your inbox

Subscribe
Get articles from automation experts in your inbox

Sign up today and we'll email you the newest articles every week.

Thank you for subscribing!

Thank you for subscribing! Each week, we'll send the best automation blog posts straight to your inbox.

Ask AI about...Ask AI...