- Información general
- Comience ya
- Conceptos
- Uso de UiPath CLI
- Guías prácticas
- Recetas de CI/CD
- Referencia de los comandos
- Información general
- Códigos de salida
- Opciones globales
- agente de código UIP
- codificador UIP
- Contextualización de UIP
- UIP Docsai
- Función uip
- barreras de seguridad de UIP
- Configuración de UIP llm
- puerta de enlace llm de uip
- UIP model-hub
- 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-repositorio-de-objetos-de-biblioteca
- obtener-objeto-repositorio
- obtener versiones
- get-workflow-example
- indicar-aplicación
- indicar-elemento
- inspeccionar-paquete
- install-data-fabric-entities
- instalar-o-actualizar-paquetes
- enumerar-data-fabric-entities
- lista-instancias
- ejemplos-de-flujo-de-trabajo-de-lista
- Paquete
- Publicar
- Remoto
- restore
- ejecutar, depurar & Ejecución
- archivo de ejecución
- plantillas-de-búsqueda
- iniciar-studio
- detener la ejecución
- TM
- UIA
- Tareas de UIP
- Archivo adjunto
- Campo personalizado
- Ejecuciones
- EtiquetaDeObjeto
- Paquete
- escenario de rendimiento
- grupos de carga de escenarios de rendimiento
- datos de ejecución de perf-scenario
- informe de escenario de rendimiento
- Proyecto
- Informar
- Requisitos
- Resultado
- Casos de prueba
- Conjuntos de prueba
- registro de pasos de prueba
- Usuario
- Esperar
- Seguimientos de UIP
- Comentarios de seguimientos de UIP
- Migración
- Referencia y soporte
Receta CI/CD: Azure Pipelines
Complete Azure Pipelines YAML para autenticar, empaquetar, publicar, implementar una solución UiPath y ejecutar pruebas de Test Manager.
Esta página te ofrece una azure-pipelines.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. El proceso es autónomo: cópialo en la raíz de tu repositorio, conecta 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 Azure Pipelines.
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 en un grupo de variables de Azure DevOps:
- Configuración del proyecto → Procesos → Biblioteca → Nuevo grupo de variables (por ejemplo,
uipath-prod). - Añade
UIPATH_CLIENT_IDyUIPATH_CLIENT_SECRET: marca ambos como secretos (icono de candado). - Opcionalmente, añade
UIPATH_TENANT(no un secreto).
- Configuración del proyecto → Procesos → Biblioteca → Nuevo grupo de variables (por ejemplo,
- Vincula el grupo de variables al proceso (consulta el bloque
variablesa continuación). - Aprovisiona un proyecto de Test Manager y un conjunto de pruebas (si quieres la etapa de prueba). Necesitarás el
TEST_SET_KEY(formatoPROJECT:42) yPROJECT_KEY. Consulta Tutorial: ejecutar pruebas desde la CLI.
azure-pipelines.yml
trigger:
branches:
include: [ main ]
pr:
branches:
include: [ main ]
variables:
- group: uipath-prod # contains UIPATH_CLIENT_ID, UIPATH_CLIENT_SECRET
- name: CLI_VERSION
value: '1.0.0'
- name: NODE_VERSION
value: '22.x'
- name: SOLUTION_NAME
value: 'my-solution'
- name: SOLUTION_DIR
value: '$(Build.SourcesDirectory)/my-solution'
- name: OUTPUT_DIR
value: '$(Build.ArtifactStagingDirectory)'
- name: SOLUTION_VERSION
value: '1.2.0-ci.$(Build.BuildId)'
# Path where npm places globally-installed packages. Used to cache the CLI + tools.
- name: NPM_GLOBAL_CACHE
value: '$(HOME)/.npm-global/lib/node_modules'
stages:
- stage: Build
displayName: 'Pack the Solution'
jobs:
- job: pack
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
fi
uip --version
displayName: 'Install UiPath CLI'
- script: |
set -euo pipefail
uip solution pack "$(SOLUTION_DIR)" "$(OUTPUT_DIR)" \
--name "$(SOLUTION_NAME)" \
--version "$(SOLUTION_VERSION)"
displayName: 'Pack Solution'
- publish: '$(OUTPUT_DIR)'
artifact: solution-zip
displayName: 'Publish artifact'
- stage: Deploy
displayName: 'Publish to feed and deploy to Orchestrator'
dependsOn: Build
jobs:
- deployment: deploy
environment: 'uipath-prod' # Azure DevOps environment — gates / approvals live here
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
fi
displayName: 'Install UiPath CLI'
- script: |
set -euo pipefail
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- download: current
artifact: solution-zip
- script: |
set -euo pipefail
ARTIFACT=$(find "$(Pipeline.Workspace)/solution-zip" -maxdepth 1 -name "*.zip" | head -1)
uip solution publish "$ARTIFACT"
displayName: 'Publish to tenant feed'
- script: |
set -euo pipefail
uip solution deploy run \
--name "$(SOLUTION_NAME)-$(Build.BuildId)" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(SOLUTION_VERSION)" \
--folder-name MySolution \
--parent-folder-path Shared
displayName: 'Deploy to Orchestrator'
- stage: Test
displayName: 'Run Test Manager suite'
dependsOn: Deploy
condition: and(succeeded(), ne(variables['TEST_SET_KEY'], ''))
jobs:
- job: test
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
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"
displayName: 'Install + authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- script: |
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 "##vso[task.logissue type=error]test run did not finish within 30 minutes"; exit 2 ;;
*) echo "##vso[task.logissue type=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 "##vso[task.logissue type=error]$FAILED test case(s) failed"
exit 1
fi
displayName: 'Launch, wait, verify'
env:
TEST_SET_KEY: $(TEST_SET_KEY)
PROJECT_KEY: $(PROJECT_KEY)
trigger:
branches:
include: [ main ]
pr:
branches:
include: [ main ]
variables:
- group: uipath-prod # contains UIPATH_CLIENT_ID, UIPATH_CLIENT_SECRET
- name: CLI_VERSION
value: '1.0.0'
- name: NODE_VERSION
value: '22.x'
- name: SOLUTION_NAME
value: 'my-solution'
- name: SOLUTION_DIR
value: '$(Build.SourcesDirectory)/my-solution'
- name: OUTPUT_DIR
value: '$(Build.ArtifactStagingDirectory)'
- name: SOLUTION_VERSION
value: '1.2.0-ci.$(Build.BuildId)'
# Path where npm places globally-installed packages. Used to cache the CLI + tools.
- name: NPM_GLOBAL_CACHE
value: '$(HOME)/.npm-global/lib/node_modules'
stages:
- stage: Build
displayName: 'Pack the Solution'
jobs:
- job: pack
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
fi
uip --version
displayName: 'Install UiPath CLI'
- script: |
set -euo pipefail
uip solution pack "$(SOLUTION_DIR)" "$(OUTPUT_DIR)" \
--name "$(SOLUTION_NAME)" \
--version "$(SOLUTION_VERSION)"
displayName: 'Pack Solution'
- publish: '$(OUTPUT_DIR)'
artifact: solution-zip
displayName: 'Publish artifact'
- stage: Deploy
displayName: 'Publish to feed and deploy to Orchestrator'
dependsOn: Build
jobs:
- deployment: deploy
environment: 'uipath-prod' # Azure DevOps environment — gates / approvals live here
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
mkdir -p "$HOME/.npm-global"
npm config set prefix "$HOME/.npm-global"
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
if ! command -v uip >/dev/null; then
npm install -g "@uipath/cli@$(CLI_VERSION)"
fi
displayName: 'Install UiPath CLI'
- script: |
set -euo pipefail
uip login \
--client-id env.UIPATH_CLIENT_ID \
--client-secret env.UIPATH_CLIENT_SECRET \
--tenant "$UIPATH_TENANT"
displayName: 'Authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- download: current
artifact: solution-zip
- script: |
set -euo pipefail
ARTIFACT=$(find "$(Pipeline.Workspace)/solution-zip" -maxdepth 1 -name "*.zip" | head -1)
uip solution publish "$ARTIFACT"
displayName: 'Publish to tenant feed'
- script: |
set -euo pipefail
uip solution deploy run \
--name "$(SOLUTION_NAME)-$(Build.BuildId)" \
--package-name "$(SOLUTION_NAME)" \
--package-version "$(SOLUTION_VERSION)" \
--folder-name MySolution \
--parent-folder-path Shared
displayName: 'Deploy to Orchestrator'
- stage: Test
displayName: 'Run Test Manager suite'
dependsOn: Deploy
condition: and(succeeded(), ne(variables['TEST_SET_KEY'], ''))
jobs:
- job: test
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
displayName: 'Use Node.js $(NODE_VERSION)'
inputs:
versionSpec: $(NODE_VERSION)
- task: Cache@2
displayName: 'Cache npm global (@uipath/cli)'
inputs:
key: 'uip | "$(Agent.OS)" | $(CLI_VERSION)'
path: $(NPM_GLOBAL_CACHE)
- script: |
set -euo pipefail
export PATH="$HOME/.npm-global/bin:$PATH"
echo "##vso[task.prependpath]$HOME/.npm-global/bin"
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"
displayName: 'Install + authenticate'
env:
UIPATH_CLIENT_ID: $(UIPATH_CLIENT_ID)
UIPATH_CLIENT_SECRET: $(UIPATH_CLIENT_SECRET)
UIPATH_TENANT: $(UIPATH_TENANT)
- script: |
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 "##vso[task.logissue type=error]test run did not finish within 30 minutes"; exit 2 ;;
*) echo "##vso[task.logissue type=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 "##vso[task.logissue type=error]$FAILED test case(s) failed"
exit 1
fi
displayName: 'Launch, wait, verify'
env:
TEST_SET_KEY: $(TEST_SET_KEY)
PROJECT_KEY: $(PROJECT_KEY)
Tutorial
Etapa 1: compilación
NodeTool@0ancla Node.js a la versión 22. Anclar a una especialidad; el CLI requiere 22+.Cache@2almacena en caché el directorionode_modulesglobal de npm. La clave de caché incluye$(CLI_VERSION), por lo que un golpe de versión invalida limpiamente.- El paso de instalación cambia el prefijo global de npm a
$HOME/.npm-global(no se necesitasudo), lo antepone a la RUTA y, solo si la caché se ha perdido, instala@uipath/cli. La primera invocación de un comando de herramienta (uip solution …,uip tm …) instala automáticamente esa herramienta, por lo que no se necesitauip tools installexplícito. Consulta Instalar UiPath CLI: patrones de CI/CD y scripting: fijación de versiones. - El paso de paquete invoca
uip solution packcon un--versionexplícito (nunca confíes en el1.0.0predeterminado en CI). publish: ...carga el$(OUTPUT_DIR)completo como un artefacto de proceso llamadosolution-zippara que la etapa de implementación pueda consumirlo. Publicar el directorio en lugar de un nombre de archivo codificado mantiene la receta estable a través de los cambios en la convención de nomenclatura de CLI.
Etapa 2: implementación
Utiliza un trabajo de implementación vinculado a un entorno con nombre. Los entornos son donde configuras las puertas y aprobaciones en Azure DevOps: el propio YAML sigue siendo simple.
- Reinstala la CLI (la caché debe aparecer en la segunda etapa de la misma ejecución).
uip loginutiliza el prefijoenv.VAR_NAMEtanto para el ID de cliente como para el secreto. El bloqueenv:en el nivel de paso asigna$(UIPATH_CLIENT_ID)(del grupo de variables) a la variable de entorno realUIPATH_CLIENT_IDque resuelve el marcador. No pases el secreto literalmente en la línea de comandos (--client-secret "$(UIPATH_CLIENT_SECRET)"), eso lo filtra en el registro de compilación y la salidaps. La característica del prefijoenv.se documenta en Autenticación: el prefijo env.VAR_NAME.download: currentextrae el artefactosolution-zipde la etapa 1 a$(Pipeline.Workspace)/solution-zip.uip solution publishcarga.zipen la fuente del tenant.uip solution deploy runcrea la implementación.--nameutiliza$(Build.BuildId)para que el registro de cada implementación sea identificable, pero--folder-name/--parent-folder-pathson estáticos ydeploy runsiempre crea una nueva implementación en una nueva carpeta; nunca actualiza uno existente. En una ejecución repetida contra un paquete ya implementado, se detiene y apunta a la ruta de actualización (a menos que se pase--yes, que implementa una segunda copia renombrada por colisión:MySolution 1,MySolution 2, ...). Esa comprobación previa necesita una sesión de usuario, por lo que se omite por completo en el inicio de sesión de credenciales de cliente, que utiliza este proceso: cada ejecución verde aquí crea una nueva carpeta. Para actualizar la implementación existente en su lugar, utilizauip solution deploy upgrade <deployment-key>(busca la clave conuip solution deploy list --folder-path Shared).
Etapa 3: prueba
Solo se ejecuta si TEST_SET_KEY está establecido en el nivel de grupo de variables: el protector condition: omite la etapa limpiamente si no tienes un conjunto de pruebas configurado.
El bloque de shell es el lanzamiento canónico → esperar → verificar flujo de Tutorial: ejecutar pruebas desde la CLI:
uip tm testsets runinicia la ejecución y devuelve unExecutionId.uip tm waitse bloquea hasta que la ejecución alcanza un estado terminal (la salida2significa tiempo de espera, no fallo de autenticación: una reutilización específica del dominio de la ranura del código de salida).uip tm report getleeData.Failed; el paso falla con##vso[task.logissue type=error], por lo que el resultado aparece claramente en la interfaz de usuario de Azure DevOps.
Variaciones comunes
Promocionar en todos los entornos
Vincula dos grupos de variables, uipath-stage y uipath-prod , y convierte cada uno en un trabajo deployment: independiente. Usa puertas/aprobaciones específicas del entorno para decidir cuándo se ejecuta producción:
- stage: DeployStage
dependsOn: Build
jobs:
- deployment: deploy-stage
variables: [ { group: uipath-stage } ]
environment: 'uipath-stage'
# …same steps as above, but with stage's tenant
- stage: DeployProd
dependsOn: DeployStage
jobs:
- deployment: deploy-prod
variables: [ { group: uipath-prod } ]
environment: 'uipath-prod' # attach a manual approval gate here
# …same steps as above
- stage: DeployStage
dependsOn: Build
jobs:
- deployment: deploy-stage
variables: [ { group: uipath-stage } ]
environment: 'uipath-stage'
# …same steps as above, but with stage's tenant
- stage: DeployProd
dependsOn: DeployStage
jobs:
- deployment: deploy-prod
variables: [ { group: uipath-prod } ]
environment: 'uipath-prod' # attach a manual approval gate here
# …same steps as above
Cobertura más profunda en Tutorial: empaquetar y publicar una solución: promocionar un paquete entre tenants.
Reversión
Azure DevOps no se revierte automáticamente; añade una etapa manual que actualice la implementación existente a la versión anterior: deploy run crearía una nueva carpeta en lugar de tocar la que estás intentando revertir:
- stage: Rollback
dependsOn: [] # run on demand, not from Deploy
jobs:
- job: rollback
pool: { vmImage: 'ubuntu-latest' }
steps:
# …install + auth…
- script: |
set -euo pipefail
DEPLOYMENT_KEY=$(uip solution deploy list --folder-path Shared \
--output-filter "Data[?Name=='MySolution'].Key | [0]" --output plain)
uip solution deploy upgrade "$DEPLOYMENT_KEY" --version "$(ROLLBACK_VERSION)"
displayName: 'Roll back to previous version'
- stage: Rollback
dependsOn: [] # run on demand, not from Deploy
jobs:
- job: rollback
pool: { vmImage: 'ubuntu-latest' }
steps:
# …install + auth…
- script: |
set -euo pipefail
DEPLOYMENT_KEY=$(uip solution deploy list --folder-path Shared \
--output-filter "Data[?Name=='MySolution'].Key | [0]" --output plain)
uip solution deploy upgrade "$DEPLOYMENT_KEY" --version "$(ROLLBACK_VERSION)"
displayName: 'Roll back to previous version'
Pase ROLLBACK_VERSION en el tiempo de cola. deploy upgrade conserva la configuración existente de la implementación (los valores de activos/credenciales ya establecidos no se restablecen a los valores predeterminados del paquete). Para la reversión destructiva (desinstalar + eliminar artefacto), consulta Tutorial: empaquetar y publicar una solución: reversión.
Omitir pruebas
Para ejecutar sin la etapa de prueba, elimina el bloque de etapa Test (o deja TEST_SET_KEY sin establecer; el condition: en la etapa lo omitirá).
Errores comunes
env.prefijo frente a secreto literal. Siempre--client-secret env.UIPATH_CLIENT_SECRET, nunca--client-secret "$(UIPATH_CLIENT_SECRET)". La forma literal incrusta el valor en la línea de comandos renderizada. Consulta la advertencia de autenticación.##vso[task.setvariable]no es necesario para la resoluciónenv.—env:en el paso expone la variable directamente.- Bash multilínea necesita
set -euo pipefailen la parte superior de cada bloquescript:. Sin ella,packpuede fallar mientras los pasos posteriores siguen ejecutándose. Consulta Patrones de scripts: opciones de shell estrictas. - Los aciertos de caché no están garantizados. Envuelve siempre los comandos de instalación en
if ! command -v uippara que el proceso se autorrepare cuando la caché esté fría.
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 en profundidad.
- Receta CI/CD: GitHub Actions, Jenkins, GitLab CI : el mismo proceso en otras plataformas.