Một lệnh test chờ dịch vụ không trả lời có thể giữ runner lâu hơn dự kiến. Đặt giới hạn ở từng lệnh hữu ích, nhưng bạn vẫn cần giới hạn tổng thời gian của job. Bài này giúp bạn đọc đúng hai vị trí timeout-minutes và thiết kế một lần thử nhỏ trong repository thử nghiệm.
Tài liệu GitHub Actions được đối chiếu ngày 02/11/2026. YAML bên dưới đã được parse và kiểm tra cấu trúc cục bộ, script đã kiểm tra cú pháp Bash. Chưa gửi workflow lên GitHub, chưa chạy runner hay đo thời gian hủy thực tế. Các mốc một, hai và bốn phút là cấu hình minh họa, không phải số đo.
Hai cấp giới hạn phục vụ hai câu hỏi
Ở jobs.<job_id>.timeout-minutes, bạn giới hạn job. Ở jobs.<job_id>.steps[*].timeout-minutes, bạn giới hạn một step. Giới hạn step không tạo thêm ngân sách ngoài giới hạn job: nếu job hết thời gian trước, việc step còn ngân sách không giúp nó chạy tiếp.
Theo tài liệu hiện tại, job mặc định là 360 phút, còn step cần số nguyên dương và tối đa 360 phút. Giới hạn thực tế còn phụ thuộc loại runner; đừng dùng một con số lớn hơn để cố vượt giới hạn nền tảng. Với team nhỏ, giá trị hữu ích nên xuất phát từ các lần chạy bình thường và khoảng dự phòng hợp lý, thay vì sao chép một giá trị mặc định rất dài.
Một workflow thử không cần checkout hay secret
Lưu thành .github/workflows/timeout-demo.yml trong repository thử nếu bạn muốn chạy thử thủ công:
name: Timeout demonstration
on:
workflow_dispatch:
permissions: {}
jobs:
timeout-demo:
runs-on: ubuntu-latest
timeout-minutes: 4
steps:
- name: Quick setup
timeout-minutes: 1
shell: bash
run: echo 'Setup completed'
- name: Deliberately exceed step budget
timeout-minutes: 1
shell: bash
run: |
echo 'Waiting for the step timeout'
sleep 120
echo 'Reached end of long step'
Workflow chỉ có trigger thủ công. Không có action bên ngoài, repository checkout hay credential. Lệnh sleep 120 cố ý dài hơn ngân sách step để bạn quan sát trường hợp quá hạn. Nếu thực sự chạy, nó tiêu thụ thời gian runner của tài khoản; không cần thêm vào pipeline production để tìm hiểu cú pháp.
Kỳ vọng cần xác nhận trên GitHub là step dài không hoàn thành bình thường và job không thành công. Đừng dùng đúng một timestamp đến từng giây làm tiêu chí duy nhất: giao diện, quá trình dừng và cập nhật trạng thái có thể không xuất hiện đồng thời. Trong bài này chưa có bằng chứng thực thi để báo một thời lượng cụ thể.
Đọc kết quả và chọn ngân sách
Ghi lại bước nào quá hạn, thời điểm bắt đầu, log cuối cùng và kết luận của job. Sau đó kiểm tra lệnh có đang chờ một tài nguyên mà nó không thể tiếp cận hay không. Tăng timeout có thể phù hợp với test chậm hợp lệ, nhưng không sửa địa chỉ dịch vụ sai hoặc vòng chờ không có điều kiện dừng.
Trong workflow thật, có thể cấp ngân sách riêng cho cài dependency, build và test, đồng thời giữ giới hạn chung. Các ngân sách step không phải lịch đặt chỗ chạy tuần tự: step nhanh hơn sẽ kết thúc sớm. Cũng cần phân biệt thời gian chờ runner trong hàng đợi với thời gian job đã chạy; timeout của job không phải cam kết workflow sẽ xong sau đúng số phút tính từ lúc bạn bấm Run.
Những lỗi dễ làm mất tín hiệu
Đặt timeout-minutes ngang cấp jobs hoặc dưới env không tạo giới hạn job như mong muốn. Dùng giá trị thập phân cho step cũng sai hợp đồng được tài liệu nêu. Khi review YAML, nhìn rõ đường dẫn cấp lồng nhau thay vì chỉ tìm thấy tên key.
Không thêm continue-on-error: true chỉ để workflow nhìn xanh sau một bước test quá hạn. Hãy xác định chính sách lỗi trước. Ngoài ra, dừng một runner không chứng minh giao dịch đã gửi tới dịch vụ ngoài được hoàn tác. Với tác vụ deploy hay tạo tài nguyên, cơ chế kiểm tra kết quả và thu hồi tài nguyên cần thiết kế riêng.
Timeout là hàng rào thời gian, còn điều kiện thoát và xử lý tài nguyên vẫn thuộc trách nhiệm tác vụ. Bắt đầu từ một workflow thử nhỏ, kiểm chứng trên loại runner đang dùng, rồi đưa ngân sách phù hợp vào CI.


