※24/01/18追記
iOS16以上から UnityCloudBuild上でビルドしていないと
iPhone/iPadにインストール出来なくなっています…。
UnityForum 22/10/11に質問あがってましたが 未だ解決せず [UnityForum]
私は諦めて Firebase AppDistributionを使用することにしました。
※19/07/12追記
いつの間にか変わって無料でも出来るぽい [公式]
※19/06/26追記
2018年1月くらいから UnityCloudBuild、有料化したんですね(Advanced・Proのみ)
知りませんでした… [公式]
※この記事を書いてる途中(2019/4/17)に ふとググったら去年10月[公式]に…
それはさておき、2017年12月15日に
Unity Cloud Buildがローカル環境で作ったビルド成果物をアップロードできるようになった
という記事を見かけました。
しかし、WebからじゃなくCLIからアップロードしたいと思い、
きっと誰かが良い記事書いてくれるのでは…と思ってましたが
びっくりするくらい簡単なDeployGate1があるせいか、
はたまた そもそも興味持たれないのか 待てど暮らせど見つからず2
CloudBuildのページあたりを見ていましたらAPIドキュメント発見
CloudBuild API Document (v1.0.0時点)
https://build-api.cloud.unity3d.com/
よし作ってみるか!
…なるほど、まったくわからん
とまでは行きませんでしたが
ChromeDeveloperで挙動やログを追いかけて なんとか出来ました 3
どれだけの方が利用するかわかりませんが、とりあえず公開
前提
- 私の環境: MacOSX10.14.4(iMac4K)
- 成果物は apk / ipa のみしかアップロードチェックしていません
-
unity DashBoard
にて アプリ名登録まで済んでいるものとします - bashシェルスクリプトで順番に説明
- json解析にjqを使用
- 置換にgsedを使用
- curl等、色々間違ってたらすいません…
- ですので最低限のみ記載
以下スクショの文字列は例ですので DashBoard眺めてメモってください。
PROJECT_ID(ここではTest)と UPID(ここでは3dc…)をメモ
Testの下の ORG_ID(ここではdeveloper…)をメモ
成果物ファイル名は アスキーコード 0x20〜0x40 辺りを使ってましたら
%20〜%40 に変換してください(URLEncode?)
初期設定
API_KEY= #DashBoard - プロジェクト - Develop - Settings - Cloud Build - APIキーに書いてある
PROJECT_ID= #DashBoard - プロジェクト名
ORG_ID= #DashBoard - プロジェクト名の下に書いてある
UP_ID= #DashBoard - プロジェクト - プロジェクト名の横に書いてあるUPID
FILE_NAME= #成果物ファイル名 xxxx.ipa 等をURLEncode
EXT= #成果物の拡張子(つまりapkかipa)
FILE_SIZE= #成果物のファイルサイズ `wc -c < 成果物ファイル名` とか
if [ "${EXT}" = "apk" ]; then
PLATFORM=android
TYPE_NAME=".APK file"
TYPE_NAMEe=".APK%20file"
elif [ "${EXT}" = "ipa" ]; then
PLATFORM=ios
TYPE_NAME=".IPA file"
TYPE_NAMEe=".IPA%20file"
else
exit 1
fi
BUILD_API_DOMAIN="https://build-api.cloud.unity3d.com/api/v1"
ARTIFACT_API_DOMAIN="https://build-artifact-api.cloud.unity3d.com/api/v1"
BUILD_TARGET_ID="_local"
LOG=`mktemp --tmpdir=./`
function endJob {
echo $1
rm ${LOG}
}
ビルドエリア生成して ビルド番号取得
curl -X POST -H "Content-Type: application/json" -H "Authorization: Basic ${API_KEY}" --data-binary "{\"platform\": \"${PLATFORM}\", \"label\": \"${COMMENT}\"}" ${BUILD_API_DOMAIN}/orgs/${ORG_ID}/projects/${PROJECT_ID}/buildtargets/${BUILD_TARGET_ID}/builds -o ${LOG} -s
BUILD_NO=`cat ${LOG} | jq .[0].build`
STAT=`cat ${LOG} | jq .[0].buildStatus`
if [ "${STAT}" != "\"success\"" ]; then
endJob "BuildArea - Error: ${STAT}"
exit 1
fi
アーティファクト生成
curl -X POST -H "Content-Type: application/json" -H "Authorization: Basic ${API_KEY}" --data-binary "{\"name\":\"${TYPE_NAME}\",\"primary\":true,\"public\":false,\"files\":[{\"filename\":\"${FILE_NAME}\",\"size\":${FILE_SIZE}}]}" ${ARTIFACT_API_DOMAIN}/projects/${UP_ID}/buildtargets/${BUILD_TARGET_ID}/builds/${BUILD_NO}/artifacts -o ${LOG} -s
STAT=`cat ${LOG}`
if [ "${STAT}" != "Created" ]; then
endJob "Generate Artifact - Error: ${STAT}"
exit 1
fi
アップロード
hc=$( curl -d "" -X POST -H "Upload-Length: ${FILE_SIZE}" -H 'Tus-Resumable: 1.0.0' -H 'Content-Type: application/offset+octet-stream' -H "Authorization: Basic ${API_KEY}" ${ARTIFACT_API_DOMAIN}/projects/${UP_ID}/buildtargets/${BUILD_TARGET_ID}/builds/${BUILD_NO}/artifacts/${TYPE_NAMEe}/upload/${FILE_NAME} -o ${LOG} -w '%{http_code}\n' -s )
if [ $hc != 201 ]; then
STAT=`cat ${LOG}`
endJob "Upload Post - Error: $hc\n${STAT}"
exit 1
fi
hc=$( curl -X PATCH -H 'Upload-Offset: 0' -H "Content-Length: ${FILE_SIZE}" -H 'Tus-Resumable: 1.0.0' -H 'Content-Type: application/offset+octet-stream' -H "Authorization: Basic ${API_KEY}" --data-binary @"${1}" ${ARTIFACT_API_DOMAIN}/projects/${UP_ID}/buildtargets/${BUILD_TARGET_ID}/builds/${BUILD_NO}/artifacts/${TYPE_NAMEe}/upload/${FILE_NAME} -o ${LOG} -w '%{http_code}\n' -s)
if [ $hc != 204 ]; then
STAT=`cat ${LOG}`
endJob "Upload Patch - Error: $hc\n${STAT}"
exit 1
fi
シェアリンク作成
# GET:既に生成済みのShareID取得、POST:ShareID生成、DELETE:ShareID削除
curl -d "" -X POST -H "Content-Type: application/json" -H "Authorization: Basic ${API_KEY}" ${BUILD_API_DOMAIN}/orgs/${ORG_ID}/projects/${PROJECT_ID}/buildtargets/${BUILD_TARGET_ID}/builds/${BUILD_NO}/share -o ${LOG} -s
STAT=`cat ${LOG} | jq .shareid | gsed 's/"//g'`
if [ "${STAT}" == "null" ]; then
cat ${LOG}
endJob "ShareLink - failed"
exit 1
fi
SHARE_URL="https://developer.cloud.unity3d.com/share/${STAT}"
#ここらへんで SHARE_URL をチャット等に送る
endJob "success"
出来上がったSHARE_URLをチャットやメール等に流せばOKかと。
Android・iOSからダウンロード・インストール・実行出来ました。
みんな幸せにな〜れ
規約違反とかありましたら記事消します…。