CIのActivateとかでライセンスを自動でActivateさせたい!
CIでUnityを扱う時はJenkinsとかであれば問題ないのですが、CircleCIやGitHub Actionsを使用するときにDockerでのライセンス認証では.ulfファイルというのが必要になってきます。
現在.ulfファイルをコマンドラインから生成することはできません。生成するにはブラウザ経由の一択です。
それを今回Puppeteerというnode.jsのツールを使って自動化してみました。
※今回の認証フローはPersonalEdition固定になります。
Puppetterとは、Webブラウザでの操作をソースコードから行えるものになります。
詳しくはこちら
Puppeteer
今回のリポジトリはこちら
MizoTake/unity-license-activate
実装
npm経由でPuppeteerを入れて以下のjsで実装しました。
今回はライセンスの認証が必要になるので https://license.unity3d.com/manual
のページで操作を行います。
手元にあるalfファイルから最終的にulfファイルをダウンロードする操作になります。
叩くコマンドは以下になりますnode activate.js $email $password $alf_file_path
以下が今回のScriptの全容ですが細かく分けてどうなっているのか下で記述します。
activate.js
constpuppeteer=require('puppeteer')constfs=require('fs');(async()=>{constbrowser=awaitpuppeteer.launch()constpage=awaitbrowser.newPage()constdownloadPath=process.cwd()constclient=awaitpage.target().createCDPSession()awaitclient.send('Page.setDownloadBehavior',{behavior:'allow',downloadPath:downloadPath})awaitpage.goto('https://license.unity3d.com/manual')awaitpage.waitForNavigation({timeout:60000,waitUntil:'domcontentloaded'})constemail=`${process.argv[2]}`awaitpage.type('input[type=email]',email)constpassword=`${process.argv[3]}`awaitpage.type('input[type=password]',password)awaitpage.click('input[name="commit"]')awaitpage.waitForNavigation({timeout:60000,waitUntil:'domcontentloaded'})constinput=awaitpage.$('input[name="licenseFile"]')constalfPath=`${process.argv[4]}`awaitinput.uploadFile(alfPath)awaitpage.click('input[name="commit"]')awaitpage.waitForNavigation({timeout:60000,waitUntil:'domcontentloaded'})constselectedTypePersonal='input[id="type_personal"][value="personal"]'awaitpage.evaluate(s=>document.querySelector(s).click(),selectedTypePersonal)constselectedPersonalCapacity='input[id="option3"][name="personal_capacity"]'awaitpage.evaluate(s=>document.querySelector(s).click(),selectedPersonalCapacity)awaitpage.click('input[class="btn mb10"]')awaitpage.waitForNavigation()awaitpage.click('input[name="commit"]')let_=await(async()=>{letulfdo{for(constfileoffs.readdirSync(downloadPath)){ulf|=file.endsWith('.ulf')}awaitsleep(1000)}while(!ulf)})()functionsleep(milliSeconds){returnnewPromise((resolve,reject)=>{setTimeout(resolve,milliSeconds)})}awaitbrowser.close()})()
画面ごとの処理
// ライセンス認証を行うページに行くawaitpage.goto('https://license.unity3d.com/manual')awaitpage.waitForNavigation({timeout:60000,waitUntil:'domcontentloaded'})// ライセンス認証を行うページに飛ばしたがリダイレクトでUnityのログインページに飛んでいる//コマンド引数からメールアドレスとパスワードをとってくるconstemail=`${process.argv[2]}`awaitpage.type('input[type=email]',email)constpassword=`${process.argv[3]}`awaitpage.type('input[type=password]',password)// Sign inのボタンを押すawaitpage.click('input[name="commit"]')
↓
constinput=awaitpage.$('input[name="licenseFile"]')// コマンドライン引数で指定したpathからfileを添付constalfPath=`${process.argv[4]}`awaitinput.uploadFile(alfPath)// Nextボタンを押すawaitpage.click('input[name="commit"]')
これでファイル添付ができてることがわかります。ファイル添付までできるのすげぇ…Puppeteer…
↓
// Personal Editionの選択constselectedTypePersonal='input[id="type_personal"][value="personal"]'awaitpage.evaluate(s=>document.querySelector(s).click(),selectedTypePersonal)// Personal Edition選択後に出てくるのOptionを選択constselectedPersonalCapacity='input[id="option3"][name="personal_capacity"]'awaitpage.evaluate(s=>document.querySelector(s).click(),selectedPersonalCapacity) // Nextボタンを押すawaitpage.click('input[class="btn mb10"]')
↓
// Download license fileボタンを押すawaitpage.click('input[name="commit"]')// ダウンロードが始まるので手元に.ulfファイルができるまで待つlet_=await(async()=>{letulfdo{for(constfileoffs.readdirSync(downloadPath)){ulf|=file.endsWith('.ulf')}awaitsleep(1000)}while(!ulf)})()functionsleep(milliSeconds){returnnewPromise((resolve,reject)=>{setTimeout(resolve,milliSeconds)})}
以上のような流れになっています。
さいごに
Puppeteer便利!!!!
awaitpage.screenshot({path:"./example.png"});
でScreenShotを撮りつつ実装してました。
ブラウザでしか行えない操作もこれがあればできるので色々と捗るんじゃないかなと思っています。