Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Layanan Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022
Templat memungkinkan Anda menentukan konten, logika, dan parameter yang dapat digunakan kembali dalam alur YAML. Untuk bekerja dengan templat secara efektif, Anda harus memiliki pemahaman dasar tentang konsep utama Azure Pipelines seperti tahapan, langkah, dan pekerjaan.
Ada dua jenis templat utama:
- Menyertakan templat: Sisipkan konten yang dapat digunakan kembali ke dalam alur. Jika templat digunakan untuk menyertakan konten, templat berfungsi seperti direktif sertakan dalam banyak bahasa pemrograman. Konten dari templat disisipkan ke dalam alur atau templat yang menyertakannya.
- Memperluas templat: Mengontrol dan menentukan skema untuk apa yang diizinkan dalam alur. Saat templat perluasan digunakan, templat menentukan logika dan struktur yang harus diikuti alur. Ini berguna untuk menegakkan standar keamanan, kepatuhan, atau organisasi.
Templat dapat membantu Anda mempercepat pengembangan. Misalnya, Anda dapat memiliki serangkaian tugas yang sama dalam templat lalu menyertakan templat beberapa kali dalam tahap yang berbeda dari alur YAML Anda.
Templat juga dapat membantu Anda mengamankan alur proses Anda. Saat templat mengontrol apa yang diizinkan dalam alur, templat menentukan logika yang harus diikuti file lain. Misalnya, Anda mungkin ingin membatasi tugas apa yang diizinkan untuk dijalankan. Untuk skenario tersebut, Anda dapat menggunakan templat untuk mencegah seseorang berhasil menjalankan tugas yang melanggar kebijakan keamanan organisasi Anda.
Untuk memanfaatkan templat sepenuhnya, Anda juga harus menggunakan ekspresi templat dan parameter templat.
Prasyarat
| Produk | Persyaratan |
|---|---|
| Azure DevOps | - Proyek Azure DevOps. - Kemampuan untuk menjalankan alur pada agen yang dihosting Microsoft. Anda dapat membeli pekerjaan paralel atau Anda dapat meminta tingkat gratis. - Pengetahuan dasar tentang YAML dan Azure Pipelines. Untuk informasi selengkapnya, lihat Buat pipa pertama Anda. - Izin: - Untuk membuat alur: Anda harus berada di grup Kontributor dan grup harus mengatur izin Buat alur build ke Izinkan. Anggota grup Administrator Proyek dapat mengelola alur. - Untuk membuat koneksi layanan: Anda harus memiliki peran Administrator atau Pembuat untuk koneksi layanan. |
| GitHub | - Akun GitHub . - Koneksi layanan GitHub untuk mengotorisasi Azure Pipelines. |
| Azure | Sebuah langganan Azure. |
Batas yang diberlakukan pada pembaruan templat
Templat dan ekspresi templat dapat menyebabkan pertumbuhan eksplosif pada ukuran dan kompleksitas alur. Untuk membantu mencegah pertumbuhan yang tidak terkendali, Azure Pipelines memberlakukan batas berikut:
- Tidak lebih dari 100 file YAML terpisah dapat disertakan (secara langsung atau tidak langsung)
- Tidak lebih dari 100 tingkat susunan templat (templat yang mencakup templat lainnya)
- Tidak lebih dari 20 megabyte memori yang dikonsumsi saat mengurai YAML (dalam praktiknya, ini biasanya antara 600 KB - 2 MB YAML pada disk, tergantung pada fitur spesifik yang digunakan)
Mengembangkan dari templat
Untuk meningkatkan keamanan, Anda dapat memastikan bahwa pipeline berasal dari templat tertentu. File start-extends-template.yml menentukan parameter buildSteps, yang kemudian digunakan dalam alur azure-pipelines.yml.
Di start-extends-template.yml, jika sebuah buildStep diteruskan dalam langkah skrip, maka itu akan ditolak dan proses build alur kerja akan gagal.
Saat memperluas dari templat, Anda dapat meningkatkan keamanan dengan menambahkan persetujuan templat yang diperlukan.
# File: start-extends-template.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-extends-template.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"
Perluas dari templat dengan sumber daya
Anda juga dapat menggunakan extends untuk memperluas dari templat di alur Azure Anda yang berisi sumber daya.
# File: azure-pipelines.yml
trigger:
- none
extends:
template: resource-extends-template.yml
# File: resource-extends-template.yml
resources:
pipelines:
- pipeline: my-pipeline
source: sourcePipeline
steps:
- script: echo "Testing resource template"
Menyisipkan templat
Anda dapat menyisipkan konten dari satu YAML dan menggunakannya kembali di YAML yang berbeda. Menyisipkan konten dari satu YAML ke YAML lain akan menghemat Anda dari keramaian menyertakan logika yang sama secara manual di beberapa tempat.
insert-npm-steps.yml Templat file berisi langkah-langkah yang digunakan ulang di azure-pipelines.yml.
Catatan
File templat harus ada di sistem file Anda di awal eksekusi alur. Anda tidak dapat mereferensikan templat dalam artefak.
# File: templates/insert-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/insert-npm-steps.yml # Template reference
- job: Windows
pool:
vmImage: 'windows-latest'
steps:
- template: templates/insert-npm-steps.yml # Template reference
Gunakan kembali langkah-langkah di beberapa pekerjaan
Anda dapat menyisipkan templat untuk menggunakan kembali satu atau beberapa langkah di beberapa pekerjaan. Selain langkah-langkah dari templat, setiap pekerjaan dapat menentukan lebih banyak langkah.
# File: templates/insert-npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml
jobs:
- job: Linux
pool:
vmImage: 'ubuntu-latest'
steps:
- template: templates/insert-npm-steps.yml # Template reference
- job: macOS
pool:
vmImage: 'macOS-latest'
steps:
- template: templates/insert-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/insert-npm-steps.yml # Template reference
- script: echo This step runs after the template's steps.
Menggunakan kembali tugas di beberapa templat
Sama seperti langkah-langkah, tugas dapat digunakan ulang dengan templat.
# File: templates/insert-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/insert-jobs.yml # Template reference
Saat bekerja dengan beberapa pekerjaan, ingatlah untuk menghapus nama pekerjaan dalam file templat, sehingga menghindari konflik
# File: templates/insert-multiple-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/insert-multiple-job.yml # Template reference
- template: templates/insert-multiple-jobs.yml # Template reference
- template: templates/insert-multiple-jobs.yml # Template reference
Menggunakan kembali tahapan di beberapa templat
Tahap juga dapat digunakan kembali dengan template.
# File: templates/insert-stage1.yml
stages:
- stage: Angular
jobs:
- job: angularinstall
steps:
- script: npm install angular
# File: templates/insert-stage2.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/insert-stage1.yml # Template reference
- template: templates/insert-stage2.yml # Template reference
Menambahkan parameter ke templat pekerjaan, tahap, dan langkah
Dalam templat berikut:
-
templates/npm-with-params.ymlmenentukan dua parameter:namedanvmImagedan membuat pekerjaan dengan parameter nama untuk nama pekerjaan dan parameter vmImage untuk gambar VM. - Alur (
azure-pipelines.yml) mereferensikan templat tiga kali, masing-masing dengan nilai parameter yang berbeda yang mengacu pada sistem operasi dan nama gambar VM. - Alur bawaan berjalan pada gambar VM yang berbeda dan dinamai sesuai dengan OS yang ditentukan. Setiap pekerjaan melakukan langkah-langkah penginstalan npm dan pengujian npm.
# 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
Saat Anda menggunakan templat di alur Anda, tentukan nilai untuk parameter templat.
# 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'
Templat tahapan dengan beberapa parameter
Dalam templat berikut:
-
stage-template.ymlTemplat mendefinisikan empat parameter:stageName,jobName,vmImage, danscriptPath, semua berjenis string. Templat membuat tahap dengan parameterstageNameuntuk mengatur nama tahap, menentukan pekerjaan denganjobName, dan menyertakan langkah untuk menjalankan skrip. - Alur,
azure-pipeline.yml, kemudian secara dinamis menentukan tahapan dan pekerjaan menggunakan parameter dan menjalankan pekerjaan yang menjalankan skrip,build-script.sh.
# stage-template.yml
parameters:
- name: stageName
type: string
- name: jobName
type: string
- name: vmImage
type: string
- name: scriptPath
type: string
stages:
- stage: ${{ parameters.stageName }}
jobs:
- job: ${{ parameters.jobName }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: ./${{ parameters.scriptPath }}
# azure-pipelines.yml
trigger:
- main
stages:
- template: stage-template.yml
parameters:
stageName: 'BuildStage'
jobName: 'BuildJob'
scriptPath: 'build-script.sh' # replace with script in your repository
vmImage: 'ubuntu-latest'
Templat dengan langkah dan parameter
Anda juga dapat menggunakan parameter dengan templat langkah atau tahap.
Dalam templat berikut:
- Templat (
templates/steps-with-params.yml) mendefinisikan parameter bernamarunExtendedTestsdengan nilai default false. - Jalur pipa (
azure-pipelines.yml) berjalannpm testdannpm test --extendedkarena parameterrunExtendedTestsadalah benar.
# 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
Saat Anda menggunakan templat di alur Anda, tentukan nilai-nilai untuk parameter templat.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Catatan
Parameter skalar tanpa jenis tertentu diperlakukan sebagai string.
Misalnya, eq(true, parameters['myparam']) akan mengembalikan true, bahkan jika myparam parameternya adalah kata false, jika myparam tidak dibuat booleansecara eksplisit .
String yang tidak kosong dilemparkan ke true dalam konteks Boolean.
Ekspresi tersebut dapat ditulis ulang untuk membandingkan string secara eksplisit: eq(parameters['myparam'], 'true').
Parameter tidak terbatas pada string skalar.
Lihat daftar jenis data.
Misalnya, menggunakan object jenis :
# 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 }}
Penggunaan ulang variabel
Variabel dapat didefinisikan dalam satu YAML dan disertakan dalam templat lain. Ini bisa berguna jika Anda ingin menyimpan semua variabel Anda dalam satu file. Jika Anda menggunakan templat untuk menyertakan variabel dalam alur, templat yang disertakan hanya dapat digunakan untuk menentukan variabel. Anda dapat menggunakan langkah-langkah dan logika yang lebih kompleks saat memperluas dari templat.
Catatan
Gunakan parameter alih-alih variabel untuk keamanan tambahan seperti menentukan jenis. Untuk informasi selengkapnya tentang pentingnya menggunakan parameter untuk tugas shell, silakan merujuk pada dokumentasi validasi parameter argumen tugas shell.
Dalam contoh ini, variabel favoriteVeggie disertakan dalam azure-pipelines.yml.
# File: insert-vars.yml
variables:
favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml
variables:
- template: insert-vars.yml # Template reference
steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
Templat variabel dengan parameter
Anda dapat meneruskan parameter ke variabel dengan templat. Dalam contoh ini, Anda meneruskan parameter DIRECTORY ke variabel 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}'
Saat Anda menggunakan templat di alur Anda, tentukan nilai-nilai untuk parameter templat.
# 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
Perluas dari templat dan gunakan templat yang disertakan dengan menggunakan variabel
Salah satu skenario umum adalah memiliki alur dengan tahapan untuk pengembangan, pengujian, dan produksi yang menggunakan templat yang disertakan untuk variabel dan templat perluasan untuk tahap dan pekerjaan.
Dalam contoh berikut, variables-template.yml mendefinisikan sekumpulan variabel komputer virtual yang kemudian digunakan dalam azure-pipeline.yml.
# variables-template.yml
variables:
- name: devVmImage
value: 'ubuntu-latest'
- name: testVmImage
value: 'ubuntu-latest'
- name: prodVmImage
value: 'ubuntu-latest'
File berikut, stage-template.yml menentukan konfigurasi tahap yang dapat digunakan kembali dengan tiga parameter (name, , vmImagesteps) dan pekerjaan bernama Build.
# stage-template.yml
parameters:
- name: name
type: string
default: ''
- name: vmImage
type: string
default: ''
- name: steps
type: stepList
default: []
stages:
- stage: ${{ parameters.name }}
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps: ${{ parameters.steps }}
Alur berikut, azure-pipelines.yml, mengimpor variabel dari variables-template.yml, lalu menggunakan stage-template.yml templat untuk setiap tahap. Setiap tahap (Dev, Test, Prod) didefinisikan dengan templat yang sama tetapi dengan parameter yang berbeda, yang mengarah ke konsistensi di seluruh tahap sambil memungkinkan penyesuaian. Tahap 'Prod' menyertakan variabel lingkungan sebagai contoh sesuatu yang mungkin Anda gunakan untuk autentikasi. Untuk mempelajari selengkapnya tentang menentukan parameter, lihat Parameter templat.
# azure-pipelines.yml
trigger:
- main
variables:
- template: variables-template.yml
stages:
- template: stage-template.yml
parameters:
name: Dev
vmImage: ${{ variables.devVmImage }}
steps:
- script: echo "Building in Dev"
- template: stage-template.yml
parameters:
name: Test
vmImage: ${{ variables.testVmImage }}
steps:
- script: echo "Testing in Test"
- template: stage-template.yml
parameters:
name: Prod
vmImage: ${{ variables.prodVmImage }}
steps:
- script: echo "Deploying to Prod"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Jalur templat referensi
Jalur templat dapat menjadi jalur absolut dalam repositori atau relatif terhadap file yang menyertakan.
Untuk menggunakan jalur absolut, jalur templat harus dimulai dengan /. Semua jalur lain dianggap relatif.
Berikut adalah contoh hierarki berlapis.
|
+-- fileA.yml
|
+-- dir1/
|
+-- fileB.yml
|
+-- dir2/
|
+-- fileC.yml
Kemudian, dalam fileA.yml Anda dapat mereferensikan fileB.yml dan fileC.yml seperti ini.
steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml
Jika fileC.yml adalah titik awal Anda, Anda dapat menyertakan fileA.yml dan fileB.yml seperti ini.
steps:
- template: ../../fileA.yml
- template: ../fileB.yml
Ketika fileB.yml adalah titik awal Anda, Anda dapat menyertakan fileA.yml dan fileC.yml seperti ini.
steps:
- template: ../fileA.yml
- template: dir2/fileC.yml
Atau, fileB.yml dapat merujuk ke fileA.yml dan fileC.yml menggunakan jalur absolut seperti ini.
steps:
- template: /fileA.yml
- template: /dir1/dir2/fileC.yml
Menyimpan templat di repositori lain
Anda dapat menyimpan templat Anda di repositori lain. Misalnya, Anda memiliki alur inti yang Anda inginkan untuk digunakan oleh semua alur aplikasi Anda. Anda dapat menempatkan templat dalam repositori inti lalu merujuknya dari setiap repositori aplikasi Anda:
# 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
Sekarang Anda dapat menggunakan kembali templat ini di beberapa alur.
resources Gunakan spesifikasi untuk menyediakan lokasi repositori inti.
Ketika Anda merujuk ke repositori inti, gunakan @ dan nama yang Anda berikan di 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'
Untuk type: github, name adalah <identity>/<repo> seperti dalam contoh sebelumnya.
Untuk type: git (Azure Repos), name adalah <project>/<repo>.
Jika proyek tersebut berada dalam organisasi Azure DevOps terpisah, Anda perlu mengonfigurasi koneksi layanan jenis Azure Repos/Team Foundation Server dengan akses ke proyek dan menyertakannya dalam YAML:
resources:
repositories:
- repository: templates
name: Contoso/BuildTemplates
endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates
Repositori dikonfigurasi hanya sekali, ketika pipeline dimulai. Setelah itu, sumber daya yang sama digunakan selama pelaksanaan pipeline. Hanya file templat yang digunakan. Setelah templat diperluas sepenuhnya, alur akhir berjalan seolah-olah didefinisikan sepenuhnya dalam repositori sumber. Ini berarti Anda tidak dapat menggunakan skrip dari repositori templat di alur Anda.
Jika Anda ingin menggunakan versi templat yang spesifik dan tetap, pastikan untuk menyematkannya ke ref.
refs adalah cabang (refs/heads/<name>) atau tag (refs/tags/<name>).
Jika Anda ingin menyematkan penerapan tertentu, pertama-tama buat tag yang menunjuk ke penerapan tersebut, lalu sematkan ke tag tersebut.
Catatan
Jika tidak ada ref yang ditentukan, alur default menggunakan refs/heads/main.
Anda juga dapat menyematkan ke komit tertentu di Git dengan nilai SHA untuk sumber daya repositori. Nilai SHA adalah hash checksum yang terdiri dari 40 karakter yang secara unik mengidentifikasi komit.
resources:
repositories:
- repository: templates
type: git
name: Contoso/BuildTemplates
ref: 1234567890abcdef1234567890abcdef12345678
Anda juga dapat menggunakan @self untuk merujuk ke repositori tempat alur asli ditemukan.
Ini praktis digunakan dalam extends template jika Anda ingin merujuk kembali ke konten di repositori dari alur yang diperluas.
Contohnya:
# 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: []
FAQ
Bagaimana cara menggunakan variabel di dalam template?
Ada kalanya berguna untuk mengatur parameter ke nilai berdasarkan variabel. Parameter diekspansi lebih awal saat menjalankan pipeline sehingga tidak semua variabel tersedia. Untuk melihat variabel yang telah ditentukan sebelumnya yang tersedia dalam template, lihat Menggunakan variabel yang telah ditentukan sebelumnya.
Dalam contoh ini, variabel Build.SourceBranch yang telah ditentukan sebelumnya dan Build.Reason digunakan dalam kondisi dalam 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