Node.jsとGithub Webhooksを使ってリモートプロジェクトを同期する方法

0 株式
0
0
0
0

導入

複数の開発者がプロジェクトに取り組んでいる場合、ある開発者がリポジトリにプッシュした直後に別の開発者が古いバージョンのコードに変更を加え始めると、イライラすることがあります。このようなミスを防ぐには、リポジトリの同期を維持するためのスクリプトを設定することが効果的です。この方法は本番環境にも適用でき、ホットフィックスやその他の変更を迅速に行うことができます。.

この特定のタスクを完了するための他のソリューションもありますが、独自のスクリプトを作成することは、将来のカスタマイズの余地を残す柔軟なオプションです。.

GitHubでは、リポジトリにWebhookを設定できます。Webhookとは、イベント発生時にHTTPリクエストを送信するイベントです。例えば、誰かがプルリクエストを作成したり、新しいコードをプッシュしたりしたときに通知を受け取ることができます。.

このガイドでは、GitHub にコードをプッシュするたびに GitHub Webhook 通知をリッスンする Node.js サーバーを作成します。このスクリプトは、リモートサーバー上のリポジトリを最新バージョンのコードで自動的に更新するため、新しいコミットを行うためにサーバーにログインする必要がなくなります。.

前提条件
  • sudo 権限を持つ非 root ユーザーとファイアウォールを含むセットアップ済みの Ubuntu サーバー。.
  • Git がローカル マシンにインストールされています。.
  • Node.js と npm は、公式 PPA を使用してリモート サーバーにインストールされます。.
  • プロジェクト コードが含まれる Github 上のリポジトリ。.

ステップ1 – Webhookの設定

まず、リポジトリのフックを設定します。このステップは重要です。この設定がないと、GitHub は何かが起きたときにどのイベントを送信すればいいのか、またどこに送信するべきなのかが分からなくなってしまうからです。まず Webhook を作成し、次にそのリクエストに応答するサーバーを作成します。.

GitHubアカウントにログインし、監視したいリポジトリに移動します。リポジトリページ上部のメニューバーにある「設定」タブをクリックし、左側のナビゲーションメニューで「Webhooks」をクリックします。画面右隅にある「Webhookを追加」をクリックし、プロンプトが表示されたらアカウントのパスワードを入力します。次のようなページが表示されます。

  • 「ペイロードURL」フィールドに「http://your_server_ip:8080」と入力します。これは、後ほど記述するNode.jsサーバーのアドレスとポートです。.
  • コンテンツタイプを application/json に変更してください。現在作成中のスクリプトは JSON データを想定しており、他のデータ型は認識できません。.
  • 「シークレット」には、このWebhookのシークレットパスワードを入力します。このシークレットは、Node.jsサーバー上でリクエストを認証し、GitHubから送信されていることを確認するために使用します。.
  • このWebhookをトリガーするイベントを指定するには、プッシュイベントを選択します。プッシュイベントが必要なのは、コードが更新され、サーバーと同期する必要があるタイミングだからです。.
  • [アクティブ]チェックボックスを選択します。.
  • フィールドを確認し、「Webhook を追加」をクリックして作成します。.

最初はpingが失敗しますが、Webhookの設定は完了しているのでご安心ください。それでは、リポジトリをサーバーにクローンしてみましょう。.

ステップ2 – リポジトリをサーバーにクローンする

このスクリプトはリポジトリを更新できますが、初期化はできないので、ここで初期化します。サーバーにログインしてください。

ssh sammy@your_server_ip

ホームディレクトリにいることを確認してください。Gitを使ってリポジトリをクローンしてください。GitHubのユーザー名をsammyに、Githubのプロジェクト名をhello_hapiに置き換えてください。.

cd
git clone https://github.com/sammy/hello_hapi.git

これにより、プロジェクトを含む新しいディレクトリが作成されます。このディレクトリは次のステップで使用します。.

プロジェクトのクローンを作成すると、Webhook スクリプトを作成できます。.

ステップ3 – Webhookスクリプトを作成する

GitHubからのWebhookリクエストをリッスンする独自のサーバーを作成しましょう。8080ポートでWebサーバーを起動するNode.jsスクリプトを作成します。サーバーはWebhookリクエストをリッスンし、指定したシークレットを検証し、GitHubから最新バージョンのコードを取得します。.

メインメニューに移動します:

cd ~

NodeWebhooks という Webhook スクリプト用の新しいディレクトリを作成します。

mkdir ~/NodeWebhooks

次に、新しいディレクトリに移動します。

cd ~/NodeWebhooks

NodeWebhooks ディレクトリに webhook.js という新しいファイルを作成します。.

nano webhook.js

スクリプトに次の 2 行を追加します。

/* Your codevar secret = "your_secret_here";
var repo = "/home/sammy/hello_hapi";... */

最初の行は、ステップ1で作成したシークレットを保持する変数を定義します。このシークレットは、リクエストがGitHubからのものであることを検証します。2行目は、ローカルディスク上で更新するリポジトリへのフルパスを保持する変数を定義します。このパスは、ステップ2でチェックアウトしたリポジトリを指す必要があります。.

次に、スクリプトにhttpライブラリとcryptoライブラリをインポートする以下の行を追加します。これらを使ってWebサーバーとシークレットハッシュを作成し、GitHubから取得したものと比較できるようにします。

let http = require('http');
let crypto = require('crypto');

次に、スクリプトからシェル コマンドを実行できるように、child_process ライブラリを追加します。

const exec = require('child_process').exec;

次に、次のコードを追加して、GitHub Webhook リクエストを処理する新しい Web サーバーを定義し、リクエストが有効な場合は新しいバージョンのコードをプッシュダウンします。

http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);

http.createServer() 関数は、ポート8080でWebサーバーを起動し、GitHubからのリクエストをリッスンします。セキュリティ上の理由から、リクエストに含まれるシークレットが、手順1でWebhookを作成したときに指定したシークレットと一致することを確認します。このシークレットは、SHA1ハッシュ化された文字列として x-hub-signature ヘッダーで送信されるため、シークレットをハッシュ化し、GitHubから送信されるものと比較します。.

リクエストが有効な場合は、シェル コマンドを実行し、git pull を使用してローカル リポジトリを更新します。.

完成したスクリプトは次のようになります。

const secret = "your_secret_here";
const repo = "~/your_repo_path_here/";
const http = require('http');
const crypto = require('crypto');
const exec = require('child_process').exec;
http.createServer(function (req, res) {
req.on('data', function(chunk) {
let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
if (req.headers['x-hub-signature'] == sig) {
exec('cd ' + repo + ' && git pull');
}
});
res.end();
}).listen(8080);

初期サーバー設定ガイドに従った場合は、ポート 8080 のトラフィックを許可して、この Web サーバーが外部 Web と通信できるようにする必要があります。

sudo ufw allow 8080/tcp

スクリプトが配置されたので、正しく動作することを確認しましょう。.

ステップ4 – Webhookのテスト

Node.jsを使ってWebhookをコマンドラインで実行し、テストすることができます。スクリプトを起動し、ターミナルでプロセスを開いたままにしておきます。

cd ~/NodeWebhooks
nodejs webhook.js

Github.comのプロジェクトページに戻ります。リポジトリページ上部のメニューバーにある「設定」タブをクリックし、左側のナビゲーションメニューで「Webhooks」をクリックします。手順1で設定したWebhookの横にある「編集」をクリックします。下の画像のように、下にスクロールして「最近のコミット」セクションを表示します。

右側の3つの点をクリックすると、「再配信」ボタンが表示されます。ノードサーバーが稼働中の場合は、「再配信」をクリックしてリクエストを再送信してください。リクエストの送信を確認すると、成功したことを示す応答が表示されます。これは、pingが再配信された後に返される200 OKレスポンスコードで示されます。.

これで、スクリプトがバックグラウンドで実行され、起動時に開始されることを確認できます。Ctrl+C を押すと、ノードの Webhook サーバーが停止します。.

ステップ5 – WebhookをSystemdサービスとしてインストールする

systemdは、Ubuntuのサービスを制御するためのタスクマネージャーです。起動時にWebhookスクリプトを起動し、他のサービスと同様にsystemdコマンドを使って管理できるサービスを起動します。.

まず、新しいサービス ファイルを作成します。

sudo nano /etc/systemd/system/webhook.service

サービスファイルに以下の設定を追加し、systemdにスクリプトの実行方法を指示します。これにより、systemdはノードスクリプトの場所とサービスの説明を見つけることができます。.

必ずSamiを自分のユーザー名に置き換えてください。.

[Unit]
Description=Github webhook
After=network.target
[Service]
Environment=NODE_PORT=8080
Type=simple
User=sammy
ExecStart=/usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js
Restart=on-failure
[Install]
WantedBy=multi-user.target

システムの起動時に新しいサービスを開始できるようにします。

sudo systemctl enable webhook.service

次にサービスを開始します。

sudo systemctl start webhook

サービスが開始されていることを確認します。

sudo systemctl status webhook

サービスがアクティブであることを示す次の出力が表示されます。

Output
● webhook.service - Github webhook
Loaded: loaded (/etc/systemd/system/webhook.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-08-17 19:28:41 UTC; 6s ago
Main PID: 9912 (nodejs)
Tasks: 6
Memory: 7.6M
CPU: 95ms
CGroup: /system.slice/webhook.service
└─9912 /usr/bin/nodejs /home/sammy/NodeWebhooks/webhook.js

これで、新しいコミットをリポジトリにプッシュし、サーバー上の変更を確認できるようになりました。.

デスクトップ デバイスからリポジトリをエミュレートします。

git clone https://github.com/sammy/hello_hapi.git

リポジトリ内のファイルの1つを変更します。その後、ファイルをコミットし、コードをGitHubにプッシュします。.

git add index.js
git commit -m "Update index file"
git push origin master

Webhook がアクティブ化され、変更がサーバー上に表示されます。.

結果

新しいコミットをリモートリポジトリに自動的にデプロイするNode.jsスクリプトを設定しました。このプロセスを使用して、監視対象のリポジトリを追加設定できます。リポジトリをプッシュする際に、ウェブサイトやアプリケーションを本番環境にデプロイするように設定することも可能です。.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

あなたも気に入るかもしれない