I. Tại sao cần triển khai CI/CD?
Team mobile của chúng tôi vốn dĩ có quy mô nhỏ và hoạt động theo mô hình in-house. Tất cả các công việc từ phát triển, kiểm thử cho đến phân phối đều được trao đổi và xử lý trực tiếp giữa các thành viên trong team. Việc build app được thực hiện ngay trên máy local rồi install trực tiếp cho tester qua cable.
Tuy nhiên, khi dự án mở rộng, nhu cầu chia sẻ bản build cho tester ở nhiều khu vực, hoặc gửi cho khách hàng review/accept trước release trở nên quan trọng. Việc tiếp tục build local bằng cách install trực tiếp trở nên thủ công, không đảm bảo được version, chất lượng code và tốn thời gian.
Chính vì vậy, việc thiết lập CI/CD để phân phối các bản build nhanh chóng, đồng bộ, có versioning rõ ràng và dễ gửi cho tester/khách hàng là yếu tố bắt buộc.
II. Điều kiện thực tế & giải pháp triển khai
1. Điều kiện hiện tại của team
Tiêu chí |
Mô tả |
Hệ thống quản lý mã nguồn |
GitLab Enterprise |
Nền tảng phát triển |
iOS và Android |
Số lượng developer |
< 5 người |
Resource CI/CD |
Chưa có server riêng để build |
Nhu cầu hiện tại |
Cần chia sẻ build nhanh cho tester/khách hàng |
Mục tiêu |
Tự động hoá build, giảm tải thao tác thủ công, quản lý versioning, dễ maintain |
2. So sánh các lựa chọn CI/CD phổ biến
Tiêu chí |
GitLab CI (self-hosted) |
Bitrise |
GitHub Actions + Fastlane |
Phù hợp mobile |
Có |
Rất dễ |
Tốt |
Cấu hình ban đầu |
Khó (cần runner riêng) |
Rất phù hợp |
Dễ |
Gói miễn phí |
Không rõ ràng (self-host tốn tài nguyên) |
Giới hạn 200 min/tháng |
2000 phút/tháng cho private repo |
Dễ maintain |
Khó nếu team nhỏ |
Rất dễ |
Dễ |
Tự động hoá cert/profile |
Cần làm thủ công |
Có tích hợp |
Hỗ trợ tốt với Match |
Tích hợp TestFlight/Firebase |
Tùy config |
Có sẵn |
Có thể tích hợp dễ dàng |
3. Lý do chọn GitHub Actions + Fastlane
- Có hoặc không có runner đều được → linh hoạt cho việc scale trong tương lai
- Giao diện dễ hiểu, tài liệu đầy đủ
- Hỗ trợ workflow chi tiết, dễ tuỳ chỉnh
- Kết hợp tốt với Fastlane → sync cert, build, upload TestFlight
- Gói free phù hợp team nhỏ, không cần nâng cấp giai đoạn đầu
4. Phạm vi triển khai
- iOS: phân phối build lên TestFlight
- Android: phân phối build lên Firebase App Distribution
III. Tổng quan kiến trúc và quy trình hoạt động với iOS
Flow hoạt động CI/CD iOS với GitHub Actions:
Điều kiện cần để triển khai:
- Tài khoản apple develop quyền Admin hoặc Account Holder
- GitLab repository định triển khai có quyền maintainer
- GitHub repository (repository mirror) có quyền maintainer
- GitHub repository (repository lưu certificates) có quyền maintainer
Chi tiết các bước triển khai:
1. Developer pushes code to gitLab
Dev thực hiện push code như thường lệ vào GitLab (nơi quản lý source chính của dự án). Đây là bước khởi đầu cho chuỗi CI/CD mà không làm thay đổi thói quen của team.
2. GitLab triggers mirror code to GitHub
GitLab được cấu hình để mirror tự động mã nguồn sang GitHub repository mỗi khi có commit mới.
- Đầu tiên, setup dự án github để mirror
- Trên GitHub, tạo repo trống (không README). Trong bài viết này, tôi tạo repo như sau: https://github.com/thevx-sanan/cicd.git
- Tạo Personal Access Token trên GitHub
- Truy cập: https://github.com/settings/tokens
- Chọn Generate new token -> Generate new token (classic) -> cấp quyền repo, workflow
- Thêm GITHUB_TOKEN vào GitLab CI/CD variables
- Truy cập GitLab repository định triển khai CI/CD
- Chọn Settings -> CI/CD -> Variables
- Thêm biến:
- Value: Token từ GitHub ở bước trên
- Chọn Masked
- Tiếp theo, setup .gitlab-ci.yml
- Tạo file .gitlab-ci.yml
- Cài đặt GitLab Runner (nếu chưa có)
- Đăng ký runner với GitLab
Chạy trên máy chủ hoặc local (macOS, Linux, Windows đều được):
Bạn sẽ được hỏi:
Prompt |
Ví dụ trả lời |
Enter the GitLab instance URL: |
https://gitlab.com hoặc URL GitLab self-host |
Enter the registration token: |
Lấy token trong Settings > CI/CD > Runners |
Enter a description for the runner: |
mirror-runner |
Enter tags for the runner (comma-separated): |
mirror |
Enter executor: |
shell |
Lưu ý:
- mirror là tag quan trọng, job trong .gitlab-ci.yml đang dùng tag này để lọc runner.
- Nếu bạn dùng nhiều runner, tag này giúp chỉ định job chạy đúng nơi.
Bây giờ, bạn có thể testing bằng cách push code trên GitLab và theo dõi có update trên GitHub hay không.
3. Fastlane runtest and build iOS app
Sau khi mirror code từ GitLab sang GitHub thành công, workflow GitHub Actions sẽ thực hiện việc build và upload app iOS lên TestFlight thông qua Fastlane. Toàn bộ quy trình được chia thành các bước sau:
- Tạo GitHub/GitLab repository để lưu chứng chỉ
- Tạo 1 repository riêng (private) có tên như: ios-certificates , Trong ví dụ này, chúng tôi tạo repository sau: git@github.com:thevx-sanan/ios-certificates.git
- Repo này sẽ được sử dụng bởi fastlane match để lưu:
- Distribution certificate
- Provisioning profile
- Tạo bundle ID & App trên App Store Connect
- Truy cập https://developer.apple.com/account/resources/identifiers/list
- Vào Identifiers
Tạo bundle ID cho app test, ví dụ: com.sanan.setup.cicd
- Truy cập https://appstoreconnect.apple.com/apps
- Tạo app tương ứng trên App Store Connect → điền bundle ID trên
- Tạo App Store Connect API Key
- Truy cập https://appstoreconnect.apple.com/access/integrations/api
- Tạo API Key và lưu các thông số:
- Issuer ID
- Key ID
- File API key (tải xuống) nhớ lưu kỹ vì chỉ cho phép tải xuống 1 lần
4. Distribute build to testers
Cài đặt Fastlane cho dự án (macos):- Nếu bạn chưa cài đặt fastlane trước đó, hãy mở terminal lên và nhập:
brew install fastlane
- Sau đó, Hãy mở thư mục lưu repository GitLab của bạn và chạy terminal:
fastlane init
- Sau khi init fastlane xong, chúng ta setup fastlane match:
fastlane match init
- Sau đó, hãy chọn 1 (git), sau đó nhập git url của repository mà bạn đã setup dùng để lưu config (nhớ copy dạng SSH): git@github.com:thevx-sanan/ios-certificates.git
- Tiếp theo, trong thư mục sẽ tạo folder fastlane và các file Gemfile, Gemfile.lock. Bây giờ, hãy mở folder fastfile, sau đó mở Fastfile:
- Tiếp theo, mở Appfile:
- Tiếp theo, mở Matchfile: Sửa git_url và username tương ứng của bạn
- Test Fastlane trên máy local của bạn (macos):
- Thay các giá trị tương ứng và mở terminal tại thư mục đang setup:
export ASC_KEY_ID="<key_id_appstore_connect_api>"
export ASC_ISSUER_ID="<isuer_id_appstore_connect_api>"
export ASC_KEY_CONTENT="<content_appstore_connect_api>"
export MATCH_PASSWORD="<your_setup>"
export FASTLANE_APPLE_ID="<your_apple_id>"
export DEVELOPER_PORTAL_TEAM_ID="<your_apple_developer_account_id>"
export TEMP_KEYCHAIN_USER="<your_setup>"
export TEMP_KEYCHAIN_PASSWORD="<your_setup>"
Kết quả chạy thành công:
Successfully uploaded the new binary to App Store Connect
- Cài đặt các variable tương ứng trên GitHub:
- Truy cập Settings -> Secrets and variables -> Actions và cài đặt các variables như bước trên:
1. ACTIONS_DEPLOY_KEY
2. ASC_KEY_ID
3. ASC_ISSUER_ID
4. ASC_KEY_CONTENT
5. MATCH_PASSWORD
6. FASTLANE_APPLE_ID
7. DEVELOPER_PORTAL_TEAM_ID
8. TEMP_KEYCHAIN_USER
9. TEMP_KEYCHAIN_PASSWORD
Lưu ý: ACTIONS_DEPLOY_KEY là private key khi bạn setup ssh thông thường đối với repo lưu ios-certificates
- Tạo Github Actions Workflow:
- Bạn có thể tạo trực tiếp trên github hoặc tạo bằng trực tiếp từ folder repository:
- Tạo thư folder .github -> tạo folder workflows -> new terminal at workflows -> touch fastlane.yml
- Sau đó, hãy mở file fastlane.yml và chúng tôi setup với dự án test này như sau:
- Bạn có thể tạo trực tiếp trên github hoặc tạo bằng trực tiếp từ folder repository:
- Cuối cùng, push code lên và testing thôi. Hãy vào tab Actions nhé.
IV. Kết thúc phần 1
Với phần hướng dẫn chi tiết ở trên, chúng ta đã từng bước triển khai được quy trình CI/CD cho dự án iOS từ tình huống thực tế của một team nhỏ:
- Duy trì workflow hiện tại trên GitLab mà không cần thay đổi thói quen của dev
- Tự động hoá quá trình build, phân phối TestFlight qua GitHub Actions
- Sử dụng Fastlane để quản lý chứng chỉ, build và upload app an toàn, hiệu quả
- Đảm bảo tester, khách hàng nhận bản build nhanh chóng, không cần thao tác thủ công
Việc áp dụng CI/CD không chỉ giúp tiết kiệm thời gian mà còn tăng độ ổn định, kiểm soát tốt hơn các bản phân phối – đặc biệt khi số lượng thành viên và môi trường kiểm thử bắt đầu mở rộng.
______________________________________________________________
Tiếp theo?
Trong phần 2, chúng ta sẽ tiếp tục mở rộng quy trình này cho Android, sử dụng Firebase App Distribution kết hợp cùng Fastlane và GitHub Actions để tạo quy trình phân phối tương tự cho ứng dụng Android của bạn.
Nếu bạn chưa từng triển khai CI/CD trước đó, hãy thử áp dụng phần iOS này ngay trong dự án cá nhân hoặc staging – bạn sẽ thấy sự khác biệt rõ rệt trong quy trình làm việc hằng ngày.