Bài tập tuần 8 – CI/CD Fundamentals và GitHub Actions
Tóm tắt: Thiết kế pipeline Test, Build, Publish, Deploy cho Club API, chạy bản giả lập bằng shell script để chứng minh gate dừng đúng lúc, rồi viết workflow GitHub Actions thật chạy
npm civànpm testkhi push và pull request, có cache và matrix. Mọi kết quả phải kiểm chứng được qua source, log của script và log của run trên GitHub, không chỉ ảnh chụp màn hình.
Phạm vi: Buổi 15 – CI/CD Fundamentals và Buổi 16 – GitHub Actions Basics. Bài nộp nằm ở hai thư mục lab-15/ và lab-16/ trong repository cá nhân.
Bối cảnh
Từ tuần 9 nhóm capstone sẽ làm việc chung trên một repo. Khi 4 người cùng đẩy code, câu hỏi "bản này có chạy được không" không thể dựa vào máy của từng người. Mentor cần chắc rằng bạn biết thiết kế một pipeline có điều kiện dừng rõ ràng, và biết biến thiết kế đó thành workflow chạy được trên runner sạch của GitHub.
Bài tập tuần này có hai nửa. Nửa đầu (Buổi 15) là thiết kế và giả lập pipeline trên máy. Nửa sau (Buổi 16) là viết workflow thật cho backend của Club API và đọc log khi nó chạy xanh hoặc đỏ. Bạn chỉ cần dùng kiến thức của hai buổi này.
Quy ước làm việc:
- Làm trong terminal WSL2 Ubuntu, thư mục nằm trong filesystem của WSL (ví dụ
~/devops-labs), không dùng/mnt/c. - Source là backend của
starter-project/đã copy vào repo cá nhân (không copynode_modules). Không sửa mã backend, chỉ sửa test khi bài yêu cầu làm test đỏ và phải hoàn tác. - Ghi lệnh và output thật bằng
2>&1 | tee -a evidence/command-output.txt. Không sửa tay file evidence. - Pin phiên bản action (ví dụ
actions/checkout@v4,actions/setup-node@v4) và đặtpermissionstối thiểu. Không đưa token, mật khẩu hay file.envvào repo.
Nhiệm vụ L1 (bắt buộc)
Nhiệm vụ 1. Thiết kế và giả lập pipeline (lab-15)
Biến ý tưởng "Test, Build, Publish, Deploy" thành bản thiết kế cụ thể rồi chạy thử phần đầu của nó trên máy.
Yêu cầu:
- Vẽ sơ đồ pipeline có trigger, 4 stage nối tiếp và nhánh "dừng, báo lỗi". Mỗi stage ghi lệnh chính, output (artifact) và điều kiện qua. Lưu file nguồn (
.drawiohoặc.mmd) vàolab-15/source/và ảnh xuất ralab-15/screenshots/pipeline.png. - Viết
lab-15/source/pipeline-spec.mdcó bảng đủ 4 stage với các cột: lệnh chính, runner cần, input, output, điều kiện qua. Ghi thêm cách đặt tag image, secret nào cần (chỉ tên, không giá trị) và stage nào có thể chạy song song. - Viết
lab-15/source/run-pipeline.shdùngset -euo pipefail, chạy các stage test, build, kiểm tra artifact và in dòngPIPELINE OKở cuối. Chạy script và lưu log.
Tiêu chí hoàn thành:
-
pipeline-spec.mdcó đủ 4 stage, mỗi stage không để trống ô nào. -
evidence/command-output.txtcó đủ các dòng=== STAGE: test ===,=== STAGE: build ===,# fail 0vàPIPELINE OK. - Log cho thấy tên image kèm tag cụ thể (không chỉ
latest) lấy từdocker image inspect. - Mỗi mũi tên trong sơ đồ cho biết cái gì chảy qua nó (artifact hoặc kết quả).
Nhiệm vụ 2. Chứng minh gate dừng khi test fail (lab-15)
Một gate chưa được thử làm fail thì chưa được tin.
Yêu cầu:
- Sao lưu
tests/health.test.js, cố tình sửa một assertion cho đỏ, chạy lạirun-pipeline.shvà ghiexit codecủa script. - Hoàn tác file test từ bản sao lưu và chạy
npm testđể chứng minh đã xanh lại. - Giải thích trong
lab-15/report.mdbằng 2 đến 3 câu vì sao stage test phải đứng trước stage build.
Tiêu chí hoàn thành:
- Evidence có lần chạy đỏ: stage
testbáo# faillớn hơn 0, không có dòng=== STAGE: build ===sau đó vàexit codekhác 0. - Evidence có lần
npm testxanh sau khi hoàn tác (# fail 0). -
git diffcủa thư mụclab-15/source/starter-project/backend/teststrống tại thời điểm nộp (file test đã trả về nguyên trạng). -
report.mdnêu đúng nguyên tắc fail fast và nêu được thứ bị lãng phí nếu build trước test.
Nhiệm vụ 3. Workflow CI thật chạy test (lab-16)
Chuyển bản thiết kế thành workflow GitHub Actions cho backend.
Yêu cầu:
- Copy
starter-project/backendvàolab-16/source/(kèmpackage-lock.json), chạynpm civànpm testcục bộ, lưu log vào evidence. - Viết
.github/workflows/ci.ymlchạy khipush(nhánh chính của repo bạn) vàpull_request, cópermissions: contents: read, các step checkout, setup-node với Node 22,npm ci,npm testđều đặt đúngworking-directory. - Đẩy lên GitHub, đạt ít nhất một run xanh. Lưu log run: tải từ trang run (Download log archive) hoặc dùng
gh run viewnếu máy bạn đã cài GitHub CLI và đăng nhập. Chép phần log của stepRun testsvào evidence. - Chép
ci.ymlvàolab-16/source/ci.yml.copyvì file thật nằm ngoài thư mục lab.
Tiêu chí hoàn thành:
-
ci.ymlđúng cú pháp YAML (thụt lề 2 dấu cách), đủ 4 step, cópermissionsvà action được pin theo phiên bản. - Evidence có log local (
npm ci,npm testvới# fail 0) vàgit log --onelinechứa commit thêm workflow. -
report.mdcó link tới run xanh và đoạn log của stepRun testschứa# passvà# fail 0. -
report.mdgiải thích vì sao phải có step checkout và vì saoworking-directorylàlab-16/source.
Nhiệm vụ 4. Bật cache và tách job (lab-16)
Làm pipeline nhanh hơn và tách phần kiểm tra độc lập khỏi phần test.
Yêu cầu:
- Bật
cache: npmtrongactions/setup-node@v4kèmcache-dependency-pathtrỏ đúng tớilab-16/source/package-lock.json. - Chạy workflow hai lần (lần hai bằng Re-run all jobs hoặc một commit mới không đổi lock file) và so sánh log step Setup Node.js của hai lần.
- Thêm job thứ hai tên
validatekiểm trapackage.jsonđọc được bằng JSON, chạy song song với jobtest.
Tiêu chí hoàn thành:
- Log lần chạy đầu và lần chạy hai của step Setup Node.js đều có trong
report.md; lần hai có dòng cho thấy cache được khôi phục. - Trang run hiển thị ít nhất hai job
testvàvalidateđều xanh, không cóneedsgiữa hai job này. -
report.mdgiải thích bằng lời của bạn artifact khác cache ở điểm nào, kèm ví dụ của Club API. - Có ghi lại thời gian của step
npm ciở hai lần chạy (số giây thật, chênh lệch nhỏ vẫn chấp nhận).
Nhiệm vụ L2 (nâng cao / Advanced Challenge)
L2 tính điểm thưởng tối đa 10. Chỉ làm khi đã hoàn thành L1. Mentor chỉ nhận triệu chứng, bạn phải tự tìm nguyên nhân gốc.
Thử thách 1. Matrix, needs và job build-image
Mở rộng workflow để chạy trên nhiều phiên bản Node.js và chỉ build image khi mọi kiểm tra đã xanh.
Tiêu chí hoàn thành:
- Job
testdùngstrategy.matrixvới tối thiểu hai phiên bản Node.js đang được hỗ trợ và đặtfail-fast: false. - Có job
build-imagevớineedstrỏ tớitestvàvalidate; run xanh cho thấy đủ ba nhóm job vàbuild-imagechạy sau cùng. - Chứng minh
needshoạt động: ghi lại một run màtestđỏ làmbuild-imagebị bỏ qua (skipped), kèm link run và ảnh chụp. -
report.mdnêu số job do matrix tạo ra và vì saofail-fast: falsehữu ích khi học.
Thử thách 2. Pull request đỏ và Tình huống 06
Tạo nhánh feature/break-test, làm một test đỏ, mở pull request để thấy check đỏ, sau đó sửa. Xử lý Tình huống 06 – Workflow fail theo báo cáo 5 phần.
Tiêu chí hoàn thành:
- Có link PR cho thấy check đỏ ở bước chạy test, và run xanh sau khi sửa trên cùng PR.
-
report.mdcó mục báo cáo 5 phần của tình huống 06: triệu chứng, nguyên nhân gốc, cách xác minh, giải pháp, phòng tránh. - Phần xác minh trích đúng dòng log đầu tiên báo lỗi và nói rõ lỗi xảy ra trước hay trong lệnh
npm. - Có bằng chứng tái hiện trên bản clone sạch (lệnh
git clonevào thư mục mới và kết quảnpm cihoặcgit ls-files).
Thử thách 3. Môi trường và build một lần
Tiêu chí hoàn thành:
-
lab-15/source/environments.mdcó bảng 3 môi trường dev, staging, production với trigger deploy, gate (test nào, ai duyệt) và cách rollback. -
report.mdchọn Continuous Delivery hoặc Continuous Deployment cho production của Club API, có ít nhất 3 lý do dựa trên rủi ro và độ phủ test hiện có. -
run-pipeline.shđã sửa để image chỉ build một lần; evidence có đúng một lệnhdocker builddù pipeline "deploy" cho cả 3 môi trường (script phải in lệnh ra log, ví dụecho "+ docker build ...", rồi kiểm tra bằnggrep -c). - Đề xuất 2 gate bổ sung và nêu mỗi gate chặn loại lỗi nào.
Bằng chứng cần nộp
Cấu trúc theo templates/lab-template.md, tách làm hai thư mục:
lab-15/
├── README.md (7 câu theo template, ghi rõ đã làm L1 hay L2)
├── source/
│ ├── starter-project/ (bản sao, không có node_modules)
│ ├── pipeline.mmd (hoặc pipeline.drawio)
│ ├── pipeline-spec.md
│ ├── run-pipeline.sh
│ └── environments.md (chỉ khi làm L2 thử thách 3)
├── screenshots/
│ └── pipeline.png (chỉ minh họa)
├── evidence/
│ └── command-output.txt
└── report.md (câu hỏi kiểm tra, giải thích gate; phần L2 nếu có)
lab-16/
├── README.md
├── source/ (backend đã copy, package-lock.json, ci.yml.copy)
├── screenshots/ (run xanh; check đỏ trên PR nếu làm L2)
├── evidence/
│ └── command-output.txt
└── report.md (link run, log, nguyên nhân gốc, 5 câu trả lời)Evidence cụ thể theo nhiệm vụ:
| Nhiệm vụ | Evidence bắt buộc |
|---|---|
| 1 | pipeline-spec.md, sơ đồ (nguồn và ảnh), log run-pipeline.sh thành công trong lab-15/evidence/command-output.txt |
| 2 | Log lần chạy đỏ kèm exit code, log npm test sau khi hoàn tác, đoạn giải thích trong report.md |
| 3 | .github/workflows/ci.yml và source/ci.yml.copy, log local, git log --oneline, link và đoạn log run xanh trong lab-16/report.md |
| 4 | Log Setup Node.js của hai lần chạy, ảnh hoặc mô tả hai job song song, thời gian npm ci |
| L2 | Output hoặc link mà từng tiêu chí L2 yêu cầu |
Mentor kiểm chứng bằng cách đọc workflow trong repo, mở link run và đối chiếu với log bạn dán, chạy lại run-pipeline.sh trên máy mentor và đọc lịch sử commit. Link run không truy cập được hoặc log không khớp với workflow trong repo sẽ bị hỏi lại trực tiếp. Ảnh chụp màn hình chỉ để minh họa, không thay thế log.
Barem chấm
Tổng 100 điểm, cộng tối đa 10 điểm thưởng từ L2 (trần cuối cùng 110).
| Tiêu chí | Đạt | Không đạt | Điểm |
|---|---|---|---|
| Nhiệm vụ 1: thiết kế và giả lập pipeline | Sơ đồ và spec đủ 4 stage, script chạy được, log có PIPELINE OK và tag cụ thể | Thiếu stage, thiếu output hoặc điều kiện qua, không có log | 15 |
| Nhiệm vụ 2: gate dừng khi fail | Log đỏ không có stage build, exit code khác 0, test đã hoàn tác và xanh lại | Chỉ mô tả bằng lời, hoặc để lại test hỏng | 15 |
| Nhiệm vụ 3: workflow CI | ci.yml đúng, có permissions, pin action, run xanh có link và log | Workflow không chạy, thiếu checkout hoặc working-directory, không có link run | 20 |
| Nhiệm vụ 4: cache và tách job | Có log cache hai lần, hai job song song xanh, giải thích artifact và cache | Cache không hoạt động mà không giải thích, hoặc validate phụ thuộc job khác | 15 |
Chất lượng README.md và report.md | 7 câu theo template, ngắn gọn, đúng, nêu nguyên nhân gốc khi có lỗi | Sao chép đề bài, trả lời chung chung | 10 |
| Câu hỏi kiểm tra kiến thức | 5 câu trả lời đúng ý và dẫn chứng bằng lệnh hoặc đoạn YAML khi cần (3 điểm mỗi câu) | Sai hoặc bỏ trống | 15 |
| Vệ sinh và quy trình | Không có secret hay .env, không commit node_modules, PR đúng quy trình, có reviewer | Có secret, thiếu package-lock.json hoặc thiếu review | 10 |
| L2 thử thách 1 (thưởng) | Matrix, needs, có run chứng minh job bị skipped | Có YAML nhưng không có run chứng minh | 4 |
| L2 thử thách 2 (thưởng) | PR đỏ rồi xanh, báo cáo 5 phần, tái hiện bằng clone sạch | Chỉ nêu kết luận, không trích log | 3 |
| L2 thử thách 3 (thưởng) | Bảng môi trường hợp lý, chỉ một lệnh docker build, 2 gate có lý do | Lý do chung chung, log có nhiều hơn một docker build | 3 |
Câu hỏi kiểm tra kiến thức
Trả lời ngắn (2 đến 4 câu mỗi câu, kèm lệnh hoặc đoạn YAML nếu cần) trong lab-16/report.md.
- Continuous Integration, Continuous Delivery và Continuous Deployment khác nhau ở điểm nào? Với Club API hiện chỉ có test cho
/health, bạn chọn mô hình nào cho production và vì sao? - Workflow, job, step và runner khác nhau thế nào? Vì sao hai job trong cùng một workflow không dùng chung được thư mục file với nhau và bạn chuyển dữ liệu giữa chúng bằng cách nào?
- Vì sao CI dùng
npm cithay chonpm install? Điều gì xảy ra nếu bạn quên commitpackage-lock.json? - Cache của
actions/setup-nodelấy gì làm key? Khi bạn thêm một dependency mới thì lần chạy kế tiếp xảy ra điều gì? Cache khác artifact ở điểm nào? - Check CI trên PR đỏ ở step
npm cinhưng local chạy tốt. Nêu ba việc bạn kiểm tra tiếp theo theo thứ tự và mỗi việc cho bạn biết điều gì.
Lỗi hay bị trừ điểm
- Nộp ảnh chụp màn hình thay cho log, hoặc link run mà không dán đoạn log liên quan.
- Làm trong
/mnt/c, hoặc chạynpm testtrên Windows rồi ghi là WSL. - Dùng
npm installtrong workflow thay chonpm ci, hoặc thêmpackage-lock.jsonvào.gitignore. - Workflow thiếu
actions/checkout, hoặc đặt saiworking-directorynên chỉ chạy được khi sửa tay. - Nuốt mã thoát của lệnh kiểm tra (ví dụ thêm
|| truesaunpm test) khiến pipeline xanh dù test đỏ. - Không pin phiên bản action, dùng
permissions: write-allhoặc cấp quyền rộng hơn nhu cầu. - Để lại test đã bị làm hỏng trong nhánh chính, hoặc không hoàn tác sau phần thử nghiệm gate.
- Commit
node_modules,.env, token hoặc mật khẩu. - Chỉ viết "đã sửa được" mà không nêu nguyên nhân gốc, dòng log chứng minh và cách phòng tránh.
- Sửa tay file evidence cho "đẹp" hơn thực tế.
Quy trình nộp
- Trong repository cá nhân (ví dụ
devops-labs), tạo nhánh mới, ví dụweek-08. - Thêm hai thư mục
lab-15/vàlab-16/theo cấu trúc ở trên. File workflow thật nằm ở.github/workflows/ci.ymlcủa chính repo; workflow cần nằm trên nhánh mặc định để các run hiển thị đầy đủ, vì vậy hãy ghi rõ trong mô tả PR bạn đã chạy run ở nhánh nào. - Push nhánh và mở Pull Request vào nhánh chính của repo cá nhân. Mô tả PR nêu đã làm L1 hay L2 và dán link các run xanh, run đỏ.
- Nhờ một bạn review. Reviewer để lại ít nhất hai nhận xét cụ thể (một điểm tốt, một điểm cần cải thiện) và bạn phản hồi hoặc sửa theo.
- Gửi link PR cho mentor. Mentor chấm theo barem trên PR và để lại nhận xét.
- Hạn nộp: trước buổi đầu tiên của tuần 9.
Checklist trước khi nộp
-
lab-15/vàlab-16/đúng cấu trúc theotemplates/lab-template.md -
README.mdmỗi thư mục trả lời đủ 7 câu và ghi rõ đã làm L1 hay L2 -
lab-15/evidence/command-output.txtđược sinh bằngtee, có cả lần chạy xanh và lần chạy đỏ của pipeline giả lập - File test đã hoàn tác,
npm testxanh ở trạng thái nộp -
.github/workflows/ci.ymlcópermissions, action pin theo phiên bản,npm civà đúngworking-directory -
lab-16/source/ci.yml.copytrùng với workflow thật -
lab-16/report.mdcó link run xanh, đoạn log Setup Node.js hai lần chạy và 5 câu trả lời -
package-lock.jsonđã được commit,node_modulesvà.envkhông có trong repo - Không commit token, mật khẩu, private key
- Nếu làm L2: link run bị skipped do
needs, link PR đỏ rồi xanh, báo cáo 5 phần,environments.md - PR đã được ít nhất một bạn review và bạn đã phản hồi