技術探し

JavaScriptを中心に記事を書いていきます :;(∩´﹏`∩);:

仕事を効率化するデプロイツールを作った

仕事の開発環境改善のために欲しかったので金曜日からコツコツ作っていたアプリケーションを紹介します。

github.com

目的

CIが走るとstorybookやフロントエンドの成果物などの静的ファイルを自動的にアップロードして、PRでのレビューコストを下げるのが目的です。
PRでのレビュー時にCSSの変更などローカルに落として確認するほどでもないものを落としてビルドするのは時間の無駄だと思っています。

また、特にstorybookはデザイナさんと共有することが多いので、常に見れるところにあってほしいなって思っています。
gh-pagesでもいいけどコミットが面倒なのと、複数並列でアップロードできないのが問題です。
つまりmasterのしか置けず、今自分が作業している状態を見せたい時の共有が大変です。

このツールと同じでS3にデプロイするツールは知ってますが、カスタマイズしたいのと自分のサーバーに置いておけばいいかなって気持ちです。

さて実は、今までにも会社ではコンテナデプロイをしてURLを発行する仕組みがありました。
しかし、フロントエンドの場合にはコンテナまで必要ないことが多いため(むしろDockerfileを書かないといけない)、静的ファイル用のホスティングアプリケーションを作りました。

デモ

以下のデモでは、ブラウザ上でコマンドを生成し、それを実行することよりlocalhostに立てたサーバーへ自分のスライドをデプロイしています。
また、デプロイが終了した時に指定したPRにbotがコメントを投稿しています。
この処理をCI上で行うことにより、PRが更新される度に静的ファイルがデプロイされbotが通知します。

f:id:about_hiroppy:20180826213342g:plain

できること

アップロード

CLIからサーバーへファイルをアップロードしランダムなURLを生成します。

つまり、以下の使用方法が想定されます。

  • CIのタスクとして書いておけば、CIが走る時に自動的に指定したフォルダをアップロードできる
    • さらにCLIにはPRにコメントするオプションがあるため、PRへの通知も可能
  • 各々のPCからCLIを使って、GitHubへpushしてなくても即座に成果物を公開でき、チームメンバーへの共有コストを下げることができる

Bot通知

サーバー側でGitHubアカウントの情報を環境変数としてを登録することにより、CLIを実行するとフラグで指定したPRへデプロイ先のURL等を通知することができます。
なので、実際ローカルから--prを指定してもPRへコメントを投稿することができます。

f:id:about_hiroppy:20180827092346p:plain

Botは過去のリンクも持つので、コミット前の差分と確認することが可能です。

有効期限

アップロードされたファイル群は指定された有効期限を過ぎたら自動的に削除されます。(デフォルトは一週間)
これにより、サーバーに不要なファイル群を溜まりづらくしメンテナンスコストを下げることが可能となります。

実行例

travis.ymlでは以下のように記述することより、デプロイが出来ます。

sudo: false
language: node_js
node_js:
  - 10
before_script:
  - npm i
  - npm run build
  - npx @demobook/cli -o onwer-name -r repo-name -t https://your-domain -d dist --pr ${TRAVIS_PULL_REQUEST} -n core

やることとしては、ローカルでやってもCIでやっても変わらず、 npx @demobook/cli を実行するだけです。
上記の場合、PRが指定されているためデプロイが終了するとBotがPRに投稿します。

Web

今回は、エンジニア以外の方も使いやすいようにしたかったためUIも作りました。

CLIのオプションは多いと毎回忘れるため、ブラウザ上からでもコマンドを生成できるようにしておきました。

f:id:about_hiroppy:20180826112137p:plain

f:id:about_hiroppy:20180827092540p:plain

これはサービスではないため、オレオレ証明書を使うことが多くservice workerのエラーが出るので、service workerは今後抜くかもしれません。。
当初と設計を変えたので、lerna抜くかも。。

導入方法

docker-composeを使っています。

$ git clone git@github.com:hiroppy/demobook.git && cd demobook && npm i && cd packages/app
$ cp .env.sample .env # please edit it[f:id:about_hiroppy:20180827095744p:plain]
$ npm run build:client:prod
$ openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout key.pem -out cert.pem # if you need
$ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

FYI: Getting Started

はじめてやった実装

inputを全選択してコピー

よくnpmとかのページにあるinputをクリックしたら全選択してコピーしてくれる機能を実装してみました。
あと、Chromeでしか確認していませんので他のブラウザで動くかはわからないです。。。

class Input extends React.Component {
  copy = (e: React.FormEvent<HTMLInputElement>) => {
    if (e.nativeEvent && e.nativeEvent.target) {
      e.nativeEvent.target.setSelectionRange(0, e.currentTarget.value.length);

      document.execCommand('copy');
    }
  };

  render() {
    return <input type="text" value="yayyyyyyyyyyyyy" onChange={() => {}} onClick={this.copy} />;
  }
}

さいごに

やっぱりツールとかインフラ作るのが楽しい。
ぜひ使ってみてください!

github.com