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

  • 142
    いいね
  • 2
    コメント

はじめに

静的なサイトや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/config/default.jsonという設定ファイルの雛形が作られるので、これを適宜修正してください。

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

{
  "repos": [
    {
      "remote": "owner/repo",                   // GitHubリポジトリ名
      "local": "/path/to/local/repo",           // ローカルのディレクトリパス
      "ignores": [
        "path/to/dir/or/file/to/be/ignored",    // ローカルのディレクトリパスのうち
        "/absolute/path/is/also/allowed"        // 変更監視の対象から外したいもの
      ]
    }
  ],
  "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を使う例を書きました)

おわりに

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

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