Electron + Travis で楽々ビルド・リリースする最強のデスクトップアプリ開発

この記事は古いです。

---------

# ぼくが考えた最強のデスクトップアプリ開発環境

Web技術でデスクトップアプリ書いて push するだけの環境を作る。

主に利用するのは Electron + Travis + GitHub の3つ。

Electron でデスクトップアプリ書いて、push するだけでビルドしてリリースまで完結するデスクトップアプリ開発ができる。

もっと簡単に言うと
「ローカルで開発→push」
だけで GitHub Release に自動でリリースできる。

アプリのビルド自体もTravis内で行えるため、開発環境のOSに依存しない開発が可能。
以下は OS X 環境を前提として説明するが、クロスプラットフォームのためのビルドはTravis内で行うため OS は何でも良い。

# 念のため各種サービス・フレームワークの説明

簡単に説明すると以下。どれもすごく便利。

- [Electron](http://electron.atom.io/): みんな大好きHTML/CSS/JSのWeb技術でクロスプラットフォーム・デスクトップアプリケーションを書ける。
- [Travis CI](https://travis-ci.org/): 中央集権的CI/CDサービス。GitHubと連携して、pushするだけでテスト、デプロイを実現できる。
- [GitHub](https://github.com/): Release ページで公開したいアプリをそのまま置ける点が今回は大事。

# 実際のステップはこれだけ

1. Electron を使ってWeb技術でデスクトップアプリを開発する
2. GitHub にリポジトリを作る
3. Travis CI で GitHub 認証して、該当リポジトリをTravisから扱えるよう許可する
4. `.travis.yml` を書く
5. push する。これだけでテストしてビルドしてインストーラが作成されて、公開まで完了

# 実際のコードを見ながら進めてみる

GoogleフォトをWebViewでただそのまま表示するだけのアプリ。

- ~~deak link~~

自動ビルド・デプロイのために重要なファイルは2つ。

- ~~deak link~~
- ~~deak link~~

## package.json

npm で実行できるように以下のスクリプトを追加している。

- npm clean
- npm pack
- npm build
- npm archive

### npm clean
ビルドしたファイルの削除

### npm pack
electron-packager を使ってElectronアプリを各種OSに合わせて生成する。

- Windows における .exe の実行ファイル本体。
- OS X における .app 。

### npm build
`npm pack` + electron-builder を使ってインストーラを生成する。

- Windows における .exe の実行ファイル本体のインストーラ exe を生成する。
- OS X における .app のインストーラの dmg を生成する。

### npm archive
`npm build` + インストーラをzipにまとめる。
つまりこれ一つで、実行ファイル生成 + インストーラ作成 + zip化 まで全て行う。

- exe → zip
- dmg → zip

zip にした方が配布に都合良い。
zip であれば GitHub Release にもアップロードできる。

```json:package.json
{
  "name": "Google-Photos",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "electron .",
    "test": "echo \"Warning: no test specified\"",

    "clean": "rm -rf ./dist",
    "clean:osx": "rm -rf ./dist/osx",
    "clean:win": "rm -rf ./dist/win",
 
    "pack": "npm run pack:osx && npm run build:win",
    "pack:osx": "npm run clean:osx && electron-packager . \"Google Photos\" --out=dist/osx --platform=darwin --arch=x64 --version=0.36.2 --icon=assets/osx/icon.icns --ignore=\"dist|assets\"",
    "pack:win": "npm run clean:win && electron-packager . \"Google Photos\" --out=dist/win --platform=win32 --arch=ia32 --version=0.36.2 --icon=assets/win/icon.ico --ignore=\"dist|assets\"",
 
    "build": "npm run build:osx && npm run build:win",
    "build:osx": "npm run pack:osx && electron-builder \"dist/osx/Google Photos-darwin-x64/Google Photos.app\" --platform=osx --out=\"dist/osx\" --config=builder.json",
    "build:win": "npm run pack:win && electron-builder \"dist/win/Google Photos-win32-ia32\" --platform=win --out=\"dist/win\" --config=builder.json",

    "archive": "npm run archive:osx && npm run archive:win",
    "archive:osx": "npm run build:osx && zip -j \"dist/osx/Google-Photos-osx.zip\" \"dist/osx/Google Photos.dmg\"",
    "archive:win": "npm run build:win && zip -j \"dist/win/Google-Photos-win.zip\" \"dist/win/Google Photos Setup.exe\""
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "electron-builder": "^2.5.0",
    "electron-packager": "^5.2.0",
    "electron-prebuilt": "^0.36.2"
  },
  "dependencies": {
    "electron-window-state": "^2.0.0"
  }
}
```

## .travis.yml

それぞれの環境向けに一工夫が必要。ここが注意点。

- Windows: Windowsソフトウェアが実行できる環境が必要あり
- OS X: OS X 環境でビルドする必要あり
- Linux: 特に工夫は不要

結果として、OS X 環境で Wine を入れてビルドする。

```yaml:travis.yml
# 実際には Node を使うが、Objective-C を指定することで OS X 環境で動かすようにする
language: objective-c
cache:
  directories:
    - node_modules
env:
  # Node はコマンドを個別に実行してインストールするため、ここでバージョンを指定する
  - NODE_VERSION="4.1"
before_install:
  # nvm をインストールする。Travis の OS X 環境には nvm はデフォルトで入っていない
  - git clone https://github.com/creationix/nvm.git /tmp/.nvm
  - source /tmp/.nvm/nvm.sh
  # 指定バージョンの Node をインストールする
  - nvm install $NODE_VERSION
  # 指定バージョンの Node を有効にする
  - nvm use --delete-prefix $NODE_VERSION
  - node --version
install:
  - npm install
script:
  - npm test
before_deploy:
  # brew は最新状態にする
  - brew update
  # Windows環境へのビルドのために Wine は必須
  - brew install wine
  - wine --version
  # Windowsインストーラ作成のために makensis は必須
  - brew install makensis
  # ビルド + インストーラ作成 + zip化 までを各プラットフォームに対して行う
  - npm run archive
deploy:
  provider: releases
  # GitHub にリリースするための API KEY を暗号化した値
  api_key:
    secure: <key>
  # Releases ページにアップロードするファイル
  file:
    - dist/win/Google-Photos-win.zip
    - dist/osx/Google-Photos-osx.zip
  skip_cleanup: true
  on:
    repo: <repo>
    tags: true
    all_branches: true
```

`api_key` の部分は GitHub の API KEY を暗号化した値を入れる。以下を実行すれば良い。
参考: [GitHub Releases Uploading - Travis CI](https://docs.travis-ci.com/user/deployment/releases)

```bash
gem install travis    # Travis CI クライアントをインストール。要 Ruby
travis setup releases # GitHub の API KEY をセットする
```

# 後は GitHub に push するだけ

すると Travis が後は頑張ってくれる。
今回の `.travis.yml` ではタグが付いているリビジョンのみリリースビルドとして扱う。

時間は結構かかるので注意。
ビルドやインストーラ作成のための依存パッケージのインストールが時間の全体を占める。
ここはキャッシュできるようにすれば高速化できるかも。

# リリースされたページ

これで GitHub Release にリリースされる。

OS X, Windows 向けのアプリはビルド済みのため以下からすぐにダウンロードできる。

これで完了だ。
後はコードを書いて tag を付けて push するだけでリリースできる。

push するだけでリリースまで完了するため、後は開発に全て集中できる。

みんなも快適にクロスプラットフォーム・デスクトップアプリを作ってみよう。