1import chalk from 'chalk';
2
3import * as Log from '../../../log';
4import * as Security from './Security';
5import { resolveCertificateSigningIdentityAsync } from './resolveCertificateSigningIdentity';
6import { getCodeSigningInfoForPbxproj, setAutoCodeSigningInfoForPbxproj } from './xcodeCodeSigning';
7
8export async function ensureDeviceIsCodeSignedForDeploymentAsync(
9  projectRoot: string
10): Promise<string | null> {
11  if (isCodeSigningConfigured(projectRoot)) {
12    return null;
13  }
14  return configureCodeSigningAsync(projectRoot);
15}
16
17function isCodeSigningConfigured(projectRoot: string): boolean {
18  // Check if the app already has a development team defined.
19  const signingInfo = getCodeSigningInfoForPbxproj(projectRoot);
20
21  const allTargetsHaveTeams = Object.values(signingInfo).reduce((prev, curr) => {
22    return prev && !!curr.developmentTeams.length;
23  }, true);
24
25  if (allTargetsHaveTeams) {
26    const teamList = Object.values(signingInfo).reduce<string[]>((prev, curr) => {
27      return prev.concat([curr.developmentTeams[0]]);
28    }, []);
29    Log.log(chalk.dim`\u203A Auto signing app using team(s): ${teamList.join(', ')}`);
30    return true;
31  }
32
33  const allTargetsHaveProfiles = Object.values(signingInfo).reduce((prev, curr) => {
34    return prev && !!curr.provisioningProfiles.length;
35  }, true);
36
37  if (allTargetsHaveProfiles) {
38    // this indicates that the user has manual code signing setup (possibly for production).
39    return true;
40  }
41  return false;
42}
43
44async function configureCodeSigningAsync(projectRoot: string) {
45  const ids = await Security.findIdentitiesAsync();
46
47  const id = await resolveCertificateSigningIdentityAsync(ids);
48
49  Log.log(`\u203A Signing and building iOS app with: ${id.codeSigningInfo}`);
50
51  setAutoCodeSigningInfoForPbxproj(projectRoot, {
52    appleTeamId: id.appleTeamId!,
53  });
54  return id.appleTeamId!;
55}
56