Jenkins pipeline job executing commands in tmp folder - android

MacOS Monterey version 12.4
I'm trying to run a simple pipeline script on my jenkins job
pipeline {
agent any
stages {
stage('Build') {
steps {
sh('emulator -list-avds')
}
}
}
But it throws an error:
/Users/<my_username>/.jenkins/workspace/<my_job_name>#tmp/durable-22217e91/script.sh: line 1: emulator: command not found
My question is: why is it executing commands in the tmp folder? Anything "emulator" related does work when I run commands via terminal.
Following this answer, I've confirmed I'm in the correct dir
Why Jenkins mounts a temporary volume in addition to the workspace?

You are getting this error because the emulator executable is not set in the PATH. Try something like the below.
Try setting your PATH variable to add emulator executable.
environment {
PATH = "/PATH_EMULATOR/bin:${env.PATH}"
}
or something like the below.
withEnv(["PATH+EMULATOR=/PATH_EMULATOR/bin"]) {
sh('emulator -list-avds')
}
or you can also use the full qualified path to the executable
sh('/PATH_TO_EMULATOR/bin/emulator -list-avds')

Related

Shell script in Gradle build: java.io.IOException

I have the following lines in my build.gradle file of my Android project:
"./prebuild.sh".execute()
But during the build I get this error:
java.io.IOException: Cannot run program "./prebuild.sh": error=2, No such file or directory
The prebuild.sh script is in the root directory of the app and executable.
What's weird is that this exact build works for everyone on the team, just not on my machine (M1). I also remember that this used to work months ago.
This happens on a fresh clone of the repository and a fresh install of Android Studio.
I think I've narrowed it down to a problem with the working directory. If I try to print it like this:
println new File(".").absolutePath
I get the following:
/Users/ale/.gradle/daemon/6.5/.
Which is obviously not my project directory.
Any hints on what I could do to fix it?
Assuming a functional shell prompt; pass the absolute path instead of . current working directory:
if(rootProject.file('prebuild.sh').exists()) {
commandLine 'sh', rootProject.file('prebuild.sh').absolutePath
} else {
println "missing: prebuild.sh"
}
Or how you start it as process, one can also pass the current working directory as second argument:
def proc = "./prebuild.sh".execute([], rootProject.absolutePath)
proc.waitForProcessOutput(System.out, System.err)
I'd run cd first, then pwd should return the expected value:
def proc = "cd ${rootProject.absolutePath} && pwd".execute()
...
Check if the file has DOS line endings (\r\n). This can lead to a confusing "no such file or directory", because it searches for a file called /bin/sh\r (ending with an actual carriage return), which does not exist.

Jenkins custom tools into Jenkinsfile declarative pipeline

I am trying to import a custom tool into the pipeline Jenkinsfile script (specifically, the Android SDK). From the build console, it says that I need to set the ANDROID_HOME environment variable to build my Android app. However, when I tried adding the SDK download and set it to the ANDROID_HOME variable, it's telling me that the directory does not exist:
Caused by: java.lang.RuntimeException: The SDK directory '/var/jenkins_home/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/Android_SDK_CLI_tools_4333796/bin' does not exist.
In the global tools configuration page, here's how I added the Android SDK:
Name: Android_SDK_CLI_tools_4333796
Tool home: bin
Command: (below)
if [ ! -f "Android_SDK_tools_4333796/" ]; then
echo "curl"
curl -O https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
echo "unzip"
yes | unzip -q sdk-tools-linux-4333796.zip
rm sdk-tools-linux-4333796.zip
echo "licenses"
yes | tools/bin/sdkmanager --licenses
fi
Below is how I set my Jenkinsfile:
pipeline {
agent any
environment {
ANDROID_HOME = tool 'Android_SDK_CLI_tools_4333796'
//ANDROID_HOME = tool name: 'Android_SDK_CLI_tools_4333796', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool' //alternative but still has the same results.
//env.PATH = "${env.PATH}:${androidSDKHome}"
}
tools {
jdk 'JDK_9.0.4'
}
stages {
stage('Pre-build') {
steps {
// seeing if Java JDK installed correctly
sh 'java --version'
print (env.ANDROID_HOME) // prints: /var/jenkins_home/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/Android_SDK_CLI_tools_4333796/bin
}
}
stage('Test') {
steps {
echo 'Testing stage...'
sh './gradlew clean --stacktrace' //ERROR (above)
}
}
}
}
My question is, am I pulling in this custom tool into the build properly? It seems Jenkins can't find it the custom tool even though I trying to access the absolute path.
I tried referencing this SO question; However, this is for me to obtain the executable whereas I'm looking to set the env var for Gradle to pick up the ANDROID_HOME env var automatically.
Ok, after struggling with this for the past few days, I realized many new things, the most important was how the dir structure has to be for commands to work.
The folder structure should be in this layout:
/<unpacked_location>
/tools
/bin
...
/build-tools
/licenses
/platforms
From there, everything should fall like dominos. My problem was, when Jenkins unpacks the Android SDK cli tools download, I was setting the home to bin. That's wrong since when you unpack the Android SDK, /bin is located inside the /tools dir. Jenkins kinda confused me by not allowing me to leave the home dir blank (makes sense since you can also set absolute paths if needed), so I set it to the present working dir (. in this case).
The other major thing that I was missing was installing the latest Android SDK version. I just added this to the global tool config script for Android SDK:
yes | tools/bin/sdkmanager "build-tools;28.0.3"

Jenkins hanged when I try to build Unity project

I found Jenkins(windows) hanged when I try to build Unity project for android package.
I'm trying to use Jenkins with Unity plugin and windows bat to build project, after windows exe exported successful, android package exported failed.
The arguemnt when I use Unity plugin is
-batchmode -quit -projectPath "D:\Program Files (x86)\Jenkins\jobs\UnityJenkinsTest\workspace\QBAD" -executeMethod QBADBuildScript.Android -logFile "${WORKSPACE}/Build-Log.txt"
Meanwhile, I try using a windows bat to execute the same command from Jenkins, the result is the same.
"D:\Program Files\Unity\Editor\Unity.exe" -batchmode -quit -projectPath "D:\Program Files (x86)\Jenkins\jobs\UnityJenkinsTest\workspace\QBAD" -executeMethod QBADBuildScript.Android -logFile "${WORKSPACE}/Build-Log.txt"
When the building process went to the some part of build process, it hanged, and the build of jenkins never ended. I check with succeed log, it hanged before entering the part of Android.
(succeed log)
Used Assets, sorted by uncompressed size:
....
AndroidSDKTools: // This line and below never showed when hanging happened.
root : D:/Android/sdk
tools : D:/Android/sdk\tools
platform-tools: D:/Android/sdk\platform-tools
build-tools : D:\Android\sdk\build-tools\23.0.1
On the contrary, when I call the same script from command console of windows, it ended and succeed. I wonder what went wrong. Maybe I need set up environment variable for Jenkins.
The version of my Jenkins is 1.614, the version of my Unity is 5.0.1 .
Thanks
public static class AndroidSDKFolder
{
public static string Path
{
get { return EditorPrefs.GetString("AndroidSdkRoot"); }
set { EditorPrefs.SetString("AndroidSdkRoot", value); }
}
}
http://answers.unity3d.com/questions/495735/setting-android-sdk-path-in-environment-variable.html <-- This should help, setting the android sdk path stops the hang.

Unity command line arguments for android and iOS

Please pardon my ignorance, relatively new to working with Unity3D. I am working on automating Unity3d builds from the command line.
I am looking for command line arguments to build apk & xcode project.
Unity's documentation does mention arguments to build a standalone Mac OSX player (-buildOSXPlayer) and a standalone Windows player (-buildWindowsPlayer) but not for android and iOS.
Any help would be really appreciated. Thanks.
Start with Unity's own documentation for command line builds for iOS and android.
For example, put this script in your Assets/Editor folder:
// C# example
using UnityEditor;
class Autobuilder
{
[MenuItem ("File/AutoBuilder/iOS")]
static void PerformBuild ()
{
string[] scenes = { "Assets/MyScene.unity" };
string buildPath = "../../../Build/iOS";
// Create build folder if not yet exists
Directory.CreateDirectory(buildPath);
BuildPipeline.BuildPlayer(scenes, buildPath, BuildTarget.iOS, BuildOptions.Development);
}
}
You can actually run this script in the Unity application by going to File -> Autobuilder -> iOS
To run on command line, it looks something like this:
/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -executeMethod Autobuilder.PerformBuild -email me#email.com -password myPassword
Of course, you're going to want to check the debug log for any errors:
Mac OS X ~/Library/Logs/Unity/Editor.log
Windows XP C:\Documents and Settings\username\Local Settings\Application Data_\Unity\Editor\Editor.log
Windows Vista/7 C:\Users\username\AppData\Local\Unity\Editor\Editor.log
The -executeMethod command line parameter is a very simple option to invoke any function in any of your scripts - which you can then use to do pretty much anything, including firing off an Android build.

Android NDK - Library not found CANNOT LINK EXECUTABLE - how to set LD_LIBRARY_PATH?

I have an Android activity where I'm executing NDK compiled code (command line program) with:
Runtime.getRuntime().exec(myCommand);
and load the needed shared libraries with:
static {
System.loadLibrary(myLib);
}
but when running my project and printing the output from error stream I get the following error:
link_image[1963]: 7520 could not load needed library 'libmyLib.so' for './myCommand'
(load_library[1105]: Library 'libmyLib.so' not found)CANNOT LINK EXECUTABLE
I assure libmyLib.so does exist in my project under libs/armeabi/ directory and it's copied to my Android device under /data/data/myProject.path.package/lib/ directory. Owner and group of both executable and library are system:system and permissions are ok as well.
When executing the command from adb shell in the beginning I get the same error but then I can set LD_LIBRARY_PATH and it runs ok:
./adb shell
export LD_LIBRARY_PATH=/data/data/myProject.path.package/lib:$LD_LIBRARY_PATH
/data/data/myProject.path.package/myCommand
So the question is, how to do that from java Android project?
Note: I'm using Linux, Eclipse + Sequoyah, NDK-r5b, Android 2.3.6 (API 10) on GT-P1010.
Solved: you can use exec(String prog, String[] envp). In my case this was:
String[] envp = {"LD_LIBRARY_PATH=/data/data/cse.ecg.dcmtk/lib:$LD_LIBRARY_PATH"};
Runtime.getRuntime().exec(myCommand, envp);
The issue now is that with exec() the process executed can't resolve hostnames (it does from adb shell; Internet permission is set). Any hint about that?

Categories

Resources