iOS使用Jenkins自动打包+上传到 fir+钉钉通知

摘要

本文介绍的 iOS 自动打包功能使用 Jenkins 的操作页面,配置 Shell 脚本,调用 Fastlane 提供的打包命令,将打包生成的 .ipa 文件上传到 fir 平台,生成安装包的二维码,然后将打包的自定义信息和二维码链接发送到钉钉群组中(钉钉开放文档)。用户接到通知后即可扫码安装 App。
整个流程需要安装 Java 软件、jenkins.war、fastlane、fir 插件,然后配置 Jenkins。在文中将逐一介绍。

安装 Java 软件

使用 Jenkins 首先需要使用 java 安装 jenkins.war 文件,Java 的安装包版本需要在 jdk11.0~jdk17.0之间。


Java 的安装包版本要求.jpg

在终端中输入 java -version 可查看当前的 java 版本。若版本在jdk11.0~jdk17.0之间,则无需再安装 Java 软件。否则,需要先卸载旧 Java 版本。卸载旧 Java 版本方法,可在终端中粘贴以下命令:

sudo rm -fr ~/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
sudo rm -fr ~/Library/PreferencesPanes/JavaControlPanel.prefPane
sudo rm -fr ~/Library/Application\ Support/Oracle/Java
sudo rm -rf ~/Library/Java/JavaVirtualMachines/*

Mac 安装 Java 软件分为 x86 版本和 arm 版本。在 Mac-关于本机-概览-处理器 中,若处理器为 Intel 版本,则安装 x86 版本,否则安装 arm 版本。可在 Oracle 官网下载:jdk17-mac
也可以从百度云盘中下载:
x86 版本 jdk17-mac
arm 版本 jdk17-mac
双击安装包,按提示安装即可。

安装 Jenkins

Jenkins 可以使用 jenkins.war 安装,也可以使用 homebrew 安装:

使用 jenkins.war 安装
在官网下载: jenkins.war 。 也可以在 Github 仓库 JenkinsAutoArchive 里下载 jenkins.war。

使用 homebrew 安装
Mac 若未安装 HomeBrew ,需先 安装 HomeBrew, 然后执行命令:
brew install jenkins‐lts

启动 jenkins 服务

使用 Jenkins 打包,首先要启动 Jenkins 服务。启动服务有两种方式:

使用 jenkins.war 的方式
使用终端定位在 jenkins.war 所在的目录下,然后执行命令: java -jar jenkins.war // 使用默认端口 8080。或者执行命令: java -jar jenkins.war --httpPort=8888 //指定端口 8888
通过上面的命令,即可启动 Jenkins 服务,Jenkins 使用期间,不要终止此服务。终止了的话,可以重新使用该命令启动服务。

使用 homebrew 的方式
使用终端执行命令:brew services start jenkins-lts 即可。

brew services 还有其他支持的命令:
重启jenkins: brew services restart jenkins-lts
更新jenkins版本: brew upgrade jenkins-lts
停止jenkins: brew services stop jenkins-lts

安装 Fastlane

首先确保已经安装了 Xcode 或者 Xcode命令行工具:xcode-select --install
安装 fastlane 可使用两种方式:

使用 ruby 安装
ruby 的版本最好 >= 3.0.0 。使用 ruby -v 可以查看 ruby 的版本。在终端中输入命令:sudo gem install fastlane 即可安装 fastlane。

使用 homebrew 安装
可在终端中输入命令:brew install fastlane
安装完成后,使用终端定位到 iOS 项目的目录下, 例如: cd ~/projectName/ 。然后输入命令:fastlane init 。此命令会在项目目录下生成一个 fastlane 文件夹,文件夹内的 Fastfile 文件用于打包配置。

Fastfile

fastlane 整个文件夹可在 JenkinsAutoArchive 中下载。
fastlane 内各文件描述:

  • Appfile:用于存储应用程序标识符和 Apple ID 等信息
  • Fastfile:配置管理 lane,打包主要是配置这个文件

安装 fir 插件

安装完 fastlane 后,就可以安装 fir 插件了。在终端中输入命令: fastlane add_plugin fir_cli 即可。

初始化 Jenkins

Jenkins 服务启动后,在浏览器页面输入以下地址:
http://localhost:8080 //端口指定的多少写多少
第一次运行会出现如下界面,提示需要填写指定路径文件里面的内容(该内容也可以在终端上面看到)。

unlock jenkins

根据提示目录打开initialAdminPassword文件,复制出密码,填写,Continue。
然后选择"安装推荐的插件":


安装插件

等待插件安装完成:


等待安装完成

安装完成后,输入自己的信息后,点击保存:
admin

保存好填写的信息后,即可看到 Jenkins 的首页:
首页

配置 Jenkins

配置 Jenkins 凭据

在 Jenkins-系统管理-Credentials-Global credentials (unrestricted),点击“Add Credentials”,如下图所示,我们填写自己的 SSH 信息,然后点击“Save”,这样就把 SSH 添加到 Jenkins 的全局域中去了。


添加凭据.jpg
  • 类型选择:SSH Usename with private key
  • 范围:全局(Jenkin, nodes, items, all child items, etc)
  • userName:git中的名字
  • PrivateKey:ssh中的私钥,使用 open ~/.ssh/id_rsa 命令打开文件,全选并复制粘贴到此处。
  • Passphrase:git密码。

添加获取提交日志的插件

打包日志中为了获取代码提交记录,可以通过第三方插件来获取,先下载 changelog-environment.hpi 文件。然后在 系统管理-插件管理-高级 页面:

插件管理

点击“选择文件”,选择刚下载的 changelog-environment.hpi 文件,然后点击 “Deploy” 上传插件。
在👇🏻下面的 构建环境 处即可勾选上插件使用了。

创建任务

在 Jenkins 首页,点击创建任务,页面如下:


创建任务

填入任务名,选择“构建一个自由风格的软件项目”,点击“确定”后进入配置任务页面:

配置 general

general

配置 源码管理

源码管理

  • Repository URL:项目仓库链接
  • Credentials:选择 配置 Jenkins 凭据 步骤中的凭据
  • 指定分支:输入想要打包的分支名,例如 origin/xxx

配置 构建环境

构建环境

  1. 勾选上“Add timestamps to the Console Output”
  2. 勾选上“Add Changelog Information to Environment”,这是 changelog-environment.hpi 插件提供的获取提交日志的功能。然后在 Entry Format 中输入 - %3$s (%4$s %1$s)\n,在 Date Format 中输入yyyy-MM-dd HH:mm:ss

配置 Build steps
输入自定义的打包脚本

Build steps

脚本如下:

export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
cd ~/projectName
# 要打包的分支名
lastName="${GIT_BRANCH##*/}"
# 当前仓库的分支名
currentBranch="$(git rev-parse --abbrev-ref HEAD)"
echo "currentBranch=$currentBranch, lastName=$lastName"
# 如果要打包的分支和当前分支不一致,则暂存当前分支的改动内容,然后切换分支到要打包的分支
if [ "$currentBranch" != "$lastName" ]; then
    time=$(date "+%Y-%m-%d %H:%M:%S")
    git stash -u -m "$BRANCH_NAME $time"
    git checkout $lastName
fi

git pull
pod install 
# 更新插件。fir_cli 插件不及时更新的话,可能会导致无法上传应用文件。
# sudo 是以管理员身份执行命令,在<< EOF与EOF之间输入你的开机密码
sudo -S bundle exec fastlane update_plugins << EOF
    
EOF
# 安装 fir 插件。sudo 是以管理员身份执行命令,在<< EOF与EOF之间输入你的开机密码
sudo -S fastlane add_plugin fir_cli << EOF
    
EOF
echo "fastlane Project_Debug: BRANCH_NAME = $GIT_BRANCH, jobName = $JOB_NAME"
# SCM_CHANGELOG 是插件 changelog-environment.hpi 提供的获取提交日志的环境变量
bundle exec fastlane project_Release branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG"

执行脚本中的 pod install 命令,需要先配置一下 Jenkins 的环境变量,否则会报错。配置环境变量步骤:

  1. 系统管理-系统配置-全局属性 中勾选上环境变量。
  2. 在终端中输入 echo $PATH,终端会打印出一串字符串,几个路径,复制该路径,返回到Jenkins中。
  3. 键默认填写 PATH,值填写从终端复制的那个字符串,点击保存,完成,构建该项目。
    环境变量

配置 fastlane 打包脚本
脚本中的 bundle exec fastlane Project_Debug branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG" 命令,其中 Project_Debug 是在工程项目目录下的 fastlane/Fastfile 文件中自定义的打包方法。
GIT_BRANCH 、JOB_NAME 是 Jenkins 提供的环境变量,分别代表分支名和 Jenkins 任务名。SCM_CHANGELOG 是插件changelog-environment.hpi 提供的获取提交日志的环境变量。

配置 邮件通知
邮件通知可不配置,如需配置,可参考 Jenkins 踩坑(三)| Email 配置与任务邮件发送

保存配置

应用

点击 应用 即可。

复制任务

jenkins 每新建一个任务,并不需要重新配置一次,可以通过复制任务的方式,来快速新建任务。


复制任务

如上图,在复制栏输入希望复制的,已经存在的任务名,点击确定。然后在新创建好的任务中,修改配置即可。

fastlane 打包脚本介绍

fastlane actions

fastlane 支持许多 action,在终端输入命令:fastlane actions 或者在 官网 actions 查看。
简单介绍几个 action:

  • get_version_number : 获取工程的版本号
  • get_build_number : 获取工程的 build 号
  • increment_build_number : 自动增加 build 号
  • gym : iOS app打包签名自动化工具
  • fir_cli : fir 插件的 action,可以使用 fir 的功能,上传 ipa 文件,支持扫码安装

fastlane action gym

iOS 打包使用 fastlane action 中的 gym 命令,在终端输入命令:fastlane action gym 或者在 官网 gym 查看。如下:

gym parameters

fastlane action fir_cli

fir 官方维护的插件提供的 action: fir_cli 命令,在终端输入命令:fastlane action fir_cli 或者在 github fir_cli 查看。如下:

fir_cli

fastlane action fir_cli api_token:"xxxxxxxxxxx" 传入 api_token 即可将 ipa 文件上传到 fir。api_token 获取方法:首先在 fir 登录,然后按下图点击 API token,即可获取。
api_token

钉钉智能群助手

钉钉群支持自定义机器人接入。在钉钉群设置页点击 智能群助手

钉钉群设置

在机器人管理页面复制 Webhook 链接,给群发消息需要这个链接。
机器人管理

根据 钉钉开放文档 的介绍,自定义机器人支持文本 (text)、链接 (link)、markdown(markdown)、ActionCard、FeedCard消息类型。

Fastfile 中的 Project_Debug 为例,lane 配置如下:

default_platform(:ios)

platform :ios do
  desc "iOS 自动打包"

  lane :Project_Debug do |options|

    scheme_name = "Project"
    # 输出文件放在工程目录下的 debug 文件夹下,没有 debug 文件夹的话,需要手动创建一下。
    output_directory = "./debug/"

    #increment_build_number

    #version = get_version_number(xcodeproj: "Project.xcodeproj", target: "#{scheme_name}")

    buildNumber = get_build_number

    output_name = "#{scheme_name}_#{buildNumber}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"

    gym(scheme: scheme_name,
            workspace: "Project.xcworkspace",
            include_bitcode: false,
            configuration: "Debug",
        include_symbols: true,
        export_method: "development",
        output_directory: output_directory,
        build_path: output_directory,
        archive_path: output_directory,
        output_name: output_name)
    branchName = options[:branchName]
    jobName = options[:jobName]
    changeLog = options[:changeLog]
    answer = fir_cli api_token:"xxxxxxxxxxx", need_release_id: true
 
    puts "上传后的结果:#{answer}"
    # fir 安装包链接需要手动拼接一下。hey.appc01.com 可能会改变,如果无法使用,则需要根据 fir 的实际链接修改。
    download_url = "https://hey.appc01.com/#{answer[:short]}?release_id=#{answer[:release_id]}"

    dingdingMsg = "打包结果通知:Jenkins 打包成功。Debug 开发包。\n branchName:#{branchName}\n jobName:#{jobName}\n 下载二维码链接:#{download_url} \n 修改日志:#{changeLog} \n"
    puts "打包结束时,输出文案:#{dingdingMsg}"

    #fir_cli api_token:"xxxxxx", dingtalk_at_all: true, #dingtalk_access_token:"xxxxxxx", #dingtalk_custom_message: dingdingMsg
    
    dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx"

    # 构造消息格式
    text = {
      "at": {
        "isAtAll": true
      },
      "text": {
          "content": "#{dingdingMsg}"
      }, 
      "msgtype": "text"
    }

    puts "发送的钉钉消息:#{text} "

    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 = text.to_json

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

参考文章

  1. jenkens构建前执行 pod install
  2. 傻瓜式-iOS自动化分发部署-持续化集成方案【Fastlane+蒲公英+Jenkins】
  3. iOS 持续集成与持续分发(jenkins+fastlane+pgyer)
  4. Jenkins+fastlane打包出现找不到对应scheme的问题(fastlane 配置的 scheme 没有生效的解决方案)
  5. iOS fastlane 配合蒲公英打包, 并进行钉钉群组通知
  6. jenkins使用Changelog获取commit记录
  7. jenkins检查更新站点时出错:SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败:sun.secu
  8. Jenkins 踩坑(三)| Email 配置与任务邮件发送
  9. 如何在 Mac 上卸载 Java?
  10. mac 安装HomeBrew
  11. shell脚本中填写密码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容