前置き
この記事はGitHub Actions Advent Calender 2020の20日目の記事です。昨日は@taptappunさんの記事でした。
概要
GitHub Actions誕生までの歴史、GitHub Actionsの用語や環境について記載しています。GitHub Actionsにはクラウド版とオンプレミス版がありますが、この記事ではオンプレミス版の説明は省きます。
間違っている箇所がある場合はご指摘をお願いします。
GitHub Actionsとは
GitHubの公式ドキュメントから抜粋します。
GitHub Actionsは、コードを保存するのと同じ場所でソフトウェア開発のワークフローを自動化し、プルリクエストやIssueで協力することを支援します。 個々のタスクを書き、アクションを呼び出し、それらを組み合わせてカスタムのワークフローを作成できます。 GitHub Actions では、エンドツーエンドの継続的インテグレーション (CI) と継続的デプロイメント (CD) 機能をリポジトリに直接ビルドすることができます。
Using GitHub Packages with GitHub Actions
この文章をまとめると、GitHub ActionsはGitHubに備わっているPull RequestやIssueなどの機能をトリガーにして、ビルド、テスト、デプロイなどをワークフローとして作成・実行できるツールとなります。
GitHub Actions誕生までの歴史
GitHub Actionsは2018年10月16日〜17日に開催されたGitHub Universeで発表されました。また、翌年のGitHub UniverseでGitHub Actionsが正式版となりました。この10年前の2008年4月10日にGitHubの正式版が発表されています。
そのため、GitHubが登場してからGitHub Actionsの登場までの10年間、世界とGitHubで何が起きていたか、年表に表してみることにしました。なおGitHubのイベントについては、GitHub10周年ページの翻訳サイトがあり、そこから引用しています。
GitHubの10周年ページを簡単に翻訳してGitHubの歴史を振り返ってみた
世界とGitHubの変遷
歴史から見えること
個人の考察です。
Dockerの登場、CNCFの設立、Kubernetesの登場により一気にコンテナ技術が発展してきました。またCNCFの設立により、コンテナ周りのテクノロジーが急速に増えてきました。これにより、開発者はコンテナをメインとした開発、CI/CD運用に移行していったと思われます。
また、GitHubにおいてはユーザ数が増加し、有名なプロジェクトのOSS化が行われてきました。またPull Requestによるマージが1億回を突破したことから、GitHub上でのユーザの活動が非常に活発になっていたと考えられます。
なぜGitHub Actionsが誕生したのか
GitHubが抱えていた問題
詳しい説明がGitHubの新機能「GitHub Actions」でワークフローを自動化しようにありましたので、一部抜粋して説明します。
ソフトウェア開発を取り巻く環境は日々変化し、様々なツールやライブラリが次々と登場する時代がやってきました。
・・・中略・・・
一方で新しいツールができることや、それらを正しく連携させるための設定はどんどん複雑化し、本来の目的だったソフトウェア開発のために十分な時間を取れないといったケースが増えています。
開発を便利に楽にするためのツールが、逆に開発の時間をとられてしまうという逆転の現象が起きてしまったようですね。これらのツールがどのくらいあるのか、CNCFが作成している代表的なクラウド関連テクノロジー一覧を記事の中で紹介されていましたので、改めて確認してみました。
[CNCF Cloud Native Interactive Landscape ](https://landscape.cncf.io/)※2020/12/02に取得しました。この図を見ると、上記記事が執筆された2019年4月5日時点よりもさらにツールが増加していることが分かります。この大量のツールが登場したことによる問題を、記事では次のように伝えられています。
ソフトウェアのソースコードを一定の品質に保ちつつ速いサイクルで開発・デプロイするために、現代ではこれだけ多様な技術が使われるようになりました。テスト、ビルド、デプロイのパターンだけでも多くの選択肢があり、その他のツールの利用も含めると組み合わせは無限にあります。苦労してプロジェクトに最適な組み合わせを見つけ、ワークフローを作り上げたとしても、今まではそれをコードとして記述するスタンダードな方法がなかったので、GitHub上で共有したり再利用することができないという問題がありました。
GitHubの利用形態について分析すると、全ユーザの約60%がリポジトリと何らかの外部ツールやサービスを連携させている、という結果がわかっていました。そこでGitHubでは、ソフトウェア開発のプラットフォームとしてこの問題を解決し、開発者の体験をより良いものにするにはどうしたらいいか考え、2018年10月にGitHub Actionsを発表しました。
GitHub Actionsがない時代では、他プロジェクトのワークフローを参考に組み立てたいと思っても、再現させるのは一苦労だったのでしょうね。
GitHubのミッションとして
GitHub’s mission is to help every developer—regardless of experience level—learn, code, and ship software effectively.
At GitHub, our mission is to build the global platform for developer collaboration
を掲げられている視点から見ると、GitHub Actionsの誕生は必然だったとも思えそうです。
GitHub Actionsでできること
GitHub Actionsは、GitHubのイベントをトリガーとして、コードのチェックアウトやビルドといった一連のコマンドを実行できます。一連のコマンドは以下のコードのようにYAML形式で定義できます。
以降、このコードをもとに各用語やできることを説明します。
サンプルコード:
name: Ruby
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rake
ワークフロー
ワークフローは、後述するジョブが1つ以上存在している自動可能プロセスです。このワークフローをYAML構文で記載したYAMLファイルがワークフローファイルとなります。ワークフローファイルをProject名/.github/workflows/
に置くことで、GitHub Actionsが動作します。
さきほどのサンプルコードがワークフローであり、そのワークフローにはイベント、ジョブ、ステップ、アクションが含まれています。これらの用語について説明します。
イベント
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
イベントは、ワークフロー実行のトリガーとなるGitHubのアクティビティです。また、指定イベントが指定ブランチで発生したときにワークフローを実行させることも可能です。主なイベントして、pull_request、issue、scheduleがあり、2020/12/09時点で30個のイベントがあります。各イベントについては、GitHubの公式ドキュメントを参照してください。
GitHub Docs ワークフローをトリガーするイベント
サンプルワークフローでは、push
イベントがmain
ブランチで発生したとき、もしくはpull_request
イベントがmain
ブランチで発生したときに、ワークフローを実行します。
ジョブ
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rake
ジョブは同じ仮想環境上で実行されるステップの集合であり、ジョブごとに仮想環境の新しいインスタンスで実行されます。ジョブはruns-on
で指定した環境で実行されます。指定可能な環境は、後述する「Cloud hostsのリソース」の環境に記載しています。
ジョブはデフォルトでは並列で実行され、needs
オプションをつけることで、あるジョブの後に別のジョブを実行することもできます。
GitHub Docs GitHub Actionsのワークフロー構文 jobs.<job_id>.needsから抜粋したコード:
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]
サンプルワークフローでは、test
と名付けられた1つのジョブが定義されており、ubuntu-latest
(Ubuntu 18.04)上でジョブが実行されます。
ステップ
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rake
ステップは、後述するアクションやコマンドなどを実行できる個別のタスクです。ステップはジョブ内に1つ以上必要です。ジョブ中の各ステップは同じ仮想環境で実行されるため、ジョブ内のアクションはファイルシステムを利用して情報共有可能です。ただし、各ステップは別プロセスとして動くので注意が必要です。
サンプルワークフローでは、ステップは1つのみ定義されており、Rubyのセットアップ、依存関係のインストール、テストの実行タスクの3つを含んだタスクとなっています。
アクション
- uses: actions/checkout@v2
uses: ruby/setup-ruby@v1
アクションはステップ内の個々のタスクとなります。GitHub公式のアクションやサードパーティのアクション、独自作成したアクションを使用可能です。
サンプルワークフローでは、GitHub公式が提供しているactions/checkout@v2
、サードパーティのアクションであるrubyのruby/setup-ruby@v1
を使用して、コードのチェックアウト、Rubyのセットアップを行っています。
アクションの種類
アクションには以下の3種類があります。
- GitHubが提供するアクション
GitHubが提供するアクション一覧は、さくらインターネットさんがブログでまとめられています。
GitHubの新機能「GitHub Actions」で試すCI/CD - GitHub Marketplaceで公開された3rd Partyのアクション
AmazonやDockerなどがGitHub Actionsで使用できるアクションを提供しています。
GitHub Marketplace Actions - 独自定義のアクション
独自にアクションを定義して使用することもできます。定義できるアクションは、Dockerコンテナ、JavaScriptの2つです。- Dockerコンテナのアクション
GitHub Docs Docker コンテナのアクションを作成する - JavaScriptのアクション
GitHub Docs JavaScript アクションを作成する
- Dockerコンテナのアクション
実行環境
GitHub Actionsの実行環境を図として表すと以下のようになります。Cloud hosts上でGitHub-hosted runnersが動作しジョブを実行します。またGitHub-hosted runners上で、コンテナ(図のContainerやService Container)を使用したジョブの実行やデータベースとの通信も可能です。
実行環境イメージ図:
実行環境の図にあるCloud hosts、GitHub-hosted runners、Container、Service Containerについてそれぞれ説明します。
環境
Cloud hosts
Cloud hostsは、後述するGitHub-hosted runnersを実行させる環境です。GitHub-hosted runnersで使用するOSごとにCloud hostsが異なります。
GitHub-hosted runnersで使用するOS | Cloud hosts |
---|---|
Ubuntu | Microsoft Azure Standard_DS2_v2 |
Windows Server | Microsoft Azure Standard_DS2_v2 |
macOS | MacStadium |
Cloud hostsのリソース
Microsoft Azure、MacStadiumのどちらでも、使用するリソースは同一のハードウェアリソースです。GitHubの公式ドキュメントから抜粋します。
- 2コアCPU
- 7 GBのRAMメモリー
- 14 GBのSSDディスク容量
仮想環境 | YAMLのワークフローラベル |
---|---|
Windows Server 2019 | windows-latest or windows-2019 |
Ubuntu 20.04 | ubuntu-20.04 |
Ubuntu 18.04 | ubuntu-latestまたはubuntu-18.04 |
Ubuntu 16.04 | ubuntu-16.04 |
macOS Big Sur 11.0 | macos-11.0 |
macOS Catalina 10.15 | macos-latestもしくはmacos-10.15 |
GitHub-hosted runners
GitHub-hosted runnersはCloud hosts上で動作する仮想環境です。このGitHub-hosted runnersには、オープンソースであるGitHub Actionsランナーアプリケーションのrunnerがインストールされています。
また、このGitHub-hosted runnersのOSにはUbuntu、Windows Server、macOSを指定可能です。(2020年12月9日時点)
Container
ContainerはDockerコンテナであり、ジョブの実行場所として指定可能です。このDockerコンテナで指定可能なイメージは、通常のDockerコンテナと同様、Docker HubやパブリックなDockerレジストリにあるイメージとなります。
Service Container
Service Containerはジョブごとに定義可能なDockerコンテナです。このService Containerはジョブ内の処理と通信することができますが、Service Containerが定義されたジョブと同じジョブにある各ステップのみとなります。またジョブ完了時には、Service Containerは破棄されます。
このService Containerの用途としては、データベースへのアクセスが必要なテストをジョブで実行したいときに使うといった場合があります。
Service Containerとの通信
Service Containerとの通信方法は、ジョブの実行場所により異なります。ジョブの実行場所がGitHub-hosted runners上の場合はポート番号によるアクセス、GitHub-hosted runners上のContainer上の場合はラベルによるアクセスとなります。
管理権限
LinuxやmacOSの仮想環境を使う場合、sudoのパスワードは不要です。またWindowsの仮想環境を使う場合、ユーザアカウント制御(UAC)は無効となり管理者として動作します。
制限事項
GitHubの公式ドキュメントから抜粋します。
・ジョブの実行時間 - ワークフロー中のそれぞれのジョブは、最大で6時間の間実行できます。 ジョブがこの制限に達すると、ジョブは終了させられ、完了できずに失敗します。
・ワークフローの実行時間 - 各ワークフローの実行は72時間までに制限されます。 ワークフローの実行がこの制限に達すると、そのワークフローの実行はキャンセルされます。
・APIリクエスト - リポジトリ内のすべてのアクションにわたって、1時間のうちに最大1000回のAPIリクエストを実行できます。 この制限を超えた場合、超過のAPIコールは失敗し、それによってジョブも失敗するかもしれません。
・並行ジョブ - アカウント内で実行できる並行ジョブ数は、以下の表に示すとおり、利用しているGitHubのプランによります。 この制限を超えた場合、超過のジョブはキューイングされます。
GitHubプラン | 最大同時実行ジョブ | 最大同時macOSジョブ |
---|---|---|
無料 | 20 | 5 |
Pro | 40 | 5 |
Team | 60 | 5 |
Enterprise | 180 | 50 |
ジョブマトリックス - ジョブマトリックスは、ワークフローの実行ごとに最大で256のジョブを生成できます。 この制限は、セルフホストランナーにも適用されます。
制限事項は今後変わる可能性があるので、使用される際は注意が必要です。個人の意見として、CI/CDとしてジョブやワークフローでこの制限に引っかかることはほとんどないと思われます。もし引っかかるようであれば、どこかでボトルネックになっている部分があると考えられるので、そのボトルネックの改善が必要ですね。
利用料金
パブリックリポジトリで使用する場合は無料で使えます。一方、プライベートリポジトリの場合は、GitHubアカウントの契約プランによって無料で使える範囲とストレージが決まります。またGitHub Actions利用料金の上限はデフォルトで0ドルとなっています。
そのため無料の範囲を超過し、かつ利用料金の上限がデフォルトの0ドルままであれば、GitHub Actionsは使用不可となります。利用上限を0ドル以上に設定した場合は、無料の範囲を超えた利用時間やストレージ料が請求されます。
請求金額や計算方法の詳細はGitHubの公式ドキュメントを参照してください。
GitHub Docs 使用制限、支払い、管理
GitHub Docs GitHub Actionsの支払いについて
ローカル環境でGitHub Actionsを実行
ローカル環境でGitHub Actionsを実行できるGitHub公式のツールはありませんが、別の方々が作成されたオープンソースのactがあります。actはGitHub Actionsをローカルで実行できるGolangのツールです。使用方法や実際に使ってみた記事はこちらに記載しています。
GitHub ActionsでRun rubocop with reviewdogを使ったCIの構築
今後のGitHub Actions
GitHubが公開しているroadmapにて、GitHub Actionsの今後の機能追加について記載されています。この中には、GitHub-hosted runnersのリソースを複数選べるようにする機能(Actions: Multiple hosted runner sizes, custom networking, and custom images #95)や、プライベートリポジトリのアクションを使用可能にする機能(Actions: Use actions from private and internal repositories #74 )などがあります。
[roadmap GitHub public roadmap](https://github.com/github/roadmap/projects/1?card_filter_query=label%3Aactions)まとめ
GitHub Actionsの誕生の歴史やサンプルワークフローを使った用語の説明、GitHub Actionsの環境を説明しました。はじめてGitHub Actionsを触る人にとって、この記事がお役に立てれば幸いです。またここに書ききれなかったGitHub Actionsの機能やオプションなどたくさんありますので、GitHub公式のドキュメントも確認されてみてください。
GitHub Docs GitHub Actions
明日は@que9さんの記事です。お楽しみに。
その他参考資料
Dockerコンテナ時代の第一章の終わり、そして第二章の展望など
The Linux Foundation
The Moby Project
GitHub Docs GitHub Actions 入門
GitHub Docs ワークフロー データをアーティファクトとして保存する
GitHub Docs GitHub Actionsのワークフロー構文
GitHub Docs GitHub ホストランナーの仕様
GitHub Docs サービスコンテナについて