iOS使用Jenkins自动打包+上传到 fir+钉钉通知(二)-参数化构建

前言

按照 iOS使用Jenkins自动打包+上传到 fir+钉钉通知(一) 的步骤来配置已可快速实现自动打包了。但测试、产品、设计人员反馈,通过复制打包任务的方式新建任务,仍显不够方便。鉴于此,提供一种通过选择分支和配置来打包的方式就能简化打包流程。
参数化构建页面概览如下:

参数化构建概览

使用方法

  1. 在任务详情页,点击 Build with Parameters
  2. 选择 打包分支
  3. 选择 打包配置
  4. 点击 开始构建 即可打包。
    多次点击 开始构建 会创建多个任务,按照先后顺序排队,上一个任务完成后,自动开始下一个打包任务。

参数化构建

选择分支

步骤一 使用选择分支的功能,需要先安装 Git Parameter 插件。

Git Parameter

Jenkins 首页-系统管理-插件管理-Installed plugins 页面的输入框中,输入Git Parameter,选中Git Parameter,然后安装。安装完成后,在网址中输入链接 http://localhost:8080/restart 重启 Jenkins。

步骤二 安装好插件后,进入任务详情页,点击 配置-General,然后勾选上 参数化构建过程

勾选参数化构建过程

步骤三 添加参数

添加参数

勾选上 参数化构建过程 后,点击 添加参数 ,在下拉菜单中选中 Git 参数

步骤四 配置 Git 参数

  1. 在 Git 参数-名称中输入自定义名称,如:branchName。
  2. 在参数类型选项中选择-分支
  3. 在默认值中输入默认的打包分支
  4. 勾选上 Required Parameter


    配置 Git 参数
  5. 配置完参数后,在源码管理中,将指定分支中的分支名换成 $branchName 即可将选中的分支用于打包分支。
    在这里插入图片描述

打包配置选项

配置好了选择分支的功能,还要再配置一下选择 debug/release 的功能。点击 添加参数 ,在下拉菜单中选中 选项参数

配置选项

  1. 在 选项参数-名称中输入自定义名称,如: configuration。
  2. 在选项中输入选项 Debug、Release,使用换行来分隔选项。
  3. 描述可输入备注信息,可不填。
    配置

    经过上面的配置后,点击 应用-保存 后,即可在任务详情页看到 Build with Parameters 选项了。
    [图片上传失败...(image-b36150-1676282831388)]
    在打包脚本中,使用 $configuration 就可以获取到选中的打包配置了。

附加参数

在自动打包应用中,根据反馈,希望知道是谁启动的打包任务,使用哪台打包机器打的包。基于此,需要额外的附加参数。

  1. shell 脚本中使用 ${USER} 可以获取到当前电脑登录的用户名。
  2. shell 脚本中使用 $BUILD_USER 可以获取到 build user vars plugin 插件提供的环境变量,代表登录 jenkins 的用户名。安装 build user vars plugin 插件的方法,不再赘述。
    build user vars plugin

启动电脑自动启动 Jenkins 服务

启动电脑自动启动 Jenkins 服务可参考文章:Mac开机自动运行shell脚本

git fetch --tags 超时

打包时偶尔遇到打包失败的情况,查看打包日志输出发现是 git fetch --tags 命令超时,原因是网速差的情况下请求超时导致的。解决此问题,可参考文章:Jenkins ERROR: Timeout after 10 minutes

git fetch --tags 超时

完整打包脚本

经过上面的配置后,打包脚本也要随之修改。


打包脚本

脚本如下:

export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
cd ~/projectName
git fetch
lastName="${GIT_BRANCH##*/}"
currentBranch="$(git rev-parse --abbrev-ref HEAD)"
macUser="${USER}"
configuration="${configuration}"
echo "currentBranch=$currentBranch, lastName=$lastName, macUser=$macUser, configuration=$configuration"
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

if [ "$configuration" = "Debug" ]; then
    echo "fastlane project_Debug: macUser=$macUser BUILD_USER = $BUILD_USER, BRANCH_NAME = $GIT_BRANCH, jobName = $JOB_NAME outputDirectory = /Users/username/debug/"
    bundle exec fastlane project_Debug branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG" buildUser:$BUILD_USER macUser:$macUser outputDirectory:"/Users/username/debug/"
else
    echo "fastlane project_Release: macUser=$macUser BUILD_USER = $BUILD_USER, BRANCH_NAME = $GIT_BRANCH, jobName = $JOB_NAME outputDirectory = /Users/username/release/"
    bundle exec fastlane project_Release branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG" buildUser:$BUILD_USER macUser:$macUser outputDirectory:"/Users/username/release/"
fi

Fastlane 配置

脚本配置了参数后,在 fastlane 的配置文件 Fastfile 中接收参数,然后输出到钉钉消息中。

default_platform(:ios)

platform :ios do
  desc "iOS 自动打包"
  lane :project_Debug do |options|
    scheme_name = "project"
    output_directory = "./debug/"
    custom_directory = options[:outputDirectory]
    if !(custom_directory.nil? || custom_directory.empty?)
      output_directory = custom_directory
    end
    puts "打包输出路径为 #{output_directory}"

    #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]
    buildUser = options[:buildUser]
    macUser = options[:macUser]
    changeLog = options[:changeLog]

    answer = fir_cli api_token:"xxxx", need_release_id: true
    puts "上传后的结果:#{answer}"

    download_url = "https://hey.scandown.com/#{answer[:short]}?release_id=#{answer[:release_id]}"
    dingdingMsg = "打包结果通知:Jenkins 打包成功。Debug 开发包。\n打包者:#{buildUser}\n分支名:#{branchName}\n任务名:#{jobName}\n打包使用的是#{macUser}的电脑\n下载二维码链接:#{download_url} \n修改日志: \n#{changeLog} \n"
    puts "打包结束时,输出文案:#{dingdingMsg}"

    #fir_cli api_token:"xxxx", dingtalk_at_all: true, #dingtalk_access_token:"xxxx", #dingtalk_custom_message: dingdingMsg
  
    # 构造消息格式
    text = {
      "at": {
        "isAtAll": false
      },
      "text": {
          "content": "#{dingdingMsg}"
      }, 
      "msgtype": "text"
    }
    puts "发送的钉钉消息:#{text}"
    
    dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
    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

  lane :project_Release do |options|
    scheme_name = "project"
    output_directory = "./release/"
    custom_directory = options[:outputDirectory]
    if !(custom_directory.nil? || custom_directory.empty?)
      output_directory = custom_directory
    end
    puts "打包输出路径为 #{output_directory}"
    #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: "Release",
        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]
    buildUser = options[:buildUser]
    macUser = options[:macUser]
    changeLog = options[:changeLog]
    
    answer = fir_cli api_token:"xxxxxx", need_release_id: true
    puts "上传后的结果:#{answer}"

    download_url = "https://hey.scandown.com/#{answer[:short]}?release_id=#{answer[:release_id]}"
    dingdingMsg = "打包结果通知:Jenkins 打包成功。Release 线上包。\n打包者:#{buildUser}\n分支名:#{branchName}\n任务名:#{jobName}\n打包使用的是#{macUser}的电脑\n下载二维码链接:#{download_url} \n修改日志: \n#{changeLog} \n"
    puts "打包结束时,输出文案:#{dingdingMsg}"

    #fir_cli api_token:"xxxx", dingtalk_at_all: true, #dingtalk_access_token:"xxx", #dingtalk_custom_message: dingdingMsg
    # 构造消息格式
    text = {
      "at": {
        "isAtAll": false
      },
      "text": {
          "content": "#{dingdingMsg}"
      }, 
      "msgtype": "text"
    }

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

    dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
    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. Jenkins ERROR: Timeout after 10 minutes
  2. Mac开机自动运行shell脚本
  3. Jenkins获取运行job的用户名(在构建历史中展示构建人)
  4. 如何在shell脚本中获取当前用户名?
  5. jenkins多分支构建选择
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容