やろうやろうと思っていたけど,できていなかったので,いよいよ自動化した. ここにおけるポイントは,ほぼMacOSをどうするかという話に集約すると思うんだけど,一応Windows/Linuxでもちょっと変更しなきゃいけないことはあったので,書いておく.
リリースのやり方について
ふだん,MAS以外のビルドについてはelectron-builderを使っているんだけど,electron-builderは公式でactionsも出している.
これを使うと,electron-bulderのconfigにpublish関連の設定を書いたりすることで,ビルドからリリースまで自動でやってくれたりする.が,今回これは使っていない.理由は
- リリースフローが違う.Marketplaceのactionsでは,タグ等を起因にしてリリースを自動作成するactionsが非常に多いが,私はリリースを作成した後に,そのリリースのpublishを起因にCDが動いて成果物を,作成したreleaseのassetsにつけてほしい.
.deb
や.tar.bz2
の成果物以外に,そのshasumもアップロードしたい.
というのが大きいところだ.特に1は大事で,リリース時に変更点は毎回書いておきたい.しかし,自動でリリースを作成されると,こういうことが非常にやりにくく,どう考えてもリリース後に手動で本文を書き換える必要がある.リリースに関する手動作業を限りなく少なくしたいのに,CD完了を見計らって本文を書き換えるなど許容できない. action-gh-releaseなどはテンプレート機能も用意してあるが,そうじゃないんだ,毎回ではないけどリリースのときには注意点とかBreaking Changesを書きたいのだ.そうなるとどうしてもこれらは候補から外れる.
というわけで,基本的には自前でビルドし,アップロードも複数のactionsを組み合わせて行うこととする.
MacOS向けのアプリをGitHub Actions内でビルドする
何はともあれビルドだ.MacOSで面倒なのはCodeSignとNotarizeだろう.
今回はここを参考にした.
CodeSignする
これはApple公式のactionsでかなり楽になっている.
- name: Apple Codesigning uses: apple-actions/import-codesign-certs@v1 with: p12-file-base64: ${{ secrets.CERTIFICATES_P12 }} p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
こんなのだけで良い.
まず,CERTIFICATES_P12
についてだが,こちらは,Developer ID Application
の証明書を使う(Developer ID Installer
ではないことに注意).Mac上で,この証明書をp12形式で書き出す.このとき,適当なパスワードを設定してやる.
このときに設定したパスワードを CERTIFICATES_P12_PASSWORD
としてactionsのsecretsに入れる.
p12形式の証明書の方は
$ base64 -i <CERT_FILE_NAME>.p12
として,出てきた値を CERTIFICATES_P12
としてactionsのsecretsに入れる.基本的にこれでCodeSignは完了する.
Notarizeする
まず,notarize用のスクリプトを用意する.この辺の作業はローカルでnotarizeするときも必要になるので,すでに設定済みの場合は読み飛ばして良い.
const { notarize } = require('electron-notarize') exports.default = async function notarizing(context) { const { electronPlatformName, appOutDir } = context if (electronPlatformName !== 'darwin') { return } const appName = context.packager.appInfo.productFilename return await notarize({ tool: 'notarytool', appBundleId: 'org.whalebird.desktop', ascProvider: process.env.ASC_PROVIDER, appPath: `${appOutDir}/${appName}.app`, appleId: process.env.APPLE_ID, appleIdPassword: process.env.APPLE_PASSWORD, teamId: process.env.TEAM_ID }) }
こいつをelectron-builderの設定に入れる.
{ "productName": "Whalebird", "appId": "org.whalebird.desktop", "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", "afterSign": "build/notarize.js",
ここからactionsの設定になる.
release-darwin: name: Release for MacOS runs-on: macos-11 # ... - name: Package env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} ASC_PROVIDER: ${{ secrets.ASC_PROVIDER }} TEAM_ID: ${{ secrets.TEAM_ID }} run: | yarn run build:mac
で,あとは環境変数を与えてやれば良い.
APPLE_ID
は,そのままAppleのログイン時に使うIDで良い.APPLE_PASSWORD
は,App用パスワードを用意し,それを入れれば良い.参考にした記事では,altool
を使ってactionsのVM上のkeychainにパスワードを入れているが,notarizeにnotarytoolを使う場合は不要である.legacyを使う場合は,このままでは認証できなかったので,keychainが必要なのかもしれない.ASC_PROVIDER
とTEAM_ID
は同じ値でいけた.どちらもTeam Shortnameで問題なかった.
notarizeにnotarytoolを使う場合は,osはmacos-latest
ではダメだった.notarytoolはXCode13で入ったツールであり,Big Sure以降でないと使えない.ちなみに2022年1月4日現在,GitHub Actionsのmaxos-latest
はBig SureではなくCatalinaである.なので,maxos-latest
ではnotarytoolが使えず,maxos-11
とする必要がある.
なお,shasumを計算するにあたり,MacOSでは
$ shasum -a 256 file_path
を使った.
Linux向けアプリをビルドする
基本的にubuntu-latest
でだいたいビルドできるが,一つ問題だったのはpacmanである.pacmanだけはビルドエラーになった.
⨯ cannot execute cause=exit status 1 out={:timestamp=>"2022-01-03T14:13:17.667212+0000", :message=>"Process failed: /bin/sh failed (exit code 127). Full command was:[\"/bin/sh\", \"-c\", \"LANG=C bsdtar -czf .MTREE --format=mtree --options='!all,use-set,type,uid,gid,mode,time,size,md5,sha256,link' opt .INSTALL usr .PKGINFO\"]", :level=>:error} command=/home/runner/.cache/electron-builder/fpm/fpm-1.9.3-2.3.1-linux-x86_64/fpm -s dir --force -t pacman -d c-ares -d ffmpeg -d gtk3 -d http-parser -d libevent -d libvpx -d libxslt -d libxss -d minizip -d nss -d re2 -d snappy -d libnotify -d libappindicator-gtk3 --pacman-compression xz --architecture i686 --after-install /tmp/t-MalZPa/4-after-install --after-remove /tmp/t-MalZPa/5-after-remove --description ' An Electron based Mastodon client for Windows, Mac and Linux' --version 4.5.0 --package /home/runner/work/whalebird-desktop/whalebird-desktop/build/Whalebird-4.5.0-linux-i686.pacman --name Whalebird --maintainer 'AkiraFukushima <h3.poteto@gmail.com>' --url 'https://github.com/h3poteto/whalebird-desktop#readme' --vendor 'AkiraFukushima <h3.poteto@gmail.com>' --license MIT /home/runner/work/whalebird-desktop/whalebird-desktop/build/linux-ia32-unpacked/=/opt/Whalebird /home/runner/work/whalebird-desktop/whalebird-desktop/build/icons/256x256.png=/usr/share/icons/hicolor/256x256/apps/whalebird.png /tmp/t-MalZPa/e-Whalebird.desktop=/usr/share/applications/whalebird.desktop workingDir=
これについては未解決である.
おそらくubuntuでpacmanをビルドするにはなにか足らないものがある気がするのだが,ローカルはManjaroなので再現できなかった.また,そもそもGitHubのreleaseにpacmanを入れる必要性が今の所ないので,pacmanをスキップすることにした.AURを用意してあれば,ほぼそれで問題ないだろうしね.
Windows向けアプリをビルドする
Windowsはwindows-latest
(初めて使った)で無事ビルドできた.ia32もx64も両方とも同じOSでビルドできたし,特に問題はなかった.
なお,shasumを計算するにあたり,Windowsでは
$ sha256sum file_path
を使った.Windowsにはshasum
コマンドが存在しなかった.
Publishについて
こちらを使っている.
triggerは
on: release: types: [published]
こう.created
でもいいんだけど,created
だと,releaseをdraft -> publishしたときにtriggerしてくれない.
基本的にはこれで成果物をreleaseにあげている.asset_path
に上げたいもののパスを指定すれば良い.
- uses: shogo82148/actions-upload-release-asset@v1 with: upload_url: ${{ github.event.release.upload_url }} asset_path: "build/Whalebird-*.dmg" - uses: shogo82148/actions-upload-release-asset@v1 with: upload_url: ${{ github.event.release.upload_url }} asset_path: "build/Whalebird-*.shasum"
とかしておけば,成果物もshasumもアップロードできる.
snapについて
生成されたもののうち,github releaseではないところにアップロードしたいものもある.一つはsnapだ.
これについては
を使っている.
- uses: snapcore/action-publish@v1 with: store_login: ${{ secrets.STORE_LOGIN }} snap: "build/Whalebird-${{ github.event.release.name }}-linux-amd64.snap" release: beta
とかしておけば良い.