[GitHub/YAML]GitHubActionsで作業を自動化しよう[前半]

GithubActionsGitHub

どうも。Kenny(https://twitter.com/tsujikenzo)です。ケニーの進化が止まらないです。 このシリーズでは 「GitHubActionsで作業を自動化しよう」をお送りしています。

前回は、GitHub Actionsのワークフローを記述する「YAMLファイル」について解説しました。pushをきっかけに、かんたんなメッセージをログに出力するワークフローを作成しましたね。

今回は、YAMLファイルの中身を一つ一つ分解し、それぞれの役割と、できることを詳しく解説していきます。

おさらい

前回作成した greeting.yml を、もう一度見てみましょう。

# ワークフローの名前
name: はじめての自動化

# ワークフローが動き出す「きっかけ」
on:
  push:

# 実行される「作業」
jobs:
  # 作業の塊に名前を付ける
  show-message:
    # 作業する場所を指定(おまじないでOK)
    runs-on: ubuntu-latest

    # 具体的な「手順」
    steps:
      # 手順に名前を付ける
      - name: "メッセージをログに出力します"
        # 実際に実行するコマンド
        run: echo "ファイルがPUSHされました!"

この短いコードの中に、GitHub Actionsを動かすための重要な要素が詰まっています。

今回は、on, jobs, steps, run の4つのキーワードを深掘りしていきます。

【on:】自動化の「きっかけ」を自由に設定する

on: は、ワークフローが動き出す「きっかけ(イベント)」を指定する部分です。

前回は push: とだけ書きましたが、実はもっと細かく条件を指定できます。

特定のブランチだけに反応させる

例えば、「main ブランチにプッシュされた時だけ動かしたい」という場合は、branches: を使います。

on:
  push:
    branches:
      - main  # mainブランチに限定

逆に、「main ブランチ以外にプッシュされた時に動かしたい」という場合は、branches-ignore: を使います。

on:
  push:
    branches-ignore:
      - main  # mainブランチは無視

feature/** のようにワイルドカードを使って、「feature/ で始まる名前のブランチ全て」といった指定も可能です。

プルリクエストをきっかけにする

push だけでなく、「プルリクエストが作成されたとき」を、きっかけにすることもできます。

on:
  pull_request:
    types: [opened, reopened] # PRがオープンまたは再オープンされたとき
    branches:
      - main # mainブランチへのPRに限定

schedule (cron) で定期実行する

push や pull_request のような操作がなくても、決まった時間に自動でワークフローを実行させることができます。これには cron(クロン) という、サーバーの世界で古くから使われているスケジュール設定の書式を使います。

on:
  schedule:
    # cron: '分 時 日 月 曜日' (UTC: 協定世界時)
    - cron: '0 18 * * *' # 毎日18:00 (UTC) に実行

cronの読み方:

  • (アスタリスク) は「毎〜」を意味します。
  • 左から順番に「分・時・日・月・曜日」を表します。
cron: '0 18 * * *'→ 0分、18時、毎日、毎月、毎日曜日 → つまり「毎日18時0分」に実行されます。

※注意: この時刻はUTC (協定世界時) です。日本時間 (JST) はUTCより9時間
進んでいるので、この設定は日本時間の午前3時 (18 + 9 - 24) に実行されます。
cron: '0 0 * * 1'→ 0分、0時、毎日、毎月、月曜日 → 「毎週月曜日の午前0時 (UTC)」に実行されます。
(日本時間では月曜の朝9時)

GASの時限トリガーのように、定期実行ができるのは便利ですね。以下のような使い方ができると思います。

  • ウェブサイトのリンク切れを毎晩チェックする。
  • 毎週月曜の朝に、チームに進捗確認のリマインダー(イシュー)を自動で作成する。
  • 毎日、外部のデータを取得してレポートを更新する。

このように、on:の設定を使いこなすことで、「いつ、自動化を動かすか」を非常に柔軟にコントロールできるようになります。

【jobs:】作業の「かたまり」を定義する

jobs: は、実際に行う「作業」を定義するセクションです。jobs: の下には、一つ以上の「ジョブ」を定義します。

前回は show-message: というジョブを一つだけ作りました。

ジョブは、それぞれ独立した仮想環境(ランナー)で実行されます。(仮想環境については後述します)

例えば、「テストするジョブ」と「ウェブサイトを公開するジョブ」のように、関連性の低い作業を別のジョブとして定義することができます。

# ~中略~
jobs:
  test: # 「テスト」という名前のジョブ
    #実行環境の指定(おまじない)
    runs-on: ubuntu-latest
    steps:
      - run: echo "テストを実行します..."
  
  deploy: # 「デプロイ」という名前のジョブ
    #実行環境の指定(おまじない)
    runs-on: ubuntu-latest
    # needs: test テストジョブが終わってから実行する、という依存関係も作れる
    steps:
      - run: echo "デプロイを実行します..."

今回はジョブは一つだけで進めますが、「作業の大きな単位を定義するのが jobs:と覚えておけばOKです。

【steps:】具体的な「手順」を順番に書く

jobs: で大きな「作業」を決めたら、次はその作業をこなすための具体的な「手順」を steps: の中に記述していきます。

steps: は、複数のステップ(手順)をリスト形式で並べたものです。

各ステップは – (ハイフン) から始まり、上から順番に一つずつ実行されます。

各ステップには、name: を使って分かりやすい名前を付けることができます。これは、後で実行ログを確認する際に、「今どの手順を実行しているのか」が一目でわかるようになるので、必ず付けるようにしましょう。

# ~中略~
jobs:
  show-info:
    runs-on: ubuntu-latest
    # steps: は、このジョブの「手順リスト」の始まりを示します
    steps:
      # - から始まるのが1つの「手順」
      - name: "手順1: 最初の挨拶"
        run: echo "作業を開始します!"

      # - から始まる、これが2つ目の「手順」
      - name: "手順2: ファイル一覧を表示"
        run: ls -la

      # - から始まる、これが3つ目の「手順」
      - name: "手順3: 完了の挨拶"
        run: echo "作業が完了しました!"

このように、steps: の中に複数の – name:run: のペアを並べることで、一連の連続した処理を定義できます。

【run:】実際に実行するコマンドを記述する

run: は、各ステップで実際に実行したいコマンドを記述する部分です。

ここに書かれた内容は、インターネットの向こう側にある、GitHubが貸してくれる一時的なパソコン(仮想サーバー)上で実行されます。

コマンドが実行される場所:【ランナー】

ここで少し、jobs: のセクションで出てきた「仮想環境(ランナー)」について説明しましょう。

YAMLファイルで runs-on: ubuntu-latest と書きましたよね。

これは、「GitHubさん、この作業のためにインターネットの向こう側で、最新のLinux (Ubuntu) が入ったまっさらなコンピュータを1台用意してください!」とお願いしている、という意味です。

この一時的に用意されるコンピュータのことを ランナー (Runner) と呼びます。

そして、run: に書かれたコマンドは、このランナーの中にある「ターミナル(黒い画面)」で実行されるのです。

runs-on: ubuntu-latest (Linux) を指定した場合、run: には echo (文字の表示) や ls (ファイル一覧) のような、Linuxの基本的なコマンドを書くことができます。

つまり、run: とは、「このランナーのターミナルで、このコマンドを打ち込んで実行してね」という、具体的な指示そのものなのです。

ランナーには、macOSやWindowsOSの指定もできるようですが、ここでは割愛します。

複数行のコマンドを実行する

一つのステップの中で、複数のコマンドを順番に実行したいばあいは、まずrun: の後に | (パイプ記号) を付けます。

そして、次の行からインデントして、コマンドを並べます。

# ~中略~
- name: "複数行のコマンドを実行するステップ"
        run: |
          echo "1行目のコマンドです。"
          echo "現在の場所は..."
          pwd  # 現在のディレクトリパスを表示
          echo "ファイルとフォルダの一覧は..."
          ls -la  # ファイル一覧を詳しく表示
          echo "3行目のコマンドでした。"

|(パイプ記号) を使うと、その下のインデントされたブロック全体が、一つのスクリプトとして実行される、と覚えておきましょう。

かんたんなスクリプトを直接埋め込む

シェルコマンドだけでなく、かんたんなPythonやJavaScriptのコードを直接実行することも可能です。

これは、わざわざファイルを作成するまでもない、ちょっとした処理を行いたい場合に便利です。

# Pythonの例:
- name: "Pythonで現在時刻を表示"
   run: python -c "import datetime; print(f'Pythonからのメッセージ: 現在の日時は {datetime.datetime.now()} です')"
# JavaScript (Node.js) の例:
- name: "JavaScriptで簡単な計算"
   run: node -e "console.log('JavaScriptからのメッセージ: 1 + 2 は ' + (1 + 2) + ' です')"

このように、run: を使えば、シェルコマンドからかんたんなスクリプトまで、さまざまな処理を実行させることができます。

ただし、乱用は禁物です。

【ハンズオン】YAMLの定期実行で、毎日天気予報を教えてもらおう!

さて、ここまでのまとめとして、実用的な自動化処理に挑戦してみましょう。

schedule (cron) と run を使って、「毎日決まった時間に、東京の天気予報を取得してログに出力する」ワークフローを作成します。

今回は、無料で使える天気予報API wttr.in を利用します。

ステップ1: 新しいワークフローファイルを作成する

前回作成した greeting.yml とは別に、天気予報用の新しいワークフローファイルを作成します。

ファイル名: .github/workflows/weather-forecast.yml

ステップ2: 天気予報を取得するYAMLを書く

作成した weather-forecast.yml に、以下の内容をコピー&ペーストしてください。

# ワークフローの名前
name: 毎日の天気予報

# ワークフローが動き出す「きっかけ」
on:
  # スケジュール実行
  schedule:
    # 毎日22:00 (UTC) に実行します
    # 日本時間では午前7時です (22 + 9 - 24 = -2 + 24 = 22 -> 22+9 = 31 -> 31-24 = 7)
    # 日本時間では午前7時です (22 + 9 = 31 -> 31 - 24 = 7時)
    - cron: '0 22 * * *'
  # 手動でも実行できるように workflow_dispatch を追加
  workflow_dispatch:

# 実行される「作業」
jobs:
  # ジョブの名前
  get-weather-forecast:
    # 作業する場所
    runs-on: ubuntu-latest

    # 具体的な「手順」
    steps:
      - name: "東京の天気予報を取得して表示します"
        run: curl wttr.in/Tokyo?lang=ja&format=4

このワークフローのポイント解説

  • 【on:】schedule: – cron: ‘0 22 * * *’: 毎日22:00(UTC)、つまり日本時間の朝7時にこのワークフローが自動で実行されるようにスケジュールを設定しました。これで、毎朝の天気予報チェックが自動化できますね!
  • 【on:】workflow_dispatch: これを追加しておくと、「Actions」タブから手動でこのワークフローを実行できるようになります。定期実行の時間まで待たずに、すぐに動作確認ができて非常に便利です。
  • 【run:】curl wttr.in/Tokyo?lang=ja&format=4 curl は、指定したURLにアクセスして、その内容を取得してくるコマンドです。
  • wttr.in/Tokyo は、東京の天気予報を提供してくれるウェブサービスのURLです。
  • ?lang=ja&format=4 は、表示を「日本語」で「シンプルな一行形式」にするためのオプションです。

ステップ3: 保存して、手動で動かしてみよう!

  1. 作成した weather-forecast.yml を main ブランチにコミットして保存します。
  2. 「Actions」タブを開きます。
  3. 左側のワークフロー一覧から「毎日の天気予報」をクリックします。
  4. 「This workflow has a workflow_dispatch event trigger.」というメッセージの右側に、「Run workflow」というボタンが表示されているはずです。 「Run workflow」ボタンをクリックします。 

ステップ4: 実行ログを確認する

実行が完了したら、実行履歴をクリックし、get-weather-forecastジョブ(タイトル:毎日の天気予報)をクリックします。 

「東京の天気予報を取得して表示します」のステップを展開すると、以下のように東京の天気予報が表示されているはずです! 

これで、GitHub Actionsを使って、外部の情報を定期的に取得する自動化をマスターしました!

まとめ

以上です。今回は、YAMLファイルの主要な構成要素である on, jobs, steps, run を詳しく解説し、schedule を使った定期実行のハンズオンも行いました。

run: の中に書くコマンドを変えるだけで、アイデア次第で様々なことができる、という可能性を感じていただけたのではないでしょうか。

次回はいよいよ、他の人が作った便利な部品「アクション」を uses: で呼び出し、プルリクエストの自動作成に挑戦します。

シリーズのクライマックスです、お楽しみに!

このシリーズの目次

[GitHub/YAML]GitHubActionsで作業を自動化しよう[前半]

[ハンズオン]はじめてのYAMLでGitHub Actionsを動かしてみよう!

タイトルとURLをコピーしました