「GitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する」オンライントレーニングを受講してみた
本記事では、Microsoft Learn の無料オンライントレーニング「GitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する」の内容を紹介します。また、トレーニング内容の一部が最新の GitHub の Web UI と異なる点についても共有します。
Microsoft Learn とは
Microsoft Learn は、Microsoft が提供する無料のオンライン学習プラットフォームです。個人や組織向けに、クラウド、AI、開発ツールなど幅広い技術トピックについて、実践的なトレーニングコンテンツを提供しています。
今回は GitHub Actions の基礎を学ぶべく初学者向けのトレーニングを受講しました。
トレーニングの概要
- URL: GitHub Actions を使用して継続的インテグレーション (CI) ワークフローを作成する - Training | Microsoft Learn
- 所要時間: 約 2 時間
- 難易度: 初級
- 前提知識: GitHub アカウントの所持、基本的な GitHub の操作、GitHub Actions の基本的な知識
学習内容
本トレーニングは以下の 2 つのパートで構成されています。
- 座学パート:
- GitHub Actions のワークフローの基礎理解
- 実技パート:
- CI 用のワークフロー作成
- ブランチの保護ルール設定
座学パート
座学パートでは、GitHub Actions ワークフローの基本を学びます。主な内容は以下の通りです。
- ワークフローのステップ構造
- アクションログの見方
- ジョブ間のデータ受け渡し方法
気になったところ
ステップ間での変数受け渡しについて理解を深めるため、以下の実験用ワークフローを作成し、動作検証しました。必要な説明はコメントに書きました。
name: Data Sharing Example
on:
push:
branches: [ main ]
jobs:
example-job:
runs-on: ubuntu-latest
steps:
- name: Step 1 - Set and export variable
# このステップ内でexportした変数は、このステップ内でのみ有効
run: |
export STEP1_MESSAGE="Hello from Step 1" # 環境変数に値をセット
echo "STEP1_MESSAGE is set to: $STEP1_MESSAGE" # 同じステップ内では変数の値を表示可能
- name: Step 2 - Try to access exported variable
# 異なるステップ間では環境変数は共有されないため、STEP1_MESSAGEは空
run: |
echo "Trying to access STEP1_MESSAGE: $STEP1_MESSAGE" # 出力結果は空になる
echo "As you can see, STEP1_MESSAGE is not accessible in this step"
- name: Step 3 - Share data using GITHUB_OUTPUT
# GITHUB_OUTPUTを使用することで、他のステップでこの値を参照可能になる
id: share # このステップにIDを設定し、後で参照できるようにする
env:
STEP1_MESSAGE: "Hello from Step 1" # 環境変数を再度設定
run: |
echo "step1_value=$STEP1_MESSAGE" >> $GITHUB_OUTPUT # GITHUB_OUTPUTを使用してデータを共有
echo "Data shared using GITHUB_OUTPUT"
- name: Step 4 - Access shared data
# 前のステップ(Step 3)で共有された値を参照する
run: |
echo "Accessing shared data: ${{ steps.share.outputs.step1_value }}" # steps.{step_id}.outputs.{output_name}の形式で参照できる
GitHub Actions の実行結果です。
同じワークフローを act を使用してローカル環境で実行も試してみました。GitHub Actions と同じ結果を得られました。
実行結果折りたたみ
$ act
INFO[0000] Using docker host 'unix:///var/run/docker.sock', and daemon socket 'unix:///var/run/docker.sock'
[Data Sharing Example/example-job] 🚀 Start image=ghcr.io/catthehacker/ubuntu:act-latest
[Data Sharing Example/example-job] 🐳 docker pull image=ghcr.io/catthehacker/ubuntu:act-latest platform=linux/amd64 username= forcePull=true
[Data Sharing Example/example-job] 🐳 docker create image=ghcr.io/catthehacker/ubuntu:act-latest platform=linux/amd64 entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Data Sharing Example/example-job] 🐳 docker run image=ghcr.io/catthehacker/ubuntu:act-latest platform=linux/amd64 entrypoint=["tail" "-f" "/dev/null"] cmd=[] network="host"
[Data Sharing Example/example-job] 🐳 docker exec cmd=[node --no-warnings -e console.log(process.execPath)] user= workdir=
[Data Sharing Example/example-job] ⭐ Run Main Step 1 - Set and export variable
[Data Sharing Example/example-job] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0] user= workdir=
| STEP1_MESSAGE is set to: Hello from Step 1
[Data Sharing Example/example-job] ✅ Success - Main Step 1 - Set and export variable
[Data Sharing Example/example-job] ⭐ Run Main Step 2 - Try to access exported variable
[Data Sharing Example/example-job] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/1] user= workdir=
| Trying to access STEP1_MESSAGE:
| As you can see, STEP1_MESSAGE is not accessible in this step
[Data Sharing Example/example-job] ✅ Success - Main Step 2 - Try to access exported variable
[Data Sharing Example/example-job] ⭐ Run Main Step 3 - Share data using GITHUB_OUTPUT
[Data Sharing Example/example-job] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/share] user= workdir=
| Data shared using GITHUB_OUTPUT
[Data Sharing Example/example-job] ✅ Success - Main Step 3 - Share data using GITHUB_OUTPUT
[Data Sharing Example/example-job] ⚙ ::set-output:: step1_value=Hello from Step 1
[Data Sharing Example/example-job] ⭐ Run Main Step 4 - Access shared data
[Data Sharing Example/example-job] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/3] user= workdir=
| Accessing shared data: Hello from Step 1
[Data Sharing Example/example-job] ✅ Success - Main Step 4 - Access shared data
[Data Sharing Example/example-job] Cleaning up container for job example-job
[Data Sharing Example/example-job] 🏁 Job succeeded
実技パート
実技パートでは、以下の 2 つの主要タスクに取り組みます。
- main ブランチへのマージ前に Markdown の品質チェックを自動化するワークフローの作成
- CI をパスしないとマージできないブランチ保護ルールの設定
以下は作成したワークフローの詳細です。
- Markdown Lint の実行
- アーティファクトのアップロード
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4
# Add Step 2
- name: Run markdown lint
run: |
npm install remark-cli remark-preset-lint-consistent
npx remark . --use remark-preset-lint-consistent --frail
# Add Step 3
- uses: actions/upload-artifact@v4
with:
name: remark-lint-report
path: remark-lint-report.json
ブランチの保護ルールの設定
GitHub の設定画面が最近更新され、テキスト内容と実際の UI 間に相違が生じています。以下に、現在の UI での推奨設定手順を示します。
ブランチ保護ルール設定後の動作確認
ブランチ保護ルールの設定が正しく機能しているかを確認するため、以下の手順で検証しました。
- 直接pushの試行
main ブランチに直接 push を試みました。以下のエラーメッセージが表示され、push が拒否されたことを確認しました。また、エラーメッセージから以下の 2 点が確認できました。
- 変更はプルリクエストを通じて行う必要がある
- "ci"という名前の必須ステータスチェックが期待されている
$ git push origin main
info: please complete authentication in your browser...
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 10 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 304 bytes | 304.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: Review all repository rules at http://github.com/bigmuramura/skills-test-with-actions/rules?ref=refs%2Fheads%2Fmain
remote:
remote: - Changes must be made through a pull request.
remote:
remote: - Required status check "ci" is expected.
remote:
To https://github.com/bigmuramura/skills-test-with-actions.git
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/bigmuramura/skills-test-with-actions.git'
- プルリクエストして変更
プルリクエストを作成し、CI ワークフローが正常に実行されることを確認しました。
- CI ワークフローが正常に実行され、パスしている
- すべての必要な条件が満たされ、マージが可能になっている
以上、トレーニングコースは終了です。
まとめ
このトレーニングを通じて、以下の点を学びました。
- GitHub Actions を用いた CI ワークフローの基本構造
- ブランチ保護ルールの重要性と設定方法
おわりに
GitHub CI/CD実践ガイドを読んでいました。ちゃんと手を動かした方がいいなと思いつつ、めんどくさがって動かさないことが多いので反省しました。今回は Microsoft Learn の GitHub Actions トレーニングをしながら書籍の内容も一緒に試してみて理解を深めています。勉強にはなりますがなかなかに時間がかかりますね。