SPEC-6276 Move ci_build and ci_build_metrics to scripts\build

This commit is contained in:
Esteban Papp
2021-04-14 14:40:42 -07:00
committed by GitHub
parent 9c01e993db
commit 4a3d24f189
161 changed files with 42 additions and 14760 deletions
+1 -1
View File
@@ -201,7 +201,7 @@ def CheckoutBootstrapScripts(String branchName) {
sparseCheckoutPaths: [
[ $class: "SparseCheckoutPath", path: "scripts/build/Jenkins/" ],
[ $class: "SparseCheckoutPath", path: "scripts/build/bootstrap/" ],
[ $class: "SparseCheckoutPath", path: "Tools/build/JenkinsScripts/build/Platform" ]
[ $class: "SparseCheckoutPath", path: "scripts/build/Platform" ]
]
],
[
+5 -5
View File
@@ -1,12 +1,12 @@
{
"BUILD_ENTRY_POINT": "Tools/build/JenkinsScripts/build/ci_build.py",
"BUILD_ENTRY_POINT": "scripts/build/ci_build.py",
"PIPELINE_CONFIGS": [
"Tools/build/JenkinsScripts/build/Platform/*/pipeline.json",
"restricted/*/Tools/build/JenkinsScripts/build/pipeline.json"
"scripts/build/Platform/*/pipeline.json",
"restricted/*/scripts/build/pipeline.json"
],
"BUILD_CONFIGS": [
"Tools/build/JenkinsScripts/build/Platform/*/build_config.json",
"restricted/*/Tools/build/JenkinsScripts/build/build_config.json"
"scripts/build/Platform/*/build_config.json",
"restricted/*/scripts/build/build_config.json"
],
"PYTHON_DIR": "python"
}
@@ -0,0 +1,45 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
CALL %~dp0gradle_windows.cmd
IF NOT %ERRORLEVEL%==0 GOTO :error
IF NOT EXIST "%LY_3RDPARTY_PATH%" (
ECHO [ci_build] LY_3RDPARTY_PATH is invalid or not set
GOTO :error
)
IF NOT EXIST "%LY_ANDROID_SDK%" (
SET LY_ANDROID_SDK=!LY_3RDPARTY_PATH!/android-sdk/platform-29
)
IF NOT EXIST "%LY_ANDROID_SDK%" (
ECHO [ci_build] FAIL: LY_ANDROID_SDK=!LY_ANDROID_SDK!
GOTO :error
)
SET ANDROID_SDK_ROOT=%LY_ANDROID_SDK%
ECHO "ANDROID_SDK_ROOT=!ANDROID_SDK_ROOT!"
SET PYTHON=python\python.cmd
ECHO [ci_build] %PYTHON% scripts\build\Platform\Android\run_test_on_android_simulator.py --android-sdk-path %LY_ANDROID_SDK% --build-path %OUTPUT_DIRECTORY% --build-config %CONFIGURATION%
CALL %PYTHON% scripts\build\Platform\Android\run_test_on_android_simulator.py --android-sdk-path %LY_ANDROID_SDK% --build-path %OUTPUT_DIRECTORY% --build-config %CONFIGURATION%
IF NOT %ERRORLEVEL%==0 GOTO :popd_error
EXIT /b 0
:popd_error
POPD
:error
ECHO ERROR
EXIT /b 1
@@ -0,0 +1,167 @@
{
"clean": {
"TAGS": [],
"COMMAND": "../Windows/clean_windows.cmd",
"PARAMETERS": {
"OUTPUT_DIRECTORY": "build",
"CMAKE_LY_PROJECTS": "AutomatedTesting"
}
},
"profile_pipe": {
"TAGS": [
"default"
],
"steps": [
"profile"
]
},
"metrics": {
"TAGS":[
"weekly"
],
"COMMAND":"../Windows/python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH":"scripts/build/ci_build_metrics.py",
"SCRIPT_PARAMETERS":"--platform Android --jobname \"!JOB_NAME!\" --jobnumber \"!BUILD_NUMBER!\" --jobnode \"!NODE_NAME!\" --changelist \"!CHANGE_ID!\""
}
},
"debug": {
"TAGS":[
"nightly",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"debug",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
}
},
"profile": {
"TAGS":[
"weekly-build-metrics",
"daily-pipeline-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
}
},
"profile_nounity": {
"TAGS":[
"nightly",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
}
},
"asset_profile": {
"TAGS":[
"default",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_asset_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\windows_vs2019",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"AssetProcessorBatch",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"ASSET_PROCESSOR_BINARY": "bin\\profile\\AssetProcessorBatch.exe",
"ASSET_PROCESSOR_OPTIONS": "/zeroAnalysisMode --regset=\"/Amazon/AssetProcessor/Settings/Exclude Android/pattern=.*/DiffuseGlobalIllumination/.*precompiledshader\"",
"ASSET_PROCESSOR_PLATFORMS":"es3"
}
},
"asset_clean_profile": {
"TAGS":[
"nightly"
],
"PIPELINE_ENV": {
"CLEAN_ASSETS": "1"
},
"steps": [
"clean",
"asset_profile"
]
},
"release": {
"TAGS":[
"nightly",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"release",
"OUTPUT_DIRECTORY":"build\\android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
}
},
"monolithic_release": {
"TAGS":[
"nightly",
"weekly-build-metrics"
],
"COMMAND":"../Windows/build_ninja_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"release",
"OUTPUT_DIRECTORY":"build\\mono_android",
"CMAKE_OPTIONS":"-G \"Ninja Multi-Config\" -DCMAKE_TOOLCHAIN_FILE=cmake\\Platform\\Android\\Toolchain_android.cmake -DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID_ARM_NEON=FALSE -DANDROID_NATIVE_API_LEVEL=21 -DLY_NDK_DIR=\"!LY_3RDPARTY_PATH!\\android-ndk\\r21d\" -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AutomatedTesting",
"CMAKE_TARGET":"all",
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
}
},
"gradle": {
"TAGS":[
"weekly-build-metrics"
],
"COMMAND":"gradle_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android_gradle",
"GAME_PROJECT": "AutomatedTesting",
"ANDROID_NDK_PLATFORM": "21",
"ANDROID_SDK_PLATFORM": "29",
"SIGN_APK": "false",
"GRADLE_BUILD_CMD": "build",
"ADDITIONAL_GENERATE_ARGS": ""
}
},
"periodic_test_profile": {
"TAGS":[
"nightly",
"weekly-build-metrics"
],
"COMMAND":"build_and_run_unit_tests.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"build\\android_unittest",
"GAME_PROJECT": "AutomatedTesting",
"ANDROID_NDK_PLATFORM": "21",
"ANDROID_SDK_PLATFORM": "29",
"SIGN_APK": "true",
"GRADLE_BUILD_CMD": "assemble",
"ADDITIONAL_GENERATE_ARGS": "--unit-test"
}
}
}
@@ -0,0 +1,213 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
IF NOT EXIST "%LY_3RDPARTY_PATH%" (
ECHO [ci_build] LY_3RDPARTY_PATH is invalid or not set
GOTO :error
)
IF NOT EXIST "%GRADLE_HOME%" (
REM This is the default for developers
SET GRADLE_HOME=C:\Gradle\gradle-5.6.4
)
IF NOT EXIST "%GRADLE_HOME%" (
ECHO [ci_build] FAIL: GRADLE_HOME=%GRADLE_HOME%
GOTO :error
)
IF NOT EXIST "%CMAKE_HOME%" (
SET CMAKE_HOME=%LY_3RDPARTY_PATH%/CMake/3.19.1/Windows/
)
IF NOT EXIST "%CMAKE_HOME%" (
ECHO [ci_build] FAIL: CMAKE_HOME=%CMAKE_HOME%
GOTO :error
)
IF NOT EXIST "%LY_NINJA_PATH%" (
SET LY_NINJA_PATH=%LY_3RDPARTY_PATH%/ninja/1.10.1/Windows
)
IF NOT EXIST "%LY_NINJA_PATH%" (
ECHO [ci_build] FAIL: LY_NINJA_PATH=%LY_NINJA_PATH%
GOTO :error
)
REM Make sure that Ninja in the Path variable
ECHO Testing ninja on the current path variable
call ninja --version
IF %ERRORLEVEL%==0 GOTO ninja_on_path
ECHO Ninja wasnt in the call path, add the value set by LY_NINJA_PATH
SET PATH=%PATH%;%LY_NINJA_PATH%
:ninja_on_path
IF NOT EXIST "%LY_ANDROID_SDK%" (
SET LY_ANDROID_SDK=!LY_3RDPARTY_PATH!/android-sdk/platform-29
)
IF NOT EXIST "%LY_ANDROID_SDK%" (
ECHO [ci_build] FAIL: LY_ANDROID_SDK=!LY_ANDROID_SDK!
GOTO :error
)
IF NOT EXIST "%LY_ANDROID_NDK%" (
set LY_ANDROID_NDK=!LY_3RDPARTY_PATH!/android-ndk/r21d
)
IF NOT EXIST "%LY_ANDROID_NDK%" (
ECHO [ci_build] LY_ANDROID_NDK=!LY_ANDROID_NDK!
GOTO :error
)
IF NOT EXIST %OUTPUT_DIRECTORY% (
mkdir %OUTPUT_DIRECTORY%
)
REM Jenkins reports MSB8029 when TMP/TEMP is not defined, define a dummy folder
SET TMP=%cd%/temp
SET TEMP=%cd%/temp
IF NOT EXIST %TMP% (
mkdir %TMP%
)
REM Optionally sign the APK if we are generating an APK
SET GENERATE_SIGNED_APK=false
IF "%SIGN_APK%"=="true" (
IF "%GRADLE_BUILD_CMD%"=="assemble" (
SET GENERATE_SIGNED_APK=true
)
)
SET PYTHON=python\python.cmd
REM Regardless of whether or not we generate a signing key, apparently we must set variables outside of
REM an IF clause otherwise it will not work.
REM First look for the JDK HOME in the environment variable
IF EXIST "%JDK_HOME%" (
ECHO JDK Home found in Environment: !JDK_HOME!
GOTO JDK_FOUND
)
REM Next, look in the registry
FOR /F "skip=2 tokens=1,2*" %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\1.8" /v "JavaHome" 2^>nul') DO (
SET JDK_REG_VALUE=%%C
)
IF EXIST "%JDK_REG_VALUE%" (
SET JDK_HOME=!JDK_REG_VALUE!
ECHO JDK Home found in registry: !JDK_HOME!
GOTO JDK_FOUND
)
ECHO Unable to locate JDK_HOME
GOTO error
:JDK_FOUND
SET JDK_BIN=%JDK_HOME%\bin
IF NOT EXIST "%JDK_BIN%" (
ECHO The environment variable JDK_HOME is not set to a valid JDK 1.8 folder %JDK_BIN%
ECHO Make sure the variable is set to your local JDK 1.8 installation
GOTO error
)
SET KEYTOOL_PATH=%JDK_BIN%\keytool.exe
IF NOT EXIST "%KEYTOOL_PATH%" (
ECHO The environment variable JDK_HOME is not set to a valid JDK 1.8 folder. Cannot find keytool at %JDK_BIN%\keytool.exe
ECHO Make sure the variable is set to your local JDK 1.8 installation
GOTO error
)
SET CI_ANDROID_KEYSTORE_FILE=ly-android-dev.keystore
SET CI_ANDROID_KEYSTORE_ALIAS=ly-android
SET CI_ANDROID_KEYSTORE_PASSWORD=lumberyard
SET CI_ANDROID_KEYSTORE_DN=cn=LY Developer, ou=Lumberyard, o=Amazon, c=US
SET CI_KEYSTORE_VALIDITY_DAYS=10000
SET CI_KEYSTORE_CERT_DN=cn=LY Developer, ou=Lumberyard, o=Amazon, c=US
REM Clear out any existing keystore file since the password/alias may have changed
SET CI_ANDROID_KEYSTORE_FILE_ABS=%cd%\%OUTPUT_DIRECTORY%\%CI_ANDROID_KEYSTORE_FILE%
IF "%GENERATE_SIGNED_APK%"=="true" (
REM Prepare a temporary keystore just for this unit test session
REM Generate the keystore file if needed
IF NOT EXIST "%CI_ANDROID_KEYSTORE_FILE_ABS%" (
ECHO [ci_build] Generating keystore file %CI_ANDROID_KEYSTORE_FILE%
ECHO [ci_build] "%KEYTOOL_PATH%" -genkeypair -v -keystore %CI_ANDROID_KEYSTORE_FILE_ABS% -storepass %CI_ANDROID_KEYSTORE_PASSWORD% -alias %CI_ANDROID_KEYSTORE_ALIAS% -keypass %CI_ANDROID_KEYSTORE_PASSWORD% -keyalg RSA -keysize 2048 -validity %CI_KEYSTORE_VALIDITY_DAYS% -dname "%CI_KEYSTORE_CERT_DN%"
CALL "%KEYTOOL_PATH%" -genkeypair -v -keystore %CI_ANDROID_KEYSTORE_FILE_ABS% -storepass %CI_ANDROID_KEYSTORE_PASSWORD% -alias %CI_ANDROID_KEYSTORE_ALIAS% -keypass %CI_ANDROID_KEYSTORE_PASSWORD% -keyalg RSA -keysize 2048 -validity %CI_KEYSTORE_VALIDITY_DAYS% -dname "%CI_KEYSTORE_CERT_DN%" 2> nul
IF errorlevel 1 (
ECHO Unable to generate keystore file "%CI_ANDROID_KEYSTORE_FILE_ABS%"
GOTO error
)
) ELSE (
ECHO Using keystore file at %CI_ANDROID_KEYSTORE_FILE_ABS%
)
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %OPTIONAL_TEST_FLAG% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% --signconfig-store-file %CI_ANDROID_KEYSTORE_FILE_ABS% --signconfig-store-password %CI_ANDROID_KEYSTORE_PASSWORD% --signconfig-key-alias %CI_ANDROID_KEYSTORE_ALIAS% --signconfig-key-password %CI_ANDROID_KEYSTORE_PASSWORD% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
) ELSE (
ECHO [ci_build] %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
CALL %PYTHON% cmake\Tools\Platform\Android\generate_android_project.py --engine-root=. --build-dir=%OUTPUT_DIRECTORY% -g %GAME_PROJECT% --gradle-install-path=%GRADLE_HOME% --cmake-install-path=%CMAKE_HOME% --ninja-install-path=%LY_NINJA_PATH% --third-party-path=%LY_3RDPARTY_PATH% --android-ndk-path=%LY_ANDROID_NDK% --android-sdk-path=%LY_ANDROID_SDK% --android-ndk-version=%ANDROID_NDK_PLATFORM% --android-sdk-version=%ANDROID_SDK_PLATFORM% %ADDITIONAL_GENERATE_ARGS% --overwrite-existing
)
REM Validate the android project generation
IF %ERRORLEVEL%==0 GOTO generate_project_success
ECHO Error Generating Android Project
goto error
:generate_project_success
REM Run the gradle build from the output directory
PUSHD %OUTPUT_DIRECTORY%
REM Stop any running or orphaned gradle daemon
ECHO [ci_build] gradlew --stop
CALL gradlew --stop
ECHO [ci_build] gradlew --no-daemon %GRADLE_BUILD_CMD%%CONFIGURATION%
CALL gradlew --no-daemon %GRADLE_BUILD_CMD%%CONFIGURATION%
IF %ERRORLEVEL%==0 GOTO gradle_build_success
REM Do another build with the debug flag to try to get the failure reasons
GOTO error
ECHO Error building gradle. Rebuilding with debug information
ECHO [ci_build] gradlew --debug --full-stacktrace --no-daemon %GRADLE_BUILD_CMD%%CONFIGURATION%
CALL gradlew --debug --full-stacktrace --no-daemon %GRADLE_BUILD_CMD%%CONFIGURATION%
ECHO [ci_build] gradlew --stop
CALL gradlew --stop
POPD
GOTO error
:gradle_build_success
ECHO [ci_build] gradlew --stop
CALL gradlew --stop
POPD
EXIT /b 0
:popd_error
POPD
:error
EXIT /b 1
@@ -0,0 +1,18 @@
{
"ENV": {
"GRADLE_HOME": "C:/Gradle/gradle-5.6.4",
"NODE_LABEL": "windows-047e5cdf",
"LY_3RDPARTY_PATH": "C:/ly/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "D:/workspace",
"MOUNT_VOLUME": true
},
"PIPELINE_ENV_OVERRIDE": {
"daily-pipeline-metrics": {
"CLEAN_WORKSPACE": true
},
"packaging": {
"CLEAN_WORKSPACE": true
}
}
}
@@ -0,0 +1,544 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import os
import pathlib
import re
import sys
import subprocess
import time
import logging
CURRENT_PATH = pathlib.Path(os.path.dirname(__file__)).absolute()
ENGINE_ROOT = CURRENT_PATH.parent.parent.parent.parent.parent.parent
class AndroidEmuError(Exception):
pass
def get_android_sdk_path():
try:
android_sdk_path = pathlib.Path(os.getenv('LY_ANDROID_SDK'))
if not android_sdk_path:
raise AndroidEmuError(f"LY_ANDROID_SDK environment variable is not set")
if not android_sdk_path.is_dir():
raise AndroidEmuError(f"Android SDK Path ('{android_sdk_path}') set with the LY_ANDROID_SDK variable is invalid")
#TODO: Sanity check on necessary files
return android_sdk_path
except Exception as err:
raise AndroidEmuError(f"Unable to determine android SDK path: {err}")
class Command(object):
def __init__(self, tool_name, tool_path, run_as_shell=True):
if not tool_path.is_file():
raise AndroidEmuError(f"Invalid path for {tool_name}. Cannot find ('{tool_path.absolute()}')")
self.tool_path = tool_path
self.run_as_shell = run_as_shell
def run_return_output(self, cmd_args):
args = [str(self.tool_path)]
if isinstance(cmd_args, str):
args.append(cmd_args)
elif isinstance(cmd_args, list):
args.extend(cmd_args)
else:
assert False, "run_return_output argument must be a string or list of strings"
full_cmd = subprocess.list2cmdline(args)
logging.debug(f"run_return_output: {full_cmd}")
run_result = subprocess.run(args,
capture_output=True,
encoding='UTF-8',
errors='ignore',
shell=self.run_as_shell)
if run_result.returncode != 0:
raise AndroidEmuError(f"Error executing command '{full_cmd}' (return code {run_result.returncode}): {run_result.stderr}")
return run_result.stdout
def run(self, cmd_args, cwd=None, suppress_output=False):
args = [str(self.tool_path)]
if isinstance(cmd_args, str):
args.append(cmd_args)
elif isinstance(cmd_args, list):
args.extend(cmd_args)
else:
assert False, "run_return_output argument must be a string or list of strings"
full_cmd = subprocess.list2cmdline(args)
logging.debug(f"run: {full_cmd}")
run_result = subprocess.run(args,
#stdout=subprocess.DEVNULL if suppress_output else subprocess.STDOUT,
capture_output=False,
shell=self.run_as_shell,
cwd=cwd)
if run_result.returncode != 0:
raise AndroidEmuError(f"Error executing command '{full_cmd}' (return code {run_result.returncode}): {run_result.stderr}")
def run_process(self, cmd_args):
args = [str(self.tool_path)]
if isinstance(cmd_args, str):
args.append(cmd_args)
elif isinstance(cmd_args, list):
args.extend(cmd_args)
else:
assert False, "run_return_output argument must be a string or list of strings"
full_cmd = subprocess.list2cmdline(args)
logging.debug(f"run_process: {full_cmd}")
process = subprocess.Popen(args,
shell=True,
stdout=subprocess.PIPE,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.NORMAL_PRIORITY_CLASS |
subprocess.CREATE_NO_WINDOW,
encoding='UTF-8',
errors='ignore')
return process
class AndroidEmulatorManager(object):
UNIT_TEST_AVD_NAME = "LY_UNITTEST_AVD"
UNIT_TEST_SYSTEM_IMAGE_PACKAGE = "android-30;google_apis;x86_64"
UNIT_TEST_DEVICE_TEMPLATE_NAME = "pixel_xl"
UNIT_TEST_DEVICE_SETTINGS_MAP = {
"disk.dataPartition.size": "32G",
"vm.heapSize": "1024",
"hw.ramSize": "2048",
"hw.sdCard": "no"
}
EMULATOR_STARTUP_TIMEOUT_SECS = 60*5 # Set the emulator startup timeout to 5 minutes
def __init__(self, base_android_sdk_path, hide_emulator_windows=True, force_avd_creation=False, emulator_startup_timeout=EMULATOR_STARTUP_TIMEOUT_SECS):
self.android_sdk_path = base_android_sdk_path
self.force_avd_creation = force_avd_creation
self.unit_test_avd_name = AndroidEmulatorManager.UNIT_TEST_AVD_NAME
self.unit_test_device_template_name = AndroidEmulatorManager.UNIT_TEST_DEVICE_TEMPLATE_NAME
self.unit_test_device_settings_map = AndroidEmulatorManager.UNIT_TEST_DEVICE_SETTINGS_MAP
self.unit_test_avd_system_image = AndroidEmulatorManager.UNIT_TEST_SYSTEM_IMAGE_PACKAGE
self.hide_emulator_windows = hide_emulator_windows
self.emulator_startup_timeout = emulator_startup_timeout
self.emulator_cmd = Command("Emulator", self.android_sdk_path / 'emulator' / 'emulator.exe')
self.avd_manager_cmd = Command("AVD Manager", self.android_sdk_path / 'tools' / 'bin' / 'avdmanager.bat')
self.sdk_manager_cmd = Command("SDK Manager", self.android_sdk_path / 'tools' / 'bin' / 'sdkmanager.bat')
self.adb_cmd = Command("ADB", self.android_sdk_path / 'platform-tools' / 'adb.exe')
def collect_android_sdk_list(self):
"""
Use the SDK Manager to get the list of installed, available, and updateable packages
:return: tuple of 3 lists: installed, available, and updateable packages
"""
result_str = self.sdk_manager_cmd.run_return_output(['--list'])
# the result will be listed out in 3 sections: Installed packages, Available Packages, and Available updates
# and each item is represented by 3 columns separated by a '|' character
installed_packages = []
available_packages = []
available_updates = []
current_append_list = None
for avd_item in result_str.split('\n'):
avd_item_stripped = avd_item.strip()
if not avd_item_stripped:
continue
if '|' not in avd_item_stripped:
if avd_item_stripped.upper() == 'INSTALLED PACKAGES:':
current_append_list = installed_packages
elif avd_item_stripped.upper() == 'AVAILABLE PACKAGES:':
current_append_list = available_packages
elif avd_item_stripped.upper() == 'AVAILABLE UPDATES:':
current_append_list = available_updates
else:
current_append_list = None
continue
item_parts = [split.strip() for split in avd_item_stripped.split('|')]
if len(item_parts) < 3:
continue
elif item_parts[1].upper() in ('VERSION', 'INSTALLED', '-------'):
continue
elif current_append_list is None:
continue
if current_append_list is not None:
current_append_list.append(item_parts)
return installed_packages, available_packages, available_updates
def install_system_package_if_necessary(self):
"""
Make sure that we have the correct system image installed, and install if not
"""
installed_packages, available_packages, _ = self.collect_android_sdk_list()
unit_test_sdk_package_name = f'system-images;{self.unit_test_avd_system_image}'
detected_sdk_package_version = None
for package_line_items in installed_packages:
if package_line_items[0] == unit_test_sdk_package_name:
detected_sdk_package_version = package_line_items[0]
if detected_sdk_package_version:
# Already installed
logging.info(f"Detected installed system image {self.unit_test_avd_system_image} version {detected_sdk_package_version}")
return
# Make sure its an available image to install
detected_available_sdk_package_version = None
for package_line_items in available_packages:
if package_line_items[0] == unit_test_sdk_package_name:
detected_available_sdk_package_version = package_line_items[0]
if not detected_available_sdk_package_version:
raise AndroidEmuError(f"Unable to install required system image {self.unit_test_avd_system_image}, not found by the Android SDK Manager")
# Install the package
logging.info(f"Installing system image {self.unit_test_avd_system_image}...")
self.sdk_manager_cmd.run(['--install', unit_test_sdk_package_name])
logging.info(f"Installed Completed")
def find_device_id_by_name(self, device_name):
"""
Find a device id (from AVD Manager) by the device name
:param device_name: Name to lookup
:return: The device id
"""
result_str = self.avd_manager_cmd.run_return_output(['list', 'device'])
result_lines = [result_line.strip() for result_line in result_str.split('\n')]
result_line_count = len(result_lines)
current_index = 0
device_to_id_map = {}
while current_index < result_line_count:
current_line = result_lines[current_index]
current_index += 1
# This assumes the pattern "id: <id> or "<device name>"
if current_line.startswith('id:') and 'or' in current_line:
id_and_name_combo = current_line.split('or')
id_and_value_combo = id_and_name_combo[0].split(' ')
name = id_and_name_combo[1].replace('"', '').strip().upper()
id = id_and_value_combo[1]
device_to_id_map[name] = id
if current_line.startswith('Available Android targets:'):
break
device_id = device_to_id_map.get(device_name.upper())
if not device_id:
raise AndroidEmuError(f"Unable to locate device id for '{device_name}'")
return device_id
def query_installed_avds(self):
"""
Get maps of all valid and invalid AVDs installed on the current system
:return: tuple of 2 maps (AVD Name -> Path): Valid and invalid
"""
result_str = self.avd_manager_cmd.run_return_output(['list', 'avd'])
result_lines = [result_line.strip() for result_line in result_str.split('\n')]
line_count = len(result_lines)
current_index = 0
current_name = None
current_path = None
valid_avd_to_path_map = {}
invalid_avd_to_path_map = {}
current_avd_to_path_map = valid_avd_to_path_map
while current_index < line_count:
current_line = result_lines[current_index]
current_index += 1
if current_line.startswith('Name:'):
name = current_line[6:].strip()
if current_name is not None:
current_avd_to_path_map[current_name] = current_path
current_path = None
current_name = name
elif current_line.startswith('Path:'):
current_path = current_line[6:].strip()
elif current_line.startswith('Device:'):
pass
elif 'could not be loaded:' in current_line:
if current_name is not None:
current_avd_to_path_map[current_name] = current_path
current_avd_to_path_map = invalid_avd_to_path_map
current_path = None
current_name = None
if current_name is not None:
current_avd_to_path_map[current_name] = current_path
return valid_avd_to_path_map, invalid_avd_to_path_map
def create_unitest_avd(self):
"""Create the unit test AVD"""
self.install_system_package_if_necessary()
device_id = self.find_device_id_by_name(self.unit_test_device_template_name)
self.avd_manager_cmd.run(['--silent',
'create', 'avd',
'--name', self.unit_test_avd_name,
'--package', f'system-images;{self.unit_test_avd_system_image}',
'--device', device_id])
valid_avd_map, _ = self.query_installed_avds()
unit_test_avd_path = valid_avd_map.get(self.unit_test_avd_name)
if not unit_test_avd_path:
raise AndroidEmuError(f"Unable to create unit test AVD {self.unit_test_avd_name}")
unit_test_avd_config_path = pathlib.Path(unit_test_avd_path) / 'config.ini'
if not unit_test_avd_config_path.is_file():
raise AndroidEmuError(f"Unable to create unit test AVD {self.unit_test_avd_name}: The expected config file '{unit_test_avd_config_path}' does not exist.")
config_content_full = unit_test_avd_config_path.read_text(encoding='UTF-8', errors='ignore')
for item, value in self.unit_test_device_settings_map.items():
regex_friendly_str = item.replace('.', '\\.')
repl_pattern = f"{regex_friendly_str}\\s*=\\s*[\\d]+"
repl_value = f"{item}={value}"
if re.search(repl_pattern, config_content_full):
config_content_full = re.sub(repl_pattern, repl_value, config_content_full)
else:
if not config_content_full.endswith('\n'):
config_content_full += '\n'
config_content_full += f"{repl_value}\n"
unit_test_avd_config_path.write_text(config_content_full)
def query_emulator_device_id(self):
result_str = self.adb_cmd.run_return_output(['devices', '-l'])
emulators = []
for result_line in result_str.split('\n'):
if not result_line.startswith('emulator-'):
continue
emulator = result_line[:result_line.find(' ')].strip()
emulators.append(emulator)
if len(emulators) > 1:
logging.warning(f"Found multiple emulators connect ({','.join(emulators)}). Defaulting to {emulators[0]}")
return emulators[0] if len(emulators) > 0 else None
def install_unit_test_avd(self):
"""
Install the unit test AVD (Android Virtual Device)
"""
valid_avd_map, invalid_avd_map = self.query_installed_avds()
if not self.unit_test_avd_name in valid_avd_map:
create_avd = True
elif self.force_avd_creation or self.unit_test_avd_name in invalid_avd_map:
logging.info(f"Deleting AVD {self.unit_test_avd_name}..")
self.avd_manager_cmd.run(['delete', 'avd', '--name', self.unit_test_avd_name])
create_avd = True
else:
create_avd = False
if create_avd:
self.create_unitest_avd()
def uninstall_unit_test_avd(self):
"""
Uninstall the unit test AVD
"""
logging.info(f"Uninstalling AVD {self.unit_test_avd_name}..")
self.avd_manager_cmd.run(['delete', 'avd', '--name', self.unit_test_avd_name])
def launch_emulator_process(self):
"""
Launch the emulator process for the unit test avd and return the process handle and its device id
:return: tuple of the process handle and the device id for the emulator
"""
emulator_device_id = None
process = None
try:
# Launch the emulator process
emulator_process_args = [
"-avd",
self.unit_test_avd_name
]
if self.hide_emulator_windows:
emulator_process_args.append("-no-window")
process = self.emulator_cmd.run_process(emulator_process_args)
# Wait for the emulator to signal that its bootup is complete
boot_completed = False
start_time = time.time()
timeout_secs = 360
while process.poll() is None:
elapsed_time = time.time() - start_time
if elapsed_time > timeout_secs > 0:
break
line = process.stdout.readline()
print(line, end='')
if "boot completed" in line:
boot_completed = True
break
if not boot_completed:
raise AndroidEmuError("Bootup of emulator timed out")
# query ADB to get the emulator ID
emulator_device_id = self.query_emulator_device_id()
return process, emulator_device_id
except Exception:
if process:
if emulator_device_id:
self.terminate_emulator_process(emulator_device_id)
else:
process.kill()
raise
def terminate_emulator_process(self, device_id):
# Terminate the emulator
kill_emu_args = [
'-s', device_id,
'emu', 'kill'
]
self.adb_cmd.run(kill_emu_args)
def run_emulation_process(self, process_func):
"""
Execute a function that relies on the session based android simulator.
:param process_func: The process function to execute. Function requires one argument which will be the device id
:return: The return value of the process function
"""
emulator_device_id = None
try:
emulator_process, emulator_device_id = self.launch_emulator_process()
return process_func(emulator_device_id)
finally:
if emulator_device_id is not None:
self.terminate_emulator_process(emulator_device_id)
def process_unit_test_on_simulator(base_android_sdk_path, build_path, build_config):
"""
Run the android unit tests on a sessioned simulator
:param base_android_sdk_path: The path to where the Android SDK exists
:param build_path: The build path relative to the engine root where the android unit test project is configured and built
:param build_config: The configuration of the build unit test APK to run
"""
python_cmd = Command("Python", ENGINE_ROOT / 'python' / 'python.cmd')
android_script_root = ENGINE_ROOT / 'cmake' / 'Tools' / 'Platform' / 'Android'
assert android_script_root.is_dir(), "Missing the android scripts path in the engine folder hierarchy"
deploy_android_py_path = android_script_root / 'deploy_android.py'
assert deploy_android_py_path.is_file(), "Missing the android deployment script in the engine folder hierarchy"
launch_android_ptest_py_path = android_script_root / 'launch_android_test.py'
assert launch_android_ptest_py_path.is_file(), "Missing the android unit test launcher script in the engine folder hierarchy"
def _install_and_run_unit_tests(emulator_id):
# install unit test on the emulator
install_apk_args = [
str(deploy_android_py_path),
'-b', build_path,
'-c', build_config,
'--device-id-filter', emulator_id,
'--clean'
]
python_cmd.run(cmd_args=install_apk_args,
cwd=os.path.normpath(str(ENGINE_ROOT)))
try:
# Launch the unit test on the emulator
launch_apk_args = [
str(launch_android_ptest_py_path),
'-b', build_path,
'-c', build_config,
'--device-serial', emulator_id
]
python_cmd.run(cmd_args=launch_apk_args,
cwd=os.path.normpath(str(ENGINE_ROOT)))
return True
except AndroidEmuError:
print("\n\n")
raise AndroidEmuError("Unit Tests Failed")
# Prepare the emulator manager
manager = AndroidEmulatorManager(base_android_sdk_path=base_android_sdk_path,
force_avd_creation=True)
# First Install or overwrite the unit test emulator
manager.install_unit_test_avd()
# Run the emulator-dependent process based on the session AVD created by the manager
manager.run_emulation_process(_install_and_run_unit_tests)
# Uninstall the AVD when done
manager.uninstall_unit_test_avd()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Install and an android unit test APK on a android simulator.")
parser.add_argument('--android-sdk-path',
help='Path to the Android SDK')
parser.add_argument('--build-path',
help='The build path (relative to the engine root) where the project was generated and the APK is built',
required=True)
parser.add_argument('--build-config',
help='The build config of the built APK',
required=True)
parser.add_argument('--debug',
help='Enable debug messages from this script',
action="store_true")
parsed_args = parser.parse_args(sys.argv[1:])
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG if parsed_args.debug else logging.INFO)
try:
base_android_sdk_path = pathlib.Path(parsed_args.android_sdk_path) if parsed_args.android_sdk_path else get_android_sdk_path()
process_unit_test_on_simulator(base_android_sdk_path=base_android_sdk_path,
build_path=parsed_args.build_path,
build_config=parsed_args.build_config)
exit(0)
except AndroidEmuError as e:
print(e)
exit(1)
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if [[ ! -d $OUTPUT_DIRECTORY ]]; then
echo [ci_build] Error: $OUTPUT_DIRECTORY was not found
exit 1
fi
pushd $OUTPUT_DIRECTORY
if [[ ! -e $ASSET_PROCESSOR_BINARY ]]; then
echo [ci_build] Error: $ASSET_PROCESSOR_BINARY was not found
exit 1
fi
for project in $(echo $CMAKE_LY_PROJECTS | sed "s/;/ /g")
do
echo [ci_build] ${ASSET_PROCESSOR_BINARY} $ASSET_PROCESSOR_OPTIONS --project-path=$project --platforms=$ASSET_PROCESSOR_PLATFORMS
${ASSET_PROCESSOR_BINARY} $ASSET_PROCESSOR_OPTIONS --project-path=$project --platforms=$ASSET_PROCESSOR_PLATFORMS
done
popd
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/build_linux.sh
source $BASEDIR/asset_linux.sh
@@ -0,0 +1,173 @@
{
"clean": {
"TAGS": [],
"COMMAND": "clean_linux.sh",
"PARAMETERS": {
"OUTPUT_DIRECTORY": "build",
"CMAKE_LY_PROJECTS": "AutomatedTesting"
}
},
"profile_pipe": {
"TAGS": [
"default"
],
"steps": [
"profile_nounity",
"asset_profile",
"test_profile"
]
},
"metrics": {
"TAGS": [
"weekly"
],
"COMMAND": "python_linux.sh",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/ci_build_metrics.py",
"SCRIPT_PARAMETERS": "--platform Linux --jobname '${JOB_NAME}' --jobnumber '${BUILD_NUMBER}' --jobnode '${NODE_NAME}' --changelist '${CHANGE_ID}'"
}
},
"debug": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
},
"profile": {
"TAGS": [
"nightly",
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
},
"profile_nounity": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
},
"test_profile": {
"TAGS": [
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "build_test_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all",
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
}
},
"asset_profile": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_asset_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
"ASSET_PROCESSOR_OPTIONS": "/zeroAnalysisMode",
"ASSET_PROCESSOR_PLATFORMS": "pc,server"
}
},
"asset_clean_profile": {
"TAGS": [
"nightly"
],
"PIPELINE_ENV": {
"CLEAN_ASSETS": "1"
},
"steps": [
"clean",
"asset_profile"
]
},
"periodic_test_profile": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
}
},
"benchmark_test_profile": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
}
},
"release": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
},
"monolithic_release": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_linux.sh",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mono_linux",
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all"
}
}
}
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/env_linux.sh
mkdir -p ${OUTPUT_DIRECTORY}
SOURCE_DIRECTORY=${PWD}
pushd $OUTPUT_DIRECTORY
LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt
CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'"
if [[ ! -e "CMakeCache.txt" ]]; then
echo [ci_build] First run, generating
RUN_CONFIGURE=1
elif [[ ! -e ${LAST_CONFIGURE_CMD_FILE} ]]; then
echo [ci_build] Last run command not found, generating
RUN_CONFIGURE=1
else
# Detect if the input has changed
LAST_CMD=$(<${LAST_CONFIGURE_CMD_FILE})
if [[ "${LAST_CMD}" != "${CONFIGURE_CMD}" ]]; then
echo [ci_build] Last run command different, generating
RUN_CONFIGURE=1
fi
fi
if [[ ! -z "$RUN_CONFIGURE" ]]; then
# have to use eval since $CMAKE_OPTIONS (${EXTRA_CMAKE_OPTIONS}) contains quotes that need to be processed
echo [ci_build] ${CONFIGURE_CMD}
eval ${CONFIGURE_CMD}
# Save the run only if success
echo "${CONFIGURE_CMD}" > ${LAST_CONFIGURE_CMD_FILE}
fi
echo [ci_build] cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(grep -c processor /proc/cpuinfo) -- ${CMAKE_NATIVE_BUILD_ARGS}
cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(grep -c processor /proc/cpuinfo) -- ${CMAKE_NATIVE_BUILD_ARGS}
popd
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/build_linux.sh
source $BASEDIR/test_linux.sh
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if [[ -n "$CLEAN_ASSETS" ]]; then
echo "[ci_build] CLEAN_ASSETS option set"
for project in $(echo $CMAKE_LY_PROJECTS | sed "s/;/ /g")
do
if [[ -d "$project/Cache" ]]; then
echo "[ci_build] Deleting \"$project/Cache\""
rm -rf $project/Cache
fi
done
fi
if [[ -n "$CLEAN_OUTPUT_DIRECTORY" ]]; then
echo "[ci_build] CLEAN_OUTPUT_DIRECTORY option set"
if [[ -d $OUTPUT_DIRECTORY ]]; then
echo "[ci_build] Deleting \"${OUTPUT_DIRECTORY}\""
rm -rf ${OUTPUT_DIRECTORY}
fi
fi
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if ! command -v cmake &> /dev/null; then
if [[ -z $LY_CMAKE_PATH ]]; then LY_CMAKE_PATH=${LY_3RDPARTY_PATH}/CMake/3.19.1/Linux/bin; fi
if [[ ! -d $LY_CMAKE_PATH ]]; then
echo "[ci_build] CMake path not found"
exit 1
fi
PATH=${LY_CMAKE_PATH}:${PATH}
if ! command -v cmake &> /dev/null; then
echo "[ci_build] CMake not found"
exit 1
fi
fi
if ! command -v ninja &> /dev/null; then
if [[ -z $LY_NINJA_PATH ]]; then LY_NINJA_PATH=${LY_3RDPARTY_PATH}/ninja/1.10.1/Linux; fi
if [[ ! -d $LY_NINJA_PATH ]]; then
echo "[ci_build] Ninja path not found"
exit 1
fi
PATH=${LY_NINJA_PATH}:${PATH}
if ! command -v ninja &> /dev/null; then
echo "[ci_build] Ninja not found"
exit 1
fi
fi
@@ -0,0 +1,17 @@
{
"ENV": {
"NODE_LABEL": "linux",
"LY_3RDPARTY_PATH": "/home/lybuilder/ly/workspace/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "/data/workspace",
"MOUNT_VOLUME": true
},
"PIPELINE_ENV_OVERRIDE": {
"daily-pipeline-metrics": {
"CLEAN_WORKSPACE": true
},
"packaging": {
"CLEAN_WORKSPACE": true
}
}
}
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
echo [ci_build] python/python.sh -u ${SCRIPT_PATH} ${SCRIPT_PARAMETERS}
python/python.sh -u ${SCRIPT_PATH} ${SCRIPT_PARAMETERS}
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/env_linux.sh
if [[ ! -d $OUTPUT_DIRECTORY ]]; then
echo [ci_build] Error: $OUTPUT_DIRECTORY was not found
exit 1
fi
pushd $OUTPUT_DIRECTORY
# Find the CTEST_RUN_FLAGS from cmake's cache variables, then replace the $<CONFIG> with the current configuration
IFS='=' read -ra CTEST_RUN_FLAGS <<< $(cmake -N -LA . | grep "CTEST_RUN_FLAGS:STRING")
CTEST_RUN_FLAGS=${CTEST_RUN_FLAGS[1]/$<CONFIG>/${CONFIGURATION}}
# Run ctest
echo [ci_build] ctest ${CTEST_RUN_FLAGS} ${CTEST_OPTIONS}
ctest ${CTEST_RUN_FLAGS} ${CTEST_OPTIONS}
popd
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if [[ ! -d $OUTPUT_DIRECTORY ]]; then
echo [ci_build] Error: $OUTPUT_DIRECTORY was not found
exit 1
fi
pushd $OUTPUT_DIRECTORY
if [[ ! -e $ASSET_PROCESSOR_BINARY ]]; then
echo [ci_build] Error: $ASSET_PROCESSOR_BINARY was not found
exit 1
fi
for project in $(echo $CMAKE_LY_PROJECTS | sed "s/;/ /g")
do
echo [ci_build] ${ASSET_PROCESSOR_BINARY} $ASSET_PROCESSOR_OPTIONS --project-path=$project --platforms=$ASSET_PROCESSOR_PLATFORMS
${ASSET_PROCESSOR_BINARY} $ASSET_PROCESSOR_OPTIONS --project-path=$project --platforms=$ASSET_PROCESSOR_PLATFORMS
done
popd
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/build_mac.sh
source $BASEDIR/asset_mac.sh
@@ -0,0 +1,167 @@
{
"clean": {
"TAGS": [],
"COMMAND": "clean_mac.sh",
"PARAMETERS": {
"OUTPUT_DIRECTORY": "build",
"CMAKE_LY_PROJECTS": "AutomatedTesting"
}
},
"profile_pipe": {
"TAGS": [
"nightly"
],
"steps": [
"profile",
"asset_profile"
]
},
"metrics": {
"TAGS": [
"weekly"
],
"COMMAND": "python_mac.sh",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/ci_build_metrics.py",
"SCRIPT_PARAMETERS": "--platform Mac --jobname '${JOB_NAME}' --jobnumber '${BUILD_NUMBER}' --jobnode '${NODE_NAME}' --changelist '${CHANGE_ID}'"
}
},
"debug": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
},
"profile": {
"TAGS": [
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
},
"profile_nounity": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
},
"asset_profile": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_asset_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
"ASSET_PROCESSOR_OPTIONS": "/zeroAnalysisMode",
"ASSET_PROCESSOR_PLATFORMS": "osx_gl"
}
},
"asset_clean_profile": {
"TAGS": [
"nightly"
],
"PIPELINE_ENV": {
"CLEAN_ASSETS": "1"
},
"steps": [
"clean",
"asset_profile"
]
},
"periodic_test_profile": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
}
},
"benchmark_test_profile": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
}
},
"release": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
},
"monolithic_release": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/mono_mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD"
}
},
"mac_packaging_all": {
"TAGS": [
"packaging"
],
"COMMAND": "python_mac.sh",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/package/package.py",
"SCRIPT_PARAMETERS": "--platform Mac --type all"
}
}
}
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/env_mac.sh
mkdir -p ${OUTPUT_DIRECTORY}
SOURCE_DIRECTORY=${PWD}
pushd $OUTPUT_DIRECTORY
LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt
CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'"
if [[ ! -e "CMakeCache.txt" ]]; then
echo [ci_build] First run, generating
RUN_CONFIGURE=1
elif [[ ! -e ${LAST_CONFIGURE_CMD_FILE} ]]; then
echo [ci_build] Last run command not found, generating
RUN_CONFIGURE=1
else
# Detect if the input has changed
LAST_CMD=$(<${LAST_CONFIGURE_CMD_FILE})
if [[ "${LAST_CMD}" != "${CONFIGURE_CMD}" ]]; then
echo [ci_build] Last run command different, generating
RUN_CONFIGURE=1
fi
fi
if [[ ! -z "$RUN_CONFIGURE" ]]; then
# have to use eval since $CMAKE_OPTIONS (${EXTRA_CMAKE_OPTIONS}) contains quotes that need to be processed
echo [ci_build] ${CONFIGURE_CMD}
eval ${CONFIGURE_CMD}
# Save the run only if success
echo "${CONFIGURE_CMD}" > ${LAST_CONFIGURE_CMD_FILE}
fi
echo [ci_build] cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS}
cmake --build . --target ${CMAKE_TARGET} --config ${CONFIGURATION} -j $(sysctl -n hw.ncpu) -- ${CMAKE_NATIVE_BUILD_ARGS}
popd
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/build_mac.sh
source $BASEDIR/test_mac.sh
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if [[ -n "$CLEAN_ASSETS" ]]; then
echo "[ci_build] CLEAN_ASSETS option set"
for project in $(echo $CMAKE_LY_PROJECTS | sed "s/;/ /g")
do
if [[ -d "$project/Cache" ]]; then
echo "[ci_build] Deleting \"$project/Cache\""
rm -rf $project/Cache
fi
done
fi
if [[ -n "$CLEAN_OUTPUT_DIRECTORY" ]]; then
echo "[ci_build] CLEAN_OUTPUT_DIRECTORY option set"
if [[ -d $OUTPUT_DIRECTORY ]]; then
echo "[ci_build] Deleting \"${OUTPUT_DIRECTORY}\""
rm -rf ${OUTPUT_DIRECTORY}
fi
fi
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
if ! command -v cmake &> /dev/null; then
if [[ -z $LY_CMAKE_PATH ]]; then LY_CMAKE_PATH=${LY_3RDPARTY_PATH}/CMake/3.19.1/Mac/CMake.app/Contents/bin; fi
if [[ ! -d $LY_CMAKE_PATH ]]; then
echo "[ci_build] CMake path not found"
exit 1
fi
PATH=${LY_CMAKE_PATH}:${PATH}
if ! command -v cmake &> /dev/null; then
echo "[ci_build] CMake not found"
exit 1
fi
fi
+17
View File
@@ -0,0 +1,17 @@
{
"ENV": {
"NODE_LABEL": "mac",
"LY_3RDPARTY_PATH": "/Users/lybuilder/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "/Users/lybuilder/workspace",
"MOUNT_VOLUME": false
},
"PIPELINE_ENV_OVERRIDE": {
"daily-pipeline-metrics": {
"CLEAN_WORKSPACE": true
},
"packaging": {
"CLEAN_WORKSPACE": true
}
}
}
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
echo [ci_build] python/python.sh -u ${SCRIPT_PATH} ${SCRIPT_PARAMETERS}
python/python.sh -u ${SCRIPT_PATH} ${SCRIPT_PARAMETERS}
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set -o errexit # exit on the first failure encountered
BASEDIR=$(dirname "$0")
source $BASEDIR/env_mac.sh
if [[ ! -d $OUTPUT_DIRECTORY ]]; then
echo [ci_build] Error: $OUTPUT_DIRECTORY was not found
exit 1
fi
pushd $OUTPUT_DIRECTORY
# Find the CTEST_RUN_FLAGS from the CMakeCache.txt file, then replace the $<CONFIG> with the current configuration
IFS='=' read -ra CTEST_RUN_FLAGS <<< $(cmake -N -LA . | grep "CTEST_RUN_FLAGS:STRING")
CTEST_RUN_FLAGS=${CTEST_RUN_FLAGS[1]/$<CONFIG>/${CONFIGURATION}}
# Run ctest
echo [ci_build] ctest ${CTEST_RUN_FLAGS} ${CTEST_OPTIONS}
ctest ${CTEST_RUN_FLAGS} ${CTEST_OPTIONS}
popd
@@ -0,0 +1,39 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
IF NOT EXIST %OUTPUT_DIRECTORY% (
ECHO [ci_build] Error: %OUTPUT_DIRECTORY% was not found
GOTO :error
)
PUSHD %OUTPUT_DIRECTORY%
IF NOT EXIST %ASSET_PROCESSOR_BINARY% (
ECHO [ci_build] Error: %ASSET_PROCESSOR_BINARY% was not found
GOTO :error
)
FOR %%P in (%CMAKE_LY_PROJECTS%) do (
ECHO [ci_build] %ASSET_PROCESSOR_BINARY% %ASSET_PROCESSOR_OPTIONS% --project-path=%%P --platforms=%ASSET_PROCESSOR_PLATFORMS%
%ASSET_PROCESSOR_BINARY% %ASSET_PROCESSOR_OPTIONS% --project-path=%%P --platforms=%ASSET_PROCESSOR_PLATFORMS%
IF NOT !ERRORLEVEL!==0 GOTO :popd_error
)
POPD
EXIT /b 0
:popd_error
POPD
:error
EXIT /b 1
@@ -0,0 +1,22 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
CALL "%~dp0build_windows.cmd"
IF NOT %ERRORLEVEL%==0 GOTO :error
CALL "%~dp0asset_windows.cmd"
IF NOT %ERRORLEVEL%==0 GOTO :error
EXIT /b 0
:error
EXIT /b 1
@@ -0,0 +1,285 @@
{
"clean": {
"TAGS": [],
"COMMAND": "clean_windows.cmd",
"PARAMETERS": {
"OUTPUT_DIRECTORY": "build",
"CMAKE_LY_PROJECTS": "AutomatedTesting"
}
},
"validation_pipe": {
"TAGS": [
"default"
],
"steps": [
"validation"
]
},
"debug_vs2019_pipe": {
"TAGS": [
"nightly"
],
"steps": [
"debug_vs2019",
"test_debug_vs2019"
]
},
"profile_vs2019_pipe": {
"TAGS": [
"default"
],
"steps": [
"profile_vs2019",
"asset_profile_vs2019",
"test_cpu_profile_vs2019"
]
},
"scrubbing": {
"TAGS": [],
"COMMAND": "python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/scrubbing_job.py"
}
},
"validation": {
"TAGS": [],
"COMMAND": "python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/commit_validation/validate_file_or_folder.py"
}
},
"metrics": {
"TAGS": [
"weekly"
],
"COMMAND": "python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/ci_build_metrics.py",
"SCRIPT_PARAMETERS": "--platform Windows --jobname \"!JOB_NAME!\" --jobnumber \"!BUILD_NUMBER!\" --jobnode \"!NODE_NAME!\" --changelist \"!CHANGE_ID!\""
}
},
"windows_packaging_all": {
"TAGS": [
"packaging"
],
"COMMAND": "python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/package/package.py",
"SCRIPT_PARAMETERS": "--platform Windows --type all"
}
},
"3rdParty_all": {
"TAGS": [
"packaging"
],
"COMMAND": "python_windows.cmd",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/package/package.py",
"SCRIPT_PARAMETERS": "--platform 3rdParty --type 3rdParty_all"
}
},
"debug_vs2019": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
},
"test_debug_vs2019": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_BUILD_WITH_INCREMENTAL_LINKING_DEBUG=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_smoke|SUITE_main)\" -LE \"(REQUIRES_gpu)\" -T Test"
}
},
"profile_vs2019": {
"TAGS": [
"project",
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
},
"profile_vs2019_nounity": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
},
"test_cpu_profile_vs2019": {
"TAGS": [
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_smoke|SUITE_main)\" -LE \"(REQUIRES_gpu)\" -T Test"
}
},
"test_gpu_profile_vs2019": {
"TAGS":[
"nightly"
],
"PIPELINE_ENV":{
"NODE_LABEL":"windows-gpu"
},
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_smoke TEST_SUITE_main",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_smoke_REQUIRES_gpu|SUITE_main_REQUIRES_gpu)\" -T Test"
}
},
"asset_profile_vs2019": {
"TAGS": [
"weekly-build-metrics"
],
"COMMAND": "build_asset_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"ASSET_PROCESSOR_BINARY": "bin\\profile\\AssetProcessorBatch.exe",
"ASSET_PROCESSOR_OPTIONS": "/zeroAnalysisMode",
"ASSET_PROCESSOR_PLATFORMS": "pc,server"
}
},
"asset_clean_profile_vs2019": {
"TAGS": [
"nightly"
],
"PIPELINE_ENV": {
"CLEAN_ASSETS": "1"
},
"steps": [
"clean",
"asset_profile_vs2019"
]
},
"periodic_test_profile_vs2019": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\" -T Test"
}
},
"sandbox_test_profile_vs2019": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"PIPELINE_ENV": {
"ON_FAILURE_MARK": "UNSTABLE"
},
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_sandbox",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_sandbox)\" -T Test"
}
},
"benchmark_test_profile_vs2019": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_test_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo",
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\" -T Test"
}
},
"release_vs2019": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
},
"monolithic_release_vs2019": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build\\mono_windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_MONOLITHIC_GAME=TRUE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
}
}
@@ -0,0 +1,30 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
IF NOT EXIST "%LY_NINJA_PATH%" (
SET LY_NINJA_PATH=%LY_3RDPARTY_PATH%/ninja/1.10.1/Windows
)
IF NOT EXIST "%LY_NINJA_PATH%" (
ECHO [ci_build] FAIL: LY_NINJA_PATH=%LY_NINJA_PATH%
GOTO :error
)
PATH %LY_NINJA_PATH%;%PATH%
CALL "%~dp0build_windows.cmd"
IF NOT %ERRORLEVEL%==0 GOTO :error
EXIT /b 0
:error
EXIT /b 1
@@ -0,0 +1,22 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
CALL "%~dp0build_windows.cmd"
IF NOT %ERRORLEVEL%==0 GOTO :error
CALL "%~dp0test_windows.cmd"
IF NOT %ERRORLEVEL%==0 GOTO :error
EXIT /b 0
:error
EXIT /b 1
@@ -0,0 +1,73 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
CALL %~dp0env_windows.cmd
IF NOT EXIST "%OUTPUT_DIRECTORY%" (
MKDIR %OUTPUT_DIRECTORY%.
)
SET SOURCE_DIRECTORY=%CD%
PUSHD %OUTPUT_DIRECTORY%
ECHO [ci_build] cmake --version
cmake --version
IF ERRORLEVEL 1 (
ECHO [ci_build] CMAKE not found!
exit /b 1
)
REM Jenkins reports MSB8029 when TMP/TEMP is not defined, define a dummy folder
SET TMP=%cd%/temp
SET TEMP=%cd%/temp
IF NOT EXIST %TMP% (
MKDIR temp
)
REM Compute half the amount of processors so some jobs can run
SET /a HALF_PROCESSORS = NUMBER_OF_PROCESSORS / 2
SET LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt
SET CONFIGURE_CMD=cmake %SOURCE_DIRECTORY% %CMAKE_OPTIONS% %EXTRA_CMAKE_OPTIONS% -DLY_3RDPARTY_PATH="%LY_3RDPARTY_PATH%" -DLY_PROJECTS=%CMAKE_LY_PROJECTS%
IF NOT EXIST CMakeCache.txt (
ECHO [ci_build] First run, generating
SET RUN_CONFIGURE=1
) ELSE IF NOT EXIST %LAST_CONFIGURE_CMD_FILE% (
ECHO [ci_build] Last run command not found, generating
SET RUN_CONFIGURE=1
) ELSE (
REM Detect if the input has changed
FOR /F "delims=" %%x in (%LAST_CONFIGURE_CMD_FILE%) DO SET LAST_CMD=%%x
IF !LAST_CMD! NEQ !CONFIGURE_CMD! (
ECHO [ci_build] Last run command different, generating
SET RUN_CONFIGURE=1
)
)
IF DEFINED RUN_CONFIGURE (
ECHO [ci_build] %CONFIGURE_CMD%
%CONFIGURE_CMD%
IF NOT !ERRORLEVEL!==0 GOTO :error
ECHO !CONFIGURE_CMD!> %LAST_CONFIGURE_CMD_FILE%
)
ECHO [ci_build] cmake --build . --target %CMAKE_TARGET% --config %CONFIGURATION% %CMAKE_BUILD_ARGS% -- %CMAKE_NATIVE_BUILD_ARGS%
cmake --build . --target %CMAKE_TARGET% --config %CONFIGURATION% %CMAKE_BUILD_ARGS% -- %CMAKE_NATIVE_BUILD_ARGS%
IF NOT %ERRORLEVEL%==0 GOTO :error
POPD
EXIT /b 0
:error
POPD
EXIT /b 1
@@ -0,0 +1,31 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
IF DEFINED CLEAN_ASSETS (
ECHO [ci_build] CLEAN_ASSETS option set
FOR %%P in (%CMAKE_LY_PROJECTS%) do (
IF EXIST %%P\Cache (
ECHO [ci_build] Deleting "%%P\Cache"
DEL /s /q /f %%P\Cache 1>nul
)
)
)
IF DEFINED CLEAN_OUTPUT_DIRECTORY (
ECHO [ci_build] CLEAN_OUTPUT_DIRECTORY option set
IF EXIST %OUTPUT_DIRECTORY% (
ECHO [ci_build] Deleting "%OUTPUT_DIRECTORY%"
DEL /s /q /f %OUTPUT_DIRECTORY% 1>nul
)
)
@@ -0,0 +1,31 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
where /Q cmake
IF NOT %ERRORLEVEL%==0 (
IF "%LY_CMAKE_PATH%"=="" (SET LY_CMAKE_PATH=%LY_3RDPARTY_PATH%/CMake/3.19.1/Windows/bin)
IF NOT EXIST !LY_CMAKE_PATH! (
ECHO [ci_build] CMake path not found
GOTO :error
)
PATH !LY_CMAKE_PATH!;!PATH!
where /Q cmake
IF NOT !ERRORLEVEL!==0 (
ECHO [ci_build] CMake not found
GOTO :error
)
)
EXIT /b 0
:error
EXIT /b 1
@@ -0,0 +1,24 @@
{
"profile_vs2017_atom": {
"COMMAND": "build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "windows_vs2017",
"CMAKE_OPTIONS": "-G \"Visual Studio 15 2017\" -A x64 -T host=x64 -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AtomTest;AtomSampleViewer",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m:4 /p:CL_MPCount=!HALF_PROCESSORS! /nologo"
}
},
"profile_vs2019_atom": {
"COMMAND":"build_windows.cmd",
"PARAMETERS": {
"CONFIGURATION":"profile",
"OUTPUT_DIRECTORY":"windows_vs2019",
"CMAKE_OPTIONS":"-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS":"AtomTest;AtomSampleViewer",
"CMAKE_TARGET":"ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
}
}
@@ -0,0 +1,17 @@
{
"ENV": {
"NODE_LABEL": "windows-047e5cdf",
"LY_3RDPARTY_PATH": "C:/ly/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "D:/workspace",
"MOUNT_VOLUME": true
},
"PIPELINE_ENV_OVERRIDE": {
"daily-pipeline-metrics": {
"CLEAN_WORKSPACE": true
},
"packaging": {
"CLEAN_WORKSPACE": true
}
}
}
@@ -0,0 +1,18 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
ECHO [ci_build] python/python.cmd -u %SCRIPT_PATH% %SCRIPT_PARAMETERS%
CALL python/python.cmd -u %SCRIPT_PATH% %SCRIPT_PARAMETERS%
EXIT /b %ERRORLEVEL%
@@ -0,0 +1,41 @@
@ECHO OFF
REM
REM All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
REM its licensors.
REM
REM For complete copyright and license terms please see the LICENSE at the root of this
REM distribution (the "License"). All use of this software is governed by the License,
REM or, if provided, by the license below or the license accompanying this file. Do not
REM remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
REM
SETLOCAL EnableDelayedExpansion
CALL %~dp0env_windows.cmd
IF NOT EXIST %OUTPUT_DIRECTORY% (
ECHO [ci_build] Error: $OUTPUT_DIRECTORY was not found
GOTO :error
)
PUSHD %OUTPUT_DIRECTORY%
REM Find the CTEST_RUN_FLAGS from cmake's cache variables, then replace the $<CONFIG> with the current configuration
FOR /F "tokens=2 delims==" %%V IN ('cmake -N -LA . ^| findstr /I CTEST_RUN_FLAGS:STRING') do (
SET CTEST_RUN_FLAGS=%%V
)
SET CTEST_RUN_FLAGS=%CTEST_RUN_FLAGS:$<CONFIG>=!CONFIGURATION!%
REM Run ctest
ECHO [ci_build] ctest !CTEST_RUN_FLAGS! !CTEST_OPTIONS!
ctest !CTEST_RUN_FLAGS! !CTEST_OPTIONS!
IF NOT %ERRORLEVEL%==0 GOTO :popd_error
POPD
EXIT /b 0
:popd_error
POPD
:error
EXIT /b 1
@@ -0,0 +1,110 @@
{
"clean": {
"TAGS": [],
"COMMAND": "../Mac/clean_mac.sh",
"PARAMETERS": {
"OUTPUT_DIRECTORY": "build",
"CMAKE_LY_PROJECTS": "AutomatedTesting"
}
},
"metrics": {
"TAGS": [
"weekly"
],
"COMMAND": "../Mac/python_mac.sh",
"PARAMETERS": {
"SCRIPT_PATH": "scripts/build/ci_build_metrics.py",
"SCRIPT_PARAMETERS": "--platform iOS --jobname '${JOB_NAME}' --jobnumber '${BUILD_NUMBER}' --jobnode '${NODE_NAME}' --changelist '${CHANGE_ID}'"
}
},
"debug": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "debug",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
}
},
"profile": {
"TAGS": [
"nightly",
"daily-pipeline-metrics",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
}
},
"profile_nounity": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
}
},
"asset_profile": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_asset_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build/mac",
"CMAKE_OPTIONS": "-G Xcode -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "AssetProcessorBatch",
"ASSET_PROCESSOR_BINARY": "bin/profile/AssetProcessorBatch",
"ASSET_PROCESSOR_OPTIONS": "/zeroAnalysisMode",
"ASSET_PROCESSOR_PLATFORMS": "ios"
}
},
"asset_clean_profile": {
"TAGS": [
"nightly"
],
"PIPELINE_ENV": {
"CLEAN_ASSETS": "true"
},
"steps": [
"clean",
"asset_profile"
]
},
"release": {
"TAGS": [
"nightly",
"weekly-build-metrics"
],
"COMMAND": "../Mac/build_mac.sh",
"PARAMETERS": {
"CONFIGURATION": "release",
"OUTPUT_DIRECTORY": "build/ios",
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
}
}
}
+17
View File
@@ -0,0 +1,17 @@
{
"ENV": {
"NODE_LABEL": "mac",
"LY_3RDPARTY_PATH": "/Users/lybuilder/3rdParty",
"TIMEOUT": 30,
"WORKSPACE": "/Users/lybuilder/workspace",
"MOUNT_VOLUME": false
},
"PIPELINE_ENV_OVERRIDE": {
"daily-pipeline-metrics": {
"CLEAN_WORKSPACE": true
},
"packaging": {
"CLEAN_WORKSPACE": true
}
}
}
+104
View File
@@ -0,0 +1,104 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import json
import os
import sys
import subprocess
def parse_args():
cur_dir = os.path.dirname(os.path.abspath(__file__))
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--platform', dest="build_platform", help="Platform to build")
parser.add_argument('-t', '--type', dest="build_type", help="Target config type to build")
parser.add_argument('-c', '--config', dest="build_config_filename",
default="build_config.json",
help="JSON filename in Platform/<platform> that defines build configurations for the platform")
args = parser.parse_args()
# Input validation
if args.build_platform is None:
print('[ci_build] No platform specified')
sys.exit(-1)
if args.build_type is None:
print('[ci_build] No type specified')
sys.exit(-1)
return args
def build(build_config_filename, build_platform, build_type):
# Read build_config and locate build_type
current_dir = os.path.dirname(os.path.abspath(__file__))
cwd_dir = os.path.abspath(os.path.join(current_dir, '../..')) # engine's root
config_dir = os.path.abspath(os.path.join(current_dir, 'Platform', build_platform))
build_config_abspath = os.path.join(config_dir, build_config_filename)
if not os.path.exists(build_config_abspath):
config_dir = os.path.abspath(os.path.join(cwd_dir, 'restricted', build_platform, os.path.relpath(current_dir, cwd_dir)))
build_config_abspath = os.path.join(config_dir, build_config_filename)
if not os.path.exists(build_config_abspath):
print('[ci_build] File: {} not found'.format(build_config_abspath))
return -1
with open(build_config_abspath) as f:
build_config_json = json.load(f)
build_type_config = build_config_json[build_type]
if build_type_config is None:
print('[ci_build] Build type {} was not found in {}'.format(build_type, build_config_abspath))
# Load the command to execute
build_cmd = build_type_config['COMMAND']
if build_cmd is None:
print('[ci_build] Build type {} in {} is missing required COMMAND entry'.format(build_type, build_config_abspath))
return -1
build_params = build_type_config['PARAMETERS']
# Parameters are optional, so we could have none
# build_cmd is relative to the folder where this file is
build_cmd_path = os.path.join(current_dir, 'Platform/{}/{}'.format(build_platform, build_cmd))
if not os.path.exists(build_cmd_path):
config_dir = os.path.abspath(os.path.join(cwd_dir, 'restricted', build_platform, os.path.relpath(current_dir, cwd_dir)))
build_cmd_path = os.path.join(config_dir, build_cmd)
if not os.path.exists(build_cmd_path):
print('[ci_build] File: {} not found'.format(build_cmd_path))
return -1
print('[ci_build] Executing \"{}\"'.format(build_cmd_path))
print(' cwd = {}'.format(cwd_dir))
print(' paramaters:')
env_params = os.environ.copy()
for v in build_params:
if v[:6] == "FORCE:":
env_params[v[6:]] = build_params[v]
print(' {} = {} (forced)'.format(v[6:], env_params[v[6:]]))
else:
existing_param = env_params.get(v)
if not existing_param:
env_params[v] = build_params[v]
print(' {} = {} {}'.format(v, env_params[v], '(environment override)' if existing_param else ''))
print('--------------------------------------------------------------------------------', flush=True)
process_return = subprocess.run(build_cmd_path, cwd=cwd_dir, env=env_params)
print('--------------------------------------------------------------------------------')
if process_return.returncode != 0:
print('[ci_build] FAIL: Command {} returned {}'.format(build_cmd_path, process_return.returncode), flush=True)
return process_return.returncode
else:
print('[ci_build] OK', flush=True)
return 0
if __name__ == "__main__":
args = parse_args()
ret = build(args.build_config_filename, args.build_platform, args.build_type)
sys.exit(ret)
+299
View File
@@ -0,0 +1,299 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import datetime
import json
import math
import os
import platform
import psutil
import shutil
import stat
import subprocess
import sys
import time
import ci_build
from pathlib import Path
import submit_metrics
if platform.system() == 'Windows':
EXE_EXTENSION = '.exe'
else:
EXE_EXTENSION = ''
DATE_FORMAT = "%Y-%m-%dT%H:%M:%S"
METRICS_TEST_MODE = os.environ.get('METRICS_TEST_MODE')
def parse_args():
cur_dir = os.path.dirname(os.path.abspath(__file__))
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--platform', dest="platform", help="Platform to gather metrics for")
parser.add_argument('-a', '--jobname', dest="jobname", default="unknown", help="Name/tag of the job in the CI system (used to track where the report comes from, constant through multiple runs)")
parser.add_argument('-u', '--jobnumber', dest="jobnumber", default=-1, help="Number of run in the CI system (used to track where the report comes from, variable through runs)")
parser.add_argument('-o', '--jobnode', dest="jobnode", default="unknown", help="Build node name (used to track where the build happened in CI systems where the same jobs run in different hosts)")
parser.add_argument('-l', '--changelist', dest="changelist", default=-1, help="Last changelist in this workspace")
parser.add_argument('-c', '--config', dest="build_config_filename", default="build_config.json",
help="JSON filename in Platform/<platform> that defines build configurations for the platform")
args = parser.parse_args()
# Input validation
if args.platform is None:
print('[ci_build_metrics] No platform specified')
sys.exit(-1)
return args
def shutdown_processes():
process_list = {f'AssetBuilder{EXE_EXTENSION}', f'AssetProcessor{EXE_EXTENSION}', f'RC{EXE_EXTENSION}', f'Editor{EXE_EXTENSION}'}
for process in psutil.process_iter():
try:
if process.name() in process_list:
process.kill()
except Exception as e:
print(f'Exception while trying to kill process: {e}')
def on_rmtree_error(func, path, exc_info):
if os.path.exists(path):
try:
os.chmod(path, stat.S_IWRITE)
os.unlink(path)
except Exception as e:
print(f'Exception while trying to remove {path}: {e}')
def clean_folder(folder):
if os.path.exists(folder):
print(f'[ci_build_metrics] Cleaning {folder}...', flush=True)
if not METRICS_TEST_MODE:
shutil.rmtree(folder, onerror=on_rmtree_error)
print(f'[ci_build_metrics] Cleaned {folder}', flush=True)
def compute_folder_size(folder):
total = 0
if os.path.exists(folder):
folder_path = Path(folder)
print(f'[ci_build_metrics] Computing size of {folder_path}...', flush=True)
if not METRICS_TEST_MODE:
total += sum(f.stat().st_size for f in folder_path.glob('**/*') if f.is_file())
print(f'[ci_build_metrics] Computed size of {folder_path}', flush=True)
return total
def build(metrics, folders_of_interest, build_config_filename, platform, build_type, output_directory, time_delta = 0):
build_start = time.time()
if not METRICS_TEST_MODE:
metrics['result'] = ci_build.build(build_config_filename, platform, build_type)
else:
metrics['result'] = -1 # mark as failure so the data is not used in elastic
build_end = time.time()
# truncate the duration (expressed in seconds), we dont need more precision
metrics['duration'] = math.trunc(build_end - build_start - time_delta)
metrics['output_sizes'] = []
output_sizes = metrics['output_sizes']
for folder in folders_of_interest:
output_size = dict()
if folder != output_directory:
output_size['folder'] = folder
else:
output_size['folder'] = 'OUTPUT_DIRECTORY' # make it homogenous to facilitate search
output_size['output_size'] = compute_folder_size(os.path.join(engine_dir, folder))
output_sizes.append(output_size)
def gather_build_metrics(current_dir, build_config_filename, platform):
config_dir = os.path.abspath(os.path.join(current_dir, 'Platform', platform))
build_config_abspath = os.path.join(config_dir, build_config_filename)
if not os.path.exists(build_config_abspath):
cwd_dir = os.path.abspath(os.path.join(current_dir, '../..')) # engine's root
config_dir = os.path.abspath(os.path.join(cwd_dir, 'restricted', platform, os.path.relpath(current_dir, cwd_dir)))
build_config_abspath = os.path.join(config_dir, build_config_filename)
if not os.path.exists(build_config_abspath):
print(f'[ci_build_metrics] File: {build_config_abspath} not found', flush=True)
sys.exit(-1)
with open(build_config_abspath) as f:
build_config_json = json.load(f)
all_builds_metrics = []
for build_type in build_config_json:
build_config = build_config_json[build_type]
if not 'weekly-build-metrics' in build_config['TAGS']:
# skip build configs that are not tagged with 'weekly-build-metrics'
continue
print(f'[ci_build_metrics] Starting {build_type}', flush=True)
metrics = dict()
metrics['build_type'] = build_type
build_parameters = build_config['PARAMETERS']
if not build_parameters:
metrics['result'] = -1
reason = f'PARAMETERS entry {build_type} in {build_config_abspath} is missing.'
metrics['reason'] = reason
print(f'[ci_build_metrics] {reason}', flush=True)
continue
# Clean the build output
output_directory = build_parameters['OUTPUT_DIRECTORY'] if 'OUTPUT_DIRECTORY' in build_parameters else None
if not output_directory:
metrics['result'] = -1
reason = f'OUTPUT_DIRECTORY entry in {build_config_abspath} is missing.'
metrics['reason'] = reason
print(f'[ci_build_metrics] {reason}', flush=True)
continue
folders_of_interest = [output_directory]
# Clean the AP output
cmake_ly_projects = build_parameters['CMAKE_LY_PROJECTS'] if 'CMAKE_LY_PROJECTS' in build_parameters else None
if cmake_ly_projects:
projects = cmake_ly_projects.split(';')
for project in projects:
folders_of_interest.append(os.path.join(project, 'user', 'AssetProcessorTemp'))
folders_of_interest.append(os.path.join(project, 'Cache'))
metrics['build_metrics'] = []
build_metrics = metrics['build_metrics']
# Do the clean build
shutdown_processes()
for folder in folders_of_interest:
clean_folder(os.path.join(engine_dir, folder))
build_metric_clean = dict()
build_metric_clean['build_metric'] = 'clean'
build(build_metric_clean, folders_of_interest, build_config_filename, platform, build_type, output_directory)
build_metrics.append(build_metric_clean)
# Do the incremental "zero" build
build_metric_zero = dict()
build_metric_zero['build_metric'] = 'zero'
build(build_metric_zero, folders_of_interest, build_config_filename, platform, build_type, output_directory)
build_metrics.append(build_metric_zero)
# Do a reconfigure
# To measure a reconfigure, we will delete the "ci_last_configure_cmd.txt" file from the output and trigger a
# zero build, then we will substract the time from the zero_build above
last_configure_file = os.path.join(output_directory, 'ci_last_configure_cmd.txt')
if os.path.exists(last_configure_file):
os.remove(last_configure_file)
build_metric_generation = dict()
build_metric_generation['build_metric'] = 'generation'
build(build_metric_generation, folders_of_interest, build_config_filename, platform, build_type, output_directory, build_metric_zero['duration'])
build_metrics.append(build_metric_generation)
# Clean the otuput before ending to reduce the size of these workspaces
shutdown_processes()
for folder in folders_of_interest:
clean_folder(os.path.join(engine_dir, folder))
metrics['result'] = 0
metrics['reason'] = 'OK'
all_builds_metrics.append(metrics)
return all_builds_metrics
def prepare_metrics(args, build_metrics):
return {
'changelist': args.changelist,
'job': {'name': args.jobname, 'number': args.jobnumber, 'node': args.jobnode},
'platform': args.platform,
'build_types': build_metrics,
'timestamp': timestamp.strftime("%Y-%m-%dT%H:%M:%S")
}
def upload_to_s3(upload_script_path, base_dir, bucket, key_prefix):
try:
subprocess.run([sys.executable, upload_script_path,
'--base_dir', base_dir,
'--file_regex', '.*',
'--bucket', bucket,
'--key_prefix', key_prefix],
check=True)
except subprocess.CalledProcessError as err:
print(f'[ci_build_metrics] {upload_script_path} failed with error {err}')
sys.exit(1)
def submit_report_document(report_file):
print(f'[ci_build_metrics] Submitting {report_file}')
with open(report_file) as json_file:
report_json = json.load(json_file)
ret = True
for build_type in report_json['build_types']:
for build_metric in build_type['build_metrics']:
newjson = {
'timestamp': report_json['timestamp'],
'changelist': report_json['changelist'],
'job': report_json['job'],
'platform': report_json['platform'],
'type': build_type['build_type'],
'result': int(build_type['result']) or int(build_metric['result']),
'reason': build_type['reason'],
'metric': build_metric['build_metric'],
'duration': build_metric['duration'],
'output_sizes': build_metric['output_sizes']
}
index = "pappeste.build_metrics." + datetime.datetime.strptime(report_json['timestamp'], DATE_FORMAT).strftime("%Y.%m")
ret &= submit_metrics.submit(index, newjson)
if ret:
print(f'[ci_build_metrics] {report_file} submitted')
else:
print(f'[ci_build_metrics] {report_file} failed to submit')
return ret
if __name__ == "__main__":
args = parse_args()
print(f"[ci_build_metrics] Generatic build metrics for:"
f"\n\tPlatform: {args.platform}"
f"\n\tJob Name: {args.jobname}"
f"\n\tJob Number: {args.jobnumber}"
f"\n\tJob Node: {args.jobnode}"
f"\n\tChangelist: {args.changelist}")
# Read build_config
current_dir = os.path.dirname(os.path.abspath(__file__))
engine_dir = os.path.abspath(os.path.join(current_dir, '../..')) # engine's root
timestamp = datetime.datetime.now()
build_metrics = gather_build_metrics(current_dir, args.build_config_filename, args.platform)
metrics = prepare_metrics(args, build_metrics)
# Temporarly just printing the metrics until we get an API to uplaod it to CloudWatch
# SPEC-1810 will then upload these metrics
print("[ci_build_metrics] metrics:")
print(json.dumps(metrics, sort_keys=True, indent=4))
metric_file_path = os.path.join(engine_dir, 'build_metrics')
if os.path.exists(metric_file_path):
shutil.rmtree(metric_file_path)
os.makedirs(metric_file_path)
metric_file_path = os.path.join(metric_file_path, timestamp.strftime("%Y%m%d_%H%M%S.json"))
with open(metric_file_path, 'w') as metric_file:
json.dump(metrics, metric_file, sort_keys=True, indent=4)
# transfer
upload_script = os.path.join(current_dir, 'tools', 'upload_to_s3.py')
upload_to_s3(upload_script, os.path.join(engine_dir, 'build_metrics'), 'ly-jenkins-cmake-metrics', args.jobname)
# submit
submit_report_document(metric_file_path)
# Dont cleanup, next build will remove the file, but leaving it helps to do some post-build forensics
+1 -1
View File
@@ -16,7 +16,7 @@ import progressbar
from optparse import OptionParser
from PackageEnv import PackageEnv
cur_dir = cur_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, f'{cur_dir}/../../../Tools/build/JenkinsScripts/build')
sys.path.insert(0, f'{cur_dir}/..')
from ci_build import build
from util import *
from glob3 import glob
+92
View File
@@ -0,0 +1,92 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
import argparse
import logging
import json
import socket
from datetime import datetime
SOCKET_TIMEOUT = 60
DATE_FORMAT = "%Y-%m-%dT%H:%M:%S"
FILEBEAT_PIPELINE = "filebeat"
FILEBEAT_DEFAULT_IP = "127.0.0.1"
FILEBEAT_DEFAULT_PORT = 9000
def parse_args():
parser = argparse.ArgumentParser(
prog="submit_metrics.py",
description="Pushes a JSON document via Filebeat.",
add_help=False
)
def file_arg(arg):
try:
with open(arg) as json_file:
return json.load(json_file)
except ValueError:
raise argparse.ArgumentTypeError("Invalid json file '%s'" % arg)
parser.add_argument("-f", "--file", default=None, type=file_arg, help="File containing JSON data to upload.")
parser.add_argument("-i", "--index", default=None, help="Index to use when sending the data")
parser.add_argument("-ip", "--filebeat_ip", default=FILEBEAT_DEFAULT_IP, help="IP address where filebeat service is listening")
parser.add_argument("-port", "--filebeat_port", default=FILEBEAT_DEFAULT_PORT, help="Port where filebeat service is listening")
return parser.parse_args()
def submit(index, payload, filebeat_ip = FILEBEAT_DEFAULT_IP, filebeat_port = FILEBEAT_DEFAULT_PORT):
try:
filebeat_address = filebeat_ip, filebeat_port
logging.debug(f"Connecting to Filebeat on '{filebeat_address[0]}:{filebeat_address[1]}'")
fb_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
fb_socket.settimeout(SOCKET_TIMEOUT)
fb_socket.connect(filebeat_address)
event = {
"index": index,
"timestamp": datetime.strptime(payload['timestamp'], DATE_FORMAT).strftime(DATE_FORMAT),
"pipeline": FILEBEAT_PIPELINE,
"payload": json.dumps(payload),
}
# Serialise event, add new line and encode as UTF-8 before sending to Filebeat.
data = json.dumps(event) + "\n"
data = data.encode()
total_sent = 0
logging.debug(f"Sending JSON data")
while total_sent < len(data):
try:
sent = fb_socket.send(data[total_sent:])
except BrokenPipeError:
print("An exception occurred while sending data")
fb_socket.close()
total_sent = 0
else:
total_sent = total_sent + sent
logging.debug("JSON data sent")
fb_socket.close()
logging.debug(f"Disconnected from Filebeat on '{filebeat_address[0]}:{filebeat_address[1]}'")
except (ConnectionError, socket.timeout):
logging.error("Failed to connect to Filebeat")
return False
return True
if __name__ == "__main__":
# Parse CLI arguments.
args = parse_args()
if not args.index:
logging.error(f"Index not specified")
exit(1)
if not submit(args.index, json.dumps(args.file), args.filebeat_ip, args.filebeat_port):
exit(1)