Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Signing Package from the command line

Discussion in 'Android' started by johno, Dec 13, 2012.

  1. johno

    johno

    Joined:
    Feb 20, 2011
    Posts:
    12
    We use a build server to create all our builds by running Unity using build scripts from the command line. This presented a bit of a problem when it comes to android as there doesn't seem to be any way to enter the keystore password if you are running unity on the command line.

    I couldn't find any help for this on the forums, so I thought I'd share my solution:

    - In player settings leave all the keystore entries blank so unity signs the package with the debug keys.
    - Use BuildPipeline.BuildPlayer() to build the game package.
    - Run this command to remove the signing information from the package:
    Code (csharp):
    1. zip -d MyAndroidPackage.apk "META-INF/*"
    - Now sign the package with your keystore:
    Code (csharp):
    1. jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore MyKeystore.keystore -storepass <password> MyAndroidPackage.apk <keystore alias>
    - Finally run zipalign to ensure the package has proper alignment:
    Code (csharp):
    1. zipalign -v 4 MyAndroidPackage.apk FinalAlignedPackage.apk
    This approach obviously has the disadvantage that you have the password for your keystore included in your build scripts. My current plan is to use one keystore for development, and a different keystore when we actually submit to the app store. I'll have to enter the passwords for the final submission build manually which is a bit of a pain, but at least we have fully automatic builds during development.

    I'd love to know if anyone has a better solution to this problem?

    John
     
  2. Tomo-Games

    Tomo-Games

    Joined:
    Sep 20, 2010
    Posts:
    220
  3. jimrogerz

    jimrogerz

    Joined:
    Aug 8, 2013
    Posts:
    6
    You can set the passwords in PlayerSettings before calling BuildPlayer, e.g.:

    PlayerSettings.keyaliasPass = "...";
    PlayerSettings.keystorePass = "...";
    BuildPipeline.BuildPlayer(...)
     
  4. turbanov

    turbanov

    Joined:
    Dec 22, 2014
    Posts:
    59
    The problem here is to actually pass those passwords from the command line in a secure way. Unity logs every command-line argument it receives, excluding its own "-password" one, which is unfortunate. The log files are usually saved in CI, so having those in them is totally insecure.
     
  5. Deleted User

    Deleted User

    Guest

    Why passing them from the command line, do they change frequently? I'd keep them in the build source code
     
  6. KGC

    KGC

    Joined:
    Oct 2, 2014
    Posts:
    12
    I've just implemented this on our CI pipeline. For anyone still interested, the gist is to use Environment.ExpandEnvironmentVariables() to evaluate and expand environment variables set in the terminal that is executing the Unity.exe process. This lets you read the keystore password value, without having the value leak into the console output because you pass it as a command line parameter.

    Here is the C# code that should go in your C# buildscript that is executed via command line:
    Code (CSharp):
    1. string query = "%AndroidKeystorePassword%"; // TODO: Account for OSX and Linux syntax for environment variables
    2. string keystorePassword = Environment.ExpandEnvironmentVariables(query);
    And here is a sample Windows batch script to set the environment variable and execute the Unity.exe for building via command line:
    Code (CSharp):
    1. @echo off
    2.  
    3. SET Unity=C:\Program Files\Unity\2018.4.5f1\Editor\Unity.exe
    4. SET Project=C:\Users\kgc\Documents\Projects\AwesomeUnityProject
    5. SET BuildPath=%Project%\Builds
    6. SET AndroidKeystorePassword=12345678
    7.  
    8. "%Unity%" -quit -batchmode -nographics -projectPath "%Project%" -logFile "%BuildPath%\build.android.log" -executeMethod "BuildScript.BuildAndroid"
    Hope this helps someone out there with the same problem!
     
    eugeneloza, Jribs and jochemlam like this.