UiPath Documentation
uipath-cli
latest
false
Wichtig :
Dieser Inhalt wurde maschinell übersetzt. Es kann 1–2 Wochen dauern, bis die Lokalisierung neu veröffentlichter Inhalte verfügbar ist.

UiPath-CLI-Benutzerhandbuch

CI/CD-Rezept: GitLab CI

Auf dieser Seite erhalten Sie eine vollständige .gitlab-ci.yml , die die CLI installiert, sich mit einer externen Anwendung authentifiziert, eine UiPath-Lösung verpackt und veröffentlicht, sie im Orchestrator für mehrere Mandanten bereitstellt (über eine Matrix) und eine Test Manager-Suite ausführt. Legen Sie es im Stammverzeichnis Ihres Repositorys ab, legen Sie drei CI/CD-Variablen fest und es wird ausgeführt.

Für die zugrundeliegenden Prinzipien – Authentifizierung, Zwischenspeicherung, Vorinstallation des Tools, Versionsheft – siehe Anleitung: Bereitstellen von CI im Orchestrator. Diese Seite konzentriert sich auf die GitLab-Syntax, einschließlich der Funktionen (Cache mit einem Schlüssel-Scope, parallel: matrix), die GitLab-spezifisch sind.

Voraussetzungen

Bevor Sie die folgende YAML-Datei kopieren:

  1. Erstellen Sie eine externe Anwendung in UiPath mit den OR.* Scopes, die Ihre Pipeline benötigt. Siehe Authentifizierung – Flow 2.
  2. Speichern Sie die Geheimnisse als CI/CD-Variablen:
    • Projekt → Einstellungen → CI/CD → Variablen.
    • Fügen Sie UIPATH_CLIENT_ID und UIPATH_CLIENT_SECRET hinzu. Markieren Sie sowohl Maskiert als auch Geschützt (damit sie nur für geschützte Verzweigungen/Tags offengelegt werden).
    • Fügen Sie UIPATH_TENANT_DEV, UIPATH_TENANT_STAGE, UIPATH_TENANT_PROD mit den Mandantennamen hinzu (nicht maskiert – Mandantennamen sind nicht vertraulich).
  3. Stellen Sie ein Test Manager-Projekt und einen Testsatz bereit, wenn Sie den Testauftrag möchten. Fügen Sie TEST_SET_KEY und PROJECT_KEY als reguläre Variablen hinzu.

.gitLab-ci.yml

# -----------------------------------------------------------------------------
# Deploy UiPath Solution
# -----------------------------------------------------------------------------
# Auth: External Application, env.VAR_NAME prefix (never the literal value).
# Cache: npm global node_modules, keyed by CLI version.
# Matrix: deploy job fans out across dev / stage / prod tenants.
# -----------------------------------------------------------------------------

image: node:20

stages:
  - build
  - deploy
  - test

variables:
  CLI_VERSION: '1.0.0'
  SOLUTION_NAME: 'my-solution'
  SOLUTION_DIR:  './my-solution'
  OUTPUT_DIR:    './dist'
  SOLUTION_VERSION: '1.2.0-ci.$CI_PIPELINE_IID'

  # Workspace-local npm prefix so installs need no sudo and are cacheable.
  NPM_PREFIX: "$CI_PROJECT_DIR/.npm-global"

# Re-usable install block. GitLab does not have anchors for script:; we use
# YAML anchors on a hidden job and extend from it.
.install-uip: &install-uip |
  set -euo pipefail
  mkdir -p "$NPM_PREFIX"
  npm config set prefix "$NPM_PREFIX"
  export PATH="$NPM_PREFIX/bin:$PATH"

  if ! command -v uip >/dev/null; then
    npm install -g "@uipath/cli@$CLI_VERSION"
  fi
  uip --version

cache:
  key: "uip-$CLI_VERSION"
  paths:
    - .npm-global/lib/node_modules
  policy: pull-push

# -----------------------------------------------------------------------------
# Stage: build
# -----------------------------------------------------------------------------

pack:
  stage: build
  script:
    - *install-uip
    - mkdir -p "$OUTPUT_DIR"
    - |
      uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
        --name "$SOLUTION_NAME" \
        --version "$SOLUTION_VERSION"
  artifacts:
    paths:
      - "$OUTPUT_DIR/*.zip"
    expire_in: 30 days

# -----------------------------------------------------------------------------
# Stage: deploy — matrix across environments
# -----------------------------------------------------------------------------

deploy:
  stage: deploy
  needs:
    - job: pack
      artifacts: true
  parallel:
    matrix:
      - ENVIRONMENT: dev
        TENANT_VAR:  UIPATH_TENANT_DEV
      - ENVIRONMENT: stage
        TENANT_VAR:  UIPATH_TENANT_STAGE
      - ENVIRONMENT: prod
        TENANT_VAR:  UIPATH_TENANT_PROD
  environment:
    name: uipath/$ENVIRONMENT
  rules:
    # Prod only on protected branches — set protection under Settings → Repository.
    - if: '$ENVIRONMENT == "prod" && $CI_COMMIT_REF_PROTECTED != "true"'
      when: never
    - when: on_success
  script:
    - *install-uip
    - |
      # Resolve the per-environment tenant from the matrix variable.
      UIPATH_TENANT="${!TENANT_VAR}"
      if [ -z "$UIPATH_TENANT" ]; then
        echo "Tenant variable $TENANT_VAR is empty; set it in CI/CD settings." >&2
        exit 3
      fi

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

      ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
      uip solution publish "$ARTIFACT"

      uip solution deploy run \
        --name "$SOLUTION_NAME-$ENVIRONMENT-$CI_PIPELINE_IID" \
        --package-name "$SOLUTION_NAME" \
        --package-version "$SOLUTION_VERSION" \
        --folder-name MySolution \
        --folder-path Shared

# -----------------------------------------------------------------------------
# Stage: test
# -----------------------------------------------------------------------------

test:
  stage: test
  needs:
    - job: "deploy: [dev, UIPATH_TENANT_DEV]"   # depend on the dev leg of the matrix
      optional: true
  rules:
    - if: '$TEST_SET_KEY == null || $TEST_SET_KEY == ""'
      when: never
    - when: on_success
  script:
    - *install-uip
    - |
      uip login \
        --client-id env.UIPATH_CLIENT_ID \
        --client-secret env.UIPATH_CLIENT_SECRET \
        --tenant "$UIPATH_TENANT_DEV"

      EXECUTION_ID=$(uip tm testsets run \
        --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 "test run did not finish within 30 minutes" >&2; exit 2 ;;
          *) echo "wait failed (exit $code)" >&2; 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 "$FAILED test case(s) failed" >&2
        exit 1
      fi
# -----------------------------------------------------------------------------
# Deploy UiPath Solution
# -----------------------------------------------------------------------------
# Auth: External Application, env.VAR_NAME prefix (never the literal value).
# Cache: npm global node_modules, keyed by CLI version.
# Matrix: deploy job fans out across dev / stage / prod tenants.
# -----------------------------------------------------------------------------

image: node:20

stages:
  - build
  - deploy
  - test

variables:
  CLI_VERSION: '1.0.0'
  SOLUTION_NAME: 'my-solution'
  SOLUTION_DIR:  './my-solution'
  OUTPUT_DIR:    './dist'
  SOLUTION_VERSION: '1.2.0-ci.$CI_PIPELINE_IID'

  # Workspace-local npm prefix so installs need no sudo and are cacheable.
  NPM_PREFIX: "$CI_PROJECT_DIR/.npm-global"

# Re-usable install block. GitLab does not have anchors for script:; we use
# YAML anchors on a hidden job and extend from it.
.install-uip: &install-uip |
  set -euo pipefail
  mkdir -p "$NPM_PREFIX"
  npm config set prefix "$NPM_PREFIX"
  export PATH="$NPM_PREFIX/bin:$PATH"

  if ! command -v uip >/dev/null; then
    npm install -g "@uipath/cli@$CLI_VERSION"
  fi
  uip --version

cache:
  key: "uip-$CLI_VERSION"
  paths:
    - .npm-global/lib/node_modules
  policy: pull-push

# -----------------------------------------------------------------------------
# Stage: build
# -----------------------------------------------------------------------------

pack:
  stage: build
  script:
    - *install-uip
    - mkdir -p "$OUTPUT_DIR"
    - |
      uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
        --name "$SOLUTION_NAME" \
        --version "$SOLUTION_VERSION"
  artifacts:
    paths:
      - "$OUTPUT_DIR/*.zip"
    expire_in: 30 days

# -----------------------------------------------------------------------------
# Stage: deploy — matrix across environments
# -----------------------------------------------------------------------------

deploy:
  stage: deploy
  needs:
    - job: pack
      artifacts: true
  parallel:
    matrix:
      - ENVIRONMENT: dev
        TENANT_VAR:  UIPATH_TENANT_DEV
      - ENVIRONMENT: stage
        TENANT_VAR:  UIPATH_TENANT_STAGE
      - ENVIRONMENT: prod
        TENANT_VAR:  UIPATH_TENANT_PROD
  environment:
    name: uipath/$ENVIRONMENT
  rules:
    # Prod only on protected branches — set protection under Settings → Repository.
    - if: '$ENVIRONMENT == "prod" && $CI_COMMIT_REF_PROTECTED != "true"'
      when: never
    - when: on_success
  script:
    - *install-uip
    - |
      # Resolve the per-environment tenant from the matrix variable.
      UIPATH_TENANT="${!TENANT_VAR}"
      if [ -z "$UIPATH_TENANT" ]; then
        echo "Tenant variable $TENANT_VAR is empty; set it in CI/CD settings." >&2
        exit 3
      fi

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

      ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
      uip solution publish "$ARTIFACT"

      uip solution deploy run \
        --name "$SOLUTION_NAME-$ENVIRONMENT-$CI_PIPELINE_IID" \
        --package-name "$SOLUTION_NAME" \
        --package-version "$SOLUTION_VERSION" \
        --folder-name MySolution \
        --folder-path Shared

# -----------------------------------------------------------------------------
# Stage: test
# -----------------------------------------------------------------------------

test:
  stage: test
  needs:
    - job: "deploy: [dev, UIPATH_TENANT_DEV]"   # depend on the dev leg of the matrix
      optional: true
  rules:
    - if: '$TEST_SET_KEY == null || $TEST_SET_KEY == ""'
      when: never
    - when: on_success
  script:
    - *install-uip
    - |
      uip login \
        --client-id env.UIPATH_CLIENT_ID \
        --client-secret env.UIPATH_CLIENT_SECRET \
        --tenant "$UIPATH_TENANT_DEV"

      EXECUTION_ID=$(uip tm testsets run \
        --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 "test run did not finish within 30 minutes" >&2; exit 2 ;;
          *) echo "wait failed (exit $code)" >&2; 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 "$FAILED test case(s) failed" >&2
        exit 1
      fi

Exemplarische Vorgehensweise

Einrichtung auf höchster Ebene

  • image: node:20 – Jeder Auftrag wird im offiziellen Node.js 20-Image ausgeführt. Die CLI erfordert Knoten 18+. Wenn in Ihrem GitLab-Ausführungsmodell bereits Node installiert ist und Sie keinen Container benötigen, können Sie dies entfernen und stattdessen einen shell -Executor verwenden.
  • variables: – Die Pipeline-weiten Werte. SOLUTION_VERSION interpoliert $CI_PIPELINE_IID (die inkrementelle, projektbezogene Pipelinenummer – besser für die Versionierung als $CI_JOB_ID, das global und nicht ist).
  • .install-uip Anker – Mit GitLab können Sie script: -Blöcke nicht direkt verankern, aber Sie können einen YAML-Knoten verankern, der eine Shell-Zeichenfolge enthält, und ihn mit - *install-uip verbinden. Der gleiche Installationsschutz wie die anderen Schemas: lokales Präfix „Arbeitsbereich“, bedingte CLI-Installation. Tools werden bei der ersten Verwendung automatisch installiert, sodass der Anker nur den Host verarbeitet.
  • cache: – Der Schlüssel uip-$CLI_VERSION stellt sicher, dass ein Fehler in der CLI-Version den Cache sauber ungültig macht. policy: pull-push liest beim Eintrag und schreibt bei erfolgreichem Beenden des Auftrags. Wenn Sie in großem Umfang ausführen und jeden Auftrag um Sekunden sparen möchten, teilen Sie sich einen dedizierten Auftrag „an den Cache“ auf, der pull-push ausführt und alle anderen Aufträge nur policy: pull verwenden lassen.

Packauftrag

  • Installiert die CLI über den freigegebenen Anker.
  • uip solution pack mit einer expliziten Version – siehe uip solution pack.
  • artifacts: führt .zip zur nächsten Phase. Der Pfad ist ein Glob ($OUTPUT_DIR/*.zip), sodass er den Dateinamen aufnimmt, uip solution pack erzeugt. expire_in: 30 days verhindert, dass der Artefaktspeicher von GitLab grenzenlos wächst; Verwenden Sie diese Option, wenn Sie eine längere Rückverfolgbarkeit benötigen.

Auftrag mit Parallelität bereitstellen: Matrix

Die Matrix erweitert sich in drei Aufträge – deploy: [dev, UIPATH_TENANT_DEV], deploy: [stage, UIPATH_TENANT_STAGE], deploy: [prod, UIPATH_TENANT_PROD] – die parallel ausgeführt werden. Jeder erhält ein anderes $ENVIRONMENT und $TENANT_VAR und verwendet eine indirekte Bash-Erweiterung (${!TENANT_VAR}), um den Mandanten pro Umgebung aus der richtigen CI/CD-Variable zu lesen.

  • environment: name: uipath/$ENVIRONMENT – GitLab verfolgt Bereitstellungen in seiner Umgebungsansicht, sodass jeder Mandant einen Verlauf pro Umgebung mit Rollback-Schaltflächen erhält.
  • rules: – Die erste Regel blockiert prod aus nicht geschützten Verzweigungen. In Kombination mit Einstellungen → Repository → Geschützte Verzweigungen (wo Sie main als geschützt markieren) verhindern Sie, dass eine Funktionsverzweigung versehentlich in der Produktion bereitgestellt wird. Die UIPATH_CLIENT_* -Variablen sollten auch als „Geschützt“ markiert sein, damit sie nur in geschützten Referenzen aufgelöst werden.
  • uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET – Das Präfix env.VAR_NAME ist die unterstützte Methode, um ein Geheimnis an die CLI zu übergeben, ohne dass es jemals in der Shell-Befehlszeile angezeigt wird. GitLab maskiert Variablen in Protokollen, wenn sie maskiert markiert sind, aber das Präfix env. ist sowieso eine Development-in-Depth. Siehe Authentifizierung – das Präfix env.VAR_NAME.
  • Bereitstellungsname$SOLUTION_NAME-$ENVIRONMENT-$CI_PIPELINE_IID macht jede Bereitstellung auf eine bestimmte Pipelineausführung und Umgebung nachverfolgbar.
Hinweis:

Wenn bei parallelen Matrixaufträgen ein Zweig ausfällt, werden die anderen standardmäßig weiter ausgeführt. Wenn Sie möchten, dass das Produkt auf Entwicklung und Phase wartet, wandeln Sie die Matrix in drei sequenzielle Aufträge um (oder verwenden Sie stattdessen needs: dazwischen).

Testauftrag

  • needs: verweist durch seinen erweiterten Namen auf das Matrixzeile – "deploy: [dev, UIPATH_TENANT_DEV]". Der optional: true macht die Abhängigkeit nicht schwerwiegend, wenn die Entwicklungsphase vom rules: -Block übersprungen wurde.
  • rules: überspringt den Auftrag, wenn TEST_SET_KEY nicht festgelegt ist, nach dem gleichen Muster wie die anderen Schemas.
  • Starten → warten → überprüfen – das kanonische Testmuster aus So: Ausführen von Tests über die CLI. Das Beenden 2 aus uip tm wait bedeutet eine Zeitüberschreitung (kein Authentifizierungsfehler).

Häufige Varianten

Serie mit manuellem Prüfpunkt

Wenn Sie möchten, dass das Prod einen manuellen Klick anstelle des Gating für geschützte Verzweigungen erfordert, teilen Sie die Matrix in drei Aufträge auf und fügen Sie when: manual zum Prod-Auftrag hinzu:

deploy-dev:
  stage: deploy
  # …as deploy above, fixed to UIPATH_TENANT_DEV…

deploy-stage:
  stage: deploy
  needs: [ pack, deploy-dev ]
  # …as deploy above, fixed to UIPATH_TENANT_STAGE…

deploy-prod:
  stage: deploy
  needs: [ pack, deploy-stage ]
  when: manual                    # requires a reviewer to click "Play"
  allow_failure: false
  environment:
    name: uipath/prod
  # …as deploy above, fixed to UIPATH_TENANT_PRODdeploy-dev:
  stage: deploy
  # …as deploy above, fixed to UIPATH_TENANT_DEV…

deploy-stage:
  stage: deploy
  needs: [ pack, deploy-dev ]
  # …as deploy above, fixed to UIPATH_TENANT_STAGE…

deploy-prod:
  stage: deploy
  needs: [ pack, deploy-stage ]
  when: manual                    # requires a reviewer to click "Play"
  allow_failure: false
  environment:
    name: uipath/prod
  # …as deploy above, fixed to UIPATH_TENANT_PROD…

Rollback

Manuell über einen separaten Auftrag mit einer Pipelinevariablen auslösen:

rollback:
  stage: deploy
  when: manual
  rules:
    - if: '$ROLLBACK_VERSION != null && $ROLLBACK_VERSION != ""'
  script:
    - *install-uip
    - |
      uip login \
        --client-id env.UIPATH_CLIENT_ID \
        --client-secret env.UIPATH_CLIENT_SECRET \
        --tenant "$UIPATH_TENANT_PROD"

      uip solution deploy run \
        --name "$SOLUTION_NAME-rollback" \
        --package-name "$SOLUTION_NAME" \
        --package-version "$ROLLBACK_VERSION" \
        --folder-name MySolution \
        --folder-path Shared
rollback:
  stage: deploy
  when: manual
  rules:
    - if: '$ROLLBACK_VERSION != null && $ROLLBACK_VERSION != ""'
  script:
    - *install-uip
    - |
      uip login \
        --client-id env.UIPATH_CLIENT_ID \
        --client-secret env.UIPATH_CLIENT_SECRET \
        --tenant "$UIPATH_TENANT_PROD"

      uip solution deploy run \
        --name "$SOLUTION_NAME-rollback" \
        --package-name "$SOLUTION_NAME" \
        --package-version "$ROLLBACK_VERSION" \
        --folder-name MySolution \
        --folder-path Shared

Starten Sie die Pipeline von CI/CD → Pipelines → Pipeline ausführen und legen Sie ROLLBACK_VERSION auf die Zielversion fest (z. B. 1.1.9). Informationen zum destruktiven Rollback (Deinstallieren + Löschen des Artefakts) finden Sie unter Anleitung: Packen und Veröffentlichen einer Lösung – Rollback.

Überspringen Sie Tests

Lassen Sie TEST_SET_KEY in den CI/CD-Variablen unset. Der rules: -Block im Auftrag test überspringt es sauber.

Häufige Fallstricke

  • Maskiert != Geschützt. Eine maskierte Variable blendet den Wert in Protokollen aus, ist aber weiterhin für alle Verzweigungen (einschließlich kurzlebiger Funktionsverzweigungen) verfügbar. Eine geschützte Variable wird nur in geschützten Referenzen verfügbar gemacht. Sie möchten beides für Authentifizierungsgeheimnisse – andernfalls könnte eine verschobene Funktionsverzweigung uip login gegen Prod ausgeführt werden.
  • Indirekte Erweiterung erfordert Bash. ${!TENANT_VAR} ist eine Bash-Funktion; der Standardwert sh in einigen minimalen Images unterstützt dies nicht. Das node:20 -Bild enthält standardmäßig Bash; Fügen Sie auf alpine-basierten Images apk add bash hinzu oder wechseln Sie zu einer Fallanweisung über explizite Variablen pro Umgebung.
  • Matrix-Auftragsnamen enthalten Leerzeichen. needs: - job: "deploy: [dev, UIPATH_TENANT_DEV]" – Der Name enthält : [, also zitieren Sie ihn in YAML.
  • Cache-Pfade sind relativ zum Arbeitsbereich. Der Cache-Eintrag .npm-global/lib/node_modules funktioniert, da NPM_PREFIX="$CI_PROJECT_DIR/.npm-global" ihn innerhalb des Arbeitsbereichs einfügt. Wenn Sie das Präfix nach außerhalb verschieben, funktioniert der Cache nicht mehr.
  • set -euo pipefail muss oben in jedem mehrzeiligen Skript stehen. Ohne diese kann auf ein fehlgeschlagenes Pack eine „erfolgreiche“ Veröffentlichung eines veralteten Artefakts folgen. Siehe Skriptmuster – Strikte Shell-Optionen.

Siehe auch

War diese Seite hilfreich?

Verbinden

Benötigen Sie Hilfe? Support

Möchten Sie lernen? UiPath Academy

Haben Sie Fragen? UiPath-Forum

Auf dem neuesten Stand bleiben