【Github】GithubActionからSQLDatabaseにEFCoreのマイグレーション実施


Azure SQL Database に DB を構築して使用している際に DB の更新をこれまではローカル PC から EF Core コマンドを直接実行して更新していました。

しかしこの方法だとローカル DB と本番環境で 2 回手動で実行が必要であり二度手間でした。そこで本番環境へ Github Actions 経由でデプロイを行った際に同時に DB も更新されるようにしました。

その方法をまとめます。

## 結論

大きく分けて 2 つの対応が必要です。

- Github Actions から Azure にログイン
- Github Actions のコマンドライン上から DB 更新を実施

## Github Actions から Azure にログイン

当然だが Azure SQL Database は Azure 上に存在する。Github からアクセスするためにはフロー上でログインする必要があります。
公式ページを参考に認証を追加します。

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/connect-github-actions-sql-db?view=azuresql&tabs=openid

認証はサービスプリンシパルと OpenID Connect の 2 種類が存在しますが今回は後者で実施しました。

詳しい対応方法は下記記事を参照してください。

https://qiita.com/KM_20005/items/e0b24b0632b30783fd3e

`azure/login@v2`を実行した際にエラーにならなければ OK です。

## Github Actions のコマンドライン上から DB 更新を実施

普段 Visual Studio のパケージマネージャーコンソールで実施しているコマンドを PowerShell などの外部から実施することができる dotnet コマンドが MicroSoft から用意されています。今回はその中で`Database Update`コマンドを使用します。

このコマンドはオプションでデータベースへの接続文字列を実行時に引数として受け取ることが可能です。

https://learn.microsoft.com/ja-jp/ef/core/cli/dotnet#dotnet-ef-database-update

Github のシークレット経由で Azure SQL Database の接続文字列を渡すことで Github Actions 上から Azure SQL Database への更新を行うことができます。

### 使用する接続文字列の取得

Azure のポータルより対象の DB を選択して左側のサイドバーから[概要]を選択して表示されるページで[使用を開始する]から[検索文字列の参照]を選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/2d992fce-d5de-9ae8-c0e1-1d6fed36778d.png)

表示される接続文字列の中から[ADO.NET(SQL 認証)]の文字列をコピーしてパスワードを設定したものに変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/b28c312c-8236-47f4-37ce-7a3fd9dfc54f.png)

取得した文字列を Github のシークレットに格納すれば取得は完了です。

:::note warn
Database の認証について最初は MicroSoft Entra のパスワードレス認証で行おうとしていました。しかしアップデート処理時にサーバー orDB にログインすることが出来ずに失敗しました。

今思うと OIDC で設定したアカウントと Azure SQL Database の MicroSoft Entra のパスワードレス認証に設定したアカウントが異なっていたため認証に失敗していたような気がしています。ただしそうなると App Service からアクセスする際にもそのアカウントである必要があり(多分)、その辺のアーキテクチャや設定方法は別の機会に調査します。
:::

### yml ファイルにアップデートコマンドの追加

最後に yml ファイルにアップデートコマンドを記載して実行すれば完了です。

```yml
- name: Run EF Core migrations
  run: |
    cd .\BizCardKeeper.Server\
    dotnet tool install --global dotnet-ef
    dotnet ef database update --connection '${{ secrets.AZURE_SQL_CONNECTION_STRING }}'
```

この時、必要に応じてコマンド実行前にディレクトリ移動を行ってください。

例えば React ＋ ASP.net Core のアプリを Visual Studio から新規作成したとします。その際のディレクトリは下記ように生成されます。

```
Project <- デフォルトのコマンド実行ディレクトリ
├── project.client
└── Project.Server <- コマンドを実行したいディレクトリ
```

デフォルトでコマンドを実行すると一番親ディレクトリでコマンドが実行されるため今回の例では「Project」フォルダでコマンドが実行されますが失敗します。「Project.Server」に移動してから実行すると正常に実行されます。

:::note info
この考え方は EFCore に限らず Github Actions でフロントエンドのテストを実行するときなども必要なため早めに覚えるのがおすすめです。
:::

## 最終的な yml ファイル

コマンド周りを抜粋

```yml
- uses: actions/checkout@v1
- uses: azure/login@v2
  with:
    client-id: ${{ secrets.AZURE_CLIENT_ID }}
    tenant-id: ${{ secrets.AZURE_TENANT_ID }}
    subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Run EF Core migrations
  run: |
    cd .\BizCardKeeper.Server\
    dotnet tool install --global dotnet-ef
    dotnet ef database update --connection '${{ secrets.AZURE_SQL_CONNECTION_STRING2 }}'
```

## おわりに

ここまで Github Actions から Azure SQL Database に更新を行うための方法をまとめました。 上記を用いることで環境ごとにデプロイタイミングに DB が更新できることが担保できるうえ手動で作業する手間も省けます。

また実行するコマンドをうまく変えれば別の言語の ORM を使用していたとしても同じように更新を実行できるはずです。

この記事が皆様のコーディングライフの助けになれば幸いです。

## 参考

https://learn.microsoft.com/ja-jp/azure/azure-sql/database/connect-github-actions-sql-db?view=azuresql&tabs=openid

https://learn.microsoft.com/ja-jp/ef/core/cli/dotnet#dotnet-ef-database-update

https://qiita.com/KM_20005/items/e0b24b0632b30783fd3e