1. 项目概述告别手动传包的“石器时代”还在为Unity微信小游戏每次版本更新手动打包、压缩、上传到服务器、再登录微信开发者工具提交审核这一套繁琐流程而头疼吗我见过太多团队美术和策划在催包程序在焦头烂额地重复着“Build - 找包 - 传包”的体力劳动一个不小心传错版本轻则回滚重来重则线上事故。这种低效、易错的手工作坊模式早就该被扫进历史的垃圾堆了。这个项目的核心就是搭建一套基于Jenkins和阿里云OSS的自动化部署流水线。简单来说它的目标就是当你把代码提交到Git仓库后整个流程——从代码编译、Unity打包生成AB包AssetBundle和微信小游戏运行包到将产物自动上传到云端存储再到触发后续的测试或发布流程——全部由机器自动完成。你只需要点一下“构建”按钮或者更酷的是连按钮都不用点代码一提交流程自动就跑起来了。这不仅仅是省了几分钟时间更是将团队从重复劳动中解放出来让开发流程标准化、可追溯、零失误。这套方案特别适合中小型游戏开发团队或独立开发者。如果你正在被频繁的测试包交付、多环境部署如开发、测试、生产搞得疲惫不堪或者担心手动操作带来的风险那么这就是为你量身定做的“工业革命”。接下来我会带你从零开始拆解每一个环节分享我趟过的坑和积累的技巧让你也能轻松拥有自己的自动化部署流水线。2. 整体方案设计与核心组件选型在动手之前我们必须把整个流水线的蓝图和每个核心部件的作用搞清楚。盲目堆砌工具只会制造更多的混乱。2.1 方案全景图与工作流整个自动化部署流程可以抽象为一条清晰的流水线触发阶段开发者将Unity项目代码包括Assets、ProjectSettings等提交到Git服务器如GitLab、Gitee或GitHub。构建阶段Jenkins监听到Git仓库的变更通过Webhook或者由人工在Jenkins界面手动触发构建任务。Jenkins会拉取最新代码然后在指定的构建节点可以是Jenkins服务器本身或另一台安装了Unity的机器上执行我们预设的构建脚本。打包阶段构建脚本的核心是调用Unity的命令行接口Batchmode执行我们提前编写好的Editor脚本完成AB包打包和微信小游戏项目导出。上传阶段构建脚本在打包完成后调用阿里云OSS的命令行工具ossutil将生成的AB包和.wxagame微信小游戏运行包等产物上传到指定的OSS存储空间Bucket。交付阶段产物上传至OSS后会生成一个公开的URL。我们可以将这个URL通过邮件、钉钉机器人或Jenkins插件通知给测试人员。对于微信小游戏测试人员可以直接用这个URL在微信开发者工具中替换资源进行测试。生产环境部署同理。为什么是Jenkins OSSJenkins是老牌且强大的持续集成/持续部署CI/CD工具插件生态丰富灵活性极高能够很好地编排整个流程。而阿里云OSS对象存储服务提供了高可靠、低成本的文件存储和分发能力非常适合存放游戏资源包这种静态文件。两者结合一个负责“生产”一个负责“仓储和物流”完美匹配。2.2 核心组件深度解析1. Jenkins 你的自动化流水线“总控台”Jenkins在这里扮演大脑和指挥者的角色。它不仅仅是一个“编译工具”。我们需要利用它的几个关键特性任务Job每个部署流程对应一个Jenkins任务。我们会创建一个“自由风格”或“流水线”任务来定义整个构建过程。触发器可以配置GitLab等源码管理的Webhook实现代码推送即构建Push-Trigger。也可以配置定时构建例如每晚自动构建一个测试包。构建步骤这是核心我们通过添加“执行Shell”或“Windows批处理命令”步骤来顺序执行清理环境、拉代码、调用Unity打包、上传OSS等一系列命令。凭证管理安全地存储Git仓库的访问密钥、OSS的AccessKey等敏感信息避免明文写在脚本里。插件Git plugin用于拉代码Email Extension Plugin用于发送构建结果邮件DingTalk Plugin用于钉钉通知等。2. 阿里云OSS 产物的“云端仓库”OSS是一个海量、安全、低成本、高可靠的云存储服务。对于我们的场景Bucket存储空间你需要先在阿里云OSS控制台创建一个Bucket。建议根据环境命名如mygame-dev-assets,mygame-prod-assets。文件夹规划在Bucket内建议按项目名/版本号/平台/的目录结构存放资源。例如mygame/1.2.0/android/assets/。这非常利于版本管理和清理旧资源。访问权限为了让测试人员能直接下载你需要将Bucket或特定目录的权限设置为公共读切记不要设为公共读写。生产环境可以考虑通过CDN加速并设置防盗链。工具我们使用阿里云官方命令行工具ossutil进行上传、下载、管理操作。它配置简单支持断点续传。3. Unity与构建脚本 流水线的“生产车间”自动化打包的灵魂在于一个无人值守的Unity构建脚本。这个脚本需要继承IPreprocessBuildWithReport或IPostprocessBuildWithReport接口或者直接在Editor菜单中创建然后通过命令行调用。核心命令/path/to/Unity -quit -batchmode -nographics -projectPath /path/to/your/project -executeMethod YourEditorScript.BuildMethod -logFile build.log-quit: 执行完毕后退出Unity。-batchmode: 批处理模式不显示图形界面。-nographics: 无图形模式在无界面的服务器上必须使用。-executeMethod: 指定要执行的静态方法。脚本职责这个Editor脚本需要完成AB包打包调用BuildPipeline.BuildAssetBundles、小游戏项目构建调用BuildPipeline.BuildPlayer平台选择WebGL并配合微信小游戏转换工具。4. 版本控制Git 一切自动化的基石确保你的Unity项目完全受Git管理并且.gitignore文件配置正确忽略了Library、Temp、Build等文件夹。只有源码和必要的配置被提交Jenkins每次构建时拉取的是一个干净、可复现的代码状态。3. 环境准备与详细配置实操理论讲完我们进入实战环节。我会以一台干净的Linux服务器Ubuntu 20.04为例演示如何一步步搭建整个环境。Windows服务器的思路类似主要是路径和安装方式的区别。3.1 Jenkins服务安装与基础配置首先我们在服务器上安装Jenkins。这里使用官方推荐的War包方式灵活性最高。安装Java环境Jenkins基于Java。sudo apt update sudo apt install openjdk-11-jdk -y java -version # 验证安装下载并运行Jenkinswget -O /tmp/jenkins.war https://get.jenkins.io/war-stable/latest/jenkins.war # 创建一个专门用户来运行Jenkins安全最佳实践 sudo useradd -r -m -d /var/lib/jenkins jenkins # 使用nohup在后台运行建议生产环境使用systemd服务管理 sudo -u jenkins nohup java -jar /tmp/jenkins.war --httpPort8080 /var/lib/jenkins/jenkins.log 21 访问http://你的服务器IP:8080按照提示从日志中获取初始管理员密码解锁Jenkins。安装必要插件在Jenkins的“系统管理” - “插件管理”中安装以下插件Git plugin 用于从Git仓库拉取代码。Pipeline或Git Parameter Plug-In 如果你需要更复杂的流水线或参数化构建。Email Extension Plugin 用于发送美观的构建通知邮件。DingTalk Plugin 如果需要钉钉群通知。 安装后重启Jenkins。配置全局工具与凭证Git路径在“系统管理” - “全局工具配置”中指定服务器上Git可执行文件的路径通常/usr/bin/git。JDK配置同上配置Java 11的路径。OSS凭证在“凭据” - “系统” - “全局凭据”中添加一个“Secret text”类型的凭据填入你的阿里云OSS的AccessKey Secret。ID可以设为oss-access-key-secret。3.2 Unity构建环境准备Headless模式如果你的Jenkins服务器是Linux并且需要在这台服务器上执行Unity打包那么必须安装Unity的Headless版本无图形界面。Unity Hub目前对Linux的支持有限我们可以直接下载并安装Unity Editor for Linux。下载Unity安装器 从Unity官网下载适用于Linux的安装器例如unityhub.AppImage。但更直接的方式是下载指定版本的Unity Editor组件。# 示例下载Unity 2022.3 LTS版本 # 你需要从Unity下载页面找到实际的下载链接这通常是一个.sh脚本 wget https://netstorage.unity3d.com/unity/unity-2022.3.xx/unity-editor-installer.sh chmod x unity-editor-installer.sh安装Unity无界面组件# 使用--unattended模式进行静默安装并只选择必要的模块 sudo ./unity-editor-installer.sh --unattended --install-location/opt/Unity --componentsUnity,Unity-Linux-Mono安装完成后Unity的可执行文件路径通常在/opt/Unity/Editor/Unity。激活Unity许可证 这是Linux服务器上自动化打包最大的一个坑。Unity在批处理模式下需要有效的许可证。你需要在一台有图形界面的机器上比如你的Windows开发机生成一个离线许可证文件。在开发机上打开命令行切换到Unity安装目录下执行Unity.exe -batchmode -nographics -createManualActivationFile -logFile这会在当前目录生成一个Unity_v2022.x.ulf文件。将这个文件上传到Unity官网的许可证管理页面下载生成的.alf文件。将这个.alf文件上传到Jenkins服务器例如/var/lib/jenkins/目录下。在Jenkins的构建脚本中在调用Unity命令前先执行激活/opt/Unity/Editor/Unity -batchmode -nographics -quit -manualLicenseFile /var/lib/jenkins/your_license.alf -logFile实操心得许多团队会选择使用一台专用的Windows构建机作为Jenkins的Agent节点来执行Unity打包任务。这样可以利用已有的Windows Unity环境避免Linux下激活和模块依赖的麻烦。在Jenkins中配置一个Windows节点将打包任务分配给这个节点执行是更常见和稳定的做法。3.3 阿里云OSS工具配置安装ossutilwget -O ossutil.zip https://gosspublic.alicdn.com/ossutil/1.7.19/ossutil-v1.7.19-linux-amd64.zip unzip ossutil.zip sudo mv ossutil-v1.7.19-linux-amd64/ossutil /usr/local/bin/ ossutil --version # 验证安装配置ossutilossutil config根据提示输入你的阿里云OSS的Endpoint、AccessKey ID和AccessKey Secret。配置文件会保存在~/.ossutilconfig。在Jenkins的构建脚本中我们可以直接使用已配置好的工具。4. 构建任务编排与核心脚本编写环境就绪现在我们来创建Jenkins任务并编写核心的构建脚本。4.1 创建Jenkins任务与基础设置在Jenkins首页点击“新建Item”输入任务名称选择“自由风格的软件项目”。源码管理选择Git填入你的项目仓库URL。在“Credentials”处添加你的Git仓库用户名密码或SSH密钥。构建触发器根据需求选择。例如勾选“GitLab webhook”或“轮询SCM”。对于Webhook你需要在GitLab项目设置中配置Webhook URL格式为http://你的Jenkins地址:端口/gitlab/...并需要在Jenkins系统配置中安装并配置GitLab插件。构建环境可以勾选“Delete workspace before build starts”以保证每次构建环境干净。构建步骤这是核心我们添加一个“Execute shell”步骤。4.2 核心Shell构建脚本详解以下是一个集成化的Shell脚本示例包含了错误处理、日志记录和关键步骤。请将其填入Jenkins的“Execute shell”中。#!/bin/bash # 设置严格错误处理任何命令失败则停止构建 set -e echo 开始Unity微信小游戏自动化构建 echo 构建编号: $BUILD_NUMBER echo 工作空间: $WORKSPACE # 1. 定义变量 UNITY_PATH/opt/Unity/Editor/Unity # 你的Unity可执行文件路径 PROJECT_PATH$WORKSPACE # Jenkins会自动将代码拉取到工作空间 BUILD_METHODBuildScript.PerformBuild # 你的Unity Editor脚本中的静态方法 OUTPUT_DIR$WORKSPACE/Build LOG_FILE$WORKSPACE/build.log # OSS配置 OSS_ENDPOINToss-cn-hangzhou.aliyuncs.com # 你的Bucket所在地域Endpoint OSS_BUCKETyour-game-dev-bucket OSS_PREFIXmygame/$(date %Y%m%d)/$BUILD_NUMBER/ # OSS上的存储路径按日期和构建号组织 # 2. 清理并创建输出目录 echo 清理旧构建产物... rm -rf $OUTPUT_DIR mkdir -p $OUTPUT_DIR # 3. 执行Unity打包关键步骤 echo 开始Unity批处理模式打包... $UNITY_PATH \ -quit \ -batchmode \ -nographics \ -projectPath $PROJECT_PATH \ -executeMethod $BUILD_METHOD \ -buildOutput $OUTPUT_DIR \ -logFile $LOG_FILE # 检查Unity构建是否成功通过日志或返回码 if [ $? -ne 0 ]; then echo 错误Unity打包失败请查看日志: $LOG_FILE tail -100 $LOG_FILE # 打印日志尾部便于排查 exit 1 fi # 4. 检查并处理构建产物 echo 检查构建产物... WXGAME_PATH$OUTPUT_DIR/wechatgame if [ ! -d $WXGAME_PATH ]; then echo 错误未找到微信小游戏输出目录: $WXGAME_PATH exit 1 fi # 假设AB包被打包到 $OUTPUT_DIR/AssetBundles 目录 AB_DIR$OUTPUT_DIR/AssetBundles if [ -d $AB_DIR ]; then echo 找到AB包目录准备上传... fi # 5. 上传产物到阿里云OSS echo 开始上传产物到OSS... # 上传微信小游戏运行包整个目录 ossutil cp -r $WXGAME_PATH oss://$OSS_BUCKET/$OSS_PREFIX/wechatgame/ --update # 上传AB包如果有 if [ -d $AB_DIR ]; then ossutil cp -r $AB_DIR oss://$OSS_BUCKET/$OSS_PREFIX/AssetBundles/ --update fi # 6. 生成访问链接并输出 WXGAME_URLhttps://$OSS_BUCKET.$OSS_ENDPOINT/$OSS_PREFIX/wechatgame/ echo echo 构建成功 echo 微信小游戏包下载/访问地址$WXGAME_URL echo # 7. 可选将链接写入一个环境变量或文件供后续步骤如邮件通知使用 echo WXGAME_URL$WXGAME_URL $WORKSPACE/build_info.properties4.3 Unity Editor构建脚本C#示例在Unity项目的Assets/Editor/文件夹下创建如BuildScript.cs的脚本。using UnityEditor; using UnityEngine; using System.IO; using UnityEditor.Build.Reporting; public static class BuildScript { // 这个方法将被Jenkins命令行调用 public static void PerformBuild() { Debug.Log(开始自动化构建流程...); // 1. 打包AssetBundles (AB包) string abOutputPath Path.Combine(Application.dataPath, ../Build/AssetBundles); if (!Directory.Exists(abOutputPath)) { Directory.CreateDirectory(abOutputPath); } BuildPipeline.BuildAssetBundles(abOutputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget); Debug.Log($AB包打包完成输出至: {abOutputPath}); // 2. 构建微信小游戏 // 首先确保选择了WebGL平台 if (EditorUserBuildSettings.activeBuildTarget ! BuildTarget.WebGL) { Debug.LogWarning(当前不是WebGL平台正在切换...); EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.WebGL, BuildTarget.WebGL); } // 设置构建选项 BuildPlayerOptions buildOptions new BuildPlayerOptions(); buildOptions.scenes GetEnabledScenePaths(); // 获取所有启用场景 buildOptions.locationPathName Path.Combine(Application.dataPath, ../Build/wechatgame); buildOptions.target BuildTarget.WebGL; buildOptions.options BuildOptions.None; // 执行构建 BuildReport report BuildPipeline.BuildPlayer(buildOptions); BuildSummary summary report.summary; if (summary.result BuildResult.Succeeded) { Debug.Log($微信小游戏构建成功大小: {summary.totalSize / 1024 / 1024} MB, 输出路径: {buildOptions.locationPathName}); // 3. 关键这里可以加入微信小游戏转换步骤 // 通常需要调用微信小游戏转换工具一个独立的可执行程序对WebGL输出进行转换 // string converterPath C:\Program Files (x86)\Tencent\微信web开发者工具\cli.bat; // string webglPath buildOptions.locationPathName; // string outputPath buildOptions.locationPathName _converted; // System.Diagnostics.Process.Start(converterPath, $convert -o \{outputPath}\ \{webglPath}\); } else { Debug.LogError($构建失败错误信息: {summary}); // 抛出异常让Jenkins知道构建失败 throw new System.Exception(Unity构建失败详情请查看日志。); } } private static string[] GetEnabledScenePaths() { var scenes new System.Collections.Generic.Liststring(); foreach (var scene in EditorBuildSettings.scenes) { if (scene.enabled) { scenes.Add(scene.path); } } return scenes.ToArray(); } }注意事项微信小游戏的构建严格来说Unity输出的是WebGL项目。你需要使用微信开发者工具的命令行CLI或官方提供的转换工具将WebGL项目转换为.wxagame格式的小游戏包。上述脚本中的第3步注释部分提到了这一点。你需要确保构建服务器上也安装了微信开发者工具的命令行版本并在构建脚本中调用它。这是实现“一键出小游戏包”的最后一块拼图。5. 高级优化与闭环实践基础流水线跑通后我们可以让它变得更智能、更强大。5.1 参数化构建与多环境管理我们不可能每次构建都去改脚本里的OSS路径。Jenkins支持参数化构建。在任务配置中勾选“This project is parameterized”。添加“Choice Parameter”例如Name:DEPLOY_ENVChoices:dev开发环境\ntest测试环境\nprod生产环境Description: 选择部署环境在Shell脚本中就可以使用$DEPLOY_ENV这个变量了。# 根据环境变量选择不同的OSS Bucket和配置 case $DEPLOY_ENV in dev) OSS_BUCKETmygame-dev-assets UNITY_DEFINESDEVELOPMENT ;; test) OSS_BUCKETmygame-test-assets UNITY_DEFINESTEST ;; prod) OSS_BUCKETmygame-prod-assets UNITY_DEFINESPRODUCTION # 生产环境构建前可以增加代码扫描、更严格测试等步骤 ;; esac在Unity构建命令中可以通过-defineSymbols参数传递这些宏定义让代码能区分不同环境。5.2 构建后操作与通知构建完成后我们需要把结果告知相关人员。邮件通知在Jenkins任务配置的“构建后操作”中添加“Editable Email Notification”。可以配置当构建失败时发送邮件给相关负责人成功时也可以发送包含资源链接的邮件。钉钉/企业微信通知使用对应的Jenkins插件配置Webhook。在Shell脚本的最后可以将构建结果成功/失败和资源URL通过curl命令或插件功能发送到群聊。# 钉钉机器人通知示例 (简化版) BUILD_RESULT$? # 获取上一条命令的退出状态 if [ $BUILD_RESULT -eq 0 ]; then STATUS成功 COLOR00FF00 else STATUS失败 COLORFF0000 fi # 使用curl发送Markdown消息到钉钉机器人 curl https://oapi.dingtalk.com/robot/send?access_tokenYOUR_TOKEN \ -H Content-Type: application/json \ -d {\msgtype\: \markdown\,\markdown\: {\title\:\Unity构建通知\,\text\:\### 构建结果$STATUS\\n**项目**MyGame\\n**环境**$DEPLOY_ENV\\n**版本**$BUILD_NUMBER\\n**小游戏包**[点击下载]($WXGAME_URL)\}}5.3 资源版本管理与CDN刷新随着版本迭代OSS上会积累大量历史资源包。我们需要管理策略自动清理在构建脚本中可以添加逻辑在上传新版本后使用ossutil列出并删除N天前的旧版本资源。CDN加速如果使用了阿里云CDN对OSS进行加速上传新资源后需要刷新CDN缓存确保测试人员能立即访问到最新资源。可以在脚本最后调用CDN的刷新接口。# 调用阿里云CDN刷新URL REFRESH_URLhttps://cdn.aliyuncs.com/ # ... 使用阿里云CLI或API刷新 $WXGAME_URL 对应的缓存6. 常见问题排查与实战技巧这条路我踩过不少坑这里总结几个最典型的问题1Unity批处理模式构建失败日志显示许可证错误。排查检查/var/lib/jenkins/.local/share/unity3d/目录下的许可证文件。确保已使用正确流程生成并应用了离线许可证。技巧在Jenkins的Shell脚本最前面显式地执行一次许可证激活命令即使之前激活过。或者直接使用-batchmode -nographics -quit -logFile配合已激活的Unity编辑器避免许可证检查问题。问题2构建成功但上传OSS时速度慢或失败。排查检查网络ossutil是否使用了内网Endpoint如果服务器和OSS Bucket在同一地域。使用ossutil cp时加上--jobs 20 --parallel 10参数增加并发数以提高速度。技巧对于大文件或大量文件可以先使用tar命令打包上传一个压缩包然后在目标服务器解压。或者使用ossutil的断点续传功能。问题3微信小游戏包上传后在开发者工具中加载失败。排查首先直接通过浏览器访问OSS上game.json文件的URL看是否能正常打开。检查OSS的Bucket权限是否为“公共读”。检查Unity构建时Player Settings中的“Compression Format”是否设置正确如Disabled或Gzip需要与微信小游戏环境兼容。技巧在构建脚本中上传完成后可以加一个简单的HTTP检查用curl或wget测试一下关键资源URL的可访问性。问题4Jenkins构建时Unity打包过程卡住或无响应。排查查看详细的Unity日志(-logFile指定)。可能是某个Editor脚本有弹窗如Debug.LogError在批处理模式下会导致等待。确保所有自动化脚本都避免任何形式的用户交互。技巧在Unity Editor脚本中使用EditorUtility.DisplayProgressBar时在批处理模式下要小心。最好通过命令行参数或环境变量来控制是否显示进度条。问题5多团队项目AB包依赖管理混乱。技巧在自动化流程中可以加入AB包依赖分析和冗余检查的步骤。编写一个Editor脚本在打包前使用AssetDatabase.GetDependencies和BuildPipeline.GetAssetBundleVariants等API进行分析并将报告输出到日志或在构建失败时发出警告。搭建这样一套系统初期会花费一些时间但一旦运转起来它所带来的效率提升和风险降低是巨大的。从“手动传包”到“一键部署”不仅仅是工具的升级更是团队开发文化和工程成熟度的体现。我的体会是不要试图一步到位构建一个完美的系统先从最痛的点比如 nightly build开始实现一个最小可用的流水线然后随着项目发展逐步加入参数化、多环境、通知、安全扫描等特性。现在就去创建你的第一个Jenkins任务吧。
基于Jenkins与阿里云OSS的Unity微信小游戏自动化部署实践
1. 项目概述告别手动传包的“石器时代”还在为Unity微信小游戏每次版本更新手动打包、压缩、上传到服务器、再登录微信开发者工具提交审核这一套繁琐流程而头疼吗我见过太多团队美术和策划在催包程序在焦头烂额地重复着“Build - 找包 - 传包”的体力劳动一个不小心传错版本轻则回滚重来重则线上事故。这种低效、易错的手工作坊模式早就该被扫进历史的垃圾堆了。这个项目的核心就是搭建一套基于Jenkins和阿里云OSS的自动化部署流水线。简单来说它的目标就是当你把代码提交到Git仓库后整个流程——从代码编译、Unity打包生成AB包AssetBundle和微信小游戏运行包到将产物自动上传到云端存储再到触发后续的测试或发布流程——全部由机器自动完成。你只需要点一下“构建”按钮或者更酷的是连按钮都不用点代码一提交流程自动就跑起来了。这不仅仅是省了几分钟时间更是将团队从重复劳动中解放出来让开发流程标准化、可追溯、零失误。这套方案特别适合中小型游戏开发团队或独立开发者。如果你正在被频繁的测试包交付、多环境部署如开发、测试、生产搞得疲惫不堪或者担心手动操作带来的风险那么这就是为你量身定做的“工业革命”。接下来我会带你从零开始拆解每一个环节分享我趟过的坑和积累的技巧让你也能轻松拥有自己的自动化部署流水线。2. 整体方案设计与核心组件选型在动手之前我们必须把整个流水线的蓝图和每个核心部件的作用搞清楚。盲目堆砌工具只会制造更多的混乱。2.1 方案全景图与工作流整个自动化部署流程可以抽象为一条清晰的流水线触发阶段开发者将Unity项目代码包括Assets、ProjectSettings等提交到Git服务器如GitLab、Gitee或GitHub。构建阶段Jenkins监听到Git仓库的变更通过Webhook或者由人工在Jenkins界面手动触发构建任务。Jenkins会拉取最新代码然后在指定的构建节点可以是Jenkins服务器本身或另一台安装了Unity的机器上执行我们预设的构建脚本。打包阶段构建脚本的核心是调用Unity的命令行接口Batchmode执行我们提前编写好的Editor脚本完成AB包打包和微信小游戏项目导出。上传阶段构建脚本在打包完成后调用阿里云OSS的命令行工具ossutil将生成的AB包和.wxagame微信小游戏运行包等产物上传到指定的OSS存储空间Bucket。交付阶段产物上传至OSS后会生成一个公开的URL。我们可以将这个URL通过邮件、钉钉机器人或Jenkins插件通知给测试人员。对于微信小游戏测试人员可以直接用这个URL在微信开发者工具中替换资源进行测试。生产环境部署同理。为什么是Jenkins OSSJenkins是老牌且强大的持续集成/持续部署CI/CD工具插件生态丰富灵活性极高能够很好地编排整个流程。而阿里云OSS对象存储服务提供了高可靠、低成本的文件存储和分发能力非常适合存放游戏资源包这种静态文件。两者结合一个负责“生产”一个负责“仓储和物流”完美匹配。2.2 核心组件深度解析1. Jenkins 你的自动化流水线“总控台”Jenkins在这里扮演大脑和指挥者的角色。它不仅仅是一个“编译工具”。我们需要利用它的几个关键特性任务Job每个部署流程对应一个Jenkins任务。我们会创建一个“自由风格”或“流水线”任务来定义整个构建过程。触发器可以配置GitLab等源码管理的Webhook实现代码推送即构建Push-Trigger。也可以配置定时构建例如每晚自动构建一个测试包。构建步骤这是核心我们通过添加“执行Shell”或“Windows批处理命令”步骤来顺序执行清理环境、拉代码、调用Unity打包、上传OSS等一系列命令。凭证管理安全地存储Git仓库的访问密钥、OSS的AccessKey等敏感信息避免明文写在脚本里。插件Git plugin用于拉代码Email Extension Plugin用于发送构建结果邮件DingTalk Plugin用于钉钉通知等。2. 阿里云OSS 产物的“云端仓库”OSS是一个海量、安全、低成本、高可靠的云存储服务。对于我们的场景Bucket存储空间你需要先在阿里云OSS控制台创建一个Bucket。建议根据环境命名如mygame-dev-assets,mygame-prod-assets。文件夹规划在Bucket内建议按项目名/版本号/平台/的目录结构存放资源。例如mygame/1.2.0/android/assets/。这非常利于版本管理和清理旧资源。访问权限为了让测试人员能直接下载你需要将Bucket或特定目录的权限设置为公共读切记不要设为公共读写。生产环境可以考虑通过CDN加速并设置防盗链。工具我们使用阿里云官方命令行工具ossutil进行上传、下载、管理操作。它配置简单支持断点续传。3. Unity与构建脚本 流水线的“生产车间”自动化打包的灵魂在于一个无人值守的Unity构建脚本。这个脚本需要继承IPreprocessBuildWithReport或IPostprocessBuildWithReport接口或者直接在Editor菜单中创建然后通过命令行调用。核心命令/path/to/Unity -quit -batchmode -nographics -projectPath /path/to/your/project -executeMethod YourEditorScript.BuildMethod -logFile build.log-quit: 执行完毕后退出Unity。-batchmode: 批处理模式不显示图形界面。-nographics: 无图形模式在无界面的服务器上必须使用。-executeMethod: 指定要执行的静态方法。脚本职责这个Editor脚本需要完成AB包打包调用BuildPipeline.BuildAssetBundles、小游戏项目构建调用BuildPipeline.BuildPlayer平台选择WebGL并配合微信小游戏转换工具。4. 版本控制Git 一切自动化的基石确保你的Unity项目完全受Git管理并且.gitignore文件配置正确忽略了Library、Temp、Build等文件夹。只有源码和必要的配置被提交Jenkins每次构建时拉取的是一个干净、可复现的代码状态。3. 环境准备与详细配置实操理论讲完我们进入实战环节。我会以一台干净的Linux服务器Ubuntu 20.04为例演示如何一步步搭建整个环境。Windows服务器的思路类似主要是路径和安装方式的区别。3.1 Jenkins服务安装与基础配置首先我们在服务器上安装Jenkins。这里使用官方推荐的War包方式灵活性最高。安装Java环境Jenkins基于Java。sudo apt update sudo apt install openjdk-11-jdk -y java -version # 验证安装下载并运行Jenkinswget -O /tmp/jenkins.war https://get.jenkins.io/war-stable/latest/jenkins.war # 创建一个专门用户来运行Jenkins安全最佳实践 sudo useradd -r -m -d /var/lib/jenkins jenkins # 使用nohup在后台运行建议生产环境使用systemd服务管理 sudo -u jenkins nohup java -jar /tmp/jenkins.war --httpPort8080 /var/lib/jenkins/jenkins.log 21 访问http://你的服务器IP:8080按照提示从日志中获取初始管理员密码解锁Jenkins。安装必要插件在Jenkins的“系统管理” - “插件管理”中安装以下插件Git plugin 用于从Git仓库拉取代码。Pipeline或Git Parameter Plug-In 如果你需要更复杂的流水线或参数化构建。Email Extension Plugin 用于发送美观的构建通知邮件。DingTalk Plugin 如果需要钉钉群通知。 安装后重启Jenkins。配置全局工具与凭证Git路径在“系统管理” - “全局工具配置”中指定服务器上Git可执行文件的路径通常/usr/bin/git。JDK配置同上配置Java 11的路径。OSS凭证在“凭据” - “系统” - “全局凭据”中添加一个“Secret text”类型的凭据填入你的阿里云OSS的AccessKey Secret。ID可以设为oss-access-key-secret。3.2 Unity构建环境准备Headless模式如果你的Jenkins服务器是Linux并且需要在这台服务器上执行Unity打包那么必须安装Unity的Headless版本无图形界面。Unity Hub目前对Linux的支持有限我们可以直接下载并安装Unity Editor for Linux。下载Unity安装器 从Unity官网下载适用于Linux的安装器例如unityhub.AppImage。但更直接的方式是下载指定版本的Unity Editor组件。# 示例下载Unity 2022.3 LTS版本 # 你需要从Unity下载页面找到实际的下载链接这通常是一个.sh脚本 wget https://netstorage.unity3d.com/unity/unity-2022.3.xx/unity-editor-installer.sh chmod x unity-editor-installer.sh安装Unity无界面组件# 使用--unattended模式进行静默安装并只选择必要的模块 sudo ./unity-editor-installer.sh --unattended --install-location/opt/Unity --componentsUnity,Unity-Linux-Mono安装完成后Unity的可执行文件路径通常在/opt/Unity/Editor/Unity。激活Unity许可证 这是Linux服务器上自动化打包最大的一个坑。Unity在批处理模式下需要有效的许可证。你需要在一台有图形界面的机器上比如你的Windows开发机生成一个离线许可证文件。在开发机上打开命令行切换到Unity安装目录下执行Unity.exe -batchmode -nographics -createManualActivationFile -logFile这会在当前目录生成一个Unity_v2022.x.ulf文件。将这个文件上传到Unity官网的许可证管理页面下载生成的.alf文件。将这个.alf文件上传到Jenkins服务器例如/var/lib/jenkins/目录下。在Jenkins的构建脚本中在调用Unity命令前先执行激活/opt/Unity/Editor/Unity -batchmode -nographics -quit -manualLicenseFile /var/lib/jenkins/your_license.alf -logFile实操心得许多团队会选择使用一台专用的Windows构建机作为Jenkins的Agent节点来执行Unity打包任务。这样可以利用已有的Windows Unity环境避免Linux下激活和模块依赖的麻烦。在Jenkins中配置一个Windows节点将打包任务分配给这个节点执行是更常见和稳定的做法。3.3 阿里云OSS工具配置安装ossutilwget -O ossutil.zip https://gosspublic.alicdn.com/ossutil/1.7.19/ossutil-v1.7.19-linux-amd64.zip unzip ossutil.zip sudo mv ossutil-v1.7.19-linux-amd64/ossutil /usr/local/bin/ ossutil --version # 验证安装配置ossutilossutil config根据提示输入你的阿里云OSS的Endpoint、AccessKey ID和AccessKey Secret。配置文件会保存在~/.ossutilconfig。在Jenkins的构建脚本中我们可以直接使用已配置好的工具。4. 构建任务编排与核心脚本编写环境就绪现在我们来创建Jenkins任务并编写核心的构建脚本。4.1 创建Jenkins任务与基础设置在Jenkins首页点击“新建Item”输入任务名称选择“自由风格的软件项目”。源码管理选择Git填入你的项目仓库URL。在“Credentials”处添加你的Git仓库用户名密码或SSH密钥。构建触发器根据需求选择。例如勾选“GitLab webhook”或“轮询SCM”。对于Webhook你需要在GitLab项目设置中配置Webhook URL格式为http://你的Jenkins地址:端口/gitlab/...并需要在Jenkins系统配置中安装并配置GitLab插件。构建环境可以勾选“Delete workspace before build starts”以保证每次构建环境干净。构建步骤这是核心我们添加一个“Execute shell”步骤。4.2 核心Shell构建脚本详解以下是一个集成化的Shell脚本示例包含了错误处理、日志记录和关键步骤。请将其填入Jenkins的“Execute shell”中。#!/bin/bash # 设置严格错误处理任何命令失败则停止构建 set -e echo 开始Unity微信小游戏自动化构建 echo 构建编号: $BUILD_NUMBER echo 工作空间: $WORKSPACE # 1. 定义变量 UNITY_PATH/opt/Unity/Editor/Unity # 你的Unity可执行文件路径 PROJECT_PATH$WORKSPACE # Jenkins会自动将代码拉取到工作空间 BUILD_METHODBuildScript.PerformBuild # 你的Unity Editor脚本中的静态方法 OUTPUT_DIR$WORKSPACE/Build LOG_FILE$WORKSPACE/build.log # OSS配置 OSS_ENDPOINToss-cn-hangzhou.aliyuncs.com # 你的Bucket所在地域Endpoint OSS_BUCKETyour-game-dev-bucket OSS_PREFIXmygame/$(date %Y%m%d)/$BUILD_NUMBER/ # OSS上的存储路径按日期和构建号组织 # 2. 清理并创建输出目录 echo 清理旧构建产物... rm -rf $OUTPUT_DIR mkdir -p $OUTPUT_DIR # 3. 执行Unity打包关键步骤 echo 开始Unity批处理模式打包... $UNITY_PATH \ -quit \ -batchmode \ -nographics \ -projectPath $PROJECT_PATH \ -executeMethod $BUILD_METHOD \ -buildOutput $OUTPUT_DIR \ -logFile $LOG_FILE # 检查Unity构建是否成功通过日志或返回码 if [ $? -ne 0 ]; then echo 错误Unity打包失败请查看日志: $LOG_FILE tail -100 $LOG_FILE # 打印日志尾部便于排查 exit 1 fi # 4. 检查并处理构建产物 echo 检查构建产物... WXGAME_PATH$OUTPUT_DIR/wechatgame if [ ! -d $WXGAME_PATH ]; then echo 错误未找到微信小游戏输出目录: $WXGAME_PATH exit 1 fi # 假设AB包被打包到 $OUTPUT_DIR/AssetBundles 目录 AB_DIR$OUTPUT_DIR/AssetBundles if [ -d $AB_DIR ]; then echo 找到AB包目录准备上传... fi # 5. 上传产物到阿里云OSS echo 开始上传产物到OSS... # 上传微信小游戏运行包整个目录 ossutil cp -r $WXGAME_PATH oss://$OSS_BUCKET/$OSS_PREFIX/wechatgame/ --update # 上传AB包如果有 if [ -d $AB_DIR ]; then ossutil cp -r $AB_DIR oss://$OSS_BUCKET/$OSS_PREFIX/AssetBundles/ --update fi # 6. 生成访问链接并输出 WXGAME_URLhttps://$OSS_BUCKET.$OSS_ENDPOINT/$OSS_PREFIX/wechatgame/ echo echo 构建成功 echo 微信小游戏包下载/访问地址$WXGAME_URL echo # 7. 可选将链接写入一个环境变量或文件供后续步骤如邮件通知使用 echo WXGAME_URL$WXGAME_URL $WORKSPACE/build_info.properties4.3 Unity Editor构建脚本C#示例在Unity项目的Assets/Editor/文件夹下创建如BuildScript.cs的脚本。using UnityEditor; using UnityEngine; using System.IO; using UnityEditor.Build.Reporting; public static class BuildScript { // 这个方法将被Jenkins命令行调用 public static void PerformBuild() { Debug.Log(开始自动化构建流程...); // 1. 打包AssetBundles (AB包) string abOutputPath Path.Combine(Application.dataPath, ../Build/AssetBundles); if (!Directory.Exists(abOutputPath)) { Directory.CreateDirectory(abOutputPath); } BuildPipeline.BuildAssetBundles(abOutputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget); Debug.Log($AB包打包完成输出至: {abOutputPath}); // 2. 构建微信小游戏 // 首先确保选择了WebGL平台 if (EditorUserBuildSettings.activeBuildTarget ! BuildTarget.WebGL) { Debug.LogWarning(当前不是WebGL平台正在切换...); EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.WebGL, BuildTarget.WebGL); } // 设置构建选项 BuildPlayerOptions buildOptions new BuildPlayerOptions(); buildOptions.scenes GetEnabledScenePaths(); // 获取所有启用场景 buildOptions.locationPathName Path.Combine(Application.dataPath, ../Build/wechatgame); buildOptions.target BuildTarget.WebGL; buildOptions.options BuildOptions.None; // 执行构建 BuildReport report BuildPipeline.BuildPlayer(buildOptions); BuildSummary summary report.summary; if (summary.result BuildResult.Succeeded) { Debug.Log($微信小游戏构建成功大小: {summary.totalSize / 1024 / 1024} MB, 输出路径: {buildOptions.locationPathName}); // 3. 关键这里可以加入微信小游戏转换步骤 // 通常需要调用微信小游戏转换工具一个独立的可执行程序对WebGL输出进行转换 // string converterPath C:\Program Files (x86)\Tencent\微信web开发者工具\cli.bat; // string webglPath buildOptions.locationPathName; // string outputPath buildOptions.locationPathName _converted; // System.Diagnostics.Process.Start(converterPath, $convert -o \{outputPath}\ \{webglPath}\); } else { Debug.LogError($构建失败错误信息: {summary}); // 抛出异常让Jenkins知道构建失败 throw new System.Exception(Unity构建失败详情请查看日志。); } } private static string[] GetEnabledScenePaths() { var scenes new System.Collections.Generic.Liststring(); foreach (var scene in EditorBuildSettings.scenes) { if (scene.enabled) { scenes.Add(scene.path); } } return scenes.ToArray(); } }注意事项微信小游戏的构建严格来说Unity输出的是WebGL项目。你需要使用微信开发者工具的命令行CLI或官方提供的转换工具将WebGL项目转换为.wxagame格式的小游戏包。上述脚本中的第3步注释部分提到了这一点。你需要确保构建服务器上也安装了微信开发者工具的命令行版本并在构建脚本中调用它。这是实现“一键出小游戏包”的最后一块拼图。5. 高级优化与闭环实践基础流水线跑通后我们可以让它变得更智能、更强大。5.1 参数化构建与多环境管理我们不可能每次构建都去改脚本里的OSS路径。Jenkins支持参数化构建。在任务配置中勾选“This project is parameterized”。添加“Choice Parameter”例如Name:DEPLOY_ENVChoices:dev开发环境\ntest测试环境\nprod生产环境Description: 选择部署环境在Shell脚本中就可以使用$DEPLOY_ENV这个变量了。# 根据环境变量选择不同的OSS Bucket和配置 case $DEPLOY_ENV in dev) OSS_BUCKETmygame-dev-assets UNITY_DEFINESDEVELOPMENT ;; test) OSS_BUCKETmygame-test-assets UNITY_DEFINESTEST ;; prod) OSS_BUCKETmygame-prod-assets UNITY_DEFINESPRODUCTION # 生产环境构建前可以增加代码扫描、更严格测试等步骤 ;; esac在Unity构建命令中可以通过-defineSymbols参数传递这些宏定义让代码能区分不同环境。5.2 构建后操作与通知构建完成后我们需要把结果告知相关人员。邮件通知在Jenkins任务配置的“构建后操作”中添加“Editable Email Notification”。可以配置当构建失败时发送邮件给相关负责人成功时也可以发送包含资源链接的邮件。钉钉/企业微信通知使用对应的Jenkins插件配置Webhook。在Shell脚本的最后可以将构建结果成功/失败和资源URL通过curl命令或插件功能发送到群聊。# 钉钉机器人通知示例 (简化版) BUILD_RESULT$? # 获取上一条命令的退出状态 if [ $BUILD_RESULT -eq 0 ]; then STATUS成功 COLOR00FF00 else STATUS失败 COLORFF0000 fi # 使用curl发送Markdown消息到钉钉机器人 curl https://oapi.dingtalk.com/robot/send?access_tokenYOUR_TOKEN \ -H Content-Type: application/json \ -d {\msgtype\: \markdown\,\markdown\: {\title\:\Unity构建通知\,\text\:\### 构建结果$STATUS\\n**项目**MyGame\\n**环境**$DEPLOY_ENV\\n**版本**$BUILD_NUMBER\\n**小游戏包**[点击下载]($WXGAME_URL)\}}5.3 资源版本管理与CDN刷新随着版本迭代OSS上会积累大量历史资源包。我们需要管理策略自动清理在构建脚本中可以添加逻辑在上传新版本后使用ossutil列出并删除N天前的旧版本资源。CDN加速如果使用了阿里云CDN对OSS进行加速上传新资源后需要刷新CDN缓存确保测试人员能立即访问到最新资源。可以在脚本最后调用CDN的刷新接口。# 调用阿里云CDN刷新URL REFRESH_URLhttps://cdn.aliyuncs.com/ # ... 使用阿里云CLI或API刷新 $WXGAME_URL 对应的缓存6. 常见问题排查与实战技巧这条路我踩过不少坑这里总结几个最典型的问题1Unity批处理模式构建失败日志显示许可证错误。排查检查/var/lib/jenkins/.local/share/unity3d/目录下的许可证文件。确保已使用正确流程生成并应用了离线许可证。技巧在Jenkins的Shell脚本最前面显式地执行一次许可证激活命令即使之前激活过。或者直接使用-batchmode -nographics -quit -logFile配合已激活的Unity编辑器避免许可证检查问题。问题2构建成功但上传OSS时速度慢或失败。排查检查网络ossutil是否使用了内网Endpoint如果服务器和OSS Bucket在同一地域。使用ossutil cp时加上--jobs 20 --parallel 10参数增加并发数以提高速度。技巧对于大文件或大量文件可以先使用tar命令打包上传一个压缩包然后在目标服务器解压。或者使用ossutil的断点续传功能。问题3微信小游戏包上传后在开发者工具中加载失败。排查首先直接通过浏览器访问OSS上game.json文件的URL看是否能正常打开。检查OSS的Bucket权限是否为“公共读”。检查Unity构建时Player Settings中的“Compression Format”是否设置正确如Disabled或Gzip需要与微信小游戏环境兼容。技巧在构建脚本中上传完成后可以加一个简单的HTTP检查用curl或wget测试一下关键资源URL的可访问性。问题4Jenkins构建时Unity打包过程卡住或无响应。排查查看详细的Unity日志(-logFile指定)。可能是某个Editor脚本有弹窗如Debug.LogError在批处理模式下会导致等待。确保所有自动化脚本都避免任何形式的用户交互。技巧在Unity Editor脚本中使用EditorUtility.DisplayProgressBar时在批处理模式下要小心。最好通过命令行参数或环境变量来控制是否显示进度条。问题5多团队项目AB包依赖管理混乱。技巧在自动化流程中可以加入AB包依赖分析和冗余检查的步骤。编写一个Editor脚本在打包前使用AssetDatabase.GetDependencies和BuildPipeline.GetAssetBundleVariants等API进行分析并将报告输出到日志或在构建失败时发出警告。搭建这样一套系统初期会花费一些时间但一旦运转起来它所带来的效率提升和风险降低是巨大的。从“手动传包”到“一键部署”不仅仅是工具的升级更是团队开发文化和工程成熟度的体现。我的体会是不要试图一步到位构建一个完美的系统先从最痛的点比如 nightly build开始实现一个最小可用的流水线然后随着项目发展逐步加入参数化、多环境、通知、安全扫描等特性。现在就去创建你的第一个Jenkins任务吧。