iOS 基於 launchctl + fastlane + 釘釘機器人實現定時自動打包

前言

做爲一個移動端程序員,每次 feature add 或者 bug fix 後常常要打包交付給 QA,之前傳統的操做都是手動點擊 Xcode -> Product -> Archive -> Organizer -> Distrubute App -> ipa 上傳到第三方內測分發平臺(蒲公英、fir)-> 手動填寫更新日誌 -> 發送安裝連接到部門羣(釘釘或者企業微信),看起來好像很機械和繁瑣,又沒啥技術含量是吧......ios

若是能把這部分工做給自動化了就行了,天天能夠省一點時間出來發呆也挺好的。需求整理一下大概是這樣:git

  1. 可以定時觸發;
  2. 自動打包;
  3. 自動讀取某個時間段內的 git commit messge 信息當作更新日誌;
  4. 打包完成自動發送安裝連接到部門羣(釘釘或者企業微信);

實現

需求1、定時任務

調研了一下,Mac OS 能夠基於 launchctl 來配置定時任務。能夠配置到不一樣級別的 LaunchAgents 下,幾種的區別以下:程序員

~/Library/LaunchAgents 由用戶本身定義的任務項
/Library/LaunchAgents 由管理員爲用戶定義的任務項
/Library/LaunchDaemons 由管理員定義的守護進程任務項
/System/Library/LaunchAgents 由Mac OS X爲用戶定義的任務項
/System/Library/LaunchDaemons 由Mac OS X定義的守護進程任務項
複製代碼

咱們配置在用戶目錄下就行,也就是這個目錄 ~/Library/LaunchAgents,按照固定的格式新建一個 Plist 文件就行,能夠看到已經有一些第三方的任務在這裏了:github

image-20200126210005856

個人配置文件是這樣:shell

<plist version="1.0">
<dict>
  <!-- Label惟一的標識 -->
  <key>Label</key>
  <string>com.autoArchiveTask.plist</string>

  <key>Program</key>
  <string>/Users/username/Desktop/code/Project/run.sh</string>

  <!-- 指定要運行的腳本 -->
  <key>ProgramArguments</key>
  <array>
    <string>/Users/username/Desktop/code/Project/run.sh</string>
  </array>
  <!-- 指定要運行的時間 -->
  <key>StartCalendarInterval</key>
  <array>
    <dict>
        <key>Minute</key>
        <integer>00</integer>
        <key>Hour</key>
        <integer>11</integer>
    </dict>
    <dict>
        <key>Minute</key>
        <integer>00</integer>
        <key>Hour</key>
        <integer>16</integer>
    </dict>
  </array>

<!-- 標準輸出文件 -->
<key>StandardOutPath</key>
<string>/Users/username/Desktop/code/Project/run.log</string>
<!-- 標準錯誤輸出文件,錯誤日誌 -->
<key>StandardErrorPath</key>
<string>/Users/username/Desktop/code/Project/run.error</string>
</dict>
</plist>
複製代碼

相關字段的解釋以下:macos

  1. Label:對應的須要保證全局惟一性;
  2. Program:要運行腳本;
  3. ProgramArguments:指定要運行的腳本;
  4. StartCalendarInterval:運行的時間,單個時間點使用 dict,多個時間點使用 array
  5. StartInterval:時間間隔,與 StartCalendarInterval 使用其一,單位爲秒
  6. StandardInPath、StandardOutPath、StandardErrorPath:標準的輸入、輸出、錯誤文件

配置好了就能夠加載了,加載後就生效了,相關的命令以下:json

# 加載任務, -w選項會將 plist 文件中無效的 key 覆蓋掉,建議加上
launchctl load -w xxx.plist
 # 刪除任務
launchctl unload -w xxx.plist
 # 查看任務列表, 使用 grep '任務部分名字' 過濾
launchctl list | grep 'xxx'
 # 當即執行一次任務,可用來測試
launchctl start xxx.plist
複製代碼

需求2、自動打包

這個使用 fastlane 就行,很好很強大。相關的配置可參見官網,建議使用 brew 方式安裝。配置安裝文檔就行,c#

因爲我這個是多 target 工程,因此我這邊的可能多一點配置,個人 Fastfile 文件配置以下:api

default_platform(:ios)
 # 網絡請求依賴
require 'net/http'
require 'uri'
require 'json'


 platform :ios do
		
   desc "發佈app到 App Store 或者 Fir.im "
   lane :customer_hoc do
     # add actions here: https://docs.fastlane.tools/actions
     sh "fastlane adhoc --env Customer"
   end

   desc "發佈app到 App Store 或者 Fir.im "
   lane :driver_hoc do
     # add actions here: https://docs.fastlane.tools/actions
     sh "fastlane adhoc --env Driver"
   end
		 


   desc "發佈指定Target到 Fir.im"
   lane :adhoc do
   gym(
     clean:true, #打包前clean項目
     workspace: "Hedgehog.xcworkspace",
     export_method: "ad-hoc", #導出方式
     scheme: ENV['SCHEME_NAME'], #scheme
     output_name: ENV['SCHEME_NAME']+".ipa", # ipa 文件名
     output_directory: "./ipa", #ipa的存放目錄
     export_options: {
         provisioningProfiles: {
             "cn.ccmore.hedgehog.customer"=>"CustomerAdhoc", 
             "cn.ccmore.hedgehog.driver"=>"DricerAdhoc"
         }
     }
   )
 # 前往fir.im獲取 api token, 將鼠標放置右上角帳號上面, 在下拉窗選擇API token
 # 若使用的蒲公英, 請前往 https://www.pgyer.com/ 查看上傳方法
 # 若是使用Firimfile, 此處爲 firim 便可
   firim(firim_api_token:'xxxx')

  
 # 釘釘機器人
  app_patch   = "ipa/" + ENV['SCHEME_NAME']+".ipa"
  app_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleShortVersionString")
  app_build_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleVersion")
  app_name    = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleDisplayName")

 # 根據 SCHEME_NAME 區分下載連接
  app_url = "https://fir.im/6udv"

  if ENV['SCHEME_NAME'] == "Driver" then
    app_url = "https://fir.im/sa4q"
  end
  
  app_icon = "./Hedgehog/ipa/icons/57.png"
  dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxx"
  
  markdown = 
  {
    msgtype: "link", 
    link: {
        text: "iOS #{ENV['SCHEME_NAME']} 更新了!!!", 
        title: "iOS #{ENV['SCHEME_NAME']} #{app_version} (#{app_build_version}) 內測版", 
        picUrl: "#{app_icon}", 
        messageUrl: "#{app_url}"
    }
 }

  uri = URI.parse(dingTalk_url)
  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = true

  request = Net::HTTP::Post.new(uri.request_uri)
  request.add_field('Content-Type', 'application/json')
  request.body = markdown.to_json

  response = https.request(request)
  puts "------------------------------"
  puts "Response #{response.code} #{response.message}: #{response.body}"
  end

 end
複製代碼

上傳到第三方內測平臺(蒲公英、fir等)Fastlane 也有相關的插件,一行代碼搞定,如 Fir 就是:安全

# 前往fir.im獲取 api token, 將鼠標放置右上角帳號上面, 在下拉窗選擇API token
# 若使用的蒲公英, 請前往 https://www.pgyer.com/ 查看上傳方法
# 若是使用Firimfile, 此處爲 firim 便可
firim(firim_api_token:'xxxx') 
複製代碼

需求3、讀取 git commit messge

TODO: 等待實現。

需求4、自動發送安裝消息

我這邊目前使用的釘釘進行協做,能夠在相關工做羣使用釘釘機器人自動發送消息。找釘釘羣管理員添加一下獲取 token 就行。能夠向這個地址 https://oapi.dingtalk.com/robot/send?access_token=Your Token 發送純文本、圖文、markdown 等格式的消息,還能夠填寫須要 @ 的測試妹子們。

image-20200126212339968

其餘企業微信好像也是能夠的,能夠自行去查看文檔。

踩坑

1、定時腳本執行 /bin/sh: xxx/run.sh: Operation not permitted

緣由:
image-20200126201353427

首先我配置的定時腳本路徑在 /Users/username/Desktop/code/Project/run.sh,沒有和定時任務的 Plist 配置文件在一個目錄下,而配置的定時腳本聲明的是 #!/bin/sh,意思是使用 /bin/sh 來解釋執行,可是卻沒有給徹底磁盤訪問的權限。

解決方案:

給足訪問權限就行。系統偏好設置 -> 安全性與隱私-> 徹底磁盤訪問權限,查看是否有勾選☑️ 在定時腳本中聲明的解釋執行的 shell 的路徑,就是**#!/bin/** 後面接的,有 bash 、sh、 zsh 等,個人是 sh。沒有的話就添加進去。

2、在定時腳本中直接執行 fastlane 打包命令出錯: /Users/username/Desktop/code/Project/run.sh : fastlane: command not found

緣由:

雖然 cd 到了當前項目目錄,但仍是報 fastlane 找不到

解決方案:

使用全路徑 fastlane 執行命令

/Users/username/.fastlane/bin/fastlane lane
複製代碼

總結

總共折騰了一兩天時間,流程基本都跑通了,還剩抓取指定時間段內的 git commit message 當作更新日誌的 TODO,整體上仍是很愉悅和有成就感的,之後就能夠專心幹其餘的事情了,打包幾乎無感,也不用怕忘記。nice!

效果以下:

image-20200126205435079

相關配置文件已經上傳到 GitHub 倉庫,地址點擊這裏

參考連接

  1. Mac上,執行定時任務:launchctl

  2. Operation not permitted

  3. Fastlane

  4. 釘釘開發文檔


分享我的技術學習記錄和跑步馬拉松訓練比賽、讀書筆記等內容,感興趣的朋友能夠關注個人公衆號「by在水一方」。

by在水一方
相關文章
相關標籤/搜索