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: ações do GitHub

Fluxo de trabalho completo do GitHub Actions para autenticar, empacotar, publicar, implantar uma Solução da UiPath e executar testes do Test Manager.

Esta página fornece um .github/workflows/deploy.yml 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 na implantação. Solte-o no seu repositório, adicione dois segredos 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 se concentra na sintaxe de ações do GitHub.

Para revisar solicitações de pull com um agente de codificação antes que elas atinjam esse pipeline, consulte Receita de CI/CD: revisão de solicitação de pull por agente.

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 nas configurações do repositório (ou organização/ambiente):
    • Configurações → Segredos e variáveis → Ações → Novo segredo do repositório.
    • Adicione UIPATH_CLIENT_ID e UIPATH_CLIENT_SECRET como segredos.
    • Adicione UIPATH_TENANT como uma variável (não é um segredo — não é confidencial).
    • Para as etapas de interface gráfica exatas, os comandos gh equivalentes e quando usar um segredo em vez de uma variável, consulte Configurar o repositório.
  3. Provisione um projeto do Test Manager e um conjunto de testes se você quiser o trabalho de teste. Coloque TEST_SET_KEY (por exemplo PROJECT:42) e PROJECT_KEY nas variáveis de repositório. Consulte Como fazer: executar testes a partir da CLI.

.github/workflows/deploy.yml

name: Deploy UiPath Solution

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

env:
  CLI_VERSION:      '1.0.0'
  NODE_VERSION:     '20'
  SOLUTION_NAME:    'my-solution'
  SOLUTION_DIR:     './my-solution'
  OUTPUT_DIR:       './dist'

jobs:

  build:
    name: Pack Solution
    runs-on: ubuntu-latest
    outputs:
      solution_version: ${{ steps.version.outputs.version }}
    steps:

      - uses: actions/checkout@v4

      - name: Compute version
        id: version
        run: echo "version=1.2.0-ci.${{ github.run_number }}" >> "$GITHUB_OUTPUT"

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install UiPath CLI
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/bin:$PATH"

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

      - name: Pack Solution
        id: pack
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$OUTPUT_DIR"
          uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
            --name "$SOLUTION_NAME" \
            --version "${{ steps.version.outputs.version }}"
          ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
          echo "artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"

      - uses: actions/upload-artifact@v4
        with:
          name: solution-zip
          path: ${{ steps.pack.outputs.artifact }}

  deploy:
    name: Publish and deploy
    needs: build
    runs-on: ubuntu-latest
    environment: uipath-prod   # attach approval gates here if needed
    steps:

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install UiPath CLI
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/bin:$PATH"

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

      - uses: actions/download-artifact@v4
        with:
          name: solution-zip
          path: ${{ env.OUTPUT_DIR }}

      - name: Authenticate
        shell: bash
        env:
          UIPATH_CLIENT_ID:     ${{ secrets.UIPATH_CLIENT_ID }}
          UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
          UIPATH_TENANT:        ${{ vars.UIPATH_TENANT }}
        run: |
          set -euo pipefail
          uip login \
            --client-id env.UIPATH_CLIENT_ID \
            --client-secret env.UIPATH_CLIENT_SECRET \
            --tenant "$UIPATH_TENANT"

      - name: Publish to tenant feed
        shell: bash
        run: |
          set -euo pipefail
          ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
          uip solution publish "$ARTIFACT"

      - name: Deploy to Orchestrator
        shell: bash
        run: |
          set -euo pipefail
          uip solution deploy run \
            --name "${SOLUTION_NAME}-${{ github.run_number }}" \
            --package-name "$SOLUTION_NAME" \
            --package-version "${{ needs.build.outputs.solution_version }}" \
            --folder-name MySolution \
            --parent-folder-path Shared

  test:
    name: Run Test Manager suite
    needs: deploy
    if: ${{ vars.TEST_SET_KEY != '' }}
    runs-on: ubuntu-latest
    steps:

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install CLI and authenticate
        shell: bash
        env:
          UIPATH_CLIENT_ID:     ${{ secrets.UIPATH_CLIENT_ID }}
          UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
          UIPATH_TENANT:        ${{ vars.UIPATH_TENANT }}
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/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"

      - name: Launch, wait, verify
        shell: bash
        env:
          TEST_SET_KEY: ${{ vars.TEST_SET_KEY }}
          PROJECT_KEY:  ${{ vars.PROJECT_KEY }}
        run: |
          set -euo pipefail

          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 "::error::test run did not finish within 30 minutes"; exit 2 ;;
              *) echo "::error::wait failed (exit $code)"; 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 "::error::$FAILED test case(s) failed"
            exit 1
          fi
name: Deploy UiPath Solution

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

env:
  CLI_VERSION:      '1.0.0'
  NODE_VERSION:     '20'
  SOLUTION_NAME:    'my-solution'
  SOLUTION_DIR:     './my-solution'
  OUTPUT_DIR:       './dist'

jobs:

  build:
    name: Pack Solution
    runs-on: ubuntu-latest
    outputs:
      solution_version: ${{ steps.version.outputs.version }}
    steps:

      - uses: actions/checkout@v4

      - name: Compute version
        id: version
        run: echo "version=1.2.0-ci.${{ github.run_number }}" >> "$GITHUB_OUTPUT"

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install UiPath CLI
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/bin:$PATH"

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

      - name: Pack Solution
        id: pack
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$OUTPUT_DIR"
          uip solution pack "$SOLUTION_DIR" "$OUTPUT_DIR" \
            --name "$SOLUTION_NAME" \
            --version "${{ steps.version.outputs.version }}"
          ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
          echo "artifact=$ARTIFACT" >> "$GITHUB_OUTPUT"

      - uses: actions/upload-artifact@v4
        with:
          name: solution-zip
          path: ${{ steps.pack.outputs.artifact }}

  deploy:
    name: Publish and deploy
    needs: build
    runs-on: ubuntu-latest
    environment: uipath-prod   # attach approval gates here if needed
    steps:

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install UiPath CLI
        shell: bash
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/bin:$PATH"

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

      - uses: actions/download-artifact@v4
        with:
          name: solution-zip
          path: ${{ env.OUTPUT_DIR }}

      - name: Authenticate
        shell: bash
        env:
          UIPATH_CLIENT_ID:     ${{ secrets.UIPATH_CLIENT_ID }}
          UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
          UIPATH_TENANT:        ${{ vars.UIPATH_TENANT }}
        run: |
          set -euo pipefail
          uip login \
            --client-id env.UIPATH_CLIENT_ID \
            --client-secret env.UIPATH_CLIENT_SECRET \
            --tenant "$UIPATH_TENANT"

      - name: Publish to tenant feed
        shell: bash
        run: |
          set -euo pipefail
          ARTIFACT=$(find "$OUTPUT_DIR" -maxdepth 1 -name "*.zip" | head -1)
          uip solution publish "$ARTIFACT"

      - name: Deploy to Orchestrator
        shell: bash
        run: |
          set -euo pipefail
          uip solution deploy run \
            --name "${SOLUTION_NAME}-${{ github.run_number }}" \
            --package-name "$SOLUTION_NAME" \
            --package-version "${{ needs.build.outputs.solution_version }}" \
            --folder-name MySolution \
            --parent-folder-path Shared

  test:
    name: Run Test Manager suite
    needs: deploy
    if: ${{ vars.TEST_SET_KEY != '' }}
    runs-on: ubuntu-latest
    steps:

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Cache npm global (@uipath/cli)
        uses: actions/cache@v4
        with:
          path: ~/.npm-global/lib/node_modules
          key:  uip-${{ env.CLI_VERSION }}-${{ runner.os }}

      - name: Install CLI and authenticate
        shell: bash
        env:
          UIPATH_CLIENT_ID:     ${{ secrets.UIPATH_CLIENT_ID }}
          UIPATH_CLIENT_SECRET: ${{ secrets.UIPATH_CLIENT_SECRET }}
          UIPATH_TENANT:        ${{ vars.UIPATH_TENANT }}
        run: |
          set -euo pipefail
          mkdir -p "$HOME/.npm-global"
          npm config set prefix "$HOME/.npm-global"
          echo "$HOME/.npm-global/bin" >> "$GITHUB_PATH"
          export PATH="$HOME/.npm-global/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"

      - name: Launch, wait, verify
        shell: bash
        env:
          TEST_SET_KEY: ${{ vars.TEST_SET_KEY }}
          PROJECT_KEY:  ${{ vars.PROJECT_KEY }}
        run: |
          set -euo pipefail

          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 "::error::test run did not finish within 30 minutes"; exit 2 ;;
              *) echo "::error::wait failed (exit $code)"; 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 "::error::$FAILED test case(s) failed"
            exit 1
          fi

Tutorial

Criar trabalho

  • actions/setup-node@v4 fixa o nó à versão principal especificada por NODE_VERSION. A CLI requer o Nó 18+.
  • actions/cache@v4 armazena em cache o diretório global node_modules npm, chaveado na versão da CLI fixada e no sistema operacional do executor. Quando o cache é atingido, a proteção if ! command -v uip da etapa de instalação se transforma em um não operacional.
  • A etapa de instalação configura um prefixo npm de usuário local (não sudo necessário em executores hospedados pelo GitHub), adiciona-o a GITHUB_PATH para que etapas posteriores consultem o comando uip e instala a CLI. A primeira invocação de um comando de ferramenta (uip solution …, uip tm …) instala automaticamente essa ferramenta — nenhum uip tools install explícito é necessário. Consulte Instalação do UiPath CLI — CI/CD.
  • A etapa Empacotar invoca uip solution pack com um --version explícito criado a partir de github.run_number (monito, exclusivo por execução no repositório). A etapa captura o caminho .zip produzido com find em vez de codificar o nome do arquivo — mantém a receita estável entre alterações da convenção de nomenclatura da CLI.
  • actions/upload-artifact@v4 carrega o .zip capturado para que o trabalho deploy possa baixá-lo na próxima execução.
  • outputs.solution_version propaga a versão computada para o trabalho deploy — a maneira mais simples de compartilhar um valor entre trabalhos no mesmo fluxo de trabalho.

Implantar trabalho

  • Reinstala a CLIneeds: build força a ordem de trabalho, mas cada trabalho é executado em um novo executor. O cache deve atingir a segunda instalação.
  • actions/download-artifact@v4 extrai solution-zip para $OUTPUT_DIR.
  • A etapa Autenticar passa segredos por meio do bloco env: da etapa e, em seguida, uip login os lê por meio do prefixo env. . O prefixo env.VAR_NAME é a maneira compatível de manter um segredo fora da linha de comando — consulte Autenticação — o prefixo env.var_NAME. Não escreva --client-secret "${{ secrets.UIPATH_CLIENT_SECRET }}" — isso incorpora o valor ao comando renderizado e ao log de etapas.
  • As etapas de publicação + implantação usam uip solution publish e uip solution deploy run. --name usa github.run_number para que cada implantação seja identificável.
  • environment: uipath-prod o trabalho a um ambiente de implantação. Os ambientes são onde você configura revisores necessários, temporizadores de espera e ramificações de implantação — mantenha-os na interface gráfica e deixe o YAML declarativo.

Trabalho de teste

Executa apenas se a variável repositório TEST_SET_KEY estiver definida — caso contrário, a proteção if: a ignorará. 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. Blocos uip tm wait até o estado terminal. A saída 2 significa o tempo limite em wait (não falha de autenticação); o código de saída é relatado por meio de ::error:: para que ele apareça na IU de ações.
  3. uip tm report getData.Failed e a etapa sai 1 quando algo falhou.

Variações comuns

Promover em ambientes

Adicione um deploy trabalho, que dependa do primeiro, com diferentes segredos:

  deploy-stage:
    needs: build
    environment: uipath-stage
    # …same steps as `deploy`, using ${{ secrets.UIPATH_STAGE_CLIENT_ID }} etc.

  deploy-prod:
    needs: deploy-stage
    environment: uipath-prod    # add "Required reviewers" in the environment settings
    # …same steps as `deploy`, using ${{ secrets.UIPATH_PROD_CLIENT_ID }} etc.
  deploy-stage:
    needs: build
    environment: uipath-stage
    # …same steps as `deploy`, using ${{ secrets.UIPATH_STAGE_CLIENT_ID }} etc.

  deploy-prod:
    needs: deploy-stage
    environment: uipath-prod    # add "Required reviewers" in the environment settings
    # …same steps as `deploy`, using ${{ secrets.UIPATH_PROD_CLIENT_ID }} etc.

As portas de aprovação estão nas configurações do ambiente — a ordem de aplicação da cadeia needs: . Consulte Como fazer: empacotar e publicar uma solução — promover um pacote entre tenants.

Reverter

Adicione uma entrada workflow_dispatch e um trabalho protegido que reimplanta uma versão específica:

on:
  workflow_dispatch:
    inputs:
      rollback_version:
        description: 'Version to roll back to (e.g. 1.1.9)'
        required: false
        type: string

jobs:
  rollback:
    if: ${{ github.event.inputs.rollback_version != '' }}
    runs-on: ubuntu-latest
    # …install + auth…
    steps:
      - name: Re-deploy previous version
        run: |
          uip solution deploy run \
            --name "${SOLUTION_NAME}-rollback" \
            --package-name "$SOLUTION_NAME" \
            --package-version "${{ github.event.inputs.rollback_version }}" \
            --folder-name MySolution \
            --parent-folder-path Shared
on:
  workflow_dispatch:
    inputs:
      rollback_version:
        description: 'Version to roll back to (e.g. 1.1.9)'
        required: false
        type: string

jobs:
  rollback:
    if: ${{ github.event.inputs.rollback_version != '' }}
    runs-on: ubuntu-latest
    # …install + auth…
    steps:
      - name: Re-deploy previous version
        run: |
          uip solution deploy run \
            --name "${SOLUTION_NAME}-rollback" \
            --package-name "$SOLUTION_NAME" \
            --package-version "${{ github.event.inputs.rollback_version }}" \
            --folder-name MySolution \
            --parent-folder-path Shared

Dispare com Ações → Implantar solução UiPath → Execute o fluxo de trabalho e insira a versão de reversão. Para reversão destrutiva (desinstalar + solution packages delete), consulte Instruções: empacotar e publicar uma solução — reverter.

Ignorar testes

Defina (ou deixe de definir) a variável de repositório TEST_SET_KEY . A proteção if: ${{ vars.TEST_SET_KEY != '' }} ignora o trabalho inteiro.

armadilhas comuns

  • interpolação${{ secrets.X }} . Ele substitui na camada de renderização de etapa. Se você colocar um segredo em uma linha de comando run: diretamente, o valor torna-se parte do script renderizado — e do log da etapa, a menos que o GitHub o mascare. Sempre encaminhe segredos por meio de env: e leia-os com env.VAR_NAME dentro de uip.
  • $GITHUB_PATH vs $PATH. A exportação de PATH=… em uma etapa não é carregada na próxima. Use echo "…" >> "$GITHUB_PATH" para persistir uma adição de PATH em etapas no mesmo executor.
  • strict shell options Inicie cada run: multilinha com set -euo pipefail — sem ele, um uip solution pack 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.
  • Armazene em cache falsos positivos. Se você atingir CLI_VERSION mas a chave de cache não a incluir, você continuará usando a CLI antiga. A chave neste YAML inclui ${{ env.CLI_VERSION }} exatamente por esse motivo.
  • O caminho do cache está associado ao prefixo npm. O bloco de cache usa ~/.npm-global/lib/node_modules, que só funciona porque a etapa de instalação é executada npm config set prefix "$HOME/.npm-global". Se você alterar o prefixo (por exemplo, em um executor do Windows auto-hospedado onde a convenção é %APPDATA%\npm\node_modules), tanto o cache path: quanto a linha npm config set prefix devem se mover juntos. Em um executor mais recente que não ubuntu, descarte o caminho real primeiro com - run: npm root -g e o que espelhar ele relatar.

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