Alexa ASK CLI を v2 にバージョンアップして、スキルプロジェクトを v2 用にマイグレーション

# はじめに

とある事情により、ASK CLI を v1 から v2 にしてしまったため、今まで作ったスキルのスキルプロジェクトも v2 にマイグレーションしなければならなくなった。なので、[モンスターの情報](https://amzn.to/2WefmEi)というスキルをマイグレーションしてみることにした。

`ASK CLI`が`v2`にバージョンアップされたことで、スキルを管理するスキルプロジェクトフォルダの構成やファイルの配置が変更されたため、`v1`用のスキルプロジェクトフォルダを`v2`用にマイグレ―ションしてあげる必要がある。

# 前提

- ASK CLI v2 に[バージョンアップ](https://qiita.com/takara1121/items/54d34036d108fea04982)する前に、スキルを最新の状態にしておく
- ASK CLI v2 がインストールされている

# マイグレーションの流れ


<img width="70%" alt="マイグレーションイメージ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/c7c6470c-8424-80d1-21b7-495f49739787.png">

1. スキルプロジェクトフォルダをマイグレーションする
2. スキルをデプロイする


# スキルプロジェクトフォルダをマイグレーションする

スキルプロジェクトのルートディレクトリに移動して下記コマンドを実行する。これだけ。

```
ask util upgrade-project
```

コマンドを実行したときに`[Info]: New MINOR version...`と表示されたら、`npm upgrade -g ask-cli`でASK CLIをアップグレードする。

このコマンドを実行することで、v1 のスキルプロジェクトのフォルダ構成およびファイルが v2 用に変更される。スキルプロジェクト毎にやる必要がある。


以下のような事が書いてある。
- v1 スキルのファイルやフォルダは　`./.legacy` 配下に、まるっと移動される。
- skill.jsonや、インタラクションモデルなどのJSONファイルは `./skill-package` 配下に移動される。
- lambdaは、`.\lambda\custom` から`.\lambda\lambdacustom`にフォルダ名が変更される。 

```
##########################################################################
[Info]: New MINOR version (v2.2.0) of ask-cli is available now. Current version v2.1.1.
It is recommended to use the latest version. Please update using "npm upgrade -g ask-cli".
##########################################################################

Preview of the upgrade result from v1 to v2:
- The original v1 skill project will be entirely moved to .\.legacy\
- JSON files for Skill ID amzn1.ask.skill.3cde50e1-xxxx-xxxx-xxxx-55431160679e (such as skill.json) will be moved to .\skill-package\
- Existing Lambda codebase will be moved into "lambda" folder
  - Region default: v1 "lambda/custom" -> v2 ".\lambda\lambdacustom" for existing Lambda ARN arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:ask-custom-MonHun-default
? Do you want to execute the upgrade based on the preview above?  (Y/n)

Y <ENTER>

? Do you want to execute the upgrade based on the preview above?  Yes
Project migration finished.
```

`[Info]:` を無視して、マイグレーションを実施！
マイグレーションは、ものの数秒から数十秒で完了した。（※スキルのボリュームによって時間は異なる。）


```:マイグレーション前
MonHun
│  .gitattributes
│  .gitignore
│  LICENSE.txt
│  README.md
│  skill.json
│  
├─.ask
│      config
│      
├─.github
│      PULL_REQUEST_TEMPLATE.md
│      
├─hooks
│      :
│      
├─instructions
│      :
│      
├─lambda
│  └─custom
│      │  index.js
│      │  local-debugger.js
│      │  package-lock.json
│      │  package.json
│      │  util.js
│      │  
│      └─node_modules
│          │      :
│                      
└─models
        ja-JP.json
```

　
`ASK CLI v2`ではスキルパッケージ形式（`skill-package`）が採用されているので、その構造に合わせるようにファイルが再配置されている。スキルパッケージ形式の場合、スキルアイコンの画像をローカルのフォルダ内で管理する必要があるため、アイコンが設定されている場合は、マイグレーション時にファイルを自動生成してくれる。
 
スキル内課金を使用している場合は、`skill-package`の配下に`isp`フォルダが生成される。
また、カスタムタスクを使う場合は、`skill-package`の配下に`tasks`フォルダを作ってタスクを管理する。

```:マイグレーション後
MonHun
│  .gitattributes
│  .gitignore
│  ask-resources.json      ※.ask/config ⇒ ask-resources.json
│  
├─.ask
│      ask-states.json
│      
├─.github
│      PULL_REQUEST_TEMPLATE.md
│      
├─.legacy　　　　　　　　　　※v1スキルは、.legacy配下にまるっとコピーされている
│  │  LICENSE.txt
│  │  README.md
│  │  skill.json
│  │      :
│  │      
│  └─models
│          ja-JP.json
│          
├─lambda
│  └─lambdacustom           ※./lambda/custom ⇒ ./lambda/lambdacustom
│      │  index.js
│      │  local-debugger.js
│      │  package-lock.json
│      │  package.json
│      │  util.js
│      │  
│      └─node_modules
│          │      :
│                      
└─skill-package
    │  skill.json           ※./skill.json ⇒ ./skill-package/skill.json
    │  
    ├─assets
    │  └─images             ※スキルアイコンファイルが生成されている
    │          ja-JP_largeIconUri.png
    │          ja-JP_smallIconUri.png
    │          
    └─interactionModels
        └─custom
                ja-JP.json  ※./models/ja-JP.json ⇒ ./skill-package/interactionModels/custom/ja-JP.json
```

### ※ファイルを削除してしまったら

ちなみに、このような場合マイグレーションできるのか。

- `config`ファイルがない場合
エラーとなりマイグレーションできなくなった。諦めて[スキルプロジェクトをセットアップ](https://qiita.com/takara1121/items/d0c593c0a37668e6a953)するしかない。

- `skill.json`などのJSONファイルがない場合
マイグレーションは成功して、さらにJSONファイルが自動生成される。
ローカルPC上に最新のJSONファイルないような場合は、思い切ってローカルファイルを削除してしまうのも手かもしれない。正解かはわからないけど。

- `index.js`がない場合
マイグレーションは成功したが、index.jsは生成されない。

||ASK CLI v1| |ASK CLI v2|マイグレーション|
|:--|:--|:-:|:--|:-:|
|skill|config|⇒|エラー|×|
|   |skill.json|⇒|skill.json自動生成(*)|○|
|model|ja-JP.json|⇒|ja-JP.json自動生成(*)|○|
|lambda|index.js|⇒|生成されない|○|

(*)開発版スキルの内容で自動生成される。

### ※.legacy はバックアップ

`.legacy` は ASK CLI v1 でデプロイできる。
`.legacy` は バックアップなので、`v2` でデプロイできたら削除してしまって問題ない。削除はちょっとという場合は、別の場所にアーカイブしておくのがおすすめ。理由は、そこそこの容量になっているので。

# スキルをデプロイする

マイグレーションが完了したので、何も考えずに、そのままデプロイしてみる。

`[Warn]: ` 警告が出た。これは、スキルパッケージフォルダーのハッシュ値が前回から変更されていなかったため、スキルパッケージのデプロイをスキップしたというもの。問題なし。
と思ったら`[Error]: `エラーも出た・・・

```
PS C:MonHun> ask deploy
##########################################################################
[Info]: New MINOR version (v2.2.0) of ask-cli is available now. Current version v2.1.1.
It is recommended to use the latest version. Please update using "npm upgrade -g ask-cli".
##########################################################################

==================== Deploy Skill Metadata ====================
[Warn]: The hash of current skill package folder does not change compared to the last deploy hash result, CLI will skip the deploy of skill package.
Skill ID: amzn1.ask.skill.3cde50e1-xxxx-xxxx-xxxx-55431160679e

==================== Build Skill Code ====================
npm WARN hello-world@1.1.0 No repository field.

Skill code built successfully.
Code for region default built to C:\work\AlexaSkills\MonHun\.ask\lambda\lambdacustom\build.zip successfully with build flow nodejs-npm.

==================== Deploy Skill Infrastructure ====================
  √ Deploy Alexa skill infrastructure for region "default"
[Error]: {
  "message": "Skill manifest is not valid.",
  "violations": [
    {
      "code": "INVALID_URL_FORMAT",
      "message": "String instance with value \"file://assets/images/ja-JP_smallIconUri.png\" at property path \"$.manifest.publishingInformation.locales.ja-JP.smallIconUri\" is not a valid URL.",    
      "validationDetails": {
        "originalInstance": {
          "dataType": "string",
          "propertyPath": "$.manifest.publishingInformation.locales.ja-JP.smallIconUri",
          "type": "BODY",
        }
      }
    },
    {
      "code": "INVALID_URL_FORMAT",
      "message": "String instance with value \"file://assets/images/ja-JP_largeIconUri.png\" at property path \"$.manifest.publishingInformation.locales.ja-JP.largeIconUri\" is not a valid URL.",    
      "validationDetails": {
        "originalInstance": {
          "dataType": "string",
          "propertyPath": "$.manifest.publishingInformation.locales.ja-JP.largeIconUri",
          "type": "BODY",
          "value": "file://assets/images/ja-JP_largeIconUri.png"
        }
      }
    }
  ]
}
PS C:\MonHun>
```

### ※エラー発生

（※v2.8.0では解消されていた。）

エラーの内容からすると、どうやらスキルアイコン画像のURLがダメっぽい。
※多言語用のスキルをマイグレーションすると、このエラーがバンバン出るのでちょっとビビる。

"String instance with value \"file://assets/images/ja-JP_smallIconUri.png\" at property path \"$.manifest.publishingInformation.locales.ja-JP.smallIconUri\" is not a valid URL."


```:skill.json（修正前）
          "smallIconUri": "https://dl.dropboxusercontent.com/s/vk8btpoi1shbv29/MonHun_s.png",
          "largeIconUri": "https://dl.dropboxusercontent.com/s/d3l8hoac4h60end/MonHun_l.png",
```

画像は全てdropboxに置いてたし今でも見れるはずなんだけど・・・画像は外部URLじゃダメなのか？
ということで、[スキルマニフェストのスキーマ](https://developer.amazon.com/ja-JP/docs/alexa/smapi/skill-manifest.html#locales)を見直してみたところ、v2からは、スキルパッケージ方式が採用されていて、その方式の場合は、アイコンなどの画像ファイルもローカルで管理する必要があるとのこと。なので、そのように変更した。

マイグレーション実行時に自動で書き換えて欲しいな。
※自動で書きかわることもあるっぽいな。動作がいまいちわからない。

```:skill.json（修正後）
          "smallIconUri": "file://assets/images/ja-JP_smallIcon.png",
          "largeIconUri": "file://assets/images/ja-JP_largeIcon.png",
```

そして、再デプロイ。

```
PS C:\MonHun> ask deploy
##########################################################################
[Info]: New MINOR version (v2.2.0) of ask-cli is available now. Current version v2.1.1.
It is recommended to use the latest version. Please update using "npm upgrade -g ask-cli".
##########################################################################

==================== Deploy Skill Metadata ====================
Skill package deployed successfully.
Skill ID: amzn1.ask.skill.3cde50e1-xxxx-xxxx-xxxx-55431160679e

==================== Build Skill Code ====================
npm WARN hello-world@1.1.0 No repository field.

Skill code built successfully.
Code for region default built to C:\work\AlexaSkills\MonHun\.ask\lambda\lambdacustom\build.zip successfully with build flow nodejs-npm.

==================== Deploy Skill Infrastructure ====================
  √ Deploy Alexa skill infrastructure for region "default"
Skill infrastructures deployed successfully through @ask-cli/lambda-deployer.

==================== Enable Skill ====================
Skill is already enabled, skip the enable process.
PS C:\MonHun>
```

今度は成功した。

開発中スキルの更新日が更新されているのを確認。また、Lambda関数の最終更新日時も変更されていることを確認。スキルも正常動作することを確認。

![モンスターの情報](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/7e454bc9-d153-cad5-716a-836c91f98438.png)

# おわりに

仕事では様々なマイグレーションに携わってきたが、ほとんどがうまく動かなかった。こんなにすんなりマイグレできたのは初めてかも・・・

Lambda関数をデプロイする際に、AWS CloudFormationを使用する場合は、マイグレーションした後に`ask init`して、CloudFormationの.yamlを生成するか、マイグレーションではなく、セットアップしても良いと思う。

# 参考

- [スキルマニフェストのスキーマ（※Amazon公式サイト）](https://developer.amazon.com/ja-JP/docs/alexa/smapi/skill-manifest.html)

# 関連

- [Alexa ASK CLI を v2 へバージョンアップしてスキルを新規作成](https://qiita.com/takara1121/items/54d34036d108fea04982)
- [Alexa ASK CLI v2用のスキルプロジェクトをセットアップする](https://qiita.com/takara1121/items/d0c593c0a37668e6a953)
- [モンスターの情報（Alexaスキル）](https://amzn.to/2WefmEi)