本番をFTPで直接触りたい人たちと共生するためのGitHub同期ツールを作りました

  • 145
    Like
  • 2
    Comment

はじめに

静的なサイトやWordPressぐらいならエンジニアじゃなくても割と触れてしまうので、お客さんや自社の営業さんがFTPで直接サイトをいじりたいということがあると思います。(ありますよね?)

コーポレートサイトやLPなど営業ツールとしての側面が強いサイトだと、いちいちエンジニアに頼まないと変更できないというのではスピード感に欠けるので、至極当然のニーズかなと思います。

でもやっぱりエンジニアとしては万一に備えて変更の履歴はちゃんと取っておきたいし、できればソースはGitHubに置いておきたいと思うのが人情というものですね。

ghsync

そこで、ghsync というツールを作りました。

本番サーバー上で起動しておくと、

  • 監視対象のディレクトリが更新されたら自動で git add git commit git push する
  • リモートが更新されたら自動で git pull する
  • もしコンフリクトしたら同期処理を一旦停止して通知メールを送る(その後コンフリクト解消コミットが手動でpushされたら、同期処理を自動で再開する)

というような動作をします。

想定している対象コードベースはもともとFTPで気ままに更新しようとしてたぐらいの管理体制のものなので、そうそうコンフリクトなんて発生しないだろうとは思っていますが、もしものときに

ほげほげ
<<<<<<< HEAD
ふがふが
=======
>>>>>>> c62d9833ff87775766bc4d5b5397ea6152de5edb

みたいなのが本番上で作られちゃったら困りものなので、pullに失敗した時点で一旦立ち止まって通知メールを送る仕様にしました。

本番をFTPで直接触りたい人たちと共生したいエンジニアの方々に使ってみていただけたらと思います。

インストール

本番サーバーにnpmでインストールしてください。

$ npm install -g ghsync

インストール後、

$ ghsync init

を実行すると~/.config/ghsync/default.ymlに設定ファイルが作られるので、これを適宜修正してください。

内容は以下のような感じです。

repos:
  - remote: owner/repo                      # GitHubリポジトリ名
    local: /path/to/local/repo              # ローカルのディレクトリパス
    ignores:
      - path/to/dir/or/file/to/be/ignored   # ローカルのディレクトリパスのうち
      - /absolute/path/is/also/allwoed      # 変更監視の対象から外したいもの
      - vendor                              # 絶対パス・相対パスいずれも可

webhook:
  secret: use same secrets for all repos    # GitHub Webhookのsecret(複数リポジトリで使う場合は、すべてで同じsecretを使ってください)
  port: 4949                                # Webhookを受け取るポート番号

commitInterval: 30                          # ローカルにいくつか連続で変更が加えられることを想定して、指定した秒数の間はコミットをせずに待つ

sendmail:                                   # メール通知のための設定
  enabled: true
  smtp:
    host: smtp.gmail.com
    port: 465
    secure: true
    auth:
      user: user@gmail.com
      pass: pass
  options:
    from: user@gmail.com
    to: destination@example.com
    subjectPrefix: "[ghsync] "

使い方

まずGitHubのWebhookを設定しておきます。

あとは本番サーバー上で

$ ghsync run

とすると設定ファイルの内容に従って監視が始まります。これだけです。

ghsync自体は普通にフォアグラウンドで動くので、Supervisor等でデーモン化して使ってもらう想定です。(READMEにはforeverを使う例を書きました)

なお、ghsyncは実行時にHOME環境変数を参照するので、Supervisorでデーモン化する場合、environment=HOME=/home/<user> といった設定が必要となります。

おわりに

とりあえず突貫で作ったので(あと、そもそもJS力が低いので)おかしなところとかあるかもしれません。
何か気づいたことがあれば、Issue/PRをお待ちしております。

ttskch/ghsync: Sync local git repository and remote GitHub repository automatically.