プッシュルール

GitLab 16.3で、プッシュルールの最大正規表現長が255文字から511文字に変更されました。

プッシュルールは、ユーザーフレンドリーなインターフェイスで有効化できるGitの事前受信フックです。プッシュルールは、リポジトリにプッシュできるものとできないものをよりコントロールできるようにします。GitLabは保護ブランチを提供していますが、より具体的なルールが必要な場合もあります:

  • コミットの内容の評価。
  • コミットメッセージが期待される書式と一致していることの確認
  • ブランチ名ルールの強制
  • ファイルの詳細の評価
  • Git タグの削除防止。

GitLabでは、プッシュルールの正規表現にRE2構文を使います。regex101 regex testerでテストすることができます。それぞれの正規表現は511文字までに制限されています。

カスタムプッシュルールにはサーバーフックを使ってください。

グローバルプッシュルールの有効化

すべての新規プロジェクトに継承させるプッシュルールを作成できますが、プロジェクトレベルまたはグループレベルで上書きすることができます。グローバルプッシュルールを設定した後に作成されたすべてのプロジェクトは、この設定を継承します。ただし、既存のプロジェクトは、「プロジェクトごとにグローバルプッシュルールを上書きする」で説明するプロセスを使用して、手動で更新する必要があります。

前提条件

  • 管理者である必要があります。

グローバルプッシュルールを作成するには

  1. 左のサイドバーで、Search を選択するか、次のページに進んでください。
  2. Admin Areaを選択します。
  3. プッシュルール]を選択します。
  4. プッシュルールを展開します。
  5. 必要なルールを設定します。
  6. プッシュルールを保存を選択します。

プロジェクトごとのグローバルプッシュルールの上書き

個々のプロジェクトのプッシュルールは、グローバルプッシュルールを上書きします。特定のプロジェクトのグローバルプッシュルールを上書きしたり、既存のプロジェクトのルールを新しいグローバルプッシュルールに合わせて更新したりするには、次のようにします:

  1. 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
  2. 設定] > [リポジトリ]を選択します。
  3. プッシュルールを展開します。
  4. 必要なルールを設定します。
  5. プッシュルールを保存を選択します。

ユーザーを確認

これらのルールを使用して、コミットを行うユーザーを検証します。

  • 認証されていないユーザーを拒否します:ユーザーはメールアドレスが確認されている必要があります。
  • コミット作成者がGitLabユーザーかどうかを確認します:コミット作成者とコミッターは、GitLabによって確認されたメールアドレスを持っている必要があります。
  • コミット作成者のメールアドレス:作成者とコミッターのメールアドレスの両方が正規表現にマッチする必要があります。どのようなアドレスでも許可する場合は、空のままにしてください。

コミットメッセージの検証

コミットメッセージには以下のルールを使用します。

  • コミットメッセージに式を必須とします:メッセージは式にマッチしなければなりません。どのようなコミットメッセージでも許可する場合は空のままにしてください。マルチラインモードを使用します。(?-m)で無効にすることができます。バリデーションの例

    • JIRA\-\d+ Refactored css. Fixes JIRA-123のように、すべてのコミットが Jira イシューを参照する必要があります。
    • [[:^punct:]]\b$ は、最後の文字が句読点の場合、コミットを拒否します。Git はコミットメッセージの最後に改行文字 (\n) を追加するため、単語境界文字 (\b) は誤検出を防ぎます。
  • コミットメッセージの式を拒否コミットメッセージは式にマッチしてはいけません。任意のコミットメッセージを許可するには、空のままにします。マルチラインモードを使用します。(?-m)を使用して無効にすることができます。

DCO認証されていないコミットの拒否

GitLab 15.5 で導入されました

Developer Certificate ofOrigin(DCO) で署名されたコミットは、貢献者がそのコミットで貢献したコードを書いた、または提出する権利を持っていることを証明します。プロジェクトへのすべてのコミットが DCO に従うことを要求することができます。このプッシュルールでは、すべてのコミットメッセージにSigned-off-by: のトレーラが必要で、それがないコミットは拒否されます。

ブランチ名の検証

ブランチ名を検証するには、ブランチ名に正規表現を入力します。任意のブランチ名を許可するには、空白のままにします。デフォルトのブランチは常に許可されます。デフォルトでは、セキュリティのためにブランチ名の形式が制限されています。Git のコミットハッシュに似た 16 進数 40 文字の名前は禁止されています。

検証例をいくつか示します:

  • ブランチはJIRA- で始まる必要があります。

     `^JIRA-`
    
  • ブランチは-JIRA で終わる必要があります。

     `-JIRA$`
    
  • ブランチの長さは4 から15 の間で、小文字、数字、ダッシュのみ使用できます。

     `^[a-z0-9\\-]{4,15}$`
    

意図しない結果を防ぐ

意図しない結果を防ぐために、以下のルールを使いましょう。

  • 署名されていないコミットを拒否します:コミットにはGPGによる署名が必要です。このルールは、Web IDEで作成された正当なコミットをブロックし、GitLab UIで作成された署名なしのコミットを許可することができます。
  • ユーザーがgit push を使って Git タグを削除することを許可しない:ユーザーはgit push を使って Git タグを削除することができません。ユーザーは UI でタグを削除することができます。

ファイルの検証

これらのルールを使用して、コミットに含まれるファイルを検証します。

  • シークレットファイルをプッシュしないようにします:ファイルにシークレットがあってはなりません。
  • 禁止されたファイル名:リポジトリに存在しないファイルは、正規表現にマッチしてはいけません。すべてのファイル名を許可するには、空のままにします。一般的な例を参照してください。
  • 最大ファイルサイズ:追加または更新されたファイルは、このファイルサイズ(MB)を超えてはなりません。任意のサイズのファイルを許可するには、0 に設定します。Git LFSによって追跡されるファイルは除外されます。

リポジトリにシークレットをプッシュしないようにします。

13.9でGitLab Premiumに移行しました。

認証ファイルやSSH秘密鍵のようなシークレットをバージョン管理システムにコミットしてはいけません。GitLab では、定義済みのファイルリストを使ってリポジトリからそれらのファイルをブロックすることができます。リストにマッチするファイルを含むマージリクエストはブロックされます。このプッシュルールは、すでにリポジトリにコミットされているファイルを制限するものではありません。このルールを使うには、プロジェクトごとにグローバルプッシュルールを上書きする で説明する手順で、既存のプロジェクトの設定を更新する必要があります。

このルールでブロックされるファイルを以下に示します。基準の完全なリストについては、files_denylist.ymlを参照してください。

  • AWS CLI クレデンシャル blob:

    • .aws/credentials
    • aws/credentials
    • homefolder/aws/credentials
  • RSA SSH秘密鍵:

    • /ssh/id_rsa
    • /.ssh/personal_rsa
    • /config/server_rsa
    • id_rsa
    • .id_rsa
  • 非公開DSA SSHキー:

    • /ssh/id_dsa
    • /.ssh/personal_dsa
    • /config/server_dsa
    • id_dsa
    • .id_dsa
  • 非公開ED25519 SSH鍵:

    • /ssh/id_ed25519
    • /.ssh/personal_ed25519
    • /config/server_ed25519
    • id_ed25519
    • .id_ed25519
  • 非公開ECDSA SSH鍵:

    • /ssh/id_ecdsa
    • /.ssh/personal_ecdsa
    • /config/server_ecdsa
    • id_ecdsa
    • .id_ecdsa
  • 非公開ECDSA_SK SSHキー(GitLab 14.8以降):

    • /ssh/id_ecdsa_sk
    • /.ssh/personal_ecdsa_sk
    • /config/server_ecdsa_sk
    • id_ecdsa_sk
    • .id_ecdsa_sk
  • 非公開 ED25519_SK SSH 鍵 (GitLab 14.8 以降):

    • /ssh/id_ed25519_sk
    • /.ssh/personal_ed25519_sk
    • /config/server_ed25519_sk
    • id_ed25519_sk
    • .id_ed25519_sk
  • これらの接尾辞で終わるファイル

    • *.pem
    • *.key
    • *.history
    • *_history

名前によるファイルの禁止

13.9でGitLab Premiumに移行しました。

Gitでは、ファイル名にはファイル名とその前にあるすべてのディレクトリの両方が含まれます。git push 、プッシュされた各ファイル名は、禁止されたファイル名の正規表現と比較されます。

禁止ファイル]プッシュ ルールの正規表現には、除外する複数の独立した一致を含めることができます。リポジトリ内の任意の場所に広くファイル名を一致させることも、特定の場所にのみ制限をかけることもできます。ファイル名のマッチは部分的にすることもでき、拡張子によってファイルタイプを除外することもできます。

これらの例では regex (正規表現) の文字列境界文字を使って文字列の先頭 (^) と末尾 ($) にマッチさせています。また、ディレクトリパスやファイル名に./ が含まれるインスタンスも含まれています。 これらの特殊な正規表現文字をマッチ条件の標準文字として使いたい場合は、どちらもバックスラッシュ\\ でエスケープする必要があります。

  • Prevent push.exe files to any location in the repository - この正規表現は、末尾に.exe を含むファイル名にマッチします:

     \.exe$
    
  • リポジトリのルートにある特定の設定ファイルをプッシュしないようにします。

     ^config\.yml$
    
  • 特定の設定ファイルを既知のディレクトリにプッシュしないようにします。

     ^directory-name\/config\.yml$
    
  • リポジトリの任意の場所に特定のファイルをプッシュしないようにする - この例では、install.exe という名前のファイルをテストします。括弧で囲まれた式(^|\/) は、ディレクトリ区切り文字に続くファイルか、リポジトリのルートディレクトリにあるファイルにマッチします:

     (^|\/)install\.exe$
    
  • 前の式をすべて 1 つの式にまとめる- 前の式は文字列の終端文字$ に依存しています。それぞれの式のその部分を、グループ化されたマッチ条件のコレクションの最後に移動することができます:

     (\.exe|^config\.yml|^directory-name\/config\.yml|(^|\/)install\.exe)$
    

トラブルシューティング

署名なしコミットを拒否するプッシュルールが Web IDE を無効にします

GitLab 13.10 では、プロジェクトにReject unsigned commitspush rule が設定されている場合、ユーザーは GitLab Web IDE からコミットを作成することができません。

このプッシュルールがあるプロジェクトでWeb IDEからのコミットを許可するには、GitLab管理者は機能フラグreject_unsigned_commits_by_gitlab.をフラグで無効にする必要があります。

Feature.disable(:reject_unsigned_commits_by_gitlab)

GitLab UI で作成された署名なしコミット

Reject unsigned commitsプッシュルールは、GitLab で認証され作成されたコミットを無視します(UI または API を通して)。このプッシュルールが有効な場合でも、GitLab 自身で作成されたコミットであれば、署名なしコミットがコミット履歴に表示されることがあります。予想通り、GitLab外で作成されリポジトリにプッシュされたコミットは拒否されます。この問題の詳細については、イシュー#19185をお読みください。

_全プロジェクトの_一括更新プッシュルール

すべてのプロジェクトで同じプッシュルールに更新するには、railsコンソールを使うか、Push Rules APIエンドポイントを使って各プロジェクトを更新するスクリプトを書く必要があります。

例えば、Check whether the commit author is a GitLab userandDo not allow users to remove Git tags withgit push チェックボックスを有効にし、rails consoleからのみ特定のメールドメインからのコミットを許可するフィルタを作成します:

caution
データを変更するコマンドは、正しく実行しなかったり適切な条件下で実行しなかったりすると、ダメージを与える可能性があります。必ず最初にテスト環境でコマンドを実行し、リストアできるようにバックアップインスタンスを用意してください。
Project.find_each do |p|
  pr = p.push_rule || PushRule.new(project: p)
  # Check whether the commit author is a GitLab user
  pr.member_check = true
  # Do not allow users to remove Git tags with `git push`
  pr.deny_delete_tag = true
  # Commit author's email
  pr.author_email_regex = '@domain\.com$'
  pr.save!
end