Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/build-options.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
"6000.1.*",
"6000.2"
],
"tests": [
"None",
"CompilerWarnings",
"CompilerErrors",
"BuildWarnings",
"BuildErrors",
"PlaymodeTestsErrors",
"EditmodeTestsErrors"
],
"include": [
{
"os": "ubuntu-latest",
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
checks: write # to publish unit test results via checks github api
steps:
- uses: actions/checkout@v6
with:
sparse-checkout: .github/
- uses: RageAgainstThePixel/job-builder@v1
- uses: RageAgainstThePixel/job-builder@development
id: setup-jobs
with:
build-options: ./.github/workflows/build-options.json
Expand All @@ -32,6 +33,7 @@ jobs:
name: build ${{ matrix.jobs.name }}
permissions:
contents: read
checks: write # required by nested unity-build workflow
strategy:
matrix: ${{ fromJSON(needs.setup.outputs.jobs) }}
fail-fast: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish
name: publish
on:
push:
branches: [main]
Expand Down
58 changes: 53 additions & 5 deletions .github/workflows/unity-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ jobs:
strategy:
matrix: ${{ fromJSON(inputs.matrix) }}
fail-fast: false
permissions:
contents: read
checks: write # to publish unit test results via checks github api
defaults:
run:
shell: bash
Expand Down Expand Up @@ -97,12 +100,48 @@ jobs:
else
echo "Skipping build: Unity version $version does not support the build pipeline package (requires 2019.4+)"
fi
- name: Copy selected Unity test
if: ${{ steps.verify-project-path.outputs.RUN_BUILD == 'true' && matrix.tests != '' && matrix.tests != 'None' }}
run: |
set -euo pipefail
test_name="${{ matrix.tests }}"
src="${GITHUB_WORKSPACE}/unity-tests/${test_name}.cs"
if [ ! -f "$src" ]; then
echo "::error::Requested test '$test_name' not found at $src" && exit 1
fi

case "$test_name" in
CompilerWarnings|CompilerErrors)
dest="$UNITY_PROJECT_PATH/Assets/UnityCliTests"
;;
BuildWarnings|BuildErrors)
dest="$UNITY_PROJECT_PATH/Assets/Editor/UnityCliTests"
;;
PlaymodeTestsErrors)
dest="$UNITY_PROJECT_PATH/Assets/Tests/PlayMode/UnityCliTests"
;;
EditmodeTestsErrors)
dest="$UNITY_PROJECT_PATH/Assets/Tests/EditMode/UnityCliTests"
;;
*)
echo "::error::Unknown test selection '$test_name'" && exit 1
;;
esac

mkdir -p "$dest"
cp "$src" "$dest/"
echo "Copied $test_name to $dest"
- name: Install OpenUPM and build pipeline package
if: ${{ steps.verify-project-path.outputs.RUN_BUILD == 'true' }}
working-directory: ${{ env.UNITY_PROJECT_PATH }}
run: |
npm install -g openupm-cli
openupm add com.utilities.buildpipeline
case "${{ matrix.tests }}" in
PlaymodeTestsErrors|EditmodeTestsErrors)
openupm add com.unity.test-framework
;;
esac
- name: Update Android Target Sdk Version
if: ${{ matrix.build-target == 'Android' }}
run: |
Expand All @@ -114,9 +153,11 @@ jobs:
if: ${{ steps.verify-project-path.outputs.RUN_BUILD == 'true' }}
timeout-minutes: 60
run: |
set -euo pipefail
# we don't have to specify the project path or unity editor path as unity-cli will use the environment variables
unity-cli run --log-name Validate -quit -executeMethod Utilities.Editor.BuildPipeline.UnityPlayerBuildTools.ValidateProject -importTMProEssentialsAsset
unity-cli run --log-name Build -buildTarget ${{ matrix.build-target }} -quit -executeMethod Utilities.Editor.BuildPipeline.UnityPlayerBuildTools.StartCommandLineBuild -sceneList Assets/Scenes/SampleScene.unity ${{ matrix.build-args }}
continue-on-error: ${{ matrix.tests != 'None' }}
- name: Uninstall Editor
if: ${{ matrix.unity-version != 'none' }}
run: |
Expand All @@ -132,12 +173,12 @@ jobs:
PACKAGE_MANAGER_LOG_PATH=$(unity-cli package-manager-logs)
LICENSING_CLIENT_LOG_PATH=$(unity-cli licensing-client-logs)
LICENSING_AUDIT_LOG_PATH=$(unity-cli licensing-audit-logs)

echo "Hub Log Path: ${HUB_LOG_PATH}"
echo "Package Manager Log Path: ${PACKAGE_MANAGER_LOG_PATH}"
echo "Licensing Client Log Path: ${LICENSING_CLIENT_LOG_PATH}"
echo "Licensing Audit Log Path: ${LICENSING_AUDIT_LOG_PATH}"

if [ ! -f "${HUB_LOG_PATH}" ]; then
echo "::warning:: Hub log file does not exist at ${HUB_LOG_PATH}"
# find all info-log.json files in ~/.config/unity3d/ - print their paths
Expand All @@ -151,18 +192,25 @@ jobs:
find ~/.config/ -type f -exec echo "{}" \;
echo "::warning:: Hub log file does not exist at any known location"
fi

if [ ! -f "${PACKAGE_MANAGER_LOG_PATH}" ]; then
echo "::warning::Package Manager log file does not exist at ${PACKAGE_MANAGER_LOG_PATH}"
fi

if [ ! -f "${LICENSING_CLIENT_LOG_PATH}" ]; then
echo "::error::Licensing Client log file does not exist at ${LICENSING_CLIENT_LOG_PATH}"
fi

if [ ! -f "${LICENSING_AUDIT_LOG_PATH}" ]; then
echo "::error::Licensing Audit log file does not exist at ${LICENSING_AUDIT_LOG_PATH}"
fi
- name: Upload UTP logs
if: always()
uses: actions/upload-artifact@v6
with:
name: ${{ matrix.os }}-${{ matrix.unity-version }}-${{ matrix.build-target }}-${{ matrix.tests }}-utp-logs
path: '**/*-utp-json.log'
if-no-files-found: ignore
- name: Return License
if: always()
run: unity-cli return-license --license personal
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,5 @@ dist
# Vite logs files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

.artifacts/
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rage-against-the-pixel/unity-cli",
"version": "1.8.1",
"version": "1.8.2",
"description": "A command line utility for the Unity Game Engine.",
"author": "RageAgainstThePixel",
"license": "MIT",
Expand Down
47 changes: 42 additions & 5 deletions src/logging.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as fs from 'fs';
import { UTP } from './utp/utp';

export enum LogLevel {
DEBUG = 'debug',
Expand Down Expand Up @@ -258,19 +259,55 @@ export class Logger {
}
}

public CI_appendWorkflowSummary(telemetry: any[]) {
public CI_appendWorkflowSummary(name: string, telemetry: UTP[]) {
if (telemetry.length === 0) { return; }
switch (this._ci) {
case 'GITHUB_ACTIONS': {
const githubSummary = process.env.GITHUB_STEP_SUMMARY;

if (githubSummary) {
let table = `| Key | Value |\n| --- | ----- |\n`;
telemetry.forEach(item => {
table += `| ${item.key} | ${item.value} |\n`;
});
// for now lets just log the number of items we get per type
const typeCounts: Record<string, number> = {};
for (const entry of telemetry) {
const type = entry.type || 'unknown';

if (!typeCounts[type]) {
typeCounts[type] = 0;
}

typeCounts[type]++;
}

let table = `## ${name} Summary\n\n| Type | Count |\n| --- | ---: |\n`;
for (const [type, count] of Object.entries(typeCounts)) {
table += `| ${type} | ${count} |\n`;
}

// guard against very large summaries over 1MB. Trim at a row boundary to avoid mangled tables.
const byteLimit = 1024 * 1024;
if (Buffer.byteLength(table, 'utf8') > byteLimit) {
const footer = `\n| ... | ... |\n\n***Summary truncated due to size limits.***\n`;
const footerSize = Buffer.byteLength(footer, 'utf8');

const lines = table.split('\n');
let rebuilt = '';

for (const line of lines) {
const nextSize = Buffer.byteLength(rebuilt + line + '\n', 'utf8') + footerSize;

if (nextSize > byteLimit) {
break;
}

rebuilt += `${line}\n`;
}

table = rebuilt + footer;
}

fs.appendFileSync(githubSummary, table, { encoding: 'utf8' });
}
break;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/unity-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ export class UnityEditor {
const baseEditorEnv: NodeJS.ProcessEnv = {
...process.env,
UNITY_THISISABUILDMACHINE: '1',
DISABLE_EMBEDDED_BUILD_PIPELINE_PLUGIN_LOGGING: '1',
...(linuxEnvOverrides ?? {})
};

Expand Down
2 changes: 2 additions & 0 deletions src/unity-logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,8 @@ export function TailLogFile(logPath: string, projectPath: string | undefined): L
if (telemetryFlushed) { return; }
telemetryFlushed = true;
await writeUtpTelemetryLog(utpLogPath, telemetry, logger);
const parsed = path.parse(logPath);
Logger.instance.CI_appendWorkflowSummary(parsed.name, telemetry);
};

const writeStdoutThenTableContent = (content: string, restoreTable: boolean = true): void => {
Expand Down
20 changes: 20 additions & 0 deletions unity-tests/BuildErrors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;

namespace UnityCli.UtpSamples
{
/// <summary>
/// Forces the build pipeline to fail by throwing a BuildFailedException.
/// Place under an Editor folder when copying into a project.
/// </summary>
public class BuildErrors : IPreprocessBuildWithReport
{
public int callbackOrder => 0;

public void OnPreprocessBuild(BuildReport report)
{
throw new System.Exception("Intentional build failure for test matrix coverage.");
}
}
}
20 changes: 20 additions & 0 deletions unity-tests/BuildWarnings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;

namespace UnityCli.UtpSamples
{
/// <summary>
/// Emits a build-time warning via the build pipeline (no custom UTP JSON logging).
/// Place under an Editor folder when copying into a project.
/// </summary>
public class BuildWarnings : IPreprocessBuildWithReport
{
public int callbackOrder => 0;

public void OnPreprocessBuild(BuildReport report)
{
UnityEngine.Debug.LogWarning("Intentional build warning for test matrix coverage.");
}
}
}
4 changes: 4 additions & 0 deletions unity-tests/CompilerErrors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Intentional compiler error for matrix scenario coverage.
#error Intentional compiler error: CS1029

// Note: file is kept minimal so it can be copied into a project to force a build failure.
20 changes: 20 additions & 0 deletions unity-tests/CompilerWarnings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using UnityEngine;

namespace UnityCli.UtpSamples
{
/// <summary>
/// Introduces a benign compiler warning (unused variable) without emitting custom logs.
/// </summary>
public class CompilerWarnings : MonoBehaviour
{
private void Awake()
{
ObsoleteApi(); // CS0618: call to obsolete member
}

[System.Obsolete("Intentional warning for test matrix coverage", false)]
private static void ObsoleteApi()
{
}
}
}
Loading
Loading