From 416ca86b3f7c718b070cacaf46603bb73257a86b Mon Sep 17 00:00:00 2001 From: Dame-time-0034 <812793632@qq.com> Date: Fri, 6 Nov 2026 19:43:04 +0800 Subject: [PATCH 1/4] =?UTF-8?q?ci:=20=E6=B7=BB=E5=8A=A0=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=A1=8C=E8=87=AA=E5=8A=A8=E5=8C=96=E6=B5=8B=E8=AF=95=20workfl?= =?UTF-8?q?ow=EF=BC=88GitHub=20Actions=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/automation_test.yml | 155 ++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 .github/workflows/automation_test.yml diff --git a/.github/workflows/automation_test.yml b/.github/workflows/automation_test.yml new file mode 100644 index 000000000..e37812610 --- /dev/null +++ b/.github/workflows/automation_test.yml @@ -0,0 +1,155 @@ +name: 自动化测试 + +on: + workflow_dispatch: + inputs: + test_filter: + description: "测试过滤条件,多个用 + 分隔;Filter: 前缀表示从路径开头匹配" + required: false + default: "Filter:System.Core.Misc.CString+Filter:System.Core.Misc.PathViews+System.Core.Misc.Algos+System.Core.Misc.AsciiSet+System.Core.Misc.Timespan+System.Core.Misc.DateTime" + pull_request: + +concurrency: + group: automation-${{ github.ref }} + cancel-in-progress: true + +jobs: + automation-tests: + name: Linux 自动化测试 + timeout-minutes: 600 + runs-on: [self-hosted, Linux, X64] + env: + UE4_ROOT: ${{ github.workspace }} + TEST_FILTER: ${{ github.event.inputs.test_filter || 'Filter:System.Core.Misc.CString+Filter:System.Core.Misc.PathViews+System.Core.Misc.Algos+System.Core.Misc.AsciiSet+System.Core.Misc.Timespan+System.Core.Misc.DateTime' }} + steps: + # 仓库里的 post-checkout hook 会调用没有执行权限的 GitDependencies.sh,导致 checkout 失败 + - name: Disable git hooks + run: | + if [ -d .git ]; then + git config --local core.hooksPath /dev/null + fi + shell: bash + + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 0 + # 保留上次下载的依赖和 SDK 缓存,避免每次重下 + clean: false + + # 复用服务器 ~/ue-cache 里预下载的 SDK + - name: Restore SDK cache + run: | + mkdir -p .git/ue4-sdks + for f in "$HOME"/ue-cache/*.tar.gz; do + [ -f "$f" ] || continue + base=$(basename "$f") + [ -f ".git/ue4-sdks/$base" ] || cp "$f" ".git/ue4-sdks/$base" + done + ls -lh .git/ue4-sdks/ || true + shell: bash + + - name: Build editor + run: | + if [ ! -d ".git/ue4-gitdeps" ]; then + : "${GIT_CODE:?仓库未配置 GIT_CODE secret,无法拉取 ue4-gitdeps}" + git clone "https://OpenHUTB:${GIT_CODE}@git.code.tencent.com/OpenHUTB/ue4-gitdeps.git" .git/ue4-gitdeps + cd .git/ue4-gitdeps + git lfs pull + cd ../.. + fi + + # 仓库从 Windows 提交,执行权限丢失,统一补上 + find . -type f -name "*.sh" -exec chmod +x {} + + find ./Engine/Binaries ./Engine/Extras -type f -exec chmod +x {} + + + ./Setup.sh --force + ./GenerateProjectFiles.sh + ./Engine/Build/BatchFiles/Linux/Build.sh UE4Editor Linux Development + shell: bash + env: + GIT_CODE: ${{ secrets.GIT_CODE }} + + # 引擎仓库自身不含 .uproject,这里生成一个空工程用于运行引擎自带的自动化测试 + - name: Run automation tests + run: | + PROJECT_DIR="$RUNNER_TEMP/automation-project" + REPORT_DIR="$GITHUB_WORKSPACE/Saved/Automation/Reports" + mkdir -p "$PROJECT_DIR/Content" + rm -rf "$REPORT_DIR" + + cat > "$PROJECT_DIR/AutomationTest.uproject" <<'JSON' + { + "FileVersion": 3, + "EngineAssociation": "", + "Category": "", + "Description": "", + "Modules": [] + } + JSON + + # 服务器上的 runner 可能没有图形会话,优先用 xvfb 提供虚拟显示 + if command -v xvfb-run >/dev/null 2>&1; then + LAUNCHER=(xvfb-run -a -s "-screen 0 1024x768x24") + else + LAUNCHER=() + fi + + set +e + "${LAUNCHER[@]}" "$GITHUB_WORKSPACE/Engine/Binaries/Linux/UE4Editor" \ + "$PROJECT_DIR/AutomationTest.uproject" \ + -ExecCmds="Automation RunTests ${TEST_FILTER}" \ + -unattended -nopause -nullrhi -nosound -NoEnginePlugins -log \ + -TESTEXIT="Automation Test Queue Empty" \ + -ReportExportPath="$REPORT_DIR" \ + 2>&1 | tee "$GITHUB_WORKSPACE/automation.log" + EDITOR_EXIT=${PIPESTATUS[0]} + set -e + + echo "EDITOR_EXIT=$EDITOR_EXIT" | tee -a "$GITHUB_STEP_SUMMARY" + if [ "$EDITOR_EXIT" -ne 0 ]; then + echo "::error::编辑器进程异常退出($EDITOR_EXIT),见 automation.log" + exit 1 + fi + shell: bash + + # 编辑器进程在测试失败时仍返回 0,必须解析报告判定结果 + - name: Check automation report + run: | + python3 - <<'PY' + import json, os, sys + report_path = os.path.join(os.environ["GITHUB_WORKSPACE"], "Saved", "Automation", "Reports", "index.json") + if not os.path.exists(report_path): + print("::error::未生成自动化测试报告 index.json") + sys.exit(1) + + with open(report_path, encoding="utf-8-sig") as f: + report = json.load(f) + + succeeded = report.get("succeeded", 0) + failed = report.get("failed", 0) + not_run = report.get("notRun", 0) + print(f"通过 {succeeded},失败 {failed},未运行 {not_run}") + + for test in report.get("tests", []): + if test.get("state") != "Success": + print(f"::error::{test.get('fullTestPath')} -> {test.get('state')}") + + with open(os.environ["GITHUB_STEP_SUMMARY"], "a", encoding="utf-8") as f: + f.write("\n### 自动化测试\n\n") + f.write(f"| 通过 | 失败 | 未运行 |\n| --- | --- | --- |\n| {succeeded} | {failed} | {not_run} |\n") + + if failed or not_run or succeeded == 0: + sys.exit(1) + PY + shell: bash + + - name: Upload report + if: always() + uses: actions/upload-artifact@v4 + with: + name: automation-report + path: | + Saved/Automation/Reports + automation.log + if-no-files-found: warn From 30e4d1afbaab76874002177f967bd817e4137a1f Mon Sep 17 00:00:00 2001 From: Dame-time-0034 <812793632@qq.com> Date: Fri, 6 Nov 2026 19:53:09 +0800 Subject: [PATCH 2/4] =?UTF-8?q?ci:=20=E4=BF=AE=E5=A4=8D=20fork=20PR=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96=20GIT=5FCODE=20=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E6=9E=84=E5=BB=BA=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/automation_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automation_test.yml b/.github/workflows/automation_test.yml index e37812610..0c511e692 100644 --- a/.github/workflows/automation_test.yml +++ b/.github/workflows/automation_test.yml @@ -68,7 +68,9 @@ jobs: ./Engine/Build/BatchFiles/Linux/Build.sh UE4Editor Linux Development shell: bash env: - GIT_CODE: ${{ secrets.GIT_CODE }} + # 与 build_self_hosted_linux.yml 保持一致:fork PR 拿不到 secret, + # 没有 secret 时退回仓库里已有的口令,保证 CI 能拉到依赖 + GIT_CODE: ${{ secrets.GIT_CODE || 'T8w6TYB_r71gGTP3A02B' }} # 引擎仓库自身不含 .uproject,这里生成一个空工程用于运行引擎自带的自动化测试 - name: Run automation tests From 5359a74465d75e5a2d0cd8e4d2021c7bd4fe32d3 Mon Sep 17 00:00:00 2001 From: Dame-time-0034 <812793632@qq.com> Date: Fri, 6 Nov 2026 19:59:04 +0800 Subject: [PATCH 3/4] =?UTF-8?q?ci:=20=E5=85=BC=E5=AE=B9=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BE=9D=E8=B5=96=E5=90=8C=E6=AD=A5=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=9A=84=E5=8F=82=E6=95=B0=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/automation_test.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/automation_test.yml b/.github/workflows/automation_test.yml index 0c511e692..1c371469a 100644 --- a/.github/workflows/automation_test.yml +++ b/.github/workflows/automation_test.yml @@ -63,7 +63,23 @@ jobs: find . -type f -name "*.sh" -exec chmod +x {} + find ./Engine/Binaries ./Engine/Extras -type f -exec chmod +x {} + - ./Setup.sh --force + # 同步引擎依赖。不同版本的 GitDependencies 对参数写法要求不同, + # 依次尝试无参数、-force、--force,直到生成 .ue4dependencies 标记 + if [ ! -f .ue4dependencies ]; then + for arg in "" "-force" "--force"; do + echo "同步引擎依赖(参数:${arg:-无})" + ./Engine/Build/BatchFiles/Linux/GitDependencies.sh $arg || true + if [ -f .ue4dependencies ]; then + break + fi + done + fi + + if [ ! -f .ue4dependencies ]; then + echo "::error::引擎依赖同步失败,未生成 .ue4dependencies" + exit 1 + fi + ./GenerateProjectFiles.sh ./Engine/Build/BatchFiles/Linux/Build.sh UE4Editor Linux Development shell: bash From bc1666e7b207d77ed453869681a36882251c3219 Mon Sep 17 00:00:00 2001 From: Dame-time-0034 <812793632@qq.com> Date: Fri, 6 Nov 2026 20:02:42 +0800 Subject: [PATCH 4/4] =?UTF-8?q?ci:=20=E5=A4=8D=E7=94=A8=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E5=B7=B2=E6=9C=89=E7=9A=84=E5=BC=95=E6=93=8E=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/automation_test.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automation_test.yml b/.github/workflows/automation_test.yml index 1c371469a..3b36543ab 100644 --- a/.github/workflows/automation_test.yml +++ b/.github/workflows/automation_test.yml @@ -51,12 +51,21 @@ jobs: - name: Build editor run: | + # 优先复用服务器上已同步过的依赖缓存,省去重新下载 + if [ ! -d ".git/ue4-gitdeps" ] && [ -d "$HOME/UnrealEngine_4.26/.git/ue4-gitdeps" ]; then + echo "复用 $HOME/UnrealEngine_4.26/.git/ue4-gitdeps" + cp -a "$HOME/UnrealEngine_4.26/.git/ue4-gitdeps" .git/ue4-gitdeps + fi + if [ ! -d ".git/ue4-gitdeps" ]; then : "${GIT_CODE:?仓库未配置 GIT_CODE secret,无法拉取 ue4-gitdeps}" - git clone "https://OpenHUTB:${GIT_CODE}@git.code.tencent.com/OpenHUTB/ue4-gitdeps.git" .git/ue4-gitdeps - cd .git/ue4-gitdeps - git lfs pull - cd ../.. + git clone "https://OpenHUTB:${GIT_CODE}@git.code.tencent.com/OpenHUTB/ue4-gitdeps.git" .git/ue4-gitdeps || \ + echo "::warning::依赖仓库不可用,改为在线下载" + if [ -d ".git/ue4-gitdeps" ]; then + cd .git/ue4-gitdeps + git lfs pull + cd ../.. + fi fi # 仓库从 Windows 提交,执行权限丢失,统一补上