Espressioni modello

Usare le espressioni modello per specificare in che modo i valori vengono risolti dinamicamente durante l'inizializzazione della pipeline. Eseguire il wrapping dell'espressione modello all'interno di questa sintassi: ${{ }}.

Le espressioni modello possono espandere i parametri del modello e anche le variabili. È possibile usare i parametri per influenzare la modalità di espansione di un modello. L'oggetto parameters funziona come l'oggetto in un'espressionevariables. Nelle espressioni modello è possibile usare solo le variabili predefinite.

Nota

Le espressioni vengono espanse solo per stages, jobs, stepse containers (all'interno resourcesdi ). Non è possibile, ad esempio, usare un'espressione all'interno trigger di o una risorsa come repositories. Inoltre, in Azure DevOps 2020 RTW non è possibile usare espressioni modello all'interno containersdi .

Ad esempio, si definisce un modello:

# File: steps/msbuild.yml

parameters:
- name: 'solution'
  default: '**/*.sln'
  type: string

steps:
- task: msbuild@1
  inputs:
    solution: ${{ parameters['solution'] }}  # index syntax
- task: vstest@2
  inputs:
    solution: ${{ parameters.solution }}  # property dereference syntax

Quindi si fa riferimento al modello e si passa il parametro facoltativo solution :

# File: azure-pipelines.yml

steps:
- template: steps/msbuild.yml
  parameters:
    solution: my.sln

Contesto

All'interno di un'espressione modello è possibile accedere al parameters contesto che contiene i valori dei parametri passati. Inoltre, è possibile accedere al variables contesto che contiene tutte le variabili specificate nel file YAML più molte delle variabili predefinite (annotate in ogni variabile in tale articolo). Importante, non include variabili di runtime, ad esempio quelle archiviate nella pipeline o specificate all'avvio di un'esecuzione. L'espansione del modello avviene all'inizio dell'esecuzione, quindi tali variabili non sono disponibili.

Funzioni di espressione modello

È possibile usare funzioni generali nei modelli. È anche possibile usare alcune funzioni di espressione modello.

format

  • Sostituzione semplice del token di stringa
  • Parametri min: 2. Numero massimo di parametri: N
  • Esempio: ${{ format('{0} Build', parameters.os) }}'Windows Build'

coalesce

  • Restituisce il primo argomento stringa non vuoto e non Null
  • Parametri min: 2. Numero massimo di parametri: N
  • Esempio:
parameters:
- name: 'restoreProjects'
  default: ''
  type: string
- name: 'buildProjects'
  default: ''
  type: string

steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}

Inserimento

È possibile usare espressioni modello per modificare la struttura di una pipeline YAML. Ad esempio, per inserire in una sequenza:

# File: jobs/build.yml

parameters:
- name: 'preBuild'
  type: stepList
  default: []
- name: 'preTest'
  type: stepList
  default: []
- name: 'preSign'
  type: stepList
  default: []

jobs:
- job: Build
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: cred-scan
  - ${{ parameters.preBuild }}
  - task: msbuild@1
  - ${{ parameters.preTest }}
  - task: vstest@2
  - ${{ parameters.preSign }}
  - script: sign
# File: .vsts.ci.yml

jobs:
- template: jobs/build.yml
  parameters:
    preBuild:
    - script: echo hello from pre-build
    preTest:
    - script: echo hello from pre-test

Quando una matrice viene inserita in una matrice, la matrice nidificata viene appiattita.

Per inserire in un mapping, utilizzare la proprietà ${{ insert }}speciale .

# Default values
parameters:
- name: 'additionalVariables'
  type: object
  default: {}

jobs:
- job: build
  variables:
    configuration: debug
    arch: x86
    ${{ insert }}: ${{ parameters.additionalVariables }}
  steps:
  - task: msbuild@1
  - task: vstest@2
jobs:
- template: jobs/build.yml
  parameters:
    additionalVariables:
      TEST_SUITE: L0,L1

Inserimento condizionale

Se si desidera inserire in modo condizionale in una sequenza o in un mapping in un modello, usare inserimenti ed espressioni di valutazione. È anche possibile usare if istruzioni esterne ai modelli , purché si usi la sintassi del modello.

Ad esempio, per inserire in una sequenza in un modello:

# File: steps/build.yml

parameters:
- name: 'toolset'
  default: msbuild
  type: string
  values:
  - msbuild
  - dotnet

steps:
# msbuild
- ${{ if eq(parameters.toolset, 'msbuild') }}:
  - task: msbuild@1
  - task: vstest@2

# dotnet
- ${{ if eq(parameters.toolset, 'dotnet') }}:
  - task: dotnet@1
    inputs:
      command: build
  - task: dotnet@1
    inputs:
      command: test
# File: azure-pipelines.yml

steps:
- template: steps/build.yml
  parameters:
    toolset: dotnet

Ad esempio, per inserire in un mapping in un modello:

# File: steps/build.yml

parameters:
- name: 'debug'
  type: boolean
  default: false

steps:
- script: tool
  env:
    ${{ if eq(parameters.debug, true) }}:
      TOOL_DEBUG: true
      TOOL_DEBUG_DIR: _dbg
steps:
- template: steps/build.yml
  parameters:
    debug: true

È anche possibile usare l'inserimento condizionale per le variabili. In questo esempio, start stampa sempre e this is a test stampa solo quando la foo variabile è uguale testa .

variables:
  - name: foo
    value: test

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: echo "start" # always runs
- ${{ if eq(variables.foo, 'test') }}:
  - script: echo "this is a test" # runs when foo=test

Inserimento iterativo

La each direttiva consente l'inserimento iterativo in base a una sequenza YAML (matrice) o a un mapping (coppie chiave-valore).

Ad esempio, è possibile eseguire il wrapping dei passaggi di ogni processo con altri passaggi preliminari e successivi:

# job.yml
parameters:
- name: 'jobs'
  type: jobList
  default: []

jobs:
- ${{ each job in parameters.jobs }}: # Each job
  - ${{ each pair in job }}:          # Insert all properties other than "steps"
      ${{ if ne(pair.key, 'steps') }}:
        ${{ pair.key }}: ${{ pair.value }}
    steps:                            # Wrap the steps
    - task: SetupMyBuildTools@1       # Pre steps
    - ${{ job.steps }}                # Users steps
    - task: PublishMyTelemetry@1      # Post steps
      condition: always()
# azure-pipelines.yml
jobs:
- template: job.yml
  parameters:
    jobs:
    - job: A
      steps:
      - script: echo This will get sandwiched between SetupMyBuildTools and PublishMyTelemetry.
    - job: B
      steps:
      - script: echo So will this!

È anche possibile modificare le proprietà di qualsiasi cosa si stia eseguendo l'iterazione. Ad esempio, per aggiungere altre dipendenze:

# job.yml
parameters:
- name: 'jobs'
  type: jobList
  default: []

jobs:
- job: SomeSpecialTool                # Run your special tool in its own job first
  steps:
  - task: RunSpecialTool@1
- ${{ each job in parameters.jobs }}: # Then do each job
  - ${{ each pair in job }}:          # Insert all properties other than "dependsOn"
      ${{ if ne(pair.key, 'dependsOn') }}:
        ${{ pair.key }}: ${{ pair.value }}
    dependsOn:                        # Inject dependency
    - SomeSpecialTool
    - ${{ if job.dependsOn }}:
      - ${{ job.dependsOn }}
# azure-pipelines.yml
jobs:
- template: job.yml
  parameters:
    jobs:
    - job: A
      steps:
      - script: echo This job depends on SomeSpecialTool, even though it's not explicitly shown here.
    - job: B
      dependsOn:
      - A
      steps:
      - script: echo This job depends on both Job A and on SomeSpecialTool.

Escape di un valore

Se è necessario eseguire l'escape di un valore che contiene ${{letteralmente , eseguire il wrapping del valore in una stringa di espressione. Ad esempio, ${{ 'my${{value' }} o ${{ 'my${{value with a '' single quote too' }}