Skip to content
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Fx Studio
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Written by chuotfx on September 16, 2019

Trigger build iOS Application với Travis CI

Tutorials

Contents

  • 1. Bài toán đặt ra
    • 1.1. Phân tích yêu cầu
    • 1.2. Các công việc chúng ta cần làm
  • 2. Cấu hình Project và Fastlane
    • 2.1. Project
    • 2.2. Fastlane
  • 3. Trigger
  • Tổng kết

Mọi thứ đã hoạt động một cách trơn tru rồi nhưng để thực sự thông minh hơn và tiện lợi hơn thì máy CI sẽ tự động build đúng theo cấu hình tương ứng với với những cài đặt của mình. Và đây cũng làm phần cuối trong seri mệt mỏi này.

1. Bài toán đặt ra

a) khi merge 1 pull request vào nhánh develop thì build môi trường dev gởi QCs 1 bản thông qua fabric
b) khi merge develop vào master thì tự động build môi trường stag gởi PMs
c) khi tạo branch release/* (ví dụ release/build) thì sẽ tự động build 1 bản production file *.ipa để đó, không up lên đâu hết.
(Các nhóm QCs, Pms được tạo trong Fabric)

1.1. Phân tích yêu cầu

    • Cần 3 bản build với 3 cấu hình khác nhau
      • Dev
      • Staging
      • Product
    • Theo dõi các hoạt động của GitHub bằng CI
      • Pull Request
      • Commit
      • Push Branch
    • Phân tích xác định được các tên Branch
      • master cho Staging
      • develop cho Dev
      • release/* cho Product

1.2. Các công việc chúng ta cần làm

    • Cấu hình lại project và lane để build được theo các config (đã tạo ở phần này)
      • Dev
      • Staging
      • Release
    • Bắt được các trigger của Travis CI để chon lên build fastlane tương ứng
    • Code xử lý các trigger đó

2. Cấu hình Project và Fastlane

2.1. Project

  • Về project trong Xcode thì bạn cần tuỳ chỉnh lại các cấu hình
    • Develop : auto signing để build
    • Staging : thì build manual, Xcode sẽ tự chọn cấu hình tương ứng trong Certificate và Provisioning
    • Release : tương tự như Staging
  • Với phần 1 thì mình mới chỉ hướng dẫn mỗi 1 việc tạo các file Config để cấu hình chứa chưa đi vào hướng dẫn cấu hình từng cái như thế nào. Sau đây là cấu hình đề nghị cho mọi người có thể dễ làm theo.

  • Giải thích
    • Debug thì sẽ là auto theo iOS Developer, certificate và provisioning sẽ tự nhận theo config trong Xcode
    • Staging thì sẽ là manual cho iOS Distribution, chỉ định rõ provisioning AdHoc. Còn certificatie sẽ được import từ ngoài vào máy MAC OS
      • Trên máy local là kích bằng tay và nó sẽ vào Keychain
      • Trên máy Travis thì mình dùng lệnh để import vào máy thông qua Keychain tự tạo
    • Release thì tương tư Staging, hoặc có thể cấu hình khác một chút nếu khách hàng muốn build cho AppStore…

2.2. Fastlane

  • Trước tiên chúng ta cần test lại các cấu hình ở local để xem fastlane hoạt đồng hiệu quả hay không.
  • Chú ý:
    • scheme
    • configuration
    • export_method (tham khảo sau)
      • app-store
      • ad-hoc
      • package
      • enterprise
      • development
      • developer-id
desc "Build App AdHoc Local"
  lane :build_adhoc_local do
    make_build_folder
    build_ios_app(
      scheme: "TheLastProject_Staging", 
      workspace: "TheLastProject.xcworkspace",
      configuration: "Staging", 
      export_method: "ad-hoc",
      output_directory: "./build",
      output_name: "TheLastProject_Staging.ipa",
      silent: true,
      clean: true
    )
  end
  • ​ Tiến hành build chạy trên local và tận hưởng kết quả. Nếu gặp lỗi thì bạn hãy bình tỉnh và xem lại các config trong Xcode và edit lại cho đúng.
bundle exec fastlane build_adhoc_local
  • ​ Cần chú ý là bạn phải import các cetificate (development & distribution) vào máy trước đã. Nếu Terminal chạy ra như thế này thì fastlane đã chọn đúng cấu hình.

  • Áp dụng cho các config còn lại
  • Fastlane cho build trên máy CI, tham khảo 2 đoạn code sau và chú ý các config để sao cho đúng
    • Build Staging
desc "Build Staging"
  lane :build_staging do
    make_build_folder
    disable_automatic_code_signing(
      path: "TheLastProject.xcodeproj"
    )
    import_certificate(
      keychain_name: "ios-build.keychain",
      keychain_password: ENV["KEYCHAIN_PASS"],
      certificate_path: "./scripts/certs/dis.p12",
      certificate_password: ENV["CERT_PASS"]
    )
    update_project_provisioning(
      xcodeproj: "TheLastProject.xcodeproj",
      profile: "./scripts/profiles/TheLastProject_AdHoc.mobileprovision",
      target_filter: "TheLastProject",
      build_configuration: "Staging",
    )
    build_ios_app(
      scheme: "TheLastProject_Staging", 
      workspace: "TheLastProject.xcworkspace",
      configuration: "Staging", 
      export_method: "ad-hoc",
      output_directory: "./build",
      silent: true,
      clean: true,
      skip_profile_detection: true,
      export_options: {
        provisioningProfiles: { "com.fx.thelastproject": "TheLastProject_AdHoc" }
      }
    )
    create_release_notes(format: 'Appstore: %h %s')
    upload_fabric(groups: "staging")
    enable_automatic_code_signing(
      path: "TheLastProject.xcodeproj"
    )
  end
    • Build Release
desc "Build Release"
  lane :build_release do
    make_build_folder
    disable_automatic_code_signing(
      path: "TheLastProject.xcodeproj"
    )
    import_certificate(
      keychain_name: "ios-build.keychain",
      keychain_password: ENV["KEYCHAIN_PASS"],
      certificate_path: "./scripts/certs/dis.p12",
      certificate_password: ENV["CERT_PASS"]
    )
    update_project_provisioning(
      xcodeproj: "TheLastProject.xcodeproj",
      profile: "./scripts/profiles/TheLastProject_AdHoc.mobileprovision",
      target_filter: "TheLastProject",
      build_configuration: "Release",
    )
    build_ios_app(
      scheme: "TheLastProject_Release", 
      workspace: "TheLastProject.xcworkspace",
      configuration: "Release", 
      export_method: "ad-hoc",
      output_directory: "./build",
      silent: true,
      clean: true,
      skip_profile_detection: true,
      export_options: {
        provisioningProfiles: { "com.fx.thelastproject": "TheLastProject_AdHoc" }
      }
    )
    create_release_notes(format: 'Appstore: %h %s')
    upload_fabric(groups: "release")
    enable_automatic_code_signing(
      path: "TheLastProject.xcodeproj"
    )
  end

Nếu kết quả chạy trên máy CI không được đúng như mong muốn thì cần bình tĩnh lại. Giải quyết từng lỗi một. Khi mọi thứ hoàn hảo thì mới tiến hành sang bước tiếp theo được.

3. Trigger

  • Muốn cho máy CI có thể chọn đúng cấu hình để build thì chúng ta cần phải bắt được và xử lý được các thông tin sau:
- Tên branch
- Kiểu tương tác
  - Commit
  - Push
  - Pull Request
  - Merge
  • Các thông tin đó thì Travis đã hỗ trợ bạn trong các biến môi trường (environment-variables) của nó. Đọc thêm tại đây.
  • Kiểm tra các config trong setting của Travis đã ổn chưa
    • Build pushed branches : on
    • Build pushed pull requests : on
  • Thử với việc kiểm tra các pull request đúng với 2 branch
    • develop thì sẽ build cho môi trường Dev
    • master thì sẽ build cho môi trường Staging
  • Mở file .travis.yml và edit đoạn script sau:
script:
  - ./scripts/lint
  - if [[ "$TRAVIS_BRANCH" == "develop" ]]; then bundle exec fastlane build_dev; fi
  • ​ Tạo branch develop commit code và tận hưởng cái kết.
  • Giải thích
    • Đoạn script trên:
      • Sử dụng biến muôi trường
      • Vài dòng if else cơ bản
      • Bạn có thể sử dụng cho master
  • Tuy nhiên, với việc build cho môi trường Release thì có yêu cầu là khi tạo 1 branch với tên là release/* thì Travis sẽ tự động chạy và build. Công việc chúng ta còn 2 việc
    • Lấy đúng tên branch
    • Xử lý chuỗi để biết là có chữ release hay không
    • Tham khảo : https://stackoverflow.com/questions/2172352/in-bash-how-can-i-check-if-a-string-begins-with-some-value
  • Bash cách bá hơn để lấy được tên branch hiện tại.
script:
  - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
  - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
  • Sau khi đủ các điều kiện và biến thì bạn hãy viết 1 script riêng cho việc build app này. Đây là đoạn code tham khảo, mình tạo file shell bash với tên là run
    • Lấy được current branch
    • Xử lý đc chuỗi
    • Khuyên bạn là nên test đoạn script này ở local (xoá các dòng lệnh build, để lại lệnh echo)
#Log debug branch
BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"

if [ "$TRAVIS_BRANCH" == "develop" ]
then
  echo "********** BUILD DEV **********"
  bundle exec fastlane build_dev
elif [ "$TRAVIS_BRANCH" == "master" ]
then
  echo "********** BUILD STAGING **********"
  bundle exec fastlane build_staging
elif [[ "$TRAVIS_BRANCH" == "release"* ]]
then
  echo "********** BUILD RELEASE **********"
  bundle exec fastlane build_release
else
  echo "NOTHING"
fi
  • Sau khi đã OK thì bạn commit code và tiến hành test theo các trường hợp mà yêu cầu đề ra
    • Tạo branch develop , tạo tiếp branch con từ nó, edit và gởi pull request
    • Merge develop về master
    • Tạo branch release/* từ master
  • Bạn kiểm tra các bản build đã được upload lên Fabric hay chưa. Nếu còn lỗi thì hãy fix nó. Nếu oke hết thì chúc mừng bạn đã hoàn thành seri mệt mỏi này
  • Phần tiếp theo mà bạn cần làm
    • Làm đẹp code
    • Build matrix
    • Config với các dịch vụ CI khác

 

Tổng kết

  • Cấu hình để fastlane build được với các config khác nhau của iOS Project
  • Tạo các trigger để có Travis CI biết lúc nào nên build cho môi trường nào
  • Cấu hình cho CI tự động build và gởi cho các môi trường tương ứng.
FacebookTweetPinYummlyLinkedInPrintEmailShares4

Related Posts:

  • testing
    Hello Testing iOS
  • feature_bg_3
    Clean Architecture trong iOS
Tags: ci/cd, Trigger
Written by chuotfx

Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Donate – Buy me a coffee!

Fan page

Fx Studio

Tags

Actor Advanced Swift AI api AppDistribution autolayout basic ios tutorial blog ci/cd closure collectionview combine concurrency crashlytics dart dart basic dart tour Declarative delegate deploy design pattern fabric fastlane firebase flavor flutter GCD gradients iOS MVVM optional Prompt engineering protocol Python rxswift safearea Swift Swift 5.5 SwiftData SwiftUI SwiftUI Notes tableview testing TravisCI unittest

Recent Posts

  • [Swift 6.2] Raw Identifiers – Đặt tên hàm có dấu cách, tại sao không?
  • Vibe Coding là gì?
  • Cách Đọc Sách Lập Trình Nhanh và Hiệu Quả Bằng GEN AI
  • Nỗ Lực – Hành Trình Kiến Tạo Ý Nghĩa Cuộc Sống
  • Ai Sẽ Là Người Fix Bug Khi AI Thống Trị Lập Trình?
  • Thời Đại Của “Dev Tay To” Đã Qua Chưa?
  • Prompt Engineering – Con Đường Để Trở Thành Một Nghề Nghiệp
  • Vấn đề Ảo Giác (hallucination) khi tương tác với Gen AI và cách khắc phục nó qua Prompt
  • Điều Gì Xảy Ra Nếu… Những Người Dệt Mã Trở Thành Những Người Bảo Vệ Cuối Cùng Của Sự Sáng Tạo?
  • Khi Cô Đơn Gặp Python

You may also like:

  • Clean Architecture trong iOS
    feature_bg_3
  • Hello Testing iOS
    testing

Archives

  • May 2025 (1)
  • April 2025 (1)
  • March 2025 (8)
  • January 2025 (7)
  • December 2024 (4)
  • September 2024 (1)
  • July 2024 (1)
  • June 2024 (1)
  • May 2024 (4)
  • April 2024 (2)
  • March 2024 (5)
  • January 2024 (4)
  • February 2023 (1)
  • January 2023 (2)
  • November 2022 (2)
  • October 2022 (1)
  • September 2022 (5)
  • August 2022 (6)
  • July 2022 (7)
  • June 2022 (8)
  • May 2022 (5)
  • April 2022 (1)
  • March 2022 (3)
  • February 2022 (5)
  • January 2022 (4)
  • December 2021 (6)
  • November 2021 (8)
  • October 2021 (8)
  • September 2021 (8)
  • August 2021 (8)
  • July 2021 (9)
  • June 2021 (8)
  • May 2021 (7)
  • April 2021 (11)
  • March 2021 (12)
  • February 2021 (3)
  • January 2021 (3)
  • December 2020 (3)
  • November 2020 (9)
  • October 2020 (7)
  • September 2020 (17)
  • August 2020 (1)
  • July 2020 (3)
  • June 2020 (1)
  • May 2020 (2)
  • April 2020 (3)
  • March 2020 (20)
  • February 2020 (5)
  • January 2020 (2)
  • December 2019 (12)
  • November 2019 (12)
  • October 2019 (19)
  • September 2019 (17)
  • August 2019 (10)

About me

Education, Mini Game, Digital Art & Life of coders
Contacts:
contacts@fxstudio.dev

Fx Studio

  • Home
  • About me
  • Contact us
  • Mail
  • Privacy Policy
  • Donate
  • Sitemap

Categories

  • Art (1)
  • Blog (43)
  • Code (11)
  • Combine (22)
  • Flutter & Dart (24)
  • iOS & Swift (102)
  • No Category (1)
  • RxSwift (37)
  • SwiftUI (80)
  • Tutorials (86)

Newsletter

Stay up to date with our latest news and posts.
Loading

    Copyright © 2025 Fx Studio - All rights reserved.