Phần 1: Tối ưu hoá quy trình phân phối ứng dụng: Hành trình triển khai CI/CD cho mobile team nhỏ

thg 7 9, 2025 | Phần 1: Tối ưu hoá quy trình phân phối ứng dụng: Hành trình triển khai CI/CD cho mobile team nhỏ

Hành trình triển khai CI/CD cho mobile team nhỏ: tự động hoá build iOS bằng GitHub Actions + Fastlane, phân phối hiệu quả qua TestFlight, tối ưu quy trình.

Tối ưu hoá quy trình phân phối ứng dụng: Hành trình triển khai CI/CD cho mobile team nhỏ


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 

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

 

➔ Copy token vừa tạo (lưu ý, token này chỉ hiển thị 1 lần nên nhớ lưu kỹ)
  • 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: 
- Key: GITHUB_TOKEN
- Value: Token từ GitHub ở bước trên
- Chọn Masked
  • Tiếp theo, setup .gitlab-ci.yml
    • Tạo file .gitlab-ci.yml 

Ảnh màn hình 2025-06-11 lúc 13.44.15

Cuối cùng, setup runner để chạy mirror
  • 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):

Ảnh màn hình 2025-06-11 lúc 13.47.35

 

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

Ảnh màn hình 2025-06-11 lúc 13.51.20

  • Repo này sẽ được sử dụng bởi fastlane match để lưu:
    • Distribution certificate
    • Provisioning profile

Tạo bundle ID cho app test, ví dụ: com.sanan.setup.cicd

 

Ảnh màn hình 2025-06-11 lúc 13.57.31

Ảnh màn hình 2025-06-11 lúc 14.01.58

 

Ảnh màn hình 2025-06-11 lúc 14.03.43

 

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

Ảnh màn hình 2025-06-11 lúc 14.05.39

  • 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:

Ảnh màn hình 2025-06-11 lúc 14.07.02

Ảnh màn hình 2025-06-11 lúc 14.15.45

  • Tiếp theo, mở Appfile:

Ảnh màn hình 2025-06-11 lúc 14.20.59

  • Tiếp theo, mở Matchfile: Sửa git_url và username tương ứng của bạn

Ảnh màn hình 2025-06-11 lúc 14.22.19

  • 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>"

Sau đó chạy: bundle exec fastlane beta_prod

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

Ảnh màn hình 2025-06-11 lúc 14.23.58

  • 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:

Ảnh màn hình 2025-06-11 lúc 14.25.04

Ảnh màn hình 2025-06-11 lúc 14.25.50

Ảnh màn hình 2025-06-11 lúc 14.26.12

  • Cuối cùng, push code lên và testing thôi. Hãy vào tab Actions nhé.

Ảnh màn hình 2025-06-11 lúc 14.27.05

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.

Written By: SanAn