Dependabot คืออะไร และวิธีตั้งค่าให้ช่วยอัปเดต package ในโปรเจกต์ Laravel

Dependabot เป็น bot ของ GitHub ที่อ่าน composer.lock กับ package-lock.json แล้วเปิด pull request อัปเดต package ให้เอง ทั้งตอนที่มีช่องโหว่และตอนที่มีเวอร์ชันใหม่ โพสต์นี้อธิบายวิธีทำงาน การเปิดใช้ ไฟล์ dependabot.yml และสิ่งที่ควรดูก่อนกด merge

เผยแพร่
เวลาอ่าน
6 นาที

ปกติเรามักอัปเดต package ตอนที่นึกขึ้นได้ หรือตอนที่มีข่าวช่องโหว่ใหญ่ ๆ แล้วรัน composer update ทีเดียวทั้งโปรเจกต์ ผลคือ package ขยับทีละหลายเวอร์ชัน พอมีอะไรพังก็ไล่ยากว่าพังเพราะตัวไหน

ใน repo ของเว็บนี้มี PR ชื่อ "Bump vite from 8.3.0 to 8.3.4" ที่เราไม่ได้เปิดเอง คนเปิดคือ Dependabot ใน PR แก้แค่ package.json กับ package-lock.json มี release notes ของ Vite แนบมาให้อ่าน และ CI รันเทสต์กับ lint ผ่านแล้ว สิ่งที่เหลือให้เราทำคืออ่านแล้วตัดสินใจว่าจะ merge ไหม

Dependabot คืออะไร

Dependabot เป็นบริการของ GitHub ที่ดูแล dependency ของโปรเจกต์ให้ ไม่ต้องติดตั้งอะไรลงเครื่อง ทำงานอยู่บน GitHub ทั้งหมด แบ่งเป็นสามส่วนที่เปิดแยกกันได้

ส่วน ทำอะไร เปิดจากไหน
Dependabot alerts แจ้งเตือนเมื่อ package ที่เราใช้มีช่องโหว่ที่ประกาศแล้ว Settings ของ repo
Dependabot security updates เปิด PR อัปเดต package ตัวนั้นไปเวอร์ชันที่แก้ช่องโหว่แล้ว Settings ของ repo
Dependabot version updates เปิด PR อัปเดต package ที่มีเวอร์ชันใหม่ ตามรอบที่ตั้งไว้ ไฟล์ .github/dependabot.yml

ส่วน alerts มีอยู่ในทุก plan ของ GitHub รวมถึง GitHub Free ตามหน้าเปรียบเทียบ plan ใช้กับ repo แบบ private ได้ด้วย อย่าง repo ของเว็บนี้ก็เป็น private

Dependabot อ่าน lock file แล้วเทียบกับฐานข้อมูลช่องโหว่

GitHub สร้าง dependency graph จากไฟล์ manifest กับ lock file ใน repo ของเรา สำหรับโปรเจกต์ Laravel ก็คือ composer.json กับ composer.lock ฝั่ง PHP และ package.json กับ package-lock.json ฝั่ง JavaScript ทุกครั้งที่เรา push แล้ว dependency เปลี่ยน หรือมีช่องโหว่ใหม่เข้ามาใน GitHub Advisory Database Dependabot จะเทียบสองอย่างนี้กันใหม่

ถ้าเจอว่าเราใช้เวอร์ชันที่มีช่องโหว่ หน้า Security ของ repo จะขึ้น alert ที่บอกว่า

  • ช่องโหว่อะไร ร้ายแรงแค่ไหน พร้อมระดับ Low ถึง Critical ที่คิดจากคะแนน CVSS (อ่านวิธีดูคะแนนได้ในคะแนน CVSS คืออะไร)
  • เราใช้ package นี้ตรง ๆ หรือมันติดมากับตัวอื่น (direct หรือ transitive)
  • package อยู่ใน runtime หรือ development อย่าง Vite อยู่ใน devDependencies ใช้แค่ตอนพัฒนาและตอน build
  • เวอร์ชันไหนแก้แล้ว

ถ้าเปิด security updates ไว้ Dependabot จะเปิด PR อัปเดต package ตัวนั้นไปเวอร์ชันที่แก้ช่องโหว่แล้วให้เลย โดยไม่ต้องรอรอบเวลา PR ที่ผูกกับ alert แบบนี้ GitHub จำกัดไว้ที่ครั้งละ 10 PR และเมื่อเรา merge แล้ว alert ก็ปิดเอง

version updates ทำงานคนละแบบ Dependabot จะดูตามรอบที่เราตั้ง เช่น ทุกสัปดาห์ ว่ามี package ไหนออกเวอร์ชันใหม่ แล้วเปิด PR ให้ทีละตัว หรือรวมเป็นกลุ่มก็ได้ ค่าเริ่มต้นคือเปิดค้างไว้ไม่เกิน 5 PR และจะรอให้เวอร์ชันใหม่ออกมาครบ 3 วันก่อน เผื่อมีแพตช์แก้ตามมา ช่วงรอนี้ไม่ใช้กับ security updates

PR ทั้งสองแบบมี release notes, changelog และรายการ commit ของ package แนบมาด้วย ถ้า branch หลักขยับไปจน PR เกิด conflict Dependabot จะrebase ให้เอง ไปจนครบ 30 วัน หลังจากนั้นต้อง rebase เอง

เปิด Dependabot ใน repo ของเรา

alerts กับ security updates เปิดได้จากหน้าเว็บ ไม่ต้องเขียนไฟล์

  1. เข้า repo บน GitHub แล้วไปที่ Settings
  2. เลือกเมนู Advanced Security
  3. กด Enable ที่ Dependency graph, Dependabot alerts และ Dependabot security updates

ส่วน version updates ต้องเพิ่มไฟล์ .github/dependabot.yml ใน branch หลัก จะกด Enable ที่ Dependabot version updates ในหน้าเดียวกันให้ GitHub สร้างไฟล์ตั้งต้นให้ก็ได้ หรือเขียนเองแล้ว commit ขึ้นไปเลย

สำหรับโปรเจกต์ Laravel ทั่วไปที่มีทั้ง Composer, npm และ GitHub Actions ไฟล์ตั้งต้นหน้าตาแบบนี้

version: 2
updates:
  - package-ecosystem: composer
    directory: /
    schedule:
      interval: weekly
    groups:
      composer-minor-patch:
        patterns: ['*']
        update-types: [minor, patch]

  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    groups:
      npm-minor-patch:
        patterns: ['*']
        update-types: [minor, patch]

  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: monthly
  • package-ecosystem บอกว่าให้ดู package แบบไหน ใช้ composer, npm และ github-actions สำหรับ action ใน workflow
  • directory คือโฟลเดอร์ที่มี composer.json หรือ package.json โปรเจกต์ Laravel อยู่ที่ราก repo จึงเป็น / ส่วน GitHub Actions ใช้ / เสมอ
  • schedule.interval เลือกได้ตั้งแต่ daily, weekly, monthly ไปจนถึง yearly
  • groups รวมการอัปเดต minor กับ patch ไว้ใน PR เดียว ส่วน major ที่อาจมี breaking change ยังแยกเป็น PR ของตัวเอง จะได้อ่าน upgrade guide ทีละตัว

ตัวเลือกทั้งหมดอยู่ในเอกสาร dependabot.yml ถ้าโปรเจกต์ดึง package จาก private registry เช่น Laravel Nova ต้องตั้ง registries ให้ Dependabot เข้าถึงด้วย ไม่อย่างนั้น Dependabot จะ resolve dependency ไม่ผ่าน

เว็บนี้ปิด PR อัปเดตเวอร์ชันไว้ เพราะ merge ทุกครั้งคือ deploy

เว็บนี้ deploy ขึ้น production ทุกครั้งที่มี commit เข้า main ถ้าเปิด version updates รายสัปดาห์ไว้ ก็จะมี PR อัปเดตเวอร์ชันเข้ามาทุกสัปดาห์ และกด merge ทีไรก็ deploy ทีนั้น เราอยากอัปเดต package เป็นรอบ ๆ ตอนที่นั่งอ่าน release notes และลองเปิดเว็บดูเองได้มากกว่า จึงตั้งไฟล์ไว้แบบนี้

version: 2
updates:
  - package-ecosystem: composer
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 0

  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 0

  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: monthly
    open-pull-requests-limit: 2
    groups:
      actions:
        patterns: ['*']
  • open-pull-requests-limit: 0 ปิด version updates ของ Composer กับ npm แต่ security updates ยังเข้ามาตามปกติ เพราะ GitHub นับ PR สองแบบนี้แยกกัน
  • GitHub Actions อัปเดตเดือนละครั้ง รวมทุก action ไว้ใน PR เดียว เช่น actions/checkout กับ actions/setup-node ขยับเวอร์ชันพร้อมกัน
  • alerts กับ security updates เปิดไว้ในหน้า Settings

ผลคือ PR จาก Dependabot ที่เข้ามาเกือบทั้งหมดเป็นเรื่องช่องโหว่ อย่าง PR ของ Vite ข้างบน ส่วนการอัปเดตเวอร์ชันทั่วไปเราทำเองเป็นรอบ ถ้าวันหนึ่งอยากให้ Dependabot เปิด PR รายสัปดาห์ให้ ก็แค่เปลี่ยนเลข 0 เป็นจำนวน PR ที่อยากให้เปิดค้างไว้

สิ่งที่ดูก่อนกด merge PR ของ Dependabot

PR ของ Dependabot จะคุ้มค่าก็ต่อเมื่อมีเทสต์คอยจับ ถ้า repo มี CI ที่รันตอนเปิด PR อยู่แล้ว PR พวกนี้ก็จะรันเทสต์ให้ทันที ใน repo นี้ PR ของ Vite ผ่านทั้ง test และ lint ส่วนขั้น deploy ข้ามไปเพราะยังไม่ได้ merge เข้า main ถ้ายังไม่มี CI ก็ดึง branch ของ PR ลงมารันเทสต์ในเครื่องก่อนได้

ก่อน merge ลองดูทีละข้อแบบนี้

  • CI ผ่านไหม ถ้าไม่ผ่าน ให้เปิด log ดูก่อนว่าพังเพราะ package จริง หรือพังเพราะ workflow ต้องใช้ secret
  • อ่าน release notes โดยเฉพาะ PR ที่ขยับ major version
  • ดูว่าช่องโหว่กระทบ production ไหม ช่องโหว่ใน Vite ที่ทำให้มี PR นี้อยู่ใน dev server ซึ่งเปิดเฉพาะตอน npm run dev บนเครื่องเรา ส่วน production เสิร์ฟไฟล์ที่ build แล้ว จึงไม่รีบเท่าช่องโหว่ใน package ที่รันอยู่บน production แต่ก็ควร merge เพราะเครื่องที่ใช้พัฒนาก็เสี่ยงได้

ถ้าอยากสั่ง Dependabot เพิ่ม ให้พิมพ์ comment ใน PR ได้เลย คำสั่งที่ใช้บ่อย มีดังนี้

  • @dependabot rebase ให้ rebase PR กับ branch หลักใหม่
  • @dependabot recreate สร้าง PR ใหม่ทั้งอัน ทับสิ่งที่เราแก้ไว้ใน PR
  • @dependabot ignore this major version ปิด PR นี้ และไม่ต้องเปิด PR ของ major version นี้อีก จนกว่าเราจะอัปเดตเอง
  • @dependabot ignore this dependency ปิด PR และเลิกอัปเดต package ตัวนี้

คำสั่ง ignore จะเก็บไว้ในฝั่ง GitHub ไม่ได้อยู่ในไฟล์ ถ้าทำงานกันหลายคน ให้เขียน ignore ลงใน dependabot.yml แทน คนอื่นจะได้เห็นว่าข้าม package ไหนไว้

ถ้าโค้ดไม่ได้อยู่บน GitHub

Dependabot ทำงานกับ repo บน GitHub เท่านั้น ถ้าโปรเจกต์อยู่บน GitLab, Bitbucket หรือยังไม่ได้ใช้ Git เลย ก็ยังเช็คช่องโหว่ได้จากเครื่องเราเอง

composer audit
npm audit

composer audit เทียบ package ใน composer.lock กับฐานข้อมูล advisory แล้วบอกว่าตัวไหนมีช่องโหว่ npm audit ทำแบบเดียวกันกับ package-lock.json ใส่สองคำสั่งนี้ไว้ในขั้นตอน deploy หรือรันก่อนขึ้นงานใหม่ทุกครั้งก็ช่วยได้มาก

ถ้าอยากได้ PR อัปเดตอัตโนมัติแบบ Dependabot บนที่อื่น ลองดู Renovate ซึ่งเป็น open source รองรับทั้ง GitHub, GitLab และ Bitbucket และรันบนเซิร์ฟเวอร์ของเราเองได้

อ่านต่อ

ถูกอ้างถึงใน

ล่าสุด

ดูทั้งหมด →