Artifacts Archiving & Test Reporting
ส่งมอบผลผลิตอย่างมืออาชีพ: กู้คืนไฟล์ผลลัพธ์สำคัญด้วย archiveArtifacts ก่อนที่ Worker Workspace จะถูกล้างทิ้ง, การสืบค้นย้อนกลับด้วย fingerprint: true, และการสรุปผลการทดสอบด้วยรายงาน junit XML เพื่อปิดฉาก Phase 1 Foundation อย่างสมบูรณ์แบบ
"Never Destroy Workspace Without Archiving Delivery Assets."
เครื่อง Worker Agent เป็นเพียงแรงงานชั่วคราว (Ephemeral) ที่ต้องถูกสั่ง `cleanWs()` เสมอ หากไม่สั่ง `archiveArtifacts` ไฟล์ Binary ที่คอมไพล์มาจะสูญสลายไปพร้อมกับ Workspace และต้องเสียเวลาบิลด์ใหม่ทั้งหมด
ข้อสอบวันนี้มี 15 ข้อ ประกอบด้วยเนื้อหาใหม่ Day 5 จำนวน 9 ข้อ + ทบทวน Day 4 จำนวน 2 ข้อ + Day 3 จำนวน 2 ข้อ + Day 2 จำนวน 1 ข้อ + Day 1 จำนวน 1 ข้อ เพื่อการันตีความพร้อมก่อนขึ้น Phase 2
Introduced Topic & The Big Picture
Artifacts Archiving และ Test Reporting คืออะไรในระบบ Jenkins?
Artifacts Archiving คือ "การเอาผลผลิตที่ทำเสร็จแล้ว (เช่น ไฟล์ .jar, .zip, .apk) ออกจากโต๊ะช่าง แล้วนำไปเก็บเข้าตู้เซฟกลางบน Controller" ก่อนที่โต๊ะช่างจะถูกกวาดทิ้ง ส่วน Test Reporting คือ "ใบตรวจรับสินค้าอย่างเป็นทางการ" ที่สรุปให้ทุกคนในทีมและผู้บริหารเห็นว่า ในบิลด์นี้มีฟังก์ชันผ่านกี่ข้อ ล้มเหลวกี่ข้อ และรันเทสต์ใช้เวลานานกี่วินาที โดยไม่ต้องไปนั่งไล่อ่าน Console Log หมื่นบรรทัด
- บิลด์เสร็จแต่ไฟล์หาย: พอคำสั่ง `cleanWs()` ทำงาน ไฟล์ Binary ผลลัพธ์ที่ใช้เวลาคอมไพล์ 40 นาทีหายวับไปกับตา ต้องกดรันใหม่เสียเวลาและเปลืองพลังงาน
- ไล่หาข้อผิดพลาดใน Log ดิบ: เมื่อ Unit Test มีข้อผิดพลาด ต้องนั่งเลื่อน Console Output สีขาวดำ 50,000 บรรทัดเพื่อหาว่า Error อยู่ตรงไหน
- ไม่รู้ว่าไฟล์มาจาก Commit ไหน: เกิดเหตุการณ์จำไม่ได้ว่าไฟล์ที่ Deploy ขึ้นเซิร์ฟเวอร์มาจากโค้ดเวอร์ชันใด ไม่สามารถสืบค้นย้อนหลังได้ (No Traceability)
- มีปุ่ม Download บนหน้าเว็บ: ไฟล์ `.jar` หรือ `.zip` ถูกดึงมาฝากไว้บน Controller หน้าประวัติของบิลด์นั้น ใครจะนำไปใช้ต่อก็กดดาวน์โหลดได้ทันที
- มีกราฟผลการทดสอบสวยงาม: เห็นแถบสีเขียว-แดง แสดงจำนวน Pass/Fail/Skip พร้อมดูได้ทันทีว่า Test Case ใดพังโดยไม่ต้องเปิด Log
- สืบค้นย้อนกลับด้วย Fingerprint: Jenkins คำนวณค่า SHA-1 Hash ของไฟล์ ทำให้ตรวจสอบได้ตลอดเวลาว่าไฟล์นี้ถูกบิลด์โดย Job ไหน และใช้ Git Commit ใด
archiveArtifacts
คำสั่งคัดลอกไฟล์ Binary จากโฟลเดอร์ Workspace ของ Agent ส่งข้ามเครือข่ายมาเก็บรักษาไว้ใน JENKINS_HOME/jobs/.../builds/ บน Controller
Fingerprinting (SHA-1)
กลไกคำนวณ Checksum ของไฟล์ เพื่อสร้างประวัติบันทึกความเชื่อมโยงข้ามไปป์ไลน์ ตอบคำถามว่า "ไฟล์นี้บิลด์จากรอบไหน และถูกส่งต่อไปที่ใด"
junit XML Reporter
Step สำหรับอ่านไฟล์สรุปผลการทดสอบที่เป็นมาตรฐานสากล (เช่น `target/surefire-reports/*.xml`) แล้วสร้างหน้ารายงานผลทดสอบแบบ Interactive
Workspace vs Controller Storage
แยกหน้าที่ชัดเจน: Workspace บน Agent มีไว้รันงานชั่วคราวและลบได้ ส่วน Artifacts บน Controller มีไว้เก็บรักษาถาวรเพื่อการส่งมอบ
Everyday Mental Model & Intuition
หากต้องการเห็นภาพความแตกต่างระหว่าง Workspace, Artifacts, และ Test Reports ให้จินตนาการถึง **โรงงานประกอบเครื่องยนต์**:
ช่างยกเครื่องยนต์ส่งเข้าคลัง (archiveArtifacts)
เมื่อช่างประกอบเครื่องยนต์เสร็จบนโต๊ะทำงาน จะต้องยกเครื่องยนต์ใส่รถเข็นส่งเข้าคลังสินค้ากลางทันที เพราะพอหมดกะ ช่างทำความสะอาดจะฉีดน้ำล้างโต๊ะทำงานจนเกลี้ยง (cleanWs) ถ้าไม่ยกออก เครื่องยนต์จะพัง
ปั๊มตราเลขตัวถัง VIN (Fingerprinting)
ก่อนส่งเข้าคลัง เจ้าหน้าที่จะตอกหมายเลขประจำเครื่องยนต์ไว้ หากอีก 6 เดือนข้างหน้าเกิดอุบัติเหตุ ตำรวจสามารถเอาเลขตัวถังนี้มาเช็กได้ทันทีว่าใครเป็นคนประกอบ และใช้วัตถุดิบรหัสอะไร
ใบตรวจสภาพ 100 จุด (junit XML Report)
ทีม QC แนบเอกสารตรวจเช็กความปลอดภัยหน้ารถ: หัวฉีดผ่าน ✓ เบรกผ่าน ✓ หากจุดไหนไม่ผ่าน มีตราสีแดงประทับชัดเจน หัวหน้าฝ่ายผลิตเซ็นผ่านงานได้โดยไม่ต้องลงไปมุดดูใต้ท้องรถด้วยตัวเอง
Real-World Engineering Context & War Story
จุดเริ่มต้น: ทีมพัฒนาสร้างไปป์ไลน์ปล่อยแอปพลิเคชัน โดยในขั้นตอนสุดท้ายสั่งรันคำสั่ง Shell แบบบ้านๆ คือใช้ sh 'scp ./build/app.jar prod-server:/opt/app/' เพื่อยิงไฟล์ตรงจาก Worker Agent ขึ้น Production Server เลย โดยไม่ทำ archiveArtifacts ไว้ใน Jenkins
วันที่พังยับเยิน: ระหว่างที่คำสั่ง `scp` กำลังส่งไฟล์ขนาด 850MB เครือข่ายของ Agent สะดุดกะทันหัน ส่งไฟล์ไปได้เพียง 310MB แต่เนื่องจากในสคริปต์ไม่ได้เขียนเช็ก Exit Code สเต็ปนั้นจึงไม่แจ้งเตือน และกระโดดไปรันคำสั่งรีสตาร์ต Service บน Production ทันที
สิ่งที่เกิดขึ้น: แอปพลิเคชันบน Production พังทันทีเพราะไฟล์ JAR พิการ (Invalid or corrupt jarfile) เซิร์ฟเวอร์ไม่สามารถสตาร์ตได้ ระบบล่มทันทีในเวลาบ่าย 2 โมง และที่แย่กว่านั้นคือ ไม่มีใครรู้ว่าไฟล์ JAR เวอร์ชันเดิมก่อนหน้านี้อยู่ที่ไหน เพราะ Worker ตัวเก่าถูกคำสั่ง `cleanWs()` กวาดขยะทิ้งไปแล้ว และไม่ได้เก็บ Artifact สำรองไว้บน Controller เลย!
ห้ามยิงไฟล์ดิบจาก Workspace ขึ้น Production เด็ดขาด! กฎเหล็กคือ: 1. สั่ง archiveArtifacts artifacts: 'build/*.jar', fingerprint: true, onlyIfSuccessful: true เพื่อดึงไฟล์มาฝากบน Controller ให้ปลอดภัยก่อน -> 2. ให้ Stage Deploy ดึงไฟล์ที่ผ่านการตรวจสอบ Checksum ไปติดตั้งอย่างเป็นระบบ หากเกิดปัญหา สามารถกด Rollback เอาไฟล์ Artifact รอบก่อนหน้ามาใช้ได้ใน 10 วินาที
Hands-on Syntax Breakdown (ลงมือทำทีละก้าว 3 ระดับ)
การเก็บรักษาไฟล์ผลลัพธ์ด้วย archiveArtifacts
pipeline { agent any stages { stage('Build Package') { steps { // จำลองการคอมไพล์และสร้างไฟล์แพ็กเกจ sh 'mkdir -p dist && echo "v1.5.0-payload" > dist/app.jar' // คำสั่งสั่งเก็บไฟล์ผลลัพธ์ขึ้น Controller archiveArtifacts artifacts: 'dist/*.jar', allowEmptyArchive: false } } } }
คำอธิบาย: พารามิเตอร์ allowEmptyArchive: false คือ Best Practice ที่จะสั่งให้ไปป์ไลน์ติดสีแดงทันทีหากไม่พบไฟล์ที่ระบุ เพื่อป้องกันการเข้าใจผิดว่าบิลด์ผ่านทั้งที่ไม่มีไฟล์ผลลัพธ์ออกมา
การแสดงผลรายงานการทดสอบด้วย junit Directive
pipeline { agent any stages { stage('Unit & Regression Tests') { steps { sh './mvnw test' } } } post { always { // ต้องใส่ใน always เสมอ เพื่อให้อ่านผลรายงานแม้จะมีบาง Test Case ล้มเหลว junit testResults: '**/target/surefire-reports/*.xml', allowEmptyResults: false } } }
คำอธิบาย: คำสั่ง junit ต้องวางไว้ใน post { always } เสมอ เพราะหากวางไว้ใน steps ปกติ เมื่อมี Unit Test ข้อใดไม่ผ่าน สเตปจะหยุดชะงักทันที และรายงานจะไม่ถูกแปลงขึ้นหน้าเว็บ
ผสาน Artifacts + Fingerprint + JUnit + Safe Workspace Purge
pipeline { agent any stages { stage('Build & Test Suite') { steps { sh './build.sh' } } stage('Archive Release Deliverables') { steps { // เก็บเฉพาะเมื่อทุกสเตจสำเร็จ + บันทึก Fingerprint SHA-1 ตรวจสอบย้อนกลับ archiveArtifacts( artifacts: 'target/*.jar, config/*.yaml', fingerprint: true, onlyIfSuccessful: true ) } } } post { always { // 1. บันทึกผลทดสอบขึ้น Dashboard junit '**/test-results/**/*.xml' // 2. ล้าง Workspace บน Agent ให้สะอาดหมดจด 100% (Artifact ปลอดภัยบน Controller แล้ว) cleanWs() } } }
คำอธิบาย: นี่คือสถาปัตยกรรมที่ถูกต้องสมบูรณ์แบบของ Phase 1: ไฟล์ Binary ถูกดึงไปเก็บใน Controller Vault พร้อมปั๊มตรา Fingerprint เรียบร้อยแล้ว ก่อนที่เครื่อง Agent จะรันคำสั่ง cleanWs() ลบพื้นที่ทำงานทิ้งอย่างปลอดภัยไร้กังวล
Interactive Simulator: Artifact Vault & Workspace Purge Drill
จำลองสถานการณ์: พิสูจน์ความปลอดภัยของไฟล์เมื่อ Agent Workspace ถูก Purge ด้วย cleanWs()
ปรับตั้งค่าคำสั่ง archiveArtifacts, ตัวเลือก fingerprint, และผลการรัน Test ด้านล่าง จากนั้นคลิก "Simulate Build & Cleanup Cycle" เพื่อดูการย้ายไฟล์จาก Workspace สู่ Controller Storage
หากปิดใช้งาน สังเกตว่าไฟล์ Binary จะสูญหายทันทีเมื่อจบไปป์ไลน์
คำนวณ Checksum SHA-1 สำหรับสอบประวัติย้อนหลัง