Closed13

GitHub Actionsのconcurrencyを触ってみる

Futa HirakobaFuta Hirakoba

ちょうどghコマンドでworkflow_dispatchを叩けるようになったので使ってみた

❯ gh workflow run .github/workflows/concurrency-workflow.yaml 
✓ Created workflow_dispatch event for concurrency-workflow.yaml at main

To see runs for this workflow, try: gh run list --workflow=concurrency-workflow.yaml
Futa HirakobaFuta Hirakoba

.github/workflows/concurrency-workflow.yamlは実行後60秒はワークフローが終わらないのですぐさま2回実行するとconcurrencyを確かめられる。

下みたいになった。確かに待ってる!

Futa HirakobaFuta Hirakoba

今度はジョブのconcurrencyを実験。下のようなworkflowを流してみる。

.github/workflows/concurrency-workflow.yaml
on:
  workflow_dispatch

jobs:
  normal-job:
    runs-on: ubuntu-20.04
    steps:
      - run: sleep 5

  concurrency-job:
    runs-on: ubuntu-20.04
    concurrency:
      this_is_concurrency_job
    steps:
      - run: sleep 60

  dependent-job:
    runs-on: ubuntu-20.04
    needs:
      - normal-job
    concurrency:
      this_is_concurrency_job_2
    steps:
      - run: sleep 20

  after-job:
    runs-on: ubuntu-20.04
    needs:
      - dependent-job
    concurrency:
      this_is_concurrency_job
    steps:
      - run: sleep 5

実行

おっ。concurrency-jobafter-jobは同じ名前のconcurrencyが設定されているからちゃんと待ったぞ
(まあこのワークフローの場合普通にneedsを使えば同時実行は防げるけど)

Futa HirakobaFuta Hirakoba

ジョブのconcurrencyはワークフローをまたいでも同時実行を防げるのか!?
というわけで.github/workflows/concurrency-job.yamlをすかさず二回実行。

❯ gh workflow run .github/workflows/concurrency-job.yaml
✓ Created workflow_dispatch event for concurrency-job.yaml at main

To see runs for this workflow, try: gh run list --workflow=concurrency-job.yaml

❯ gh workflow run .github/workflows/concurrency-job.yaml
✓ Created workflow_dispatch event for concurrency-job.yaml at main

To see runs for this workflow, try: gh run list --workflow=concurrency-job.yaml

実行...

↑ 最初に実行したワークフロー
↓ その後実行したワークフロー

同じ名前のconcurrencyならワークフローをまたいでも同時実行は防げるようですね

Futa HirakobaFuta Hirakoba

ちなみにIntelliJで参照できるJSONスキーマはまだconcurrencyに未対応な模様

Futa HirakobaFuta Hirakoba

おおっと。さっき実行したワークフローをもっかい見に行ったらキャンセルされてた。

Canceling since a higher priority waiting request for 'this_is_concurrency_job' exists

(DeepL翻訳くん) this_is_concurrency_job' に対するより優先度の高い待機中のリクエストが存在するため、キャンセルします。

workflowをまたぐと後続のジョブはキャンセルされる??不思議なのはdependent-jobだ。こっちもwaitになってたのにしっかり実行されたみたい。

Futa HirakobaFuta Hirakoba

cancel-in-progress: trueを使ってみた。

.github/workflows/concurrency-job2.yaml
on:
  workflow_dispatch

jobs:
  normal-job:
    runs-on: ubuntu-20.04
    steps:
      - run: sleep 5

  concurrency-job:
    runs-on: ubuntu-20.04
    concurrency:
      group: this_is_concurrency_job
      cancel-in-progress: true
    steps:
      - run: sleep 60

  dependent-job:
    runs-on: ubuntu-20.04
    needs:
      - normal-job
    concurrency:
      group: this_is_concurrency_job2
      cancel-in-progress: true
    steps:
      - run: sleep 20

  after-job:
    runs-on: ubuntu-20.04
    needs:
      - dependent-job
    concurrency:
      this_is_concurrency_job
    steps:
      - run: sleep 5

うーんいまいち挙動がわからん。
先に実行されたジョブがキャンセルされるのもあれば後に実行されたジョブがキャンセルされることもある。両方キャンセルされるのもある。謎

Futa HirakobaFuta Hirakoba

もしかしてcancel-in-progress: trueがデフォルトなのかと思ってcancel-in-progress: falseにしてみた。

.github/workflows/concurrency-job3.yaml
on:
  workflow_dispatch

jobs:
  normal-job:
    runs-on: ubuntu-20.04
    steps:
      - run: sleep 5

  concurrency-job:
    runs-on: ubuntu-20.04
    concurrency:
      group: this_is_concurrency_job
      cancel-in-progress: false
    steps:
      - run: sleep 60

  dependent-job:
    runs-on: ubuntu-20.04
    needs:
      - normal-job
    concurrency:
      group: this_is_concurrency_job2
      cancel-in-progress: false
    steps:
      - run: sleep 20

  after-job:
    runs-on: ubuntu-20.04
    needs:
      - dependent-job
    concurrency:
      this_is_concurrency_job
    steps:
      - run: sleep 5

やはりキャンセルされる...
一体どういう条件でキャンセルされるんだ?

Futa HirakobaFuta Hirakoba

ベータ版だからかちょっと同時実行のキャンセル周りの挙動が謎なので本番利用するのはまだちょっと厳しいかも?
正式リリースを待ちたいぜ

このスクラップは2021/04/25にクローズされました