Tentukan kondisi

Layanan Azure DevOps | Azure DevOps Server 2022 - Azure DevOps Server 2019

Anda dapat menentukan kondisi di mana setiap tahap, pekerjaan, atau langkah berjalan. Secara default, pekerjaan atau tahap berjalan jika tidak bergantung pada pekerjaan atau tahap lain, atau jika semua pekerjaan atau tahapan yang bergantung padanya telah selesai dan berhasil. Ini tidak hanya mencakup dependensi langsung, tetapi dependensinya juga, dihitung secara rekursif. Secara default, sebuah langkah berjalan jika belum ada pekerjaan yang gagal dan langkah yang mendahuluinya telah selesai. Anda dapat menyesuaikan perilaku ini dengan memaksa tahap, pekerjaan, atau langkah untuk dijalankan meskipun dependensi sebelumnya gagal atau dengan menentukan kondisi kustom.

Anda dapat menentukan kondisi di mana langkah, pekerjaan, atau tahapan akan berjalan.

  • Hanya ketika semua dependensi langsung dan tidak langsung sebelumnya dengan kumpulan agen yang sama telah berhasil. Jika Anda memiliki kumpulan agen yang berbeda, tahap atau pekerjaan tersebut akan berjalan bersamaan. Ini adalah default jika tidak ada kondisi yang diatur dalam YAML.

  • Bahkan jika dependensi sebelumnya telah gagal, kecuali jika eksekusi dibatalkan. Gunakan succeededOrFailed() dalam YAML untuk kondisi ini.

  • Bahkan jika dependensi sebelumnya telah gagal, bahkan jika eksekusi dibatalkan. Gunakan always() dalam YAML untuk kondisi ini.

  • Hanya setelah dependensi sebelumnya telah gagal. Gunakan failed() dalam YAML untuk kondisi ini.

  • Kondisi kustom

Secara default, langkah-langkah, pekerjaan, dan tahapan berjalan jika semua dependensi langsung dan tidak langsung telah berhasil. Seolah-olah Anda menentukan "kondisi: berhasil()" (lihat fungsi status yang berhasil).

jobs:
- job: Foo

  steps:
  - script: echo Hello!
    condition: always() # this step will always run, even if the pipeline is canceled

- job: Bar
  dependsOn: Foo
  condition: failed() # this job will only run if Foo fails

Anda juga dapat menggunakan variabel dalam kondisi.

variables:
  isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]

stages:
- stage: A
  jobs:
  - job: A1
    steps:
      - script: echo Hello Stage A!

- stage: B
  condition: and(succeeded(), eq(variables.isMain, true))
  jobs:
  - job: B1
    steps:
      - script: echo Hello Stage B!
      - script: echo $(isMain)

Kondisi dievaluasi untuk memutuskan apakah akan memulai tahap, pekerjaan, atau langkah. Ini berarti bahwa tidak ada yang dihitung pada runtime di dalam unit kerja tersebut yang akan tersedia. Misalnya, jika Anda memiliki pekerjaan yang mengatur variabel menggunakan ekspresi runtime menggunakan $[ ] sintaksis, Anda tidak dapat menggunakan variabel tersebut dalam kondisi kustom Anda.

YAML tidak didukung di TFS.

Catatan

Ketika Anda menentukan properti Anda sendiri condition untuk tahap / pekerjaan / langkah, Anda menimpa defaultnya condition: succeeded(). Ini dapat menyebabkan tahap / pekerjaan / langkah Anda berjalan bahkan jika build dibatalkan. Pastikan Anda memperhitungkan status tahap /pekerjaan induk saat menulis kondisi Anda sendiri.

Mengaktifkan kondisi kustom

Jika kondisi bawaan tidak memenuhi kebutuhan Anda, maka Anda dapat menentukan kondisi kustom.

Kondisi ditulis sebagai ekspresi dalam alur YAML. Agen mengevaluasi ekspresi yang dimulai dengan fungsi terdalam dan mencari jalan keluarnya. Hasil akhirnya adalah nilai boolean yang menentukan apakah tugas, pekerjaan, atau tahapan harus dijalankan atau tidak. Lihat artikel ekspresi untuk panduan lengkap untuk sintaks.

Apakah salah satu kondisi Anda memungkinkan tugas berjalan bahkan setelah build dibatalkan oleh pengguna? Jika demikian, tentukan nilai yang wajar untuk waktu habis pembatalan sehingga jenis tugas ini memiliki cukup waktu untuk diselesaikan setelah pengguna membatalkan eksekusi.

Perilaku alur saat build dibatalkan

Saat build dibatalkan, itu tidak berarti semua tahapan, pekerjaan, atau langkah-langkahnya berhenti berjalan. Keputusan tergantung pada tahap, pekerjaan, atau langkah conditions yang Anda tentukan dan pada titik mana eksekusi alur Anda membatalkan build.

Jika kondisi Anda tidak memperhitungkan status induk tahap/ pekerjaan / langkah Anda, maka jika kondisi mengevaluasi ke true, tahap, pekerjaan, atau langkah Anda akan berjalan, bahkan jika induknya dibatalkan. Jika induknya dilewati, maka tahap, pekerjaan, atau langkah Anda tidak akan berjalan.

Mari kita lihat beberapa contoh.

Dalam alur ini, secara default, stage2 bergantung pada stage1 dan stage2 memiliki satu condition set. stage2 hanya berjalan ketika cabang sumber adalah main.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
  jobs:
  - job: B
    steps:
      - script: echo 2

Jika Anda mengantre build di main cabang, dan Anda membatalkannya saat stage1 sedang berjalan, stage2 akan tetap berjalan, karena eq(variables['Build.SourceBranch'], 'refs/heads/main') mengevaluasi ke true.

Dalam alur ini, stage2 tergantung pada stage1. Pekerjaan B memiliki set condition untuk itu.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  jobs:
  - job: B
    condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
    steps:
      - script: echo 2

Jika Anda mengantre build di main cabang, dan Anda membatalkannya saat stage1 sedang berjalan,stage2 tidak akan berjalan, meskipun berisi pekerjaan B yang kondisinya dievaluasi ke true. Alasannya adalah karena stage2 memiliki default condition: succeeded(), yang mengevaluasi kapan falsestage1 dibatalkan. Oleh karena itu, stage2 dilewati, dan tidak ada pekerjaannya yang berjalan.

Katakanlah Anda memiliki alur YAML berikut. Perhatikan bahwa, secara default, stage2 tergantung pada stage1 dan yang script: echo 2 memiliki set condition untuk itu.

stages:
- stage: stage1
  jobs:
  - job: A
    steps:
      - script: echo 1; sleep 30
- stage: stage2
  jobs:
  - job: B
    steps:
      - script: echo 2
        condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')

Jika Anda mengantre build di main cabang, dan Anda membatalkannya saat stage1 sedang berjalan,stage2 tidak akan berjalan, meskipun berisi langkah dalam pekerjaan B yang kondisinya dievaluasi ke true. Alasannya adalah karena stage2 dilewati sebagai respons untuk stage1 dibatalkan.

Untuk mencegah tahapan, pekerjaan, atau langkah-langkah dengan conditions menjalankan saat build dibatalkan, pastikan Anda mempertimbangkan status induknya saat menulis conditions. Untuk informasi selengkapnya, lihat Fungsi status pekerjaan.

Contoh

Jalankan untuk cabang utama, bahkan jika dibatalkan, bahkan jika gagal

eq(variables['Build.SourceBranch'], 'refs/heads/main')

Jalankan untuk cabang utama, jika berhasil

and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Jalankan jika cabang tidak utama, jika berhasil

and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))

Jalankan untuk cabang topik pengguna, jika berhasil

and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))

Jalankan untuk build integrasi berkelanjutan (CI) jika berhasil

and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))

Jalankan jika build dijalankan oleh kebijakan cabang untuk permintaan pull, jika gagal

and(failed(), eq(variables['Build.Reason'], 'PullRequest'))

Jalankan jika build dijadwalkan, bahkan jika gagal, bahkan jika dibatalkan

eq(variables['Build.Reason'], 'Schedule')

Release.Artifacts. {artifact-alias}. SourceBranch setara dengan Build.SourceBranch.

Selalu jalankan jika variabel diatur ke true, bahkan jika dibatalkan, bahkan jika gagal

eq(variables['System.debug'], true)

Jalankan jika variabel null (string kosong)

Karena semua variabel diperlakukan sebagai string di Azure Pipelines, string kosong setara dengan null dalam alur ini.

variables:
- name: testEmpty
  value: ''

jobs:
  - job: A
    steps:
    - script: echo testEmpty is blank
    condition: eq(variables.testEmpty, '')

Menggunakan parameter templat sebagai bagian dari suatu kondisi

Saat Anda mendeklarasikan parameter dalam alur yang sama dengan kondisi yang Anda miliki, ekspansi parameter terjadi sebelum kondisi dipertimbangkan. Dalam hal ini, Anda dapat menyematkan parameter di dalam kondisi. Skrip dalam file YAML ini akan berjalan karena parameters.doThing benar.

condition dalam alur menggabungkan dua fungsi: succeeded() dan eq('${{ parameters.doThing }}', true). Fungsi succeeded() memeriksa apakah langkah sebelumnya berhasil. Fungsi succeeded() mengembalikan true karena tidak ada langkah sebelumnya.

Fungsi eq('${{ parameters.doThing }}', true) memeriksa apakah parameter doThing sama dengan true. Karena nilai default untuk doThing adalah true, kondisi akan mengembalikan true secara default kecuali nilai yang berbeda diatur dalam alur.

Untuk contoh parameter templat lainnya, lihat Jenis templat &penggunaan.

parameters:
- name: doThing
  default: true
  type: boolean

steps:
- script: echo I did a thing
  condition: ${{ eq(parameters.doThing, true) }}

Saat meneruskan parameter ke templat, Anda perlu mengatur nilai parameter di templat Anda atau menggunakan templateContext untuk meneruskan properti ke templat.

# parameters.yml
parameters:
- name: doThing
  default: true # value passed to the condition
  type: boolean

jobs:
  - job: B
    steps:
    - script: echo I did a thing
    condition: ${{ eq(parameters.doThing, true) }}
# azure-pipeline.yml
parameters:
- name: doThing
  default: true 
  type: boolean

trigger:
- none

extends:
  template: parameters.yml

Output dari alur ini adalah I did a thing karena parameternya doThing benar.

Menggunakan variabel output dari pekerjaan dalam suatu kondisi di pekerjaan berikutnya

Anda dapat membuat variabel tersedia untuk pekerjaan di masa mendatang dan menentukannya dalam kondisi. Variabel yang tersedia untuk pekerjaan di masa mendatang harus ditandai sebagai variabel output multi-pekerjaan menggunakan isOutput=true.

jobs:
- job: Foo
  steps:
  - bash: |
      echo "This is job Foo."
      echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
    name: DetermineResult
- job: Bar
  dependsOn: Foo
  condition: eq(dependencies.Foo.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
  steps:
  - script: echo "Job Foo ran and doThing is Yes."

Menggunakan variabel alur yang dibuat dari langkah dalam suatu kondisi di langkah berikutnya

Anda dapat membuat variabel tersedia untuk langkah-langkah di masa mendatang dan menentukannya dalam kondisi. Secara default, variabel yang dibuat dari langkah tersedia untuk langkah-langkah di masa mendatang dan tidak perlu ditandai sebagai variabel output multi-pekerjaan menggunakan isOutput=true.

Ada beberapa hal penting yang perlu diperhatikan mengenai pendekatan dan cakupan di atas:

  • Variabel yang dibuat dalam langkah dalam pekerjaan akan dilingkupkan ke langkah-langkah dalam pekerjaan yang sama.
  • Variabel yang dibuat dalam langkah hanya akan tersedia dalam langkah berikutnya sebagai variabel lingkungan.
  • Variabel yang dibuat dalam langkah tidak dapat digunakan dalam langkah yang menentukannya.

Di bawah ini adalah contoh pembuatan variabel alur dalam langkah dan menggunakan variabel dalam kondisi dan skrip langkah berikutnya.

steps:

# This step creates a new pipeline variable: doThing. This variable will be available to subsquent steps.
- bash: |
    echo "##vso[task.setvariable variable=doThing]Yes"
  displayName: Step 1

# This step is able to use doThing, so it uses it in its condition
- script: |
    # You can access the variable from Step 1 as an environment variable.
    echo "Value of doThing (as DOTHING env var): $DOTHING."
  displayName: Step 2
  condition: and(succeeded(), eq(variables['doThing'], 'Yes')) # or and(succeeded(), eq(variables.doThing, 'Yes'))

FAQ

Bagaimana cara memicu pekerjaan jika pekerjaan sebelumnya berhasil dengan masalah?

Anda dapat menggunakan hasil pekerjaan sebelumnya. Misalnya, dalam file YAML ini, kondisi eq(dependencies.A.result,'SucceededWithIssues') memungkinkan pekerjaan berjalan karena Pekerjaan A berhasil dengan masalah.

jobs:
- job: A
  displayName: Job A
  continueOnError: true # next job starts even if this one fails
  steps:
  - script: echo Job A ran
  - script: exit 1

- job: B
  dependsOn: A
  condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job 
  displayName: Job B
  steps:
  - script: echo Job B ran

Saya membatalkan build saya, tetapi masih berjalan. Apa yang terjadi?

Anda akan mengalami masalah ini jika kondisi yang dikonfigurasi dalam tahap tidak menyertakan fungsi pemeriksaan status pekerjaan. Untuk mengatasi masalah ini, tambahkan fungsi pemeriksaan status pekerjaan ke kondisi tersebut. Jika Anda membatalkan pekerjaan saat dalam antrean, tetapi tidak berjalan, seluruh pekerjaan dibatalkan, termasuk semua tahap lainnya.

Pelajari selengkapnya tentang perilaku alur saat build dibatalkan.