Open14

GitHub Actions で学ぶシェル芸

雪猫雪猫

GitHub Actionsrun でシェルを実行していくのが基本です。
シェルに詳しければサードパーティアクションを使わなくて済んだり[1]、複雑なロジックを組まずに済んだりするので、改めてシェルを学ぶきっかけにいいのではないかと思いました。

ネタ募集。

脚注
  1. サードパーティアクションを使用するとセキュリティへの配慮が必要だったり、 Enterprise だと GitHub Connect の設定をしたり actions-sync したりしないといけなかったりするので意外と面倒です ↩︎

雪猫雪猫

変数展開

結構色々できます。

https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51

具体例 1

文字列の一部を除去。ブランチ名を取得。
branch-name でも refs/heads/branch-name でも branch-name が返ってきます。

      - run: git switch -C ${GITHUB_REF#refs/heads/}

https://github.com/snow-actions/sparse-checkout/blob/4646a92625178395db2afd88d3b763b48e6d4dc0/action.yml#L146

具体例 2

大文字を小文字へ変換。

      - name: Build
        run: docker build -t ghcr.io/${OWNER,,}/texturepacker:${VERSION} .
        env:
          OWNER: ${{ github.repository_owner }}
          VERSION: ${{ matrix.version }}

https://zenn.dev/snowcait/articles/b856ad712b9a32

雪猫雪猫

ファイルへの書き込み

具体例

      - name: 単行
        run: echo "line" > one-line.txt
      - name: 複数行
        run: |
          cat <<<EOF > multi-line.txt
          line1 
          line2 
          EOF
雪猫雪猫

GitHub API

GitHub CLI を使うとシンプルに書けます。

https://zenn.dev/snowcait/articles/0e430af5fb1e50

具体例

Pull request (PR) へコメント。

      - run: gh pr comment --body "Comment via GitHub Actions"
        env:
          GH_TOKEN: ${{ github.token }}
          GH_REPO: ${{ github.repository }}
雪猫雪猫

代替可能なアクション

actions/github-script

https://github.com/actions/github-script

      - uses: actions/github-script@v4
        with:
          script: |
            github.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'Comment via GitHub Actions'
            })

octokit/request-action

https://github.com/octokit/request-action

      - uses: octokit/request-action@v2.x
        with:
          route: POST /repos/{repository}/issues/{issue_number}/comments
          repository: ${{ github.repository }}
          issue_number: ${{ github.event.number }}
          body: Comment via GitHub Actions
        env:
          GITHUB_TOKEN: ${{ github.token }}
雪猫雪猫

ディレクトリがなければ作る

mkdir-p オプションを使うと if を書かずに済みます。

具体例

      - run: mkdir -p path/to/
      - run: pwd
        working-directory: path/to/
雪猫雪猫

if

具体例 1

空文字列の判定。

https://hacknote.jp/archives/32292/

      - name: 差分があったらエラー
        run: |
          DIFF=$(git diff --name-only)
          if [ -n "$DIFF" ]; then
            exit 1
          fi

具体例 2

exit code で判定。

https://zenn.dev/snowcait/articles/18c9137f49e378

      - name: 差分があったらエラー
        run: |
          if ! git diff --exit-code --quiet; then
            exit 1
          fi
      - name: 差分があったらエラー
        run: |
          git diff --exit-code --quiet
          if [ $? -ne 0 ]; then
            exit 1
          fi
雪猫雪猫

zcat, zgrep

圧縮されたファイルのまま catgrep をすることができます。

具体例

TODO: 思いついたら書く。

雪猫雪猫

git grep

Git 管理下のファイルを grep できます。

具体例

TODO: 思いついたら書く。

雪猫雪猫

一定時間待機

sleep コマンドが使えます。
秒数を指定しますが suffix を付けることもできます。

具体例

90秒待機
      - run: sleep 90
      - run: sleep 1m 30s
雪猫雪猫

条件で待機

while を使うことが多いかもしれませんが until コマンドもあります。
while の反対で条件式の終了コードが 0 ではない間ループします。

具体例

Docker コンテナが起動するまで待機。

      - run: |
          until [ "$(docker inspect --format='{{.State.Health.Status}}' $(docker-compose ps -q mysql))" = 'healthy' ]; do
            sleep 1s
          done