GitLab Workflow vs Job Rules วิธีควบคุม CI/CD Pipeline ให้แม่นยำและประหยัดเวลา
เคยเจอปัญหา Pipeline รันพร่ำเพรื่อไหม? หรือบาง Job รันในตอนที่ไม่ควรจะรัน? การปล่อยให้ CI/CD ทำงานผิดจังหวะทำให้เราเสียเวลาและเปลือง Resource โดยใช่เหตุ
กุญแจสำคัญที่จะแก้ปัญหานี้คือการเข้าใจความแตกต่างระหว่าง Workflow Rules และ Job Rules ใน GitLab ทั้งสองอย่างนี้ทำหน้าที่ "คัดกรอง" เหมือนกัน แต่ทำงานคนละระดับ บทความนี้จะเจาะลึกวิธีใช้เครื่องมือเหล่านี้ให้เราควบคุม Pipeline ได้ดั่งใจในปี 2025
Workflow Rules ผู้คุมประตูหน้าด่าน
Workflow Rules คือด่านแรกสุดของการคัดกรอง มันทำงานที่ระดับ "ทั้ง Pipeline" (Global Level)
ถ้าเงื่อนไขใน Workflow Rules เป็นเท็จ Pipeline นั้นจะไม่ถูกสร้างขึ้นมาเลย แม้แต่ Job เดียวก็ไม่ได้รัน
วิธีใช้งาน
ต้องประกาศ workflow: ไว้ที่ระดับบนสุดของไฟล์ .gitlab-ci.yml
ตัวอย่าง: ต้องการให้ Pipeline รันเฉพาะตอนที่มีการ Push Code หรือมี Schedule เท่านั้น
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- when: alwaysในตัวอย่างนี้ ถ้าเป็น Schedule หรือ Push (ตามเงื่อนไขที่กำหนด never) Pipeline จะไม่ทำงาน แต่ถ้าเป็นกรณีอื่นจะทำงานเสมอ (หรือคุณสามารถสลับ Logic เพื่อ "อนุญาต" เฉพาะสิ่งที่ต้องการได้)
จำง่ายๆ: Workflow Rules ตัดสินชะตา "ทั้งกระบวนการ" ถ้าไม่ผ่าน ก็จบข่าวตั้งแต่เริ่ม
Job Rules ผู้จัดการรายแผนก
Rules (Job Level) ทำงานละเอียดกว่า มันโฟกัสที่ "แต่ละ Job" แยกกัน
ใช้ Job Rules เพื่อกำหนดว่า Job ไหนควรทำ Job ไหนควรข้าม โดยพิจารณาจากเงื่อนไขเฉพาะเจาะจง เช่น ชื่อ Branch, การเปลี่ยนแปลงของไฟล์ หรือค่าตัวแปร
กรณีใช้งานจริง
1. รันเมื่อ Branch ตรงกัน (Scenario 1) เราอยากให้ Job นี้รันเฉพาะเมื่อ Source Branch ของ Merge Request ตรงกับ Default Branch เท่านั้น
job:
script:
- echo "Checking branch..."
rules:
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == $CI_DEFAULT_BRANCH2. รันเมื่อไฟล์เปลี่ยน (Scenario 2) ไม่ต้องรัน Terraform Plan ถ้าไฟล์ .tf ไม่มีการเปลี่ยนแปลง ใช้ changes เพื่อประหยัดเวลา
job:
script:
- terraform plan
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- terraform/**/*.tf3. รันเมื่อไฟล์มีอยู่จริง (Scenario 3) ตรวจสอบว่ามีไฟล์ Gemfile.lock หรือไม่ ถ้ามีค่อยรัน Audit
job:
script:
- bundle-audit check
rules:
- exists:
- Gemfile.lock4. ยอมให้พังได้ (Scenario 4) บางงานถ้าล้มเหลวก็ไม่ควรขัดขวางงานอื่น ใช้ allow_failure: true เข้าช่วย
job:
script:
- run-non-critical-test
rules:
- if: $CI_COMMIT_BRANCH == "main"
allow_failure: trueความแตกต่างที่ต้องรู้ (Workflow vs Job Rules)
ตารางเปรียบเทียบเพื่อให้เห็นภาพชัดเจน
| คุณสมบัติ | Workflow Rules | Job Rules |
|---|---|---|
| ขอบเขต | ควบคุมทั้ง Pipeline (Global) | ควบคุมเฉพาะ Job นั้นๆ (Local) |
| ตำแหน่ง | บนสุดของ YAML (Top Level) | ภายใน Block ของ Job |
| ผลลัพธ์ | Pipeline เกิดหรือไม่เกิด | Job รันหรือถูกข้าม (Skipped) |
| ความถี่การใช้ | ใช้เพื่อประหยัด Resource ภาพรวม | ใช้เพื่อ Logic การทำงานที่ซับซ้อน |
บทสรุป
การเลือกใช้ Workflow Rules หรือ Job Rules ไม่ใช่เรื่องของการรักพี่เสียดายน้อง เราต้องใช้ทั้งคู่ให้ถูกที่ Workflow Rules มันจะช่วยคัดกรองขยะที่หน้าประตู ส่วน Job Rules ช่วยจัดการงานละเอียดภายในบ้าน
ลองใช้งานดูครับเพราะตอนนี้ only และ except จะไม่ให้ใช้งานแล้ว https://docs.gitlab.com/ci/yaml/deprecated_keywords/#only--except