#5 GitHub Rulesetsでブランチを守る - Python OSS開発記録
python 13 min read

#5 GitHub Rulesetsでブランチを守る - Python OSS開発記録

avatar-m-1

karrinn

著者

Git Flowでブランチ戦略を決めた、次は?「人の注意に頼らず、技術的に間違いを防止」します。
今回はGitHub Rulesetsを使って、mainに直pushを防ぐ設定を、wagtail-reusable-blocksの実例から振り返ります。

KEY TAKEAWAYS

この記事でわかること

  • Branch Protection RulesとRulesetsの決定的な違い
  • main/develop保護の具体的な設定項目
  • 「うっかりミス」を技術的に防止する仕組み作り

用語の定義

TERM 01

Branch Protection Rules

旧方式のブランチ保護機能。ブランチ単位で設定。2024年以降、GitHub Rulesetsへの移行が推奨されている。

TERM 02

GitHub Rulesets

新方式のブランチ・タグ保護機能。パターンマッチで複数ブランチに一括適用可能。Organization単位でも設定可。

TERM 03

Pull Request(PR)

ブランチのマージ前にコードレビューを行う仕組み。変更内容を可視化し、承認フローを経てからマージする。

TERM 04

Force Push

Gitの履歴を強制的に書き換えるpush(git push -f)。共有ブランチで実行すると他の人の作業が消える危険な操作。

なぜ「人の注意」に頼ってはいけないのか

前回、Git Flowでブランチ戦略を決めました。でも「mainに直pushしないでね」と言うだけでは、必ず事故が起きます

これ、企業プロジェクトでよく見る問題です。

事故例1

「小さい修正だから...」→ うっかりmainにpush → 本番破壊

事故例2

「急いでるから...」→ force push → 他人の作業消失

事故例3

「新人だから知らなかった」→ 直push → 大惨事

解決策: GitHub Rulesetsで技術的に防止すれば、うっかりミスも、知らないミスも、全部ブロックできます。

wagtail-reusable-blocksでは初日にRulesets設定。結果、「mainに直pushしちゃった...」の事故ゼロ。

Branch Protection Rules vs GitHub Rulesets

まず、どっちを使うべきかを決めます。結論から言うと、Rulesetsを使ってください

決定的な違い

項目Branch Protection RulesGitHub Rulesets
リリース2016年〜(旧方式)2023年〜(新方式)
設定単位ブランチ1つずつパターンマッチで一括
スコープリポジトリのみOrganization全体も可
タグ保護不可可能
UISettings > BranchesSettings > Rules
今後の対応メンテナンスのみ新機能追加あり

なぜRulesetsを使うべきか

wagtail-reusable-blocksでは、最初からRulesetsを採用しました。

理由1

パターンマッチ → main/develop両方を1つのRulesetで保護

理由2

タグ保護も可能 → v0.1.0タグの削除を防げる

理由3

今後の新機能 → Branch Protection Rulesは新機能なし

移行について

既にBranch Protection Rulesを使ってるプロジェクトは、徐々にRulesetsに移行することをGitHubが推奨しています。両方併用も可能ですが、Rulesetsの方が優先されます。

Ruleset設定: main/develop保護

wagtail-reusable-blocksで実際に設定した「default」Rulesetを見ていきます。

「default」Rulesetの全容

基本設定

項目設定値意味
NamedefaultRuleset名
EnforcementActive有効化(Disabledで無効化可)
TargetBranchブランチ保護(Tagも選択可)
Target branchesmain, develop保護対象のブランチ

保護ルール一覧

wagtail-reusable-blocksでは、5つのルールを設定しました。

ルール設定防ぐこと
Restrict deletions✅ 有効 main/developの削除を禁止
「間違えて消しちゃった」を防ぐ
Block force pushes✅ 有効 force push(git push -f)を禁止
履歴の書き換えを防ぐ
Require signed commits✅ 有効 GPG署名付きコミットのみ許可
なりすましを防ぐ
Require a pull request✅ 有効(詳細あり) 直pushを禁止、PR必須
レビューなしのマージを防ぐ

「Require a pull request」の詳細設定

一番重要なルール。PRを経由しないとマージできない設定です。

項目設定値意味
Required approving review count1承認者1人必要
Dismiss stale reviews on push新しいpush後、承認を無効化
Require code owner reviewCODEOWNERS承認必須(トピック#7)
Require last push approval最終pushの後に承認必要
Required review thread resolutionすべてのコメント解決必須
Allowed merge methodsSquash onlySquash mergeのみ許可

これで防げること

  • git push origin main → ブロック(PR必須)
  • git push -f origin main → ブロック(force push禁止)
  • PRを自分で承認してマージ → ブロック(別の人の承認必要)
  • コメント未解決でマージ → ブロック(全コメント解決必須)

実装: Rulesetの作成手順

実際にGitHub UIで設定していきます。

ステップバイステップ

Step 1: Rulesetsページを開く

  1. リポジトリ → Settings
  2. 左サイドバー → Rules → Rulesets
  3. 「New ruleset」→「New branch ruleset」

Step 2: 基本情報を入力

入力項目:

  • Ruleset Name:default
  • Enforcement status: Active
  • Bypass list: 空(誰もバイパスできない)

Bypass listについて:

管理者でもルールをバイパスできなくします。緊急時は一時的にRulesetを無効化する方が安全。

Step 3: ターゲットブランチを指定

Target branches:

  • 「Include default branch」✅
  • 「Add target」→ 「Include by pattern」
  • Pattern: develop
Pattern Examples
# 単一ブランチ
main
develop

# ワイルドカード
feature/*
release/*

# 複数パターン(ORで結合)
main, develop, release/*

Step 4: ルールを選択

チェックする項目:

  • ✅ Restrict deletions
  • ✅ Block force pushes
  • ✅ Require signed commits
  • ✅ Require a pull request before merging
    • Required approvals: 1
    • ✅ Dismiss stale pull request approvals when new commits are pushed
    • ✅ Require review from Code Owners
    • ✅ Require approval of the most recent reviewable push
    • ✅ Require conversation resolution before merging
    • Allowed merge methods: Squash

Step 5: 保存

「Create」ボタンを押して完了。

確認方法: mainに直pushしてみる → エラーが出ればOK

Bash
# テスト: mainに直push
git checkout main
echo "test" >> README.md
git add README.md
git commit -m "test"
git push origin main

# エラーが出る:
# remote: error: GH013: Repository rule violations
# remote: error: - Changes must be made through a pull request.
# → Rulesets動いてる!

OSS vs 企業プロジェクト: 技術的制限の意味

OSS: メンテナーの負担軽減

OSSプロジェクトでは、様々なレベルのコントリビューターが参加します。
全員が完璧にルールを守れるわけではありません。

「mainに直pushしないでね」と毎回コメントするのはメンテナーの負担
GitHub Rulesetsで技術的にブロックすれば、指摘する手間がゼロになります。

メリット

  • 自動的に防げる: 人間が気づかなくても、システムが止めてくれる
  • レビュー負担軽減: 「ブランチ間違ってますよ」と指摘する時間がゼロ
  • 初心者に優しい: 間違えたらGitHubが教えてくれるので、安心してPRを送れる

技術的予防: 「ルールを守ってね」ではなく、「ルール違反はできない」ようにする。
これがOSSプロジェクトを持続可能にする秘訣です。

企業: 「萎縮」から「安心して失敗できる環境」へ

前回(Topic #4)で触れた「萎縮による開発効率の激減」問題。
GitHub Rulesetsは、この問題を根本から解決します。

従来の問題: 脅しによる教育

  • 「mainに直pushするな!壊れるぞ!」 ← 脅し
  • 新人は萎縮: 「何をやっても怒られるのでは?」と必要以上に慎重になる
  • 「えい」ってやってみることができない: 失敗を恐れて試せない
  • 経験値が溜まらない: 試さないから成長しない
  • 開発効率が激減: 想像の何倍も遅くなる(日本の大企業に多い)

GitHub Rulesetsによる解決: システムで防御

システムでちゃんと防御してあげれば、逆にできることは何やってもいい

  • 失敗したらシステムが弾く: mainに直pushしようとしても、GitHubが止めてくれる
  • 「えい」ってやってみることができる: 間違えても大丈夫だから、試せる
  • 経験値が遥かに溜まりやすい: 失敗を恐れずに試せる = 成長が早い
  • 心理的安全性: 「これやっていいのかな?」と不安にならない

安心して失敗できる環境: これは教育の本質です(私が教育機関で働いていた経験から)。
失敗を恐れずに試せる環境こそが、人を育てます。
システムで防御するのは「面倒」ではなく、チーム全体の生産性への投資です。

具体例: mainへの直push禁止

従来(脅しによる教育):

  • 先輩: 「mainに直pushするな!本番が壊れるぞ!」
  • 新人: 「怖い...何もできない...」(萎縮)
  • 結果: 異常に慎重になり、開発効率が激減

GitHub Rulesets(システムによる防御):

  • 新人: 「mainにpushしてみよう」
  • GitHub: 「エラー: PRを経由してください」(システムが止める)
  • 新人: 「なるほど、PRを作ればいいのか」(学習)
  • 結果: 失敗を恐れずに試せる。経験値が溜まる。

プロジェクト管理の責任

効果的なプロジェクト管理には、システムやツールに対する理解が重要です。

技術的な背景を持つマネージャーは、以下のような利点があります:
システムを活用した予防: ツールや自動化で問題を未然に防げる
効果的な意思決定: 技術的な制約や可能性を理解した上で判断できる
円滑なコミュニケーション: チームメンバーとの技術的な対話がスムーズになる

重要: 技術的制限を「面倒」と感じるかもしれません。
しかし、新規参画者の目線に立てば、これは最大の親切です。
不十分な説明で脅されて萎縮するより、システムで守られて安心して試せる方が、遥かに生産的です。

よくある質問と回答

FAQ

Q1: ソロ開発でも必要?

A: 必要です。自分のうっかりミスを防げます。「小さい修正だから...」で直pushして後悔、よくあります。

Q2: 承認者1人って、自分で承認できない?

A: できません。「Require approval of the most recent reviewable push」が有効なので、別の人の承認が必須

Q3: 緊急時はどうする?

A: Rulesetを一時的に「Disabled」に変更。修正後、すぐ「Active」に戻す。Bypass listより安全です。

Q4: 既存のBranch Protection Rulesは?

A: Rulesetsと併用可能ですが、Rulesetsが優先されます。徐々に移行推奨。

参考リンク

こちらの記事もおすすめ

#4 Git Flowブランチ戦略でチームの混乱を防ぐ - Python OSS開発記録

記事を読む

#6 ブランチ命名規則を技術的に強制する - Python OSS開発記録

記事を読む

関連トピック

コメント (0)

まだコメントはありません。最初のコメントを残しませんか?

コメントを投稿

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