シリーズの第4部では、GitHub Actionsを使用して継続的インテグレーション(CI)と継続的デプロイメント(CD)を構成し、バックエンドをテストしてHerokuにデプロイします。

はじめに
このシリーズの目標は、具体的な問題(オンラインコースの採点システム)を解決することにより、最新のバックエンドにおけるさまざまなパターン、問題、アーキテクチャを探索し、実証することです。
ライブストリームの録画は上記で利用可能であり、この記事と同じ内容をカバーしています。
シリーズで取り上げる内容
このシリーズでは、バックエンド開発のあらゆる側面におけるデータベースの役割に焦点を当て、以下を取り上げます。
トピック | パート |
---|---|
データモデリング | パート1 |
CRUD | パート1 |
集計 | パート1 |
REST APIレイヤー | パート2 |
バリデーション | パート2 |
テスト | パート2 |
パスワードレス認証 | パート3 |
認可 | パート3 |
外部APIとの統合 | パート3 |
継続的インテグレーション | パート4(現在) |
デプロイメント | パート4(現在) |
最初の記事では、問題領域のデータモデルを設計し、シードスクリプトを作成しました。このスクリプトはPrisma Clientを使用してデータをデータベースに保存します。
シリーズの2番目の記事では、最初の記事のデータモデルとPrismaスキーマの上にREST APIを構築しました。Hapiを使用してREST APIを構築し、HTTPリクエストを介してリソースに対するCRUD操作を実行できるようにしました。
シリーズの3番目の記事では、JSON Web Tokens(JWT)をHapiとともに使用してREST APIを保護し、メールベースのパスワードレス認証と認可を実装しました。さらに、ユーザーが許可されている操作を定義するために、リソースベースの認可を実装しました。
今日学ぶこと
この記事では、GitHub ActionsをCI/CDサーバーとしてセットアップし、テストを実行してバックエンドをHerokuにデプロイするワークフローを定義します。Herokuでは、バックエンドとPostgreSQLデータベースをホストします。
Herokuはサービスとしてのプラットフォーム(PaaS)です。サーバーレスデプロイメントモデルとは対照的に、Herokuを使用すると、リクエストがなくてもアプリケーションは常に実行されます。サーバーレスには、コストの削減や運用オーバーヘッドの削減など、多くの利点がありますが、このアプローチでは、サーバーレスアプローチに共通するデータベース接続のチャーンとコールドスタートの課題を回避できます。
Prismaを使用するアプリケーションのデプロイメントパラダイム間のトレードオフの詳細については、Prismaのデプロイメントドキュメントを参照してください。
注:ガイド全体を通して、手順を正しく実行したかどうかを検証できるさまざまなチェックポイントがあります。
前提条件
GitHub Actionを使用してバックエンドをHerokuにデプロイするには、以下が必要です。
- Herokuアカウント。
- Heroku CLIがインストールされていること。
- メール送信用のSendGrid APIトークン(シリーズのパート3で作成したもの)。
継続的インテグレーションと継続的デプロイメント
継続的インテグレーション(CI)は、個々の開発者からの作業をメインコードリポジトリに統合し、統合バグを早期に捕捉し、共同開発を加速するために使用される手法です。通常、CIサーバーはGitリポジトリに接続されており、コミットがリポジトリにプッシュされるたびに、CIサーバーが実行されます。
継続的デプロイメント(CD)は、変更を迅速かつ一貫してデプロイできるように、デプロイメントプロセスを自動化することに関心のあるアプローチです。
CIとCDは異なる責任に関係していますが、関連性があり、同じツールを使用して処理されることがよくあります。この記事では、GitHub Actionsを使用してCIとCDの両方を処理します。
継続的インテグレーションパイプライン
継続的インテグレーションでは、主要な構成要素はパイプラインです。パイプラインは、変更によってバグやリグレッションが導入されないようにするために定義する一連のステップです。たとえば、パイプラインには、テスト、コードリンター、TypeScriptコンパイラーを実行するステップが含まれる場合があります。いずれかのステップが失敗した場合、CIサーバーは停止し、失敗したステップをGitHubに報告します。
プルリクエストを使用してコード変更が導入されるチームで作業する場合、CIサーバーは通常、すべてのプルリクエストに対してパイプラインを自動的に実行するように構成されます。
前の手順で作成したテストは、APIのエンドポイントへのリクエストをシミュレートすることで機能します。これらのエンドポイントのハンドラーはデータベースと対話するため、テストの実行時間中はバックエンドのスキーマを持つPostgreSQLデータベースが必要です。次のステップでは、GitHub Actionsを構成して、(CI実行時間中の)テストデータベースを実行し、マイグレーションを実行して、テストデータベースがPrismaスキーマと一致するようにします。
注:CIは、作成したテストと同じくらい優れています。テストカバレッジが低い場合、テストに合格しても、誤った安心感が生まれる可能性があります。
GitHub Actionsでワークフローを定義する
GitHub Actionsは、継続的インテグレーションに使用できる自動化プラットフォームです。GitHubのイベントに基づいてワークフローを調整するためのAPIを提供し、GitHubからコードをビルド、テスト、デプロイするために使用できます。
GitHub Actionsを構成するには、yamlを使用してワークフローを定義します。ワークフローは、さまざまなリポジトリイベント(例:コミットがリポジトリにプッシュされたとき、またはプルリクエストが作成されたとき)で実行するように構成できます。
各ワークフローには複数のジョブを含めることができ、各ジョブは複数のステップを定義します。ジョブの各ステップはコマンドであり、テストされている特定のコミットのソースコードにアクセスできます。
注:CIサービスはパイプラインに対して異なる用語を使用します。たとえば、GitHub Actionsは同じものを指すためにワークフローという用語を使用します。
この記事では、リポジトリのgrading-app
ワークフローを使用します。
ワークフローを見てみましょう
grading-app
ワークフローには、test
とdeploy
の2つのジョブがあります。
testジョブは次のことを行います。
- リポジトリをチェックアウトします。
- nodeを構成します。
- 依存関係をインストールします。
services
を使用して起動されるテストデータベースにデータベーススキーマを作成します。- テストを実行します。
注:
services
は、追加のサービスを実行するために使用できます。上記のtestジョブでは、テストPostgreSQLデータベースを作成するために使用されています。
deployジョブは次のことを行います。
- リポジトリをチェックアウトします
- 依存関係をインストールします
- 本番データベースに対してマイグレーションを実行します
- Herokuにデプロイします
注:
on: push
は、プッシュされたすべてのコミットに対してワークフローをトリガーします。if: github.event_name == 'push' && github.ref == 'refs/heads/master'
条件は、deploy
ジョブがmasterに対してのみトリガーされるようにします。
リポジトリをフォークしてワークフローを有効にする
GitHub actionsを構成できるように、GitHubリポジトリをフォークすることから始めます。
注:すでにリポジトリをフォークしている場合は、オリジンリポジトリのmasterブランチから変更をマージしてください
フォークしたら、Githubのアクションタブに移動します
有効にするボタンをクリックしてワークフローを有効にします
これで、コミットをリポジトリにプッシュすると、GitHubがワークフローを実行します。
Heroku CLIログイン
CLIを使用してHerokuにログインしていることを確認してください
Herokuアプリを作成する
バックエンドアプリケーションをHerokuにデプロイするには、Herokuアプリを作成する必要があります。クローンされたリポジトリのフォルダーから次のコマンドを実行します。
注:
YOUR_APP_NAME
の代わりに、任意のユニークな名前を使用してください。
チェックポイント Heroku CLIは、アプリが正常に作成されたことをログに記録する必要があります
HerokuでPostgreSQLデータベースをプロビジョニングする
次のコマンドでデータベースを作成します。
チェックポイント:データベースが作成されたことを確認するには、次の内容が表示されるはずです
注:Herokuは、アプリケーションランタイム用に
DATABASE_URL
環境変数を自動的に設定します。Prisma Clientは、Prismaスキーマで構成された環境変数と一致するため、DATABASE_URL
を使用します。
GitHubでビルド時のシークレットを定義する
GitHub Actionsが本番データベースのマイグレーションを実行し、バックエンドをHerokuにデプロイするには、GitHubのワークフローで参照されている4つのシークレットを作成します。
注:ビルド時のシークレットとランタイムシークレットの間には区別が必要です。ビルド時のシークレットはGitHubで定義され、GitHub Actionsの実行時間中に使用されます。一方、ランタイムシークレットはHerokuで定義され、バックエンドで使用されます。
シークレット
HEROKU_APP_NAME
:前の手順で選択したアプリの名前。HEROKU_EMAIL
:Herokuにサインアップしたときに使用したメールアドレス。HEROKU_API_KEY
:Heroku APIキーDATABASE_URL
:デプロイ前に本番データベースのマイグレーションを実行するために必要なHerokuの本番PostgreSQL URL。
本番DATABASE_URL
を取得する
データベースがプロビジョニングされたときにHerokuによって設定されたDATABASE_URL
を取得するには、次のHeroku CLIコマンドを使用します。
チェックポイント:出力にURL(例:postgres://username:password@ec2-12.eu-west-1.compute.amazonaws.com:5432/dbname
)が表示されるはずです
HEROKU_API_KEY
を取得する
Heroku APIキーは、Herokuアカウント設定から取得できます
GitHubでシークレットを作成する
4つのシークレットを作成するには、リポジトリ設定に移動し、Secretsタブを開きます
[New secret]をクリックし、シークレット名(例:HEROKU_APP_NAME
)に名前フィールドを使用し、値を設定します
チェックポイント:4つのシークレットを作成した後、次の内容が表示されるはずです
Herokuで環境変数を定義する
バックエンドには、ランタイム時に環境変数としてアプリケーションに渡される3つのシークレットが必要です
SENDGRID_API_KEY
:SendGrid APIキー。JWT_SECRET
:JWTトークンの署名に使用されるシークレット。DATABASE_URL
:Herokuによって自動的に設定されたデータベース接続URL。
注:
JWT_SECRET
は、ターミナルで次のコマンドを実行して生成できます:node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"
Heroku CLIで設定するには、次のコマンドを使用します。
チェックポイント:環境変数が設定されたことを確認するには、次の内容が表示されるはずです
ワークフローをトリガーしてテストとデプロイを実行する
ワークフローが構成され、Herokuにアプリが作成され、すべてのシークレットが設定されたので、ワークフローをトリガーしてテストとデプロイを実行できます。
ビルドをトリガーするには、空のコミットを作成してプッシュします
コミットをプッシュしたら、GitHubリポジトリの[Actions]タブに移動すると、次の内容が表示されるはずです
コミットメッセージを含むテーブルの最初の行をクリックします
test
ジョブのログを表示する
test
ジョブのログを表示するには、[test
]をクリックすると、各ステップのログを表示できます。たとえば、下のスクリーンショットでは、テストの結果を表示できます
Herokuへのデプロイメントを検証する
deploy
ジョブがHerokuに正常にデプロイされたことを検証するには、左側の[deploy
]をクリックし、[Deploy to Heroku
]ステップを展開します。ログの最後に次の行が表示されるはずです
ブラウザからAPIにアクセスするには、クローンされたリポジトリフォルダーから次のHeroku CLIコマンドを使用します。
これにより、https://YOUR_APP_NAME.herokuapp.com/
を指すブラウザが開きます。
チェックポイント:ブラウザに{"up":true}
が表示されるはずです。これは、ステータスエンドポイントによって提供されます。
バックエンドログを表示する
バックエンドのログを表示するには、クローンされたリポジトリフォルダーから次のHeroku CLIコマンドを使用します。
ログインフローをテストする
ログインフローをテストするには、REST APIへの2つの呼び出しを行う必要があります。
まず、APIのURLを取得します
curlを使用してログインエンドポイントにPOST呼び出しを行います
メールで8桁のトークンを確認し、2番目の呼び出しを行います
チェックポイント:レスポンスは200の成功ステータスコードを持ち、JWTトークンを含むAuthorization
ヘッダーが含まれている必要があります
まとめ
バックエンドがデプロイされ、実行されています。よくできました!
GitHub Actionsワークフローを定義し、Herokuアプリを作成し、PostgreSQLデータベースをプロビジョニングし、GitHub Actionsを使用してバックエンドをHerokuにデプロイすることにより、継続的インテグレーションとデプロイメントを構成しました。
リポジトリにコミットして変更をプッシュすることにより新機能を導入すると、テストとTypeScriptコンパイラーが自動的に実行され、成功した場合、バックエンドがデプロイされます。
Herokuダッシュボードにアクセスすると、メモリ使用量、応答時間、スループットなどのメトリクスを表示できます。これは、バックエンドがさまざまなトラフィック量をどのように処理するかについての洞察を得るのに役立ちます。たとえば、バックエンドへの負荷が増加すると、応答時間が遅くなる可能性があります。
TypeScriptとPrisma Clientを使用することで、通常はランタイムで検出され、デバッグが必要になる可能性のあるタイプエラーのクラスを排除できます。
バックエンドの完全なソースコードはGitHubで見つけることができます。
Prismaはリレーショナルデータベースの操作を容易にすることを目指していますが、基盤となるデータベースとHeroku固有の詳細を理解することは役立ちます。
質問がある場合は、Twitterでお気軽にお問い合わせください。
次回の投稿をお見逃しなく!
Prismaニュースレターにサインアップ