GitHub Actionsのrun小ネタ3連発

GitHub Actionsを調べていたら面白そうな記述をいくつか見つけたのでブログにする。

シェルとしてPythonが使える

公式のドキュメントによると、bashpowershellなどのおなじみのシェルの中にpythonもいる。

docs.github.com

ということで確かめてみよう。

こんなworkflowを定義してみる。

Name: shell options demo

on: push
jobs:
  python:
    runs-on: ubuntu-22.04
    steps:
      - name: Run python
        shell: python
        run: |
          import sys
          print(sys.version)

実行結果は次の通り。

  import sys
  print(sys.version)
  shell: /usr/bin/python {0}
3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0]

正常にPythonが呼び出せたことが分かる。

github.com
執筆当時のGitHub Actionsのソフトウェア一覧にもPython3.10.6が入っていることが明記されている。

同じbashでも挙動が変わることがある

またもやshellネタである。

ドキュメントとにらめっこするとこんな記述がある。

set -eo pipefail を使うフェイルファスト動作: shell: bash が明示的に指定されていると、このオプションが設定されます。 既定では適用されません。

docs.github.com

shell:bashを指定すると挙動が変わるらしい。pipefailであればパイプ内のどれかが異常終了すると全体を異常終了させられる。
やってみた。

name: shell options demo

on: push
jobs:
  bash:
    runs-on: ubuntu-22.04
    steps:
      - name: Run Bash
        run: |
          false | echo 'error occurred'
          echo 'after error' # this command will be triggered
      - name: Run Bash with shell specification
        shell: bash
        run: |
          false | echo 'error occurred'
          echo 'after error' # this command will not be triggered

上のstepは1行目のパイプ内で異常終了しても2行目が実行されてしまう。

一方下のstepは1行目のパイプ内で異常終了しても2行目が実行されない。
嬉しい。

実際の実行結果も添付する。

  false | echo 'error occurred'
  echo 'after error' # this command will be triggered
  shell: /usr/bin/bash -e {0}
error occurred
after error
###############
  false | echo 'error occurred'
  echo 'after error' # this command will not be triggered
  shell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
error occurred

自由なカスタムシェル

実はshellは割と自由に設定できる。

ドキュメントを参照するとperlを使った例が出てくる。ドキュメントと同じことをやってもなぁと思って僕はdocker composeを呼び出してみることにした。

name: shell options demo

on: push
jobs:
  docker-compose:
    timeout-minutes: 1
    runs-on: ubuntu-22.04
    steps:
      - name: docker-compose
        shell: "docker compose -f {0} up"
        run: |
          services:
            connect:
              image: ubuntu:latest
              restart: always
              entrypoint:
                - "bash"
                - "-c"
                - "echo 'conn' > /dev/tcp/db/3306"
            db:
              image: mysql:latest
              environment:
                MYSQL_ALLOW_EMPTY_PASSWORD: yes

この定義をpushすると確かにdocker composeが動作する。

もはやシェルでも何でもない気がする。

まとめ

GitHub actionsではrunのshellを編集することができる。個人的に良かった点はshellとしてbashを指定したときの挙動の違いを知れたことだ。

やはりドキュメントは定期的に読んで知識を入れ直すべきであると感じた。

今回のWorkflowはGitHubに上げた。
もしより興味を持った人は覗いてもらえば。
github.com