Specificare i lavori nella pipeline
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
È possibile organizzare una pipeline in compiti. Ogni pipeline ha almeno un job. Un processo è una serie di passaggi eseguiti in sequenza come unità. In altre parole, un job è l'unità di lavoro più piccola che può essere pianificata per essere eseguita.
Per informazioni sui concetti chiave e sui componenti che costituiscono una pipeline, vedere Concetti chiave per i nuovi utenti di Azure Pipelines.
Azure Pipelines non offre supporto per la priorità dei lavori nelle pipeline YAML. Per controllare quando vengono eseguiti i processi, è possibile specificare condizioni e dipendenze.
Definire un singolo lavoro
Nel caso più semplice, una pipeline ha un'unica attività. In tal caso, non è necessario usare in modo esplicito la job
parola chiave a meno che non si usi un modello. È possibile specificare direttamente i passaggi nel file YAML.
Questo file YAML include un processo eseguito in un agente ospitato da Microsoft e restituisce Hello world
.
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"
Potresti voler specificare più proprietà in quel lavoro. In tal caso, è possibile usare la job
parola chiave .
jobs:
- job: myJob
timeoutInMinutes: 10
pool:
vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"
La pipeline potrebbe avere più compiti. In tal caso, usare la jobs
parola chiave .
jobs:
- job: A
steps:
- bash: echo "A"
- job: B
steps:
- bash: echo "B"
La pipeline può avere più fasi, ognuna con più attività. In tal caso, usare la stages
parola chiave .
stages:
- stage: A
jobs:
- job: A1
- job: A2
- stage: B
jobs:
- job: B1
- job: B2
La sintassi completa per specificare un processo è:
- 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 sintassi completa per specificare un processo è:
- 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
Se lo scopo principale del processo è distribuire l'app (anziché compilare o testare l'app), è possibile usare un tipo speciale di processo denominato processo di distribuzione.
La sintassi per un processo di distribuzione è:
- deployment: string # instead of job keyword, use deployment keyword
pool:
name: string
demands: string | [ string ]
environment: string
strategy:
runOnce:
deploy:
steps:
- script: echo Hi!
Sebbene sia possibile aggiungere passaggi per le attività di distribuzione in un job
, è consigliabile usare invece un processo di distribuzione. Un compito di distribuzione offre alcuni vantaggi. Ad esempio, è possibile eseguire la distribuzione in un ambiente, che include vantaggi come la possibilità di visualizzare la cronologia di ciò che è stato distribuito.
Tipi di lavori
I lavori possono essere di tipi diversi, a seconda di dove vengono eseguiti.
- I job del pool di agenti vengono eseguiti su un agente del pool.
- I processi del server vengono eseguiti in Azure DevOps Server.
- I processi contenitore vengono eseguiti in un contenitore su un agente in un pool di agenti. Per altre informazioni sulla scelta dei contenitori, vedere Definire i processi del contenitore.
Attività del pool di agenti
I compiti del pool di agenti sono i compiti più comuni. Questi processi vengono eseguiti su un agente all'interno di un pool di agenti. È possibile specificare il pool in cui eseguire il processo ed è anche possibile specificare le richieste per specificare le funzionalità necessarie per l'esecuzione del processo da parte di un agente. Gli agenti possono essere ospitati da Microsoft o autogestiti. Per altre informazioni, vedere gli agenti di Azure Pipelines .
- Quando si usano agenti ospitati da Microsoft, a ogni job in una pipeline viene assegnato un nuovo agente.
- Quando utilizzi agenti self-hosted, è possibile usare richieste per specificare quali funzionalità un agente deve avere per eseguire l'attività lavorativa. Puoi ottenere lo stesso agente per incarichi consecutivi, a condizione che nel tuo pool di agenti ci siano più agenti che soddisfano le esigenze della tua pipeline. Se nel pool è presente un solo agente che corrisponde alle richieste della pipeline, la pipeline attende fino a quando l'agente non è disponibile.
Nota
Le richieste e le capacità sono progettate per l'uso con agenti self-hosted in modo che i job possano essere abbinati a un agente che soddisfi i requisiti del job. Quando si usano agenti ospitati da Microsoft, si seleziona un'immagine per l'agente che soddisfa i requisiti del compito. Anche se è possibile aggiungere funzionalità a un agente ospitato da Microsoft, non è necessario usare le funzionalità con gli agenti ospitati da 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 più richieste:
pool:
name: myPrivateAgents
demands:
- agent.os -equals Darwin
- anotherCapability -equals somethingElse
steps:
- script: echo hello world
Altre informazioni sulle funzionalità dell'agente.
Lavori del server
Il server orchestra ed esegue attività all'interno di un job server. Un'attività del server non richiede un agente o macchine di destinazione. Solo alcune attività sono supportate in un processo del server. Il tempo massimo per un processo server è di 30 giorni.
Attività supportate da lavori senza agente
Attualmente, per i processi senza agente sono supportate solo le seguenti attività:
- Ritardare attività
- Richiamare l'attività Funzione di Azure
- Attività di richiamo dell'API REST
- Attività Di convalida manuale
- Attività Pubblica su Azure Service Bus
- Eseguire query sugli avvisi di Monitoraggio di Azure
- Attività di Interrogazione dei Work Items
Poiché le attività sono estendibili, è possibile aggiungere altre attività senza agente usando le estensioni. Il timeout predefinito per i processi senza agente è 60 minuti.
La sintassi completa per specificare un processo del server è:
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
È anche possibile usare la sintassi semplificata:
jobs:
- job: string
pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job
Dipendenze
Quando si definiscono più processi in una singola fase, è possibile specificare le dipendenze tra di esse. La pipeline deve contenere almeno un'attività senza dipendenze. Per impostazione predefinita, i processi della pipeline YAML di Azure DevOps vengono eseguiti in parallelo, a meno che il dependsOn
valore non sia impostato.
Nota
Ogni agente può eseguire un solo processo alla volta. Per eseguire più processi in parallelo, è necessario configurare più agenti. Sono necessari anche sufficienti processi paralleli.
La sintassi per la definizione di più processi e le relative dipendenze è:
jobs:
- job: string
dependsOn: string
condition: string
Esempi di lavori che si costruiscono in sequenza:
jobs:
- job: Debug
steps:
- script: echo hello from the Debug build
- job: Release
dependsOn: Debug
steps:
- script: echo hello from the Release build
Esempi di lavori eseguiti simultaneamente, senza dipendenze:
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
Esempio di fan-out:
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
Esempio di fan-in:
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
Condizioni
È possibile specificare le condizioni in base alle quali eseguire ogni processo. Per impostazione predefinita, un processo viene eseguito se non dipende da altri processi o se tutti i processi da cui dipende sono stati completati con successo. È possibile personalizzare questo comportamento forzando l'esecuzione di un processo anche se un processo precedente ha esito negativo o specificando una condizione personalizzata.
Esempio per eseguire un processo in base allo stato di esecuzione di un processo precedente:
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
Esempio di utilizzo di una condizione personalizzata:
jobs:
- job: A
steps:
- script: echo hello
- job: B
dependsOn: A
condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/main'))
steps:
- script: echo this only runs for master
È possibile specificare che un processo viene eseguito in base al valore di una variabile di output impostata in un processo precedente. In questo caso, è possibile usare solo le variabili impostate in processi dipendenti direttamente:
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
Timeout
Per evitare di occupare risorse quando il processo non risponde o è in attesa per troppo tempo, è possibile impostare un limite sulla durata del processo. Usare l'impostazione di timeout del processo per specificare il limite in minuti per la sua esecuzione. L'impostazione del valore su zero indica che il processo può essere eseguito:
- Sempre sugli agenti autogestiti
- Per 360 minuti (6 ore) su agenti ospitati da Microsoft con un progetto pubblico e un repository pubblico
- Per 60 minuti sugli agenti ospitati da Microsoft con un progetto privato o un repository privato (a meno che non venga pagata capacità aggiuntiva)
Il periodo di timeout inizia all'avvio dell'esecuzione del processo. Non include il tempo in cui il processo è in coda o è in attesa di un agente.
timeoutInMinutes
consente di impostare un limite per il tempo di esecuzione del processo. Se non specificato, il valore predefinito è 60 minuti. Quando si specifica 0
, viene usato il limite massimo.
cancelTimeoutInMinutes
consente di impostare un limite per il tempo di annullamento del processo quando l'attività di distribuzione è impostata per continuare a funzionare se un'attività precedente non è riuscita. Se non specificato, il valore predefinito è 5 minuti. Il valore deve essere compreso tra 1 e 35790 minuti.
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
I timeout hanno il livello di precedenza seguente.
- Negli agenti ospitati da Microsoft, i processi sono limitati per quanto tempo possono essere eseguiti in base al tipo di progetto e se vengono eseguiti usando un processo parallelo a pagamento. Quando è trascorso l'intervallo di timeout del processo ospitato da Microsoft, il processo viene terminato. Negli agenti ospitati da Microsoft i processi non possono essere eseguiti più a lungo di questo intervallo, indipendentemente dai timeout a livello di processo specificati nel processo.
- Il timeout configurato a livello di processo specifica la durata massima per l'esecuzione del processo. Quando viene trascorso l'intervallo di timeout a livello di lavoro, il lavoro viene terminato. Quando il processo viene eseguito in un agente ospitato da Microsoft, l'impostazione del timeout a livello di processo maggiore del timeout predefinito a livello di processo ospitato da Microsoft non ha alcun effetto.
- È anche possibile impostare il timeout per ogni attività singolarmente. Vedere le opzioni di controllo delle attività. Se l'intervallo di timeout a livello di processo è trascorso prima del completamento dell'attività, il processo in esecuzione viene terminato, anche se l'attività è configurata con un intervallo di timeout più lungo.
Configurazione multi-lavoro
Da un singolo processo creato, è possibile eseguire più processi su più agenti in parallelo. Alcuni esempi includono:
Compilazioni con più configurazioni: è possibile compilare più configurazioni in parallelo. Ad esempio, è possibile creare un'app Visual C++ per le configurazioni
debug
erelease
su entrambe le piattaformex86
ex64
. Per altre informazioni, vedere Compilazione di Visual Studio - più configurazioni per più piattaforme.Distribuzioni con più configurazioni: è possibile eseguire più distribuzioni in parallelo, ad esempio in aree geografiche diverse.
Test con più configurazioni: è possibile eseguire test di più configurazioni in parallelo.
La multiconfigurazione genera sempre almeno un job, anche se una variabile di multiconfigurazione è vuota.
La matrix
strategia consente di inviare più volte un'attività, con set di variabili diversi. Il maxParallel
tag limita la quantità di parallelismo. Il processo seguente viene inviato tre volte con i valori di Location e Browser impostati come specificato. Tuttavia, solo due lavori vengono eseguiti contemporaneamente.
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
I nomi di configurazione della matrice (ad esempio US_IE
nell'esempio) devono contenere solo lettere alfabetici latine di base (A - Z, a - z), numeri e caratteri di sottolineatura (_
).
Devono iniziare con una lettera.
Inoltre, devono essere di massimo 100 caratteri.
È anche possibile usare le variabili di output per generare una matrice. Questo metodo può essere utile se è necessario generare la matrice usando uno script.
matrix
accetta un'espressione di runtime contenente un oggetto JSON stringato.
L'oggetto JSON, se espanso, deve corrispondere alla sintassi di matrice.
Nell'esempio seguente, la stringa JSON è stata codificata manualmente, ma puoi generarla con un linguaggio di scripting o un programma da riga di comando.
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
Sezionamento
È possibile usare un compito dell'agente per eseguire un gruppo di test in parallelo. Ad esempio, è possibile eseguire un ampio insieme di 1.000 test su un singolo agente. In alternativa, è possibile usare due agenti ed eseguire 500 test su ognuno in parallelo.
Per applicare il sezionamento, le attività nel processo devono essere sufficientemente intelligenti da comprendere la sezione a cui appartengono.
L'attività Test di Visual Studio è un'attività di questo tipo che supporta il sezionamento dei test. Se sono stati installati più agenti, è possibile specificare il modo in cui l'attività test di Visual Studio viene eseguita in parallelo su questi agenti.
La parallel
strategia consente di duplicare un processo più volte.
Le variabili System.JobPositionInPhase
e System.TotalJobsInPhase
vengono aggiunte a ogni attività. Le variabili possono quindi essere usate all'interno degli script per dividere il lavoro tra i lavori.
Consulta Esecuzione parallela e multipla tramite lavori di agenti.
Il processo seguente viene inviato cinque volte con i valori di System.JobPositionInPhase
e System.TotalJobsInPhase
impostati in modo appropriato.
jobs:
- job: Test
strategy:
parallel: 5
Variabili di lavoro
Se si usa YAML, è possibile specificare variabili nel processo. Le variabili possono essere passate agli input dell'attività usando la sintassi della macro $(variableName) o accessibili all'interno di uno script usando la variabile di fase.
Di seguito è riportato un esempio di definizione delle variabili in un processo e dell'uso all'interno delle attività.
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"
Per informazioni sull'uso di una condizione, vedere Specificare le condizioni.
Area di lavoro
Quando si esegue un processo del pool di agenti, viene creata un'area di lavoro nell'agente. L'area di lavoro è una directory in cui vengono scaricate le sorgenti, vengono eseguite le fasi e viene prodotto l'output. È possibile fare riferimento alla directory dell'area di lavoro nel processo usando Pipeline.Workspace
variabile. In questo caso vengono create varie sottodirectory:
-
Build.SourcesDirectory
è dove le attività scaricano il codice sorgente dell'applicazione. -
Build.ArtifactStagingDirectory
è la posizione in cui le attività scaricano gli artefatti necessari per la pipeline o caricano gli artefatti prima della pubblicazione. -
Build.BinariesDirectory
è dove le attività scrivono i relativi output. - Il punto in cui le attività caricano i risultati dei test è
Common.TestResultsDirectory
.
Le $(Build.ArtifactStagingDirectory)
e le $(Common.TestResultsDirectory)
vengono sempre eliminate e ricreate prima di ogni compilazione.
Quando si esegue una pipeline su un agente ospitato internamente, per impostazione predefinita, le sottodirectory diverse da $(Build.ArtifactStagingDirectory)
e $(Common.TestResultsDirectory)
non vengono pulite tra esecuzioni consecutive. Di conseguenza, è possibile eseguire compilazioni e distribuzioni incrementali, se le attività vengono implementate per usarle. È possibile modificare questo comportamento usando l'impostazione workspace
nella configurazione del lavoro.
Importante
Le opzioni di pulizia dell'area di lavoro sono applicabili solo per gli agenti self-hosted. I processi vengono sempre eseguiti su un nuovo agente ospitato da Microsoft.
- job: myJob
workspace:
clean: outputs | resources | all # what to clean up before the job runs
Quando si specifica una delle clean
opzioni, queste vengono interpretate come segue:
-
outputs
: eliminaBuild.BinariesDirectory
prima di eseguire un nuovo processo. -
resources
: eliminaBuild.SourcesDirectory
prima di eseguire un nuovo processo. -
all
: eliminare l'interaPipeline.Workspace
directory prima di eseguire un nuovo processo.
jobs:
- deployment: MyDeploy
pool:
vmImage: 'ubuntu-latest'
workspace:
clean: all
environment: staging
Nota
A seconda delle funzionalità dell'agente e dei carichi di pipeline, ogni processo può essere instradato a un agente diverso nel pool gestito internamente. Di conseguenza, è possibile ottenere un nuovo agente per le esecuzioni successive della pipeline (o fasi o processi nella stessa pipeline). Pertanto, il fatto che non ci sia pulizia tra e non garantisce che le esecuzioni, i processi o le fasi successive possano accedere agli output di esecuzioni, processi o fasi precedenti. È possibile configurare le funzionalità dell'agente e le richieste di pipeline per determinare quali agenti verranno utilizzati per eseguire un job della pipeline. Tuttavia, a meno che nel pool non sia presente un solo agente che soddisfi le richieste, non esiste alcuna garanzia che i processi successivi usino lo stesso agente dei processi precedenti. Per altre informazioni, vedere Specificare le richieste.
Oltre alla pulizia dell'area di lavoro, è anche possibile configurare la pulizia configurando l'impostazione Pulisci nell'interfaccia utente delle impostazioni della pipeline. Quando l'impostazione Pulisci è true, che è anche il suo valore predefinito, equivale a specificare clean: true
per ogni checkout nella pipeline. Quando si specifica clean: true
, esegui git clean -ffdx
seguito da git reset --hard HEAD
prima di git fetch. Per configurare l'impostazione Pulisci :
Modificare la pipeline, scegliere ...e selezionare Trigger.
Selezionare YAML, Recupera origini e configurare l'impostazione Pulisci desiderata. Il valore predefinito è true.
Download artefatto
Questo file YAML di esempio pubblica l'artefatto WebSite
e quindi scarica l'artefatto in $(Pipeline.Workspace)
. Il processo Distribuisci viene eseguito solo se il processo di compilazione ha esito positivo.
# 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: $(Pipeline.Workspace)
dependsOn: Build
condition: succeeded()
Per informazioni sull'uso di dependsOn e condizione, vedere Specificare le condizioni.
Accesso al token OAuth
È possibile consentire agli script in esecuzione in un processo di accedere al token di sicurezza OAuth di Azure Pipelines corrente. Il token può essere usato per eseguire l'autenticazione all'API REST di Azure Pipelines.
Il token OAuth è sempre disponibile per le pipeline YAML.
Deve essere mappato in modo esplicito nel compito o nel passaggio usando env
.
Ecco un esempio:
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)