UiPath Documentation
uipath-cli
latest
false
Importante :
Este contenido se ha traducido mediante traducción automática. La localización de contenidos recién publicados puede tardar entre una y dos semanas en estar disponible.

Guía del usuario de UiPath CLI

Receta CI/CD: Acciones de GitHub

Esta página te ofrece una .github/workflows/deploy.yml completa que instala la CLI, se autentica con una aplicación externa, empaqueta y publica una solución de UiPath, la implementa en Orchestrator y ejecuta una suite de Test Manager para la implementación. Suéltalo en tu repositorio, añade dos secretos y se ejecuta.

Para conocer los principios subyacentes (autenticación, almacenamiento en caché, preinstalación de herramientas, fijación de versiones), consulta Cómo: implementar en Orchestrator desde CI. Esta página se centra en la sintaxis de las acciones de GitHub.

Requisitos previos

Antes de copiar el siguiente YAML:

  1. Cree una aplicación externa en UiPath con los OR.* ámbitos que necesita su proceso. Consulta Autenticación: flujo 2.
  2. Almacena los secretos en la configuración del repositorio (u organización/entorno):
    • Configuración → Secretos y variables → Acciones → Nuevo secreto del repositorio.
    • Añade UIPATH_CLIENT_ID y UIPATH_CLIENT_SECRET como secretos.
    • Añade UIPATH_TENANT como variable (no es un secreto, no es confidencial).
  3. Aprovisiona un proyecto de Test Manager y un conjunto de pruebas si quieres el trabajo de prueba. Pon TEST_SET_KEY (p. ej. PROJECT:42) y PROJECT_KEY en las variables del repositorio. Consulta Tutorial: ejecutar pruebas desde la 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 \
            --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 \
            --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

Crear trabajo

  • actions/setup-node@v4 fija el nodo a la versión principal especificada por NODE_VERSION. La CLI requiere Node 18+.
  • actions/cache@v4 almacena en caché el directorio global npm node_modules , introducido en la versión CLI anclada y el sistema operativo del ejecutor. Cuando la caché llega, la protección if ! command -v uip del paso de instalación se convierte en un no-op.
  • El paso de instalación configura un prefijo npm local de usuario (no es necesario sudo en los ejecutores alojados en GitHub), lo añade a GITHUB_PATH para que los pasos posteriores vean el comando uip e instala la CLI. La primera invocación de un comando de herramienta (uip solution …, uip tm …) instala automáticamente esa herramienta; no se necesita uip tools install explícito. Consulta Instalar UiPath CLI — CI/CD.
  • El paso de paquete invoca uip solution pack con un --version explícito creado a partir de github.run_number (monótono, único por ejecución en el repositorio). El paso captura la ruta .zip producida con find en lugar de codificar el nombre del archivo: mantiene la receta estable a través de los cambios en la convención de nomenclatura de CLI.
  • actions/upload-artifact@v4 carga el .zip capturado para que el trabajo deploy pueda descargarlo en la siguiente ejecución.
  • outputs.solution_version propaga la versión calculada al trabajo deploy : la forma más sencilla de compartir un valor entre trabajos en el mismo flujo de trabajo.

Implementar trabajo

  • Reinstala la CLI : needs: build fuerza el orden de los trabajos, pero cada trabajo se ejecuta en un ejecutor nuevo. La caché debería aparecer en la segunda instalación.
  • actions/download-artifact@v4 extrae solution-zip en $OUTPUT_DIR.
  • El paso de autenticación pasa los secretos a través del bloque env: del paso y luego uip login los lee a través del prefijo env. . El prefijo env.VAR_NAME es la forma admitida de mantener un secreto fuera de la línea de comandos. Consulta Autenticación: el prefijo env.VAR_NAME. No escribas --client-secret "${{ secrets.UIPATH_CLIENT_SECRET }}" : eso incrusta el valor en el comando renderizado y en el registro de pasos.
  • Los pasos de publicación e implementación utilizan uip solution publish y uip solution deploy run. --name utiliza github.run_number para que cada implementación sea identificable.
  • environment: uipath-prod el trabajo a un entorno de implementación. Los entornos son donde configuras los revisores necesarios, los temporizadores de espera y las ramas de implementación: mantenlos en la IU y deja el declarativo de YAML.

trabajo de prueba

Solo se ejecuta si la variable de repositorio TEST_SET_KEY está establecida; de lo contrario, el protector if: la omite. El bloque de shell es el patrón canónico de lanzamiento → esperar → verificar de Tutorial: ejecutar pruebas desde la CLI:

  1. uip tm testsets run inicia y devuelve un ExecutionId.
  2. uip tm wait bloquea hasta el estado terminal. La salida 2 significa tiempo de espera en wait (no fallo de autenticación); el código de salida se informa a través de ::error:: para que aparezca en la IU de Actions.
  3. uip tm report get lee Data.Failed y el paso sale de 1 cuando algo falla.

Variaciones comunes

Promocionar en todos los entornos

Añade un segundo trabajo deploy que dependa del primero, con diferentes secretos:

  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.

Las puertas de aprobación se encuentran en la configuración del entorno: la cadena needs: aplica el orden. Consulta Tutorial: empaquetar y publicar una solución: promocionar un paquete entre tenants.

Reversión

Añade una entrada workflow_dispatch y un trabajo protegido que vuelva a implementar una versión 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 \
            --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 \
            --folder-path Shared

Desencadenador con Acciones → Implementar la solución UiPath → Ejecutar flujo de trabajo e introducir la versión de reversión. Para la reversión destructiva (desinstalar + solution packages delete), consulta Tutorial: empaquetar y publicar una solución: reversión.

Omitir pruebas

Establece (o deja sin establecer) la variable de repositorio TEST_SET_KEY . El protector if: ${{ vars.TEST_SET_KEY != '' }} omite todo el trabajo.

Errores comunes

  • ${{ secrets.X }} interpolación. Sustituye en la capa de renderizado por pasos. Si introduces un secreto en una línea de comandos run: directamente, el valor pasa a formar parte del script renderizado y del registro de pasos, a menos que GitHub lo enmascare. Enruta siempre los secretos a través de env: y léelos con env.VAR_NAME dentro de uip.
  • $GITHUB_PATH frente a $PATH. Exportar PATH=… en un paso no lleva al siguiente. Usa echo "…" >> "$GITHUB_PATH" para persistir una adición de PATH en todos los pasos en el mismo ejecutor.
  • strict shell options. Comienza cada run: multilínea con set -euo pipefail : sin ella, un uip solution pack fallido puede ser seguido por una publicación "correcta" de un artefacto obsoleto. Consulta Patrones de scripts: opciones de shell estrictas.
  • Caché de falsos positivos. Si modificas CLI_VERSION , pero la clave de caché no la incluye, seguirás utilizando la CLI antigua. La clave en este YAML incluye ${{ env.CLI_VERSION }} exactamente por este motivo.
  • La ruta de caché está acoplada al prefijo npm. El bloque de caché utiliza ~/.npm-global/lib/node_modules, que solo funciona porque el paso de instalación se ejecuta npm config set prefix "$HOME/.npm-global". Si cambias el prefijo (por ejemplo, en un ejecutor de Windows autoalojado donde la convención es %APPDATA%\npm\node_modules), tanto la caché path: como la línea npm config set prefix deben moverse juntas. En un ejecutor no ubuntu-latest, volca primero la ruta real con - run: npm root -g y refleja lo que informe.

Ver también

¿Te ha resultado útil esta página?

Conectar

¿Necesita ayuda? Soporte

¿Quiere aprender? UiPath Academy

¿Tiene alguna pregunta? Foro de UiPath

Manténgase actualizado