Scrapbox の野良 Electron アプリ sbe をリリースするときは、macOS / Windows のバイナリをそれぞれ MacBook Pro や Windows ラップトップでビルドし GitHub の Release Draft にアップロードして公開しています。ビルドが1箇所でできないのは結構めんどくさいものです。
GitHub Actions の Matrix build を使うと複数の OS・複数のランタイム環境 (複数バージョンの Node.js 環境など) の組合せのビルドやテストを1つの Workflow で一気に実行できます。これを使って面倒な各 OS 向けのビルドを CI 化しようと思いました。
Sign in for Software Support and Product Help - GitHub Support
Matrix build の Matrix パラメータには Ubuntu / Windows / macOS などを仮想環境として指定可能です。
LinuxおよびWindowsのGitHub Actions仮想環境は、GitHub Actions runnerがインストールされたMicrosoft AzureのStandard_DS2_v2仮想マシン上にホストされています。 GitHub Actions runner は、Azure Pipelines Agent のフォークです。 Standard_DS2_v2マシンリソースに関する詳しい情報については、Microsoft Azureドキュメンテーションの「DSv2-series」を参照してください。 GitHubは、macOS仮想環境のホストにMacStadiumを使用しています。
Sign in for Software Support and Product Help - GitHub Support
GitHub が Microsoft に買収されたことで Azure の Windows Server 環境を Action の実行環境として使えるみたいですね。MacStadium は iOS / macOS アプリの CI/CD サービスのようです。
今回は Matrix build により macOS と Windows 環境で下記ステップを実行します。
- リポジトリへの tag push をトリガーとして開始する
- Node.js 環境を構築する (最新の v12 系のみ)
- OS に応じた npm script (electron-packager) を実行する
- 生成されたバイナリーを zip 圧縮する
- 圧縮されたバイナリーを成果物として保存する
実際の Workflow 定義です。
name: Build sbe binaries on: push: branches: - "!*" tags: - "v*" jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-latest, macos-latest] steps: - uses: actions/checkout@v1 - name: setup nodejs uses: actions/setup-node@v1 with: node-version: 12.x - name: install dependencies run: npm install - name: package for macOS if: matrix.os == 'macos-latest' run: | echo ${GITHUB_REF} npm run package-macos zip -ry sbe-darwin-x64/sbe-macos.zip sbe-darwin-x64/sbe.app - name: archive package for macOS if: matrix.os == 'macos-latest' uses: actions/upload-artifact@master with: name: sbe-v-macos path: ./sbe-darwin-x64/sbe-macos.zip - name: show ref tags if: matrix.os == 'windows-latest' run: echo %GITHUB_REF% - name: package for Windows if: matrix.os == 'windows-latest' run: npm run package-win32 - name: zip package for Windows if: matrix.os == 'windows-latest' run: powershell Compress-Archive -Path sbe-win32-x64 -DestinationPath sbe-windows.zip - name: archive package for Windows if: matrix.os == 'windows-latest' uses: actions/upload-artifact@master with: name: sbe-v-windows path: sbe-windows.zip
v
で始まる名前の tag が push された場合に起動するようにトリガーを設定しています。
Job の Matrix パラメータ に windows-latest
と macos-latest
を指定して Matrix build を実行しています。
step 毎に if expression を使って Matrix パラメータ (os) を判定し実行するコマンドを使い分けています。macos では bash を、Windows では cmd.exe ( と PowerShell) で動作するコマンドを記述しています。
GitHub Actions (beta) の Windows 仮想環境では、run:
で複数コマンドを実行できないようでしたので step を分割し1コマンドずつ実行するようにしました。
push された tag の名前はビルトインの環境変数 GITHUB_REF
に格納されます。artifact のファイル名に tag 名を使いたいのですが、GITHUB_REF
に設定される値は refs/tags/v1.0.2
のような形式なのでそのままファイル名に使用することができません。GitHub Actions の関数には文字列の join はあるのに split がないという状況です。
Sign in for Software Support and Product Help - GitHub Support
ということで tag 名を upload-artifat の path に指定するのは断念し、echo で出力するのみとしています。
Workflow を実行すると OS 毎にジョブがパラレル実行され、ビルド済みのバイナリーが Artifact として保存されます。
GitHub Actions で各 OS 向けのバイナリのビルドを 1つの Workflow で実現できました。今後は、GitHub API で Release Draft にアップロードする Job や UI テストを実行する Job を追加していきたいと思っています。
追記) electron-packager -> electron-builder に移行することで OS 固有の処理がなくなり if expression はなくすことができました。
参考記事: