Dokumentacja użycia szablonu

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Szablony umożliwiają definiowanie zawartości, logiki i parametrów wielokrotnego użytku w potokach YAML. Aby efektywnie pracować z szablonami, musisz mieć podstawową wiedzę na temat kluczowych pojęć usługi Azure Pipelines, takich jak etapy , kroki i zadania.

Szablony mogą pomóc w przyspieszeniu opracowywania. Można na przykład mieć serię tych samych zadań w szablonie, a następnie wielokrotnie dołączać szablon na różnych etapach potoku YAML.

Szablony mogą również pomóc w zabezpieczeniu potoku. Gdy szablon steruje tym, co jest dozwolone w potoku, szablon definiuje logikę, która musi być zgodna z innym plikiem. Na przykład możesz ograniczyć, jakie zadania mogą być uruchamiane. W tym scenariuszu można użyć szablonu, aby uniemożliwić komuś pomyślne uruchomienie zadania naruszającego zasady zabezpieczeń organizacji.

Istnieją dwa typy szablonów: obejmuje i rozszerza.

  • Zawiera szablony umożliwiają wstawianie zawartości wielokrotnego użytku za pomocą szablonu. Jeśli szablon jest używany do dołączania zawartości, działa jak dyrektywa include w wielu językach programowania. Zawartość z jednego pliku jest wstawiana do innego pliku.
  • Rozszerza kontrolkę szablonu , co jest dozwolone w potoku. Gdy szablon rozszerza kontrolki dozwolone w potoku, szablon definiuje logikę, którą musi przestrzegać inny plik.

Aby w pełni korzystać z szablonów, należy również użyć wyrażeń szablonu i parametrów szablonu.

Nałożone limity

Szablony i wyrażenia szablonów mogą spowodować gwałtowny wzrost rozmiaru i złożoności potoku. Aby zapobiec wzrostowi ucieczki, usługa Azure Pipelines nakłada następujące limity:

  • Nie można dołączyć więcej niż 100 oddzielnych plików YAML (bezpośrednio lub pośrednio)
  • Nie więcej niż 20 poziomów zagnieżdżania szablonów (szablony zawierające inne szablony)
  • Nie więcej niż 10 megabajtów pamięci używanej podczas analizowania kodu YAML (w praktyce jest to zwykle od 600 KB do 2 MB na dysku YAML, w zależności od określonych używanych funkcji)

Użyj szablonów, aby zdefiniować logikę raz, a następnie ponownie użyć jej kilka razy. Szablony łączą zawartość wielu plików YAML w jeden potok. Parametry można przekazać do szablonu z nadrzędnego potoku.

Rozszerzanie szablonu

Aby zwiększyć bezpieczeństwo, możesz wymusić rozszerzenie potoku z określonego szablonu. Plik start.yml definiuje parametr buildSteps, który jest następnie używany w potoku azure-pipelines.yml. W start.ymlpliku , jeśli buildStep element zostanie przekazany za pomocą kroku skryptu, zostanie odrzucony, a kompilacja potoku zakończy się niepowodzeniem. Podczas rozszerzania szablonu można zwiększyć bezpieczeństwo, dodając wymagane zatwierdzenie szablonu.

# File: start.yml
parameters:
- name: buildSteps # the name of the parameter is buildSteps
  type: stepList # data type is StepList
  default: [] # default value of buildSteps
stages:
- stage: secure_buildstage
  pool:
    vmImage: windows-latest
  jobs:
  - job: secure_buildjob
    steps:
    - script: echo This happens before code 
      displayName: 'Base: Pre-build'
    - script: echo Building
      displayName: 'Base: Build'

    - ${{ each step in parameters.buildSteps }}:
      - ${{ each pair in step }}:
          ${{ if ne(pair.value, 'CmdLine@2') }}:
            ${{ pair.key }}: ${{ pair.value }}       
          ${{ if eq(pair.value, 'CmdLine@2') }}: 
            # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
            '${{ pair.value }}': error         

    - script: echo This happens after code
      displayName: 'Base: Signing'
# File: azure-pipelines.yml
trigger:
- main

extends:
  template: start.yml
  parameters:
    buildSteps:  
      - bash: echo Test #Passes
        displayName: succeed
      - bash: echo "Test"
        displayName: succeed
      # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
      - task: CmdLine@2
        inputs:
          script: echo "Script Test"
      # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
      - script: echo "Script Test"

Rozszerzanie szablonu przy użyciu zasobów

Można również użyć extends polecenia , aby rozszerzyć szablon w potoku platformy Azure zawierającym zasoby.

# File: azure-pipelines.yml
trigger:
- none

extends:
  template: resource-template.yml
# File: resource-template.yml
resources:
  pipelines:
  - pipeline: my-pipeline 
    source: sourcePipeline

steps:
- script: echo "Testing resource template"

Wstawianie szablonu

Zawartość można skopiować z jednego kodu YAML i użyć go ponownie w innym YAML. Kopiowanie zawartości z jednego kodu YAML do innego powoduje, że trzeba ręcznie dołączyć tę samą logikę w wielu miejscach. Szablon include-npm-steps.yml pliku zawiera kroki, które są ponownie używane w programie azure-pipelines.yml.

Uwaga

Pliki szablonów muszą istnieć w systemie plików na początku uruchomienia potoku. Nie można odwoływać się do szablonów w artefaktie.

# File: templates/include-npm-steps.yml

steps:
- script: npm install
- script: yarn install
- script: npm run compile
# File: azure-pipelines.yml

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - template: templates/include-npm-steps.yml  # Template reference
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - template: templates/include-npm-steps.yml  # Template reference

Ponowne użycie kroków

Szablon można wstawić w celu ponownego użycia co najmniej jednego kroku w kilku zadaniach. Oprócz kroków z szablonu każde zadanie może zdefiniować więcej kroków.

# File: templates/npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - template: templates/npm-steps.yml  # Template reference

- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - template: templates/npm-steps.yml  # Template reference

- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: echo This script runs before the template's steps, only on Windows.
  - template: templates/npm-steps.yml  # Template reference
  - script: echo This step runs after the template's steps.

Ponowne użycie zadania

Podobnie jak w przypadku kroków, zadania można używać ponownie za pomocą szablonów.

# File: templates/jobs.yml
jobs:
- job: Ubuntu
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello Ubuntu"

- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - bash: echo "Hello Windows"
# File: azure-pipelines.yml

jobs:
- template: templates/jobs.yml  # Template reference

Podczas pracy z wieloma zadaniami pamiętaj, aby usunąć nazwę zadania w pliku szablonu, aby uniknąć konfliktu

# File: templates/jobs.yml
jobs:
- job: 
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello Ubuntu"

- job:
  pool:
    vmImage: 'windows-latest'
  steps:
  - bash: echo "Hello Windows"
# File: azure-pipelines.yml

jobs:
- template: templates/jobs.yml  # Template reference
- template: templates/jobs.yml  # Template reference
- template: templates/jobs.yml  # Template reference

Ponowne użycie etapu

Etapy można również używać ponownie za pomocą szablonów.

# File: templates/stages1.yml
stages:
- stage: Angular
  jobs:
  - job: angularinstall
    steps:
    - script: npm install angular
# File: templates/stages2.yml
stages:
- stage: Build
  jobs:
  - job: build
    steps:
    - script: npm run build
# File: azure-pipelines.yml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Install
  jobs: 
  - job: npminstall
    steps:
    - task: Npm@1
      inputs:
        command: 'install'
- template: templates/stages1.yml # Template reference
- template: templates/stages2.yml # Template reference

Szablony zadań, etapów i kroków z parametrami

# File: templates/npm-with-params.yml

parameters:
- name: name  # defaults for any parameters that aren't specified
  default: ''
- name: vmImage
  default: ''

jobs:
- job: ${{ parameters.name }}
  pool: 
    vmImage: ${{ parameters.vmImage }}
  steps:
  - script: npm install
  - script: npm test

W przypadku korzystania z szablonu w potoku określ wartości parametrów szablonu.

# File: azure-pipelines.yml

jobs:
- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: Linux
    vmImage: 'ubuntu-latest'

- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: macOS
    vmImage: 'macOS-latest'

- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: Windows
    vmImage: 'windows-latest'

Można również użyć parametrów z szablonami kroków lub etapów. Na przykład kroki z parametrami:

# File: templates/steps-with-params.yml

parameters:
- name: 'runExtendedTests'  # defaults for any parameters that aren't specified
  type: boolean
  default: false

steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, true) }}:
  - script: npm test --extended

W przypadku korzystania z szablonu w potoku określ wartości parametrów szablonu.

# File: azure-pipelines.yml

steps:
- script: npm install

- template: templates/steps-with-params.yml  # Template reference
  parameters:
    runExtendedTests: 'true'

Uwaga

Parametry skalarne bez określonego typu są traktowane jako ciągi. Na przykład funkcja zwróci truewartość , nawet jeśli myparam parametr jest wyrazem false, jeśli myparam nie zostanie jawnie wykonany boolean. eq(true, parameters['myparam']) Ciągi niepuste są rzutowane do true elementu w kontekście logicznym. To wyrażenie może zostać przepisane w celu jawnego porównania ciągów: eq(parameters['myparam'], 'true').

Parametry nie są ograniczone do ciągów skalarnych. Zobacz listę typów danych. Na przykład przy użyciu object typu:

# azure-pipelines.yml
jobs:
- template: process.yml
  parameters:
    pool:   # this parameter is called `pool`
      vmImage: ubuntu-latest  # and it's a mapping rather than a string


# process.yml
parameters:
- name: 'pool'
  type: object
  default: {}

jobs:
- job: build
  pool: ${{ parameters.pool }}

Ponowne użycie zmiennej

Zmienne można zdefiniować w jednym yaml i uwzględnić w innym szablonie. Może to być przydatne, jeśli chcesz przechowywać wszystkie zmienne w jednym pliku. Jeśli używasz szablonu do uwzględnienia zmiennych w potoku, dołączony szablon może służyć tylko do definiowania zmiennych. Podczas rozszerzania szablonu można użyć kroków i bardziej złożonej logiki. Użyj parametrów zamiast zmiennych, jeśli chcesz ograniczyć typ.

W tym przykładzie zmienna favoriteVeggie jest uwzględniona w pliku azure-pipelines.yml.

# File: vars.yml
variables:
  favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml

variables:
- template: vars.yml  # Template reference

steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.

Szablony zmiennych z parametrem

Parametry można przekazywać do zmiennych za pomocą szablonów. W tym przykładzie przekazujesz DIRECTORY parametr do zmiennej RELEASE_COMMAND .

# File: templates/package-release-with-params.yml

parameters:
- name: DIRECTORY 
  type: string
  default: "." # defaults for any parameters that specified with "." (current directory)

variables:
- name: RELEASE_COMMAND
  value: grep version ${{ parameters.DIRECTORY }}/package.json | awk -F \" '{print $4}'  

W przypadku korzystania z szablonu w potoku określ wartości parametrów szablonu.

# File: azure-pipelines.yml

variables: # Global variables
  - template: package-release-with-params.yml # Template reference
    parameters:
      DIRECTORY: "azure/checker"

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Release_Stage 
  displayName: Release Version
  variables: # Stage variables
  - template: package-release-with-params.yml  # Template reference
    parameters:
      DIRECTORY: "azure/todo-list"
  jobs: 
  - job: A
    steps: 
    - bash: $(RELEASE_COMMAND) #output release command

Odwołania do ścieżek szablonów

Ścieżki szablonów mogą być ścieżką bezwzględną w repozytorium lub względem pliku, który wykonuje dołączanie.

Aby użyć ścieżki bezwzględnej, ścieżka szablonu musi zaczynać się od /. Wszystkie inne ścieżki są uważane za względne.

Oto przykład zagnieżdżona hierarchia.

|
+-- fileA.yml
|
+-- dir1/
     |
     +-- fileB.yml
     |
     +-- dir2/
          |
          +-- fileC.yml

fileA.yml Następnie możesz się dowiedzieć fileB.yml i fileC.yml w ten sposób.

steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml

Jeśli fileC.yml jesteś punktem wyjścia, możesz uwzględnić fileA.yml i fileB.yml w ten sposób.

steps:
- template: ../../fileA.yml
- template: ../fileB.yml

Gdy fileB.yml punkt początkowy jest punktem początkowym, możesz uwzględnić fileA.yml i fileC.yml w ten sposób.

steps:
- template: ../fileA.yml
- template: dir2/fileC.yml

Alternatywnie można fileB.yml odwoływać się do ścieżek bezwzględnych i fileC.yml używać fileA.yml takich ścieżek bezwzględnych.

steps:
- template: /fileA.yml
- template: /dir1/dir2/fileC.yml

Korzystanie z innych repozytoriów

Szablony można przechowywać w innych repozytoriach. Załóżmy na przykład, że masz podstawowy potok, który ma być używany przez wszystkie potoki aplikacji. Szablon można umieścić w repozytorium podstawowym, a następnie odwołać się do niego z każdego repozytorium aplikacji:

# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
- name: 'vmImage'
  default: 'ubuntu-22.04'
  type: string

jobs:
- job: Build
  pool:
    vmImage: ${{ parameters.vmImage }}
  steps:
  - script: npm install
  - script: npm test

Teraz możesz ponownie użyć tego szablonu w wielu potokach. Użyj specyfikacji resources , aby podać lokalizację repozytorium podstawowego. W przypadku odwoływania się do repozytorium podstawowego użyj polecenia @ i nazwy nadaną w pliku resources.

# Repo: Contoso/LinuxProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: github
      name: Contoso/BuildTemplates

jobs:
- template: common.yml@templates  # Template reference
# Repo: Contoso/WindowsProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: github
      name: Contoso/BuildTemplates
      ref: refs/tags/v1.0 # optional ref to pin to

jobs:
- template: common.yml@templates  # Template reference
  parameters:
    vmImage: 'windows-latest'

W przypadku type: githubelementu name element jest <identity>/<repo> tak jak w powyższych przykładach. W przypadku type: git usługi (Azure Repos) name jest .<project>/<repo> Jeśli ten projekt znajduje się w oddzielnej organizacji usługi Azure DevOps, musisz skonfigurować połączenie usługi typu Azure Repos/Team Foundation Server z dostępem do projektu i uwzględnić je w języku YAML:

resources:
  repositories:
  - repository: templates
    name: Contoso/BuildTemplates
    endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates

Repozytoria są rozwiązywane tylko raz, gdy potok zostanie uruchomiony. Następnie ten sam zasób jest używany przez czas trwania potoku. Używane są tylko pliki szablonów. Gdy szablony zostaną w pełni rozwinięte, końcowy potok będzie uruchamiany tak, jakby został zdefiniowany całkowicie w repozytorium źródłowym. Oznacza to, że nie można używać skryptów z repozytorium szablonu w potoku.

Jeśli chcesz użyć określonej, stałej wersji szablonu, pamiętaj, aby przypiąć element do elementu ref. Są refs to gałęzie (refs/heads/<name>) lub tagi (refs/tags/<name>). Jeśli chcesz przypiąć określone zatwierdzenie, najpierw utwórz tag wskazujący to zatwierdzenie, a następnie przypnij go do tego tagu.

Uwaga

Jeśli nie ref zostanie określony, potok będzie domyślnie używany przy użyciu polecenia refs/heads/main.

Możesz również przypiąć do określonego zatwierdzenia w usłudze Git z wartością SHA zasobu repozytorium. Wartość SHA to 40-znakowy skrót sumy kontrolnej, który jednoznacznie identyfikuje zatwierdzenie.

resources:
  repositories:
    - repository: templates
      type: git
      name: Contoso/BuildTemplates
      ref: 1234567890abcdef1234567890abcdef12345678

Możesz również użyć @self polecenia , aby odwołać się do repozytorium, w którym znaleziono oryginalny potok. Jest to wygodne w przypadku extends szablonów, jeśli chcesz odwołać się z powrotem do zawartości w repozytorium rozszerzającego potoku. Na przykład:

# Repo: Contoso/Central
# File: template.yml
jobs:
- job: PreBuild
  steps: []

  # Template reference to the repo where this template was
  # included from - consumers of the template are expected
  # to provide a "BuildJobs.yml"
- template: BuildJobs.yml@self

- job: PostBuild
  steps: []
# Repo: Contoso/MyProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: git
      name: Contoso/Central

extends:
  template: template.yml@templates
# Repo: Contoso/MyProduct
# File: BuildJobs.yml
jobs:
- job: Build
  steps: []

Często zadawane pytania

Jak używać zmiennych wewnątrz szablonów?

Czasami przydatne jest ustawianie wartości parametrów na podstawie zmiennych. Parametry są rozszerzane na wczesnym etapie przetwarzania przebiegu potoku, więc nie wszystkie zmienne są dostępne. Aby zobaczyć, jakie wstępnie zdefiniowane zmienne są dostępne w szablonach, zobacz Używanie wstępnie zdefiniowanych zmiennych.

W tym przykładzie wstępnie zdefiniowane zmienne Build.SourceBranch i Build.Reason są używane w warunkach w template.yml.

# File: azure-pipelines.yml
trigger:
- main

extends:
  template: template.yml
# File: template.yml
steps:
- script: echo Build.SourceBranch = $(Build.SourceBranch) # outputs refs/heads/main
- script: echo Build.Reason = $(Build.Reason) # outputs IndividualCI
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: 
  - script: echo I run only if Build.SourceBranch = refs/heads/main 
- ${{ if eq(variables['Build.Reason'], 'IndividualCI') }}: 
  - script: echo I run only if Build.Reason = IndividualCI 
- script: echo I run after the conditions