public bool CopyBuild(DirectoryReference InstallPath) { CommandUtils.LogInformation("Copying shared cooked build from stage directory: {0} to {1}", Path.FullName, InstallPath.FullName); // Delete existing if (DirectoryReference.Exists(InstallPath)) { DirectoryReference.Delete(InstallPath, true); } DirectoryReference.CreateDirectory(InstallPath); // Copy new if (!CommandUtils.CopyDirectory_NoExceptions(Path.FullName, InstallPath.FullName)) { CommandUtils.LogWarning("Failed to copy {0} -> {1}", Path.FullName, InstallPath.FullName); return false; } FileReference SyncedBuildFile = new FileReference(CommandUtils.CombinePaths(InstallPath.FullName, SyncedBuildFileName)); FileReference.WriteAllLines(SyncedBuildFile, new string[] { CL.ToString(), Path.FullName }); return true; }
/// <summary> /// Resign application using local executable and update debug symbols /// </summary> void ResignApplication(UnrealAppConfig AppConfig) { // check that we have the signing stuff we need string SignProvision = Globals.Params.ParseValue("signprovision", String.Empty); string SignEntitlements = Globals.Params.ParseValue("signentitlements", String.Empty); string SigningIdentity = Globals.Params.ParseValue("signidentity", String.Empty); // handle signing provision if (string.IsNullOrEmpty(SignProvision) || !File.Exists(SignProvision)) { throw new AutomationException("Absolute path to existing provision must be specified, example: -signprovision=/path/to/myapp.provision"); } // handle entitlements // Note this extracts entitlements: which may be useful when using same provision/entitlements?: codesign -d --entitlements :entitlements.plist ~/.gauntletappcache/Payload/Example.app/ if (string.IsNullOrEmpty(SignEntitlements) || !File.Exists(SignEntitlements)) { throw new AutomationException("Absolute path to existing entitlements must be specified, example: -signprovision=/path/to/entitlements.plist"); } // signing identity if (string.IsNullOrEmpty(SigningIdentity)) { throw new AutomationException("Signing identity must be specified, example: -signidentity=\"iPhone Developer: John Smith\""); } string ProjectName = AppConfig.ProjectName; string BundleName = Path.GetFileNameWithoutExtension(LocalAppBundle); string ExecutableName = UnrealHelpers.GetExecutableName(ProjectName, UnrealTargetPlatform.IOS, AppConfig.Configuration, AppConfig.ProcessType, ""); string CachedAppPath = Path.Combine(GauntletAppCache, "Payload", string.Format("{0}.app", BundleName)); string LocalExecutable = Path.Combine(Environment.CurrentDirectory, ProjectName, string.Format("Binaries/IOS/{0}", ExecutableName)); if (!File.Exists(LocalExecutable)) { throw new AutomationException("Local executable not found for -dev argument: {0}", LocalExecutable); } File.WriteAllText(CacheResignedFilename, "The application has been resigned"); // copy local executable FileInfo SrcInfo = new FileInfo(LocalExecutable); string DestPath = Path.Combine(CachedAppPath, BundleName); SrcInfo.CopyTo(DestPath, true); Log.Verbose("Copied local executable from {0} to {1}", LocalExecutable, DestPath); // copy provision SrcInfo = new FileInfo(SignProvision); DestPath = Path.Combine(CachedAppPath, "embedded.mobileprovision"); SrcInfo.CopyTo(DestPath, true); Log.Verbose("Copied provision from {0} to {1}", SignProvision, DestPath); // handle symbols string LocalSymbolsDir = Path.Combine(Environment.CurrentDirectory, ProjectName, string.Format("Binaries/IOS/{0}.dSYM", ExecutableName)); DestPath = Path.Combine(GauntletAppCache, string.Format("Symbols/{0}.dSYM", ExecutableName)); if (Directory.Exists(DestPath)) { Directory.Delete(DestPath, true); } if (Directory.Exists(LocalSymbolsDir)) { CommandUtils.CopyDirectory_NoExceptions(LocalSymbolsDir, DestPath, true); } else { Log.Warning("No symbols found for local build at {0}, removing cached app symbols", LocalSymbolsDir); } // resign application // @todo: this asks for password unless "Always Allow" is selected, also for builders, document how to permanently grant codesign access to keychain string SignArgs = string.Format("-f -s \"{0}\" --entitlements \"{1}\" \"{2}\"", SigningIdentity, SignEntitlements, CachedAppPath); Log.Info("\nResigning app, please enter keychain password if prompted:\n\ncodesign {0}", SignArgs); var Result = IOSBuild.ExecuteCommand("codesign", SignArgs); if (Result.ExitCode != 0) { throw new AutomationException("Failed to resign application"); } }