Especificar trabajos en la canalización
Azure DevOps Services | Azure DevOps Server 2022: Azure DevOps Server 2019 | TFS 2018
Nota:
En Microsoft Team Foundation Server (TFS) 2018 y versiones anteriores, las canalizaciones de compilación y versión se denominan definiciones, las ejecuciones se denominan compilaciones, las conexiones de servicio se denominan puntos de conexión de servicio, las fases se denominan entornos y los trabajos se denominan fases.
Puede organizar la canalización en trabajos. Cada canalización tiene al menos un trabajo. Un trabajo es una serie de pasos que se ejecutan secuencialmente como una unidad. En otras palabras, un trabajo es la unidad de trabajo más pequeña que se puede programar para ejecutarse.
Puede organizar la canalización de compilación o versión en trabajos. Cada canalización tiene al menos un trabajo. Un trabajo es una serie de pasos que se ejecutan secuencialmente como una unidad. En otras palabras, un trabajo es la unidad de trabajo más pequeña que se puede programar para ejecutarse.
Nota:
Debe instalar TFS 2018.2 para usar trabajos en procesos de compilación. En TFS 2018 RTM, puede usar trabajos en procesos de implementación de versión.
Definición de un único trabajo
En el caso más sencillo, una canalización tiene un único trabajo. En ese caso, no es necesario usar explícitamente la job
palabra clave a menos que use una plantilla. Puede especificar directamente los pasos del archivo YAML.
Este archivo YAML tiene un trabajo que se ejecuta en un agente hospedado Microsoft y genera Hello world
.
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"
Es posible que desee especificar propiedades adicionales en ese trabajo. En ese caso, puede usar la job
palabra clave .
jobs:
- job: myJob
timeoutInMinutes: 10
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"
La canalización puede tener varios trabajos. En ese caso, use la jobs
palabra clave .
jobs:
- job: A
steps:
- bash: echo "A"
- job: B
steps:
- bash: echo "B"
La canalización puede tener varias fases, cada una con varios trabajos. En ese caso, use la stages
palabra clave .
stages:
- stage: A
jobs:
- job: A1
- job: A2
- stage: B
jobs:
- job: B1
- job: B2
La sintaxis completa para especificar un trabajo es:
- job: string # name of the job, A-Z, a-z, 0-9, and underscore
displayName: string # friendly name to display in the UI
dependsOn: string | [ string ]
condition: string
strategy:
parallel: # parallel strategy
matrix: # matrix strategy
maxParallel: number # maximum number simultaneous matrix legs to run
# note: `parallel` and `matrix` are mutually exclusive
# you may specify one or the other; including both is an error
# `maxParallel` is only valid with `matrix`
continueOnError: boolean # 'true' if future jobs should run even if this job fails; defaults to 'false'
pool: pool # agent pool
workspace:
clean: outputs | resources | all # what to clean up before the job runs
container: containerReference # container to run this job inside
timeoutInMinutes: number # how long to run the job before automatically cancelling
cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
variables: { string: string } | [ variable | variableReference ]
steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
services: { string: string | container } # container resources to run as a service container
La sintaxis completa para especificar un trabajo es:
- job: string # name of the job, A-Z, a-z, 0-9, and underscore
displayName: string # friendly name to display in the UI
dependsOn: string | [ string ]
condition: string
strategy:
parallel: # parallel strategy
matrix: # matrix strategy
maxParallel: number # maximum number simultaneous matrix legs to run
# note: `parallel` and `matrix` are mutually exclusive
# you may specify one or the other; including both is an error
# `maxParallel` is only valid with `matrix`
continueOnError: boolean # 'true' if future jobs should run even if this job fails; defaults to 'false'
pool: pool # agent pool
workspace:
clean: outputs | resources | all # what to clean up before the job runs
container: containerReference # container to run this job inside
timeoutInMinutes: number # how long to run the job before automatically cancelling
cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
variables: { string: string } | [ variable | variableReference ]
steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
services: { string: string | container } # container resources to run as a service container
uses: # Any resources (repos or pools) required by this job that are not already referenced
repositories: [ string ] # Repository references to Azure Git repositories
pools: [ string ] # Pool names, typically when using a matrix strategy for the job
Si la intención principal del trabajo es implementar la aplicación (en lugar de compilar o probar la aplicación), puede usar un tipo especial de trabajo denominado trabajo de implementación.
La sintaxis de un trabajo de implementación es:
- deployment: string # instead of job keyword, use deployment keyword
pool:
name: string
demands: string | [ string ]
environment: string
strategy:
runOnce:
deploy:
steps:
- script: echo Hi!
Aunque puede agregar pasos para las tareas de implementación en , job
se recomienda usar en su lugar un trabajo de implementación. Un trabajo de implementación tiene algunas ventajas. Por ejemplo, puede implementar en un entorno, lo que incluye ventajas como poder ver el historial de lo que ha implementado.
YAML no se admite en TFS.
Tipos de trabajos
Los trabajos pueden ser de diferentes tipos, dependiendo de dónde se ejecuten.
- Los trabajos del grupo de agentes se ejecutan en un agente de un grupo de agentes.
- Los trabajos de servidor se ejecutan en el Azure DevOps Server.
- Los trabajos de contenedor se ejecutan en un contenedor de un agente de un grupo de agentes. Para obtener más información sobre cómo elegir contenedores, consulte Definición de trabajos de contenedor.
- Los trabajos del grupo de agentes se ejecutan en un agente del grupo de agentes. Estos trabajos están disponibles en canalizaciones de compilación y versión.
- Los trabajos de servidor se ejecutan en TFS. Estos trabajos están disponibles en canalizaciones de compilación y versión.
- Los trabajos del grupo de implementación se ejecutan en máquinas de un grupo de implementación. Estos trabajos solo están disponibles en las canalizaciones de versión.
Trabajos de grupo de agentes
Estos son el tipo de trabajo más común y se ejecutan en un agente de un grupo de agentes.
- Cuando se usan agentes hospedados Microsoft, cada trabajo de una canalización obtiene un agente nuevo.
- Use demandas con agentes autohospedados para especificar qué funcionalidades debe tener un agente para ejecutar el trabajo. Puede obtener el mismo agente para trabajos consecutivos, en función de si hay más de un agente en el grupo de agentes que coincida con las demandas de la canalización. Si solo hay un agente en el grupo que coincida con las demandas de la canalización, la canalización esperará hasta que este agente esté disponible.
Nota:
Las demandas y funcionalidades están diseñadas para su uso con agentes autohospedados para que los trabajos puedan coincidir con un agente que cumpla los requisitos del trabajo. Al usar agentes hospedados Microsoft, seleccione una imagen para el agente que coincida con los requisitos del trabajo, por lo que, aunque es posible agregar funcionalidades a un agente hospedado Microsoft, no es necesario usar funcionalidades con agentes hospedados Microsoft.
pool:
name: myPrivateAgents # your job runs on an agent in this pool
demands: agent.os -equals Windows_NT # the agent must have this capability to run the job
steps:
- script: echo hello world
O varias demandas:
pool:
name: myPrivateAgents
demands:
- agent.os -equals Darwin
- anotherCapability -equals somethingElse
steps:
- script: echo hello world
YAML no se admite en TFS.
Obtenga más información sobre las funcionalidades del agente.
Trabajos de servidor
Las tareas de un trabajo de servidor se organizan mediante y se ejecutan en el servidor (Azure Pipelines o TFS). Un trabajo de servidor no requiere un agente ni ningún equipo de destino. Actualmente solo se admiten algunas tareas en un trabajo de servidor.
Tareas admitidas de trabajos sin agente
Actualmente, solo se admiten las siguientes tareas de fábrica para trabajos sin agente:
- Retrasar tarea
- Tarea Invocar función de Azure
- Invocar tarea de API REST
- Tarea validación manual
- Tarea Publicar en Azure Service Bus
- Consulta de la tarea Alertas de Azure Monitor
- Tarea Consultar elementos de trabajo
Dado que las tareas son extensibles, puede agregar más tareas sin agente mediante extensiones. El tiempo de espera predeterminado para los trabajos sin agente es de 60 minutos.
La sintaxis completa para especificar un trabajo de servidor es:
jobs:
- job: string
timeoutInMinutes: number
cancelTimeoutInMinutes: number
strategy:
maxParallel: number
matrix: { string: { string: string } }
pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job
También puede usar la sintaxis simplificada:
jobs:
- job: string
pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job
YAML no se admite en TFS.
Dependencias
Al definir varios trabajos en una sola fase, puede especificar las dependencias entre ellos. Las canalizaciones deben contener al menos un trabajo sin dependencias.
Nota:
Cada agente solo puede ejecutar un trabajo a la vez. Para ejecutar varios trabajos en paralelo, debe configurar varios agentes. También necesita trabajos paralelos suficientes.
La sintaxis para definir varios trabajos y sus dependencias es:
jobs:
- job: string
dependsOn: string
condition: string
Trabajos de ejemplo que se compilan secuencialmente:
jobs:
- job: Debug
steps:
- script: echo hello from the Debug build
- job: Release
dependsOn: Debug
steps:
- script: echo hello from the Release build
Trabajos de ejemplo que se compilan en paralelo (sin dependencias):
jobs:
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- script: echo hello from Windows
- job: macOS
pool:
vmImage: 'macOS-latest'
steps:
- script: echo hello from macOS
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo hello from Linux
Ejemplo de distribución ramificada:
jobs:
- job: InitialJob
steps:
- script: echo hello from initial job
- job: SubsequentA
dependsOn: InitialJob
steps:
- script: echo hello from subsequent A
- job: SubsequentB
dependsOn: InitialJob
steps:
- script: echo hello from subsequent B
Ejemplo de entrada ramificada:
jobs:
- job: InitialA
steps:
- script: echo hello from initial A
- job: InitialB
steps:
- script: echo hello from initial B
- job: Subsequent
dependsOn:
- InitialA
- InitialB
steps:
- script: echo hello from subsequent
YAML no se admite en TFS.
Condiciones
Puede especificar las condiciones con las que se ejecutará cada trabajo. De forma predeterminada, un trabajo se ejecuta si no depende de ningún otro trabajo, o si todos los trabajos de los que depende se han completado y realizado correctamente. Puede personalizar este comportamiento al forzar que un trabajo se ejecute incluso si se produce un error en un trabajo anterior o especificando una condición personalizada.
Ejemplo para ejecutar un trabajo en función del estado de ejecución de un trabajo anterior:
jobs:
- job: A
steps:
- script: exit 1
- job: B
dependsOn: A
condition: failed()
steps:
- script: echo this will run when A fails
- job: C
dependsOn:
- A
- B
condition: succeeded('B')
steps:
- script: echo this will run when B runs and succeeds
Ejemplo de uso de una condición personalizada:
jobs:
- job: A
steps:
- script: echo hello
- job: B
dependsOn: A
condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master'))
steps:
- script: echo this only runs for master
Puede especificar que un trabajo se ejecute en función del valor de una variable de salida establecida en un trabajo anterior. En este caso, solo puede usar variables establecidas en trabajos dependientes directamente:
jobs:
- job: A
steps:
- script: "echo ##vso[task.setvariable variable=skipsubsequent;isOutput=true]false"
name: printvar
- job: B
condition: and(succeeded(), ne(dependencies.A.outputs['printvar.skipsubsequent'], 'true'))
dependsOn: A
steps:
- script: echo hello from B
YAML no se admite en TFS.
Tiempos de espera
Para evitar el uso de recursos cuando el trabajo no responde o espera demasiado tiempo, es recomendable establecer un límite durante cuánto tiempo se permite la ejecución del trabajo. Use la configuración de tiempo de espera del trabajo para especificar el límite en minutos para ejecutar el trabajo. Establecer el valor en cero significa que el trabajo se puede ejecutar:
- Para siempre en agentes autohospedados
- Durante 360 minutos (6 horas) en agentes hospedados por Microsoft con un proyecto público y un repositorio público
- Durante 60 minutos en Microsoft agentes hospedados con un proyecto privado o un repositorio privado (a menos que se pague capacidad adicional)
El período de tiempo de espera comienza cuando el trabajo comienza a ejecutarse. No incluye el tiempo en que el trabajo está en cola o está esperando un agente.
timeoutInMinutes
permite establecer un límite para el tiempo de ejecución del trabajo. Cuando no se especifica, el valor predeterminado es de 60 minutos. Cuando 0
se especifica , se usa el límite máximo (descrito anteriormente).
cancelTimeoutInMinutes
permite establecer un límite para el tiempo de cancelación del trabajo cuando la tarea de implementación se establece para seguir ejecutándose si se ha producido un error en una tarea anterior. Cuando no se especifica, el valor predeterminado es de 5 minutos. El valor debe estar comprendido entre 1 y 35790 minutos.
jobs:
- job: Test
timeoutInMinutes: 10 # how long to run the job before automatically cancelling
cancelTimeoutInMinutes: 2 # how much time to give 'run always even if cancelled tasks' before stopping them
YAML no se admite en TFS.
Los trabajos destinados a agentes hospedados Microsoft tienen restricciones adicionales sobre cuánto tiempo pueden ejecutarse.
También puede establecer el tiempo de espera de cada tarea individualmente; consulte las opciones de control de tareas.
Configuración de varios trabajos
Desde un único trabajo que cree, puede ejecutar varios trabajos en varios agentes en paralelo. Estos son algunos ejemplos:
Compilaciones de varias configuraciones: Puede crear varias configuraciones en paralelo. Por ejemplo, podría compilar una aplicación de Visual C++ para
debug
las configuraciones yrelease
en ambasx86
plataformas.x64
Para más información, consulte Compilación de Visual Studio: varias configuraciones para varias plataformas.Implementaciones de varias configuraciones: Puede ejecutar varias implementaciones en paralelo, por ejemplo, en diferentes regiones geográficas.
Pruebas de varias configuraciones: Puede ejecutar varias configuraciones de prueba en paralelo.
La configuración múltiple siempre generará al menos un trabajo, incluso si una variable de configuración múltiple está vacía.
La matrix
estrategia permite que un trabajo se envíe varias veces, con diferentes conjuntos de variables. La maxParallel
etiqueta restringe la cantidad de paralelismo. El siguiente trabajo se enviará tres veces con los valores de Location y Browser establecidos como se especifica. Sin embargo, solo se ejecutarán dos trabajos al mismo tiempo.
jobs:
- job: Test
strategy:
maxParallel: 2
matrix:
US_IE:
Location: US
Browser: IE
US_Chrome:
Location: US
Browser: Chrome
Europe_Chrome:
Location: Europe
Browser: Chrome
Nota:
Los nombres de configuración de matriz (como US_IE
arriba) solo deben contener letras alfabéticas latinas básicas (A-Z, a-z), números y caracteres de subrayado (_
).
Deben empezar con una letra.
Además, deben tener 100 caracteres o menos.
También es posible usar variables de salida para generar una matriz. Esto puede ser útil si necesita generar la matriz mediante un script.
matrix
aceptará una expresión en tiempo de ejecución que contiene un objeto JSON con cadenas.
Ese objeto JSON, cuando se expande, debe coincidir con la sintaxis de matriz.
En el ejemplo siguiente, hemos codificado de forma rígida la cadena JSON, pero podría generarse mediante un lenguaje de scripting o un programa de línea de comandos.
jobs:
- job: generator
steps:
- bash: echo "##vso[task.setVariable variable=legs;isOutput=true]{'a':{'myvar':'A'}, 'b':{'myvar':'B'}}"
name: mtrx
# This expands to the matrix
# a:
# myvar: A
# b:
# myvar: B
- job: runner
dependsOn: generator
strategy:
matrix: $[ dependencies.generator.outputs['mtrx.legs'] ]
steps:
- script: echo $(myvar) # echos A or B depending on which leg is running
YAML no se admite en TFS.
Segmentación
Un trabajo de agente se puede usar para ejecutar un conjunto de pruebas en paralelo. Por ejemplo, puede ejecutar un conjunto grande de 1000 pruebas en un solo agente. O bien, puede usar dos agentes y ejecutar 500 pruebas en cada una en paralelo.
Para aprovechar la segmentación, las tareas del trabajo deben ser lo suficientemente inteligentes como para comprender el segmento al que pertenecen.
La tarea Prueba de Visual Studio es una tarea de este tipo que admite la segmentación de pruebas. Si ha instalado varios agentes, puede especificar cómo se ejecutará la tarea Prueba de Visual Studio en paralelo en estos agentes.
La parallel
estrategia permite duplicar un trabajo muchas veces.
Las variables System.JobPositionInPhase
y System.TotalJobsInPhase
se agregan a cada trabajo. Las variables se pueden usar en los scripts para dividir el trabajo entre los trabajos.
Consulte Parallel and multiple execution using agent jobs (Ejecución en paralelo y varias ejecuciones mediante trabajos del agente).
El siguiente trabajo se enviará cinco veces con los valores de System.JobPositionInPhase
y System.TotalJobsInPhase
se establecerá correctamente.
jobs:
- job: Test
strategy:
parallel: 5
YAML no se admite en TFS.
Variables de trabajo
Si usa YAML, se pueden especificar variables en el trabajo. Las variables se pueden pasar a las entradas de tarea mediante la sintaxis de macro $(variableName) o se puede acceder a ellas dentro de un script mediante la variable stage.
Este es un ejemplo de definición de variables en un trabajo y su uso en tareas.
variables:
mySimpleVar: simple var value
"my.dotted.var": dotted var value
"my var with spaces": var with spaces value
steps:
- script: echo Input macro = $(mySimpleVar). Env var = %MYSIMPLEVAR%
condition: eq(variables['agent.os'], 'Windows_NT')
- script: echo Input macro = $(mySimpleVar). Env var = $MYSIMPLEVAR
condition: in(variables['agent.os'], 'Darwin', 'Linux')
- bash: echo Input macro = $(my.dotted.var). Env var = $MY_DOTTED_VAR
- powershell: Write-Host "Input macro = $(my var with spaces). Env var = $env:MY_VAR_WITH_SPACES"
YAML no se admite en TFS.
Para obtener información sobre el uso de una condición, vea Especificar condiciones.
Área de trabajo
Cuando se ejecuta un trabajo de grupo de agentes, se crea un área de trabajo en el agente. El área de trabajo es un directorio en el que descarga el origen, ejecuta los pasos y genera salidas. Se puede hacer referencia al directorio del área de trabajo en el trabajo mediante Pipeline.Workspace
la variable . En este caso, se crean varios subdirectorios:
Cuando se ejecuta un trabajo de grupo de agentes, se crea un área de trabajo en el agente. El área de trabajo es un directorio en el que descarga el origen, ejecuta los pasos y genera salidas. Se puede hacer referencia al directorio del área de trabajo en el trabajo mediante Agent.BuildDirectory
la variable . En este caso, se crean varios subdirectorios:
Build.SourcesDirectory
es donde las tareas descargan el código fuente de la aplicación.Build.ArtifactStagingDirectory
es donde las tareas descargan artefactos necesarios para la canalización o cargan artefactos antes de que se publiquen.Build.BinariesDirectory
es donde las tareas escriben sus salidas.Common.TestResultsDirectory
es donde las tareas cargan sus resultados de prueba.
y $(Build.ArtifactStagingDirectory)
$(Common.TestResultsDirectory)
siempre se eliminan y se vuelven a crear antes de cada compilación.
Cuando se ejecuta una canalización en un agente autohospedado, de forma predeterminada, ninguno de los subdirectorios distintos $(Build.ArtifactStagingDirectory)
de y $(Common.TestResultsDirectory)
se limpia entre dos ejecuciones consecutivas. Como resultado, puede realizar compilaciones e implementaciones incrementales, siempre que las tareas se implementen para usarlas. Puede invalidar este comportamiento mediante la workspace
configuración del trabajo.
Importante
Las opciones de limpieza del área de trabajo solo se aplican a los agentes autohospedados. Cuando se usan agentes hospedados Microsoft, el trabajo siempre se ejecuta en un nuevo agente.
- job: myJob
workspace:
clean: outputs | resources | all # what to clean up before the job runs
Al especificar una de las clean
opciones, se interpretan de la siguiente manera:
outputs
: elimineBuild.BinariesDirectory
antes de ejecutar un nuevo trabajo.resources
: elimineBuild.SourcesDirectory
antes de ejecutar un nuevo trabajo.all
: elimine todoPipeline.Workspace
el directorio antes de ejecutar un nuevo trabajo.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Nota:
En función de las capacidades del agente y las demandas de canalización, cada trabajo se puede enrutar a otro agente del grupo autohospedado. Como resultado, puede obtener un nuevo agente para las ejecuciones de canalización posteriores (o fases o trabajos en la misma canalización), por lo que no es una garantía de que las ejecuciones, trabajos o fases posteriores puedan acceder a salidas de ejecuciones, trabajos o fases anteriores. Puede configurar las funcionalidades del agente y las demandas de canalización para especificar qué agentes se usan para ejecutar un trabajo de canalización, pero a menos que solo haya un único agente en el grupo que cumpla las demandas, no hay ninguna garantía de que los trabajos posteriores usen el mismo agente que los trabajos anteriores. Para obtener más información, vea Especificar demandas.
Además de limpiar el área de trabajo, también puede configurar la limpieza mediante la configuración Limpieza en la interfaz de usuario de configuración de canalización. Cuando la opción Limpiar es true, que también es su valor predeterminado, equivale a especificar clean: true
para cada paso de desprotección de la canalización. Al especificar clean: true
, se ejecutará git clean -ffdx
seguido de git reset --hard HEAD
antes de la captura de Git. Para configurar la opción Limpiar :
Edite la canalización, elija ... y seleccione Desencadenadores.
Seleccione YAML, Obtener orígenes y configure la opción Limpiar deseada. El valor predeterminado es true.
YAML no se admite en TFS.
Descarga de artefactos
Este archivo YAML de ejemplo publica el artefacto WebSite
y, a continuación, descarga el artefacto en $(Pipeline.Workspace)
. El trabajo Implementar solo se ejecuta si el trabajo de compilación se realiza correctamente.
# test and upload my code as an artifact named WebSite
jobs:
- job: Build
pool:
vmImage: 'ubuntu-latest'
steps:
- script: npm test
- task: PublishBuildArtifacts@1
inputs:
pathtoPublish: '$(System.DefaultWorkingDirectory)'
artifactName: WebSite
# download the artifact and deploy it only if the build job succeeded
- job: Deploy
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: none #skip checking out the default repository resource
- task: DownloadBuildArtifacts@0
displayName: 'Download Build Artifacts'
inputs:
artifactName: WebSite
downloadPath: $(System.DefaultWorkingDirectory)
dependsOn: Build
condition: succeeded()
YAML no se admite en TFS.
Para obtener información sobre el uso de dependsOn y condition, vea Especificar condiciones.
Acceso al token de OAuth
Puede permitir que los scripts que se ejecutan en un trabajo accedan al token de seguridad actual de Azure Pipelines o TFS OAuth. El token se puede usar para autenticarse en la API REST de Azure Pipelines.
El token de OAuth siempre está disponible para las canalizaciones de YAML.
Debe asignarse explícitamente a la tarea o paso mediante env
.
Este es un ejemplo:
steps:
- powershell: |
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=4.1-preview"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers @{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
env:
SYSTEM_ACCESSTOKEN: $(system.accesstoken)
YAML no se admite en TFS.