Bài 32 — CI cho TaskFlow bằng GitHub Actions: Sau khi có bộ test chạy được, bước tiếp theo là mô tả môi trường và các lệnh kiểm tra để runner sạch có thể lặp lại. CI không tự deploy ứng dụng và không cần token xuất bản bài viết hay mật khẩu production.
1. Điều kiện trước khi bật CI
TaskFlow nằm trong thư mục taskflow/ của repository nội dung. Vì vậy workflow phải nằm ở .github/workflows/taskflow-tests.yml tại gốc repository, còn các bước run đặt working-directory: taskflow. Nếu tách TaskFlow thành repository riêng, bỏ working-directory và đổi cache-dependency-path thành package-lock.json. Không đặt workflow trong taskflow/.github rồi kỳ vọng GitHub của repository cha tự tìm thấy.
Commit mã nguồn, test, composer.json/composer.lock, package.json/package-lock.json, .env.example an toàn và workflow. Không commit vendor, node_modules, .env thật, file database local hoặc .publisher.env. Bản khóa học dùng PHP 8.4, Node 24 và Ubuntu 24.04 trên CI; đây là cấu hình kiểm thử cụ thể, không phải tuyên bố mọi phiên bản PHP được Laravel hỗ trợ đều đã thử.
2. Workflow đầy đủ
name: TaskFlow Tests
on:
push:
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: taskflow-tests-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: TaskFlow PHP 8.4
runs-on: ubuntu-24.04
timeout-minutes: 15
defaults:
run:
working-directory: taskflow
env:
APP_ENV: testing
DB_CONNECTION: sqlite
DB_DATABASE: ':memory:'
DB_URL: ''
CACHE_STORE: array
SESSION_DRIVER: array
QUEUE_CONNECTION: sync
BROADCAST_CONNECTION: 'null'
MAIL_MAILER: array
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- uses: shivammathur/setup-php@b604ade2a87db23f8871b7182e69ec5e75effb45 # v2
with:
php-version: '8.4'
extensions: mbstring, dom, curl, fileinfo, pdo_sqlite, sqlite3
coverage: none
tools: composer:v2
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: '24'
cache: npm
cache-dependency-path: taskflow/package-lock.json
- name: Validate and install PHP dependencies
run: |
composer validate --strict
composer install --no-interaction --prefer-dist --no-progress
composer check-platform-reqs
- name: Prepare ephemeral application key
run: |
cp .env.example .env
php artisan key:generate
- name: Build frontend from lockfile
run: |
npm ci
npm run build
- name: Check formatting
run: vendor/bin/pint --test
- name: Run complete test suite
run: php artisan test
- name: Check real Reverb transport
run: node tests/reverb-smoke.mjs3. Vì sao chọn các bước này?
Composer validate kiểm tra khai báo và lockfile; install cài đúng dependency đã khóa, không update tùy ý trong CI. check-platform-reqs kiểm tra PHP/extension thực tế. npm ci dùng package-lock và build Vite trước test để view có manifest assets. Composer có thể chạy script của dependency; action và package vẫn là thành phần cần đánh giá độ tin cậy.
.env được tạo mới trong runner dùng một lần và key:generate tạo khóa riêng cho lần chạy đó. Biến môi trường ở job chọn testing, SQLite bộ nhớ, cache/session/mail giả lập. Các test database của dự án còn ép connection riêng trước migrate. Không chạy migrate trên database production, không dùng dữ liệu khách hàng làm fixture. Test queue tự chuyển sang database queue để đo worker, còn smoke Reverb tự cấp credential tạm và bật sync broadcast trong subprocess.
Pint chạy --test, nên lỗi định dạng làm job thất bại thay vì CI âm thầm sửa code. Sửa local bằng vendor/bin/pint rồi chạy lại test. php artisan test chạy cả class PHPUnit cũ và test Pest mới. Reverb smoke kiểm tra transport thật trên loopback; nó không thay test authorization HTTP, kiểm thử browser hay TLS/Nginx.
4. Quyền, dependency và cache
permissions: contents: read giới hạn GITHUB_TOKEN; checkout không giữ credential cho lệnh Git tiếp theo. Workflow dùng pull_request, không dùng pull_request_target để thực thi code chưa tin cậy với quyền cao. Không truyền secret production vào test và không tự chạy pull request lạ trên self-hosted runner chứa dữ liệu nội bộ.
Ba action được ghim commit SHA đã đối chiếu với tag tại checkpoint. SHA giúp tránh tag đổi ngầm nhưng không thay audit mã hoặc cập nhật bảo mật. Định kỳ review bản mới, thay SHA trong PR và chạy lại kiểm tra. Cache npm lưu dữ liệu tải gói, không biến node_modules cũ thành nguồn sự thật; npm ci vẫn chạy. Workflow này chưa bật cache Composer để giữ cấu hình ban đầu đơn giản.
Timeout 15 phút tránh job treo vô hạn. concurrency hủy lần chạy cũ cùng ref khi có commit mới. Không có path filter, nên check vẫn xuất hiện cho thay đổi ngoài taskflow; đổi sang filter sau này phải xem ảnh hưởng tới required checks, tránh PR chờ mãi một check bị bỏ qua.
5. Kiểm chứng thực tế và phần chưa chạy
Local đã pass composer validate --strict, check-platform-reqs, Pint --test, build frontend, 97 tests/435 assertions và Reverb smoke. Lần lint đầu phát hiện lỗi import/spacing; formatter đã sửa và suite vẫn pass. Đây là bằng chứng các lệnh chạy trên môi trường local hiện có, không chứng minh đã cài sạch trên Ubuntu runner.
Workflow chưa được push hoặc dispatch trên GitHub trong checkpoint này. Chưa có run URL, chưa bật branch protection và không tuyên bố CI xanh. Để xác minh hosted CI: đưa đúng source/lockfile lên nhánh, mở pull request, kiểm tra Actions từ đầu đến cuối, lưu run URL và commit SHA. Nếu lỗi, sửa bước đầu tiên thất bại thay vì bỏ assertion để lấy màu xanh.
6. Chẩn đoán lỗi thường gặp
| Lỗi | Cách kiểm tra |
|---|---|
| Không tìm thấy composer.json | Kiểm tra repository layout và working-directory. |
| Lockfile không tương thích PHP | Đọc check-platform-reqs; review dependency, không dùng --ignore-platform-reqs để che lỗi. |
| Vite manifest missing | Kiểm tra npm ci/build và đường dẫn public/build. |
| Database không đúng | Kiểm tra DB_URL, config cache và thiết lập test; không in credential ra log. |
| Reverb timeout | Kiểm tra process startup, cổng loopback và script; không mở cổng test ra Internet. |
| Pint fail | Chạy formatter local, review diff, chạy lại test. |
7. Từ báo cáo sang cổng chất lượng
Sau khi có run thật ổn định, chọn đúng check TaskFlow PHP 8.4 trong ruleset/branch protection để yêu cầu pass trước merge. Đây là thao tác quản trị repository riêng, không được YAML tự cấu hình. Thử một PR có test cố ý fail trên nhánh thử nghiệm để xác nhận merge bị chặn, rồi phục hồi code. Không bỏ qua check chỉ vì local pass.
CI hiện không đo coverage, không chạy PHPStan, MySQL/Redis integration, browser hoặc deployment. Thêm từng kiểm tra theo rủi ro và thời gian phản hồi. CD về sau cần môi trường, secret tối thiểu, approval và rollback riêng; đừng ghép token publisher của website vào pipeline học Laravel.
Tham khảo: Checkout, Setup Node, Setup PHP. Điều hướng: Bài 31 · Lộ trình.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.