UiPath Documentation
uipath-cli
latest
false
Guia do usuário da UiPath CLI
Importante :
Este conteúdo foi traduzido com auxílio de tradução automática. A localização de um conteúdo recém-publicado pode levar de 1 a 2 semanas para ficar disponível.

Receita de CI/CD: Jenkins

JenkinsFile declarativo completo para autenticar, empacotar, publicar, implantar uma solução da UiPath e executar testes do Test Manager.

Esta página fornece um Jenkinsfiledeclarativo completo que instala a CLI, autentica com um Aplicativo Externo, empacota e publica uma Solução da UiPath, a implanta no Orchestrator e executa um pacote do Test Manager. Coloque-a na raiz do seu repositório, crie uma entrada de credenciais correspondente do Jenkins e o pipeline será executado.

Para os princípios subjacentes — autenticação, cache, pré-instalação de ferramentas, aplicação de versão — consulte Como fazer: implantar no Orchestrator a partir de CI. Esta página se concentra na sintaxe do Jenkins, incluindo os bits (withCredentials, stash / unstash, seleção de agente) que são específicos do Jenkins.

Pré-requisitos

Antes de copiar o arquivo Jenkins:

  1. Crie um aplicativo externo na UiPath com os escopos OR.* de que seu pipeline precisa. Consulte Autenticação — Fluxo 2.
  2. Armazene os segredos nas credenciais do Jenkins:
    • Gerenciar Jenkins → Credenciais → Sistema → Credenciais globais (sem restrição).
    • Adicione duas entradas de Texto secreto com IDs UIPATH_CLIENT_ID e UIPATH_CLIENT_SECRET.
    • Adicione uma entrada de Texto simples ou Texto secreto com ID UIPATH_TENANT (o nome do tenant; não estritamente secreto, mas as credenciais são o local mais portátil).
  3. Requisitos do agente O pipeline assume um agente rotulado linux com Node.js 18+ e npm no PATH. Veja as opções de agentes alternativas abaixo se você executar no Windows ou em um contêiner.
  4. Provisione um projeto do Test Manager e um conjunto de testes se você quiser o estágio de teste. Adicione TEST_SET_KEY e PROJECT_KEY como credenciais adicionais (ou como parâmetros do pipeline).

Arquivo do Jenkins

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

Tutorial

Configuração de nível superior

  • agent none no topo declara que o pipeline não tem agente padrão; cada estágio escolhe o seu próprio com agent { label 'linux' }. Isso permite que você crie um agente de alta capacidade e implante em um agente bloqueado se sua infraestrutura os separar dessa forma.
  • optionstimestamps() adiciona prefixos [2026-04-24T10:30:12] a cada linha do console, o que torna a depuração de execuções longas muito mais fácil. disableConcurrentBuilds() impede que duas implantações entrem na mesma pasta do Orchestrator.
  • Blocoenvironment — o mesmo padrão que as outras fórmulas: fixar CLI_VERSION, calcular SOLUTION_VERSION a partir de BUILD_NUMBER e rotear o prefixo global do npm para o espaço de trabalho para que as instalações sejam por compilação e não precisem sudo.

Estágio de criação

  • checkout scm O Jenkins precisa disso explicitamente em um pipeline declarativo.
  • Etapa de instalação — a mesma if ! command -v uip proteção que outras plataformas. O prefixo npm do espaço de trabalho local ($NPM_PREFIX) significa que toda compilação começa limpa; sem armazenamento em cache entre as execuções. Se seus agentes do Jenkins forem persistentes e você quiser armazenar em cache a CLI, use o plug-in Job Cacher ou defina NPM_PREFIX como um caminho no agente, em vez de ${env.WORKSPACE}.
  • Etapa do pacote — diretamente uip solution pack com uma versão explícita.
  • stash name: 'solution-zip' essa é a parte específica do Jenkins. Ao contrário dos artefatos GitHub Actions ou Pipelines do Azure publish, um stash está limitado à execução do pipeline e persiste entre os estágios sem precisar do espaço de trabalho para persistir. O Stash usa um glob (${OUTPUT_DIR}/*.zip) para obter qualquer nome de arquivo uip solution pack produz. Cada estágio que precisa das chamadas .zip unstash 'solution-zip' em seu início. Consulte os documentos do Jenkins em stash / unstash.
  • archiveArtifacts uma cópia do .zip também aparece na página de compilação para download por humanos. fingerprint: true permite que o Jenkins rastreie-o em trabalhos.

Estágio de implantação

  • restaura unstash 'solution-zip' para o espaço .zip trabalho. Combinado com um novo agente, isso separa com clareza o "contexto de construção" do "contexto de implantação".
  • withCredentials vincula três entradas de credenciais a variáveis de ambiente visíveis ao bloco sh . O fechamento é o limite seguro de credenciais — os valores são mascarados no log do console e não vazados para nenhuma etapa fora desse bloco. Use isso para cada chamada uip que fale com o Orchestrator.
  • uip login usa env.UIPATH_CLIENT_ID / env.UIPATH_CLIENT_SECRET — o prefixo env.VAR_NAME lê a variável definida por withCredentials. Consulte Autenticação — o prefixo env.var_NAME. Nunca interpole o segredo na linha de comando diretamente (--client-secret "$UIPATH_CLIENT_SECRET") — que o incorpora ao comando do shell renderizado e, sob algumas configurações de registro em log, na saída do console.
  • Publicar + implantaruip solution publish e depois uip solution deploy run. --name "${SOLUTION_NAME}-${BUILD_NUMBER}" torna cada implantação rastreável de volta à sua compilação do Jenkins.

Estágio de teste

Fechado por when { expression { return env.TEST_SET_KEY?.trim() } } — se você não definir a credencial TEST_SET_KEY (ou deixá-la em branco), o estágio será ignorado. O bloco de shell é o padrão de inicialização → aguardar → verificação de Como fazer: executar testes a partir da CLI:

  1. uip tm testsets run inicia e retorna um ExecutionId.
  2. uip tm wait é bloqueado até que a execução atinja um estado terminal. Em wait, o código de saída 2 significa tempo limite (não falha de autenticação — é uma reutilização do código específica do domínio).
  3. uip tm report getData.Failed e o shell sai 1 quando algum teste falhar.

postar { sempre }

Melhor esforço uip logout. Em agentes efêmeros, isso é desnecessário; em um agente persistente, ele limpa a pasta .uipath/ local do espaço de trabalho para que um trabalho posterior no mesmo espaço de trabalho não reutilize uma sessão obsoleta. O || true ingerir o erro se uip nunca foi instalado (a compilação falhou antes da instalação).

Variações comuns

Variações do agente

  • Agente do Windows — substitua sh por bat, traduza os scripts bash para cmd.exe ou PowerShell. O prefixo env. e cada comando uip são idênticos; apenas as mudanças de shell ao redor. Consulte Instalação do UiPath CLI — Windows.
  • Agente do Dockeragent { docker { image 'node:20' } } dá a você um novo runtime de nó por compilação com configuração de agente zero. Adicione args '-u root' se você precisar de instalações globais npm sem sudo em uma imagem rootful; caso contrário, configure o prefixo NPM como $WORKSPACE/.npm-global conforme acima e pule a dança de privilégio.
  • Plug-in do Kubernetes — use um modelo de pod com um contêiner node:20 e monte /root/.npm-global como um PVC para armazenar em cache a CLI entre compilações.

Promover em ambientes

Transforme cada ambiente em seu próprio estágio, reutilizando o 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...'
    }
  }
}

A etapa input pausa o pipeline até que um humano clique em Implantar. Use a Estratégia de Autorização de Matriz do Jenkins para restringir quem pode aprovar. Cobertura mais profunda em Como fazer: empacotar e publicar uma Solução — promover um pacote entre os tenants.

Reverter

Adicione um trabalho parametrizado — Jenkins → Novo item → Pipeline → Este projeto é parametrizar → Adicionar parâmetro (String) → "ROLL Robot_VERSION" — e adicione um estágio protegido:

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 \
          --parent-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 \
          --parent-folder-path Shared
      '''
    }
  }
  environment {
    ROLLBACK_VERSION = "${params.ROLLBACK_VERSION}"
  }
}

Dispare a partir da página de compilação com Build with Parâmetros. Para reversão destrutiva (desinstalar + excluir artefato), consulte Instruções: empacotar e publicar uma solução — reverter.

armadilhas comuns

  • escopo dewithCredentials . As credenciais estão disponíveis apenas dentro do fechamento. Se você chamar uip login dentro de withCredentials e uip solution publish fora, o segundo comando não terá sessão. Mantenha todo o bloco CLI dentro de um withCredentials.
  • stash de alterar os agentes. Um stash declarado em um estágio é utilizável em estágios posteriores somente se a etapa de arquivo principal for executada antes da troca do agente. Se o bloco de shell do estágio Build sair diferente de zero antes de stash, os estágios posteriores falharão em unstash. Colocar stash fora do bloco sh — como nesta receita — garante que ele seja executado em um agente limpo, independentemente do resultado do shell.
  • na hora|| true . O uip logout || true em post é seguro porque o único modo de falha é "uip nunca foi instalado". Não preencha || true com estágios anteriores — isso oculta falhas reais.
  • modosh . Inicie o script bash de cada bloco sh com #!/usr/bin/env bash e set -euo pipefail. O shell padrão do Jenkins é /bin/sh, que não é compatível com pipefail. Consulte Padrões de script — opções estritas de shell.
  • Strings multilinha no Groups Prefira strings com aspas triplas ('''...''') para corpos de shell — elas não interpolam $VAR, de modo que a variável é expandida pelo bash em vez de pelo Grooty. Isso evita uma classe comum de bugs "a variável está vazia". Para valores que você deseja que o Groupe preencha no tempo de compilação do pipeline, use ${env.SOME_VAR} explicitamente.

Veja também

Esta página foi útil?

Conectar

Precisa de ajuda? Suporte

Quer aprender? Academia UiPath

Tem perguntas? Fórum do UiPath

Fique por dentro das novidades