Testing

การทดสอบ: การอัปเดตและ Plugin

รายการตรวจสอบสำหรับการตรวจสอบความถูกต้องของการอัปเดตและ Plugin: พิสูจน์ว่าแพ็กเกจที่ติดตั้งได้สามารถ อัปเดตสถานะผู้ใช้จริง ซ่อมแซมสถานะเดิมที่ล้าสมัยผ่าน doctor และยังคง ติดตั้ง โหลด อัปเดต และถอนการติดตั้ง Plugin จากทุกแหล่งที่รองรับได้

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

สิ่งที่เราปกป้อง

  • ไฟล์ tarball ของแพ็กเกจต้องสมบูรณ์ มี dist/postinstall-inventory.json ที่ถูกต้อง และไม่ขึ้นต่อไฟล์ใน repo ที่ไม่ได้แพ็ก
  • ผู้ใช้สามารถย้ายจากแพ็กเกจที่เผยแพร่ก่อนหน้าไปยังแพ็กเกจตัวเลือก โดยไม่สูญเสียการกำหนดค่า เอเจนต์ เซสชัน พื้นที่ทำงาน รายการอนุญาตของ Plugin หรือ การกำหนดค่าช่องทาง
  • openclaw doctor --fix --non-interactive เป็นผู้รับผิดชอบเส้นทางการล้างและซ่อมแซม สถานะเดิม การเริ่มทำงานไม่ควรเพิ่มการย้ายข้อมูลเพื่อความเข้ากันได้แบบซ่อนสำหรับสถานะ Plugin ที่ล้าสมัย
  • การติดตั้ง Plugin ต้องทำงานได้จากไดเรกทอรีภายในเครื่อง, repo ของ git, แพ็กเกจ npm และ เส้นทางรีจิสทรี ClawHub
  • การขึ้นต่อกันของ npm สำหรับ Plugin ต้องติดตั้งในโปรเจกต์ npm ที่มีการจัดการหนึ่งโปรเจกต์ต่อ Plugin ได้รับการสแกนก่อนให้ความเชื่อถือ และถูกนำออกผ่าน npm uninstall ระหว่าง การถอนการติดตั้ง Plugin เพื่อไม่ให้การขึ้นต่อกันที่ถูก hoist ตกค้าง
  • การอัปเดต Plugin ต้องไม่ดำเนินการใดเมื่อไม่มีสิ่งเปลี่ยนแปลง: ระเบียนการติดตั้ง แหล่งที่มา ที่แก้ค่าแล้ว เค้าโครงการขึ้นต่อกันที่ติดตั้ง และสถานะการเปิดใช้งานต้องคงเดิม

การพิสูจน์ภายในเครื่องระหว่างการพัฒนา

เริ่มจากขอบเขตแคบ:

bash
pnpm changed:lanes --jsonpnpm check:changedpnpm test:changed

สำหรับการเปลี่ยนแปลงด้านการติดตั้ง การถอนการติดตั้ง การขึ้นต่อกัน หรือรายการแพ็กเกจของ Plugin ให้ รันการทดสอบเฉพาะจุดที่ครอบคลุมรอยต่อที่แก้ไขด้วย:

bash
pnpm test src/plugins/uninstall.test.ts src/infra/package-dist-inventory.test.ts test/scripts/package-acceptance-workflow.test.ts

ก่อนที่เลน Docker ของแพ็กเกจใดจะใช้ tarball ให้พิสูจน์อาร์ติแฟกต์แพ็กเกจก่อน:

bash
pnpm release:check

release:check รันการตรวจสอบความคลาดเคลื่อนของการกำหนดค่า/เอกสาร/API (สคีมาการกำหนดค่า เอกสารการกำหนดค่า ค่าฐาน สัญญา API ของ SDK สำหรับ Plugin ตลอดจนแมนิเฟสต์และการส่งออก เวอร์ชัน/รายการ Plugin) เขียนรายการ dist ของแพ็กเกจ รัน npm pack --dry-run ปฏิเสธ ไฟล์ที่ห้ามแพ็ก ติดตั้ง tarball ลงในคำนำหน้าชั่วคราว รัน postinstall และ ทดสอบเบื้องต้นกับจุดเข้าของช่องทางที่รวมมาในแพ็กเกจ

เลน Docker

เลน Docker คือการพิสูจน์ระดับผลิตภัณฑ์ โดยติดตั้งหรืออัปเดต แพ็กเกจจริงภายในคอนเทนเนอร์ Linux และยืนยันพฤติกรรมผ่านคำสั่ง CLI การเริ่มทำงานของ Gateway โพรบ HTTP สถานะ RPC และสถานะระบบไฟล์

ใช้เลนเฉพาะจุดระหว่างการปรับแก้:

bash
pnpm test:docker:pluginspnpm test:docker:plugin-lifecycle-matrixpnpm test:docker:plugin-updatepnpm test:docker:upgrade-survivorpnpm test:docker:published-upgrade-survivorpnpm test:docker:update-restart-authpnpm test:docker:update-migration

เลนสำคัญ:

  • test:docker:plugins ครอบคลุมการทดสอบเบื้องต้นของการติดตั้ง Plugin การติดตั้งจากโฟลเดอร์ภายในเครื่อง พฤติกรรมข้ามการอัปเดตโฟลเดอร์ภายในเครื่อง โฟลเดอร์ภายในเครื่องที่มี การขึ้นต่อกันติดตั้งไว้ล่วงหน้า การติดตั้งแพ็กเกจ file: การติดตั้งจาก git พร้อมการเรียกใช้ CLI การอัปเดต ref ของ git ที่เคลื่อนที่ได้ การติดตั้งจากรีจิสทรี npm ที่มีการขึ้นต่อกันทางอ้อมแบบ hoist การไม่ดำเนินการเมื่ออัปเดต npm การปฏิเสธข้อมูลเมตาแพ็กเกจ npm ที่ผิดรูปแบบ การติดตั้งจาก fixture ของ ClawHub ภายในเครื่องและการไม่ดำเนินการเมื่ออัปเดต พฤติกรรมการอัปเดตมาร์เก็ตเพลส และการเปิดใช้งาน/ตรวจสอบบันเดิล Claude ตั้งค่า OPENCLAW_PLUGINS_E2E_CLAWHUB=0 เพื่อ คงบล็อก ClawHub ให้แยกขาด/ออฟไลน์
  • test:docker:plugin-lifecycle-matrix ติดตั้งแพ็กเกจตัวเลือกในคอนเทนเนอร์เปล่า รัน Plugin npm ผ่านการติดตั้ง ตรวจสอบ ปิดใช้งาน เปิดใช้งาน อัปเกรดโดยชัดแจ้ง ดาวน์เกรดโดยชัดแจ้ง และถอนการติดตั้งหลังลบโค้ด Plugin โดยบันทึกเมตริก RSS และ CPU ในแต่ละระยะ
  • test:docker:plugin-update ตรวจสอบว่า Plugin ที่ติดตั้งและไม่มีการเปลี่ยนแปลง จะไม่ถูกติดตั้งซ้ำหรือสูญเสียข้อมูลเมตาการติดตั้งระหว่าง openclaw plugins update
  • test:docker:upgrade-survivor ติดตั้ง tarball ตัวเลือกทับ fixture ผู้ใช้เก่าที่มีสถานะไม่สะอาด รันการอัปเดตแพ็กเกจพร้อม doctor แบบไม่โต้ตอบ จากนั้นเริ่ม Gateway แบบลูปแบ็กและตรวจสอบการรักษาสถานะ
  • test:docker:published-upgrade-survivor ติดตั้งค่าฐานที่เผยแพร่ก่อน กำหนดค่าผ่านสูตร openclaw config set ที่ฝังไว้ อัปเดตเป็น tarball ตัวเลือก รัน doctor ตรวจสอบการล้างสถานะเดิม เริ่ม Gateway และ โพรบ /healthz, /readyz และสถานะ RPC
  • test:docker:update-restart-auth ติดตั้งแพ็กเกจตัวเลือก เริ่ม Gateway ที่มีการจัดการและใช้การตรวจสอบสิทธิ์ด้วยโทเค็น ยกเลิกการตั้งค่าตัวแปรสภาพแวดล้อมการตรวจสอบสิทธิ์ Gateway ของผู้เรียกสำหรับ openclaw update --yes --json และกำหนดให้คำสั่งอัปเดตตัวเลือก รีสตาร์ต Gateway ก่อนโพรบตามปกติ
  • test:docker:update-migration คือเลนการอัปเดตแพ็กเกจที่เผยแพร่ซึ่งเน้นการล้างข้อมูล โดยเริ่มจากสถานะผู้ใช้ที่กำหนดค่าในรูปแบบ Discord/Telegram รัน doctor ของค่าฐานเพื่อให้การขึ้นต่อกันของ Plugin ที่กำหนดค่ามีโอกาสถูกสร้างขึ้น เติม เศษตกค้างจากการขึ้นต่อกันของ Plugin แบบเดิมสำหรับ Plugin ที่กำหนดค่าและบรรจุในแพ็กเกจ อัปเดตเป็น tarball ตัวเลือก และกำหนดให้ doctor หลังการอัปเดตนำรากการขึ้นต่อกันแบบเดิมออก

รูปแบบการทดสอบการอัปเกรดแพ็กเกจที่เผยแพร่ที่เป็นประโยชน์:

bash
OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC=openclaw@2026.4.23 \OPENCLAW_UPGRADE_SURVIVOR_SCENARIO=versioned-runtime-deps \pnpm test:docker:published-upgrade-survivor OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC=openclaw@latest \OPENCLAW_UPGRADE_SURVIVOR_SCENARIO=bootstrap-persona \pnpm test:docker:published-upgrade-survivor

สถานการณ์ที่ใช้ได้: base, acpx-openclaw-tools-bridge, feishu-channel, bootstrap-persona, channel-post-core-restore, plugin-deps-cleanup, configured-plugin-installs, stale-source-plugin-shadow, tilde-log-path, และ versioned-runtime-deps ในการรันแบบรวม OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues (นามแฝง far-reaching) จะขยายเป็นทุกสถานการณ์ รวมถึง การย้ายข้อมูลการติดตั้ง Plugin ที่กำหนดค่า

การย้ายข้อมูลการอัปเดตแบบเต็มแยกจาก CI สำหรับรีลีสแบบเต็มโดยตั้งใจ ใช้ เวิร์กโฟลว์ Update Migration แบบเรียกเองเมื่อคำถามเกี่ยวกับรีลีสคือ "รีลีสเสถียร ที่เผยแพร่ทั้งหมดตั้งแต่ 2026.4.23 เป็นต้นมาสามารถอัปเดตเป็นตัวเลือกนี้และ ล้างเศษตกค้างจากการขึ้นต่อกันของ Plugin ได้หรือไม่":

bash
gh workflow run update-migration.yml \  --ref main \  -f workflow_ref=main \  -f package_ref=main \  -f baselines=all-since-2026.4.23 \  -f scenarios=plugin-deps-cleanup

การยอมรับแพ็กเกจ

การยอมรับแพ็กเกจคือเกตแพ็กเกจที่ทำงานบน GitHub โดยจะแก้ค่าหนึ่งแพ็กเกจ ตัวเลือกเป็น tarball package-under-test บันทึกเวอร์ชันและ SHA-256 จากนั้น รันเลน Docker E2E ที่นำกลับมาใช้ใหม่ได้กับ tarball ที่ตรงกันนั้น ref ของชุดควบคุมเวิร์กโฟลว์ แยกจาก ref แหล่งที่มาของแพ็กเกจ เพื่อให้ตรรกะการทดสอบปัจจุบันสามารถตรวจสอบ รีลีสเก่าที่เชื่อถือได้

แหล่งที่มาของตัวเลือก:

  • source=npm: ตรวจสอบ openclaw@extended-stable, openclaw@beta, openclaw@latest หรือเวอร์ชันที่เผยแพร่แบบเจาะจง
  • source=ref: แพ็ก branch, tag หรือ commit ที่เชื่อถือได้ด้วยชุดควบคุมปัจจุบัน ที่เลือก
  • source=url: ตรวจสอบ tarball HTTPS สาธารณะพร้อม package_sha256 ที่จำเป็น เส้นทางนี้ปฏิเสธข้อมูลรับรองใน URL พอร์ต HTTPS ที่ไม่ใช่ค่าเริ่มต้น ชื่อโฮสต์หรือผลลัพธ์ DNS/IP ภายในหรือส่วนตัว พื้นที่ IP สำหรับวัตถุประสงค์พิเศษ และการเปลี่ยนเส้นทางที่ไม่ปลอดภัย
  • source=trusted-url: ตรวจสอบ tarball HTTPS พร้อม package_sha256 และ trusted_source_id ที่จำเป็นตามนโยบายที่ผู้ดูแลเป็นเจ้าของ ใน .github/package-trusted-sources.json ใช้สิ่งนี้สำหรับมิเรอร์ขององค์กร/ส่วนตัว แทนการลดความเข้มงวดของ source=url ด้วยสวิตช์อนุญาตส่วนตัวระดับอินพุต การตรวจสอบสิทธิ์แบบ Bearer เมื่อกำหนดค่าตามนโยบาย จะใช้ข้อมูลลับ OPENCLAW_TRUSTED_PACKAGE_TOKEN แบบคงที่
  • source=artifact: นำ tarball ที่อัปโหลดโดยการรัน Actions อื่นมาใช้ซ้ำ

การตรวจสอบความถูกต้องของรีลีสแบบเต็มใช้ source=artifact โดยค่าเริ่มต้น ซึ่งสร้างจาก SHA ของรีลีสที่แก้ค่าแล้ว สำหรับการพิสูจน์หลังเผยแพร่ ให้ส่ง package_acceptance_package_spec=openclaw@YYYY.M.PATCH เพื่อให้เมทริกซ์การอัปเกรดเดียวกัน มุ่งเป้าไปยังแพ็กเกจ npm ที่เผยแพร่แล้วแทน

การตรวจสอบรีลีสเรียกการยอมรับแพ็กเกจด้วยชุดแพ็กเกจ/อัปเดต/รีสตาร์ต/Plugin:

text
doctor-switch update-channel-switch skill-install update-corrupt-plugin upgrade-survivor published-upgrade-survivor root-managed-vps-upgrade update-restart-auth plugins-offline plugin-update plugin-binding-command-escape

เมื่อเปิดใช้การเฝ้าดูรีลีส (บังคับเปิดสำหรับ release_profile=stable และ full) ระบบจะส่งค่าต่อไปนี้ด้วย:

text
published_upgrade_survivor_baselines=last-stable-4 2026.4.23 2026.5.2 2026.4.15published_upgrade_survivor_scenarios=reported-issuestelegram_mode=mock-openai

สิ่งนี้ทำให้การย้ายข้อมูลแพ็กเกจ การสลับช่องทางอัปเดต ความทนทานต่อ Plugin ที่มีการจัดการ แต่เสียหาย การล้างการขึ้นต่อกันของ Plugin ที่ล้าสมัย ความครอบคลุม Plugin แบบออฟไลน์ พฤติกรรมการอัปเดต Plugin และ QA แพ็กเกจ Telegram ใช้อาร์ติแฟกต์ที่แก้ค่าแล้วเดียวกัน โดยไม่ทำให้เกตแพ็กเกจรีลีสเริ่มต้นต้องไล่ตรวจทุกรีลีสที่เผยแพร่

last-stable-4 แก้ค่าเป็นรีลีส OpenClaw เสถียรล่าสุดสี่รายการ ที่เผยแพร่บน npm การยอมรับแพ็กเกจรีลีสตรึง 2026.4.23 เป็นขอบเขตความเข้ากันได้ ของการอัปเดต Plugin แรก 2026.5.2 เป็นขอบเขตการเปลี่ยนแปลงครั้งใหญ่ของสถาปัตยกรรม Plugin และ 2026.4.15 เป็นค่าฐานการอัปเดตแพ็กเกจที่เผยแพร่ในช่วงเก่ากว่าของ 2026.4.1x โดยตัวแก้ค่า จะตัดค่าตรึงที่มีอยู่แล้วในสี่รายการล่าสุดออก สำหรับความครอบคลุมการย้ายข้อมูล การอัปเดตแพ็กเกจที่เผยแพร่อย่างครบถ้วน ให้ใช้ all-since-2026.4.23 ในเวิร์กโฟลว์การย้ายข้อมูล การอัปเดตแยกต่างหากแทน CI สำหรับรีลีสแบบเต็ม release-history ยังคง พร้อมใช้งานสำหรับการสุ่มตัวอย่างด้วยตนเองที่กว้างขึ้น เมื่อจำเป็นต้องมีจุดยึดเดิมก่อนวันที่กำหนดด้วย

เมื่อเลือกค่าฐานของการทดสอบการอัปเกรดแพ็กเกจที่เผยแพร่หลายค่า เวิร์กโฟลว์ Docker ที่นำกลับมาใช้ใหม่ได้จะแบ่งแต่ละค่าฐานเป็นงานตัวรันเฉพาะของตนเอง แต่ละ ชาร์ดค่าฐานยังคงรันชุดสถานการณ์ที่เลือก แต่บันทึกและอาร์ติแฟกต์จะ แยกตามค่าฐาน และเวลารวมถูกจำกัดด้วยชาร์ดที่ช้าที่สุดแทนงานแบบอนุกรมขนาดใหญ่หนึ่งงาน

รันโปรไฟล์แพ็กเกจด้วยตนเองเมื่อตรวจสอบตัวเลือกก่อนรีลีส:

bash
gh workflow run package-acceptance.yml \  --ref main \  -f workflow_ref=main \  -f source=npm \  -f package_spec=openclaw@beta \  -f suite_profile=package \  -f published_upgrade_survivor_baselines="last-stable-4 2026.4.23 2026.5.2 2026.4.15" \  -f published_upgrade_survivor_scenarios=reported-issues \  -f telegram_mode=mock-openai

สำหรับคานารี extended-stable ที่เผยแพร่แล้ว ให้ตั้งค่า package_spec=openclaw@extended-stable การยอมรับแพ็กเกจจะแก้ค่าตัวเลือกนั้น เป็น tarball ที่เจาะจงก่อนเลน Docker จะทำงาน

ใช้ suite_profile=product เมื่อคำถามเกี่ยวกับรีลีสรวมถึงช่องทาง MCP การล้าง cron/เอเจนต์ย่อย การค้นหาเว็บของ OpenAI หรือ OpenWebUI ใช้ suite_profile=full เฉพาะเมื่อต้องการความครอบคลุมเส้นทางรีลีส Docker แบบเต็ม

ค่าเริ่มต้นของรีลีส

สำหรับตัวเลือกรีลีส ชุดการพิสูจน์เริ่มต้นคือ:

  1. pnpm check:changed และ pnpm test:changed สำหรับการถดถอยระดับซอร์ส
  2. pnpm release:check สำหรับความสมบูรณ์ของอาร์ติแฟกต์แพ็กเกจ
  3. โปรไฟล์ package ของการยอมรับแพ็กเกจ หรือเลนแพ็กเกจกำหนดเอง สำหรับการตรวจสอบรีลีส เพื่อทดสอบสัญญาการติดตั้ง/อัปเดต/รีสตาร์ต/Plugin
  4. การตรวจสอบรีลีสข้ามระบบปฏิบัติการสำหรับตัวติดตั้ง การเริ่มต้นใช้งาน และพฤติกรรม เฉพาะแพลตฟอร์ม
  5. ชุดทดสอบแบบใช้งานจริงเฉพาะเมื่อพื้นผิวที่เปลี่ยนแปลงแตะพฤติกรรมของผู้ให้บริการหรือ บริการที่โฮสต์

บนเครื่องของผู้ดูแล เกตแบบกว้างและการพิสูจน์ผลิตภัณฑ์ Docker/แพ็กเกจควรรัน ใน Testbox เว้นแต่จะทำการพิสูจน์ภายในเครื่องโดยชัดแจ้ง

ความเข้ากันได้กับระบบเดิม

การผ่อนปรนด้านความเข้ากันได้มีขอบเขตแคบและจำกัดเวลา:

  • แพ็กเกจจนถึง 2026.4.25 รวมถึง 2026.4.25-beta.* อาจยอมรับ ช่องว่างของข้อมูลเมตาแพ็กเกจที่เผยแพร่ไปแล้วในการยอมรับแพ็กเกจ
  • แพ็กเกจ 2026.4.26 ที่เผยแพร่แล้วอาจแสดงคำเตือนสำหรับไฟล์ตราประทับ ข้อมูลเมตาบิลด์ภายในเครื่องที่เผยแพร่ไปแล้ว
  • แพ็กเกจหลังจากนั้นต้องเป็นไปตามสัญญาสมัยใหม่ ช่องว่างเดียวกันจะทำให้ล้มเหลว แทนการเตือนหรือข้าม

อย่าเพิ่มการย้ายข้อมูลเมื่อเริ่มทำงานใหม่สำหรับรูปแบบเก่าเหล่านี้ ให้เพิ่มหรือขยายการซ่อมแซมของ doctor จากนั้นพิสูจน์ด้วย upgrade-survivor, published-upgrade-survivor หรือ update-restart-auth เมื่อคำสั่งอัปเดตเป็นผู้รับผิดชอบการรีสตาร์ต

การเพิ่มความครอบคลุม

เมื่อเปลี่ยนลักษณะการทำงานของการอัปเดตหรือ Plugin ให้เพิ่มความครอบคลุมที่ชั้นต่ำสุดซึ่ง สามารถล้มเหลวด้วยเหตุผลที่ถูกต้อง:

  • ตรรกะพาธหรือเมทาดาทาแบบบริสุทธิ์: ทดสอบหน่วยไว้ข้างซอร์ส
  • รายการแพ็กเกจหรือลักษณะการทำงานของไฟล์ที่แพ็กแล้ว: package-dist-inventory หรือการทดสอบ ตัวตรวจสอบ tarball
  • ลักษณะการทำงานของการติดตั้ง/อัปเดตผ่าน CLI: การยืนยันในเลน Docker หรือฟิกซ์เจอร์
  • ลักษณะการทำงานของการย้ายข้อมูลรุ่นที่เผยแพร่แล้ว: สถานการณ์ published-upgrade-survivor
  • ลักษณะการทำงานของการรีสตาร์ตที่การอัปเดตเป็นเจ้าของ: update-restart-auth
  • ลักษณะการทำงานของรีจิสทรี/แหล่งแพ็กเกจ: ฟิกซ์เจอร์ test:docker:plugins หรือเซิร์ฟเวอร์ ฟิกซ์เจอร์ ClawHub
  • ลักษณะการทำงานของโครงสร้างหรือการล้างข้อมูลการขึ้นต่อกัน: ยืนยันทั้งการเรียกใช้ขณะรันไทม์และ ขอบเขตระบบไฟล์ การขึ้นต่อกันของ npm อาจถูกยกระดับภายในโปรเจกต์ npm ที่มีการจัดการของ Plugin ดังนั้นการทดสอบควรพิสูจน์ว่าโปรเจกต์นั้นได้รับการสแกน/ล้างข้อมูล แทนที่จะสมมติว่ามีเพียงโครงสร้าง node_modules ภายในแพ็กเกจของ Plugin

โดยค่าเริ่มต้น ให้ฟิกซ์เจอร์ Docker ใหม่แยกตัวอย่างสมบูรณ์ ใช้รีจิสทรีฟิกซ์เจอร์ภายในเครื่องและ แพ็กเกจจำลอง เว้นแต่วัตถุประสงค์ของการทดสอบคือลักษณะการทำงานของรีจิสทรีจริง

การคัดแยกความล้มเหลว

เริ่มจากข้อมูลระบุอาร์ติแฟกต์:

  • สรุป Package Acceptance resolve_package: แหล่งที่มา เวอร์ชัน SHA-256 และ ชื่ออาร์ติแฟกต์
  • อาร์ติแฟกต์ Docker: .artifacts/docker-tests/**/summary.json, failures.json, บันทึกของเลน และคำสั่งสำหรับรันซ้ำ
  • สรุปสิ่งที่คงอยู่หลังการอัปเกรด: .artifacts/upgrade-survivor/summary.json รวมถึงเวอร์ชันฐาน เวอร์ชันที่เป็นตัวเลือก สถานการณ์ ระยะเวลาของแต่ละเฟส และ ความครอบคลุมของสูตรการกำหนดค่า

ควรรันซ้ำเฉพาะเลนที่ล้มเหลวด้วยอาร์ติแฟกต์แพ็กเกจเดิม แทนการรันชุดการเผยแพร่ทั้งหมดซ้ำ

Was this useful?
On this page

On this page