tagをGitHubにpushしたらAWS CodeBuildでElectronのビルドが走ってGitHubのReleaseにzipをアップロードするところまでを自動化してみた。GitHubとCodeBuildをどうインテグレーションするのがいいかよくわからなかったのでAPI GatewayとLambdaでつないだ。
コードはここに。
Electronのビルド
まずはElectronをビルドするビルドスクリプトを書く。
#!/bin/sh
set -e
OUT_DIR=./dist
rm -rf $OUT_DIR
./node_modules/.bin/electron-packager . Test \
--platform=darwin \
--arch=x64 \
--overwrite \
--app-version=$BUILD_VERSION \
--build-version=$BUILD_VERSION \
--out=$OUT_DIR
cd dist
zip -qry Test-$BUILD_VERSION-darwin-x64.zip Test-darwin-x64
これで次のようなコマンドを実行してzipファイルを作れるようにしとく。
$ BUILD_VERSION=v1.0.0 ./build.sh
次にAWS CodeBuildでprojectを作って、buildspec.yml
をこんな感じで書いてAWSコンソールとかからビルド実行すればビルドできるようになる。環境変数は実行時に指定できる。
version: 0.1
phases:
install:
commands:
- npm install
build:
commands:
- /bin/sh ./build.sh
GitHubのWebhookでCodeBuildをキックする
次にLambdaにfunctionを作る。
exports.handler = (event, context, callback) => {
var AWS = require('aws-sdk');
var codebuild = new AWS.CodeBuild();
var body = JSON.parse(event.body);
if (body.ref_type !== 'tag') {
callback(null, { statusCode: 200 });
return;
}
codebuild.startBuild({
projectName: 'electron-build-test',
sourceVersion: body.ref,
environmentVariablesOverride: [
{ name: 'BUILD_VERSION', value: body.ref },
{ name: 'GITHUB_ACCESS_TOKEN', value: process.env.GITHUB_ACCESS_TOKEN },
],
}, function(err) {
callback(err, { statusCode: err ? 500 : 200 });
});
};
やってるのはGitHubのWebhookを受けて、CodeBuildのstartBuildを呼んでるだけ。ここでGitHubのアクセストークンをLambdaの環境変数に指定しとく。最初CodeBuild側に指定してて、トークンが反映されなくてはまったけど、呼び出し側でenvironmentVariablesOverride
を指定した場合マージされずに上書きされるからだった。
次にAPI Gatewayで適当なパスのPOSTメソッドのエンドポイントを作ってこのLambda関数につなぐ。API Gatewayはそれだけ。作ったエンドポイントをGitHubのWebhookに設定すれば終わり。
Releaseを作る
最後にGitHubのAPIを使ってpushされたtagでReleaseを作って、zipを添付する。
リリースのスクリプトはこんな感じ。
#!/bin/sh
set -ex
FILE_NAME=Test-$BUILD_VERSION-darwin-x64.zip
FILE_PATH=./dist/$FILE_NAME
UPLOAD_URL=`curl -s -X POST \
-H "Authorization: token $GITHUB_ACCESS_TOKEN" \
-d "{\"tag_name\":\"$BUILD_VERSION\",\"name\":\"$BUILD_VERSION\"}" \
https://api.github.com/repos/hokaccha/electron-build-test/releases | \
jq -r '.upload_url' |
sed -e 's/{?name,label}$//g'
`
curl --data-binary @$FILE_PATH -H "Content-Type: application/zip" -H "Authorization: token $GITHUB_ACCESS_TOKEN" $UPLOAD_URL?name=$FILE_NAME
buildspec.ymlでjqをインストールしたりrelease.shを実行する設定を入れる。
version: 0.1
phases:
install:
commands:
- apt-get update -y
- apt-get install -y jq
- npm install
build:
commands:
- /bin/sh ./build.sh
post_build:
commands:
- /bin/sh ./release.sh
これでtagを打ってpushすれば自動でビルドされてリリースが作られる。こんな感じ。
感想
けっこうめんどいので小さいプロジェクトだったらCircleCIでいいんじゃないかな。