UiPath Documentation
uipath-cli
latest
false
重要 :
このコンテンツは機械翻訳によって処理されています。 新しいコンテンツの翻訳は、およそ 1 ~ 2 週間で公開されます。

UiPath CLI ユーザー ガイド

CI/CD レシピ: Jenkins

このページでは、CLI のインストール、外部アプリケーションでの認証、UiPath ソリューションのパッケージ化とパブリッシュ、Orchestrator へのデプロイ、および Test Manager スイートの実行を、宣言 的な Jenkinsfile で完全に説明しています。これをリポジトリのルートに配置し、一致する Jenkins 資格情報エントリを作成すると、パイプラインが実行されます。

基本原則 (認証、キャッシュ、ツールのプレインストール、バージョンのピン留め) については、「 方法: CI から Orchestrator にデプロイする」をご覧ください。このページでは、Jenkins 固有のビット (withCredentialsstash / unstash、エージェントの選択) を含め、Jenkins 構文に焦点を当てています。

前提条件

Jenkinsfile をコピーする前に、以下を実行します。

  1. パイプラインに必要なOR.*スコープを持つ外部アプリケーションを UiPath で作成します「認証 — フロー 2」を参照してください。
  2. シークレットを Jenkins の資格情報に保存します。
    • Jenkins の → 資格情報を System → Global Credentials (無制限) →管理します
    • ID が UIPATH_CLIENT_IDUIPATH_CLIENT_SECRETの 2 つの [シークレット テキスト] エントリを追加します。
    • ID が UIPATH_TENANT (テナント名。厳密にはシークレットではありませんが、資格情報が最も移植性の高い場所です) の [プレーン テキスト] または [シークレット テキスト] エントリを追加します。
  3. エージェントの要件。パイプラインは、Node.js 18+ のラベルが付いた linux のラベルが付いたエージェントが PATH 上に npm と想定しています。Windows で実行する場合、またはコンテナーで実行する場合は、以下の 代替エージェント オプション をご覧ください。
  4. テスト ステージが必要な場合は、Test Manager プロジェクトとテスト セットをプロビジョニングします。TEST_SET_KEYPROJECT_KEY を追加の資格情報として (またはパイプライン パラメーターとして) 追加します。

Jenkinsfile

pipeline {
  agent none

  options {
    timestamps()
    buildDiscarder(logRotator(numToKeepStr: '30'))
    disableConcurrentBuilds()
  }

  environment {
    CLI_VERSION      = '1.0.0'
    SOLUTION_NAME    = 'my-solution'
    SOLUTION_DIR     = 'my-solution'
    OUTPUT_DIR       = 'dist'
    SOLUTION_VERSION = "1.2.0-ci.${env.BUILD_NUMBER}"

    // npm global prefix for a user-local, no-sudo install
    NPM_PREFIX       = "${env.WORKSPACE}/.npm-global"
  }

  stages {

    stage('Build') {
      agent { label 'linux' }
      steps {
        checkout scm
        sh '''#!/usr/bin/env bash
          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

          mkdir -p "$OUTPUT_DIR"
          uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
            --name "$SOLUTION_NAME" \
            --version "$SOLUTION_VERSION"
        '''

        // Carry the .zip to the Deploy stage, which runs on a fresh agent.
        stash name: 'solution-zip', includes: "${OUTPUT_DIR}/*.zip"

        archiveArtifacts artifacts: "${OUTPUT_DIR}/*.zip", fingerprint: true
      }
    }

    stage('Deploy') {
      agent { label 'linux' }
      steps {
        unstash 'solution-zip'

        withCredentials([
          string(credentialsId: 'UIPATH_CLIENT_ID',     variable: 'UIPATH_CLIENT_ID'),
          string(credentialsId: 'UIPATH_CLIENT_SECRET', variable: 'UIPATH_CLIENT_SECRET'),
          string(credentialsId: 'UIPATH_TENANT',        variable: 'UIPATH_TENANT')
        ]) {
          sh '''#!/usr/bin/env bash
            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 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}-${BUILD_NUMBER}" \
              --package-name "$SOLUTION_NAME" \
              --package-version "$SOLUTION_VERSION" \
              --folder-name MySolution \
              --folder-path Shared
          '''
        }
      }
    }

    stage('Test') {
      when {
        expression { return env.TEST_SET_KEY?.trim() }
      }
      agent { label 'linux' }
      steps {
        withCredentials([
          string(credentialsId: 'UIPATH_CLIENT_ID',     variable: 'UIPATH_CLIENT_ID'),
          string(credentialsId: 'UIPATH_CLIENT_SECRET', variable: 'UIPATH_CLIENT_SECRET'),
          string(credentialsId: 'UIPATH_TENANT',        variable: 'UIPATH_TENANT'),
          string(credentialsId: 'TEST_SET_KEY',         variable: 'TEST_SET_KEY'),
          string(credentialsId: 'PROJECT_KEY',          variable: 'PROJECT_KEY')
        ]) {
          sh '''#!/usr/bin/env bash
            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 login \
              --client-id env.UIPATH_CLIENT_ID \
              --client-secret env.UIPATH_CLIENT_SECRET \
              --tenant "$UIPATH_TENANT"

            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
          '''
        }
      }
    }
  }

  post {
    always {
      // Best-effort cleanup; uip logout only matters on a persistent agent.
      node('linux') {
        sh '''
          if command -v uip >/dev/null; then
            uip logout || true
          fi
        '''
      }
    }
  }
}
pipeline {
  agent none

  options {
    timestamps()
    buildDiscarder(logRotator(numToKeepStr: '30'))
    disableConcurrentBuilds()
  }

  environment {
    CLI_VERSION      = '1.0.0'
    SOLUTION_NAME    = 'my-solution'
    SOLUTION_DIR     = 'my-solution'
    OUTPUT_DIR       = 'dist'
    SOLUTION_VERSION = "1.2.0-ci.${env.BUILD_NUMBER}"

    // npm global prefix for a user-local, no-sudo install
    NPM_PREFIX       = "${env.WORKSPACE}/.npm-global"
  }

  stages {

    stage('Build') {
      agent { label 'linux' }
      steps {
        checkout scm
        sh '''#!/usr/bin/env bash
          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

          mkdir -p "$OUTPUT_DIR"
          uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
            --name "$SOLUTION_NAME" \
            --version "$SOLUTION_VERSION"
        '''

        // Carry the .zip to the Deploy stage, which runs on a fresh agent.
        stash name: 'solution-zip', includes: "${OUTPUT_DIR}/*.zip"

        archiveArtifacts artifacts: "${OUTPUT_DIR}/*.zip", fingerprint: true
      }
    }

    stage('Deploy') {
      agent { label 'linux' }
      steps {
        unstash 'solution-zip'

        withCredentials([
          string(credentialsId: 'UIPATH_CLIENT_ID',     variable: 'UIPATH_CLIENT_ID'),
          string(credentialsId: 'UIPATH_CLIENT_SECRET', variable: 'UIPATH_CLIENT_SECRET'),
          string(credentialsId: 'UIPATH_TENANT',        variable: 'UIPATH_TENANT')
        ]) {
          sh '''#!/usr/bin/env bash
            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 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}-${BUILD_NUMBER}" \
              --package-name "$SOLUTION_NAME" \
              --package-version "$SOLUTION_VERSION" \
              --folder-name MySolution \
              --folder-path Shared
          '''
        }
      }
    }

    stage('Test') {
      when {
        expression { return env.TEST_SET_KEY?.trim() }
      }
      agent { label 'linux' }
      steps {
        withCredentials([
          string(credentialsId: 'UIPATH_CLIENT_ID',     variable: 'UIPATH_CLIENT_ID'),
          string(credentialsId: 'UIPATH_CLIENT_SECRET', variable: 'UIPATH_CLIENT_SECRET'),
          string(credentialsId: 'UIPATH_TENANT',        variable: 'UIPATH_TENANT'),
          string(credentialsId: 'TEST_SET_KEY',         variable: 'TEST_SET_KEY'),
          string(credentialsId: 'PROJECT_KEY',          variable: 'PROJECT_KEY')
        ]) {
          sh '''#!/usr/bin/env bash
            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 login \
              --client-id env.UIPATH_CLIENT_ID \
              --client-secret env.UIPATH_CLIENT_SECRET \
              --tenant "$UIPATH_TENANT"

            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
          '''
        }
      }
    }
  }

  post {
    always {
      // Best-effort cleanup; uip logout only matters on a persistent agent.
      node('linux') {
        sh '''
          if command -v uip >/dev/null; then
            uip logout || true
          fi
        '''
      }
    }
  }
}

チュートリアル

最上位のセットアップ

  • 上部にあるagent noneは、パイプラインに既定のエージェントがないことを宣言しています。各ステージは、agent { label 'linux' }で独自のものを選択します。これにより、ビルドを大容量エージェントに配置し、インフラストラクチャがロックダウンされたエージェントに分散している場合は、そのようにデプロイできます。
  • optionstimestamps() はすべてのコンソール行に [2026-04-24T10:30:12] プレフィックスを追加するため、長時間の実行のデバッグがはるかに簡単になります。disableConcurrentBuilds() 、2 つのデプロイが同じ Orchestrator フォルダーに競合することが防止されます。
  • environmentブロック — 他のレシピと同じパターンです: ピンCLI_VERSIONBUILD_NUMBERからSOLUTION_VERSIONを計算し、 npm のグローバルプレフィックスをワークスペースにルーティングするため、インストールはビルドごとに行われ、sudoは必要ありません。

ビルド ステージ

  • checkout scm — Jenkins は、宣言型パイプラインでこれを明示的に必要とします。
  • インストール手順 — 他のプラットフォームと同じ if ! command -v uip ガードです。workspace-local npm プレフィックス ($NPM_PREFIX) は、すべてのビルドがクリーンに開始されることを意味します。実行間でキャッシュが行われない。Jenkins エージェントが永続的で、CLI をキャッシュする場合は、ジョブキャッシャープラグインを使用するか、${env.WORKSPACE}ではなくエージェント上のパスに NPM_PREFIX を設定します。
  • パックステップ — 明示的なバージョンでストレート uip solution pack
  • stash name: 'solution-zip' — これはジェンキンス特有の作品です。GitHub Actions 成果物や Azure Pipelines publishとは異なり、 stash はパイプラインの実行にスコープが設定され、ワークスペースを保持することなく、ステージ間で存続します。stash は glob (${OUTPUT_DIR}/*.zip) を使用するため、生成したファイル名 uip solution pack 取得します。.zip を必要とするすべてのステージは、開始時にunstash 'solution-zip'を呼び出します。stash / unstashに関する Jenkins ドキュメントを参照してください。
  • archiveArtifacts.zipのコピーもビルドページに表示され、人間がダウンロードすることができます。fingerprint: true を使用すると、Jenkins は複数のジョブにわたって追跡できます。

デプロイ ステージ

  • unstash 'solution-zip'ワークスペースに.zipを復元します。新しいエージェントと組み合わせることで、「ビルドコンテキスト」と「デプロイコンテキスト」が明確に分離されます。
  • withCredentials は、3 つの資格情報エントリを、sh ブロックに表示される環境変数にバインドします。クロージャはクレデンシャルセーフ境界です — 値はコンソールログでマスクされ、このブロックの外側のステップにリークされることはありません。Orchestrator と通信するすべての uip 呼び出しに使用します。
  • uip loginenv.UIPATH_CLIENT_ID / env.UIPATH_CLIENT_SECRET を使用します — env.VAR_NAME プレフィックスは withCredentialsによって設定された変数を読み取ります。「認証 — 環境」を参照してください。VAR_NAMEプレフィックス。シークレットをコマンドラインに直接補間しないでください (--client-secret "$UIPATH_CLIENT_SECRET") — レンダリングされたシェルコマンドに埋め込まれ、一部のログ設定ではコンソール出力に埋め込まれます。
  • パブリッシュ + デプロイ その後uip solution publish uip solution deploy run--name "${SOLUTION_NAME}-${BUILD_NUMBER}" により、各デプロイを Jenkins ビルドまでさかのぼることができます。

テストステージ

when { expression { return env.TEST_SET_KEY?.trim() } }によるゲート — TEST_SET_KEY資格情報を設定しない (または空のままにする) と、ステージはスキップされます。シェルブロックは、「 方法:CLIからテストを実行する 」 →パターンの検証→待機 する正規の起動です。

  1. uip tm testsets run が起動し、ExecutionIdが返されます。
  2. 実行が終了ステートに達するまでブロックuip tm waitwaitでは、終了2コードはタイムアウトを意味します(認証の失敗ではなく、ドメイン固有のコードの再利用です)。
  3. uip tm report getData.Failedを読み取り、テストが失敗するとシェルは1終了します。

投稿 { always }

ベストエフォートuip logout一時的なエージェントでは、これは不要です。永続エージェントでは、ワークスペースローカルの .uipath/ フォルダーがクリアされるため、同じワークスペース上の後続のジョブで古いセッションが再利用されません。|| true は、uip がインストールされていない (インストール前にビルドが失敗した) 場合、エラーを飲み込みます。

一般的なバリエーション

エージェントのバリエーション

  • Windows エージェントshbatに置き換え、bash スクリプトを cmd.exe または PowerShell に変換します。env. プレフィックスとすべての uip コマンドは同一です。周囲のシェルのみが変更されます。「 UiPath CLI のインストール — Windows」をご覧ください。
  • Dockerエージェントagent { docker { image 'node:20' } } 、エージェント構成がゼロのビルドごとに新しいノードランタイムを提供します。ルートフルイメージにsudo-freeグローバルnpmをインストールする必要がある場合は、 args '-u root' を追加します。それ以外の場合は、上記のように NPM プレフィックスを $WORKSPACE/.npm-global に設定し、特権ダンスをスキップします。
  • Kubernetes プラグインnode:20 コンテナーでポッド テンプレートを使用し、 /root/.npm-global を PVC としてマウントして、ビルド間で CLI をキャッシュします。

環境間でプロモートする

各環境を独自のステージに変換し、同じ stashを再利用します。

stage('Deploy stage') {
  agent { label 'linux' }
  steps {
    unstash 'solution-zip'
    withCredentials([string(credentialsId: 'UIPATH_STAGE_CLIENT_ID', variable: 'UIPATH_CLIENT_ID'), ...]) {
      sh '...deploy to stage tenant...'
    }
  }
}

stage('Approval') {
  steps {
    input message: 'Deploy to production?', ok: 'Deploy'
  }
}

stage('Deploy prod') {
  agent { label 'linux' }
  steps {
    unstash 'solution-zip'
    withCredentials([string(credentialsId: 'UIPATH_PROD_CLIENT_ID', variable: 'UIPATH_CLIENT_ID'), ...]) {
      sh '...deploy to prod tenant...'
    }
  }
}
stage('Deploy stage') {
  agent { label 'linux' }
  steps {
    unstash 'solution-zip'
    withCredentials([string(credentialsId: 'UIPATH_STAGE_CLIENT_ID', variable: 'UIPATH_CLIENT_ID'), ...]) {
      sh '...deploy to stage tenant...'
    }
  }
}

stage('Approval') {
  steps {
    input message: 'Deploy to production?', ok: 'Deploy'
  }
}

stage('Deploy prod') {
  agent { label 'linux' }
  steps {
    unstash 'solution-zip'
    withCredentials([string(credentialsId: 'UIPATH_PROD_CLIENT_ID', variable: 'UIPATH_CLIENT_ID'), ...]) {
      sh '...deploy to prod tenant...'
    }
  }
}

input手順では、人間が [デプロイ] をクリックするまでパイプラインを一時停止します。Jenkins の マトリックス承認戦略 を使用して、承認できるユーザーを制限します。「使い方」のより詳細な説明 : ソリューションをパッケージ化してパブリッシュする — 1 つのパッケージを複数のテナントに昇格させます

ロールバック

パラメーター化されたジョブ ( Jenkins → New Item → Pipeline → を追加します このプロジェクトは、パラメーター (文字列) → "ROLLBACK_VERSION" →パラメーター化され 、保護されたステージを追加します。

stage('Rollback') {
  when { expression { return params.ROLLBACK_VERSION?.trim() } }
  agent { label 'linux' }
  steps {
    withCredentials([/* UIPATH_* credentials */]) {
      sh '''#!/usr/bin/env bash
        set -euo pipefail
        # …install + login…

        uip solution deploy run \
          --name "${SOLUTION_NAME}-rollback" \
          --package-name "$SOLUTION_NAME" \
          --package-version "$ROLLBACK_VERSION" \
          --folder-name MySolution \
          --folder-path Shared
      '''
    }
  }
  environment {
    ROLLBACK_VERSION = "${params.ROLLBACK_VERSION}"
  }
}
stage('Rollback') {
  when { expression { return params.ROLLBACK_VERSION?.trim() } }
  agent { label 'linux' }
  steps {
    withCredentials([/* UIPATH_* credentials */]) {
      sh '''#!/usr/bin/env bash
        set -euo pipefail
        # …install + login…

        uip solution deploy run \
          --name "${SOLUTION_NAME}-rollback" \
          --package-name "$SOLUTION_NAME" \
          --package-version "$ROLLBACK_VERSION" \
          --folder-name MySolution \
          --folder-path Shared
      '''
    }
  }
  environment {
    ROLLBACK_VERSION = "${params.ROLLBACK_VERSION}"
  }
}

[パラメーターを指定して構築] を使用して [構築] ページからトリガーします。破壊的なロールバック (アンインストール + 成果物の削除) については、「 方法: ソリューションをパックして発行する — ロールバック」を参照してください。

よくある落とし穴

  • withCredentials スコーピング。認証情報はクロージャー内でのみ利用可能です。uip loginwithCredentials 内で呼び出し、uip solution publish を外部で呼び出した場合、2 番目のコマンドにはセッションがありません。CLI ブロック全体を 1 つの withCredentials内に保持します。
  • エージェントを変更する前にstashしてください。あるステージで宣言された stash は、エージェントが切り替わる前にスタッシュ・ステップが完了していた場合にのみ、後のステージで使用できます。Build ステージのシェル ブロックが stashより前に 0 以外から出た場合、後のステージは unstashで失敗します。このレシピのようにstashshブロックの外に置くことで、シェルの結果に関係なく、クリーンなエージェントで動作するようになります。
  • 間違ったタイミングで|| truepostuip logout || trueは、唯一の障害モードが「uipがインストールされなかった」であるため安全です。初期の段階で || true を唐辛子にしないでください—それは本当の失敗を隠します。
  • sh ストリクト モードです。sh ブロックのすべての bash スクリプトを #!/usr/bin/env bashset -euo pipefailで開始します。既定の Jenkins シェルは /bin/shです。これは pipefailをサポートしていません。スクリプトパターン — 厳密なシェルオプション を参照してください。
  • Groovyの複数行の文字列。シェル本体にはトリプルシングルクォート文字列 ('''...''') を優先します — $VARを補間しないため、変数は Groovy ではなく bash で展開されます。これにより、一般的なクラスの「変数が空である」というバグが回避されます。パイプラインのコンパイル時にGroovyに入力させたい値については、 ${env.SOME_VAR} 明示的に使用してください。

参照

このページは役に立ちましたか?

接続

ヘルプ リソース サポート

学習する UiPath アカデミー

質問する UiPath フォーラム

最新情報を取得