+7

CI/CD cho Mobile App | Auto build Mobile App bằng CodeMagic ✨

Lời chúc

Như thường lệ lướt Viblo, mình thường không để ý tới cái header đầu trang cho lắm 😀 Nay nhân ngày vừa mới được nghỉ việc mà chưa tìm được việc mới, tiện nhìn thấy cái header của Viblo có đăng tải event viết khai bút đầu xuân (đúng ý trời đã định) nên tham gia cho vui, nhân tiện cũng là lần đầu mình viết blog/ guide lên mạng, có gì sai sót hay lủng củng mong anh em góp ý để mình sửa chữa nhé. Giống như mọi bài viết khác tham gia event này, lời đầu tiên mình chúc những người đang đọc bài viết này thật nhiều sức khoẻ ( alway first thing 😀), hạnh phúc bên gia đình và người thân bạn bè, công việc thật thuận lợi nhé. Qua đó cũng cảm ơn đội ngũ của Viblo đã tạo ra sân chơi bổ ích và những sự kiện rất ý nghĩa cho cộng đồng

Mở đầu

CI/CD là gì?

Khái niệm CI (Continuos Integration) hay CD (Continuous Delivery - chuyển giao liên tục) chắc cũng không còn xa lạ với anh em dev. Theo cách văn vở thì nó là quá trình tích hợp và sử dụng các công cụ làm việc liên tục và tự động hoá của phần mềm vào vòng đời phát triển của sản phẩm. Còn theo cách dân dã, đây là quá trình tự động build, test, deploy web (đối với FE/BE) hoặc build app, deploy app lên chợ ứng dụng (đối với Mobile App) chỉ với 1 nút nhất (hoặc trigger vào hành động on push của Git). Hiện nay, CI CD trở thành điều hiển nhiên sẽ có trong quá trình phát triển phần mềm. CI-CD-la-gi-1.png

Mục đích và hạn chế

Như đã nói ở trên thì CI/CD được ứng dụng rất nhiều vào quy trình tự động hoá phát triển phần mềm. Hoặc chúng ta có thể tự build cài đặt cho Android/ iOS từ những dự án open source mà không cần kiến thức về lập trình Mobile chẳng hạn. Cái này khá hay với anh em non-tech vì có rất nhiều dự án mobile open-source hay ho (Youtube Vanced là 1 ví dụ), sau khi build ra file apk hoặc file ipa (dùng AltStore để cài đặt lên macOS, cái này nếu mọi người quan tâm mình sẽ lên 1 bài nữa sau) cài trực tiếp trên device luôn.
Hạn chế lớn nhất là dùng nhiều sẽ tốn phí. Với mỗi nhà cung cấp dịch vụ CI/CD thì mức phí sẽ khác nhau. Nếu dùng CodeMagic thì sẽ được free 150 tiếng mỗi tháng, khá là tẹt ga. Ở đây có 1 tips nhỏ là dùng hết 150 tiếng thì tạo tài khoản khác để xài free 😁
Hạn chế thứ 2 nữa là khá là khó để cấu hình với nhiều dự án quá phức tạp (nhiều môi trường,...)

Chuẩn bị

Giới thiệu về CodeMagic

Như tiêu đề bài viết, chúng ta sẽ chỉ đi vào CI/CD trên Mobile App (hoặc do mình không biết làm FE/BE 😁). Hiện nay có rất nhiều nhà cung cấp đã hỗ trợ việc này, có thể kể đến như Github Action, Bitrise, Gilab CLI,... (nếu mọi người quan tâm mình sẽ lên 1 bài nữa). Tuy nhiên ở bài viết này chúng ta sẽ sử dụng đến CodeMagic. Chắc hẳn anh em code Flutter nhiều có thể sẽ thấy cái tên này quen quen vì đây là nơi chia sẻ khá nhiều blog/ guide về Mobile App rất chi tiết, anh em có thể tham khảo thêm ở đây

Đăng kí và cấu hình Source Code

Để sử dụng thì for sure, chúng ta phải đăng kí tài khoản ở đây. Bước này mình xin phép skip nhé

Sau khi đăng nhập xong, chúng ta tiến hành thêm ứng dụng vào từ Git repo (Github, Gitlab, Bitbucket...). Ở đây mình sẽ demo add Github repo vào. Chọn Add application, sau đó chọn Github và chọn Github integration để cấp quyền read github repo cho CodeMagic
image.png Lưu ý là ở đây chỉ có thể add được những repo của mình, nên nếu repo nào không phải của mình thì anh em có thể fork nó về cho nhanh
Tiếp đến, chọn project type. Ở đây mình đang thử build 1 ứng dụng Flutter nên mình sẽ chọn Flutter và khi add thành công sẽ có kết quả như sau image.png

Cấu hình

Tiếp đến là phần quan trọng nhất của quá trình. Ở đây ta sẽ có 2 cách cấu hình

Cấu hình bằng Work Flow Editor

image.png Đây là cách cấu hình theo kiểu mì ăn liền khá là đơn giản. Như anh em có thể thấy trong ảnh trên, chúng ta chỉ cần tick và tick vào các mục như sau: Build for Platforms: Sẽ build ra file cài đặt cho những platform nào Run build on: Source code sẽ được build trên thiết bị nào. Ở đây theo mặc định ta sẽ build trên Mac Mini M1, những option còn lại đều phải nạp lần đầu (thêm banking info) để lựa chọn, có đầy đủ cả Linux, MacOS và Window.
image.png
Build trigger: Trigger hành động khi nào thì ứng dụng sẽ được build. Cái này tuỳ vào tính chất của work flow, nếu deploy lên môi trường testing thì thường sẽ trigger vào on push của nhánh dev hoặc staging. Còn nếu cấu hình để deploy thì sẽ trigger vào nhánh master của repo. image.png Environment variables: Thêm các biến env vào bản build
Build: Lựa chọn Flutter, XCode, CocoaPods version, lựa chọn chế độ build (debug, release hay profile), Android output format (apk hay aab), các tham số truyền vào khi build image.png Distribution: Cấu hình keystore, sign app để publish image.png Notification: Kênh thông báo, có thể thông báo qua email hoặc Slack khi build xong (ở đây có thể tự cấu hình webhook để bắn thông báo)

Cấu hình bằng file .yaml

Với 1 số project có cấu hình phức tạp hơn thì chúng ta cần phải cấu hình bằng file yaml. Tương tự như cấu hình như cách ở trên thì sử dụng file .yaml cũng sẽ có những mục tương tự nhưng ở mức độ advantage hơn.
Sau đây là đoạn workflow bằng file .yaml mẫu để chạy build được ra file cài đặt Android.

workflows:
  android-workflow:
    name: Android Workflow
    instance_type: mac_mini_m1
    max_build_duration: 120
    environment:
      groups:
        - google_credentials # <-- (Includes GCLOUD_KEY_FILE, GOOGLE_CREDENTIALS)
      vars:
        FIREBASE_PROJECT: "YOUR_FIREBASE_PROJECT_NAME" # <-- Put your Firebase Project Name here
      flutter: stable
      xcode: latest
      cocoapods: default
    scripts:
      - name: Set up debug.keystore
        script: |
          rm -f ~/.android/debug.keystore
          keytool -genkeypair -alias androiddebugkey -keypass android -keystore ~/.android/debug.keystore -storepass android -dname 'CN=Android Debug,O=Android,C=US' -keyalg 'RSA' -keysize 2048 -validity 10000
      - name: Set up local.properties
        script: |
          echo "flutter.sdk=$HOME/programs/flutter" > "$CM_BUILD_DIR/android/local.properties"
      - name: Get Flutter packages
        script: |
          flutter packages pub get
      - name: Build APK with Flutter
        script: |
          flutter build apk --debug
      - name: Create debug and test APK
        script: |
          set -ex
          cd android
          ./gradlew app:assembleAndroidTest
          ./gradlew app:assembleDebug -Ptarget="$CM_BUILD_DIR/integration_test/app_test.dart"
    artifacts:
      - build/**/outputs/**/*.apk
      - build/**/outputs/**/*.aab
      - build/**/outputs/**/mapping.txt
      - flutter_drive.log
    publishing:
      email:
        recipients:
          - user_1@example.com
          - user_2@example.com
        notify:
          success: true # To not receive a notification when a build succeeds
          failure: false # To not receive a notification when a build fails

Như anh em có thể thấy là khá là lằng nhằng để cấu hình được với những người không có kiến thức về lập trình, nên mình không recommend cách này cho lắm.

Kết quả

Sau khi build thành công sẽ có thông báo gửi về. File cài đặt sẽ được gửi kèm trong email hoặc build history, anh em chỉ việc tải file về và cài đặt trực tiếp (đối với Android) hoặc qua 1 chút thủ thuật khác (đổi với iOS).
image.png

Trên đây mình vừa hướng dẫn cơ bản tạo 1 workflow để build file 1 cách tự động, ở bài viết tiếp theo mình sẽ hướng dẫn về sign keystore, auto deploy lên CHPlay mỗi lần build. Nhấn upvote nếu thấy hấp dẫn để ủng hộ mình nhé 😘


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí