From 3f014528116e0a6d6900f8b1104a2720ff952794 Mon Sep 17 00:00:00 2001 From: monthop-gmail Date: Thu, 27 Aug 2026 01:50:55 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20=E0=B8=95=E0=B8=B2=E0=B8=A3=E0=B8=B2?= =?UTF-8?q?=E0=B8=87=E0=B8=9F=E0=B8=B5=E0=B9=80=E0=B8=88=E0=B8=AD=E0=B8=A3?= =?UTF-8?q?=E0=B9=8C=E0=B8=84=E0=B8=A7=E0=B8=B2=E0=B8=A1=E0=B8=9B=E0=B8=A5?= =?UTF-8?q?=E0=B8=AD=E0=B8=94=E0=B8=A0=E0=B8=B1=E0=B8=A2=E0=B8=95=E0=B8=B2?= =?UTF-8?q?=E0=B8=A1=20visibility=20=E0=B9=81=E0=B8=A5=E0=B8=B0=E0=B8=9B?= =?UTF-8?q?=E0=B8=A3=E0=B8=B0=E0=B9=80=E0=B8=A0=E0=B8=97=E0=B8=9A=E0=B8=B1?= =?UTF-8?q?=E0=B8=8D=E0=B8=8A=E0=B8=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ทีมถามบ่อยว่า "ปิดเป็น private ปลอดภัยกว่าไหม" และ "ย้ายไปบัญชีส่วนตัว จะต่างไหม" — เดิมเอกสารตอบได้แค่ครึ่งเดียว และไม่ได้แยก org กับ personal ทดสอบจริงกับ repo ทั้ง 4 แบบบนแผนฟรี (personal/org × public/private) ผลคือ public/private เป็นตัวตัดสินเกือบทุกอย่าง ส่วน org/personal แทบไม่เกี่ยว — คอลัมน์ personal+public กับ org+public เหมือนกันทุกแถว และ personal+private กับ org+private ก็เหมือนกันทุกแถว - ตารางฟีเจอร์ 9 อย่าง × 4 แบบบัญชี/visibility - ตารางสิ่งที่ต่างกันจริงระหว่าง org กับ personal (CODEOWNERS ใช้ @team, org-level ruleset/secret, และ gitleaks-action ที่ org ต้องมี license) - สรุปวิธีตัดสินใจ: อย่าปิดเป็น private เพื่อความปลอดภัย เพราะบนแผนฟรี มันทำให้แย่ลง เหลือเครื่องมือตรวจแค่ Dependabot ตัวเดียว - docs/05: ใส่ caveat ว่า org-level ruleset มีผลกับ public เท่านั้นบนแผนฟรี - docs/99: เพิ่มแถวในตารางแก้ปัญหา Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Dru5ECsrJrqhTfUhUvDsqw --- docs/04-ci-branch-protection.md | 83 ++++++++++++++++++++++++++------- docs/05-multi-repo.md | 4 ++ docs/99-cheatsheet.md | 1 + 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/docs/04-ci-branch-protection.md b/docs/04-ci-branch-protection.md index 00c89f1..861dd3e 100644 --- a/docs/04-ci-branch-protection.md +++ b/docs/04-ci-branch-protection.md @@ -153,33 +153,84 @@ git switch main && echo x >> README.md && git commit -am 'test' && git push git reset --hard origin/main ``` -### ข้อจำกัดตามแผนของ GitHub +### ข้อจำกัดตามแผนและ visibility -**branch protection / rulesets ใช้กับ private repo ไม่ได้บนแผนฟรี** ต้องเป็น GitHub Pro/Team/Enterprise -บน public repo ใช้ได้ทุกแผน +คำถามที่ทีมถามบ่อยที่สุดคือ "ถ้าย้ายไปบัญชีอื่น หรือปิดเป็น private จะได้อะไร เสียอะไร" +คำตอบสั้น ๆ: -เช็คว่า repo ไหนติดข้อจำกัดนี้: +> **public/private เป็นตัวตัดสินเกือบทุกอย่าง · org/personal แทบไม่เกี่ยว** + +ตารางข้างล่างมาจากการทดสอบจริงกับ repo ทั้ง 4 แบบบนแผนฟรี ไม่ใช่จากเอกสารอย่างเดียว + +#### ฟีเจอร์ความปลอดภัยบนแผนฟรี + +| ฟีเจอร์ | personal + public | personal + private | org + public | org + private | +| --- | :---: | :---: | :---: | :---: | +| branch protection / rulesets | ได้ | **ไม่ได้** | ได้ | **ไม่ได้** | +| secret scanning | ได้ | **ไม่ได้** | ได้ | **ไม่ได้** | +| push protection (บล็อกตอน push) | ได้ | **ไม่ได้** | ได้ | **ไม่ได้** | +| code scanning (CodeQL) | ได้ | **ไม่ได้** | ได้ | **ไม่ได้** | +| private vulnerability reporting | ได้ | **ไม่ได้** | ได้ | **ไม่ได้** | +| Dependabot alerts + security updates | ได้ | **ได้** | ได้ | **ได้** | +| Actions | ไม่จำกัด | กินโควตา | ไม่จำกัด | กินโควตา | +| `gitleaks` ผ่าน docker ใน CI | ได้ | ได้ | ได้ | ได้ | +| `pip-audit` / `npm audit` ใน CI | ได้ | ได้ | ได้ | ได้ | + +**คอลัมน์ที่ 1 กับ 3 เหมือนกันทุกแถว และคอลัมน์ที่ 2 กับ 4 ก็เหมือนกันทุกแถว** — +การย้าย repo จาก org ไปบัญชีส่วนตัว (หรือกลับกัน) ไม่เปลี่ยนอะไรเลยเรื่องความปลอดภัย + +สิ่งที่ต้องจ่ายเพิ่มถึงจะได้บน private: + +| ต้องการ | ต้องมี | +| --- | --- | +| branch protection บน private | GitHub Pro (บัญชีส่วนตัว) หรือ Team (org) | +| secret scanning + CodeQL บน private | GitHub Advanced Security (แพงกว่ามาก) | + +#### สิ่งที่ต่างกันจริงระหว่าง org กับบัญชีส่วนตัว + +| | personal | org | +| --- | --- | --- | +| `CODEOWNERS` ใช้ `@org/team` ได้ | ไม่ได้ — ใส่ได้แค่ชื่อคน | **ได้** | +| org-level ruleset (ตั้งทีเดียวครอบทุก repo) | ไม่มี concept นี้ | มี (private ต้องมีแผน Team ขึ้นไป) | +| org-level secret (`gh secret set --org`) | ไม่ได้ | **ได้** | +| `gitleaks/gitleaks-action` | ใช้ฟรี | **ต้องมี `GITLEAKS_LICENSE`** | +| จัดสิทธิ์เป็นทีม / audit log | ไม่ได้ | ได้ | + +`gitleaks-action` เป็นข้อเดียวที่ org แย่กว่า — เลี่ยงด้วยการเรียก CLI ผ่าน docker แทน +ซึ่งกลายเป็นดีกว่าเพราะ pin เวอร์ชันได้และใช้ได้เหมือนกันทุกที่: + +```yaml + - uses: actions/checkout@v7 + with: + fetch-depth: 0 # ต้องเห็นทั้ง history ไม่งั้นจับ secret ที่ commit แล้วลบทีหลังไม่ได้ + + - name: gitleaks + run: | + docker run --rm -v "$PWD:/repo" zricethezav/gitleaks:v8.30.1 \ + git /repo --no-banner --redact --exit-code 1 +``` + +`--redact` ห้ามลืม — ไม่งั้น secret ที่เจอจะถูกพิมพ์ลง log ของ Actions +ซึ่งบน public repo ใครก็อ่านได้ เครื่องมือกันรั่วจะกลายเป็นตัวรั่วเสียเอง + +#### เช็คว่า repo ไหนติดข้อจำกัดนี้ ```bash gh api repos/OWNER/REPO/rules/branches/main # → 403 "Upgrade to GitHub Pro or make this repository public to enable this feature." ``` -`audit-repos.sh` จะแสดงเป็น `n/a` ไม่ใช่ `no` — เพราะสองอย่างนี้ต้องแก้คนละวิธี +`audit-repos.sh` แสดงเป็น `n/a` ไม่ใช่ `no` เพราะสองอย่างนี้แก้คนละวิธี — `no` = ไปตั้งซะ · `n/a` = ต้องอัปเกรดแผน หรือเปลี่ยน repo เป็น public -ตารางฟีเจอร์ความปลอดภัยบนแผนฟรี: +#### สรุปวิธีตัดสินใจ -| | public | private | -| --- | --- | --- | -| branch protection / rulesets | ใช้ได้ | **ใช้ไม่ได้** | -| secret scanning + push protection | ใช้ได้ | ใช้ไม่ได้ (ต้องมี Advanced Security) | -| code scanning (CodeQL) | ใช้ได้ | ใช้ไม่ได้ (ต้องมี Advanced Security) | -| Dependabot alerts + security updates | ใช้ได้ | **ใช้ได้** | -| Actions | ไม่จำกัด | กินโควตาของแผน | - -ถ้า repo เป็น private บนแผนฟรี สิ่งที่ทำได้คือเอา `gitleaks` กับ `pip-audit`/`npm audit` -ไปเป็น job ใน CI แทน — ได้ผลใกล้เคียงแต่ต้องดูแลเอง +- **อย่าปิดเป็น private เพื่อความปลอดภัย** — บนแผนฟรีมันทำให้แย่ลง เพราะเสียเครื่องมือตรวจ 5 ตัว + เหลือแค่ Dependabot · ปิดเพราะเป็นความลับทางธุรกิจได้ แต่นั่นคือการตัดสินใจเชิงธุรกิจ +- **ถ้าจำเป็นต้อง private** ให้เอา `gitleaks` + `pip-audit` ไปเป็น job ใน CI ทดแทน + ไม่งั้นจะกลายเป็นปิดตาแล้วรู้สึกปลอดภัยขึ้น ทั้งที่มองไม่เห็นอะไรเลย +- **ถ้าจะจ่ายเพิ่ม** GitHub Team ที่ระดับ org คุ้มกว่าซื้อ Pro รายคน เพราะได้ทั้ง + branch protection บน private ทุก repo และ org-level ruleset ที่ตั้งครั้งเดียวครอบทุก repo ### ระวังตอนเริ่มใช้ diff --git a/docs/05-multi-repo.md b/docs/05-multi-repo.md index 1e0a2ca..2a51c58 100644 --- a/docs/05-multi-repo.md +++ b/docs/05-multi-repo.md @@ -158,6 +158,10 @@ gh api -X POST orgs/myorg/rulesets --input templates/rulesets/org-main-protectio ข้อควรรู้: กฎระดับ org **บวกเพิ่ม**กับกฎระดับ repo ไม่ได้ทับกัน — repo เข้มกว่าได้ แต่หย่อนกว่าไม่ได้ เริ่มด้วย `"enforcement": "evaluate"` เพื่อดูผลก่อนบังคับจริง แล้วค่อยเปลี่ยนเป็น `"active"` +> ⚠️ **บนแผนฟรี กฎจะมีผลกับ public repo เท่านั้น** — private repo ต้องมีแผน Team ขึ้นไป +> ดูตารางเต็มว่าอะไรใช้ได้บ้างตาม visibility และประเภทบัญชีที่ +> [04 — ข้อจำกัดตามแผนและ visibility](04-ci-branch-protection.md) + --- ## 5.5 ใช้ Claude Code กับหลาย repo diff --git a/docs/99-cheatsheet.md b/docs/99-cheatsheet.md index 5862580..b74e37b 100644 --- a/docs/99-cheatsheet.md +++ b/docs/99-cheatsheet.md @@ -98,6 +98,7 @@ reflog กู้ได้เกือบทุกอย่างที่เค | `refusing to allow an OAuth App to create or update workflow` | token ไม่มี scope `workflow` | `gh auth refresh -h github.com -s workflow` | | push แล้วขึ้น `protected branch hook declined` | กำลัง push ตรงเข้า main | ถูกแล้ว — เปิด branch + PR | | PR merge ไม่ได้ ปุ่มเทา ทั้งที่ CI เขียว | มี review thread ที่ยังไม่ resolve / branch ไม่ up-to-date | resolve ให้หมด แล้ว `gh pr update-branch 142` | +| ตั้ง branch protection บน private repo ไม่ได้ (403 Upgrade to GitHub Pro) | แผนฟรีรองรับเฉพาะ public repo | อัปเกรดเป็น Team/Pro หรือใช้ `gitleaks`+`pip-audit` ใน CI แทน — ดู [04](04-ci-branch-protection.md) | | เปิด PR แล้วไม่มี check ขึ้นเลย (repo เพิ่งสร้าง) | GitHub ยังไม่ register workflow เพราะยังไม่เคยมีบน default branch | merge workflow เข้า main รอบแรกก่อน แล้วค่อยตั้ง required check — ดู [04](04-ci-branch-protection.md) | | required check ค้าง "Expected — Waiting for status" | ชื่อ check ใน ruleset ไม่ตรงกับชื่อ job จริง | เทียบชื่อกับ `gh pr checks` แล้วแก้ ruleset — ดู [04](04-ci-branch-protection.md) | | CI ผ่านบนเครื่อง แต่แดงบน GitHub | เวอร์ชัน runtime / env var ต่างกัน | pin เวอร์ชันใน workflow ให้ตรงกับ local แล้วดู `gh run view --log-failed` |