- Información general
- Comience ya
- Conceptos
- Uso de UiPath CLI
- UiPath para agentes de codificación
- Guías prácticas
- Recetas de CI/CD
- Azure DevOps
- Acciones de GitHub
- Jenkins
- CI de GitLab
- Referencia de los comandos
- Información general
- Códigos de salida
- Opciones globales
- agente de código UIP
- UIP Docsai
- añadir-entidad-de-datos-de-prueba
- añadir-cola-de-datos-de-prueba
- añadir-variación-de-datos-de-prueba
- Analizar
- Crear
- Crear proyecto
- Diferencia
- Buscar actividades
- obtener-reglas-del-analizador
- obtener-predeterminado-actividad-xaml
- obtener-errores
- obtener-casos-de-prueba-manual
- obtener-pasos-de-prueba-manual
- obtener versiones
- get-workflow-example
- indicar-aplicación
- indicar-elemento
- inspeccionar-paquete
- install-data-fabric-entities
- instalar-o-actualizar-paquetes
- enumerar-data-fabric-entities
- ejemplos-de-flujo-de-trabajo-de-lista
- Paquete
- restore
- archivo de ejecución
- plantillas-de-búsqueda
- iniciar-studio
- detener la ejecución
- UIA
- Seguimientos de UIP
- Migración
- Referencia y soporte
Guía del usuario de UiPath CLI
Esta página te ofrece una .gitlab-ci.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 en varios tenants (a través de una matriz) y ejecuta una suite de Test Manager. Suéltalo en la raíz de tu repositorio, establece tres variables CI/CD 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 GitLab, incluidas las características (caché con un ámbito con clave, parallel: matrix) que son específicas de GitLab.
Requisitos previos
Antes de copiar el siguiente YAML:
- Cree una aplicación externa en UiPath con los
OR.*ámbitos que necesita su proceso. Consulta Autenticación: flujo 2. - Almacena los secretos como variables CI/CD:
- Proyecto → Configuración → CI/CD → Variables.
- Añade
UIPATH_CLIENT_IDyUIPATH_CLIENT_SECRET. Marca ambos como Enmascarados y Protegidos (para que solo se expongan en ramas/etiquetas protegidas). - Añade
UIPATH_TENANT_DEV,UIPATH_TENANT_STAGE,UIPATH_TENANT_PRODcon los nombres de los tenants (no enmascarados: los nombres de los tenants no son confidenciales).
- Aprovisiona un proyecto de Test Manager y un conjunto de pruebas si quieres el trabajo de prueba. Añade
TEST_SET_KEYyPROJECT_KEYcomo variables 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
Configuración de nivel superior
image: node:20: cada trabajo se ejecuta en la imagen oficial de Node.js 20. La CLI requiere Node 18+. Si tu ejecutor de GitLab ya tiene Node instalado y no necesitas un contenedor, puedes eliminarlo y utilizar un ejecutorshellen su lugar.variables:: los valores de todo el proceso.SOLUTION_VERSIONinterpola$CI_PIPELINE_IID(el número de proceso incremental en el ámbito del proyecto, mejor para el control de versiones que$CI_JOB_ID, que es global y no monótono).- Anclaje
.install-uip: GitLab no te permite anclar bloquesscript:directamente, pero puedes anclar un nodo YAML que contenga una cadena de shell y empalmarlo con- *install-uip. La misma protección de instalación que las otras recetas: prefijo local del espacio de trabajo, instalación CLI condicional. Las herramientas se instalan automáticamente en el primer uso, por lo que el anclaje solo maneja el host. cache:: la claveuip-$CLI_VERSIONgarantiza que un aumento de la versión CLI invalide la caché de forma limpia.policy: pull-pushlee en la entrada y escribe en la salida del trabajo con éxito. Si ejecutas a escala y quieres ahorrar segundos en cada trabajo, divídelo en un trabajo dedicado a "sembrar la caché" que se ejecutepull-pushy haz que todos los demás trabajos utilicen solopolicy: pull.
Empaquetar trabajo
- Instala la CLI a través del anclaje compartido.
uip solution packcon una versión explícita — consultauip solution pack.artifacts:lleva.zipa la siguiente etapa. La ruta es un global ($OUTPUT_DIR/*.zip), por lo que recoge cualquier nombre de archivo que produzcauip solution pack.expire_in: 30 daysevita que el almacenamiento de artefactos de GitLab crezca sin límites; elimínelo si necesita una trazabilidad más larga.
implementar trabajo con paralelo: matriz
La matriz se expande en tres trabajos, deploy: [dev, UIPATH_TENANT_DEV], deploy: [stage, UIPATH_TENANT_STAGE], deploy: [prod, UIPATH_TENANT_PROD] , que se ejecutan en paralelo. Cada uno obtiene un $ENVIRONMENT y $TENANT_VAR diferentes, y utiliza la expansión indirecta de bash (${!TENANT_VAR}) para leer el tenant por entorno de la variable CI/CD derecha.
environment: name: uipath/$ENVIRONMENT— GitLab realiza un seguimiento de las implementaciones en su vista de Entornos, por lo que cada tenant obtiene un historial por entorno con botones de reversión.rules:: la primera regla bloqueaprodde las ramas no protegidas. Combinado con Configuración → Repositorio → Ramas protegidas (donde marcasmainprotegido), así es como evitas que una rama de características se implemente accidentalmente en producción. Las variablesUIPATH_CLIENT_*también deben marcarse como Protegidas para que solo se resuelvan en referencias protegidas.uip login --client-id env.UIPATH_CLIENT_ID --client-secret env.UIPATH_CLIENT_SECRET— el prefijoenv.VAR_NAMEes la forma admitida de pasar un secreto a la CLI sin que aparezca nunca en la línea de comandos del shell. GitLab enmascara las variables en los registros cuando se marcan como Enmascaradas, pero el prefijoenv.es una defensa en profundidad de todos modos. Consulta Autenticación: el prefijo env.VAR_NAME.- Nombre de la implementación :
$SOLUTION_NAME-$ENVIRONMENT-$CI_PIPELINE_IIDhace que cada implementación sea rastreable a una ejecución y entorno de proceso específicos.
En los trabajos de matriz paralela, si falla un tramo, los demás siguen ejecutándose de forma predeterminada. Si quieres que producción espere a dev y etapa, convierte la matriz en tres trabajos secuenciales (o utiliza needs: entre ellos) en su lugar.
trabajo de prueba
needs:hace referencia a la rama de la matriz por su nombre expandido:"deploy: [dev, UIPATH_TENANT_DEV]".optional: truehace que la dependencia no sea grave si el bloquerules:omite la etapa de desarrollo.rules:omite el trabajo cuandoTEST_SET_KEYno está configurado, el mismo patrón que las otras recetas.- Iniciar → esperar → verificar : el patrón de prueba canónico de Tutorial: ejecutar pruebas desde la CLI. La salida
2deuip tm waitsignifica tiempo de espera (no fallo de autenticación).
Variaciones comunes
Promoción en serie con puerta manual
Si quieres que prod requiera un clic manual en lugar de una activación de rama protegida, divide la matriz en tres trabajos y añade when: manual al de prod:
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_PROD…
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_PROD…
Cobertura más profunda en Tutorial: empaquetar y publicar una solución: promocionar un paquete entre tenants.
Reversión
Desencadenador manual a través de un trabajo independiente con una variable de proceso:
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
Inicia el proceso desde CI/CD → Procesos → Ejecutar proceso y establece ROLLBACK_VERSION en la versión de destino (por ejemplo, 1.1.9). Para la reversión destructiva (desinstalar + eliminar artefacto), consulta Tutorial: empaquetar y publicar una solución: reversión.
Omitir pruebas
Deja TEST_SET_KEY sin establecer en las variables CI/CD. El bloque rules: en el trabajo test lo omite limpiamente.
Errores comunes
- Enmascarado != Protegido. Una variable enmascarada oculta el valor en los registros, pero sigue estando disponible en todas las ramas (incluidas las ramas de características de corta duración). Una variable protegida solo se expone en referencias protegidas. Quieres ambos para los secretos de autenticación; de lo contrario, una rama de característica insertada podría ejecutarse
uip loginen prod. - La expansión indirecta necesita bash.
${!TENANT_VAR}es una característica bash; elshpredeterminado en algunas imágenes mínimas no lo admite. La imagennode:20incluye bash de forma predeterminada; en imágenes basadas enalpine, añadeapk add basho cambia a una declaración de caso sobre variables explícitas por entorno. - Los nombres de trabajos de matriz contienen espacios.
needs: - job: "deploy: [dev, UIPATH_TENANT_DEV]": el nombre incluye: [, así que cítalo en YAML. - Las rutas de caché son relativas al espacio de trabajo. La entrada de caché
.npm-global/lib/node_modulesfunciona porqueNPM_PREFIX="$CI_PROJECT_DIR/.npm-global"la coloca dentro del espacio de trabajo. Si mueves el prefijo fuera, la caché deja de funcionar. set -euo pipefaildebe estar en la parte superior de cada script multilínea. Sin él, un paquete fallido puede ser seguido por una publicación "correcta" de un artefacto obsoleto. Consulta Patrones de scripts: opciones de shell estrictas.
Ver también
- Tutorial: implementar en Orchestrator desde CI : orientación independiente de la plataforma.
- Tutorial: empaquetar y publicar una solución : control de versiones y reversión.
- Tutorial: ejecutar pruebas desde la CLI : el patrón iniciar → esperar → verificar.
- Receta CI/CD: Azure Pipelines, GitHub Actions, Jenkins : el mismo proceso en otras plataformas.