しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Kudu のデプロイスクリプトを PowerShell で書き直してみた

Azure Web Apps に Git でデプロイする場合に作られるデプロイスクリプトは、バッチファイルと bash の 2 種類を選択できますが、正直なところ機能不足感が否めません。

タイトル通りですが deploy.cmd を PowerShell で書き直しました。これで柔軟に処理が書けるはずです。

# ----------------------
# KUDU Deployment Script
# Version: 0.2.2
# ----------------------

# Helpers
# -------

function exitWithMessageOnError($1) {
  if ($? -eq $false) {
    echo "An error has occurred during web site deployment."
    echo $1
    exit 1
  }
}

# Prerequisites
# -------------

# Verify node.js installed
where.exe node 2> $null > $null
exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment."

# Setup
# -----

$SCRIPT_DIR = $PSScriptRoot
$ARTIFACTS = "$SCRIPT_DIR\..\artifacts"

$KUDU_SYNC_CMD = $env:KUDU_SYNC_CMD

$DEPLOYMENT_SOURCE = $env:DEPLOYMENT_SOURCE
$DEPLOYMENT_TARGET = $env:DEPLOYMENT_TARGET

$NEXT_MANIFEST_PATH = $env:NEXT_MANIFEST_PATH
$PREVIOUS_MANIFEST_PATH = $env:PREVIOUS_MANIFEST_PATH

if ($DEPLOYMENT_SOURCE -eq $null) {
  $DEPLOYMENT_SOURCE = $SCRIPT_DIR
}

if ($DEPLOYMENT_TARGET -eq $null) {
  $DEPLOYMENT_TARGET = "$ARTIFACTS\wwwroot"
}

if ($NEXT_MANIFEST_PATH -eq $null) {
  $NEXT_MANIFEST_PATH = "$ARTIFACTS\manifest"

  if ($PREVIOUS_MANIFEST_PATH -eq $null) {
    $PREVIOUS_MANIFEST_PATH = $NEXT_MANIFEST_PATH
  }
}

if ($KUDU_SYNC_CMD -eq $null) {
  # Install kudu sync
  echo "Installing Kudu Sync"
  npm install kudusync -g --silent
  exitWithMessageOnError "npm failed"

  # Locally just running "kuduSync" would also work
  $KUDU_SYNC_CMD = "$env:APPDATA\npm\kuduSync.cmd"
}

##################################################################################################################################
# Deployment
# ----------

echo "Handling Basic Web Site deployment."

# 1. KuduSync
if ($env:IN_PLACE_DEPLOYMENT -ne "1") {
  & $KUDU_SYNC_CMD -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.ps1"
  exitWithMessageOnError "Kudu Sync failed"
}

##################################################################################################################################

# Post deployment stub
if ($env:POST_DEPLOYMENT_ACTION -ne $null) {
  & $env:POST_DEPLOYMENT_ACTION
  exitWithMessageOnError "post deployment action failed"
}

echo "Finished successfully."

相変わらず PowerShell 力は低い感じですが、ひとまず動作するものを作ることが出来ました。基本的な方針として処理の流れをバッチファイル版に合わせてあります。

.deployment ファイルを作成し、PowerShell を使ってスクリプトを実行するコマンドを追加しておきます。

[config]
command = powershell -NoProfile -NoLogo -ExecutionPolicy Unrestricted -File deploy.ps1

これを Web Apps にデプロイすると、これまで通りにデプロイされるのが確認できます。

たまに "Window title cannot be longer than 1023 characters" というエラーが表示されて失敗することがありますが、ポータルから再デプロイを行うと問題なく動きます。

同様のエラーが WebJob を PowerShell で書いた時にも発生しているようです。何となく Web Apps 側の問題なのではないかと思っていますが、原因はよくわかっていません。

上に載せたスクリプトはシンプルな Web サイトをデプロイするものでしたが、ちょっと修正すると ASP.NET アプリケーションのデプロイも行えるようになります。

いちいち手書きするのはとてもめんどくさいので、デプロイスクリプトのジェネレータである KuduScript を弄って PowerShell 版のスクリプトを生成できるようにしました。

https://github.com/shibayan/KuduScript/tree/powershell

git clone してから NPM を使ってインストールすると、ローカルで使えるようになります。具体的なインストール手順を念のために書いておきます。

npm install

npm -g install "kuduscript へのフルパス"

kuduscript -y -t posh -aspWAP WebApplication\WebApplication.csproj -s WebApplication.sln

これで ASP.NET アプリケーションのデプロイ用スクリプトが PowerShell で生成されます。