【Github】Github Actions ~ runs-onを動的変更することを考える ~

■ はじめに

Self-hosted runner が各環境(e.g. dev/stage/prod)にあり
動的に変更したいってことを考える。

なお、以下のサイトが参考になった。

https://zenn.dev/snowcait/articles/56fad93b7dc95e

目次

【1】案1:ファイルを分けて管理する
 1)デメリット
【2】案2:workflow_dispatch.inputs で指定
 1)デメリット
 2)サンプル
【3】案3:条件分岐(真or偽)で切り替える
 1)デメリット
 2)サンプル
【4】案4:Reusable Workflows を利用する
 1)デメリット
 2)サンプル

【1】案1:ファイルを分けて管理する

* 例えば「dev.workflow.yml」「prod.workflow.yml」って
 感じで分ける

1)デメリット

[1] ファイルが増える
[2] 同じ処理を別々のファイルに書くためメンテナンス性が下がる

【2】案2:workflow_dispatch.inputs で指定

構文

runs-on: ${{ inputs.<変数> }}
# or
runs-on: ${{ github.event.inputs.<変数> }}
# or
runs-on: ${{ fromJSON(github.event.inputs.<変数>) }}

1)デメリット

* 手動でデプロイする運用ならいいが、
 それ以外(自動化)は不可

2)サンプル

name: DemoWorkflow

on:
  workflow_dispatch:
    inputs:
      runs_on:
        type: choice
        default: ubuntu-latest
        options:
        - ubuntu-latest
        - ubuntu-24.04
        - ubuntu-20.04
jobs:
  demo_job:
    runs-on: ${{ inputs.runs_on }}
    steps:
      - uses: actions/checkout@v4
      - name: settings
        run: |
          echo "Hello, world"

【3】案3:条件分岐(真or偽)で切り替える

* 三項演算子を利用する

https://stackoverflow.com/questions/73241812/how-to-dynamically-assign-the-runs-on-value-in-the-github-actions

* Github Actions の 三項演算子についての詳細は、以下の関連記事を参照のこと

Github Actions ~ 三項演算子
https://dk521123.hatenablog.com/entry/2024/06/20/234016

構文

    runs-on: >-
      ${{
        【条件】
          && 【条件が真の場合】
          || 【条件が偽の場合】
      }}

1)デメリット

* 条件が増えると可読性が下がる

2)サンプル

例1:ブランチで切換

name: demo for multiple runners

on:
  push:
    branches:
      - dev
      - prod

jobs:
  demo-job1:
    # if affected branch is 'demo' then runs on 'ubuntu-latest' else self-hosted...
    runs-on: >-
      ${{
        github.ref_name == 'dev'
          && fromJSON('[ "ubuntu-latest", "development" ]')
          || fromJSON('["self-hosted", "production" ]')
      }}
    steps:
      - name: Demo sample
        run: echo "Hello, world!!"

例2:3通り

name: StartA

on:
  push:

jobs:
  test:
    runs-on: >-
      ${{
        github.ref_name == 'prod'
          && fromJSON('[ "ubuntu-latest" ]')
          || (github.ref_name == 'stage' && fromJSON('["ubuntu-24.04" ]')
          # 4通りなら、、、
          # || (github.ref_name == 'dev' && fromJSON('["ubuntu-24.04" ]')
          || fromJSON('["ubuntu-20.04" ]'))
      }}
    steps:
      - name: test
        run: echo "Hi!!"

例3:複数条件

name: DemoWorkflow

on:
  workflow_dispatch:
    inputs:
      env:
        type: choice
        default: dev
        options:
        - dev
        - stage
        - prod
jobs:
  demo_job:
    runs-on: >-
      ${{
        # (【条件1(github.ref_name == 'develop')】 &&(かつ) 【条件2(inputs.env == 'dev')】)
        (github.ref_name == 'develop' && inputs.env == 'dev')
          && fromJSON('[ "ubuntu-20.04" ]')
          || ((github.ref_name != 'develop' && inputs.env == 'dev') && fromJSON('["ubuntu-24.04" ]')
          || fromJSON('["ubuntu-latest" ]'))
      }}
    steps:
      - uses: actions/checkout@v4
      - name: settings
        run: |
          echo "Hello, world"

例4:手動実行&Pushイベント混合

name: TestA

on:
  workflow_dispatch:
    inputs:
      runs_on:
        type: choice
        default: ''
        options:
        - ubuntu-24.04
        - ubuntu-20.04
  push:
    branches:
      - develop
jobs:
  sample:
    runs-on: >-
      ${{
        inputs.runs_on != ''
          && inputs.runs_on
          || (github.ref_name == 'develop' && fromJSON('["ubuntu-latest"]')
          || fromJSON('["ubuntu-24.04"]'))
      }}
    steps:
      - name: Demo sample
        run: echo "Hello, world!!"

【4】案4:Reusable Workflows を利用する

Reusable Workflows の引数に設定する runs-on の値を
当たすようにする方法。(まずは、以下のサンプルをみた方がいいかも)
 => Reusable Workflowsについては、以下の関連記事を参照のこと

Github Actions ~ workflow_run / workflow_call ~
https://dk521123.hatenablog.com/entry/2024/02/14/232546

1)デメリット

* はじめに、Reusable Workflows に渡す引数を決めるために
 runs-onを固定しなくてはならない

2)サンプル

.github/workflows/start.yml

name: StartDemo

on:
  push:

jobs:
  init:
    # ★デメリット:まずは固定する必要がある
    runs-on: "ubuntu-latest"
    steps:
      # ★ここで値を決める
      - name: set for dev
        if: github.ref_name == 'develop'
        run: |
          value="ubuntu-24.04"
          echo "GITHUB_RUNS_ON=${value}" >> $GITHUB_ENV
      - name: set for stage
        if: github.ref_name == 'stage'
        run: |
          value="ubuntu-22.04"
          echo "GITHUB_RUNS_ON=${value}" >> $GITHUB_ENV
      - name: set for prod
        if: github.ref_name == 'prod'
        run: |
          value="ubuntu-latest"
          echo "GITHUB_RUNS_ON=${value}" >> $GITHUB_ENV
      # ★ここで、最終的な値を outputs に設定する
      - name: set value
        id: set-value
        run: |
          echo "ref_name = ${{ github.ref_name }}"
          echo "GITHUB_RUNS_ON = ${{ env.GITHUB_RUNS_ON }}"
          echo "github_runs_on=${{ env.GITHUB_RUNS_ON }}" >> $GITHUB_OUTPUT
    outputs:
      github_runs_on: ${{ steps.set-value.outputs.github_runs_on }}
  call_demo_workflow:
    needs: init
    uses: ./.github/workflows/reusable.yml
    with:
      # ★ここで、runs-onの値を渡す
      runs_on: ${{ needs.init.outputs.github_runs_on }}

.github/workflows/reusable.yml

name: reusable

on:
  workflow_call:
    inputs:
      # ★引数としてもらってくる
      runs_on:
        description: runs on
        default: ubuntu-latest
        type: string

jobs:
  greeting:
    # ★引数でもらってきた値をそのまま設定する
    runs-on: ${{ inputs.runs_on }}
    steps:
      - id: message
        run: |
          echo "Hello world..."

関連記事

Github ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/07/18/234652
Github Actions ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/04/142835
Github Actions ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2022/06/16/151443
Github Actions ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2023/12/22/195715
Github Actions ~ workflow_run / workflow_call ~
https://dk521123.hatenablog.com/entry/2024/02/14/232546
Github Actions ~ if ~
https://dk521123.hatenablog.com/entry/2024/03/11/000000
Github Actions ~ 三項演算子
https://dk521123.hatenablog.com/entry/2024/06/20/234016
Github Actions ~ Self-hosted runners / 入門編 ~
https://dk521123.hatenablog.com/entry/2023/12/18/204119
Github Actions ~ Self-hosted runners / あれこれ編 ~
https://dk521123.hatenablog.com/entry/2024/02/07/002736
Amazon S3AWS CLI
https://dk521123.hatenablog.com/entry/2017/04/01/235355