diff --git a/action.yml b/action.yml index 989c2569..121174df 100644 --- a/action.yml +++ b/action.yml @@ -101,6 +101,12 @@ inputs: required: false default: '' description: '[CloudRunner] GitHub owner name or organization/team name' + runAsHostUser: + required: false + default: 'false' + description: + 'Whether to run as a user that matches the host system or the default root container user. Only applicable to + Linux hosts and containers. This is useful for fixing permission errors on Self-Hosted runners.' chownFilesTo: required: false default: '' diff --git a/dist/BlankProject/ProjectSettings/XRSettings.asset b/dist/BlankProject/ProjectSettings/XRSettings.asset deleted file mode 100644 index 482590c1..00000000 --- a/dist/BlankProject/ProjectSettings/XRSettings.asset +++ /dev/null @@ -1,10 +0,0 @@ -{ - "m_SettingKeys": [ - "VR Device Disabled", - "VR Device User Alert" - ], - "m_SettingValues": [ - "False", - "False" - ] -} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index dc3aac42..f55c9a57 100644 Binary files a/dist/index.js and b/dist/index.js differ diff --git a/dist/index.js.map b/dist/index.js.map index 6f16cb34..c72ad08f 100644 Binary files a/dist/index.js.map and b/dist/index.js.map differ diff --git a/dist/platforms/mac/entrypoint.sh b/dist/platforms/mac/entrypoint.sh index 80ec6d09..bea8f36a 100755 --- a/dist/platforms/mac/entrypoint.sh +++ b/dist/platforms/mac/entrypoint.sh @@ -41,7 +41,7 @@ echo "" echo "Please note that the exit code is not very descriptive." echo "Most likely it will not help you solve the issue." echo "" -echo "To find the reason for failure: please search for errors in the log above." +echo "To find the reason for failure: please search for errors in the log above and check for annotations in the summary view." echo "" fi; diff --git a/dist/platforms/mac/steps/activate.sh b/dist/platforms/mac/steps/activate.sh index 2d3339ef..3f749f04 100755 --- a/dist/platforms/mac/steps/activate.sh +++ b/dist/platforms/mac/steps/activate.sh @@ -20,10 +20,6 @@ echo "Requesting activation" # Store the exit code from the verify command UNITY_EXIT_CODE=$? -if [ ! -f "/Library/Application Support/Unity/Unity_lic.ulf" ]; then - echo "::error ::There was an error while trying to activate the Unity license." -fi - # # Display information about the result # diff --git a/dist/platforms/ubuntu/entrypoint.sh b/dist/platforms/ubuntu/entrypoint.sh index af7a4ea2..0847d0c9 100755 --- a/dist/platforms/ubuntu/entrypoint.sh +++ b/dist/platforms/ubuntu/entrypoint.sh @@ -1,47 +1,76 @@ #!/usr/bin/env bash -# -# Create directory for license activation -# - -ACTIVATE_LICENSE_PATH="$GITHUB_WORKSPACE/_activate-license~" -mkdir -p "$ACTIVATE_LICENSE_PATH" +# Ensure machine ID is randomized +dbus-uuidgen > /etc/machine-id && mkdir -p /var/lib/dbus/ && ln -sf /etc/machine-id /var/lib/dbus/machine-id # -# Run steps -# -source /steps/set_extra_git_configs.sh -source /steps/set_gitcredential.sh -source /steps/activate.sh -source /steps/build.sh -source /steps/return_license.sh - -# -# Remove license activation directory +# Prepare Android SDK, if needed +# We do this here to ensure it has root permissions # -rm -r "$ACTIVATE_LICENSE_PATH" -chmod -R 777 "/BlankProject" +fullProjectPath="$GITHUB_WORKSPACE/$PROJECT_PATH" -# -# Instructions for debugging -# +if [[ "$BUILD_TARGET" == "Android" ]]; then + export JAVA_HOME="$(awk -F'=' '/JAVA_HOME=/{print $2}' /usr/bin/unity-editor.d/*)" + ANDROID_HOME_DIRECTORY="$(awk -F'=' '/ANDROID_HOME=/{print $2}' /usr/bin/unity-editor.d/*)" + SDKMANAGER=$(find $ANDROID_HOME_DIRECTORY/cmdline-tools -name sdkmanager) + if [ -z "${SDKMANAGER}" ] + then + echo "No sdkmanager found" + exit 1 + fi -if [[ $BUILD_EXIT_CODE -gt 0 ]]; then -echo "" -echo "###########################" -echo "# Failure #" -echo "###########################" -echo "" -echo "Please note that the exit code is not very descriptive." -echo "Most likely it will not help you solve the issue." -echo "" -echo "To find the reason for failure: please search for errors in the log above." -echo "" -fi; + if [[ -n "$ANDROID_SDK_MANAGER_PARAMETERS" ]]; then + echo "Updating Android SDK with parameters: $ANDROID_SDK_MANAGER_PARAMETERS" + $SDKMANAGER "$ANDROID_SDK_MANAGER_PARAMETERS" + else + echo "Updating Android SDK with auto detected target API version" + # Read the line containing AndroidTargetSdkVersion from the file + targetAPILine=$(grep 'AndroidTargetSdkVersion' "$fullProjectPath/ProjectSettings/ProjectSettings.asset") -# -# Exit with code from the build step. -# + # Extract the number after the semicolon + targetAPI=$(echo "$targetAPILine" | cut -d':' -f2 | tr -d '[:space:]') -exit $BUILD_EXIT_CODE + $SDKMANAGER "platforms;android-$targetAPI" + fi + + echo "Updated Android SDK." +else + echo "Not updating Android SDK." +fi + +if [[ "$RUN_AS_HOST_USER" == "true" ]]; then + echo "Running as host user" + + # Stop on error if we can't set up the user + set -e + + # Get host user/group info so we create files with the correct ownership + USERNAME=$(stat -c '%U' "$fullProjectPath") + USERID=$(stat -c '%u' "$fullProjectPath") + GROUPNAME=$(stat -c '%G' "$fullProjectPath") + GROUPID=$(stat -c '%g' "$fullProjectPath") + + groupadd -g $GROUPID $GROUPNAME + useradd -u $USERID -g $GROUPID $USERNAME + usermod -aG $GROUPNAME $USERNAME + mkdir -p "/home/$USERNAME" + chown $USERNAME:$GROUPNAME "/home/$USERNAME" + + # Normally need root permissions to access when using su + chmod 777 /dev/stdout + chmod 777 /dev/stderr + + # Don't stop on error when running our scripts as error handling is baked in + set +e + + # Switch to the host user so we can create files with the correct ownership + su $USERNAME -c "$SHELL -c 'source /steps/runsteps.sh'" +else + echo "Running as root" + + # Run as root + source /steps/runsteps.sh +fi + +exit $? diff --git a/dist/platforms/ubuntu/steps/activate.sh b/dist/platforms/ubuntu/steps/activate.sh index 4af50212..61c649d7 100755 --- a/dist/platforms/ubuntu/steps/activate.sh +++ b/dist/platforms/ubuntu/steps/activate.sh @@ -1,31 +1,54 @@ #!/usr/bin/env bash -# Run in ACTIVATE_LICENSE_PATH directory -echo "Changing to \"$ACTIVATE_LICENSE_PATH\" directory." -pushd "$ACTIVATE_LICENSE_PATH" - if [[ -n "$UNITY_SERIAL" && -n "$UNITY_EMAIL" && -n "$UNITY_PASSWORD" ]]; then # # SERIAL LICENSE MODE # - # This will activate unity, using the activating process. + # This will activate unity, using the serial activation process. # echo "Requesting activation" - # Activate license - unity-editor \ - -logFile /dev/stdout \ - -quit \ - -serial "$UNITY_SERIAL" \ - -username "$UNITY_EMAIL" \ - -password "$UNITY_PASSWORD" \ - -projectPath "/BlankProject" + # Loop the unity-editor call until the license is activated with exponential backoff and a maximum of 5 retries + retry_count=0 - # Store the exit code from the verify command - UNITY_EXIT_CODE=$? + # Initialize delay to 15 seconds + delay=15 - if [ ! -f "~/.local/share/unity3d/Unity/Unity_lic.ulf" ]; then - echo "::error ::There was an error while trying to activate the Unity license." + # Loop until UNITY_EXIT_CODE is 0 or retry count reaches 5 + while [[ $retry_count -lt 5 ]] + do + # Activate license + unity-editor \ + -logFile /dev/stdout \ + -quit \ + -serial "$UNITY_SERIAL" \ + -username "$UNITY_EMAIL" \ + -password "$UNITY_PASSWORD" \ + -projectPath "/BlankProject" + + # Store the exit code from the verify command + UNITY_EXIT_CODE=$? + + # Check if UNITY_EXIT_CODE is 0 + if [[ $UNITY_EXIT_CODE -eq 0 ]] + then + echo "Activation successful" + break + else + echo "Activation failed, retrying in $delay seconds..." + sleep $delay + + # Increment retry count + ((retry_count++)) + + # Double the delay for the next iteration + delay=$((delay * 2)) + fi + done + + if [[ $retry_count -eq 5 ]] + then + echo "Activation failed after 5 retries" fi elif [[ -n "$UNITY_LICENSING_SERVER" ]]; then @@ -54,8 +77,9 @@ else echo "Visit https://game.ci/docs/github/getting-started for more" echo "details on how to set up one of the possible activation strategies." - echo "::error ::No valid license activation strategy could be determined." - # Immediately exit as no UNITY_EXIT_CODE can be derrived. + echo "::error ::No valid license activation strategy could be determined. Make sure to provide UNITY_EMAIL, UNITY_PASSWORD, and either a UNITY_SERIAL \ +or UNITY_LICENSE. Otherwise please use UNITY_LICENSING_SERVER." + # Immediately exit as no UNITY_EXIT_CODE can be derived. exit 1; fi @@ -70,6 +94,7 @@ else # Activation failed so exit with the code from the license verification step echo "Unclassified error occured while trying to activate license." echo "Exit code was: $UNITY_EXIT_CODE" + echo "::error ::There was an error while trying to activate the Unity license." exit $UNITY_EXIT_CODE fi diff --git a/dist/platforms/ubuntu/steps/build.sh b/dist/platforms/ubuntu/steps/build.sh index 7a202bab..4cdb3e89 100755 --- a/dist/platforms/ubuntu/steps/build.sh +++ b/dist/platforms/ubuntu/steps/build.sh @@ -62,27 +62,6 @@ else # fi -# -# Prepare Android SDK, if needed -# - -if [[ "$BUILD_TARGET" == "Android" && -n "$ANDROID_SDK_MANAGER_PARAMETERS" ]]; then - echo "Updating Android SDK with parameters: $ANDROID_SDK_MANAGER_PARAMETERS" - export JAVA_HOME="$(awk -F'=' '/JAVA_HOME=/{print $2}' /usr/bin/unity-editor.d/*)" - ANDROID_HOME_DIRECTORY="$(awk -F'=' '/ANDROID_HOME=/{print $2}' /usr/bin/unity-editor.d/*)" - SDKMANAGER=$(find $ANDROID_HOME_DIRECTORY/cmdline-tools -name sdkmanager) - if [ -z "${SDKMANAGER}" ] - then - echo "No sdkmanager found" - exit 1 - fi - - $SDKMANAGER "$ANDROID_SDK_MANAGER_PARAMETERS" - echo "Updated Android SDK." -else - echo "Not updating Android SDK." -fi - # # Pre-build debug information # diff --git a/dist/platforms/ubuntu/steps/runsteps.sh b/dist/platforms/ubuntu/steps/runsteps.sh new file mode 100644 index 00000000..e8376051 --- /dev/null +++ b/dist/platforms/ubuntu/steps/runsteps.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# +# Run steps +# +source /steps/set_extra_git_configs.sh +source /steps/set_gitcredential.sh +source /steps/activate.sh + +# If we didn't activate successfully, exit with the exit code from the activation step. +if [[ $UNITY_EXIT_CODE -ne 0 ]]; then + exit $UNITY_EXIT_CODE +fi + +source /steps/build.sh +source /steps/return_license.sh + +# +# Instructions for debugging +# + +if [[ $BUILD_EXIT_CODE -gt 0 ]]; then +echo "" +echo "###########################" +echo "# Failure #" +echo "###########################" +echo "" +echo "Please note that the exit code is not very descriptive." +echo "Most likely it will not help you solve the issue." +echo "" +echo "To find the reason for failure: please search for errors in the log above and check for annotations in the summary view." +echo "" +fi; + +# +# Exit with code from the build step. +# + +# Exiting su +exit $BUILD_EXIT_CODE diff --git a/dist/platforms/windows/activate.ps1 b/dist/platforms/windows/activate.ps1 index 5e505b46..897ec17e 100644 --- a/dist/platforms/windows/activate.ps1 +++ b/dist/platforms/windows/activate.ps1 @@ -13,7 +13,4 @@ Write-Output "" -projectPath "c:/BlankProject" ` -logfile - | Out-Host -if(-not(Test-path "C:/ProgramData/Unity/Unity_lic.ulf" -PathType leaf)) -{ - Write-Output "::error ::There was an error while trying to activate the Unity license." -} +$ACTIVATION_EXIT_CODE = $LASTEXITCODE diff --git a/dist/platforms/windows/entrypoint.ps1 b/dist/platforms/windows/entrypoint.ps1 index 07cbb070..fac75b74 100644 --- a/dist/platforms/windows/entrypoint.ps1 +++ b/dist/platforms/windows/entrypoint.ps1 @@ -1,5 +1,4 @@ Get-Process -Start-Sleep -Seconds 3 # Import any necessary registry keys, ie: location of windows 10 sdk # No guarantee that there will be any necessary registry keys, ie: tvOS @@ -17,13 +16,17 @@ Get-Process -Name regsvr32 | ForEach-Object { Stop-Process -Id $_.Id -Force } # Activate Unity . "c:\steps\activate.ps1" +# If we didn't activate successfully, exit with the exit code from the activation step. +if ($ACTIVATION_EXIT_CODE -ne 0) { + exit $ACTIVATION_EXIT_CODE +} + # Build the project . "c:\steps\build.ps1" # Free the seat for the activated license . "c:\steps\return_license.ps1" -Start-Sleep -Seconds 3 Get-Process exit $BUILD_EXIT_CODE diff --git a/src/model/build-parameters.ts b/src/model/build-parameters.ts index a91e165e..6710a4da 100644 --- a/src/model/build-parameters.ts +++ b/src/model/build-parameters.ts @@ -59,6 +59,7 @@ class BuildParameters { public kubeVolumeSize!: string; public kubeVolume!: string; public kubeStorageClass!: string; + public runAsHostUser!: String; public chownFilesTo!: string; public commandHooks!: string; public pullInputList!: string[]; @@ -168,6 +169,7 @@ class BuildParameters { sshAgent: Input.sshAgent, sshPublicKeysDirectoryPath: Input.sshPublicKeysDirectoryPath, gitPrivateToken: Input.gitPrivateToken || (await GithubCliReader.GetGitHubAuthToken()), + runAsHostUser: Input.runAsHostUser, chownFilesTo: Input.chownFilesTo, dockerCpuLimit: Input.dockerCpuLimit, dockerMemoryLimit: Input.dockerMemoryLimit, diff --git a/src/model/image-environment-factory.ts b/src/model/image-environment-factory.ts index 6162b50b..2df52f1a 100644 --- a/src/model/image-environment-factory.ts +++ b/src/model/image-environment-factory.ts @@ -62,6 +62,7 @@ class ImageEnvironmentFactory { { name: 'ANDROID_EXPORT_TYPE', value: parameters.androidExportType }, { name: 'ANDROID_SYMBOL_TYPE', value: parameters.androidSymbolType }, { name: 'CUSTOM_PARAMETERS', value: parameters.customParameters }, + { name: 'RUN_AS_HOST_USER', value: parameters.runAsHostUser }, { name: 'CHOWN_FILES_TO', value: parameters.chownFilesTo }, { name: 'GITHUB_REF', value: process.env.GITHUB_REF }, { name: 'GITHUB_SHA', value: process.env.GITHUB_SHA }, diff --git a/src/model/input.ts b/src/model/input.ts index 85f45733..c12abe00 100644 --- a/src/model/input.ts +++ b/src/model/input.ts @@ -193,6 +193,10 @@ class Input { return Input.getInput('gitPrivateToken'); } + static get runAsHostUser(): string { + return Input.getInput('runAsHostUser') || 'false'; + } + static get chownFilesTo() { return Input.getInput('chownFilesTo') || ''; }