• Pgyer document center

    使用 Travis CI 實現持續集成 (iOS)

    這篇文章將會給大家介紹如何在 iOS 項目中使用 Travis CI ,并將 App 簽名后發布到蒲公英。

    關于 Travis CI 產品分類

    Travis CI 是目前比較流行的持續集成工具之一,用來構建及測試在 Github 托管的代碼,使用它可以極大的簡化工作流程。Travis CI 產品分為:

    1. Travis CI.org (用于Github開源項目的免費產品)
    2. Travis CI.com (用于私有項目的付費產品)

    注:本文中介紹的Demo是基于(Travis-ci.org)

    準備工作

    需要在本地安裝 Travis CI 命令工具。

    1. 確保本地系統配置 Ruby 1.9 以上版本:

      ruby -v
      
    2. 安裝Travis-CI (如果使用 Mac OS 最好先更新 Ruby 到最新版本,然后再安裝)

      gem install travis --no-rdoc --no-ri
      
    3. 驗證 Travis 是否安裝成功 (有版本輸出則說明安裝成功)

      travis -v
      1.8.8
      
    4. 登錄 Travis。在命令行中,使用 GitHub 賬號登錄

      travis login 
      

      登錄后,可以用

      travis accounts
      

      來驗證賬號是否成功登錄。

    集成步驟

    一、啟用Travis CI

    通過 Github 賬號登錄 Travis 平臺。Travis 會自動同步Github賬號上所有的開源項目。通過列表選擇需要啟動的項目。

    添加項目

    二、創建Travis CI構建

    1. 在工程根目錄下添加 .travis.yml文件。這個文件用于說明 Travis CI 需要處理的構建。
    • Travis CI 本身提供基本的構建和支持語言,同時開發者可以通過.travis.yml文件設置自己的構建操作,同時需要遵從 Travis CI 自己規定的構建生命周期。具體可查閱這里

    • 在完成 .travis.yml 定義后, 可以通過 travis lint [path to your .travis.yml] 命令驗證這個文件語法是否正確性。如果正確會出現以下的提示:

      驗證構建文件

    1. 配置 iOS 工程基本模板,在 .travis.yml 中定義以下內容:

      language: objective-c
      osx_image: xcode9
      

      如果你只是想使用 Travis CI 的構建功能,那么這兩行已經足夠了。在你把.travis.yml Push 到 Github 上之后,Travis CI 就會自動開始 Build 流程,在 Build 完成之后,Github 綁定的郵箱就能收到通知。當然,對蒲公英的用戶來說,只是 Build 是不夠的,我們還希望能夠對 App 進行打包,簽名,并發布到蒲公英平臺上。

    三、配置項目:

    在使用 Travis CI 需要我們修改兩處項目配置,否則的話,會導致 Build 失敗。

    1. 將項目的 scheme 管理方式改成 shared:

    1. 關閉 bitcode 選項:

    四、打包簽名并上傳至蒲公英

    為了對 App 進行簽名,我們必須得配置好證書和配置文件。

    1. 蘋果全球開發者關系認證

    蘋果官網下載證書,或者從鑰匙串中導出。并將其保存到項目的目錄 travis/certificates/AppleWWDRCA.cer 中。

    2. 導出發布證書和私鑰

    鑰匙串程序中選中證書分別導出證書和私鑰。

    切記:不要上傳沒有加密的證書和描述文件到 GitHub 的公開倉庫(下文會講如何加密)

    將證書和和 p12 文件放在 travis/certificates/sdk_demo.certravis/certificates/sdk_demo.p12 。導出 p12 文件的時候要輸入密碼。

    Travis CI 在使用 p12 文件的時候需要知道密碼,而我們又不能將密碼明文保存在某個地方,所以這個時候我們可以使用到 Travis CI 的安全環境變量功能。

    打開終端,定位到.travis.yml文件所在的目錄,用下列命令來保存 p12 文件的密碼。

    travis encrypt "KEY_PASSWORD=123456" --add

    這其中的123456就是你導出 p12 文件時輸入的密碼。在輸入了這條命令之后我們就會發現.travis.yml多了一行數據

     - secure: xJz9E1EJdBDAIZcNaz86a7nrJpbdPHS3xiXU5L4Gj4rFR0TcxHsHuu2dcZR/yRJRHg6oum2zuMr0XBsSffMBYFHX5Kw2jb31Ci6uFbOTI/FGBrwdvfhQBL+h/7xe/j3l1bmbmfElYP02fiJvN5VSVyA0    3Iobp7u3vY0TW7yce+po23DmJCTYgnUdfuf4EBO3gpgbOTPdmIxqyhqqw5Ndwmvxpq9BqneqEc3pmNCC1FC6H4RmgjkWnMln5ffWIxNN+nwgPzSDqHDMUnQaYtVUU/CHLQCmNCgQmkrG/OWYvlo4RqpEX6VZv5BUa6gD    7d4lgcfXHONkmLKNbiWBGDRbbBQNNSbubTtGlyGtzCHwEe4KvHoM4n0yDZqtd9edgrxlOSuBgNlQK+/3C6BhZZi2rWNlnqBU7F/ZSmjBONWgRuFZJ2zJByHWLoTTOHvYbFdk4CTmT5qMQPQ7favMu1L9TUBpbX4qBX4D    iXpEKNODtwOvdYjlfiZ+US6i637JeZF8OK9bBtUf4oKjvl1Oz5ly56snTBknF3V+if6VoHlG1Cfroqhy2F7ahS2K3Aq0u4O2gMIVqTRd1juBLo6QkzV/F+go4KvYDwOFpAX05AYrJNOQgAHae5a8Px2YIct1QcRTL++r    Enqx1QzQWXIEXpezm8m1pR8TcB8d2WbLGtwTd/8=
    

    這行數據就是通過上述命令安裝到.tarvis.yml文件中的環境變量KEY_PASSWORD,在后續打包的過程中,Travis 就可以通過引用KEY_PASSWORD來使用 p12 文件對應的密碼。

    3. 描述文件

    簽名打包的時候,我們還需要用到 .mobileprovison 描述文件。描述文件可以在在蘋果開發者網站上創建和下載(Provisioning Profiles > Distribution > Add > Ad Hoc or In House)。將下載后的文件保存在travis/certificates/sdk_demo.mobileprovision

    同時,我們還需要將對應的,描述文件的文件名,App 名稱,開發者名稱都保存在 .travis.yml 文件中:

    env:
      global:
      - APPNAME="PgySDKDemo"
      - 'DEVELOPER_NAME="iPhone Distribution: your developer name (your developer code)"'
      - PROFILE_NAME="sdk_demo"
    

    4. 加密證書和配置文件

    如果使用的是 GitHub 的公開倉庫,我們還需要對證書,配置文件,私鑰這些敏感文件進行加密。加密了之后,我們還需要告訴 Travis CI 如何去解密這些文件。

    1. 加密

    Travis 在解密時只支持單文件,所以,我們還需要在加密前把證書和配置文件打包成一個壓縮包。

    tar cvf certificates.tar sdk_demo.cer sdk_demo.p12 sdk_demo.mobileprovison
    

    運行完命令之后,就會發現,文件目錄中多了一個 certificates.tar的文件,我們把這個文件放到項目的根目錄下。然后在項目的根目錄下運行命令:

    travis encrypt-file certificates.tar -a
    

    對壓縮后的證書和配置文件進行加密。-a 參數的作用是自動的把解密文件的指令添加到.travis.yml文件中。運行完指令后,我們會得到一個名為 certificates.tar.enc的加密文件。這個時候,就可以把未加密的 certificates.tartravis/certificates 文件夾目錄下的 sdk_demo.cer sdk_demo.p12 sdk_demo.mobileprovison這四個文件刪除掉。

    1. 解密

    運行完加密命令后,我們還會發現 .travis.yml 文件中多了一行:

    - openssl aes-256-cbc -K $encrypted_2838d02a56a6_key -iv $encrypted_2838d02a56a6_iv
      -in certificates.tar.enc -out certificates.tar -d
    

    這一行的作用就是解密證書文件。需要注意的是,解密之后的文件仍然是一個壓縮包,我們需要將壓縮包解壓縮。

    before_install:中添加下列代碼:

    - tar xvf certificates.tar -C ./travis/certificates
    

    5.導入鑰匙串

    為了進行簽名打包,我們還需要將證書導入到 Travis CI 運行環境的鑰匙串中。為了導入鑰匙串我們在 scripts文件夾中添加一個名為add-key.sh的文件。下面是add-key.sh的全部內容:

    #!/bin/sh
    # Create a custom keychain
    security create-keychain -p travis ios-build.keychain
    security default-keychain -d user -s ios-build.keychain
    security unlock-keychain -p travis ios-build.keychain
    security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain
    
    security import ./scripts/travis/AppleWWDRCA.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
    security import ./scripts/travis/sdk_demo.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
    security import ./scripts/certs/sdk_demo.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASSWORD -A
    
    echo "list keychains: "
    security list-keychains
    echo " ****** "
    
    echo "find indentities keychains: "
    security find-identity -p codesigning  ~/Library/Keychains/ios-build.keychain
    echo " ****** "
    
    mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
    cp "./scripts/profile/sdk_demo.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
    

    通過add-key.sh這個腳本,我們創建了一個名為 ios-build 的臨時鑰匙串。臨時鑰匙串里包含了所有的證書信息。其中 $KEY_PASSWORD就是在引用 p12 文件的密碼。通過這個腳本創建的臨時鑰匙串,還需要在我們完成了簽名打包之后刪除掉。

    為了保證腳本能夠正常運行,我們還需要給腳本設置可執行權限:

    before_install:
     - chmod +x scripts/travis/add-key.sh
    

    6. 打包

    在 Xcode 8.2 以前廣泛使用的打包工具 xctool 現在已經不能使用了,我們只能通過 xcodebuild 來打包,打包分為兩步:Archive 和 簽名。打包腳本如下:

    #!/bin/sh
    xcrun xcodebuild -project PgySDKDemo.xcodeproj -scheme PgySDKDemo \
      -archivePath PgySDKDemo.xcarchive archive
    
    xcrun xcodebuild -exportArchive -archivePath PgySDKDemo.xcarchive \
      -exportPath ./build -exportOptionsPlist ExportOptions.plist
    

    這其中需要一個-exportOptionsPlist 文件,獲取這個文件最簡單的方式就是通過使用 Xcode 導出一個 ipa ,在導出的 ipa 所在的文件夾中就有一個 ExportOptions.list。我們把這個文件放在項目的根目錄中就可以了。

    運行完打包腳本之后,我們就可以在項目的 ./build 目錄下找到簽名好的 ipa 文件了。

    7. 上傳蒲公英

    我們已經寫好了一個上傳 ipa 文件的 shell 腳本。你只需要在 before_install: 中下載該腳本,并給與該腳本執行權限,并在打包完成之后調用該上傳腳本。

    - wget -c https://raw.githubusercontent.com/Pgyer/TravisFile/master/pgyer_upload.sh
      -O pgyer_upload.s
    
    #!/bin/sh
    ./pgyer_upload.sh "./build/$APPNAME.ipa" $PGYER_APIKEY
    

    上傳的時候,需要用到蒲公英的 API_KEY, 你可以在這里找到你的 API_KEY。由于 API_KEY 不能明文保存,所以我們通過使用和保存密碼一樣的方式,把它安裝到 .travis.yml文件中。打開終端,定位至項目的根目錄,在命令行中輸入:

    travis encrypt "PGYER_APIKEY=655b39fe4bad7a701bd44dfbcafdcc2f" --add
    

    8. 清理鑰匙串

    在所有環節都結束后,我們還需要刪除掉導入的鑰匙串信息。我們在 /scripts/travis 文件夾下添加一個新的文件 remove-key.sh :

    #!/bin/sh
    security delete-keychain ios-build.keychain
    rm -f ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_NAME.mobileprovision
    rm -f ~/Library/MobileDevice/Provisioning\ Profiles/team.mobileprovision
    

    完成上述工作之后,每次我們新上新代碼到 GitHub 都會觸發 Travis CI 的持續集成,并將打包簽名后的 App 發布到蒲公英上。

    一個完整版的 .travis.yml 文件如下所示:

    language: objective-c
    osx_image: xcode9.2
    env:
      global:
      - APPNAME=PgySDKDemo
      - PROFILE_NAME=sdk_demo
      - 'DEVELOPER_NAME="iPhone Distribution: shengtao lei (DG37YK9PRK)"'
      - secure: iL2KhNdYKzWLTtvaXmmQ3/ci66b0Z5c8VCTmpaoMIotdtwyTOgMnpzH+Vyrof3QBH/nV2oF6puT/b5Y6S6lrCY5b4nZSfhy8xL6FEPDboVzpq2qIAS4gn6qCGUkIkAxpcnKG9sbcxDsI5aLVOqxoevuHKB2Rkw925TWrg6+bfagtWQzVvkByIHT2jm2+7bkmNUx7UiIggNYN+H2ACpfdf/d9g7lC7w2hLb6hO0Mt5pK5eGbzlh8kn/1CnX7jSWw3SyEABEJ3CQOZX5x/yNP4oIJLgdEGW3sy1ErAi2uO+i89VDu1SaRcDLbNuAmlxb95dLVBVU7uWILdWTh6+o6FVL2Eoj1YPrNBJdcRykTvaCSR1eXPs6uCoq9tcWz0zinamSBzemOjdK+G+lOC6IpT9lTimt5Ln0lGQoVYERXnvJMEhR/2rFLvsTIqd+Wt8Agfqr9EeU0ah8agWiTIE6EuA0xdTyC0EyKVYKzXBy4wI6R2fknfn6uHyeFeIN9zpWY8tcwz8pRLDD+xiyoHgSybS1DK+Xr21llOopXkC/aacnoeslciNN28In9QRDwsiDUSlAb6dQ3pRCS/cDoRJBm759xcZ7kdMnwVAcSX7aZ9p8HT0uGvyuJdYNDr4vp0r98RtPI/7JonPXqXuWzsAzZdq5AAzchwNFAbTCrASw6qqHY=
      - secure: KuD0JYZqJEtezCBkJ6Zkfw7I+0VGiv6E7GOa34KUzYsJWpLnzPYB08+NsYZYMh6Yjc8pkC8+MixgXLOHupWm5v3iRthWqD/tdmuF5bdQqIdrWkmQSl0cK9M+rMgc+vaPajguC0/yf+BoPWL6CJXouLLzj3D6IXUwZEVYhmPB4nBv/YHVk/FNwNS4aqP9SSp98VQoYrAGAvUSY3jm5L1qSNwCjPMBcX4QnlbX5mjl0mEf0pEbJ3ZZAz9AzpALfCYR4pPsS7/eSHxVAPNboD5JVQAK6NhaFCTUw0/UlGHW9m9eY3AezMpZo1M8kHXZXsC0BWoP8R4H6WYTybILxz6Aramb8N12R+ntLfAawnFnG5kV4mtUHFY7BqNu+tyBkba4axkclaY90fETekHUcCIqTlVmMjlKq6dzWkq4hGmDtEajajZHqMPBUMy5o8n8lXKww/ZkpvgEhrJjbxbmFcoP4oS2u9Vxi/Q18t+mRoQhGfan2cVQXdpQhk0S8scisVVnUSFHSglt79KjgKwNuVKtIpW89bG8HHQaqIgPFycvIbDRxSM6Xd+I7AIzz25XFdE/ao03ULrnDaIZLbgUa+IGjDknkRJmG9hFQKO2grkZ/JqNXQDSMEIXZrH46CocD1+j39k6wvYler5fdcIStf+wAW4hXmiO0en2hl2+qEFtJds=
      - secure: YecGZLdjxnbJuIyJOywDan2lJ4sToYx2iq8ficMEzODXUxEGHRL6s6XFOPltsm6CnyUZKfT9bzAEWuGWnnES8fcPvMUAKvyNhcRW/D9JtMm/fboIdSjb2Ht8f/dY1IfgB241pMU7SkPifVIL08yxeMYZfwgFxbDQn60aXCiUKWuEcqMgxX2yLX9uHR+T/xuY6E+NX6UEB/6imx3rQ047nVfefMgh9YMGGl0ZH/N9beZgMrwlZn1lAfKMrkbJ3vw1go2RzxnDwa/Noy+6eKfbC8R4RgCvwQ6oXBEXG1IUjHbiNhR5pXajz/5jbum9T64fHUrx8e2aPKrYRWWjooQ5Q7+AER7PnAhTgFymHhDwUm7wEXoMuh5Ltp7jCNZiaKDxUoONw4Hz+oEXKbm4nYJCMFczjW4bQKH0gqNytPhl/y/08u0fuQxTP3wu6Zi0q0qo6e3eqCTGv3Q9YzEm7JWAb6RSO09aRRVvz7HwdZFwbHy07T9//YMUsX/chhw7fziso1wkutWOsVCfBVjMGO6Nve/B8xdCVV4sqiex/Wk3c/cNHB7dTVe9SC6nelrkuyvEqKtxk87/IDBo0sAHxounw9phwtXg+RM8fN+rvBqd9rY4H8hrRaZKdFqikMt3yexoFKcrAqbQuHEDVlz2dxDxZhgjOPyVaejsOHI2jt1bB58=
    before_install:
    - openssl aes-256-cbc -K $encrypted_2838d02a56a6_key -iv $encrypted_2838d02a56a6_iv
      -in certificates.tar.enc -out certificates.tar -d
    - cd $TRAVIS_BUILD_DIR
    - wget -c https://raw.githubusercontent.com/Pgyer/TravisFile/master/pgyer_upload.sh
      -O pgyer_upload.sh
    - tar xvf certificates.tar -C ./travis/certificates
    - chmod +x pgyer_upload.sh
    - chmod +x travis/scripts/add-key.sh
    - chmod +x travis/scripts/build.sh
    - chmod +x travis/scripts/upload.sh
    - chmod +x travis/scripts/remove-key.sh
    before_script:
    - "./travis/scripts/add-key.sh"
    script:
    - "./travis/scripts/build.sh"
    after_success:
    - "./travis/scripts/upload.sh"
    after_script:
    - "./travis/scripts/remove-key.sh"
    

    結語

    本文介紹了如何使用 Travis CI 對 iOS 項目進行持續集成,并把打包簽名后的 App 上傳到蒲公英。希望對你能有所幫助。對應的 Demo 項目你可以在GitHub上找到。

  • 红豆视频