【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执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/18893.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】(9) 优先级队列(堆)

一、优先级队列 优先级队列不同于队列&#xff0c;队列是先进先出&#xff0c;优先级队列是优先级最高的先出。一般有两种操作&#xff1a;返回最高优先级对象&#xff0c;添加一个新对象。 二、堆 2.1、什么是堆 堆也是一种数据结构&#xff0c;是一棵完全二叉树&#xff0c…

2025.2.15

web [HNCTF 2022 Week1]Interesting_include&#xff1a; 直接打开 PHP代码片段包含两部分&#xff1a;一个主脚本和一个潜在的被包含文件。主脚本负责处理GET请求&#xff0c;特别是filter参数&#xff0c;而被包含文件&#xff08;假设为./flag.php&#xff09;似乎包含了我…

CentOS 7.8 安装MongoDB 7教程

文章目录 CentOS 7.8 安装MongoDB 7教程一、准备工作1. 系统更新2. 权限 二、添加MongoDB软件源1. 创建MongoDB的yum源文件2. 添加以下内容3. 保存并退出编辑器 三、安装MongoDB1. 更新yum缓存2. 安装MongoDB 四、启动MongoDB服务1. 启动MongoDB2. 设置MongoDB开机自启动 五、配…

ElasticSearch基础和使用

ElasticSearch基础 1 初识ES相关组件 &#xff08;1&#xff09;Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。Elasticsearch结合kibana、Logstash、Beats组件 也就是elastic stack&#xff08;ELK&#xff09; 广泛应…

[C++]多态详解

目录 一、多态的概念 二、静态的多态 三、动态的多态 3.1多态的定义 3.2虚函数 四、虚函数的重写&#xff08;覆盖&#xff09; 4.1虚函数 4.2三同 4.3两种特殊情况 &#xff08;1&#xff09;协变 &#xff08;2&#xff09;析构函数的重写 五、C11中的final和over…

【git-hub项目:YOLOs-CPP】本地实现01:项目构建

目录 写在前面 项目介绍 最新发布说明 Segmentation示例 功能特点 依赖项 安装 克隆代码仓库 配置 构建项目 写在前面 前面刚刚实现的系列文章: 【Windows/C++/yolo开发部署01】 【Windows/C++/yolo开发部署02】 【Windows/C++/yolo开发部署03】 【Windows/C++/yolo…

在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程

既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…

安装 Docker Desktop 修改默认安装目录到指定目录

Docker Desktop安装目录设置 Docker Desktop 默认安装位置 &#xff08;C:\Program Files\Docker\Docker) 是这个 &#xff0c;导致系统盘占用过大&#xff0c;大概2G ; 那么如何安装到其他磁盘呢&#xff1f; 根据docker desktop 官网 Docker Desktop install 我们可以看到&a…

DeepSeek官方发布R1模型推荐设置

今年以来&#xff0c;DeepSeek便在AI领域独占鳌头&#xff0c;热度一骑绝尘。其官方App更是创造了惊人纪录&#xff0c;成为史上最快突破3000万日活的应用&#xff0c;这一成绩无疑彰显了它在大众中的超高人气与强大吸引力。一时间&#xff0c;各大AI及云服务厂商纷纷投身其中&…

常见的IP地址分配方式有几种:深入剖析与适用场景‌

在数字互联的世界里&#xff0c;IP地址如同网络世界的“门牌号”&#xff0c;是设备间通信的基础。随着网络技术的飞速发展&#xff0c;IP地址的分配方式也日趋多样化&#xff0c;以适应不同规模、不同需求的网络环境。本文将深入探讨当前主流的几种IP地址分配方式&#xff0c;…

NLP 八股 DAY1:BERT

BERT全称&#xff1a;Pre-training of deep bidirectional transformers for language understanding&#xff0c;即深度双向Transformer。 模型训练时的两个任务是预测句⼦中被掩盖的词以及判断输⼊的两个句⼦是不是上下句。在预训练 好的BERT模型后⾯根据特定任务加上相应的⽹…

Flutter_学习记录_动画的简单了解

用AnimationController简单实现如下的效果图&#xff1a; 1. 只用AnimationController实现简单动画 1.1 完整代码案例 import package:flutter/material.dart;class AnimationDemo extends StatefulWidget {const AnimationDemo({super.key});overrideState<AnimationDe…

sql sqlserver的特殊函数COALESCE和PIVOT的用法分析

一、COALESCE是一个返回参数中第一个非NULL值的函数&#xff0c; 列如&#xff1a;COALESCE&#xff08;a,b,c,d,e&#xff09;;可以按照顺序取abcde&#xff0c;中的第一个非空数据&#xff0c;abcde可以是表达式 用case when 加ISNULL也可以实现&#xff0c;但是写法复杂了…

类与对象C++详解(上)

目录 1.类的定义 1.1 类定义格式 补充: struct与class的区别&#xff08;c语言与c&#xff09; 1.2 访问限定符 1.3 类域 2.实例化 3.对象大小 4.this指针 1.类的定义 1.1 类定义格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&…

LabVIEW 天然气水合物电声联合探测

天然气水合物被认为是潜在的清洁能源&#xff0c;其储量丰富&#xff0c;预计将在未来能源格局中扮演重要角色。由于其独特的物理化学特性&#xff0c;天然气水合物的探测面临诸多挑战&#xff0c;涉及温度、压力、电学信号、声学信号等多个参数。传统的人工操作方式不仅效率低…

Windows上安装Go并配置环境变量(图文步骤)

前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量&#xff1b; Go语言版本&#xff1a;1.23.2 Windows版本&#xff1a;win11&#xff08;win10通用&#xff09; 下载Go环境 下载go环境&#xff1a;Go下载官网链接(https://golang.google.cn/dl/) 等待…

神经网络常见激活函数 9-CELU函数

文章目录 CELU函数导函数函数和导函数图像优缺点pytorch中的CELU函数tensorflow 中的CELU函数 CELU 连续可微指数线性单元&#xff1a;CELU&#xff08;Continuously Differentiable Exponential Linear Unit&#xff09;,是一种连续可导的激活函数&#xff0c;结合了 ELU 和 …

《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期&#xff1a;Google开…

小米平板怎么和电脑共享屏幕

最近尝试使用小米平板和电脑屏幕分屏互联 发现是需要做特殊处理的&#xff0c;需要下载一款电脑安装包&#xff1a;小米妙享 关于这个安装包&#xff0c;想吐槽的是&#xff1a; 没有找到官网渠道&#xff0c;是通过其他网络方式查到下载的 不附录链接&#xff0c;原因是因为地…

(学习总结23)Linux 目录、通配符、重定向、管道、shell、权限与粘滞位

Linux 目录、通配符、重定向、管道、shell、权限与粘滞位 Linux 目录通配符重定向管道shell 介绍Linux 权限Linux 权限的概念用户切换命令 su Linux权限管理文件访问者的分类&#xff1a;常用文件类型与其标识符&#xff1a;文件基本权限和权限值的表示方法&#xff1a;更改文件…