【Unity3D】Jenkins Pipeline流水线自动构建Apk
目录
一、准备阶段
二、创建Pipeline流水线项目
三、注意事项
四、扩展
1、Pipeline添加SVN更新项目Stage阶段
一、准备阶段
1、安装tomcat 10.0.5
Index of apache-local/tomcat/tomcat-10
2、安装jdk 17
Java Archive Downloads - Java SE 17.0.13 and later
3、下载Jenkins 2.492.1 (.war)包
War Jenkins Packages
将jenkins.war包移动到D:\Program Files\Apache Software Foundation\Tomcat 10.0\webapps下
配置环境变量
CATALINA_HOME
D:\Program Files\Apache Software Foundation\Tomcat 10.0
JAVA_HOME
E:\JDK(保持使用Unity3d所需的JDK 1.8版本)
Path环境变量新增路径
%CATALINA_HOME%\bin
D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin下新建一个setenv.bat文件,tomcat启动jenkins 2.492.1必须使用JDK 17或以上版本(有要求,否则启动会失败)
set JAVA_HOME=D:\Program Files\Java\jdk-17
win + R 输入cmd打开运行命令窗口,输入startup,会执行D:\Program Files\Apache Software Foundation\Tomcat 10.0\bin\startup.bat文件,启动tomcat


可检查上面红框处是否已经指定使用对应的JDK版本,若不是可能构建时也会出各种问题。
启动Tomcat窗口后,不能关闭,我们就是使用它访问Jenkins网页的,默认是http://localhost:8080/jenkins/
关于Jenkins的密码登录、插件安装可参考,插件:Unity3d、Gradle、Pipeline、Pipeline: Stage View、Git plugin、Push Over SSH、Maven Integration Plugin、Docker Pipeline
【Unity】Jenkins自动打包入门小结_jenkins unity-CSDN博客
安装插件镜像地址(文本使用清华大学维护的镜像中心,可正常安装插件)
维护方 镜像中心地址
Jenkins 中文社区 https://updates.jenkins-zh.cn/update-center.json
清华大学 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
华为开源镜像站 https://mirrors.huaweicloud.com/jenkins/updates/update-center.json
腾讯 https://mirrors.cloud.tencent.com/jenkins/updates/update-center.json
ustc https://mirrors.ustc.edu.cn/jenkins/updates/update-center.json
bit https://mirror.bit.edu.cn/jenkins/updates/update-center.json
lework https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/tencent/update-center.json https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/tsinghua/update-center.json https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/ustc/update-center.json https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/bit/update-center.json






修改Jenkins工作区 workspace地址
2个文件:C:\ProgramData\Jenkins\.jenkins\config.xml 和 C:\Users\lenovo\.jenkins\config.xml都修改如下标签,E:/JenkinsFile/workspace是自定义工作区,E:/JenkinsFile/builds是构建记录目录,${ITEM_FULL_NAME}是Jenkins项目名
<workspaceDir>E:/JenkinsFile/workspace/${ITEM_FULL_NAME}</workspaceDir><buildsDir>E:/JenkinsFile/builds/${ITEM_FULL_NAME}</buildsDir>
二、创建Pipeline流水线项目






脚本式Pipeline语法(还有个是声明式SCM,需配合Git拉取 具体百度)
pipeline {agent anyenvironment {JAVA_HOME = "E:/JDK" // 确保这里的路径正确,或者使用环境变量如${JAVA_HOME}}tools {// 指定JDK版本,例如JDK 1.8jdk 'JDK'}//参数设定 参数name、choices要对应上Jenkins设置的参数parameters{choice(name: "Platform",choices:['Android','Window64'],description: "平台")string(name: "BuildPath",defaultValue: "E:/UnityProject/MilkGameFramework_AutoBuildTest/BuildOutput/$Platform/AutoBuildTest", description: "构建输出目录")}stages {stage('打包') {steps {script {//执行一个.sh脚本文件(Shell命令)打包sh "F:/SH/build.sh"echo "打包完成"}}}}
}
F:/SH/build.sh文件如下,和打包Windows时一样的调用Unity去执行静态方法传参打包, 只有2个参数Platform和BuildPath,这2个参数是直接由Jenkins Pipeline的参数设置传入的,想增加其他参数同理添加,Pipeline 脚本式语法百度下(Groovy语法)
echo 'execute unity script to build project ' + $Platform + $BuildPathD:/UnityHubInstallPath/2019.4.0f1/Editor/Unity.exe -quit -batchmode -projectPath E:/UnityProject/MilkGameFramework_AutoBuildTest -executeMethod UnityProjectBuilder.CommandLineBuild -logFile JenkinsBuildUnity.log Platform-$Platform BuildPath-$BuildPath
配置完成后即可去点击构建(构建之前先把Unity相关的脚本配置好)
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.Build.Reporting;public class UnityProjectBuilder
{static string[] GetBuildScenes(){List<string> names = new List<string>();foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes){if (e == null)continue;if (e.enabled)names.Add(e.path);}return names.ToArray();}//测试用[MenuItem("BuildPackage/Build(Android)")]public static void BuildPackage(){LocalCommandLineBuild(@"E:\UnityProject\MilkGameFramework_AutoBuildTest\BuildOutput\Android\Test", "Android");}/// <summary>/// 此方法是从jienkins上接受 数据的 方法/// </summary>static void CommandLineBuild(){LocalCommandLineBuild(GetJenkinsParameter("BuildPath"), GetJenkinsParameter("Platform")); }static void LocalCommandLineBuild(string path, string platform){try{Debug.Log("Command line build\n------------------\n------------------");string[] scenes = GetBuildScenes();//string path = @"E:\Unity游戏包\Android\消消乐游戏";//这里的路径是打包的路径, 定义//string path = GetJenkinsParameter("BuildPath");Debug.Log(path);for (int i = 0; i < scenes.Length; ++i){Debug.Log(string.Format("Scene[{0}]: \"{1}\"", i, scenes[i]));}// ProjectPackageEditor.BuildByJenkins(GetJenkinsParameter("Platform"), GetJenkinsParameter("AppID"), GetJenkinsParameter("Version"), GetJenkinsParameter("IPAddress"));Debug.Log("Starting Build!");Debug.Log("Platform: " + GetJenkinsParameter("Platform"));//string platform = GetJenkinsParameter("Platform");if (platform == "Android"){Debug.Log("构建安卓开始:" + path + ".apk");BuildReport report = BuildPipeline.BuildPlayer(scenes, path + ".apk", BuildTarget.Android, BuildOptions.CompressWithLz4);if (report.summary.result == BuildResult.Succeeded){Debug.Log("Build succeeded: " + path + ".apk");}else if (report.summary.result == BuildResult.Failed){Debug.LogError("Build failed");foreach (var log in report.steps){if (log.messages != null){foreach (var message in log.messages){Debug.LogError(message.content);}}}}}else if (platform == "IOS"){//BuildPipeline.BuildPlayer(scenes, path, BuildTarget.iOS, BuildOptions.AcceptExternalModificationsToPlayer);}else if (platform == "Window64"){BuildReport report = BuildPipeline.BuildPlayer(scenes, path + ".exe", BuildTarget.StandaloneWindows64, BuildOptions.None);if (report.summary.result == BuildResult.Succeeded){Debug.Log("Build succeeded: " + path + ".exe");}else if (report.summary.result == BuildResult.Failed){Debug.LogError("Build failed");foreach (var log in report.steps){if (log.messages != null){foreach (var message in log.messages){Debug.LogError(message.content);}}}}}}catch (Exception err){Debug.LogError("方法F中捕捉到:" + err.Message);throw;//重新抛出当前正在由catch块处理的异常err}finally{Debug.Log("----------> I am copying! <--------------");}}/// <summary>///解释jekins 传输的参数/// </summary>/// <param name="name"></param>/// <returns></returns>static string GetJenkinsParameter(string name){/*下面是解析这个字符串,用空格分隔,每一个arg是空格分隔后的字符串,然后继续解析出Platform参数和BuildPath参数,注意:$BuildPath是我们Jenkins上定义的参数,它会传入一个字符串路径-quit -batchmode -projectPath D:\下载文件\游戏蛮牛源码\一个消消乐工程 -executeMethod UnityProjectBuilder.CommandLineBuild -logFile JenkinsBuildUnity.log Platform-$Platform BuildPath-$BuildPath*/foreach (string arg in Environment.GetCommandLineArgs()){//Debug.Log("arg:" + arg);if (arg.StartsWith(name)){return arg.Split("-"[0])[1];}}return null;}
}
等待一会打包成功后会得到

若失败了,去查看Jenkins日志

三、注意事项
1、Pipeline插件有最低Jenkins版本要求,最好是使用最新版本的Jenkins(其他版本可能有问题)
2、Tomcat使用11.0.x版本可能有问题,类似Could not create Java Virtual Machine...,故尝试使用Tomcat 10.0.5版本正常,若有类似问题请更换Tomcat版本(具体原因不清楚)
3、Jenkins版本有对应JDK版本要求,本文Jenkins要求必须JDK 17或以上,否则无法正常启动Jenkins
4、Tomcat启动的Jenkins是查找不到Jenkins服务的。
5、Tomcat换版本后,要注意变更环境变量CATALINA_HOME指定的地址,忘了就还是运行旧的Tomcat,即使你是去到具体的Tomcat双击startup.bat运行的,它只认环境变量。
6、Pipeline Script 语法对\敏感,尽量不要用\,全部改为/
7、点击构建时,可能会立刻报错,此时请把Pipeline代码设置为最简单的案例,例如:
pipeline {agent anystages {stage('打包') {steps {script {echo "打包测试"}}}}
}
若发现还是有报错,类似找不到stages、stage、steps等字眼的,很可能还是Pipeline相关的插件没更新好,要全部更新到最新。
8、一种非常奇怪的bug,具体怎么解决也是稀里糊涂的,反正就是一点击构建,瞬间失败,1ms都没执行,查看build log
报错1:Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: 3f2d47bc-e83a-4bd4-beae-34a81a0ce08f
groovy.lang.MissingPropertyException: No such property: Platform for class: groovy.lang.Binding
at groovy.lang.Binding.getVariable(Binding.java:63)
at PluginClassLoader for script-security//org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(S
报错2:Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: eddf3d49-e60e-4fd1-aeaf-d230d2946b16
java.lang.NullPointerException: Cannot invoke "java.util.Map.size()" because "map" is null
at java.base/java.util.TreeMap.putAll(TreeMap.java:314)
at hudson.slaves.EnvironmentVariablesNodeProperty.buildEnvVars(EnvironmentVariablesNodeProperty.java:87)
jenkins升级后启动job遇到问题java.lang.NullPointerException: Cannot invoke “java.util.Map.size()“ because “map_cannot invoke "java.util.map.size()" because "m" i-CSDN博客
参考如上文章后得知大概是config.xml被我改崩了,因此我直接删了C:\ProgramData\Jenkins\.jenkins\config.xml(记得缓存),然后重启Jenkins,也就是重新关闭tomcat和开启tomcat运行jenkins 去构建一次就会自动生成config.xml,好像还要等它一会儿才会生成,如果还是没生成,可以试试重启电脑,然后正常修改workspace地址即可。之后就能正常打包了,很有可能是我没改<buildsDir>标签,仅改了<workspaceDir>标签问题,也可能是我更换了太多次Jenkins版本,以及也尝试过使用Jenkins.msi安装包形式去安装(安装包形式有Jenkins服务)本文是将所有安装包Jenkins版本卸载,仅使用tomcat+jenkins形式的
四、扩展
1、Pipeline添加SVN更新项目Stage阶段
Pipeline Script在Stages{}节点内添加如下代码,一定是位于Stage('打包')阶段之前的
stage("更新SVN") {steps {script {sh "svn update --username=xb --password=123456 E:/UnityProject/MilkGameFramework_AutoBuildTest --accept tf"}}
}
--accept tf是采用theirs-full策略自动解决冲突(即使用服务器最新版本,弃用本地版本)
所以,如果发生本地项目没问题,打包项目出问题,很可能是冲突解决异常了,要手动去排查冲突点并修复。
请确保在cmd窗口能正常执行svn update,如果出现乱码或无法识别项目路径,可能是你的SVN URL有问题,注意本地项目的SVN库不能使用file:///...形式的本地URL库作为项目库,而要使用https://形式的,即远程URL,右键项目目录-TortoiseSVN -> Repo-browser可查看库URL,如果你的是file:///...则代表你的是本地库,svn update可能会失败。

本地搭建SVN服务器可参考:Windows搭建SVN本地服务器 + TortoiseSVN客户端-CSDN博客
如果你的是Git项目,请自行搜索git相关的更新命令,最好在cmd命令行执行成功后再搬到Jenkins执行。
相关文章:
【Unity3D】Jenkins Pipeline流水线自动构建Apk
目录 一、准备阶段 二、创建Pipeline流水线项目 三、注意事项 四、扩展 1、Pipeline添加SVN更新项目Stage阶段 一、准备阶段 1、安装tomcat 10.0.5 Index of apache-local/tomcat/tomcat-10 2、安装jdk 17 Java Archive Downloads - Java SE 17.0.13 and later 3、…...
10G EPON光模块
一、10G EPON对称光模块 工作模式:上行突发接收、下行连续发射。 工作原理:当需要发送信号时,系统信号通过光模块的电接口把信号传送到驱动芯片,芯片处理后,驱动激光器发出调制光信号,经光纤发到远端&…...
Edge浏览器翻译|自动翻译设置
文章目录 Edge浏览器翻译|自动翻译设置右键翻译显示原文 Edge浏览器翻译|自动翻译设置 在 Microsoft Edge 浏览器中使用 Microsoft Translator - Microsoft 支持 进入浏览器设置,从首选语言列表中移除多余的语言设置 网站将以受支持语言列表中的第一种语言进行显示。若要重新…...
基于微信小程序的场地预约设计与实现
第3章 系统设计 3.1系统设计目标 本系统的实现可以帮助体育馆场地信息的管理。帮助管理员对注册用户管理以及用户预约管理。同时可以帮助用户进行场地预约。本系统可以实现用户足不出户预约到需要的场地,为用户提供场地信息了解的平台。 3.2系统功能结构图 本系统的…...
腾讯发布混元-3D 2.0: 首个开源高质3D-DiT生成大模型
在之前的文章中已经和大家介绍过腾讯HunYuan-3D 1.0,感兴趣的小伙伴可以点击下面链接阅读~ HunYuan-3D 是首个开源高质3D-DiT生成大模型,几何与纹理解藕生成,一键将创意具象化。 2.0模型架构图及介绍 2.0模型将几何和纹理生成解耦࿰…...
计算机性能与网络体系结构探讨 —— 基于《计算机网络》谢希仁第八版
(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮࿰…...
C# 控制台相关 API 与随机数API
C# 控制台相关 API 与随机数API 控制台输入输出 功能说明 Console.WriteLine(string): 输出字符串并换行Console.Write(string, string): 输出字符串不换行Console.ReadLine(): 等待用户输入并返回字符串Console.ReadKey(bool).KeyChar: 读取按键,指定是否显示输…...
Git的常用命令及常见问题处理方法
目录 一、介绍二、常用 Git 命令1. 配置用户信息2. 初始化仓库3. 克隆远程仓库4. 查看状态5. 添加文件到暂存区6. 提交更改7. 查看提交历史8. 查看文件差异9. 查看分支10. 切换分支11. 合并分支12. 处理冲突13. 远程操作14. 标签管理15. 撤销操作 三、常见问题处理方法1. 无法推…...
基于vue3实现的课堂点名程序
设计思路 采用vue3实现的课堂点名程序,模拟课堂座位布局,点击开始点名按钮后,一朵鲜花在座位间传递,直到点击结束点名按钮,鲜花停留的座位被点名。 课堂点名 座位组件 seat.vue <script setup>//组合式APIimpo…...
kkFileView二开之pdf转图片接口
kkFileView二开之Pdf转图片接口 kkFileView二开系列文章:1 kkFileView源码下载及编译2 Pdf转图片接口2.1 背景2.2 分析2.2 接口开发2.2.1 编写Pdf转图片方法2.2.2 编写转换接口 2.3 接口测试2.3.1 Pdf文件准备2.3.2 pdf2Image 3 部署 kkFileView二开系列文章&#x…...
神经网络常见激活函数 9-CELU函数
文章目录 CELU函数导函数函数和导函数图像优缺点pytorch中的CELU函数tensorflow 中的CELU函数 CELU 连续可微指数线性单元:CELU(Continuously Differentiable Exponential Linear Unit),是一种连续可导的激活函数,结合了 ELU 和 …...
什么是网关?网关有什么作用?API网关的主要功能,SpringCloud可以选择有哪些API网关?什么是限流算法?网关如何实现限流?一篇文章读懂网关的前世今生
1、什么是网关? API网关(API Gateway)是一种中间层服务器,用于集中管理,保护和路由对后端服务的访问。它充当了客户端与后端服务之间的入口点,提供了一组统一的接口管理和控制API的访问。 2、网关示意图 3…...
OpenCV机器学习(1)人工神经网络 - 多层感知器类cv::ml::ANN_MLP
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::ml::ANN_MLP 是 OpenCV 库中的一部分,用于实现人工神经网络 - 多层感知器(Artificial Neural Network - Multi-Layer…...
DeepSeek告别服务器繁忙
原文地址:http://shen.iwiki.fun/2025/02/09/free-deepseek/ 博客地址:http://shen.iwiki.fun 一、申请API 1、硅基流动 免费额度:14元 注:平台 2000 万 Tokens 特指 Qwen2.5-14B-Instruct 模型单价下的数量,实际到账…...
线性代数中的正交和标准正交向量
在线性代数中,理解正交向量和正交向量至关重要,尤其是对于机器学习中的应用。这篇博文将简化这些概念,而不会太深入地深入研究复杂的数学。 正交向量 如果两个向量的点积等于零,则认为这两个向量是正交的。但点积到底是什么呢&am…...
从安装软件到flask框架搭建可视化大屏(一)——创建一个flask页面,零基础也可以学会
1.第一步:安装软件 Flask是一个轻量级Web应用框架,用python代码编写,简单方便应用。 如何安装pycharm_pycharm只能安装在c盘吗-CSDN博客 Pycharm分为专业版和社区版,是python的主流工具 如何安装Anaconda_如何安装anacoda csdn-…...
python opencv基础使用总结
1.安装opencv库:pip install opencv-python 2.基础使用范例 import cv2 #图片的基本操作#1.读取一张图片 参数 1:图片的文件名如果图片放在当前文件夹下,直接写文件名就行,如lena.jpg否则需要给出绝对路径,如D:\Ope…...
【已解决】TypeError: AsyncConnectionPool.__init__(), new install bug, httpx==0.24.1
1,参考社区链接,首先降低gradio版本,降低到4以下,但是也不能降太低,也不能太高,要适中,推荐版本3.39.0 pip install gradio3.39.0 2,下载正确的httpx版本 参考社区链接࿰…...
react中如何获取真实的dom
在 React 中,获取真实的 DOM 元素通常通过 ref 来实现。ref 是一个特殊的属性,用于引用组件或 DOM 元素的实例。你可以通过 ref 获取到组件的真实 DOM 元素或组件实例。 1. 函数组件中的 useRef 在函数组件中,获取 DOM 元素的引用需要使用 …...
HTTP协议 (爬虫)
本质上 协议就是两个计算机协商好相互沟通的方式 计算机传输的数据是0or1 需要协商好数据的规则。HTTP协议是传输网站相关的东西的。 HTTP把一条消息分成三个部分 请求: 请求行:请求方式(get、post) 请求URL 协议 请求头&a…...
Python elasticsearch客户端连接常见问题整理
python 访问 elasticsearch 在python语言中,我们一般使用 pip install elasticsearch 软件包,来访问es服务器。 正确用法 本地安装elasticsearch时,应指定与服务端相同的大版本号: pip install elasticsearch7.17.0然后就可以…...
清华大学KVCache.AI团队联合趋境科技联合的KTransformers开源项目为什么那么厉害
KTransformers是一个由清华大学KVAV.AI团队开发的开源项目,旨在优化大语言模型(LLM)的推理性能,特别是在有限显存资源下运行大型模型。以下是KTransformers的详细介绍: 1. 核心特点 高性能优化:KTransfor…...
matlab模拟风场的随机脉动风
1、内容简介 matlab137-模拟风场的随机脉动风 可以交流、咨询、答疑 2、内容说明 略 模拟风场的随机脉动风,并进行相关的统计分析和计算,包括风速谱、空间相关性、自谱、互谱、以及POD(Proper Orthogonal Decomposition)分解等…...
Code::Blocks 创建 C 项目 二
Code::Blocks 创建 C 项目 二 Code::Blocks 安装请看 Code::Blocks 安装 启动 Code Blocks 选择 Create a new project 弹出界面选择 Projects -> Console application -> Go 选择 C :表示创建的是 C 语言项目 点击 Next Project title:项目名 …...
Javascript网页设计案例:通过PDF.js实现一款PDF阅读器,包括预览、页面旋转、页面切换、放大缩小、黑夜模式等功能
前言 目前功能包括: 切换到首页。切换到尾页。上一页。下一页。添加标签。标签管理页面旋转页面随意拖动双击后还原位置 其实按照自己的预期来说,有很多功能还没有开发完,配色也没有全都搞完,先发出来吧,后期有需要…...
【IoTDB 线上小课 11】为什么 DeepSeek 要选择开源?
新年新气象,【IoTDB 视频小课】第十一期全新来临! 关于 IoTDB,关于物联网,关于时序数据库,关于开源... 一个问题重点,3-5 分钟,我们讲给你听: 开源“加成”再次展现! 现在…...
【ESP32】ESP-IDF开发 | WiFi开发 | HTTPS服务器 + 搭建例程
1. 简介 1.1 HTTPS HTTPS(HyperText Transfer Protocol over Secure Socket Layer),全称安全套接字层超文本传输协议,一般理解为HTTPSSL/TLS,通过SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信…...
ollama离线环境部署deepseek及对话网站开发
ollama离线环境部署deepseek及局域网对话网站开发 需要在离线环境下面部署deepseek大模型,而且局域网内用户能在浏览器直接对话,主机的操作系统是win10 经不断探索,找到一条能走通的路,大致流程和思路如下: 局域网服…...
【Unity】 HTFramework框架(六十)Assistant助手(在Unity中接入DeepSeek等AI语言大模型)
更新日期:2025年2月14日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 索引 Assistant助手安装Ollama使用Assistant(在编辑器中)打开Assistant配置Assistant使用Assistant处理Assistant回复的内容使用推理大…...
Spring AI集成DeepSeek,实现流式输出
前面一篇文章我们实现了《Spring AI集成DeepSeek:三步搞定Java智能应用》,大模型的响应速度是很慢的,为了提升用户体验,我们通常会使用流式输出一点点将结果输出给用户。先看下效果: 在 SpringBoot 中实现流式输出可以…...
