private void registerExtractTeamPrefixAction(Artifact teamPrefixFile) { String shellCommand = "set -e && " + "PLIST=$(mktemp -t teamprefix.plist) && trap \"rm ${PLIST}\" EXIT && " + extractPlistCommand(attributes.provisioningProfile()) + " > ${PLIST} && " + "/usr/libexec/PlistBuddy -c 'Print ApplicationIdentifierPrefix:0' ${PLIST} > " + teamPrefixFile.getShellEscapedExecPathString(); ruleContext.registerAction( ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand) .setMnemonic("ExtractIosTeamPrefix") .addInput(attributes.provisioningProfile()) .addOutput(teamPrefixFile) .build(ruleContext)); }
/** * Registers actions required to build an application. This includes any {@link * BundleSupport#registerActions(ObjcProvider) bundle} and bundle merge actions, signing this * application if appropriate and combining several single-architecture binaries into one * multi-architecture binary. * * @return this application support * @throws InterruptedException */ ReleaseBundlingSupport registerActions() throws InterruptedException { bundleSupport.registerActions(objcProvider); registerCombineArchitecturesAction(); registerTransformAndCopyBreakpadFilesAction(); registerSwiftStdlibActionsIfNecessary(); ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); Artifact ipaOutput = ruleContext.getImplicitOutputArtifact(IPA); Artifact maybeSignedIpa; if (objcConfiguration.getBundlingPlatform() == Platform.IOS_SIMULATOR) { maybeSignedIpa = ipaOutput; } else if (attributes.provisioningProfile() == null) { throw new IllegalStateException(DEVICE_NO_PROVISIONING_PROFILE); } else { maybeSignedIpa = registerBundleSigningActions(ipaOutput); } registerEmbedLabelPlistAction(); registerEnvironmentPlistAction(); BundleMergeControlBytes bundleMergeControlBytes = new BundleMergeControlBytes( bundling, maybeSignedIpa, objcConfiguration, bundleSupport.targetDeviceFamilies()); registerBundleMergeActions( maybeSignedIpa, bundling.getBundleContentArtifacts(), bundleMergeControlBytes); return this; }
private ReleaseBundlingSupport registerExtractEntitlementsAction(Artifact entitlements) { // See Apple Glossary (http://goo.gl/EkhXOb) // An Application Identifier is constructed as: TeamID.BundleID // TeamID is extracted from the provisioning profile. // BundleID consists of a reverse-DNS string to identify the app, where the last component // is the application name, and is specified as an attribute. String shellCommand = "set -e && " + "PLIST=$(mktemp -t entitlements.plist) && trap \"rm ${PLIST}\" EXIT && " + extractPlistCommand(attributes.provisioningProfile()) + " > ${PLIST} && " + "/usr/libexec/PlistBuddy -x -c 'Print Entitlements' ${PLIST} > " + entitlements.getShellEscapedExecPathString(); ruleContext.registerAction( ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand) .setMnemonic("ExtractIosEntitlements") .setProgressMessage("Extracting entitlements: " + ruleContext.getLabel()) .addInput(attributes.provisioningProfile()) .addOutput(entitlements) .build(ruleContext)); return this; }
private ReleaseBundlingSupport registerSignBundleAction( Artifact entitlements, Artifact ipaOutput, Artifact ipaUnsigned) { // TODO(bazel-team): Support variable substitution ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>(); // Explicitly sign Swift dylibs. Unfortunately --deep option on codesign doesn't do this // automatically. // The order here is important. The innermost code must singed first. String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir()); if (objcProvider.is(USES_SWIFT)) { dirsToSign.add(bundleDir + "/Frameworks/*"); } dirsToSign.add(bundleDir); StringBuilder codesignCommandLineBuilder = new StringBuilder(); for (String dir : dirsToSign.build()) { codesignCommandLineBuilder .append(codesignCommand(entitlements, "${t}/" + dir)) .append(" && "); } // TODO(bazel-team): Support nested code signing. String shellCommand = "set -e && " + "t=$(mktemp -d -t signing_intermediate) && " + "trap \"rm -rf ${t}\" EXIT && " // Get an absolute path since we need to cd into the temp directory for zip. + "signed_ipa=${PWD}/" + ipaOutput.getShellEscapedExecPathString() + " && " + "/usr/bin/unzip -qq " + ipaUnsigned.getShellEscapedExecPathString() + " -d ${t} && " + codesignCommandLineBuilder.toString() // Using zip since we need to preserve permissions + "cd ${t} && /usr/bin/zip -q -r \"${signed_ipa}\" ."; ruleContext.registerAction( ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand) .setMnemonic("IosSignBundle") .setProgressMessage("Signing iOS bundle: " + ruleContext.getLabel()) .addInput(ipaUnsigned) .addInput(attributes.provisioningProfile()) .addInput(entitlements) .addOutput(ipaOutput) .build(ruleContext)); return this; }
private String codesignCommand(Artifact entitlements, String appDir) { String signingCertName = ObjcRuleClasses.objcConfiguration(ruleContext).getSigningCertName(); final String identity; if (signingCertName != null) { identity = '"' + signingCertName + '"'; } else { // Extracts an identity hash from the configured provisioning profile. Note that this will use // the first certificate identity in the profile, regardless of how many identities are // configured in it (DeveloperCertificates:0). identity = "$(PLIST=$(mktemp -t cert.plist) && trap \"rm ${PLIST}\" EXIT && " + extractPlistCommand(attributes.provisioningProfile()) + " > ${PLIST} && " + "/usr/libexec/PlistBuddy -c 'Print DeveloperCertificates:0' ${PLIST} | " + "openssl x509 -inform DER -noout -fingerprint | " + "cut -d= -f2 | sed -e 's#:##g')"; } return String.format( "/usr/bin/codesign --force --sign %s --entitlements %s %s", identity, entitlements.getShellEscapedExecPathString(), appDir); }