1. CI/CD là gì?
Trong quá trình phát triển phần mềm, đặc biệt là những dự án có nhiều lập trình viên cùng tham gia, việc quản lý mã nguồn, kiểm tra chất lượng và phát hành ứng dụng là những công việc được thực hiện thường xuyên.
Ví dụ, một nhóm đang xây dựng ứng dụng Flutter bán hàng. Một lập trình viên phát triển chức năng đăng nhập, một người xây dựng giỏ hàng, người khác thực hiện chức năng thanh toán.
Mỗi thành viên có thể kiểm tra phần code của mình và thấy hoạt động bình thường. Tuy nhiên, khi kết hợp các phần code, có thể xuất hiện lỗi do thay đổi dependency, xung đột mã nguồn hoặc những chức năng sử dụng chung bị ảnh hưởng.
Nếu nhóm chỉ kiểm tra thủ công vào cuối dự án, việc phát hiện và sửa lỗi có thể mất nhiều thời gian.
Để hỗ trợ tự động hóa những công việc lặp lại, các dự án phần mềm thường sử dụng CI/CD.
CI/CD là tập hợp những phương pháp và quy trình tự động hóa việc tích hợp mã nguồn, kiểm tra chất lượng, xây dựng và phân phối phần mềm.
CI là viết tắt của Continuous Integration, nghĩa là tích hợp liên tục.
CD có thể là Continuous Delivery, nghĩa là chuyển giao liên tục, hoặc Continuous Deployment, nghĩa là triển khai liên tục.
Mặc dù thường được nhắc đến cùng nhau, CI và CD có những mục tiêu khác nhau.
CI tập trung vào việc tích hợp và kiểm tra code.
CD tập trung vào việc chuẩn bị, phân phối hoặc triển khai những phiên bản phần mềm đã đáp ứng điều kiện cần thiết.
2. Vấn đề khi không sử dụng CI/CD
Giả sử một nhóm có năm lập trình viên cùng phát triển ứng dụng Flutter.
Mỗi người làm việc trên một nhánh Git riêng.
Sau khi hoàn thành chức năng, họ đưa code vào nhánh chính.
Nếu không có quy trình kiểm tra tự động, một số vấn đề có thể xảy ra.
Thứ nhất, code của một thành viên có thể không tương thích với những thay đổi của người khác.
Thứ hai, một dependency mới có thể khiến dự án không còn build được.
Thứ ba, một chức năng cũ có thể bị lỗi sau khi cập nhật code.
Thứ tư, các thành viên có thể sử dụng những phiên bản Flutter khác nhau, dẫn đến kết quả không nhất quán.
Thứ năm, việc build ứng dụng thủ công có thể sử dụng nhầm cấu hình development thay vì production.
CI/CD giúp giảm những rủi ro này bằng cách thiết lập quy trình kiểm tra và build có thể lặp lại.
Tuy nhiên, CI/CD không tự động bảo đảm chương trình hoàn toàn chính xác. Nếu nhóm không viết những bài test có ý nghĩa hoặc cấu hình pipeline chưa phù hợp, lỗi vẫn có thể xuất hiện.
3. Continuous Integration (CI)
Continuous Integration là phương pháp trong đó những thay đổi mã nguồn được tích hợp thường xuyên và được kiểm tra tự động.
Ví dụ, một lập trình viên hoàn thành chức năng tìm kiếm sản phẩm.
Sau khi commit và push code lên GitHub, họ tạo Pull Request để đề nghị hợp nhất thay đổi.
GitHub Actions có thể tự động chạy:
flutter pub get
flutter analyze
flutter test
Nếu các bước thành công, nhóm có thêm cơ sở để xem xét hợp nhất code.
Nếu một bài test thất bại, hệ thống thông báo để lập trình viên kiểm tra.
3.1. Tại sao nên tích hợp thường xuyên?
Nếu các lập trình viên làm việc riêng biệt trong thời gian quá dài, code của họ có thể khác biệt nhiều so với nhánh chung.
Khi tích hợp, việc giải quyết xung đột và lỗi tương thích sẽ khó khăn hơn.
Tích hợp thường xuyên giúp phát hiện vấn đề sớm, khi phạm vi thay đổi còn tương đối nhỏ.
3.2. CI có thay thế Code Review không?
Không.
CI có thể tự động kiểm tra những điều kiện đã được cấu hình, chẳng hạn Static Analysis và Unit Test.
Tuy nhiên, CI thông thường không thể tự đánh giá đầy đủ kiến trúc phần mềm, tính phù hợp của yêu cầu nghiệp vụ hoặc chất lượng thiết kế.
Code Review vẫn quan trọng để các thành viên kiểm tra cách tổ chức code, khả năng bảo trì, bảo mật và những vấn đề mà bài test chưa bao phủ.
4. Continuous Delivery
Continuous Delivery là phương pháp duy trì phần mềm trong trạng thái có thể phát hành sau khi vượt qua các bước kiểm tra cần thiết.
Ví dụ, sau khi code Flutter vượt qua CI, hệ thống tự động tạo Android App Bundle.
Bản build này có thể được lưu thành artifact hoặc phân phối đến nhóm kiểm thử.
Sau đó, người phụ trách có thể quyết định thời điểm phát hành chính thức.
Quy trình minh họa:
Code → Analyze → Test → Build → Kiểm thử bản phát hành → Phê duyệt → Release
Điểm quan trọng của Continuous Delivery là phần mềm được chuẩn bị sẵn sàng để phát hành, nhưng vẫn có thể cần một bước quyết định thủ công.
5. Continuous Deployment
Continuous Deployment tiến thêm một bước so với Continuous Delivery.
Khi thay đổi code đáp ứng những điều kiện của pipeline, hệ thống có thể tự động triển khai mà không cần phê duyệt thủ công cho từng lần triển khai.
Ví dụ, đối với một Backend được triển khai trên máy chủ, sau khi code vượt qua test và kiểm tra cần thiết, hệ thống có thể tự động cập nhật dịch vụ.
Tuy nhiên, với ứng dụng di động Flutter, việc phát hành còn phụ thuộc vào Google Play và App Store.
Do đó, việc tự động tải bản build lên cửa hàng không đồng nghĩa với việc bản cập nhật lập tức xuất hiện trên thiết bị của mọi người dùng.
Quá trình phân phối có thể liên quan đến xét duyệt, kiểm thử hoặc triển khai theo giai đoạn.
6. CI/CD Pipeline là gì?
Pipeline là chuỗi những công việc được tổ chức để thực hiện một quy trình tự động.
Trong Flutter, một pipeline cơ bản có thể gồm:
Checkout → Setup Flutter → Install Dependencies → Format Check → Analyze → Test → Build
Mỗi bước có mục đích riêng.
6.1. Checkout Source Code
Pipeline lấy mã nguồn từ repository Git.
Mã nguồn này thường tương ứng với một commit hoặc phiên bản cụ thể.
6.2. Setup Flutter
Hệ thống chuẩn bị Flutter SDK và những công cụ cần thiết.
Việc sử dụng đúng phiên bản Flutter rất quan trọng vì các phiên bản SDK có thể có khác biệt về API, công cụ build hoặc dependency.
6.3. Install Dependencies
Pipeline chạy:
flutter pub get
Lệnh này giải quyết và tải những dependency cần thiết theo cấu hình dự án và lockfile khi áp dụng.
6.4. Format Check
Pipeline có thể kiểm tra định dạng code:
dart format --output=none --set-exit-if-changed .
Lệnh này giúp xác định code có tuân thủ định dạng Dart hay không.
6.5. Static Analysis
Pipeline chạy:
flutter analyze
Công cụ phân tích code để phát hiện những vấn đề mà Dart Analyzer và quy tắc lint có thể xác định.
6.6. Testing
Pipeline chạy:
flutter test
Lệnh này thường thực hiện Unit Test và Widget Test trong thư mục test.
Integration Test có thể cần môi trường thiết bị hoặc trình giả lập riêng.
6.7. Build
Nếu những bước kiểm tra thành công, pipeline có thể build ứng dụng.
Ví dụ:
flutter build appbundle --release
Kết quả là bản build Android phù hợp với cấu hình dự án.
7. Git, Branch và Pull Request trong CI/CD
Git là hệ thống quản lý phiên bản mã nguồn.
CI/CD thường hoạt động dựa trên những sự kiện trong hệ thống Git.
Ví dụ, nhóm có thể tổ chức các nhánh:
main: Chứa code ổn định theo quy trình của nhóm.
develop: Chứa code đang được tích hợp để phát triển.
feature/login: Phát triển chức năng đăng nhập.
feature/cart: Phát triển chức năng giỏ hàng.
Đây chỉ là một cách tổ chức nhánh tham khảo.
Khi lập trình viên hoàn thành một chức năng, họ có thể tạo Pull Request.
Pull Request là yêu cầu đề nghị hợp nhất những thay đổi từ một nhánh vào nhánh khác.
CI có thể tự động chạy khi Pull Request được tạo hoặc cập nhật.
Nếu bài test thất bại, nhóm có thể yêu cầu sửa trước khi hợp nhất.
Như vậy, Git quản lý lịch sử code, Pull Request hỗ trợ quy trình xem xét thay đổi, còn CI/CD thực hiện những bước kiểm tra và triển khai tự động.
8. Những công cụ CI/CD phổ biến
Có nhiều nền tảng hỗ trợ CI/CD.
GitHub Actions là hệ thống tự động hóa tích hợp với GitHub.
GitLab CI/CD cung cấp pipeline trong hệ sinh thái GitLab.
Jenkins là công cụ tự động hóa có khả năng tùy chỉnh cao.
Codemagic tập trung vào quy trình build, kiểm thử và phân phối ứng dụng di động, bao gồm Flutter.
Bitrise cũng hỗ trợ tự động hóa quy trình phát triển ứng dụng di động.
Đối với người mới học và đang lưu code trên GitHub, GitHub Actions thường dễ tiếp cận vì workflow được khai báo ngay trong repository.
Tuy nhiên, việc lựa chọn công cụ phụ thuộc vào yêu cầu dự án, nền tảng quản lý mã nguồn, ngân sách và khả năng vận hành của nhóm.
9. GitHub Actions hoạt động như thế nào?
GitHub Actions sử dụng các workflow được định nghĩa trong những tệp YAML.
Thông thường, các tệp này nằm trong thư mục:
.github/workflows/
Một workflow có thể được kích hoạt khi xảy ra những sự kiện như push, Pull Request hoặc khi người dùng yêu cầu chạy thủ công.
Workflow chứa một hoặc nhiều job.
Mỗi job chứa những step.
Step có thể chạy một lệnh hoặc sử dụng một action có sẵn.
Ví dụ:
name: Flutter CI
on:
push:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
cache: true
- name: Install dependencies
run: flutter pub get
- name: Check formatting
run: dart format --output=none --set-exit-if-changed .
- name: Analyze
run: flutter analyze
- name: Test
run: flutter test
Đây là workflow minh họa.
Trong dự án thực tế, nên sử dụng phiên bản Flutter được xác định rõ và xem xét cố định các action theo commit SHA để giảm rủi ro thay đổi ngoài dự kiến.
Giải thích
name là tên workflow.
on quy định sự kiện kích hoạt.
jobs chứa các công việc.
runs-on xác định môi trường thực thi.
steps chứa các bước cần chạy.
actions/checkout lấy mã nguồn.
subosito/flutter-action chuẩn bị Flutter SDK.
flutter pub get cài đặt dependency.
flutter analyze kiểm tra code.
flutter test chạy kiểm thử.
Nếu một bước quan trọng thất bại, job sẽ được đánh dấu thất bại theo cơ chế của GitHub Actions.
10. Runner là gì?
Runner là môi trường thực thi các job trong pipeline.
Ví dụ, GitHub Actions có thể sử dụng runner Ubuntu, Windows hoặc macOS.
Mỗi môi trường có những công cụ và khả năng khác nhau.
Ví dụ, nhiều công việc kiểm tra Dart và Flutter có thể chạy trên Ubuntu.
Đối với quy trình build iOS, thông thường cần macOS và Xcode phù hợp.
Runner có thể được cung cấp bởi nền tảng CI/CD hoặc do tổ chức tự quản lý.
Việc lựa chọn runner ảnh hưởng đến tốc độ, chi phí và khả năng thực hiện các công việc trong pipeline.
11. Artifact là gì?
Artifact là sản phẩm hoặc tệp được tạo ra trong quá trình chạy pipeline.
Ví dụ, khi build Flutter Android, pipeline có thể tạo tệp APK hoặc AAB.
Những tệp này có thể được lưu lại để nhóm phát triển tải xuống hoặc sử dụng trong bước phân phối tiếp theo.
Artifact cũng có thể là báo cáo test, dữ liệu coverage hoặc kết quả phân tích.
Ví dụ, một pipeline có thể tạo Android App Bundle rồi lưu nó như một artifact gắn với commit cụ thể.
Nhờ đó, nhóm phát triển có thể xác định bản build được tạo từ phiên bản code nào.
Tuy nhiên, cần quản lý quyền truy cập và thời gian lưu trữ artifact, đặc biệt khi chúng chứa dữ liệu nội bộ.
12. Cache trong CI/CD
Khi pipeline chạy nhiều lần, việc tải lại toàn bộ dependency có thể mất thời gian.
Cache là cơ chế lưu lại những dữ liệu có thể tái sử dụng giữa các lần chạy pipeline.
Ví dụ, cache có thể giúp giảm thời gian tải những package Dart đã được sử dụng trước đó.
Tuy nhiên, cache cần được quản lý đúng để tránh sử dụng dữ liệu không phù hợp hoặc cũ.
Cache không phải nguồn dữ liệu chính thức và không nên được sử dụng để lưu những bí mật.
13. Secrets và bảo mật pipeline
Trong quá trình phát hành ứng dụng, pipeline có thể cần sử dụng những thông tin nhạy cảm.
Ví dụ:
- Khóa ký ứng dụng Android.
- Mật khẩu keystore.
- Thông tin xác thực dịch vụ phân phối.
- Token truy cập những hệ thống được cấp quyền.
Những thông tin này không nên được ghi trực tiếp trong repository.
Các nền tảng CI/CD thường cung cấp cơ chế quản lý Secrets.
Ví dụ, GitHub Actions có thể truy cập những secret được cấu hình phù hợp với quyền hạn của workflow.
Tuy nhiên, việc sử dụng Secrets vẫn cần cẩn thận.
Nếu pipeline thực thi mã nguồn không đáng tin cậy với quyền truy cập bí mật, có nguy cơ thông tin bị lộ.
Vì vậy, nên áp dụng nguyên tắc cấp quyền tối thiểu, kiểm soát những workflow có quyền phát hành và hạn chế hiển thị bí mật trong log.
14. CI/CD kết hợp với Flutter Flavors
Khi dự án có nhiều môi trường như development, staging và production, CI/CD có thể tạo những bản build tương ứng.
Ví dụ, nhóm muốn tạo bản staging để kiểm thử.
Pipeline có thể chạy:
flutter build apk \
--release \
--flavor staging \
--dart-define-from-file=env/staging.json
Lệnh trên chỉ hoạt động khi dự án đã cấu hình flavor staging và có tệp môi trường phù hợp.
Khi phát hành production, pipeline sử dụng flavor và cấu hình production.
Điều quan trọng là không chỉ kiểm tra tên flavor mà còn phải xác nhận API Base URL, Firebase Project và những thông tin cấu hình khác.
Một bản build production sử dụng nhầm Backend development vẫn có thể build thành công nhưng không phù hợp để phát hành.
15. Quality Gate là gì?
Quality Gate là tập hợp những điều kiện mà code hoặc bản build phải đáp ứng trước khi được chuyển sang giai đoạn tiếp theo.
Ví dụ, nhóm có thể quy định:
flutter analyzephải thành công.- Những bài Unit Test quan trọng phải thành công.
- Không có lỗi bảo mật nghiêm trọng đã được xác định.
- Code phải được review trước khi hợp nhất.
- Bản production phải sử dụng đúng cấu hình môi trường.
Nếu một điều kiện không đạt, quá trình có thể bị chặn.
Quality Gate giúp nhóm phát triển duy trì tiêu chuẩn chất lượng nhất quán.
Tuy nhiên, không nên đặt quá nhiều điều kiện không cần thiết khiến quy trình trở nên phức tạp và khó bảo trì.
16. CI/CD có tự động sửa lỗi không?
CI/CD chủ yếu tự động hóa việc kiểm tra, build và triển khai.
Ví dụ, nếu Unit Test thất bại, pipeline sẽ thông báo kết quả.
Tuy nhiên, pipeline thông thường không tự hiểu đầy đủ nguyên nhân nghiệp vụ và sửa lỗi thay lập trình viên.
Một số công cụ có thể hỗ trợ định dạng code hoặc đề xuất sửa lỗi, nhưng những thay đổi quan trọng vẫn cần được kiểm tra.
Vai trò chính của CI/CD là phát hiện vấn đề sớm và giúp quy trình thực hiện nhất quán.
17. Ví dụ quy trình CI/CD trong dự án Flutter bán hàng
Giả sử một nhóm đang phát triển ứng dụng MilkStore.
Lập trình viên A sửa chức năng giỏ hàng.
Sau khi hoàn thành, A commit và push code lên GitHub.
GitHub Actions tự động chạy Static Analysis và Unit Test.
Nếu bài test tính tổng tiền thất bại, A cần kiểm tra lại logic.
Sau khi sửa, A cập nhật Pull Request.
Khi CI thành công và code được review, thay đổi được hợp nhất.
Tiếp theo, pipeline có thể tạo bản staging để nhóm kiểm thử sử dụng.
Nếu chức năng đặt hàng, đăng nhập và nhận thông báo hoạt động đúng, nhóm chuẩn bị bản production.
Sau khi phát hành, nhóm tiếp tục theo dõi lỗi thông qua những công cụ giám sát phù hợp.
Quy trình này cho thấy CI/CD liên kết nhiều kiến thức như Git, Testing, Debugging, Flavors và Release.
18. Những sai lầm thường gặp
Sai lầm đầu tiên là tạo pipeline nhưng không có những bài test có ý nghĩa.
Sai lầm thứ hai là không cố định phiên bản công cụ, khiến môi trường build thay đổi ngoài dự kiến.
Sai lầm thứ ba là đưa khóa ký hoặc token vào repository.
Sai lầm thứ tư là không phân biệt môi trường staging và production.
Sai lầm thứ năm là chỉ chạy CI khi sắp phát hành thay vì kiểm tra thường xuyên.
Sai lầm thứ sáu là sử dụng dữ liệu production cho kiểm thử tự động.
Sai lầm cuối cùng là xây dựng pipeline quá phức tạp ngay từ đầu.
Đối với dự án mới, nên bắt đầu bằng những bước đơn giản như flutter analyze và flutter test, sau đó bổ sung build và phân phối khi cần.
19. Kết luận
CI/CD là tập hợp những phương pháp giúp tự động hóa quá trình tích hợp mã nguồn, kiểm tra chất lượng, build và phân phối phần mềm.
Continuous Integration giúp phát hiện lỗi tích hợp sớm.
Continuous Delivery giúp phần mềm sẵn sàng phát hành.
Continuous Deployment cho phép tự động triển khai khi các điều kiện của pipeline được đáp ứng, trong phạm vi mà hệ thống phân phối hỗ trợ.
Trong Flutter, CI/CD thường được kết hợp với Git, Unit Testing, Widget Testing, Static Analysis, Flutter Flavors và quy trình build ứng dụng.
Khi được thiết kế phù hợp, CI/CD giúp nhóm phát triển giảm công việc thủ công, kiểm soát chất lượng tốt hơn và duy trì quy trình phát hành có tính nhất quán.
Tuy nhiên, CI/CD không thay thế kiến thức lập trình, kiểm thử hoặc bảo mật. Nó là công cụ hỗ trợ để quá trình phát triển phần mềm trở nên hiệu quả và đáng tin cậy hơn.
20. Tài liệu tham khảo
- Flutter Continuous Delivery: https://docs.flutter.dev/deployment/cd
- GitHub Actions: https://docs.github.com/en/actions
- GitHub Actions Workflow Syntax: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- Flutter Testing: https://docs.flutter.dev/testing/overview
- Codemagic: https://docs.codemagic.io/flutter-configuration/flutter-projects/








Khoá học lập trình game con rắn cho trẻ em




