Githubのprivateリポジトリで管理しているElectronアプリをCircleCIとGitlabCI使ってビルドする

# はじめに

Electronは、1つの開発環境で異なるOSの実行ファイルを作成できる。
たとえばmac上で、windowsやLinux用の実行ファイルを作成可能。

ところが作るアプリによっては

- 特定のOSだけ動かないのでテストしたい
- ネイティブビルドのnpmを使う
- macOSのアプリとして配布する場合、mac上でコードサイニングする必要がある

と実環境のビルドサーバーが欲しくなる。

publicリポジトリーならtravisci(mac) + appveyor(windows)が無料でつかえるので、そちらを検討したほうがよさそう

- [NW.js/ElectronアプリをGitHub Releaseで公開する[自動デプロイ] | Web Scratch](http://efcl.info/2015/07/28/nwjs-electron-github-release/)
- [Electron + Travis で楽々ビルド・リリースする最強のデスクトップアプリ開発](
http://qiita.com/oniatsu/items/98851e0463dfe83f04b0)

privateリポジトリの場合、一番安くてciecleci 39ドル + appveyor 29ドル = 68ドル ≒ 7000円/月 となる。
正直結構値が張る。

たまたま自前で立てていたGitlabがあったので、実機でCIできる環境を作ってみた。

# ざっくりした流れ

```
開発環境 -> Github -> CircleCI -> (git push gitlab master)-> GitlabCI -> 自宅のmac/win -> Github Release - Nuts(heroku) <- user
```
1. ソースコードはGithubで管理している。
2. 開発環境へGithubへpush
3. CircleCI起動（ubuntu上でのテスト、eslintなどを実行）
4. CircleCIからGitlabへgit push
5. GitlabCI起動(テスト、インストーラ作成、Gtihub Releaseでアップロード)
6. herokuにたてたNutsサーバー経由で配信

# CircleCIの設定

```circle.yml
machine:
  timezone: Asia/Tokyo
  node:
    version: 6.3.1
dependencies:
  pre:
    - git config --global user.name "Sample"
    - git config --global user.email info@example.com
  cache_directories:
    - node_modules
    - src/node_modules
deployment:
  development:
    branch: /^(?!master$).*$/
    commands:
      - sh script/deploy-circleci.sh
  production:
    branch: master
    commands:
      - sh script/deploy-circleci.sh
notify:
  webhooks:
    - url: (省略)
```

```deploy-circleci.sh
#!/bin/sh

git push gitlab ${CIRCLE_BRANCH}
```

# Gitlabを設置
Docker Composeつかってたてた。
http://qiita.com/yacchin1205/items/fa774011d72ead599eb5

CircleCIに登録した公開鍵をアカウントに登録する。

# 実機へのgitlab-multi-runnerのインストール

公式の手順どおりにインストール。

mac
https://docs.gitlab.com/runner/install/osx.html

win
https://docs.gitlab.com/runner/install/windows.html

＄　gitlab-ci-multi-runner register
executorはshell
タグは環境ごとにmac,winとつけた

忘れがちな点として点として、startしたらPCを再起動する必要がある。

```
＄　gitlab-ci-multi-runner install
＄　gitlab-ci-multi-runner start
```

またwindowsでは、SeServiceLogonRightが必要といわれることがある、Local Security Policy toolを使う部分の手順が追加になる(FAQに書いてある)
https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/faq/README.md

うちのPCはwindows7 Homeだったので下に載っているntrights.exeを使った(この辺メモ撮り忘れた。微妙にwindows7は対象外っぽいので自己責任で）

```
ntrights.exe ntrights +r SeServiceLogonRight -u USER_NAME_HERE

```

## 参考

[GitLab CIを使って仕事で楽をする](http://qiita.com/kalium/items/2e389a86e14176ad5822)

# .gitlab-ci.yml

npm run pack:win,npm run pack:macは、electron-builderを仕様。
インストールパッケージングをつくって、masterにpushされた時だけ、Github Releaseにアップロードしている。

注意点として、windowsのスクリプトは先頭にcallをつける必要がある。
つけないと複数行かけなかったり挙動かまおかしくなる。
あとshellといってもコマンドプロンプトなのでUnixコマンド使えない。

```
cache:
  key: "$CI_BUILD_NAME"
  paths:
    - node_modules/
    - src/node_modules/

build:development:mac:
  script:
    - export NVM_DIR="$HOME/.nvm"
    - . "$NVM_DIR/nvm.sh"
    - npm install
    - npm test
    - npm run pack:mac -- --publish never
  tags:
    - mac
  except:
    - master

build:master:mac:
  script:
    - export NVM_DIR="$HOME/.nvm"
    - . "$NVM_DIR/nvm.sh"
    - npm install
    - npm test
    - npm run pack:mac -- --publish onTagOrDraft
  tags:
    - mac
  only:
    - master

build:development:win:
  script:
    - call npm install
    - call npm test
    - call npm run pack:win -- --publish never
  tags:
    - win
  except:
    - master
    - 
build:master:win:
  script:
    - call npm install
    - call npm test
    - call npm run pack:win -- --publish onTagOrDraft
  tags:
    - win
  only:
    - master
```

```package.json
{
  "name": "Hogehoge",
  "version": "0.0.1",
  "description": "For Development",
  "main": "",
  "scripts": {
    "start": "electron src",
    "postinstall": "install-app-deps",
    "pack": "build --dir",
    "pack:mac": "build --mac",
    "pack:win": "build --win --ia32",
    "dist": "build -wm",
    "lint": "eslint ./src/app/**/*.js*",
    "test": "electron-mocha --recursive --require intelli-espower-loader --timeout 20000",
    "test:cover": "npm test -- --require test_util/coverage --reporter mocha-junit-reporter && istanbul report lcov"
  },
  "directories": {
    "app": "src",
    "test": "test"
  },
  "build": {
    "appId": "hogehohgoe",
    "app-category-type": "your.app.category.type",
    "win": {
      "target": [
        "nsis"
      ]
    }
  }
(省略)
}
```

# 実機へ諸々インストール
nodeとgitは先に手動でいれてしまった。(macはnvm)
なお、コードサイニングする場合は、keychainに証明書を登録する必要がある。

# 2,3ヶ月使ってみた感想
- 単体テストは割といける。
- インテグレーションテストは作業してるとフォーカス奪われるので実用的とは言えない
- インストーラー作成&アップロードが自動化されるのはかなり楽。
- windowsはなぜかファイルの削除処理でたまにテストが失敗することがあり、あまり安定してない(書き方が悪いだけかも)
- 実機をスリープするとビルドできないので、ディスプレイを閉じてもスリープしない設定にしておくほうがいい。
- CIするだけだったら、Jenkinsでよいと思う。Gitlabでソース管理してたらまた別だけど