UiPath Documentation
uipath-cli
latest
false
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.

Guia do usuário da UiPath CLI

Receita de CI/CD: GitLab CI

Esta página fornece a você um .gitlab-ci.yml completo que instala a CLI, autentica com um Aplicativo Externo, empacota e publica uma Solução da UiPath, a implanta no Orchestrator por vários tenants (através de uma matriz) e executa um pacote do Test Manager. Solte-o na raiz do seu repositório, defina três variáveis de CI/CD e ele 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 concentra-se na sintaxe do GitLab, incluindo as funcionalidades (cache com um escopo chaveado, parallel: matrix) que são específicas do GitLab.

Pré-requisitos

Antes de copiar o YAML abaixo:

  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 como variáveis de CI/CD:
    • Projeto → Configurações → CI/CD → Variáveis.
    • Adicione UIPATH_CLIENT_ID e UIPATH_CLIENT_SECRET. Marque ambos como Mascarado e Protegido (para que eles sejam expostos apenas em ramificações/tags protegidas).
    • Adicione UIPATH_TENANT_DEV, UIPATH_TENANT_STAGE, UIPATH_TENANT_PROD com os nomes de tenants (não mascarados — os nomes de tenants não são confidenciais).
  3. Provisione um projeto do Test Manager e um conjunto de testes se você quiser o trabalho de teste. Adicione TEST_SET_KEY e PROJECT_KEY como variáveis regulares.

.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

Tutorial

Configuração de nível superior

  • image: node:20 — todos os trabalhos são executados na imagem oficial do Node.js 20. A CLI requer o Nó 18+. Se seu executor do GitLab já tiver o nó instalado e você não precisar de um contêiner, remova-o e use um executor shell .
  • variables: os valores em todo o pipeline. SOLUTION_VERSION interpola $CI_PIPELINE_IID (o número de pipeline incremental com escopo de projeto — melhor para controle de versão do que $CI_JOB_ID, que é global e não monitorado).
  • Âncora.install-uip — O GitLab não permite que você anexe blocos script: diretamente, mas você pode ancorar um nó YAML contendo uma string de shell e uni-lo com - *install-uip. Mesma proteção de instalação que as outras fórmulas: prefixo do espaço de trabalho local, instalação condicional da CLI. As ferramentas são instaladas automaticamente no primeiro uso para que a âncora identifique apenas o host.
  • cache: a chave uip-$CLI_VERSION garante que um aumento na versão da CLI invalide o cache corretamente. policy: pull-push lê na entrada e grava na saída do trabalho bem-sucedida. Se você executar em escala e quiser economizar segundos de cada trabalho, divida em um trabalho dedicado "semente o cache" que executa pull-push e faça com que todos os outros trabalhos usem apenas policy: pull .

Empacotar trabalho

  • Instala a CLI por meio da âncora compartilhada.
  • uip solution pack com uma versão explícita — uip solution pack
  • artifacts: carrega .zip para o próximo estágio. O caminho é um glob ($OUTPUT_DIR/*.zip), então ele coleta qualquer nome de arquivo uip solution pack produz. expire_in: 30 days impede que o armazenamento de artefatos do GitLab aumente sem limites; processe se precisar de uma rastreabilidade mais longa.

implantar trabalho com paralelo: array

A matriz se expande em três trabalhos — deploy: [dev, UIPATH_TENANT_DEV], deploy: [stage, UIPATH_TENANT_STAGE], deploy: [prod, UIPATH_TENANT_PROD] — que são executados em paralelo. Cada um recebe um $ENVIRONMENT e $TENANT_VAR diferentes e usa a expansão indireta do bash (${!TENANT_VAR}) para ler o tenant por ambiente da variável CI/CD correta.

  • environment: name: uipath/$ENVIRONMENT O GitLab rastreia implantações em sua visualização Ambientes, para que cada tenant obtenha um histórico por ambiente com botões de reversão.
  • rules: — a primeira regra bloqueia prod de ramificações não protegidas. Combinado com Configurações → Repositório → Ramificações protegidas (onde você marca main protegida), é assim que você impede que uma ramificação de funcionalidade seja implantada acidentalmente em produção. As variáveis UIPATH_CLIENT_* também devem ser marcadas Protegidas para que sejam resolvidas apenas em referências protegidas.
  • uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET o prefixo env.VAR_NAME é a maneira suportada de passar um segredo para a CLI sem que ele nunca apareça na linha de comando do shell. O GitLab mascara variáveis em logs quando marcado Mascarado, mas o prefixo env. é uma proteção em profundidade de qualquer maneira. Consulte Autenticação — o prefixo env.var_NAME.
  • Nome da implantação$SOLUTION_NAME-$ENVIRONMENT-$CI_PIPELINE_IID torna cada implantação rastreável para uma execução e ambiente do pipeline específicos.
Observação:

Em trabalhos de matriz paralela, se uma etapa falhar, as outras continuam executando por padrão. Se você quiser que o prod aguarde o desenvolvimento e o estágio, transforme a matriz em três trabalhos sequenciais (ou use needs: entre eles).

Trabalho de teste

  • needs: faz referência à etapa da matriz por seu nome expandido — "deploy: [dev, UIPATH_TENANT_DEV]". O optional: true torna a dependência não fatal se a etapa dev for ignorada pelo bloco rules: .
  • rules: ignora o trabalho quando TEST_SET_KEY não é definido, mesmo padrão que as outras fórmulas.
  • Iniciar → aguarde → verificar — o padrão de teste canônico de Como fazer: executar testes a partir da CLI. A saída 2 de uip tm wait significa o tempo limite (não falha de autenticação).

Variações comuns

Promoção em série com porta manual

Se você quiser que o prod exija um clique manual em vez de um gatilho de ramificação protegido, divida a matriz em três trabalhos e adicione when: manual ao de produção:

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…

Reverter

Dispare manualmente por meio de um trabalho separado com uma variável de pipeline:

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

Inicie o pipeline a partir de CI/CD → Pipelines → Executar pipeline e defina ROLLBACK_VERSION como a versão de destino (por exemplo, 1.1.9). Para reversão destrutiva (desinstalar + excluir artefato), consulte Instruções: empacotar e publicar uma solução — reverter.

Ignorar testes

Deixe TEST_SET_KEY não definido nas variáveis CI/CD. O bloco rules: no trabalho test o ignora corretamente.

armadilhas comuns

  • Mascarado != Protegido. Uma variável mascarada oculta o valor nos logs, mas ainda está disponível em todas as ramificações (incluindo ramificações com funcionalidades de curta duração). Uma variável protegida só expõe referências protegidas. Você deseja ambos para segredos de autenticação — caso contrário, uma ramificação de funcionalidade enviada pode ser uip login em relação a prod.
  • A expansão indireta precisa do bash. ${!TENANT_VAR} uma funcionalidade do bash; o padrão sh em algumas imagens mínimas não é compatível com ele. A imagem node:20 inclui o bash por padrão; em imagens baseadas em alpine , adicione apk add bash ou alterne para uma instrução de caso em vez de variáveis explícitas por ambiente.
  • Os nomes dos trabalhos de matriz contêm espaços. needs: - job: "deploy: [dev, UIPATH_TENANT_DEV]" o nome inclui : [, portanto, registre-o em YAML.
  • Os caminhos de cache são relativos ao espaço de trabalho. A entrada de cache .npm-global/lib/node_modules funciona porque NPM_PREFIX="$CI_PROJECT_DIR/.npm-global" a coloca dentro do espaço de trabalho. Se você mover o prefixo para fora, o cache deixará de funcionar.
  • set -euo pipefail deve estar no topo de cada script de várias linhas. Sem ele, um pacote com falha pode ser seguido por uma publicação "bem-sucedida" de um artefato obsoleto. Consulte Padrões de script — opções estritas de shell.

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