Esempio n. 1
0
        /**
         * Handle the plethora of environment variables required to remote to the Mac
         */
        static public void ConfigurePaths()
        {
            string MachineName = Environment.MachineName;

            XcodeDeveloperDir = Utilities.GetEnvironmentVariable("ue.XcodeDeveloperDir", "/Applications/Xcode.app/Contents/Developer/");

            // MacName=%ue4.iPhone_SigningServerName%
            MacName = Config.OverrideMacName != null ? Config.OverrideMacName : Utilities.GetEnvironmentVariable("ue.IOSSigningServer", "a1487");
            iPhone_SigningDevRootMac = Config.OverrideDevRoot != null ? Config.OverrideDevRoot : "/UE4/Builds";

            if (!Config.bUseRPCUtil)
            {
                bool Results = SSHCommandHelper.Command(MacName, "xcode-select --print-path", "/usr/bin");
                if (Results)
                {
                    XcodeDeveloperDir = (string)SSHCommandHelper.SSHReturn["CommandOutput"] + "/";
                    XcodeDeveloperDir = XcodeDeveloperDir.TrimEnd();
                }
            }

            // get the path to mirror into on the Mac
            string BinariesDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\.."));
            string Root        = Path.GetPathRoot(BinariesDir);
            string BranchPath  = MachineName + "/" + Root[0].ToString() + "/" + BinariesDir.Substring(Root.Length);

            BranchPath = BranchPath.Replace('\\', '/');

            // similar for the game path (strip off the D:\ tpe root)
            BinariesDir = Path.GetFullPath(Path.Combine(Config.BinariesDirectory, ".."));
            Root        = Path.GetPathRoot(BinariesDir);

            string GameBranchPath;

            if (Program.GameName == "UE4Game")
            {
                GameBranchPath = BranchPath;
            }
            else
            {
                GameBranchPath = MachineName + "/" + Root[0].ToString() + "/" + BinariesDir.Substring(Root.Length);
                GameBranchPath = GameBranchPath.Replace('\\', '/');
            }

            Console.WriteLine("BranchPath = {0} --- GameBranchPath = {1}", BranchPath, GameBranchPath);

            // generate the directories to recursively copy into later on
            MacStagingRootDir  = string.Format("{0}/{1}/" + Config.OSString, iPhone_SigningDevRootMac, GameBranchPath);
            MacStagingRootDir  = MacStagingRootDir.Replace("//", "/");
            MacBinariesDir     = string.Format("{0}/{1}/" + Config.OSString, iPhone_SigningDevRootMac, GameBranchPath);
            MacBinariesDir     = MacBinariesDir.Replace("//", "/");
            MacXcodeStagingDir = string.Format("{0}/{1}/" + Config.OSString + "/XcodeSupportFiles", iPhone_SigningDevRootMac, GameBranchPath);
            MacXcodeStagingDir = MacXcodeStagingDir.Replace("//", "/");

            MacMobileProvisionFilename = MachineName + "_UE4Temp.mobileprovision";
            MacSigningIdentityFilename = MachineName + "_UE4Temp.p12";
        }
Esempio n. 2
0
        /**
         * Handle spawning of the RPCUtility with parameters
         */
        public static bool RunRPCUtilty(string RPCCommand, bool bIsSilent = false)
        {
            string     CommandLine        = "";
            string     WorkingFolder      = "";
            string     DisplayCommandLine = "";
            string     TempKeychain       = "$HOME/Library/Keychains/UE4TempKeychain.keychain";
            string     Certificate        = "XcodeSupportFiles/" + MacSigningIdentityFilename;
            string     LoginKeychain      = "$HOME/Library/Keychains/login.keychain";
            ErrorCodes Error = ErrorCodes.Error_Unknown;

            switch (RPCCommand.ToLowerInvariant())
            {
            case "deletemacstagingfiles":
                Program.Log(" ... deleting staging files on the Mac");
                DisplayCommandLine = "rm -rf Payload";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "ensureprovisiondirexists":
                Program.Log(" ... creating provisioning profiles directory");

                DisplayCommandLine = String.Format("mkdir -p ~/Library/MobileDevice/Provisioning\\ Profiles");

                CommandLine   = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder = "\"" + MacXcodeStagingDir + "\"";
                break;

            case "installprovision":
                // Note: The provision must have already been copied over to the Mac
                Program.Log(" ... installing .mobileprovision");

                DisplayCommandLine = String.Format("cp -f {0} ~/Library/MobileDevice/Provisioning\\ Profiles", MacMobileProvisionFilename);

                CommandLine   = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder = "\"" + MacXcodeStagingDir + "\"";
                break;

            case "removeprovision":
                Program.Log(" ... removing .mobileprovision");
                DisplayCommandLine = String.Format("rm -f ~/Library/MobileDevice/Provisioning\\ Profiles/{0}", MacMobileProvisionFilename);
                CommandLine        = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "\"";
                break;

            case "setexec":
                // Note: The executable must have already been copied over
                Program.Log(" ... setting executable bit");
                DisplayCommandLine = "chmod a+x \'" + RemoteExecutablePath + "\'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "prepackage":
                Program.Log(" ... running prepackage script remotely ");
                DisplayCommandLine = String.Format("sh prepackage.sh {0} " + Config.OSString + " {1} {2}", Program.GameName, Program.GameConfiguration, Program.Architecture);
                CommandLine        = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "\"";
                break;

            case "makeapp":
                Program.Log(" ... making application (codesign, etc...)");
                Program.Log("  Using signing identity '{0}'", Config.CodeSigningIdentity);
                DisplayCommandLine = "security -v unlock-keychain -p \"A\" \"" + TempKeychain + "\" && " + CurrentBaseXCodeCommandLine;
                CommandLine        = "\"" + MacXcodeStagingDir + "/..\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "/..\"";
                Error = ErrorCodes.Error_RemoteCertificatesNotFound;
                break;

            case "createkeychain":
                Program.Log(" ... creating temporary key chain with signing certificate");
                Program.Log("  Using signing identity '{0}'", Config.CodeSigningIdentity);
                DisplayCommandLine = "security create-keychain -p \"A\" \"" + TempKeychain + "\" && security list-keychains -s \"" + TempKeychain + "\" && security list-keychains && security set-keychain-settings -t 3600 -l  \"" + TempKeychain + "\" && security -v unlock-keychain -p \"A\" \"" + TempKeychain + "\" && security import " + Certificate + " -k \"" + TempKeychain + "\" -P \"A\" -T /usr/bin/codesign -T /usr/bin/security -t agg && CERT_IDENTITY=$(security find-identity -v -p codesigning \"" + TempKeychain + "\" | head -1 | grep '\"' | sed -e 's/[^\"]*\"//' -e 's/\".*//') && security default-keychain -s \"" + TempKeychain + "\" && security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k \"A\" -D \"$CERT_IDENTITY\" -t private " + TempKeychain;
                CommandLine        = "\"" + MacXcodeStagingDir + "/..\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "/..\"";
                break;

            case "deletekeychain":
                Program.Log(" ... remove temporary key chain");
                Program.Log("  Using signing identity '{0}'", Config.CodeSigningIdentity);
                DisplayCommandLine = "security list-keychains -s \"" + LoginKeychain + "\" && security delete-keychain \"" + TempKeychain + "\"";
                CommandLine        = "\"" + MacXcodeStagingDir + "/..\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "/..\"";
                break;

            case "validation":
                Program.Log(" ... validating distribution package");
                DisplayCommandLine = XcodeDeveloperDir + "Platforms/iPhoneOS.platform/Developer/usr/bin/Validation " + RemoteAppDirectory;
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "deleteipa":
                Program.Log(" ... deleting IPA on Mac");
                DisplayCommandLine = "rm -f " + Config.IPAFilenameOnMac;
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "kill":
                Program.Log(" ... killing");
                DisplayCommandLine = "killall " + Program.GameName;
                CommandLine        = ". " + DisplayCommandLine;
                WorkingFolder      = ".";
                break;

            case "strip":
                Program.Log(" ... stripping");
                DisplayCommandLine = "/usr/bin/xcrun strip '" + RemoteExecutablePath + "'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "resign":
                Program.Log("... resigning");
                DisplayCommandLine = "bash -c '" + "chmod a+x ResignScript" + ";" + "./ResignScript" + "'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacStagingRootDir + "\"";
                break;

            case "zip":
                Program.Log(" ... zipping");

                // NOTE: -y preserves symbolic links which is needed for iOS distro builds
                // -x excludes a file (excluding the dSYM keeps sizes smaller, and it shouldn't be in the IPA anyways)
                string dSYMName = "Payload/" + Program.GameName + Program.Architecture + ".app.dSYM";
                DisplayCommandLine = String.Format("zip -q -r -y -{0} -T {1} Payload iTunesArtwork -x {2}/ -x {2}/* " +
                                                   "-x {2}/Contents/ -x {2}/Contents/* -x {2}/Contents/Resources/ -x {2}/Contents/Resources/* " +
                                                   " -x {2}/Contents/Resources/DWARF/ -x {2}/Contents/Resources/DWARF/*",
                                                   (int)Config.RecompressionSetting,
                                                   Config.IPAFilenameOnMac,
                                                   dSYMName);

                CommandLine   = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder = "\"" + MacStagingRootDir + "\"";
                break;

            case "gendsym":
                Program.Log(" ... generating DSYM");

                string ExePath  = "Payload/" + Program.GameName + ".app/" + Program.GameName;
                string dSYMPath = Program.GameName + ".app.dSYM";
                DisplayCommandLine = String.Format("dsymutil -o {0} {1}", dSYMPath, ExePath);

                CommandLine   = "\"" + MacStagingRootDir + "\"" + DisplayCommandLine;
                WorkingFolder = "\"" + MacStagingRootDir + "\"";
                break;

            default:
                Program.Error("Unrecognized RPC command");
                return(false);
            }

            Program.Log(" ... working folder: " + WorkingFolder);
            Program.Log(" ... " + DisplayCommandLine);
            Program.Log(" ... full command: " + MacName + " " + CommandLine);

            bool bSuccess = false;

            if (Config.bUseRPCUtil)
            {
                Program.Log("Running RPC on " + MacName + " ... ");

                Process RPCUtil = new Process();
                RPCUtil.StartInfo.FileName               = @"..\RPCUtility.exe";
                RPCUtil.StartInfo.UseShellExecute        = false;
                RPCUtil.StartInfo.Arguments              = MacName + " " + CommandLine;
                RPCUtil.StartInfo.RedirectStandardOutput = true;
                RPCUtil.StartInfo.RedirectStandardError  = true;
                RPCUtil.OutputDataReceived              += new DataReceivedEventHandler(OutputReceivedRemoteProcessCall);
                RPCUtil.ErrorDataReceived += new DataReceivedEventHandler(OutputReceivedRemoteProcessCall);

                RPCUtil.Start();

                RPCUtil.BeginOutputReadLine();
                RPCUtil.BeginErrorReadLine();

                RPCUtil.WaitForExit();

                bSuccess = (RPCUtil.ExitCode == 0);
                if (bSuccess == false && !bIsSilent)
                {
                    Program.Error("RPCCommand {0} failed with return code {1}", RPCCommand, RPCUtil.ExitCode);
                    switch (RPCCommand.ToLowerInvariant())
                    {
                    case "installprovision":
                        Program.Error("Ensure your access permissions for '~/Library/MobileDevice/Provisioning Profiles' are set correctly.");
                        break;

                    default:
                        break;
                    }
                }
            }
            else
            {
                Program.Log("Running SSH on " + MacName + " ... ");
                bSuccess = SSHCommandHelper.Command(MacName, DisplayCommandLine, WorkingFolder);
                if (bSuccess == false && !bIsSilent)
                {
                    Program.Error("RPCCommand {0} failed with return code {1}", RPCCommand, Error);
                    Program.ReturnCode = (int)Error;
                }
            }


            return(bSuccess);
        }
Esempio n. 3
0
        /**
         * Handle spawning of the RPCUtility with parameters
         */
        public static bool RunRPCUtilty(string RPCCommand)
        {
            string CommandLine        = "";
            string WorkingFolder      = "";
            string DisplayCommandLine = "";

            switch (RPCCommand.ToLowerInvariant())
            {
            case "deletemacstagingfiles":
                Program.Log(" ... deleting staging files on the Mac");
                DisplayCommandLine = "rm -rf Payload";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "ensureprovisiondirexists":
                Program.Log(" ... creating provisioning profiles directory");

                DisplayCommandLine = String.Format("mkdir -p ~/Library/MobileDevice/Provisioning\\ Profiles");

                CommandLine   = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder = MacXcodeStagingDir;
                break;

            case "installprovision":
                // Note: The provision must have already been copied over to the Mac
                Program.Log(" ... installing .mobileprovision");

                DisplayCommandLine = String.Format("cp -f {0} ~/Library/MobileDevice/Provisioning\\ Profiles", MacMobileProvisionFilename);

                CommandLine   = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder = MacXcodeStagingDir;
                break;

            case "removeprovision":
                Program.Log(" ... removing .mobileprovision");
                DisplayCommandLine = String.Format("rm -f ~/Library/MobileDevice/Provisioning\\ Profiles/{0}", MacMobileProvisionFilename);
                CommandLine        = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacXcodeStagingDir;
                break;

            case "setexec":
                // Note: The executable must have already been copied over
                Program.Log(" ... setting executable bit");
                DisplayCommandLine = "chmod a+x \'" + RemoteExecutablePath + "\'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "prepackage":
                Program.Log(" ... running prepackage script remotely ");
                DisplayCommandLine = String.Format("sh prepackage.sh {0} IOS {1} {2}", Program.GameName, Program.GameConfiguration, Program.Architecture);
                CommandLine        = "\"" + MacXcodeStagingDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacXcodeStagingDir;
                break;

            case "makeapp":
                Program.Log(" ... making application (codesign, etc...)");
                Program.Log("  Using signing identity '{0}'", Config.CodeSigningIdentity);
                DisplayCommandLine = CurrentBaseXCodeCommandLine;
                CommandLine        = "\"" + MacXcodeStagingDir + "/..\" " + DisplayCommandLine;
                WorkingFolder      = "\"" + MacXcodeStagingDir + "/..\"";
                break;

            case "validation":
                Program.Log(" ... validating distribution package");
                DisplayCommandLine = XcodeDeveloperDir + "Platforms/iPhoneOS.platform/Developer/usr/bin/Validation " + RemoteAppDirectory;
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "deleteipa":
                Program.Log(" ... deleting IPA on Mac");
                DisplayCommandLine = "rm -f " + Config.IPAFilenameOnMac;
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "kill":
                Program.Log(" ... killing");
                DisplayCommandLine = "killall " + Program.GameName;
                CommandLine        = ". " + DisplayCommandLine;
                WorkingFolder      = ".";
                break;

            case "strip":
                Program.Log(" ... stripping");
                DisplayCommandLine = XcodeDeveloperDir + "Platforms/iPhoneOS.platform/Developer/usr/bin/strip '" + RemoteExecutablePath + "'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "resign":
                Program.Log("... resigning");
                DisplayCommandLine = "bash -c '" + "chmod a+x ResignScript" + ";" + "./ResignScript" + "'";
                CommandLine        = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder      = MacStagingRootDir;
                break;

            case "zip":
                Program.Log(" ... zipping");

                // NOTE: -y preserves symbolic links which is needed for iOS distro builds
                // -x excludes a file (excluding the dSYM keeps sizes smaller, and it shouldn't be in the IPA anyways)
                string dSYMName = "Payload/" + Program.GameName + Program.Architecture + ".app.dSYM";
                DisplayCommandLine = String.Format("zip -q -r -y -{0} -T {1} Payload iTunesArtwork -x {2}/ -x {2}/* " +
                                                   "-x {2}/Contents/ -x {2}/Contents/* -x {2}/Contents/Resources/ -x {2}/Contents/Resources/* " +
                                                   " -x {2}/Contents/Resources/DWARF/ -x {2}/Contents/Resources/DWARF/*",
                                                   (int)Config.RecompressionSetting,
                                                   Config.IPAFilenameOnMac,
                                                   dSYMName);

                CommandLine   = "\"" + MacStagingRootDir + "\" " + DisplayCommandLine;
                WorkingFolder = MacStagingRootDir;
                break;

            case "gendsym":
                Program.Log(" ... generating DSYM");

                string ExePath  = "Payload/" + Program.GameName + ".app/" + Program.GameName;
                string dSYMPath = Program.GameName + ".app.dSYM";
                DisplayCommandLine = String.Format("dsymutil -o {0} {1}", dSYMPath, ExePath);

                CommandLine   = "\"" + MacStagingRootDir + "\"" + DisplayCommandLine;
                WorkingFolder = MacStagingRootDir;
                break;

            default:
                Program.Error("Unrecognized RPC command");
                return(false);
            }

            Program.Log(" ... working folder: " + WorkingFolder);
            Program.Log(" ... " + DisplayCommandLine);
            Program.Log(" ... full command: " + MacName + " " + CommandLine);

            bool bSuccess = false;

            if (Config.bUseRPCUtil)
            {
                Program.Log("Running RPC on " + MacName + " ... ");

                Process RPCUtil = new Process();
                RPCUtil.StartInfo.FileName               = @"..\RPCUtility.exe";
                RPCUtil.StartInfo.UseShellExecute        = false;
                RPCUtil.StartInfo.Arguments              = MacName + " " + CommandLine;
                RPCUtil.StartInfo.RedirectStandardOutput = true;
                RPCUtil.StartInfo.RedirectStandardError  = true;
                RPCUtil.OutputDataReceived              += new DataReceivedEventHandler(OutputReceivedRemoteProcessCall);
                RPCUtil.ErrorDataReceived += new DataReceivedEventHandler(OutputReceivedRemoteProcessCall);

                RPCUtil.Start();

                RPCUtil.BeginOutputReadLine();
                RPCUtil.BeginErrorReadLine();

                RPCUtil.WaitForExit();

                bSuccess = (RPCUtil.ExitCode == 0);
                if (bSuccess == false)
                {
                    Program.Error("RPCCommand {0} failed with return code {1}", RPCCommand, RPCUtil.ExitCode);
                    switch (RPCCommand.ToLowerInvariant())
                    {
                    case "installprovision":
                        Program.Error("Ensure your access permissions for '~/Library/MobileDevice/Provisioning Profiles' are set correctly.");
                        break;

                    default:
                        break;
                    }
                }
            }
            else
            {
                Program.Log("Running SSH on " + MacName + " ... ");
                bSuccess = SSHCommandHelper.Command(MacName, DisplayCommandLine, WorkingFolder);
            }


            return(bSuccess);
        }