• Fastlane 一键打包/发布APP - 使用记录及踩坑


    最近有空, 搞一搞fastlane 一键打包发布App store / testflight / fir.com

    相关资料

    安装fastlane
    brew install fastlane

    fastlane的安装和使用
    Fastlane 官方文档
    fastlane自动化打包(android)

    fastlane - fastfile一些基础

    idea使用vs code , 可以安装一些代码片段插件,快速上手

    在这里插入图片描述

    如何传参

    传参写法

    desc "Add description of lane"
    lane :test1 do |options|
      puts(options[:arg1])
      puts(options[:arg2])
      puts(options[:arg3])
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    命令行调用

    fastlane test1 arg1:a arg2:b arg3:c 
    
    • 1

    日志输出

    [] 🚀 
    [14:33:30]: ------------------------------
    [14:33:30]: --- Step: default_platform ---
    [14:33:30]: ------------------------------
    [14:33:30]: Driving the lane 'ios test1' 🚀
    [14:33:30]: a
    [14:33:30]: b
    [14:33:30]: c
    
    +------+------------------+-------------+
    |           fastlane summary            |
    +------+------------------+-------------+
    | Step | Action           | Time (in s) |
    +------+------------------+-------------+
    | 1    | default_platform | 0           |
    +------+------------------+-------------+
    
    [14:33:30]: fastlane.tools finished successfully 🎉
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    issuer_id

    这个必须是主账户才能看到
    在这里插入图片描述

    如果提示找不到 p8 file, 记得检查一下路径, 要在fastlane 路径下, 如果是 ./ 路径, 会报错
    key_filepath: ‘./fastlane/AuXXXX.p8’,

    app_store_connect_api_key(
      key_id: "D83848D23",
      issuer_id: "227b0bbf-ada8-458c-9d62-3d8022b7d07f",
      key_filepath: "D83848D23.p8",
      duration: 200,
      in_house: true
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    iOS端 步骤 (默认已经做好环境配置)

    1.cd ios
    
    • 1
    2.fastlane init
    
    • 1

    3.编写 Fastfile 文件
    4. .p8文件放入 ./fastlane文件目录
    5. Fastfile文件代码如下

    # This file contains the fastlane.tools configuration
    # You can find the documentation at https://docs.fastlane.tools
    #
    # For a list of all available actions, check out
    #
    #     https://docs.fastlane.tools/actions
    #
    # For a list of all available plugins, check out
    #
    #     https://docs.fastlane.tools/plugins/available-plugins
    #
    
    # Uncomment the line if you want fastlane to automatically update itself
    # update_fastlane
    
    default_platform(:ios)
    platform :ios do
    
      desc "test"
      lane :test do |options|
        #add actions here
        puts(Dir.pwd)
        puts("test ----> 1")
    
      end
    
      desc "打包iOS+上传"
      lane :app do |options|
    
        # 数据变量部分
        targetName = "channelMarketing"
        scheme = targetName
        fastlane = "fastlane"
        ipa = "ipa"
        workspace = targetName+".xcworkspace"
        workspace_path = './'+workspace
        output_directory = './'+fastlane+"/"+ipa
        output_name = targetName + ".ipa"
    
    
        # 自增build版本号
        increment_build_number()
    
        gym(
          clean:true, # 打包前先clean一下
          workspace:workspace,
          configuration:'Release',
          scheme:scheme,
          silent:false, # 隐藏构建时不需要的所有信息 默认false
          output_directory:output_directory,
          output_name:output_name,
          include_symbols:true,
          export_method: 'app-store', # app-store | ad-hoc | development 等
          export_xcargs: '-allowProvisioningUpdates'
        )
    
        # 获取ipa路径
        ipa_file_path = lane_context[SharedValues::IPA_OUTPUT_PATH]
    
        # 获取ipa基本信息
        app_name = get_ipa_info_plist_value(ipa: ipa_file_path, key: "CFBundleDisplayName")
        package_name = get_ipa_info_plist_value(ipa: ipa_file_path, key: "CFBundleIdentifier")
        version_name = get_ipa_info_plist_value(ipa: ipa_file_path, key: "CFBundleShortVersionString")
        version_code = get_ipa_info_plist_value(ipa: ipa_file_path, key: "CFBundleVersion")
      
        puts("iPA基本信息: app_name = " + app_name);
        puts("iPA基本信息: package_name = " + package_name);
        puts("iPA基本信息: version_name = " + version_name);
        puts("iPA基本信息: version_code = " + version_code);
    
        # 复制一份ipa + 修改复制文件 包名
        sh("open ./ipa")
        changeName_cp = "cp"
        changeName_file_org = "./"+ipa+"/"+output_name
        changeName_file_new = "./"+ipa+"/"+targetName+"_"+version_name+"_"+version_code+".ipa";
        sh(changeName_cp +" "+ changeName_file_org +" "+ changeName_file_new)
        
    
        # 3.上传 
        api_key = app_store_connect_api_key(
          key_id: 'xxxxxxx',#自行配置
          issuer_id: 'xxxxxxx',#自行配置
          key_filepath: './fastlane/xxxxxx.p8', #自行配置
          duration: 1200,
          in_house: false
        )
        # 上传到testflight
        upload_to_testflight(
          # 上边设置的授权信息
          api_key: api_key,
          skip_waiting_for_build_processing: true,
          # 打包好要上传的文件
          ipa: ipa_file_path,
          skip_submission: true
        )
    
      end
    
    
     # 提交一下git
      after_each do |lane, options|
        # ...
        puts(Dir.pwd)
        # 提交变动的build号
        sh("cd .. && cd .. && git add . && git commit -m -a")
      end
    
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    android端 步骤 (默认已经做好环境配置)

    1.cd ios
    
    • 1
    2.fastlane init
    
    • 1
    3. 安装一些插件
    fastlane add_plugin firim 
    
    • 1
    • 2

    安装插件的一些坑

    踩坑1:

    在这里插入图片描述

    在这里插入图片描述

    踩坑2 上传 fir.im

    在这里插入图片描述

    可是使用fastlane的插件 fir-im, 这里我采用了fir-cli, 直接走脚本上传了,

    直接用fir-cli提供的命令行工具
    在 lane中添加 就可以上传
    sh "fir publish xxxxx your apk file xxxxxxx  -T xxxxxxxxyou tokenxxxxxxxx" 
    
    • 1
    • 2
    • 3

    当然安装插件的踩坑也是有的,主要是因为 Gemfile文件路径的问题
    安卓根目录下 Gemfile 与 fastlane 同级

    Could not find gem 'fir' in any of the gem sources listed in your Gemfile.
    报错:
    在这里插入图片描述
    由于我在Android项目根目录下创建的 fastlane init 所以,Gemfile文件里面 plugins_path要注意下获取路径

    原Gemfile文件对 plugins_path路径的写法为:

    plugins_path = File.join(File.dirname(__FILE__), '.', 'Pluginfile')
    eval_gemfile(plugins_path) if File.exist?(plugins_path)
    
    • 1
    • 2

    这边改为:

    plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
    eval_gemfile(plugins_path) if File.exist?(plugins_path)
    
    • 1
    • 2

    fir.im:80报错:
    遇到这个报错,主要还是fir-cli的版本过低,新版本升级后就替换了新域名

    fir.im 更换域名至 betaqr.com 后, 需要升级至 fir-cli >= 2.0.4 有部分用户反馈 2.0.2 无法直接使用 gem update fir-cli 升级到 2.0.4, 则可以尝试卸载后重新安装, 即 gem uninstall fir-cli 后 gem install fir-cli

    踩坑3: lane 中执行 sh "fir version"失败

    can't find executable fir for gem fir-cli. fir-cli is not currently included in the bundle, perhaps you meant to add it to your Gemfile? (Gem::Exception)

    问题还是出在Gemfile中, 确保其中有

    gem "fastlane"
    gem "fir"
    
    • 1
    • 2

    Fastfile文件:

    # This file contains the fastlane.tools configuration
    # You can find the documentation at https://docs.fastlane.tools
    #
    # For a list of all available actions, check out
    #
    #     https://docs.fastlane.tools/actions
    #
    # For a list of all available plugins, check out
    #
    #     https://docs.fastlane.tools/plugins/available-plugins
    #
    
    # Uncomment the line if you want fastlane to automatically update itself
    # update_fastlane
    
    default_platform(:android)
    
    platform :android do
    
      desc "package"
      lane :app do |options|
        gradle(
          task: 'assemble', 
          build_type: 'Release',
          properties: {
            "android.injected.signing.store.file" =>  Dir.pwd + "/xxxxx",
            "android.injected.signing.store.password" => "xxxxxxxx",
            "android.injected.signing.key.alias" => "xxxxxx",
            "android.injected.signing.key.password" => "xxxxxxxx",
          },
        );
    
    
      end
    
      after_each do |lane, options|
        # ...
        apk_name = "xxxxxx.apk"
        apk_path = Dir.pwd+"/"+apk_name
        fir_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    
        apk_file_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH];
        build_type = lane_context[SharedValues::GRADLE_BUILD_TYPE];
    
        sh("cp #{apk_file_path} #{apk_path}")
        sh("fir version")
        sh("fir login #{fir_token}")
        sh "fir me"
        sh "fir publish #{apk_path}"
        sh("open .")
      end
    
    
    
    end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 相关阅读:
    python--操作列表
    如何在Nginx上启用HTTPS
    JQuery ajax 提交数据提示:Uncaught TypeError:Illegal invocation
    计算机网络第4章-网络层(1)
    【pytorch】目标检测:新手也能彻底搞懂的YOLOv5详解
    函数指针详解和简单使用
    学习小记-Netty
    浅谈能源汽车下乡充电桩建设优化建议及解决方案
    现代控制理论入门+理解
    KingbaseES V8R6兼容Oracle的exp-imp导出导入工具使用
  • 原文地址:https://blog.csdn.net/iOSTianNan/article/details/125501967