我正在使用 Jenkins 为 Android 应用程序设置 CI。我正在尝试使用Custom Tools Plugin将 Android SDK 配置为 Jenkins 全局工具。这是我在 中配置的安装 shell 脚本Jenkins>Global Tool Configuration
。
printf "\nInstalling Android SDK as a Jenkins Custom Tool\n"
pwd
ls -la
if [ ! -d build-tools ];
then
printf "There's no dir by the name 'build-tools' on this agent yet. Will proceed to install the Android SDK.\n"
printf "Downloading the Android SDK tools for Linux\n"
curl -o android.zip https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
printf "Download successful\n"
printf "Unzipping downloaded Android SDK tools\n"
unzip -o -z android.zip
printf "Done unzipping\n"
printf "Removing downloaded zip file\n"
rm android.zip
printf "Done removing\n"
printf "Installing Android Build Tools 23.0.1\n"
echo "y" | tools/bin/sdkmanager "build-tools;23.0.1"
printf "Done installing Android Build Tools 23.0.1\n"
else
printf "There's already a dir by the name 'build-tools' on this agent. Aborting installation of the Android SDK.\n"
fi
printf "Done installing Android SDK as a Jenkins Custom Tool\n\n"
我目前正在尝试设置的作业从另一个位置下载未签名的 apk 并尝试对其进行签名。
这是詹金斯文件:
properties([
parameters([
[
$class: 'CredentialsParameterDefinition',
name: 'ANDROID_KEYSTORE_FILE',
credentialType: 'com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl',
defaultValue: params.ANDROID_KEYSTORE_FILE?:'',
description: 'The Android keystore file in p12 format.',
required: false
],
string(
name: 'ANDROID_SIGN_KEY_ALIAS',
defaultValue: params.ANDROID_SIGN_KEY_ALIAS?:'',
description: 'The alias of the signing key inside your keystore. If your keystore only has one key, you can leave this blank.',
),
])
])
stage('Binary sign'){
node('standard'){
def pwd = pwd()
echo(pwd)
sh('curl -o foo-unsigned.apk https://some/place/in/my/intranet/FooApp_12.apk')
sh('ls -la')
def androidHome = tool('android-sdk')
//Let's sign and archive the unsigned and signed apk files
withEnv([
"ANDROID_HOME=${androidHome}"]) {
signAndroidApks (
keyStoreId: params.ANDROID_KEYSTORE_FILE,
keyAlias: params.ANDROID_SIGN_KEY_ALIAS,
apksToSign: "**/*-unsigned.apk",
androidHome: env.ANDROID_HOME,
archiveSignedApks: true,
archiveUnsignedApks: true
)
}
}
}
您可以看到我正在使用signAndroidApks步骤。问题是当它执行时我得到这个错误:
[android-sign-test] $ echo "resolving effective environment"
[SignApksBuilder] zipalign ANDROID_HOME explicitly set to /Jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/android
[SignApksBuilder] found zipalign in Android SDK's latest build tools: /Jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/android/build-tools/23.0.1/zipalign
[SignApksBuilder] /Jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/android/build-tools/23.0.1/zipalign -f -p 4 /Jenkins/workspace/AFS-2.0/android-sign-test/foo-unsigned.apk /Jenkins/workspace/AFS-2.0/android-sign-test/SignApksBuilder-out/zipalign/aligned-foo-unsigned-6084722845076851930.apk
[android-sign-test] $ /Jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/android/build-tools/23.0.1/zipalign -f -p 4 /Jenkins/workspace/AFS-2.0/android-sign-test/foo-unsigned.apk /Jenkins/workspace/AFS-2.0/android-sign-test/SignApksBuilder-out/zipalign/aligned-foo-unsigned-6084722845076851930.apk
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // stage
[Pipeline] End of Pipeline
java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
at hudson.Proc$LocalProc.<init>(Proc.java:249)
at hudson.Proc$LocalProc.<init>(Proc.java:218)
at hudson.Launcher$LocalLauncher.launch(Launcher.java:930)
at hudson.Launcher$ProcStarter.start(Launcher.java:450)
at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1299)
at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1260)
at hudson.remoting.UserRequest.perform(UserRequest.java:153)
at hudson.remoting.UserRequest.perform(UserRequest.java:50)
at hudson.remoting.Request$2.run(Request.java:336)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at hudson.remoting.Engine$1$1.run(Engine.java:94)
at java.lang.Thread.run(Thread.java:748)
Caused: java.io.IOException: Cannot run program "/Jenkins/tools/com.cloudbees.jenkins.plugins.customtools.CustomTool/android/build-tools/23.0.1/zipalign" (in directory "/Jenkins/workspace/AFS-2.0/android-sign-test"): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at hudson.Proc$LocalProc.<init>(Proc.java:249)
at hudson.Proc$LocalProc.<init>(Proc.java:218)
at hudson.Launcher$LocalLauncher.launch(Launcher.java:930)
at hudson.Launcher$ProcStarter.start(Launcher.java:450)
at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1299)
at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:1260)
at hudson.remoting.UserRequest.perform(UserRequest.java:153)
at hudson.remoting.UserRequest.perform(UserRequest.java:50)
at hudson.remoting.Request$2.run(Request.java:336)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at hudson.remoting.Engine$1$1.run(Engine.java:94)
at java.lang.Thread.run(Thread.java:748)
at ......remote call to JNLP4-connect connection from ip-172-16-2-29.eu-west-1.compute.internal/172.16.2.29:44916(Native Method)
at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1545)
at hudson.remoting.UserResponse.retrieve(UserRequest.java:253)
at hudson.remoting.Channel.call(Channel.java:830)
at hudson.Launcher$RemoteLauncher.launch(Launcher.java:1053)
at hudson.Launcher$ProcStarter.start(Launcher.java:450)
at hudson.Launcher$ProcStarter.join(Launcher.java:461)
at org.jenkinsci.plugins.androidsigning.SignApksBuilder.perform(SignApksBuilder.java:332)
at org.jenkinsci.plugins.androidsigning.SignApksStep$SignApksStepExecution.run(SignApksStep.java:174)
at org.jenkinsci.plugins.androidsigning.SignApksStep$SignApksStepExecution.run(SignApksStep.java:126)
at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47)
at hudson.security.ACL.impersonate(ACL.java:260)
at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Finished: FAILURE
你可以看到堆栈说No such file or directory
,但我已经检查过,zipalign 可执行文件和未签名的 apk 都在它们应该在的位置。有没有人遇到过这个问题?有任何想法吗?