当前位置:   article > 正文

Unity与Jenkins打包机实战_unity jenkins

unity jenkins

前言

Jenkins是一个开源的持续集成工具,用人话来说就是没有感情的打包机。一般常见于公司项目用于持续交付。

可能有个人开发者对打包机很陌生或者不是很在意(比如在写这篇文章之前的我),项目小,本机写完本机打,甚至能边写边打,也没觉得怎么样。直到后来打包卡电脑没法做其他事情的时候,是时候单拎出来个电脑做个打包机了,要不耽误事情。

Jenkins侧

安装

前往官网下载安装,有国内下载站,直接下Windows的LTS版本即可。

接着就按照安装向导一步一步走,直到你进入Jenkins的WebUI界面。

现在请点击左侧Manage Jenkins,然后点右侧的Plugins。

单击左侧的Available Plugins,搜索Unity并安装。

配置

接下来需要告诉Jenkins你的Unity编辑器安装在哪里。

回到Manage Jenkins,点开Tools,一直下拉到底部添加安装

创建工程

选择Freestyle project,写好名字点击OK

这些选项你可以根据个人喜好配置,包括Github库位置(若需要更新CI/CD状态)、Git账号啥的。

但建议打开时间戳log和打包无响应自动叫停。

Build Steps那里添加指令,通过命令行启动Unity编辑器进行后台打包编译。

命令行参数可参考如下:

-projectPath "工程路径" -nographics -batchmode -quit -executeMethod JenkinsBuild.BuildWindows64 "${JOB_Name}" "工程打包存放位置\${BUILD_NUMBER}\output"

至此,Jenkins配置告一段落,接下来需要写一个和Jenkins联调的Unity编辑器脚本。

Unity侧

联调脚本

在你的工程下,在Assets文件夹下创建Editor文件夹,然后再创建一个JenkinsBuild.cs脚本,内容可参考如下:

  1. // -------------------------------------------------------------------------------------------------
  2. // Assets/Editor/JenkinsBuild.cs
  3. // -------------------------------------------------------------------------------------------------
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Collections.Generic;
  7. using UnityEditor.Build.Reporting;
  8. // ------------------------------------------------------------------------
  9. // https://docs.unity3d.com/Manual/CommandLineArguments.html
  10. // ------------------------------------------------------------------------
  11. public class JenkinsBuild
  12. {
  13. static string[] EnabledScenes = FindEnabledEditorScenes();
  14. // ------------------------------------------------------------------------
  15. // called from Jenkins
  16. // ------------------------------------------------------------------------
  17. public static void BuildMacOS()
  18. {
  19. var args = FindArgs();
  20. string fullPathAndName = args.targetDir + args.appName + ".app";
  21. BuildProject(EnabledScenes, fullPathAndName, BuildTargetGroup.Standalone, BuildTarget.StandaloneOSX, BuildOptions.None);
  22. }
  23. // ------------------------------------------------------------------------
  24. // called from Jenkins
  25. // ------------------------------------------------------------------------
  26. public static void BuildWindows64()
  27. {
  28. var args = FindArgs();
  29. string fullPathAndName = args.targetDir + args.appName;
  30. BuildProject(EnabledScenes, fullPathAndName, BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64, BuildOptions.None);
  31. }
  32. // ------------------------------------------------------------------------
  33. // called from Jenkins
  34. // ------------------------------------------------------------------------
  35. public static void BuildLinux()
  36. {
  37. var args = FindArgs();
  38. string fullPathAndName = args.targetDir + args.appName;
  39. BuildProject(EnabledScenes, fullPathAndName, BuildTargetGroup.Standalone, BuildTarget.StandaloneLinux64, BuildOptions.None);
  40. }
  41. // ------------------------------------------------------------------------
  42. // called from Jenkins
  43. // ------------------------------------------------------------------------
  44. public static void BuildLinuxServer()
  45. {
  46. var args = FindArgs();
  47. string fullPathAndName = args.targetDir + args.appName;
  48. BuildProject(EnabledScenes, fullPathAndName, BuildTargetGroup.Standalone, BuildTarget.LinuxHeadlessSimulation, BuildOptions.None);
  49. }
  50. // ------------------------------------------------------------------------
  51. // called from Jenkins
  52. // ------------------------------------------------------------------------
  53. public static void BuildAndroid()
  54. {
  55. var args = FindArgs();
  56. string fullPathAndName = args.targetDir + args.appName;
  57. BuildProject(EnabledScenes, fullPathAndName, BuildTargetGroup.Standalone, BuildTarget.Android, BuildOptions.None);
  58. }
  59. private static Args FindArgs()
  60. {
  61. var returnValue = new Args();
  62. // find: -executeMethod
  63. // +1: JenkinsBuild.BuildMacOS
  64. // +2: FindTheGnome
  65. // +3: D:\Jenkins\Builds\Find the Gnome\47\output
  66. string[] args = System.Environment.GetCommandLineArgs();
  67. var execMethodArgPos = -1;
  68. bool allArgsFound = false;
  69. for (int i = 0; i < args.Length; i++)
  70. {
  71. if (args[i] == "-executeMethod")
  72. {
  73. execMethodArgPos = i;
  74. }
  75. var realPos = execMethodArgPos == -1 ? -1 : i - execMethodArgPos - 2;
  76. if (realPos < 0)
  77. continue;
  78. if (realPos == 0)
  79. returnValue.appName = args[i];
  80. if (realPos == 1)
  81. {
  82. returnValue.targetDir = args[i];
  83. if (!returnValue.targetDir.EndsWith(System.IO.Path.DirectorySeparatorChar + ""))
  84. returnValue.targetDir += System.IO.Path.DirectorySeparatorChar;
  85. allArgsFound = true;
  86. }
  87. }
  88. if (!allArgsFound)
  89. System.Console.WriteLine("[JenkinsBuild] Incorrect Parameters for -executeMethod Format: -executeMethod JenkinsBuild.BuildWindows64 <app name> <output dir>");
  90. return returnValue;
  91. }
  92. // ------------------------------------------------------------------------
  93. // ------------------------------------------------------------------------
  94. private static string[] FindEnabledEditorScenes()
  95. {
  96. List<string> EditorScenes = new List<string>();
  97. foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
  98. if (scene.enabled)
  99. EditorScenes.Add(scene.path);
  100. return EditorScenes.ToArray();
  101. }
  102. // ------------------------------------------------------------------------
  103. // e.g. BuildTargetGroup.Standalone, BuildTarget.StandaloneOSX
  104. // ------------------------------------------------------------------------
  105. private static void BuildProject(string[] scenes, string targetDir, BuildTargetGroup buildTargetGroup, BuildTarget buildTarget, BuildOptions buildOptions)
  106. {
  107. System.Console.WriteLine("[JenkinsBuild] Building:" + targetDir + " buildTargetGroup:" + buildTargetGroup.ToString() + " buildTarget:" + buildTarget.ToString());
  108. // https://docs.unity3d.com/ScriptReference/EditorUserBuildSettings.SwitchActiveBuildTarget.html
  109. bool switchResult = EditorUserBuildSettings.SwitchActiveBuildTarget(buildTargetGroup, buildTarget);
  110. if (switchResult)
  111. {
  112. System.Console.WriteLine("[JenkinsBuild] Successfully changed Build Target to: " + buildTarget.ToString());
  113. }
  114. else
  115. {
  116. System.Console.WriteLine("[JenkinsBuild] Unable to change Build Target to: " + buildTarget.ToString() + " Exiting...");
  117. return;
  118. }
  119. // https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildPlayer.html
  120. BuildReport buildReport = BuildPipeline.BuildPlayer(scenes, targetDir, buildTarget, buildOptions);
  121. BuildSummary buildSummary = buildReport.summary;
  122. if (buildSummary.result == BuildResult.Succeeded)
  123. {
  124. System.Console.WriteLine("[JenkinsBuild] Build Success: Time:" + buildSummary.totalTime + " Size:" + buildSummary.totalSize + " bytes");
  125. }
  126. else
  127. {
  128. System.Console.WriteLine("[JenkinsBuild] Build Failed: Time:" + buildSummary.totalTime + " Total Errors:" + buildSummary.totalErrors);
  129. }
  130. }
  131. private class Args
  132. {
  133. public string appName = "AppName";
  134. public string targetDir = "~/Desktop";
  135. }
  136. }

至此Unity侧配置完毕

开始打包

现在你可以单击Build Now开始打包,也请注意,Jenkins显示的打包成功状态并不是很准,如果Unity工程那里出现了C#脚本语法错误等,Jenkins大概率是不会识别出来这是个错误的,因为Unity只要不是编辑器进程退出的过程中出了阻断性问题,Jenkins就会认为我正常走完了没有什么问题。

所以每次打完包记得一定要看log确认。

Happy programming!

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

闽ICP备14008679号