Nxモノレポ上でAzure Functionsをビルド・デプロイできるようにするメモ
有志の人が以下のようなNxのインテグレーションを用意してくれていた
この記事も参考になる
有志の人がesbuild-azure-functionsというnpmパッケージを作成してくれていた。これでesbuildに最適なオプションを渡せるらしい。
自分としてはひとまずシンプルに行きたいので、Nx上でesbuildが実行できればいい。
Nx公式のesbuild executorを使うことにした。
上の記事を参考にesbuildのビルドオプションをproject.jsonに追記する。最終的に以下のようになった。
関数が増えるごとに additionalEntryPoints を増やさなければならないが、仕方ないか。
"build": {
"executor": "@nrwl/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"options": {
"bundle": true,
"thirdParty": false,
"format": ["cjs"],
"platform": "node",
"target": "node16",
"skipTypeCheck": false,
"outputPath": "apps/azfunc/dist",
"additionalEntryPoints": [
"apps/azfunc/HttpTrigger/index.ts"
],
"main": "apps/azfunc/src/main.ts",
"tsConfig": "apps/azfunc/tsconfig.app.json",
"assets": ["apps/azfunc/src/assets"]
},
"configurations": {
"production": {
"minify": true,
"sourcemap": false
}
}
},
Azure Functionsは拡張子が .mjs のファイルをES Modulesのファイルとして認識し、それ以外はCommonJSと認識する。なので、生成されるファイルの拡張子を.mjsにしなければならないのだが、Nxのesbuild executorのソースコードを見ると、そのオプションが潰されてしまっている。何か理由があるのだろうか。
まあES Modulesでなくてもいいやと思い、CommonJSでビルドすることにした。
Azure Functionsをローカルからデプロイするときには以下のコマンドを使った
func azure functionapp publish {functionsのリソースid}
だが、このコマンドを実行しても関数が生えてこない。このコマンドはカレントディレクトリのdistにあるビルド成果物を見に行くようだ。function.jsonのscriptFileに リポジトリルート/dist までの相対パスを書いてあげても意味がなかった。仕方がないので、apps/azfunc/dist にビルド成果物を吐くようにした。
GitHub ActionsでCIを組んだ。最終的なWorkflowは以下のようになった。
Azure Functionsのマネジメントコンソールから、GitHub CIの設定を行うと、テンプレートとなるWorkflowを勝手にコミットし、シークレットも設定してくれた。
ポイントは、モノレポのFunctionsのディレクトリまでcdして、esbuildによって生成されたpackage.jsonでnpm installしているところだ。こうすることで、カレントディレクトリに.node_modulesが生成され、デプロイのときにそれを含めてくれるようになる。
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@v2
- uses: pnpm/action-setup@v2
with:
version: 7
- uses: actions/setup-node@v3
with:
node-version: 16
cache: pnpm
- run: pnpm install --frozen-lockfile --ignore-scripts
- run: pnpm exec nx build azfunc
- run: |
cp dist/package.json .
npm install
working-directory: apps/azfunc
- name: 'Run Azure Functions Action'
uses: Azure/functions-action@v1
id: fa
with:
app-name: '{Functionsのリソース名}'
slot-name: 'Production'
package: apps/azfunc
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_XXXXXXXXXXXXXX }}
CIでのデプロイ前にローカルからfunc azureコマンドでデプロイをしたせいか、FunctionsのConfigulationにWEBSITE_RUN_FROM_PACKAGEという設定が追加されており、これによってCIが以下のようなエラーを吐いた。WEBSITE_RUN_FROM_PACKAGEを削除することで解決した。
When request Azure resource at PublishContent, zipDepoy : WEBSITE_RUN_FROM_PACKAGE in your function app is set to an URL. Please remove WEBSITE_RUN_FROM_PACKAGE app setting from your function app.