たとえば、Githubリポジトリでコードベースを変更して、環境の一部でアプリケーションを再構築/再起動するタスクに直面した場合、そのような再構築のトリガーとして最初に思い浮かぶのは、同じgithubによって提供されるメカニズムですWebフック:リモートリポジトリでイベントが発生すると(監視対象ブランチの一部で新しいコミットが出現するため)、githubは対応するWebフックを使用し、設定で指定されたサービスを「プル」します。 アプリケーションの再構築/再起動のプロセスを開始します。 これは、そのような場合に広く使用されている標準のシンプルなメカニズムであり、誰もが行うなど...
しかし、アプリケーションがホスト上にあり、何らかの理由でgithubがアクセスを許可されていない場合はどうでしょうか? たとえば、ホストは閉じたネットワーク内にあるのか、NATの背後にあり、インターネットからアクセスできないのですか?
この場合、Git自体のローカルフックメカニズムを使用できますが、その(メカニズム)については、かなり長い間Gitを使用している人でさえ知っている人はほとんどいません。
ローカルリポジトリ(空の初期化、リモートのクローンなど)を作成すると、.gitフォルダー、そのルート、またはルート自体に、それがベアリポジトリである場合、フックフォルダーがあります。 リポジトリが初期化された後、さまざまなイベントのフックテンプレートがこのフォルダーに保存されます。たとえば、マージ後、受信後、更新後などです。
フックでサポートされているイベントの詳細な説明は、たとえばここにあります 。
このメカニズムを使用して、悲惨なアプリケーションのためのシンプルなプッシュツーデプロイスキームを実装します。
2つのローカルリポジトリが必要になります。 たとえば、指定されたパスに沿って作成します。
1. / opt / repo-dev / example-repo /
2. /opt/repo-remote.git/
最初のリポジトリは、github上のリモートのexample-repoリポジトリのクローンです。
2つ目はベアリポジトリです。1つ目のコピーは、リモートリポジトリに更新が表示されたときに更新後イベントを処理するためだけに使用されます。 では、これをどのように行うのでしょうか?
スキームは非常に単純です(テストブランチを追跡し、アプリケーションがpm2マネージャーによって管理されるnode.jsであると仮定します):
1.最初のローカルリポジトリを定期的にリモートリポジトリの状態に完全に対応する状態に更新します。
2.最初のローカルリポジトリから、2番目のローカルリポジトリを更新します。
3. HEADが移動するとすぐに-新しいコミットが表示されます-更新後フックが2番目のリポジトリで使用されます。これは、リポジトリの変更が発生したときに実行され、アプリケーションの再構築と再起動に必要なアクションを実行します。
これを行うには、次のことを行います。
1.最初のローカルリポジトリで、remote-2番目のローカルリポジトリを追加します。
cd /opt/repo-dev/example-repo/ && git remote add prod /opt/repo-remote.git
これで、最初のローカルリポジトリから2番目のリポジトリにgit pushを実行できます。
2. /opt/repo-remote.git/hooks/フォルダーで、更新後ファイルを作成して実行可能にします。
touch /opt/repo-remote.git/hooks/post-update && chmod +x /opt/repo-remote.git/hooks/post-update
これは通常のシェルスクリプトですが、拡張子.shなしのGitの内部規則によると!
それにいくつかのコマンドを追加しましょう:
#!/bin/bash cd /opt/repo-remote.git /usr/bin/git --work-tree=/opt/repo/example-repo/ checkout -f origin/test cd /opt/repo/example-repo/ /usr/bin/npm install /usr/local/bin/pm2 restart all
スクリプトは何をしますか? まず、ベアリポジトリの作業ツリーを作業中のアプリケーションのフォルダーにアンロードし、依存関係を再構築してpm2サービスを再起動します。 ご覧のとおり、魔法はありません。
3. cronを構成します。n分ごとに、リモートから最初のリポジトリが更新されます。
git fetch origin && git reset --hard -f origin/test
T.O. これで、ホストはリモートリポジトリをチェックする通常のイニシエーターになりますが、更新はありましたか?
ローカルリポジトリはgit pullではなく、git reset --hardで更新していることに注意してください。 これは、次のコミットの特定のコンテンツとのマージの必要性を排除するために行われます-ローカルリポジトリをリモートリポジトリの完全なコピーにします。
4.最初のローカルリポジトリをリモートリポジトリと同期した直後に、すべての変更を擬似リモートの2番目のローカルリポジトリにプッシュします。
git push prod test
以上です。 擬似リモートローカルリポジトリがゼロ以外の変更を受け取るとすぐに、Gitは更新後のフックをプルし、対応するスクリプトを実行します。 そして、必要に応じて、必要に応じてさらに改善できるシンプルなプッシュツーデプロイ作業スキームを取得します。
「なぜこのような消化できない怪物のような計画を立てるのですか?!」とあなたは尋ねます。 最初は同じ質問をしましたが、既存のGitフックのリストでは、これがリモートリポジトリのブランチの更新に必要な処理を呼び出すことができる唯一の方法であることがわかりました。 必要な更新後のフックは、リモートリポジトリで実行するように設計されています(そして、いくつかのフックはローカルリポジトリで実行するように設計されています)。 そして、それほどエレガントではない方法で、この擬似リモートリポジトリをエミュレートしました。 おそらく近い将来、ローカルで実行されるより便利なフックがいくつかあり、スキームを簡素化できます。 しかし、これまでのところ。
結論として、私はこれを自分で実装することに決めた人にいくつかのアドバイスをしたいと思います。壊れたフックまたはその一部の問題に直面して、元の記事の著者であるGitとリストの他のすべての人を激しく呪います:
1. cronの詳細を覚えておいてください-cron内のプログラムは、おそらく予想とはまったく異なる環境でデフォルトで実行されます。
2.ユーティリティをスクリプトやcronから呼び出すときは、ユーティリティのバージョン(npm、ノードなど)を確認します。たとえば、環境変数の実行可能ファイルへのパスが異なるため、手動で起動する場合とは異なる場合があります。 また、他のバージョンのリリースは、予測できない結果をもたらす可能性があります。
3. 20分間、次のシンプソンズシリーズを見て、新たな活力と良いユーモアの実験に戻りましょう。
メリットについてのコメントや説明を歓迎します。
良い一日を!