Travis CI で Angular + Firebase の CI/CD 環境を構築する

こんにちは。

AngularでつくってFirebase Hostingでホスティングするアプリを、Travis CIでCI/CDをまわしちゃいましょう。

# 前提

- Angular CLIとfirebase-toolsをインストール済み
- Firebaseプロジェクトを作成済み
- Angularアプリを作成済み

firebase-toolsのインストール方法と、Firebaseプロジェクトの作成方法は [Travis CI で Firebase の CI/CD 環境を構築する#Firebase
](https://qiita.com/itigoore01/items/1d0fb53677a7b35adad8#firebase) を御覧ください。

Angularアプリの作成については [公式ドキュメント](https://angular.jp/guide/setup-local) を御覧ください。

# Angular + Firebase セットアップ

[公式ドキュメント](https://angular.io/guide/deployment#automatic-deployment-with-the-cli)にもありますが、`@angular/fire`を追加すると、同時にFirebase Hostingの設定もしてくれます。

以下のコマンドで追加しましょう。

```bash:bash
ng add @angular/fire
```

Firebaseプロジェクトを選択します。

```bash:bash
? Please select a project: (Use arrow keys or type to search)
❯ ngx-firebase-travis-ci-example (ngx-firebase-travis-ci-example)
```

設定が完了すると`firebase.json`などのファイルが出来ているはずです。

また、Angular CLI 8.3.0からは`ng deploy`なるコマンドが追加されていて、これを使うとデプロイできます。
いったん手動でデプロイしてみましょう。

```bash:bash
ng deploy
```

Angular CLI 8.3.0から変わった、イケてる初期テンプレートが見れました。

![スクリーンショット 2019-08-30 15.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/33bddb99-9581-c085-71e1-63292145afa9.png)

ここからさらに設定を加えていきます。

以下のコマンドを実行します。

```bash:bash
firebase use --add
```

プロジェクトを聞かれるので先程と同じプロジェクトを選択します。

```bash:bash
? Which project do you want to add? (Use arrow keys)
❯ ngx-firebase-travis-ci-example
```

エイリアスをつけます。
production、staging、developmentなど環境を分けたい場合はここでエイリアスをつけて切り替えられるようになります。
今回はproductionオンリーでいくので`production`にします。

```bash:bash
? What alias do you want to use for this project? (e.g. staging) production
```

以上です。

なお、Firebase Hosting以外の機能も利用する場合は追加で設定が必要です。
詳しくは [Travis CI で Firebase の CI/CD 環境を構築する#firebase-toolsでプロジェクトを用意する](https://qiita.com/itigoore01/items/1d0fb53677a7b35adad8#firebase-tools%E3%81%A7%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B)を御覧ください。

# Travis CI

## .travis.yml

.travis.ymlをプロジェクトフォルダ直下に作成します。

内容は以下のとおりです。
Unit test、E2E testを行うかどうかで少し変わってきます。

- Unit test、 E2E testを行う場合 → [こちら](#unit-test-e2e-testを行う場合)
- Unit test、 E2E testを行わない場合 → [こちら](#unit-test-e2e-testを行わない場合)

### Unit test, E2E testを行う場合

.travis.ymlは以下の通りになります。

```yaml:.travis.yml
language: node_js
node_js:
  - "10"
dist: trusty
addons:
  apt:
    sources:
      - google-chrome
    packages:
      - google-chrome-stable

script:
  - npm run lint
  - npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
  - npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js
  - npm run build -- --prod

deploy:
  skip_cleanup: true
  provider: firebase
  token:
    secure: $FIREBASE_TOKEN
  project: production # Firebaseのエイリアスを指定する
```

このままではCI環境でテストを実施できないので、テストの設定を変更します。
このあたりは [公式ドキュメント](https://angular.jp/guide/testing#chrome%E3%81%A7%E3%81%AEci%E3%83%86%E3%82%B9%E3%83%88%E7%94%A8%E3%81%ABcli%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)に詳しく書いてあります。

`karma.conf.js`のbrowsersの下に、customLaunchersを追加します。

```javascript:karma.conf.js
browsers: ['Chrome'],
customLaunchers: {
  ChromeHeadlessCI: {
    base: 'ChromeHeadless',
    flags: ['--no-sandbox']
  }
},
```

E2Eテストプロジェクトのフォルダ直下に`protractor-ci.conf.js`を作成します。

```js:protractor-ci.conf.js
const config = require('./protractor.conf').config;

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--headless', '--no-sandbox']
  }
};

exports.config = config;
```

### Unit test, E2E testを行わない場合

テストを行わない場合は.travis.ymlだけでOKです。
.travis.ymlの内容もよりシンプルになっています。

```yaml:.travis.yml
language: node_js
node_js:
  - "10"
dist: trusty

script:
  - npm run lint
  - npm run build -- --prod

deploy:
  skip_cleanup: true
  provider: firebase
  token:
    secure: $FIREBASE_TOKEN
  project: production # Firebaseのエイリアスを指定する
```

## FIREBASE_TOKENを設定する

FirebaseのトークンをTravis CIに設定する必要があります。

[Travis CI で Firebase の CI/CD 環境を構築する#Travis CIにFirebaseのTokenを設定する](https://qiita.com/itigoore01/items/1d0fb53677a7b35adad8#travis-ci%E3%81%ABfirebase%E3%81%AEtoken%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)をご参照ください。

## 確認

GitHubにプッシュしてCIが走るか確認してみましょう。

まず対象のリポジトリのCIが有効になっているか確認します。
有効になっていなければ有効にしましょう。

![スクリーンショット 2019-08-30 15.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/488d297f-4ff8-bbaf-6229-141b8b5f8192.png)

次にGitHubにプッシュします。

```bash:bash
git push
```

するとこんな感じでTravis CIが動き出します。

![スクリーンショット 2019-08-30 15.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/c2debea6-c009-f73b-6dc5-3714a8bb1624.png)

成功すると緑になります。

![スクリーンショット 2019-08-30 16.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75063/7e6ac681-17e5-7bd4-c2d3-464d4348bae3.png)

以上です。

# トラブルシューティング

Q. 以下のエラーが出てデプロイに失敗する

```bash
Error: No project active. Run with --project <projectId> or define an alias by
running firebase use --add
Firebase deployment failed
```

A. `firebase use --add`をしていない可能性があります。
[こちら](#angular--firebase-セットアップ)を参照してください。


# さいごに

今回の例のソースコードは以下にあります。

[https://github.com/itigoore01/angular-firebase-travis-ci-example](https://github.com/itigoore01/angular-firebase-travis-ci-example)