当前位置:   article > 正文

【Unity】搭建Jenkins打包工作流,远程打热更、构建App_unity pc端打包bulidapp

unity pc端打包bulidapp

Jenkins是团队协作项目打包常用的工作流,不多做介绍。

Jenkins的部署Unity打包环境还是非常简单的:

工作流程如下:

1. 在Jenkins中添加打包配置参数(如: 版本号, 目标平台等), 参数将以UI的形式显示在Jenkins Web界面以便打包前填写参数;

2. 用.bat批处理代码将步骤1的参数保存到json文件,以便打包时获取参数;

3. 用.bat批处理代码调用Unity.exe触发指定C#静态方法,在此方法中执行参数配置和打包逻辑:

Unity.exe -quit -nographics -batchmode -projectPath "%ProjectRoot%" -executeMethod UGF.EditorTools.JenkinsBuilder.BuildApp -logFile "%ProjectRoot%/Tools/Jenkins/UnityBuildLog.log"

具体配置:

1. 下载Jenkins, Jenkins下载链接:Jenkins download and deployment

为了跨平台方便最好选择下载.war格式的Java包;

2. 当前版本的Jenkins要求的JDK版本是11 - 17, 安装后配置JAVA_HOME环境变量(详情自查Java环境安装)

3. 用命令行启动Jenkins:

java -jar jenkins.war

4. Jenkins启动后,在浏览器输入ip地址和端口打开Jenkins Web界面:

如果是本机通过地址 localhost:8080 打开Web界面, 填写命令行窗口显示的Jenkins密码:

 

5. 创建Jenkins 打包热更资源和打包App两个任务:

①点击新建视图:

 ②填写视图信息创建视图:

 视图就相当于文件夹,是为了更好的归类。选择对应的视图就可以在视图下新建Item,即任务;

③ 点击新建Item,创建Freestyle project任务:

 ④ 选择建好的任务,进入配置界面就可以为打包添加各种变量和批处理执行流程了:

 ⑤ 勾选This project is parameterized后就可以添加各种变量UI,这些变量用于传递给打包属性,比如版本号、打包目标平台等

 点击添加参数,以添加的参数会以可交互UI的形式显示在Web界面,一遍打包前填写配置参数:

 6. 创建好参数后点击Build with Parameters,就可以填写自定义的打包参数

 7. 使用.bat批处理代码获取打包参数并生成参数的json文件:

进入配置界面,找到Build Steps栏,添加构建步骤,类型选择Execute Windows batch command(Windows批处理脚本),Mac或Linux平台可以选择shell脚本。

 可以直接贴入批处理命令行,也可以将命令行写入.bat文件中,然后直接填写要执行的.bat文件名;

通过%参数名%的形式获取参数值;将参数值写入json文件代码如下:

生成打热更资源的参数json文件:

echo {"ResourceOutputDir":"%ResourceOutputDir%","Platform":"%Platform%","ForceRebuild":%ForceRebuild%,"ResourceVersion":%ResourceVersion%,"UpdatePrefixUrl":"%UpdatePrefixUrl%","ApplicableVersions":"%ApplicableVersions%","ForceUpdate":%ForceUpdate%,"AppUpdateUrl":"%AppUpdateUrl%","AppUpdateDescription":"%AppUpdateDescription%"}>"%ProjectRoot%\Tools\Jenkins\BuildResourceConfig.json"

生成打App的参数json文件:

echo {"ResourceOutputDir":"%ResourceOutputDir%","Platform":"%Platform%","FullBuild":%FullBuild%,"DebugMode":%DebugMode%,"DevelopmentBuild":%DevelopmentBuild%,"BuildAppBundle":%BuildAppBundle%,"Version":"%Version%","VersionCode":%VersionCode%}>%ProjectRoot%\Tools\Jenkins\BuildAppConfig.json

需要注意的是,字符串参数不能有换行,否则.bat批处理代码会执行异常。

8. 使用命令行调用Unity.exe打包:

可以直接用如下方式,使用批处理调用Unity.exe打包,但是此方式Jenkins无法实时在网页显示打包的Log信息:

Unity.exe -quit -nographics -batchmode -projectPath "%ProjectRoot%" -executeMethod UGF.EditorTools.JenkinsBuilder.BuildApp -logFile "%ProjectRoot%/Tools/Jenkins/UnityBuildLog.log"

最好的选择是安装Jenkins的Unity支持插件,使用插件启动Unity打包可以完美在网页输出Log日志。

① 安装Unity插件

进入Jenkins管理界面:

 进入插件管理界面:

 选择Available plugins栏目,搜索安装Unity3d plugin

②  安装Unity3d plugin后,进入Global Tool Configuration配置打包所用的Unity安装路径

 ③ 再次进入Item配置,添加启动Unity的Build Steps:

 启动参数为:

-quit -nographics -batchmode -projectPath "${ProjectRoot}" -executeMethod UGF.EditorTools.JenkinsBuilder.BuildResource -logFile "${ProjectRoot}/Tools/Jenkins/UnityBuildLog.log"

注意,注意Unity3d plugins的获取打包参数的方式与批处理脚本不同,使用${参数名}的方式获取参数值;

其中 -nographics 即不显示Unity图形界面,这样会减少内存消耗,一定程度上能提高打包速度。

 -projectPath "${ProjectRoot}" 为配置项目路径;

-executeMethod UGF.EditorTools.JenkinsBuilder.BuildResource为指定启动Unity后自动执行脚本UGF.EditorTools.JenkinsBuilder的BuildResource()静态方法。

在BuildResource中编写打包逻辑,如先获取生成的json参数文件,根据参数初始化各项设置,然后再打包资源。

9. 打包逻辑:

这里偷懒直接使用之前写过的一个编辑器扩展窗口类AppBuildEditor:【Unity编辑器扩展】扩展Unity工具栏Toolbar, 一键出包/打热更简化打包流程_unitytoolbar_TopGames的博客-CSDN博客

 直接调用编辑器中的方法一键打热更资源,一键打App;

需要注意的是,使用命令行打包并不是启动Unity Editor,所以继承EditorWindow的脚本都不会执行Update和OnGUI方法。如果在Update和OnGUI中有初始化参数的逻辑,需要在Jenkins打包函数中做一遍初始化操作。

  1. using System;
  2. using System.IO;
  3. using UnityEditor;
  4. using UnityEngine;
  5. namespace UGF.EditorTools
  6. {
  7. public class JenkinsBuilder
  8. {
  9. const string BuildResourceConfigFile = "Tools/Jenkins/BuildResourceConfig.json";
  10. const string BuildAppConfigFile = "Tools/Jenkins/BuildAppConfig.json";
  11. public static void BuildResource()
  12. {
  13. Debug.Log("------------------------------Start BuildResource------------------------------");
  14. var configFile = UtilityBuiltin.ResPath.GetCombinePath(Directory.GetParent(Application.dataPath).FullName, BuildResourceConfigFile);
  15. if (!File.Exists(configFile))
  16. {
  17. Debug.LogError($"构建失败! 构建配置文件不存在:{configFile}");
  18. return;
  19. }
  20. JenkinsBuildResourceConfig configJson = null;
  21. try
  22. {
  23. var jsonStr = File.ReadAllText(configFile);
  24. configJson = UtilityBuiltin.Json.ToObject<JenkinsBuildResourceConfig>(jsonStr);
  25. }
  26. catch (Exception err)
  27. {
  28. Debug.LogError($"构建失败! 构建配置文件解析失败:{configFile}, Error:{err.Message}");
  29. return;
  30. }
  31. if (configJson == null)
  32. {
  33. Debug.LogError($"构建失败! 反序列构建配置参数失败:{configFile}");
  34. return;
  35. }
  36. if (!CheckAndSwitchPlatform(configJson.Platform))
  37. {
  38. Debug.LogError($"构建失败! 切换平台({configJson.Platform})失败.");
  39. return;
  40. }
  41. var appBuilder = EditorWindow.GetWindow<AppBuildEidtor>();
  42. appBuilder.Show();
  43. appBuilder.JenkinsBuildResource(configJson);
  44. }
  45. public static void BuildApp()
  46. {
  47. Debug.Log("------------------------------Start BuildApp------------------------------");
  48. var configFile = UtilityBuiltin.ResPath.GetCombinePath(Directory.GetParent(Application.dataPath).FullName, BuildAppConfigFile);
  49. if (!File.Exists(configFile))
  50. {
  51. Debug.LogError($"构建失败! 构建配置文件不存在:{configFile}");
  52. return;
  53. }
  54. JenkinsBuildAppConfig configJson = null;
  55. try
  56. {
  57. var jsonStr = File.ReadAllText(configFile);
  58. configJson = UtilityBuiltin.Json.ToObject<JenkinsBuildAppConfig>(jsonStr);
  59. }
  60. catch (Exception err)
  61. {
  62. Debug.LogError($"构建失败! 构建配置文件解析失败:{configFile}, Error:{err.Message}");
  63. return;
  64. }
  65. if (configJson == null)
  66. {
  67. Debug.LogError($"构建失败! 反序列换构建配置失败:{configFile}");
  68. return;
  69. }
  70. if (!CheckAndSwitchPlatform(configJson.Platform))
  71. {
  72. Debug.LogError($"构建失败! 切换平台{configJson.Platform}失败.");
  73. return;
  74. }
  75. var appBuilder = EditorWindow.GetWindow<AppBuildEidtor>();
  76. appBuilder.Show();
  77. appBuilder.JenkinsBuildApp(configJson);
  78. }
  79. /// <summary>
  80. /// 切换到目标平台
  81. /// </summary>
  82. /// <param name="platform"></param>
  83. /// <returns></returns>
  84. private static bool CheckAndSwitchPlatform(BuildTarget platform)
  85. {
  86. if (EditorUserBuildSettings.activeBuildTarget != platform)
  87. {
  88. BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(platform);
  89. Debug.Log($"#########切换平台,TargetGroup:{buildTargetGroup}, BuildTarget:{platform}#######");
  90. return EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, platform);
  91. }
  92. return true;
  93. }
  94. }
  95. public class JenkinsBuildResourceConfig
  96. {
  97. public string ResourceOutputDir; //构建资源输出目录
  98. public BuildTarget Platform; //构建平台
  99. public bool ForceRebuild; //强制重新构建全部资源
  100. public int ResourceVersion; //资源版本号
  101. public string UpdatePrefixUrl; //热更资源服务器地址
  102. public string ApplicableVersions; //资源适用的App版本号
  103. public bool ForceUpdate; //是否强制更新App
  104. public string AppUpdateUrl; //App更新地址
  105. public string AppUpdateDescription; //App更新说明
  106. }
  107. public class JenkinsBuildAppConfig
  108. {
  109. public string ResourceOutputDir; //构建资源输出目录(只有非全热更需要)
  110. public BuildTarget Platform; //构建平台
  111. public bool FullBuild; //打包前先为热更生成AOT dll
  112. public bool DebugMode; //显示debug窗口
  113. public bool DevelopmentBuild; //调试模式
  114. public bool BuildAppBundle; //打Google Play aab包
  115. public string Version; //App版本号
  116. public int VersionCode; //App版本编号
  117. }
  118. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/112052
推荐阅读
相关标签
  

闽ICP备14008679号