From 7c5e09e89d14abe9c744a657aa847ddc71853612 Mon Sep 17 00:00:00 2001 From: monthop-gmail Date: Thu, 27 Aug 2026 00:24:34 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20=E0=B8=9A=E0=B8=B1=E0=B8=99=E0=B8=97?= =?UTF-8?q?=E0=B8=B6=E0=B8=81=E0=B8=81=E0=B8=B1=E0=B8=9A=E0=B8=94=E0=B8=B1?= =?UTF-8?q?=E0=B8=81=20repo=20=E0=B9=83=E0=B8=AB=E0=B8=A1=E0=B9=88?= =?UTF-8?q?=E0=B8=97=E0=B8=B5=E0=B9=88=20CI=20=E0=B9=84=E0=B8=A1=E0=B9=88?= =?UTF-8?q?=E0=B8=A2=E0=B8=AD=E0=B8=A1=E0=B8=A3=E0=B8=B1=E0=B8=99=20?= =?UTF-8?q?=E0=B9=81=E0=B8=A5=E0=B8=B0=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=20CLAUDE.md=20=E0=B8=82=E0=B8=AD=E0=B8=87=20repo=20?= =?UTF-8?q?=E0=B8=99=E0=B8=B5=E0=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ตอนตั้ง CI ให้ repo นี้เจอเองว่า repo ที่ยังไม่เคยมี workflow บน default branch จะไม่รัน CI ให้ ถึงไฟล์จะอยู่บน branch ของ PR แล้วก็ตาม ไม่มี check ขึ้นเลย และ actions/workflows คืน 0 ทั้งที่ Actions เปิดอยู่ ทีมจะเจอทุกครั้งที่ตั้ง repo ใหม่ จึงเขียนวิธีวินิจฉัยและลำดับที่ถูกไว้ เพิ่ม CLAUDE.md ให้ repo ตัวเอง — เน้นข้อห้ามที่เฉพาะกับ repo นี้จริง ๆ คือห้ามทำให้ gate job ชื่อ 'ci' ในไฟล์ template หายไป และห้ามมีข้อมูล จริงหลุดเพราะ repo เป็น public ยังไม่เพิ่ม CODEOWNERS เพราะ repo มีคนเดียว ใส่ไปก็ไม่มีผลจริง เหตุผลบันทึกไว้ใน CLAUDE.md แล้ว Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Dru5ECsrJrqhTfUhUvDsqw --- .github/PULL_REQUEST_TEMPLATE.md | 36 ++++++++++++++++++++ CLAUDE.md | 57 ++++++++++++++++++++++++++++++++ docs/04-ci-branch-protection.md | 35 ++++++++++++++++++++ docs/99-cheatsheet.md | 1 + 4 files changed, 129 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CLAUDE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..5145da2 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,36 @@ +## ทำไมต้องเปลี่ยน + + + +Closes # + +## เปลี่ยนอะไร + + + +- + +## ทดสอบยังไง + + + +```bash + +``` + +## ผลกระทบ + +- [ ] เป็น breaking change (ถ้าใช่ ระบุด้านล่างว่าใครต้องแก้ตาม) +- [ ] ต้องรัน migration +- [ ] ต้องเพิ่ม/แก้ env var หรือ secret (ระบุชื่อ ไม่ต้องใส่ค่า) +- [ ] กระทบ repo อื่น + + + +## Checklist ก่อนขอรีวิว + +- [ ] อ่าน diff ของตัวเองใน GitHub แล้ว +- [ ] CI เขียว +- [ ] ไม่มี debug log / โค้ดที่ comment ทิ้ง / `TODO` ค้าง +- [ ] ไม่มี secret หรือค่า config ที่ hardcode +- [ ] เปลี่ยนจริงไม่เกิน ~400 บรรทัด (ถ้าเกิน อธิบายว่าทำไมแตกไม่ได้) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a79a1ad --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,57 @@ +# workshop-github + +handbook + template + script สำหรับทำให้ทุก repo ของทีมเป็นมาตรฐานเดียวกัน +ใช้ในการอบรมทีม และเป็นแหล่งอ้างอิงหลังอบรมจบ + +## คำสั่งที่ใช้บ่อย + +```bash +./scripts/validate.sh # ตรวจทั้ง repo — CI เรียกตัวเดียวกันนี้ +./scripts/validate.sh templates # เฉพาะ YAML/JSON และ gate job +./scripts/check-setup.sh # ตรวจว่าเครื่องพร้อม (ตัวที่ผู้เข้าอบรมรัน) +``` + +ต้องมี `python3` + `pyyaml`, `shellcheck`, `gh`, `jq` +ถ้าเครื่องไม่มี shellcheck `validate.sh` จะเตือนแล้วข้ามไป — **แต่ CI จะรันให้ ทำให้ PR แดงได้** + +## โครงสร้าง + +``` +docs/ handbook 8 บท เรียงตามลำดับที่ต้องอ่าน (00 = agenda, 99 = cheatsheet) +templates/ ไฟล์ที่ทีมก๊อปไปใช้กับ repo จริง — พังเมื่อไหร่กระทบทุก repo ที่ก๊อปไปแล้ว +scripts/ เครื่องมือติดตั้ง/ตรวจสอบ ต้องรันได้บนเครื่องคนอื่นด้วย +``` + +## กติกาของ repo นี้ + +- **ทุกอย่างเข้าผ่าน PR ที่ CI เขียว** main มี branch protection อยู่ push ตรงเข้าไม่ได้ +- **แก้ `templates/github/workflows/ci-*.yml` แล้วห้ามทำให้ job ชื่อ `ci` หายหรือรอ job ไม่ครบ** + handbook สัญญากับทีมไว้ว่า required status check ชื่อ `ci` ใช้ได้กับทุก template — + ถ้าผิดสัญญา คนที่ก๊อปไปตั้ง branch protection จะเจอ PR ค้างโดยไม่รู้สาเหตุ + (`validate.sh templates` ตรวจข้อนี้ให้) +- **repo นี้เป็น public** ห้ามมีอีเมลจริง ชื่อ org จริง IP หรือ token + ตัวอย่างให้ใช้ `myorg`, `you@company.com`, `example.com` เท่านั้น +- **ตัวอย่างคำสั่งในเอกสารต้องรันได้จริง** ก่อนเขียนลงไปให้ลองรันก่อน + โดยเฉพาะ `gh api` ที่ path เปลี่ยนบ่อย — เอกสารที่คำสั่งพังทำให้คนเลิกเชื่อทั้งเล่ม +- แก้เอกสารแล้วเช็คลิงก์ด้วย `./scripts/validate.sh docs` + +## เขียนเอกสารแบบไหน + +ผู้อ่านคือคนในทีมที่กำลังรีบ ไม่ใช่คนที่อยากเรียนทฤษฎี + +- บอก**ผลจริงที่จะเกิด** ไม่ใช่บอกว่าควรทำเพราะเป็น best practice +- ทุกหัวข้อจบด้วยคำสั่งที่ก๊อปไปวางได้ หรือ checklist ที่ติ๊กได้ +- ตารางชนะย่อหน้า เมื่อเนื้อหาเป็นการเทียบหรือแจกแจง +- ภาษาไทย ยกเว้นศัพท์เทคนิคที่แปลแล้วงงกว่าเดิม (PR, branch, commit, merge) + +## ข้อตกลงการทำงาน + +- งานที่แตะเกิน 2 ไฟล์ → plan mode ก่อน +- ห้าม `git push`, `gh pr merge` — คนกดเอง +- commit ตาม Conventional Commits (`docs:` `ci:` `fix:` `chore:`) +- รัน `./scripts/validate.sh` ให้เขียวก่อนเปิด PR เสมอ + +## ที่ยังไม่มี + +- `CODEOWNERS` — ยังไม่ใส่เพราะ repo มีคนเดียว ใส่ไปก็ไม่มีผล (approve PR ตัวเองไม่ได้) + เพิ่มเมื่อมีคนที่สอง พร้อมเปลี่ยน ruleset เป็น `--approvals 1 --checks ci` diff --git a/docs/04-ci-branch-protection.md b/docs/04-ci-branch-protection.md index bbe0307..712ae11 100644 --- a/docs/04-ci-branch-protection.md +++ b/docs/04-ci-branch-protection.md @@ -16,6 +16,41 @@ ถ้าตั้ง required check ก่อนที่ CI จะเสถียร ทีมจะติดแหง็ก merge อะไรไม่ได้เลย แล้วคนจะขอปิด protection ทิ้ง — จบเห่ +### ข้อยกเว้น: repo ที่เพิ่งสร้างใหม่ + +**repo ที่ยังไม่เคยมี workflow อยู่บน default branch เลย จะไม่รัน CI ให้ ถึงไฟล์จะอยู่บน branch ของ PR แล้วก็ตาม** + +อาการ: เปิด PR ที่เพิ่ม `.github/workflows/ci.yml` เข้ามา แต่ไม่มี check ขึ้นเลย + +```bash +gh api repos/OWNER/REPO/actions/runs --jq .total_count # → 0 +gh api repos/OWNER/REPO/actions/workflows --jq '.workflows | length' # → 0 +gh api repos/OWNER/REPO/actions/permissions --jq .enabled # → true (Actions ไม่ได้ปิด) +``` + +ทั้งสามบรรทัดบอกตรงกันว่า GitHub ยัง**ไม่รู้จัก** workflow นี้ ไม่ใช่ว่ามันรันแล้วพัง + +ทางออก — ยอมรับว่ารอบแรกต้อง merge โดยที่ CI ยังไม่เคยเขียว: + +``` +1. merge PR ที่เพิ่ม workflow เข้า main (CI ยังไม่รัน — ปกติ) +2. GitHub register workflow แล้วรันจาก trigger push:main +3. ตรวจว่า run แรกเขียวจริง และจดชื่อ check ที่ได้ +4. ค่อยตั้ง required check +``` + +**อย่าตั้ง required check ก่อนเห็น run แรกสำเร็จ** ไม่งั้น repo จะ merge อะไรไม่ได้เลย +เพราะ check ที่ไม่เคยมีอยู่จริงจะค้างที่ `Expected — Waiting for status` ตลอดกาล + +ตรวจชื่อ check ที่ใช้ได้จริงหลัง run แรกจบ: + +```bash +gh api "repos/OWNER/REPO/commits/$(git rev-parse main)/check-runs" \ + --jq '.check_runs[] | "\(.name) → \(.conclusion)"' +``` + +ชื่อที่เอาไปใส่ `--checks` ต้องตรงกับคอลัมน์ซ้ายเป๊ะ ๆ รวมทั้งตัวพิมพ์เล็กใหญ่ + --- ## 4.2 ปัญหาที่ทุกคนเจอ: ชื่อ check ไม่นิ่ง diff --git a/docs/99-cheatsheet.md b/docs/99-cheatsheet.md index 9e74c79..5862580 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` | +| เปิด 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` | | commit ไม่ขึ้น contribution graph | `user.email` ไม่ตรงกับอีเมลที่ verified บน GitHub | ดู [01](01-setup.md) |