ドキュメントには頻繁に更新が加えられ、その都度公開されています。本ページの翻訳はまだ未完成な部分があることをご了承ください。最新の情報については、英語のドキュメンテーションをご参照ください。本ページの翻訳に問題がある場合はこちらまでご連絡ください。

このバージョンの GitHub Enterprise はこの日付をもって終了となりました: 2021-03-02. 重大なセキュリティの問題に対してであっても、パッチリリースは作成されません。 パフォーマンスの向上、セキュリティの改善、新機能のためには、最新バージョンのGitHub Enterpriseにアップグレードしてください。 アップグレードに関する支援については、GitHub Enterprise supportに連絡してください。

pre-receiveフックスクリプトの作成

pre-receiveフックスクリプトを使って、プッシュを内容に基づいて受け付けあるいは拒否するための要件を作成します。

ここには以下の内容があります:

GitHub Enterprise Server の pre-receive フックの例は、github/platform-samplesリポジトリで見ることができます。

pre-receiveフックスクリプトの作成

pre-receive フックスクリプトは、GitHub Enterprise Server アプライアンス上の pre-receive フック環境内で実行されます。 pre-receiveフックスクリプトを作成する際には、利用可能な入力、出力、終了ステータス、環境変数について考慮してください。

入力(stdin)

プッシュが行われ、リモートリポジトリ上でrefがあった場合に、それらが更新される前、 git-receive-packプロセスは更新されるrefごとに1行の標準入力を渡してpre-receiveフックスクリプトを呼び出します。

<old-value> SP <new-value> SP <ref-name> LF

この文字列は以下の引数を表現しています。

引数説明
<old-value>refに保存されている古いオブジェクトネーム。
新しいref作成した場合、これは40個のゼロになる。
<new-value>refに保存される新しいオブジェクトネーム。
ref削除した場合、これは40個のゼロになる。
<ref-name>refの完全な名前。

git-receive-packに関する詳しい情報については、Gitのドキュメンテーション中のgit-receive-packを参照してください。 refsに関する詳しい情報については、Pro GitGit Referencesを参照してください。

出力(stdout)

スクリプトの出力(stdout)はクライアントに返されるので、echo文があればその出力はコマンドライン上あるいはユーザインターフェースからユーザに見えることになります。

終了ステータス

pre-receiveスクリプトの終了ステータスは、プッシュが受け付けられるかどうかを決めます。

終了ステータスの値アクション
0プッシュは受け付けられます。
0以外プッシュは拒否されます。

環境変数

stdin に渡された値以外に、GitHub Enterprise Server 上で動作する pre-receive フックスクリプトから利用できる追加の変数があります。

変数説明
$GITHUB_USER_LOGINref を作成したユーザ ID
$GIT_DIRアプライアンス上のリモートリポジトリのパス。
$GITHUB_USER_IPプッシュを行ったユーザの IP アドレス。
$GITHUB_REPO_NAMEowner/repo フォーマットでの更新されるリポジトリの名前。
$GITHUB_PULL_REQUEST_AUTHOR_LOGINインスタンス上でオープンされたプルリクエストの作者のユーザ ID。
$GITHUB_REPO_PUBLIC論理値で、true ならパブリックリポジトリを、false ならプライベートリポジトリを示す。
$GITHUB_PUBLIC_KEY_FINGERPRINTユーザの公開鍵のフィンガープリント。
$GITHUB_PULL_REQUEST_HEADPR の HEAD に対する user:branch という形式の文字列。
例: octocat:fix-bug
$GITHUB_PULL_REQUEST_BASEPR の BASE に対する user:branch という形式の文字列。
例: octocat:main
$GITHUB_VIAref の作成に使われた方式。
取り得る値:
- auto-merge deployment api
- blob edit
- branch merge api
- branches page delete button
- git refs create api
- git refs delete api
- git refs update api
- merge api
- pull request branch delete button
- pull request branch undo button
- pull request merge api
- pull request merge button
- pull request revert button
- releases delete button
- stafftools branch restore
- slumlord (#{sha})
$GIT_PUSH_OPTION_COUNTクライアントによって送信されたプッシュオプション数。 プッシュオプションに関する詳しい情報については、Gitのドキュメンテーションのgit-pushを参照してください。
$GIT_PUSH_OPTION_Nここで N は 0 から始まる整数で、この変数にはクライアントから送信されたプッシュオプションの文字列が含まれます。 送信された最初のオプションはGIT_PUSH_OPTION_0に保存され、2番目のオプションはGIT_PUSH_OPTION_1に保存され、といったようになります。 プッシュオプションに関する詳しい情報については、Gitのドキュメンテーションのgit-pushを参照してください。

権限の設定と GitHub Enterprise Server への pre-receive フックのプッシュ

pre-receive フックスクリプトは、GitHub Enterprise Server アプライアンス上のリポジトリに含まれます。 サイト管理者はリポジトリの権限を考慮し、適切なユーザだけがアクセスできるようにしなければなりません。

フックは単一のリポジトリに集約することをおすすめします。 集約されたフックのリポジトリがパブリックになっている場合、README.mdをポリシーの強制の説明に利用できます。 また、コントリビューションをプルリクエスト経由で受け付けることもできます。 しかし、pre-receiveフックはデフォルトブランチからのみ追加できます。 テストのワークフロー用には、設定を持つリポジトリのフォークを使うべきです。

  1. Mac ユーザは、スクリプトに実行権限を持たせてください。

    $ sudo chmod +x SCRIPT_FILE.sh

    Windows ユーザは、スクリプトに実行権限を持たせてください。

    git update-index --chmod=+x SCRIPT_FILE.sh
  2. GitHub Enterprise Server インスタンス上の対象となる pre-receive フックのリポジトリにコミットおよびプッシュしてください。

    $ git commit -m "YOUR COMMIT MESSAGE"
    $ git push
  3. GitHub Enterprise Server のインスタンス上で pre-receive フックを作成してください。

ローカルでのpre-receiveスクリプトのテスト

pre-receive フックスクリプトは、GitHub Enterprise Server アプライアンス上で作成したり更新したりする前に、ローカルでテストできます。 その方法の 1 つは、pre-receive フックを実行できるリモートリポジトリとして働くローカルの Docker 環境を作成することです。

  1. ローカルにDockerがインストールされていることを確認してください。

  2. 以下を含む Dockerfile.dev というファイルを作成してください。

    FROM gliderlabs/alpine:3.3
    RUN \
    apk add --no-cache git openssh bash && \
    ssh-keygen -A && \
    sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \
    adduser git -D -G root -h /home/git -s /bin/bash && \
    passwd -d git && \
    su git -c "mkdir /home/git/.ssh && \
    ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P '' && \
    mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && \
    mkdir /home/git/test.git && \
    git --bare init /home/git/test.git"
    
    VOLUME ["/home/git/.ssh", "/home/git/test.git/hooks"]
    WORKDIR /home/git
    
    CMD ["/usr/sbin/sshd", "-D"]
    
    1. always_reject.sh というテストのpre-receiveスクリプトを作成してください。 このスクリプト例では、全てのプッシュを拒否します。これは、リポジトリをロックする場合に役立ちます。

      #!/usr/bin/env bash
      

    echo "error: rejecting all pushes" exit 1

  3. always_reject.shスクリプトが実行権限を持つことを確認してください。

    $ chmod +x always_reject.sh
  4. Dockerfile.dev を含むディレクトリからイメージをビルドしてください。

    $ docker build -f Dockerfile.dev -t pre-receive.dev .
    > Sending build context to Docker daemon 3.584 kB
    > Step 1 : FROM gliderlabs/alpine:3.3
    >  ---> 8944964f99f4
    > Step 2 : RUN apk add --no-cache git openssh bash && ssh-keygen -A && sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g"  /etc/ssh/sshd_config && adduser git -D -G root -h /home/git -s /bin/bash && passwd -d git && su git -c "mkdir /home/git/.ssh && ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P ' && mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && mkdir /home/git/test.git && git --bare init /home/git/test.git"
    >  ---> Running in e9d79ab3b92c
    > fetch http://alpine.gliderlabs.com/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
    > fetch http://alpine.gliderlabs.com/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
    ....truncated output....
    > OK: 34 MiB in 26 packages
    > ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
    > Password for git changed by root
    > Generating public/private ed25519 key pair.
    > Your identification has been saved in /home/git/.ssh/id_ed25519.
    > Your public key has been saved in /home/git/.ssh/id_ed25519.pub.
    ....出力を省略....
    > Initialized empty Git repository in /home/git/test.git/
    > Successfully built dd8610c24f82
  5. 生成された SSH キーを含むデータコンテナを実行してください。

    $ docker run --name data pre-receive.dev /bin/true
  6. テスト pre-receive フックの always_reject.sh をデータコンテナにコピーしてください:

    $ docker cp always_reject.sh data:/home/git/test.git/hooks/pre-receive
  7. sshd を実行しフックを動作させるアプリケーションコンテナを実行してください。 返されたコンテナ ID をメモしておいてください:

    $ docker run -d -p 52311:22 --volumes-from data pre-receive.dev
    > 7f888bc700b8d23405dbcaf039e6c71d486793cad7d8ae4dd184f4a47000bc58
  8. 生成された SSH キーをデータコンテナからローカルマシンにコピーしてください:

    $ docker cp data:/home/git/.ssh/id_ed25519 .
  9. テストリポジトリのリモートを修正して、Docker コンテナ内の test.git リポジトリにプッシュしてください。 この例では git@github.com:octocat/Hello-World.git を使っていますが、どのリポジトリを使ってもかまいません。 この例ではローカルマシン (127.0.0.1) がポート 52311 をバインドしているものとしていますが、docker がリモートマシンで動作しているなら異なる IP アドレスを使うことができます。

    $ git clone git@github.com:octocat/Hello-World.git
    $ cd Hello-World
    $ git remote add test git@127.0.0.1:test.git
    $ GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 52311 -i ../id_ed25519" git push -u test main
    > Warning: Permanently added '[192.168.99.100]:52311' (ECDSA) to the list of known hosts.
    > Counting objects: 7, done.
    > Delta compression using up to 4 threads.
    > Compressing objects: 100% (3/3), done.
    > Writing objects: 100% (7/7), 700 bytes | 0 bytes/s, done.
    > Total 7 (delta 0), reused 7 (delta 0)
    > remote: error: rejecting all pushes
    > To git@192.168.99.100:test.git
    >  ! [remote rejected] main -> main (pre-receive hook declined)
    > error: failed to push some refs to 'git@192.168.99.100:test.git'

    pre-receive フックの実行後にプッシュが拒否され、スクリプトからの出力がエコーされていることに注意してください。

参考リンク