Branching และ Migrations Workflow
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”Supabase branch คือ preview copy เต็มรูปแบบของ project คุณที่ผูกกับ Git branch หรือ pull request — มี Postgres schema แยกเป็นของตัวเอง และถ้าต้องการก็มี seed data เป็นของตัวเองด้วย — เพื่อให้คุณ test schema change แบบแยกส่วนก่อนที่จะไปแตะ production จริง เหมือนกับที่ preview deployment แยกส่วน app code ของคุณนั่นแหละ
Supabase branch คืออะไรกันแน่
หัวข้อที่มีชื่อว่า “Supabase branch คืออะไรกันแน่”ถ้าไม่มี branching การ “test schema change” ก็มักจะหมายถึงการรัน change นั้นเข้ากับ staging database ที่ใช้ร่วมกัน หรือแย่กว่านั้นคือรันตรงเข้า production เลย Supabase branch แทนที่จะทำแบบนั้น จะ provision Postgres instance ที่แยกจริง ๆ ตลอดอายุของ Git branch หรือ pull request นั้น — มี schema เป็นของตัวเอง, Data API เป็นของตัวเอง, Auth กับ Storage เป็นของตัวเอง และถ้าคุณขอ ก็จะได้ clone ของข้อมูล production ด้วย
# Create a persistent preview branch (stays around across pushes, not tied to a single PR)supabase --experimental branches create --persistent
# Create a preview branch for a pull request, cloning production data into itsupabase --experimental branches create feature-add-comments --with-data
# List every preview branch on the linked projectsupabase --experimental branches listนี่ไม่ใช่ feature flag ที่เปิด-ปิดอยู่ข้างใน database เดียวที่ใช้ร่วมกัน — นี่คือ database ที่แยกออกมาจริง ๆ ซึ่งเป็นเหตุผลว่าทำไมถึงปลอดภัยที่จะรัน migration แบบทำลายข้อมูล, seed test data แปลก ๆ หรือลอง alter table ที่เสี่ยง ๆ ได้ โดยไม่กระทบ production เลย
Migration คือรูปแบบไฟล์ที่ผูก branch เข้ากับ production
หัวข้อที่มีชื่อว่า “Migration คือรูปแบบไฟล์ที่ผูก branch เข้ากับ production”branch จะยังมีประโยชน์อยู่ก็ต่อเมื่อ schema change ที่ test บน branch นั้นเอาไป replay ซ้ำที่อื่นได้อย่างน่าเชื่อถือ นั่นคือหน้าที่ของ migration — ไฟล์ SQL ธรรมดา ที่ถูก commit เข้า version control และ apply ตามลำดับ
# Create a new, timestamped SQL migration file under supabase/migrations/supabase migration new add_comments_table
# Apply all pending local migrations to the linked project or branchsupabase db push
# Capture a schema change made through the Studio GUI as a migration file after the factsupabase db diff --schema publicsupabase migration new ให้ไฟล์ .sql เปล่า ๆ ที่มี timestamp กำกับ ให้คุณเขียนคำสั่ง create table (หรือ alter table) ลงไปเอง supabase db diff ครอบคลุมกรณีตรงข้าม คือมีคนแก้ผ่าน Studio GUI แล้วคุณอยากจับ change นั้นเป็น migration file ที่เป็นทางการ แทนที่จะปล่อยให้ค้างอยู่แค่ใน database ไม่ว่าจะทางไหน supabase db push จะ apply ทุก migration ที่ยังไม่เคยรันเข้ากับ project หรือ branch ที่ชี้ไป — คำสั่งเดียวกัน ไม่ว่าเป้าหมายจะเป็น preview branch หรือ production
Deploy migration ผ่าน CI ไม่ใช่มือคน
หัวข้อที่มีชื่อว่า “Deploy migration ผ่าน CI ไม่ใช่มือคน”คุณค่าของ branching แทบจะหายไปถ้าหลังจาก test migration บน branch แล้ว มีคนเปิด SQL editor แล้ววาง SQL เข้า production เอง จุดนี้แหละที่ typo, ไฟล์ที่ลืมรัน และ migration ที่ผิดลำดับมักจะแอบเข้ามา ทางแก้คือทำให้ supabase db push เป็นส่วนหนึ่งของ CI pipeline เดียวกับที่ deploy application code ของคุณ เพื่อให้ schema change ถูก ship อัตโนมัติและตามลำดับทุกครั้งที่ pull request ถูก merge
# A representative CI step — runs after tests pass, before or alongside the app deploysupabase link --project-ref "$SUPABASE_PROJECT_REF"supabase db pushเมื่อตั้งค่าแบบนี้แล้ว migration file ที่ merge เข้า main branch จะถูก apply เข้า production แบบเดียวกันทุกครั้ง โดย automated process ตัวเดียวกับที่ test บน preview branch มาแล้ว — ไม่มีคนมารัน SQL แบบ ad hoc เข้า database ที่รันจริงอยู่ และไม่มี environment ไหนแอบ drift ออกจากสิ่งที่อยู่ใน version control
flowchart LR
pr["Git branch / pull request"] --> branch["Supabase preview branch (isolated schema copy)"]
branch --> mig["Migrations applied and tested on the branch"]
mig --> merge["Pull request merged"]
merge --> ci["CI runs supabase db push"]
ci --> prod[("Production Postgres")]