GitHub Actions入門の受講内容とハンズオンまとめ

こんにちは!男の柴犬2匹と共に暮らしている、ミンです。
今日は最近GitHub CommunityでアナウンスされたGitHub Certificationsの中から、GitHub Foundationsの最も基本的なハンズオンを試してみたので、その詳細とコースの内容について書いていきたいと思います。
はじめに
GitHub Certificationsでどんな資格があるかというと以下の通り、4つの資格が提供されています。(2024年4月現在)
各種資格の勉強法については、GitHub Trainingがコースを提供していますので、興味のある方はぜひチェックしてみてください。
早速提供されているコースの中から、GitHub Actions入門を受講してみたので、その内容とハンズオン詳細をシェアしたいと思います。
今回のハンズオンは全てGitHubのUI上で実施してるので、他のCLIツールなどは不要です。
GitHub Actions入門
私は英語版で受講しましたが、日本語版も提供されています。
GitHub Actions 英語
GitHub Actions 日本語
コースモジュールは以下の通りでした。
- GitHub Actions を使用して開発タスクを自動化する(49分)
- GitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する(1時間7分)
- GitHub Actions を活用して GitHub Packages に公開する(41分)
- カスタム GitHub アクションを作成して公開する(26分)
- GitHub Actions を使ったアプリケーションのビルドと Azure へのデプロイ(59分)
- 企業で GitHub Actions を管理する(37分)
これからは、最初の二つのモジュールが最も基本的な学習内容となっていますので、まずそちらを受講し、その中で印象に残った要点や知識を共有し、ハンズオンの内容について詳細を説明していきます。
モジュール:GitHub Actions を使用して開発タスクを自動化する(49分)
これからモジュールの中のタイトルごとに内容をまとめていきます。
GitHub Actions のコンポーネントを特定する
以下はコースにて紹介されていたGitHub Actionsのコンポーネントで、
画像の通り、ワークフロー、ジョブ、ステップ、アクションの4つのコンポネントがあり、ワークフローの中に一つ以上のジョブがあって、ジョブの中には一つ以上のアクションが入っているステップが含まれてるイメージです。ジョブ自体も”ランナ”に関連づけられるワークフローのセッションで、まとめるとジョブはマシンもしくはコンテナ上で実行できるようになってます。
GitHub Actions ワークフローを構成する
- 詳細の説明はコースに記載されてるので必要に応じて設定できるワークフローのトリガー方法だけをシェアします。
スケジュール化されたイベントに対して実行するワークフローを構成する
- cron構文でスケジュール時刻を設定してトリガーすることができる点は、他のCI/CDツールと同様に柔軟で便利ですね。
手動のイベントに対して実行するようにワークフローを構成する
- GitHub REST API を使用するか、GitHub のリポジトリ内で [アクション] タブの [ワークフローの実行] ボタンを選択することで、ワークフローを実行できます。
- また、GitHub の外部で発生するアクティビティに対してワークフローをトリガーするなど、さまざまな方法でワークフローをトリガーすることができます。
Webhook イベントに対して実行するワークフローを構成する
- GitHubで特定の Webhook イベントが発生したときにワークフローをトリガーすることもできますね。
- また、条件付きキーワードを使用することや、GitHub UI または GitHub API エンドポイントを叩いてワークフローを無効化および削除することもできるので、他の CI/CD ツールと同じように条件分岐を設定でき、柔軟にワークフローを構成できるのが便利ですね。
- ワークフローの実行を取り消す場合、すべてのジョブとステップが取り消されることに注意が必要です。
組織のテンプレート化されたワークフローを使用する
- 組織のGitHubリポジトリに定義されているワークフローテンプレートを使用して、組織全体の一貫性を確保することもできます。この機能を利用することで、組織で共通のワークフローを簡単に導入できるので便利ですね。
- さらに特定のバージョンのアクションを使用することもできるので便利ですね。
ここからはハンズオンです!
演習 - GitHub Actions を使用して基本的なコンテナー アクションを作成する
ここからは当モジュールのハンズオンに入ります。日本語版の案内はありますが、リポジトリと手順が英語版のため、わかりやすく実際にハンズオンを行った作業詳細も一緒に記載していきます。もしよろしければ、ぜひ一緒にハンズオンを試してみてください。
ハンズオン対象のリポジトリ:hello-github-actions

コースの指示に従い、README.mdに記載された手順に従って、"Start course"から進みます。"Start course"ボタンの下に記載されている通り、主要な項目は自動的に設定されたままで、Create repositoryに進みます。

Create repositoryをクリックした後、20〜30秒ほど待つと、リポジトリが作成されます。ここもREADME.mdに記載されている通り、進めていきます。
ここにワークフローについて簡単な説明が書いていありましたので引用します。
What is a workflow?: A workflow is a configurable automated process that will run one or more jobs. Workflows are defined in special files in the .github/workflows directory and they execute based on your chosen event. For this exercise, we'll use a pull_request event.
GitHub Repository : hello-github-actionsのREADME.mdより引用。
ワークフローとは何ですか?: ワークフローは、1 つ以上のジョブを実行する構成可能な自動プロセスです。 ワークフローは .github/workflows ディレクトリ内の特別なファイルで定義され、選択したイベントに基づいて実行されます。 この演習では、pull_request イベントを使用します。
⌨️ Activity: Create a workflow file
ブラウザーの新しいタブで同じリポジトリを開き、Pull Requests タブを選択して、New pull request をクリックし、新規作成します。(いきなりPRは新鮮ですね)

下記画像のように、base: mainとcompare:welcome-workflow を選択して、Create pull requestをクリック。

今回はハンズオンなので特に内容は書かず、README.mdの通り、Create pull requestをクリック。(下記画像)

今度はCodeタブに移動して、Branch: welcome-workflowを選択し、Create new fileをクリック。(下記画像)


.github/workflows
ディレクトリに移遷し、Add fileメニューからCreate new fileをクリック(下記画像)



下記画像の間中にある赤枠部分、Name your file に welcome.ymlを入力して、次のコンテンツを welcome.yml ファイルに追加し、Commit changesをクリック。(下記コードと画像)
name: Post welcome comment
on:
pull_request:
types: [opened]
permissions:
pull-requests: write

コミットメッセージはそのままにして、Commit directly to the welcome-workflow branchを選択して Commit Changesをクリック。

20秒ほど待ってリフレッシュすると同じリポジトリのREADME.mdの内容が更新されるのでみてみます。ここまでがGitHub Actionsの基本的なワークフローの作成方法でした。次は、ワークフローにジョブを追加していきます。
Step 2: Add a job to your workflow file
README.mdがStep 2: Add a job to your workflow fileに更新されているので、ここも引き続きREADME.mdに記載されている通り、やっていきます。

READMEの前半はStep 1で追加した.github/workflows/welcome.ymlの中身の説明があったので、以下の画像でその解説をコメントで書いてみました。

今回Step 2でジョブを追加するのでジョブの説明もありました。以下の通りです。
ジョブとは何ですか?: ジョブは、同じランナー上で実行されるワークフロー内の一連のステップです (ランナーは、トリガーされたときにワークフローを実行するサーバーです)。 ワークフローにはジョブがあり、ジョブにはステップがあります。 ステップは順番に実行され、相互に依存します。 コースの後半でワークフローにステップを追加します。 ジョブの詳細については、ジョブを参照してください。
GitHub Repository : hello-github-actionsのREADME.mdより引用。
これからはREADMEの通り、Step 2で最速かつ安価なジョブランナーubuntu-latestを使って "build" ジョブを追加していきます。
参考:ワークフローファイルを理解する
⌨️ Activity: Add a job to your workflow file
Step 1で作成したwelcome-workflowブランチの.github/workflows/welcome.yml
ファイルを以下の内容で書き換えて更新。
name: Post welcome comment
on:
pull_request:
types: [opened]
permissions:
pull-requests: write
jobs:
build:
name: Post welcome comment
runs-on: ubuntu-latest

そのままCommit changesをクリックして、welcome-workflowブランチに直接コミット。
20秒ほど待つとREADME.mdが更新されるので、リポジトリのREADME.mdを確認してみます。

Step 3: Add a step to your workflow file
Step 3: Add a step to your workflow fileに変わりました!

今回はステップ(step)を追加するので、簡単な説明もありました。
ステップとは何ですか?: アクション ステップは、ワークフロー ジョブが処理されるときに、指定された順序で上から下に実行されます。 次のステップを実行するには、各ステップが合格する必要があります。
GitHub Repository : hello-github-actionsのREADME.mdより引用。
各ステップは、実行されるシェル スクリプト、または実行されるアクションへの参照のいずれかで構成されます。 この文脈でアクション (小文字の「a」を含む) について話すときは、再利用可能なコード単位を意味します。 アクションについては「[アクションの検索とカスタマイズ](https://docs.github.com/ja/actions/learn-github-actions/finding-and-customizing-actions)」で確認できますが、ここではワークフロー ステップでシェル スクリプトを使用します。
⌨️ Activity: Add a step to your workflow file
これまでと同様にwelcome-workflowブランチの.github/workflows/welcome.yml
ファイルを以下の内容で書き換えて更新。
name: Post welcome comment
on:
pull_request:
types: [opened]
permissions:
pull-requests: write
jobs:
build:
name: Post welcome comment
runs-on: ubuntu-latest
steps:
- run: gh pr comment $PR_URL --body "Welcome to the repository!"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}

以下の注意点も記載されていたので、ご参考までに
注: 追加したステップでは、GitHub CLI (gh) を使用して、プル リクエストが開かれたときにコメントを追加します。 GitHub CLI がコメントを投稿できるようにするには、GITHUB_TOKEN 環境変数を、ワークフローの実行時に作成されるインストール アクセス トークンである GITHUB_TOKEN シークレットの値に設定します。 詳細については、「[自動トークン認証](https://docs.github.com/ja/actions/security-guides/automatic-token-authentication)」を参照してください。 PR_URL 環境変数を新しく作成したプル リクエストの URL に設定し、これを gh コマンドで使用します。
GitHub Repository : hello-github-actionsのREADME.mdより引用。
そのままコミットし、20秒ほど待ってリポジトリのREADME.mdを確認してみます。

Step 4: Merge your workflow file
Step 4: Merge your workflow fileに変わりましたので、続きやっていきます。

今回はwelcome-workflowをmainブランチにマージします。
⌨️ Activity: Merge your workflow file
Step 1で作っていたプルリクエストを開いてMerge pull request > Confirm mergeをクリック。


今回も20秒ほど待ってリポジトリのREADME.mdを確認してみます。
Step 5: Trigger the workflow
Step 5: Trigger the workflowに変わりました。

これでwelcome.ymlのワークフローがmainブランチにマージされましたので、これからはプルリクエストが作成されるたびに実行されるようになります。これからはワークフローを実行させてみましょう。
これまで実行されたワークフローアクションの確認方法についても、以下のような記載がありましたので、Actions画面を見てみましょう。
アクションの動作を確認する: トリガーされた各ワークフロー実行のステータスは、マージされる前のプル リクエストに表示されます。以下のステップを試すと、「すべてのチェックがパスしました」を探します。 リポジトリの [アクション] タブでは、実行中または実行が終了したすべてのワークフローのリストを確認することもできます。 そこから、各ワークフロー実行をクリックして詳細を表示し、ログ ファイルにアクセスできます。
GitHub Repository : hello-github-actionsのREADME.mdより引用。

⌨️ Activity: Trigger the workflow
今回は test-workflow ブランチを新規作成し、README.mdの例の通り、README.mdに絵文字を追加してプルリクエストを作成してみます。ここではGitHubのUIからブランチ作成とプルリクエストを作成してみます。




test-workflowブランチが選択されていることを確認し、README.mdに絵文字を追加し、"Create pull request"をクリックしてプルリクエストを作成します。今回はシンプルに ":computer:" 絵文字を追加して、変更をコミットします。



プルリクエスト作成ができたら、自動でコメントがつくようになりました!(下記画像)

この状態で20秒ほど待つとREADME.mdが更新されるので確認します。

ハンズオンの終わり
これでGitHub Actionsが問題なく動作していることが確認できたました。
このハンズオンでは、GitHub Actionsワークフローファイルの簡単な作成方法とワークフローのトリガー方法を理解できました。これにより、GitHub Actionsの基本的な使い方を学ぶことができました。
ここまででGitHub Actions を使用して開発タスクを自動化する(49分)の内容を終えました。
モジュール:GitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する(1時間7分)
次はGitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する(1時間7分)モジュールをやっていきます。モジュールの内容は日本語版にも記載されているので、気になるポイントだけシェアしていきます。
このモジュールでは、GitHub リポジトリで GitHub Actions とワークフローを使用して継続的インテグレーションを実装する方法を学習できます。
学習内容は次のとおりです。(ページから引用)
GitHub Actions を使用して CI のワークフローを作成するには
学習内容は次の通りでした。
GitHub Actions を使用して CI のワークフローを作成するにはより引用
- テンプレートからワークフローを作成する
- GitHub Actions ログを理解する
- 複数のターゲットに対してテストする
- ビルドとテストのジョブを分離する
- ビルド成果物を保存してアクセスする
- レビューでの PR のラベル付けを自動化する
テンプレートからワークフローを作成するの中で成果物と成果物ストレージが気になりました。

さらに詳しくはこちらをご参照ください:ワークフロー データを成果物として保存する
ワークフローを使用して GitHub のレビューを自動化するで利用したいシナリオに合わせてワークフローをトリガーさせることができるのは大変参考になりました。さらに、以下のように
- レビュー担当者が pull request を承認した後にのみ、ワークフローを実行させる
- レビュー担当者の数を変数として設定し、その人数分の承認が得られてからワークフローを実行させる
- pull request にラベルを追加するようにリマインドする
- またラベルがつけられてから別のワークフローを実行させる
。。。などの、デベロッパーチームとしてのルールもワークフローで自動化することができるのはとても便利ですね。
環境変数と成果物データを使用してワークフローをカスタマイズする
ここでは、既定およびカスタムの環境変数、カスタム スクリプト、キャッシュ依存関係を使用して、ジョブ間で成果物データを渡す方法について説明します。また、GitHubのウェブサイトとREST APIエンドポイントの両方からワークフローログにアクセスする方法についても説明されています。
既定の環境変数とコンテキスト
- 既定の環境変数(デフォルト環境変数)は、ジョブを実行しているランナー内でのみ使用でき、すべて大文字で書かれます。
- 一方、コンテキストはワークフロー内のどの部分でも利用でき、すべて小文字で書かれます。
カスタム環境変数
- カスタム環境変数は、ワークフローファイル内で定義され、env コンテキストを使用します。
- ランナー内では、$を使ってカスタム環境変数を参照できます。
キャッシュ アクションを使用して依存関係をキャッシュする
- 別のワークフローの実行から依存関係をGitHubのcacheアクションでキャッシュすることで、ワークフローの実行速度と効率を向上させることが可能です。
ジョブ間で成果物データを渡す
- キャッシュと同様に、upload-artifactとdownload-artifactアクションを使用して、同じワークフロー内のジョブ間でデータを渡すことが可能です。
ワークフローでステップ デバッグ ログを有効にする
- 場合によっては、既定のワークフローログでは、特定のワークフローの実行、ジョブ、またはステップが失敗した原因を診断するのに十分な詳細情報が得られない場合があります。そのような場合、"実行"と"ステップ"の2つのオプションについて、追加のデバッグログを有効にすることができます。
ここからはハンズオンです!
演習 - GitHub で CI ワークフローを作成する
ここもハンズオンなので、作業詳細を記載していきます。
ハンズオン対象のリポジトリ:test-with-actions
コース記載の通り、README.mdに従って、Start courseからやっていきます。

今回もデフォルトで入力される値のまま、Create repositoryに進めます。
リポジトリ作成ができたらREADME.mdに従って、やっていきます。

Step 1: Add a test workflow
README.mdのイントロに以下の通り、CIの簡単な説明もありました。
継続的インテグレーション(Continuous integration)とは何ですか?: [継続的インテグレーション]()は、テストを実行し、GitHub で結果を報告することで、チームの品質基準を遵守するのに役立ちます。 CI ツールは、コミットによってトリガーされてビルドとテストを実行します。 品質結果はプル リクエストで GitHub にポストバックされます。 目標は、メインの問題を減らし、作業中のフィードバックを迅速化することです。
GitHub Repository : test-with-actionsのREADME.mdより引用。
その他参考:ギットハブ アクション のワークフロー構文
⌨️ Activity: Add a test workflow
README.md記載の通り、テストワークフローを作成していきます。
リポジトリのActionsタブに移動し、New workflowをクリック。

"Simple workflow"を検索して、"Configure"をクリック。

ワークフロー名に ci.yml を指定して、画像のようにステップ(step)の最後の2つを削除して、以下の内容を追加して、ciという新しいブランチに設定。

ciブランチを指定した後、Propose changesをクリック。
そのままCreate pull requestをクリックしてプルリクエストを作成。
README.mdにも記載されていますが、この段階ではワークフローが失敗しますので、次のステップで修正していきます。

リポジトリのActionsタブでワークフローが失敗していますね。
裏でREADME.mdが更新されるので確認します。

Step 2: Fix the test
先ほど失敗したテストワークフローを修正していきます。
⌨️ Activity: Fix the test
今回はなぜテストワークフローが失敗したのか、自分でログを確認して修正する必要があります。修正したらコミットし、README.mdが再度更新されます。
早速失敗したワークフローのログをみていきましょう。
最後にActionsタブで確認した失敗したワークフローのログの中身を確認してみます。

この後、エラーの部分を確認して修正していきますが、読者の皆さんも先に自分で解決を試みてみてくださいね。
エラーの内容は以下の赤枠の通りですね。

おお!18行目には、エラーが検出された対象のファイル名である resume.md が記載されていますね。後続のエラー内容に合わせて、このファイルを修正していきます。
19行目には、warningとして "Unexpected emphasis marker *, expected _" と記載されていますね。つまり、アスタリスクではなくアンダースコアを使うべきということですね。
21行目はinfoなので、今回は気にしなくて問題ありません。
それでは、早速resume.mdを修正し、コミットしてみましょう。 ちなみに、今のハンズオンで作成したワークフローファイルはciブランチ上で作成しているので、resume.mdもciブランチ上のものが対象ですね。
resume.mdファイルを開いて、編集します。

エラー内容に書いてある通り、resume.mdの9行目には*Git*という記述があるので、これを _Git_に修正して、コミットします。
12行目にも”見つけたね”のコメントがありますね。_Git_に修正して、コミットします。

念の為、ここがciブランチにコミットされることを確認。

Actionsタブでワークフローも無事完了してることが確認できました。
コミット後、20秒ほど待ってリポジトリのREADME.mdを確認してみます。

Step 3: Upload test reports
README.mdがStep 3: Upload test reportsに変わったので、続きやっていきます。
ここではupload-artifactを使って他のジョブ実行結果の成果物を特定のジョブに渡すことを学びます。
⌨️ Activity: Upload test reports
先ほど作成して ci.ymlワークフローファイルを修正します。ブランチは ciですね。

ビルドジョブの "Run markdown lint" ステップを、vfile-reporter-jsonを使用するように変更し、その結果を remark-lint-report.json に出力します。(以下画像の青線の部分のオプションが変更対象ですね)


その次に新しいbuildジョブも追加し、upload-artifactアクションを使用するステップを追加します。
追加するステップで先ほど修正したRun markdown lintで生成された成果物ファイルをアップロードします。
upload-artifactの書き方詳細は@actions/upload-artifactREADME.mdをご参照ください。

こんな感じで修正ができたら、コミットしてREADME.mdが更新されるのを待ちます。

ちなみに今回のハンズオンでは含まれていないが、新規で作成したbuildジョブでアップロードされた成果物ファイルはdownload-artifactを使ってダウンロードすることが可能です。
Step 4: Add branch protections
Step 4: Add branch protectionsに変わったので、続きやっていきます。

現在、作成中のプルリクエストは誰もレビューしておらず、それにもかかわらず下記画像のようにマージが可能な状態になっています。そのため、今後はレビューが未完了のものやワークフローステータスが失敗したプルリクエストなど、自動的にマージできないようにブランチを保護していきます。

⌨️ Activity: Add branch protections
まずはブランチの設定を変えます。
リポジトリの上の方のあるSettings > Branches > Add branch protection ruleをクリック。

Branch protection rule settingsを以下の通り設定して、Createをクリック。

設定内容としては
- Branch name patternは保護したいブランチの名前
- Protect matching branchesの配下の項目は
- Require a pull request before merging (今回は一人でハンズオンなのでレビュアはいないため、Require approvalsはチェックを外します。)と
- Require status checks to pass before merging にチェック入れて、画像の通り、設定ができたら Createをクリックして完了。
今回のハンズオンでは、上記の設定を行いますが、実際の開発ではレビュアーの人数を設定し、レビューを通過しないとマージできないようにするなど、さまざまなパターンで設定することができますので、ぜひ使ってみてください。
ブランチの設定が完了したら、リポジトリのREADME.mdを確認してみましょう。
Step 5: Merge your pull request

先ほどのプルリクエストをマージしていきます。
⌨️ Activity: Merge your pull request
作成したプルリクエストを開いて、Merge pull requestをクリックして、Confirm mergeをクリック。

README.mdが更新されて、今回のハンズオンを終えました。

ハンズオンの終わり
このハンズオンでは以下の内容を学びました。
- Markdown ファイルを lint するためのアクション ワークフローを作成。
- ワークフロー実行結果からファイル内で問題を発見し、mainブランチに反映される前に問題を修正。
- テスト レポートにビルドした成果物をアップロードさせて使用する方法。
- ブランチ保護を有効にして、マージ前にワークフローの通過を要求。
今後も色々な場面で実践していきたいですね。
最後に
ここまでが GitHub Actions コレクションのモジュール6つのうち以下2つの基礎となるモジュールとハンズオンをやってみました。
最後までお付き合いいただき、ありがとうございました!この記事が読者の皆さんに少しでも参考になれば嬉しいです。
引き続き、よろしくお願いいたします。