『GitHub CI/CD実践ガイド』でGitHub ActionsとCI/CDを体系的に学ぼう

『GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用』という書籍を最近出版したので紹介します。本書ではGitHub Actionsの実装と、CI/CDの設計・運用を体系的に学べます。一粒で二度美味しい書籍です。筆者個人としては「実践Terraform」以来、4年半ぶりの商業出版になります。

gihyo.jp

どんな本?

GitHub利用者にとって、もっとも導入が容易なCI/CD向けのソリューションはGitHub Actionsです。GitHub Actionsの活用事例は多く、検索すればたくさん情報が出てきます。ただ断片的な情報には事欠かない反面、体系的に学習する方法は意外とありません。CI/CD自体がソフトウェア開発の主役になることもまずないため、なんとなく運用している人が大半でしょう。そこで執筆したのが『GitHub CI/CD実践ガイド』です。

本書ではGitHub Actionsを基本からハンズオン形式で解説し、あわせてCI/CDの設計や運用について説明します。テスト・静的解析・リリース・コンテナデプロイなど、CI/CDのよくあるユースケースを実際に自動化し、実務で求められるスキルを効率よく身につけます。基礎から丁寧に知識を積み上げるため、GitHub Actionsがはじめてでも問題なく学べます。

一方でGitHub Actions経験者にも役立つよう、応用的なトピックも幅広く取り上げます。Dependabotによる依存関係のバージョンアップや、OpenID Connectによるセキュアなクラウド連携のような、実運用に欠かせないプラクティスも多数登場します。本記事の最後に目次詳細を掲載しているので、そちらもぜひご覧ください。

こんな人にオススメ

『GitHub CI/CD実践ガイド』の対象読者はソフトウェアエンジニアです。とくに次のような人へお勧めです。

  • GitHubは使っているけれど、プルリクエストぐらいしか利用していない
  • CI/CDというキーワードは知っているけれど、自分で設計したことはない
  • GitHub Actionsには触れているけれど、正直雰囲気で運用している

また次のようなキーワードに関心のある、感度の高い人にもお勧めできます。

  • GitHub Actions:基本構文、ワークフロー、アクション、GitHub API、運用
  • インテグレーション:テスト、静的解析、シークレットマネジメント、脆弱性検出
  • リリース:GitHub Releases、GitHub Packages、コンテナデプロイ、OSS
  • リポジトリ管理:Dependabot、ブランチ保護、コードオーナー、README
  • セキュリティ:OpenID Connect、ソフトウェアサプライチェーン、シフトレフト
  • 高度な設計:Reusable Workflows、GitHub Apps、IaC、継続的デリバリー

本書ではGitとGitHub以外の技術スタックにほとんど依存していません。使用しているプログラミング言語やフレームワークを問わず、あらゆるソフトウェア開発で役立つ知識が得られます。Gitでコミットやプッシュが扱えて、GitHubでプルリクエストの利用経験があるなら十分読みこなせるでしょう。

書籍の構成

『GitHub CI/CD実践ガイド』は全3部、18章構成です。本書ではCI/CDの目的を、「ソフトウェア開発の持続可能性を高め、長期に渡る価値提供を実現する」と定義してすべての議論を展開します。それでは部単位で、簡単に中身を紹介しましょう。

第I部「基礎編」

第1〜6章は第I部「基礎編」です。

  • 第1章:ソフトウェア開発とGitHub
  • 第2章:GitHub Actionsの基礎概念
  • 第3章:ワークフロー構文の基礎
  • 第4章:継続的インテグレーションの実践
  • 第5章:運用しやすいワークフローの設計
  • 第6章:アクションによるモジュール化

第1章でソフトウェア開発の特性やCI/CDの重要性を説明し、第2章以降でGitHub Actionsの基本的な構文や管理機能を紹介します。また第4章では本番運用を考慮したコードの実装と、自動テストや静的解析のポイントをかなり詳しく解説します。GitHub Actionsの基礎知識が最高効率で学べるよう、徹底的に構成は練り上げてあります。

第II部「実践編」

第7〜13章は第II部「実践編」です。

第7章ではブランチプロテクションやシークレットスキャンのような、地味ながら長期運用に欠かせないプラクティスを紹介します。次の第8章ではDependabotによる自動バージョンアップを詳細に説明し、最終的に自動マージまで実現します。そして第9〜13章で扱うのがリリースです。コマンドラインツールやソフトウェアパッケージのリリース、Amazon ECSへのコンテナデプロイなどを題材に実装していきます。リリースの設計観点を包括的に説明し、各種GitHubサービスの活用方法も習得します。

第III部「応用編」

第14〜18章は第III部「応用編」です。

  • 第14章:GitHub Actionsの高度な使い方
  • 第15章:GitHub Actionsのセキュリティ
  • 第16章:セキュリティのシフトレフト
  • 第17章:GitHub Appsトークンによるクロスリポジトリアクセス
  • 第18章:継続的デリバリーの実践

第14章ではReusable Workflowsやエラーハンドリングのような、GitHub Actionsの発展的な機能を解説します。第15〜17章の中核的な話題はセキュリティです。とくに第15章では、GitHub Actionsにおけるサプライチェーン攻撃対策を詳細に説明します。そして最終章ではDBマイグレーションやIaCなど、GitHubに閉じない設計観点を紹介します。第III部ではカスタムクレームを活用したOpenID Connectの堅牢化や、GitHub APIを利用したGitHub Appsトークン生成のようにディープな話題も取り扱います。

こだわりポイント

『GitHub CI/CD実践ガイド』はかなりの難産で、実は執筆に2年もかかっています。ただ時間をかけたかいはあり、渾身の一冊に仕上がりました。せっかく頑張って書いたので、こだわったポイントを紹介してみます。

手を動かしながら、長く役立つスキルを学ぶ

本書は「実際に手を動かすこと」を重視しています。コードは行単位で解説し、設定手順もスクリーンショット付きで丁寧に説明します。短く分かりやすいコードにしてあるので、写経をしながら学ぶのもお勧めです。サンプルコードはすべて公開しており、リポジトリを用意すれば即座に実行できます。

本書ではたくさんコードが登場する一方で、そのまま使えるレシピのようなコードはほぼ出てきません。どんなソフトウェア開発でも応用できるよう、あえて基礎的な概念の習得に重点を置いています。一見遠回りに見えますが、基礎を理解すれば応用力が飛躍的に高まるため、結果的に長く役立つスキルが身につきます。

コードの書き方だけでなく、設計や運用の考え方を学ぶ

本書では実践的な知識を重視しています。もう少し具体化すると、「読者が実装可能で、長期的な本番運用に役立つ」ような知識を重視しています。このときポイントになるのが設計と運用です。いくらコードの書き方を習得しても、設計や運用の知識が足りないと、長期的な本番運用に役立てるのは難しくなります。

そのため本書ではコードの『書き方』だけでなく、設計や運用の『考え方』を織り交ぜて解説する構成にしました。筆者個人の経験と大量の参考文献をベースにして、実務で役立つノウハウをこれでもかと詰め込んでいます。大半の内容は公式ドキュメントでも学べないため、すでにGitHubを使いこなしている人にもいろいろ発見があるはずです。

ソフトウェア開発のさまざまな側面を、広く深く学ぶ

CI/CDといえばテストやリリースの自動化をイメージしやすいですが、本書ではソフトウェアエンジニアリングの広範な領域をカバーしています。本書でとくに意識したのは、「実運用では重要ながら、学習機会が少ないプラクティス」です。コードのオーナーシップ・LICENSEやリリースノート・シークレットマネジメントなどがその一例です。地味でも習慣化する価値のあるプラクティスについては、積極的に限り取り上げました。

ただし広く浅くにならないよう注意しています。たとえばOpenID Connectでは使い方だけでなく、プロトコルレベルまで掘り下げて仕組みを解説します。仕組みを知らなくても動かすことはできますが、セキュアに本番運用したいならプロトコルの理解は不可欠です。こういった実務でミスの許されない領域は容赦なく深掘りし、適切な設計判断をくだすための正しい知識を提供します。

目次詳細

それでは本記事のメインコンテンツといえる、目次詳細を紹介しましょう。

1. ソフトウェア開発とGitHub
    - 1.1 ソフトウェア開発
        - 1.1.1 複雑性と変化
        - 1.1.2 品質と期待値
        - 1.1.3 不可避な試行錯誤
    - 1.2 CI/CD
        - 1.2.1 継続的インテグレーション
        - 1.2.2 継続的デリバリー
        - 1.2.3 ソフトウェア開発の持続可能性
        - 1.2.4 バージョン管理システム
    - 1.3 GitHub
        - 1.3.1 アカウント
        - 1.3.2 料金プラン
        - 1.3.3 リポジトリ
        - 1.3.4 公式ドキュメント
    - 1.4 環境構築
        - 1.4.1 GitHub CLI
        - 1.4.2 リポジトリの作成
        - 1.4.3 サンプルコード
    - 1.5 まとめ
2. GitHub Actionsの基礎概念
    - 2.1 GitHub Actionsをはじめよう
        - 2.1.1 ワークフローファイル
        - 2.1.2 ワークフロー構文
    - 2.2 GitHub Actionsの構成要素
        - 2.2.1 ワークフロー
        - 2.2.2 イベント
        - 2.2.3 ジョブ
        - 2.2.4 ランナー
        - 2.2.5 ステップ
    - 2.3 GitHub Actionsの実行
        - 2.3.1 ブラウザによるワークフロー実行ログの確認
        - 2.3.2 GitHub CLIによるワークフロー実行ログの確認
    - 2.4 GitHub Actionsのエラー
        - 2.4.1 構文エラー
        - 2.4.2 実行時エラー
    - 2.5 ワークフローの起動方法
        - 2.5.1 GitHubイベント
        - 2.5.2 手動実行
        - 2.5.3 定期実行
    - 2.6 ワークフローの実行管理
        - 2.6.1 ワークフローの再実行
        - 2.6.2 ワークフローのキャンセル
        - 2.6.3 ワークフローの無効化
    - 2.7 ジョブの実行環境
        - 2.7.1 GitHub-Hosted Runners
        - 2.7.2 Self-Hosted Runners
        - 2.7.3 サポートOS
        - 2.7.4 インストール済みソフトウェア
        - 2.7.5 エフェメラル
    - 2.8 アクション
        - 2.8.1 アクションの探し方
        - 2.8.2 Verified Creators
    - 2.9 GitHub Actionsの課金モデル
        - 2.9.1 使用時間
        - 2.9.2 ストレージ使用量
    - 2.10 まとめ
3. ワークフロー構文の基礎
    - 3.1 コンテキスト
        - 3.1.1 githubコンテキスト
        - 3.1.2 runnerコンテキスト
    - 3.2 環境変数
        - 3.2.1 環境変数の参照
        - 3.2.2 環境変数のオーバーライド
        - 3.2.3 デフォルト環境変数
        - 3.2.4 中間環境変数
    - 3.3 Variables
        - 3.3.1 Variablesの登録
        - 3.3.2 Variablesの参照
    - 3.4 Secrets
        - 3.4.1 Secretsの登録
        - 3.4.2 Secretsの参照
        - 3.4.3 Secretsのログマスク
    - 3.5 式
        - 3.5.1 リテラル
        - 3.5.2 演算子
        - 3.5.3 オブジェクトフィルター
    - 3.6 関数
        - 3.6.1 文字列比較
        - 3.6.2 文字列生成
        - 3.6.3 JSON操作
        - 3.6.4 ハッシュ生成
    - 3.7 条件分岐
        - 3.7.1 ステータスチェック関数
        - 3.7.2 ワークフロー実行のスキップ
    - 3.8 ネーミング
        - 3.8.1 ステップ名とジョブ名
        - 3.8.2 ワークフロー実行名
    - 3.9 ステップ間のデータ共有
        - 3.9.1 GITHUB_OUTPUT環境変数
        - 3.9.2 GITHUB_ENV環境変数
    - 3.10 GitHub APIの実行
        - 3.10.1 GITHUB_TOKENシークレット
        - 3.10.2 パーミッション
        - 3.10.3 パーミッションの一括指定
        - 3.10.4 contentsスコープ
        - 3.10.5 パーミッションのトラブルシューティング
    - 3.11 スターターワークフロー
    - 3.12 まとめ
4. 継続的インテグレーションの実践
    - 4.1 プルリクエストによる継続的インテグレーションの起動
        - 4.1.1 開発プロセス
        - 4.1.2 デフォルトブランチ
        - 4.1.3 継続的インテグレーションによる検証
    - 4.2 自動テスト
        - 4.2.1 プロダクションコードとテストコード
        - 4.2.2 テストワークフロー
        - 4.2.3 ステータスチェック
    - 4.3 イベントのフィルタリング
        - 4.3.1 フィルター
        - 4.3.2 Glob
        - 4.3.3 アクティビティタイプ
    - 4.4 セットアップアクション
        - 4.4.1 主要言語のセットアップ
        - 4.4.2 バージョンファイル
    - 4.5 静的解析
        - 4.5.1 actionlint
        - 4.5.2 静的解析ワークフロー
    - 4.6 タイムアウト
    - 4.7 シェル
        - 4.7.1 Bashの起動オプション
        - 4.7.2 デフォルトシェル
    - 4.8 Concurrency
        - 4.8.1 多重起動の抑制
        - 4.8.2 自動キャンセル
    - 4.9 継続的インテグレーションの黄金律
        - 4.9.1 クリーンに保つ
        - 4.9.2 高速に実行する
        - 4.9.3 ノイズを減らす
    - 4.10 自動テストの運用プラクティス
        - 4.10.1 ユニットテストを中心にする
        - 4.10.2 たまに落ちるテストをリトライでごまかさない
        - 4.10.3 リファクタリングで壊れるテストを根絶する
        - 4.10.4 スローテストの実行タイミングをずらす
        - 4.10.5 テスト実行時の挙動を制御する
        - 4.10.6 チームでテスト設計を学ぶ
    - 4.11 静的解析の運用プラクティス
        - 4.11.1 不要な警告は無視せず抑止する
        - 4.11.2 新規の警告を増やさない
        - 4.11.3 警告理由を理解する
    - 4.12 まとめ
5. 運用しやすいワークフローの設計
    - 5.1 ワークフロー設計の道具箱
        - 5.1.1 デベロッパーエクスペリエンス
        - 5.1.2 ジョブ管理
        - 5.1.3 データ管理
    - 5.2 ロギング
        - 5.2.1 デバッグログ
        - 5.2.2 ワークフローコマンド
        - 5.2.3 Bashのトレーシングオプション
        - 5.2.4 ログのグループ化
        - 5.2.5 ログの手動マスク
    - 5.3 レポーティング
        - 5.3.1 アノテーション
        - 5.3.2 ジョブサマリー
    - 5.4 チャット通知
        - 5.4.1 チャット通知の組み込み
        - 5.4.2 チャット通知の運用
    - 5.5 複数ジョブの実行制御
        - 5.5.1 ジョブの並列実行
        - 5.5.2 ジョブの逐次実行
        - 5.5.3 ジョブ間のデータ共有
    - 5.6 マトリックス
        - 5.6.1 多次元マトリックス
        - 5.6.2 組み合わせ条件の手動定義
        - 5.6.3 マトリックスジョブと使用時間
    - 5.7 Environments
        - 5.7.1 Environmentsの作成
        - 5.7.2 Environment variablesとEnvironment secretsの登録
        - 5.7.3 Environmentsの利用
    - 5.8 キャッシュ
        - 5.8.1 キャッシュアクション
        - 5.8.2 キャッシュキーの設計
        - 5.8.3 キャッシュの削除
        - 5.8.4 キャッシュ復元とキャッシュ保存の分離
    - 5.9 アーティファクト
        - 5.9.1 アーティファクトのアップロード
        - 5.9.2 アーティファクトのダウンロード
    - 5.10 まとめ
6. アクションによるモジュール化
    - 6.1 アクションの分類
        - 6.1.1 アクションの実装方式
        - 6.1.2 アクションのロケーション
        - 6.1.3 アクションの可視性
    - 6.2 Composite Action
        - 6.2.1 メタデータファイル
        - 6.2.2 Composite Actionの実装
        - 6.2.3 ローカルアクションの利用
    - 6.3 メタデータ構文
        - 6.3.1 アクション名
        - 6.3.2 アクションの概要
        - 6.3.3 アクションの入力
        - 6.3.4 アクションの出力
        - 6.3.5 アクションのメインロジック
    - 6.4 メタデータ構文とワークフロー構文の違い
        - 6.4.1 メタデータ構文のシェル
        - 6.4.2 メタデータ構文のコンテキスト
        - 6.4.3 メタデータ構文のVariablesとSecrets
        - 6.4.4 メタデータ構文の環境変数
        - 6.4.5 メタデータ構文のパーミッション
    - 6.5 アクションの設計プラクティス
        - 6.5.1 認知負荷の低減
        - 6.5.2 GITHUB_TOKENをアクションから参照
        - 6.5.3 GITHUB_ACTION_PATH環境変数とスクリプトの切り出し
        - 6.5.4 環境変数による暗黙的な依存の回避
        - 6.5.5 ロググループ化の活用
    - 6.6 まとめ
7. クリーンなリポジトリの維持
    - 7.1 コードレビュー
    - 7.2 ブランチの保護
        - 7.2.1 ブランチプロテクションルールの設定
        - 7.2.2 主要なブランチプロテクションルール
        - 7.2.3 バランス感覚を失わない
    - 7.3 オーナーシップの維持
        - 7.3.1 コードオーナー
        - 7.3.2 CODEOWNERSファイル
        - 7.3.3 個人アカウントとTeamのトレードオフ
    - 7.4 クレデンシャルの混入防止
        - 7.4.1 クレデンシャルをバージョン管理してはならぬ
        - 7.4.2 シークレットスキャンによる混入の検出
        - 7.4.3 プッシュプロテクションによる混入の抑制
        - 7.4.4 クレデンシャル検出時の対応
    - 7.5 ドキュメンテーション
        - 7.5.1 README
        - 7.5.2 LICENSE
        - 7.5.3 コミュニティヘルスファイル
    - 7.6 まとめ
8. Dependabotによる依存関係バージョンアップ
    - 8.1 依存関係
        - 8.1.1 依存関係管理
        - 8.1.2 ソフトウェアはなにもしないと壊れる
        - 8.1.3 依存関係地獄
        - 8.1.4 依存関係のバージョンアップ
    - 8.2 Dependabot
        - 8.2.1 Dependabot version updates
        - 8.2.2 Dependabotの設定ファイル
        - 8.2.3 Dependabotの実行
        - 8.2.4 バージョンアップの除外設定
    - 8.3 GitHub Actionsによる自動マージ
        - 8.3.1 自動マージとブランチプロテクションルールの両立
        - 8.3.2 自動マージワークフロー
        - 8.3.3 ステータスチェックと自動マージ
        - 8.3.4 承認と自動マージ
        - 8.3.5 自動マージを諦めるとき
    - 8.4 Dependabotのワークフロー設計
        - 8.4.1 Dependabot secrets
        - 8.4.2 依存関係のメタデータ
    - 8.5 バージョンアップの影響範囲
        - 8.5.1 破壊的変更の頻度
        - 8.5.2 ソフトウェアの依存度合い
        - 8.5.3 自動テストの充実度
    - 8.6 自動マージ戦略
        - 8.6.1 パッチバージョンの変更は自動マージ
        - 8.6.2 開発環境向けの変更は自動マージ
        - 8.6.3 GitHub Actions向けの変更は自動マージ
    - 8.7 まとめ
9. GitHub Releasesによるリリース自動化
    - 9.1 ソフトウェアのリリース
    - 9.2 バージョニング
        - 9.2.1 セマンティックバージョニング
        - 9.2.2 Gitã‚¿ã‚°
    - 9.3 アナウンス
        - 9.3.1 リリースノート
        - 9.3.2 Changelog
    - 9.4 GitHub Releases
        - 9.4.1 リリースノートの作成
        - 9.4.2 リリースノートの参照
    - 9.5 リリースノートの自動生成
        - 9.5.1 リリースノート設定ファイル
        - 9.5.2 プルリクエストへのラベル付与
        - 9.5.3 誰が為のリリースノート
    - 9.6 リリースの自動化
        - 9.6.1 リリース対象のアプリケーション
        - 9.6.2 リリースワークフロー
    - 9.7 Gitタグの保護
        - 9.7.1 可変なGitタグ
        - 9.7.2 ルールセット
    - 9.8 まとめ
10. GitHub Packagesによるパッケージ管理
    - 10.1 パッケージ
        - 10.1.1 パッケージエコシステム
        - 10.1.2 パッケージマネージャークライアント
        - 10.1.3 パッケージレジストリ
    - 10.2 GitHub Packages
        - 10.2.1 サポート対象のパッケージレジストリ
        - 10.2.2 GitHub Packagesの課金モデル
    - 10.3 Container Registry
        - 10.3.1 コンテナイメージの命名規則とビルド
        - 10.3.2 Container Registryへのログインとプッシュ
    - 10.4 GitHub Packagesの管理
        - 10.4.1 リポジトリとのリンク
        - 10.4.2 パッケージのパーミッション
        - 10.4.3 パッケージの可視性
    - 10.5 パッケージの自動リンクとパーミッションの継承
        - 10.5.1 自動リンク
        - 10.5.2 パーミッションの自動継承
        - 10.5.3 リポジトリの可視性とパッケージの可視性
    - 10.6 コンテナイメージの自動リリース
        - 10.6.1 コンテナイメージのリリース戦略
        - 10.6.2 パブリッシュワークフロー
        - 10.6.3 コンテナレジストリへのログイン
        - 10.6.4 コンテナイメージのメタデータ生成
        - 10.6.5 コンテナイメージのビルドとプッシュ
    - 10.7 まとめ
11. OpenID Connectによるセキュアなクラウド連携
    - 11.1 クラウドプロバイダのクレデンシャル
        - 11.1.1 静的クレデンシャル
        - 11.1.2 一時クレデンシャル
        - 11.1.3 クラウド連携のアンチパターン
    - 11.2 OpenID Connect
        - 11.2.1 OpenID Connectの利点
        - 11.2.2 一時クレデンシャルの取得フロー
        - 11.2.3 OIDC TrustとCloud Roles
        - 11.2.4 認証アクション
    - 11.3 検証作業のリスクヘッジ
        - 11.3.1 プライベートリポジトリの作成
        - 11.3.2 認証パラメータのSecrets管理
    - 11.4 AWSにおけるOpenID Connectの利用準備
        - 11.4.1 OpenID Connect Provider
        - 11.4.2 IAMロール
    - 11.5 OpenID ConnectによるAWS連携
        - 11.5.1 認証パラメータのSecrets登録
        - 11.5.2 AWS連携ワークフロー
        - 11.5.3 セッション名によるトレーサビリティ向上
        - 11.5.4 AWS連携のトラブルシューティングガイド
    - 11.6 Cloud Rolesのセキュアな運用
        - 11.6.1 別リポジトリからアクセスできないことを確認する
        - 11.6.2 Cloud Rolesは目的ごとに分離する
        - 11.6.3 Infrastructure as Codeを導入する
    - 11.7 まとめ
12. コンテナオーケストレーションのデプロイメント
    - 12.1 サービス
        - 12.1.1 実行環境
        - 12.1.2 デプロイメント
        - 12.1.3 コンテナオーケストレーション
    - 12.2 実行環境の構築
        - 12.2.1 Amazon ECS
        - 12.2.2 Amazon ECR
        - 12.2.3 AWS Copilotによるプロビジョニング
        - 12.2.4 テスト環境の構築
        - 12.2.5 デプロイメントIAMロール
    - 12.3 デプロイ情報のVariables管理
        - 12.3.1 デプロイ情報の取得
        - 12.3.2 デプロイ情報の登録
    - 12.4 デプロイの自動化
        - 12.4.1 コンテナビルドアクション
        - 12.4.2 コンテナデプロイアクション
        - 12.4.3 デプロイワークフロー
        - 12.4.4 デプロイの実行
    - 12.5 Environmentsを利用した複数環境デプロイ
        - 12.5.1 本番環境の構築
        - 12.5.2 Environmentsによるデプロイ情報の管理
        - 12.5.3 複数環境向けデプロイワークフロー
        - 12.5.4 デプロイメントプロテクションルール
        - 12.5.5 実行環境の後始末
    - 12.6 デプロイメント設計
        - 12.6.1 ローリングアップデート
        - 12.6.2 ロールバック
    - 12.7 まとめ
13. アクションのオープンソース化
    - 13.1 アクションの公開
        - 13.1.1 アクションのファイルレイアウト
        - 13.1.2 プルリクエスト作成アクション
        - 13.1.3 アクションの命名規則
    - 13.2 アクションのテスト
        - 13.2.1 4フェーズテスト
        - 13.2.2 アクションのテストワークフロー
        - 13.2.3 テストコードを通じた設計改善
    - 13.3 アクションのリリースマネジメント
        - 13.3.1 メジャーバージョンタグ
        - 13.3.2 バージョニングスクリプト
        - 13.3.3 アクションのリリースワークフロー
    - 13.4 アクションのドキュメンテーション
        - 13.4.1 アクションのREADME
        - 13.4.2 ドキュメンテーションを通じた設計改善
    - 13.5 GitHub Marketplaceへの公開
        - 13.5.1 ブランディング
        - 13.5.2 GitHub Marketplaceの公開プロセス
    - 13.6 アクションの進化プロセス
        - 13.6.1 ユースケースの明確化
        - 13.6.2 責務の見極め
        - 13.6.3 インターフェイスの安定化
        - 13.6.4 アクション利用者の満足度向上
        - 13.6.5 戦略的な改善
    - 13.7 まとめ
14. GitHub Actionsの高度な使い方
    - 14.1 Reusable Workflows
        - 14.1.1 Reusable Workflowsの定義
        - 14.1.2 Reusable Workflowsの呼び出し
        - 14.1.3 Reusable Workflowsの仕様
    - 14.2 動的なワークフロー定義
        - 14.2.1 動的なマトリックス生成
        - 14.2.2 文字列の型変換
    - 14.3 エラーハンドリング
        - 14.3.1 Continue on Error
        - 14.3.2 マトリックスのフェイルファスト
    - 14.4 コンテキストによるフロー制御
        - 14.4.1 stepsコンテキスト
        - 14.4.2 needsコンテキスト
        - 14.4.3 コンテキストとステータスチェック関数の併用
    - 14.5 プライベートアクションとプライベートReusable Workflows
        - 14.5.1 プライベートリポジトリへのアクセス許可
        - 14.5.2 Dependabotへのアクセス許可
    - 14.6 まとめ
15. GitHub Actionsのセキュリティ
    - 15.1 ソフトウェアサプライチェーン
        - 15.1.1 セキュリティのCIA
        - 15.1.2 守るべき資産
        - 15.1.3 利便性とのトレードオフ
    - 15.2 セキュリティの設計原則
        - 15.2.1 アタックサーフェスの最小化
        - 15.2.2 多層防御
        - 15.2.3 最小権限
    - 15.3 GitHubのサービス特性
        - 15.3.1 寛容なデフォルト設定
        - 15.3.2 リポジトリによるセキュリティ境界
        - 15.3.3 コラボレーションによるアタックサーフェスの拡大
    - 15.4 リポジトリの保護
        - 15.4.1 リポジトリのアクセス制御
        - 15.4.2 ロールの侵害リスク
        - 15.4.3 OpenSSF Scorecards
    - 15.5 サードパーティアクションのセキュリティ
        - 15.5.1 サードパーティへの信頼
        - 15.5.2 サードパーティアクションの利用制限
        - 15.5.3 コミットハッシュによる固定
        - 15.5.4 車輪の再発明
    - 15.6 スクリプトインジェクション
        - 15.6.1 中間環境変数による無害化
        - 15.6.2 ShellCheckによる静的解析
    - 15.7 最小権限のパーミッション
        - 15.7.1 デフォルトパーミッション
        - 15.7.2 明示的なパーミッション定義
        - 15.7.3 ワークフローレベルのパーミッション無効化
        - 15.7.4 ジョブ分割によるパーミッションの分離
    - 15.8 シークレットマネジメント
        - 15.8.1 クレデンシャルの把握と棚卸し
        - 15.8.2 クレデンシャルの適切な運用
        - 15.8.3 クレデンシャルのログ出力抑制
        - 15.8.4 構造化データの不使用
    - 15.9 Forkプルリクエスト対策
        - 15.9.1 Forkプルリクエストのワークフロー起動制限
        - 15.9.2 pull_request_targetイベントの不使用
    - 15.10 OpenID Connectハードニング
        - 15.10.1 IDトークン
        - 15.10.2 IDトークンの検証フロー
        - 15.10.3 IDトークンの署名検証
        - 15.10.4 IDトークンのJWTクレーム検証
        - 15.10.5 Environmentsの検証
        - 15.10.6 カスタマイズしたsubクレームの検証
    - 15.11 まとめ
16. セキュリティのシフトレフト
    - 16.1 シフトレフト
        - 16.1.1 セキュリティの自動化戦略
        - 16.1.2 ツールよりも考え方
    - 16.2 依存関係の脆弱性スキャン
        - 16.2.1 Dependency graph
        - 16.2.2 Dependabot alerts
        - 16.2.3 Dependabot security updates
    - 16.3 シークレットスキャン
        - 16.3.1 Secretlintによるシークレットスキャン
        - 16.3.2 Gitleaksによるヒストリスキャン
        - 16.3.3 Gitフックによるローカルスキャン
    - 16.4 アプリケーションセキュリティ
        - 16.4.1 Static Application Security Testing
        - 16.4.2 コンテナイメージの脆弱性スキャン
    - 16.5 Infrastructure as Codeセキュリティ
        - 16.5.1 セキュリティ設定ミスの防止
        - 16.5.2 Policy as Code
    - 16.6 継続的なセキュリティ改善
        - 16.6.1 誤検出と検出漏れ
        - 16.6.2 アラート疲れ
    - 16.7 まとめ
17. GitHub Appsトークンによるクロスリポジトリアクセス
    - 17.1 GitHubのクレデンシャル
        - 17.1.1 GitHub Actionsで推奨されるクレデンシャル
        - 17.1.2 GitHub Actionsで避けるべきクレデンシャル
    - 17.2 GitHub Appsトークン
        - 17.2.1 秘密鍵とGitHub Appsトークンのライフサイクル
        - 17.2.2 GitHub Appsのセットアップ
    - 17.3 クロスリポジトリアクセス
        - 17.3.1 App IDと秘密鍵の管理
        - 17.3.2 クロスリポジトリアクセスワークフロー
    - 17.4 GitHub Appsトークン生成の仕組み
        - 17.4.1 環境変数の準備
        - 17.4.2 JWT生成関数
        - 17.4.3 JWTの生成
        - 17.4.4 Installation APIの実行
        - 17.4.5 Access Tokens APIの実行
        - 17.4.6 GitHub Appsトークン生成スクリプトの実行
        - 17.4.7 GitHub Appsトークン生成スクリプトの組み込み
    - 17.5 GitHub Appsトークンの運用プラクティス
        - 17.5.1 秘密鍵のローテーション
        - 17.5.2 GitHub Appsトークン生成アクションの固定
        - 17.5.3 アクションのコードリーディング
        - 17.5.4 GitHub Appsトークン生成スクリプトの本番導入
    - 17.6 まとめ
18. 継続的デリバリーの実践
    - 18.1 組織パフォーマンス
        - 18.1.1 ソフトウェアデリバリーパフォーマンス
        - 18.1.2 継続的デリバリーの効果
    - 18.2 バージョン管理戦略
        - 18.2.1 包括的なバージョン管理
        - 18.2.2 短命なブランチの運用
    - 18.3 テスト戦略
        - 18.3.1 探索的テスト
        - 18.3.2 Testing in Production
    - 18.4 リリース戦略
        - 18.4.1 恐怖を克服する
        - 18.4.2 誰でもロールバック
        - 18.4.3 デプロイとリリースの分離
    - 18.5 データベースの変更管理
        - 18.5.1 マイグレーションスクリプト
        - 18.5.2 安全なマイグレーション
        - 18.5.3 本番データベースの影響分析
    - 18.6 Infrastructure as Codeの変更管理
        - 18.6.1 ドライランによる影響範囲の把握
        - 18.6.2 安全な本番環境の変更適用
        - 18.6.3 IaCツール実行環境のセキュリティ
        - 18.6.4 構成ドリフトの検出
    - 18.7 疎結合なアーキテクチャ
        - 18.7.1 テスト容易性とデプロイ容易性
        - 18.7.2 コンウェイの法則
    - 18.8 運用を忘れない
        - 18.8.1 信頼性
        - 18.8.2 自分で運用する
    - 18.9 継続的な学び
    - 18.10 まとめ

おわりに

本書の執筆は本当に大変でした。構成を何度も練り直し、推敲も10周以上しました。しかし2年も時間をかけたおかげで、本当によい書籍に仕上がっています。多岐にわたることを学べる書籍ですが、個々の節は短くテンポよく読めるようにしてあります。この機会にぜひお手にとっていただければ幸いです。

というわけで『GitHub CI/CD実践ガイド』の紹介でした。すでに買ったよ!という人は、SNSで感想をつぶやいたり、Amazonで評価したりしてもらえるとうれしいです。それではみなさまからのフィードバックをお待ちしております。