mirror of
https://github.com/game-ci/unity-builder.git
synced 2026-01-29 12:19:06 +08:00
Compare commits
2 Commits
snyk-fix-b
...
v4.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7f3f70c57 | ||
|
|
c6c8236152 |
22
.github/workflows/cloud-runner-ci-pipeline.yml
vendored
22
.github/workflows/cloud-runner-ci-pipeline.yml
vendored
@@ -3,6 +3,11 @@ name: Cloud Runner CI Pipeline
|
||||
on:
|
||||
push: { branches: [cloud-runner-develop, cloud-runner-preview, main] }
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
runGithubIntegrationTests:
|
||||
description: 'Run GitHub Checks integration tests'
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
permissions:
|
||||
checks: write
|
||||
@@ -207,3 +212,20 @@ jobs:
|
||||
name: ${{ matrix.providerStrategy }} Build (${{ matrix.targetPlatform }})
|
||||
path: ${{ steps.unity-build.outputs.BUILD_ARTIFACT }}
|
||||
retention-days: 14
|
||||
|
||||
githubChecksIntegration:
|
||||
name: GitHub Checks Integration
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'workflow_dispatch' && github.event.inputs.runGithubIntegrationTests == 'true'
|
||||
env:
|
||||
RUN_GITHUB_INTEGRATION_TESTS: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'yarn'
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn test cloud-runner-github-checks-integration-test --detectOpenHandles --forceExit --runInBand
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -56,14 +56,23 @@ namespace UnityBuilderAction
|
||||
// of either `UnityEditor.BuildPlayerOptions` or `UnityEditor.BuildPlayerWithProfileOptions`
|
||||
dynamic buildPlayerOptions;
|
||||
|
||||
if (options["customBuildProfile"] != "") {
|
||||
if (options.TryGetValue("activeBuildProfile", out var buildProfilePath)) {
|
||||
if (string.IsNullOrEmpty(buildProfilePath)) {
|
||||
throw new Exception("`-activeBuildProfile` is set but with an empty value; this shouldn't happen");
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
// Load build profile from Assets folder
|
||||
BuildProfile buildProfile = AssetDatabase.LoadAssetAtPath<BuildProfile>(options["customBuildProfile"]);
|
||||
var buildProfile = AssetDatabase.LoadAssetAtPath<BuildProfile>(buildProfilePath)
|
||||
?? throw new Exception("Build profile file not found at path: " + buildProfilePath);
|
||||
|
||||
// Set it as active
|
||||
BuildProfile.SetActiveBuildProfile(buildProfile);
|
||||
#if !BUILD_PROFILE_LOADED
|
||||
throw new Exception("Build profile's define symbol not present before script execution; shouldn't happen");
|
||||
#endif // BUILD_PROFILE_LOADED
|
||||
|
||||
// no need to set active profile, as already set by `-activeBuildProfile` CLI argument
|
||||
// BuildProfile.SetActiveBuildProfile(buildProfile);
|
||||
Debug.Log($"build profile: {buildProfile.name}");
|
||||
|
||||
// Define BuildPlayerWithProfileOptions
|
||||
buildPlayerOptions = new BuildPlayerWithProfileOptions {
|
||||
@@ -71,12 +80,16 @@ namespace UnityBuilderAction
|
||||
locationPathName = options["customBuildPath"],
|
||||
options = buildOptions,
|
||||
};
|
||||
#else
|
||||
#else // UNITY_6000_0_OR_NEWER
|
||||
throw new Exception("Build profiles are not supported by this version of Unity (" + Application.unityVersion +")");
|
||||
#endif
|
||||
#endif // UNITY_6000_0_OR_NEWER
|
||||
|
||||
} else {
|
||||
|
||||
#if BUILD_PROFILE_LOADED
|
||||
throw new Exception("Build profile's define symbol present; shouldn't happen");
|
||||
#endif // BUILD_PROFILE_LOADED
|
||||
|
||||
// Gather values from project
|
||||
var scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(s => s.path).ToArray();
|
||||
|
||||
|
||||
@@ -21,6 +21,19 @@ namespace UnityBuilderAction.Input
|
||||
EditorApplication.Exit(110);
|
||||
}
|
||||
|
||||
#if UNITY_6000_0_OR_NEWER
|
||||
var buildProfileSupport = true;
|
||||
#else
|
||||
var buildProfileSupport = false;
|
||||
#endif // UNITY_6000_0_OR_NEWER
|
||||
|
||||
string buildProfile;
|
||||
if (buildProfileSupport && validatedOptions.TryGetValue("activeBuildProfile", out buildProfile)) {
|
||||
if (validatedOptions.ContainsKey("buildTarget")) {
|
||||
Console.WriteLine("Extra argument -buildTarget");
|
||||
EditorApplication.Exit(122);
|
||||
}
|
||||
} else {
|
||||
string buildTarget;
|
||||
if (!validatedOptions.TryGetValue("buildTarget", out buildTarget)) {
|
||||
Console.WriteLine("Missing argument -buildTarget");
|
||||
@@ -31,6 +44,7 @@ namespace UnityBuilderAction.Input
|
||||
Console.WriteLine(buildTarget + " is not a defined " + typeof(BuildTarget).Name);
|
||||
EditorApplication.Exit(121);
|
||||
}
|
||||
}
|
||||
|
||||
string customBuildPath;
|
||||
if (!validatedOptions.TryGetValue("customBuildPath", out customBuildPath)) {
|
||||
|
||||
3
dist/platforms/mac/steps/build.sh
vendored
3
dist/platforms/mac/steps/build.sh
vendored
@@ -153,10 +153,11 @@ echo ""
|
||||
-password "$UNITY_PASSWORD" \
|
||||
-customBuildName "$BUILD_NAME" \
|
||||
-projectPath "$UNITY_PROJECT_PATH" \
|
||||
-buildTarget "$BUILD_TARGET" \
|
||||
$( [ -z "$BUILD_PROFILE" ] && echo "-buildTarget $BUILD_TARGET") \
|
||||
-customBuildTarget "$BUILD_TARGET" \
|
||||
-customBuildPath "$CUSTOM_BUILD_PATH" \
|
||||
-customBuildProfile "$BUILD_PROFILE" \
|
||||
${BUILD_PROFILE:+-activeBuildProfile} ${BUILD_PROFILE:+"$BUILD_PROFILE"} \
|
||||
-executeMethod "$BUILD_METHOD" \
|
||||
-buildVersion "$VERSION" \
|
||||
-androidVersionCode "$ANDROID_VERSION_CODE" \
|
||||
|
||||
3
dist/platforms/ubuntu/steps/build.sh
vendored
3
dist/platforms/ubuntu/steps/build.sh
vendored
@@ -125,10 +125,11 @@ unity-editor \
|
||||
$( [ "${MANUAL_EXIT}" == "true" ] || echo "-quit" ) \
|
||||
-customBuildName "$BUILD_NAME" \
|
||||
-projectPath "$UNITY_PROJECT_PATH" \
|
||||
-buildTarget "$BUILD_TARGET" \
|
||||
$( [ -z "$BUILD_PROFILE" ] && echo "-buildTarget $BUILD_TARGET" ) \
|
||||
-customBuildTarget "$BUILD_TARGET" \
|
||||
-customBuildPath "$CUSTOM_BUILD_PATH" \
|
||||
-customBuildProfile "$BUILD_PROFILE" \
|
||||
${BUILD_PROFILE:+-activeBuildProfile} ${BUILD_PROFILE:+"$BUILD_PROFILE"} \
|
||||
-executeMethod "$BUILD_METHOD" \
|
||||
-buildVersion "$VERSION" \
|
||||
-androidVersionCode "$ANDROID_VERSION_CODE" \
|
||||
|
||||
8
dist/platforms/windows/build.ps1
vendored
8
dist/platforms/windows/build.ps1
vendored
@@ -166,7 +166,6 @@ $unityArgs = @(
|
||||
"-customBuildName", "`"$Env:BUILD_NAME`"",
|
||||
"-projectPath", "`"$Env:UNITY_PROJECT_PATH`"",
|
||||
"-executeMethod", "`"$Env:BUILD_METHOD`"",
|
||||
"-buildTarget", "`"$Env:BUILD_TARGET`"",
|
||||
"-customBuildTarget", "`"$Env:BUILD_TARGET`"",
|
||||
"-customBuildPath", "`"$Env:CUSTOM_BUILD_PATH`"",
|
||||
"-customBuildProfile", "`"$Env:BUILD_PROFILE`"",
|
||||
@@ -181,6 +180,13 @@ $unityArgs = @(
|
||||
"-logfile", "-"
|
||||
) + $customParametersArray
|
||||
|
||||
if (-not $Env:BUILD_PROFILE) {
|
||||
$unityArgs += @("-buildTarget", $Env:BUILD_TARGET)
|
||||
}
|
||||
if ($Env:BUILD_PROFILE) {
|
||||
$unityArgs += @("-activeBuildProfile", $Env:BUILD_PROFILE)
|
||||
}
|
||||
|
||||
# Remove null items as that will fail the Start-Process call
|
||||
$unityArgs = $unityArgs | Where-Object { $_ -ne $null }
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ module.exports = {
|
||||
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
|
||||
modulePathIgnorePatterns: ['<rootDir>/lib/', '<rootDir>/dist/'],
|
||||
|
||||
// A list of paths to modules that run some code to configure or set up the testing framework before each test
|
||||
// Files that will be run before Jest is loaded to set globals like fetch
|
||||
setupFiles: ['<rootDir>/src/jest.globals.ts'],
|
||||
// A list of paths to modules that run some code to configure or set up the testing framework after the environment is ready
|
||||
setupFilesAfterEnv: ['<rootDir>/src/jest.setup.ts'],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Integration test for exercising real GitHub check creation and updates.
|
||||
import CloudRunner from '../model/cloud-runner/cloud-runner';
|
||||
import UnityVersioning from '../model/unity-versioning';
|
||||
import GitHub from '../model/github';
|
||||
import { TIMEOUT_INFINITE, createParameters } from '../test-utils/cloud-runner-test-helpers';
|
||||
|
||||
const runIntegration = process.env.RUN_GITHUB_INTEGRATION_TESTS === 'true';
|
||||
const describeOrSkip = runIntegration ? describe : describe.skip;
|
||||
|
||||
describeOrSkip('Cloud Runner Github Checks Integration', () => {
|
||||
it(
|
||||
'creates and updates a real GitHub check',
|
||||
async () => {
|
||||
const buildParameter = await createParameters({
|
||||
versioning: 'None',
|
||||
projectPath: 'test-project',
|
||||
unityVersion: UnityVersioning.read('test-project'),
|
||||
asyncCloudRunner: `true`,
|
||||
githubChecks: `true`,
|
||||
});
|
||||
await CloudRunner.setup(buildParameter);
|
||||
const checkId = await GitHub.createGitHubCheck(`integration create`);
|
||||
expect(checkId).not.toEqual('');
|
||||
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `integration`);
|
||||
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `integration`, `success`, `completed`);
|
||||
},
|
||||
TIMEOUT_INFINITE,
|
||||
);
|
||||
});
|
||||
3
src/jest.globals.ts
Normal file
3
src/jest.globals.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { fetch as undiciFetch, Headers, Request, Response } from 'undici';
|
||||
|
||||
Object.assign(globalThis, { fetch: undiciFetch, Headers, Request, Response });
|
||||
@@ -1,59 +1,65 @@
|
||||
import { BuildParameters } from '../..';
|
||||
import CloudRunner from '../cloud-runner';
|
||||
import UnityVersioning from '../../unity-versioning';
|
||||
import { Cli } from '../../cli/cli';
|
||||
import CloudRunnerOptions from '../options/cloud-runner-options';
|
||||
import setups from './cloud-runner-suite.test';
|
||||
import { OptionValues } from 'commander';
|
||||
import GitHub from '../../github';
|
||||
export const TIMEOUT_INFINITE = 1e9;
|
||||
async function CreateParameters(overrides: OptionValues | undefined) {
|
||||
if (overrides) Cli.options = overrides;
|
||||
|
||||
return BuildParameters.create();
|
||||
}
|
||||
import { TIMEOUT_INFINITE, createParameters } from '../../../test-utils/cloud-runner-test-helpers';
|
||||
describe('Cloud Runner Github Checks', () => {
|
||||
setups();
|
||||
it('Responds', () => {});
|
||||
|
||||
if (CloudRunnerOptions.cloudRunnerDebug) {
|
||||
it(
|
||||
'Check Handling Direct',
|
||||
async () => {
|
||||
// Setup parameters
|
||||
const buildParameter = await CreateParameters({
|
||||
versioning: 'None',
|
||||
projectPath: 'test-project',
|
||||
unityVersion: UnityVersioning.read('test-project'),
|
||||
asyncCloudRunner: `true`,
|
||||
githubChecks: `true`,
|
||||
});
|
||||
await CloudRunner.setup(buildParameter);
|
||||
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`);
|
||||
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`);
|
||||
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`);
|
||||
},
|
||||
TIMEOUT_INFINITE,
|
||||
);
|
||||
it(
|
||||
'Check Handling Via Async Workflow',
|
||||
async () => {
|
||||
// Setup parameters
|
||||
const buildParameter = await CreateParameters({
|
||||
versioning: 'None',
|
||||
projectPath: 'test-project',
|
||||
unityVersion: UnityVersioning.read('test-project'),
|
||||
asyncCloudRunner: `true`,
|
||||
githubChecks: `true`,
|
||||
});
|
||||
GitHub.forceAsyncTest = true;
|
||||
await CloudRunner.setup(buildParameter);
|
||||
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`);
|
||||
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`);
|
||||
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`);
|
||||
GitHub.forceAsyncTest = false;
|
||||
},
|
||||
TIMEOUT_INFINITE,
|
||||
);
|
||||
}
|
||||
beforeEach(() => {
|
||||
// Mock GitHub API requests to avoid real network calls
|
||||
jest.spyOn(GitHub as any, 'createGitHubCheckRequest').mockResolvedValue({
|
||||
status: 201,
|
||||
data: { id: '1' },
|
||||
});
|
||||
jest.spyOn(GitHub as any, 'updateGitHubCheckRequest').mockResolvedValue({
|
||||
status: 200,
|
||||
data: {},
|
||||
});
|
||||
jest.spyOn(GitHub as any, 'runUpdateAsyncChecksWorkflow').mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
it(
|
||||
'Check Handling Direct',
|
||||
async () => {
|
||||
// Setup parameters
|
||||
const buildParameter = await createParameters({
|
||||
versioning: 'None',
|
||||
projectPath: 'test-project',
|
||||
unityVersion: UnityVersioning.read('test-project'),
|
||||
asyncCloudRunner: `true`,
|
||||
githubChecks: `true`,
|
||||
});
|
||||
await CloudRunner.setup(buildParameter);
|
||||
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`direct create`);
|
||||
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `direct`);
|
||||
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `direct`, `success`, `completed`);
|
||||
},
|
||||
TIMEOUT_INFINITE,
|
||||
);
|
||||
it(
|
||||
'Check Handling Via Async Workflow',
|
||||
async () => {
|
||||
// Setup parameters
|
||||
const buildParameter = await createParameters({
|
||||
versioning: 'None',
|
||||
projectPath: 'test-project',
|
||||
unityVersion: UnityVersioning.read('test-project'),
|
||||
asyncCloudRunner: `true`,
|
||||
githubChecks: `true`,
|
||||
});
|
||||
GitHub.forceAsyncTest = true;
|
||||
await CloudRunner.setup(buildParameter);
|
||||
CloudRunner.buildParameters.githubCheckId = await GitHub.createGitHubCheck(`async create`);
|
||||
await GitHub.updateGitHubCheck(`1 ${new Date().toISOString()}`, `async`);
|
||||
await GitHub.updateGitHubCheck(`2 ${new Date().toISOString()}`, `async`, `success`, `completed`);
|
||||
GitHub.forceAsyncTest = false;
|
||||
},
|
||||
TIMEOUT_INFINITE,
|
||||
);
|
||||
});
|
||||
|
||||
11
src/test-utils/cloud-runner-test-helpers.ts
Normal file
11
src/test-utils/cloud-runner-test-helpers.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { BuildParameters } from '../model';
|
||||
import { Cli } from '../model/cli/cli';
|
||||
import { OptionValues } from 'commander';
|
||||
|
||||
export const TIMEOUT_INFINITE = 1e9;
|
||||
|
||||
export async function createParameters(overrides?: OptionValues) {
|
||||
if (overrides) Cli.options = overrides;
|
||||
|
||||
return BuildParameters.create();
|
||||
}
|
||||
@@ -20,7 +20,8 @@ MonoBehaviour:
|
||||
rid: 200022742090383361
|
||||
m_OverrideGlobalSceneList: 0
|
||||
m_Scenes: []
|
||||
m_ScriptingDefines: []
|
||||
m_ScriptingDefines:
|
||||
- BUILD_PROFILE_LOADED
|
||||
m_PlayerSettingsYaml:
|
||||
m_Settings: []
|
||||
references:
|
||||
|
||||
Reference in New Issue
Block a user