Skip to content

Commit b91bc2c

Browse files
authored
Merge pull request #2845 from Microsoft/users/mg/xcode8m105
xcode 8 changes port to M105
2 parents 81647da + bb7fbaf commit b91bc2c

File tree

12 files changed

+943
-202
lines changed

12 files changed

+943
-202
lines changed

Tasks/Common/ios-signing-common/ios-signing-common.ts

Lines changed: 118 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Q = require('q');
44
import tl = require('vsts-task-lib/task');
55
import {ToolRunner} from 'vsts-task-lib/toolrunner';
66

7-
var userProvisioningProfilesPath = path.join(tl.getVariable('HOME'), 'Library', 'MobileDevice', 'Provisioning Profiles');
7+
var userProvisioningProfilesPath = tl.resolve(tl.getVariable('HOME'), 'Library', 'MobileDevice', 'Provisioning Profiles');
88

99
/**
1010
* Creates a temporary keychain and installs the P12 cert in the temporary keychain
@@ -18,31 +18,26 @@ export async function installCertInTemporaryKeychain(keychainPath : string, keyc
1818
await deleteKeychain(keychainPath);
1919

2020
//create keychain
21-
var createKeychainCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
22-
createKeychainCommand.arg(['create-keychain', '-p', keychainPwd]);
23-
createKeychainCommand.pathArg(keychainPath);
21+
var createKeychainCommand : ToolRunner = tl.tool(tl.which('security', true));
22+
createKeychainCommand.arg(['create-keychain', '-p', keychainPwd, keychainPath]);
2423
await createKeychainCommand.exec();
2524

2625
//update keychain settings
27-
var keychainSettingsCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
28-
keychainSettingsCommand.arg(['set-keychain-settings', '-lut', '7200']);
29-
keychainSettingsCommand.pathArg(keychainPath);
26+
var keychainSettingsCommand : ToolRunner = tl.tool(tl.which('security', true));
27+
keychainSettingsCommand.arg(['set-keychain-settings', '-lut', '7200', keychainPath]);
3028
await keychainSettingsCommand.exec();
3129

3230
//unlock keychain
3331
await unlockKeychain(keychainPath, keychainPwd);
3432

3533
//import p12 cert into the keychain
36-
var importP12Command : ToolRunner = tl.createToolRunner(tl.which('security', true));
37-
importP12Command.arg('import');
38-
importP12Command.pathArg(p12CertPath);
39-
importP12Command.arg(['-P', p12Pwd, '-A', '-t', 'cert', '-f', 'pkcs12', '-k']);
40-
importP12Command.pathArg(keychainPath);
34+
var importP12Command : ToolRunner = tl.tool(tl.which('security', true));
35+
importP12Command.arg(['import', p12CertPath, '-P', p12Pwd, '-A', '-t', 'cert', '-f', 'pkcs12', '-k', keychainPath]);
4136
await importP12Command.exec();
4237

4338
//list the keychains to get current keychains in search path
4439
var listAllOutput : string;
45-
var listAllCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
40+
var listAllCommand : ToolRunner = tl.tool(tl.which('security', true));
4641
listAllCommand.arg(['list-keychain', '-d', 'user']);
4742
listAllCommand.on('stdout', function(data) {
4843
if(data) {
@@ -68,11 +63,11 @@ export async function installCertInTemporaryKeychain(keychainPath : string, keyc
6863
//login keychain is not in the search path,
6964
//this might have happened with the 2.1.21 version of Xcode task
7065
//add it back explicitly, this can be removed after a couple of sprints
71-
allKeychainsArr.push(path.join(tl.getVariable('HOME'), 'Library', 'Keychains', 'login.keychain'));
66+
allKeychainsArr.push(tl.resolve(tl.getVariable('HOME'), 'Library', 'Keychains', 'login.keychain'));
7267
}
7368

7469
//add the temporary keychain to list path along with existing keychains
75-
var listAddCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
70+
var listAddCommand : ToolRunner = tl.tool(tl.which('security', true));
7671
listAddCommand.arg(['list-keychain', '-d', 'user', '-s', keychainPath]);
7772
for(var i : number = 0; i < allKeychainsArr.length; i ++) {
7873
listAddCommand.arg(allKeychainsArr[i].trim().replace(/"/gm, ''));
@@ -81,7 +76,7 @@ export async function installCertInTemporaryKeychain(keychainPath : string, keyc
8176
await listAddCommand.exec();
8277

8378
var listVerifyOutput : string;
84-
var listVerifyCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
79+
var listVerifyCommand : ToolRunner = tl.tool(tl.which('security', true));
8580
listVerifyCommand.arg(['list-keychain', '-d', 'user']);
8681
listVerifyCommand.on('stdout', function(data) {
8782
if(data) {
@@ -108,9 +103,8 @@ export async function installCertInTemporaryKeychain(keychainPath : string, keyc
108103
*/
109104
export async function findSigningIdentity(keychainPath: string) {
110105
var signIdentity : string;
111-
var findIdentityCmd : ToolRunner = tl.createToolRunner(tl.which('security', true));
112-
findIdentityCmd.arg(['find-identity', '-v', '-p', 'codesigning']);
113-
findIdentityCmd.pathArg(keychainPath);
106+
var findIdentityCmd : ToolRunner = tl.tool(tl.which('security', true));
107+
findIdentityCmd.arg(['find-identity', '-v', '-p', 'codesigning', keychainPath]);
114108
findIdentityCmd.on('stdout', function (data) {
115109
if (data) {
116110
var matches = data.toString().trim().match(/"(.+)"/g);
@@ -140,9 +134,8 @@ export async function getProvisioningProfileUUID(provProfilePath: string) {
140134

141135
//find the provisioning profile UUID
142136
var provProfileDetails : string;
143-
var getProvProfileDetailsCmd : ToolRunner = tl.createToolRunner(tl.which('security', true));
144-
getProvProfileDetailsCmd.arg(['cms', '-D', '-i']);
145-
getProvProfileDetailsCmd.pathArg(provProfilePath);
137+
var getProvProfileDetailsCmd : ToolRunner = tl.tool(tl.which('security', true));
138+
getProvProfileDetailsCmd.arg(['cms', '-D', '-i', provProfilePath]);
146139
getProvProfileDetailsCmd.on('stdout', function(data) {
147140
if(data) {
148141
if(provProfileDetails) {
@@ -165,9 +158,8 @@ export async function getProvisioningProfileUUID(provProfilePath: string) {
165158
//use PlistBuddy to figure out the UUID
166159
var provProfileUUID : string;
167160
var plist = tl.which('/usr/libexec/PlistBuddy', true);
168-
var plistTool : ToolRunner = tl.createToolRunner(plist);
169-
plistTool.arg(['-c', 'Print UUID']);
170-
plistTool.pathArg(tmpPlist);
161+
var plistTool : ToolRunner = tl.tool(plist);
162+
plistTool.arg(['-c', 'Print UUID', tmpPlist]);
171163
plistTool.on('stdout', function (data) {
172164
if (data) {
173165
provProfileUUID = data.toString();
@@ -176,19 +168,16 @@ export async function getProvisioningProfileUUID(provProfilePath: string) {
176168
await plistTool.exec();
177169

178170
//delete the temporary plist file
179-
var deletePlistCommand : ToolRunner = tl.createToolRunner(tl.which('rm', true));
180-
deletePlistCommand.arg('-f');
181-
deletePlistCommand.pathArg(tmpPlist);
171+
var deletePlistCommand : ToolRunner = tl.tool(tl.which('rm', true));
172+
deletePlistCommand.arg(['-f', tmpPlist]);
182173
await deletePlistCommand.exec();
183174

184175
if(provProfileUUID) {
185176
//copy the provisioning profile file to ~/Library/MobileDevice/Provisioning Profiles
186177
tl.mkdirP(userProvisioningProfilesPath); // Path may not exist if Xcode has not been run yet.
187178
var pathToProvProfile : string = getProvisioningProfilePath(provProfileUUID);
188-
var copyProvProfileCmd : ToolRunner = tl.createToolRunner(tl.which('cp', true));
189-
copyProvProfileCmd.arg('-f');
190-
copyProvProfileCmd.pathArg(provProfilePath); //source
191-
copyProvProfileCmd.pathArg(pathToProvProfile); //dest
179+
var copyProvProfileCmd : ToolRunner = tl.tool(tl.which('cp', true));
180+
copyProvProfileCmd.arg(['-f', provProfilePath, pathToProvProfile]);
192181
await copyProvProfileCmd.exec();
193182

194183
return provProfileUUID;
@@ -197,15 +186,103 @@ export async function getProvisioningProfileUUID(provProfilePath: string) {
197186
}
198187
}
199188

189+
190+
/**
191+
* Find the type of the provisioning profile - development, app-store or ad-hoc
192+
* @param provProfilePath
193+
* @returns {string} type
194+
*/
195+
export async function getProvisioningProfileType(provProfilePath: string) {
196+
var provProfileType: string;
197+
try {
198+
//find the provisioning profile details
199+
var provProfileDetails:string;
200+
var getProvProfileDetailsCmd:ToolRunner = tl.tool(tl.which('security', true));
201+
getProvProfileDetailsCmd.arg(['cms', '-D', '-i', provProfilePath]);
202+
getProvProfileDetailsCmd.on('stdout', function (data) {
203+
if (data) {
204+
if (provProfileDetails) {
205+
provProfileDetails = provProfileDetails.concat(data.toString().trim().replace(/[,\n\r\f\v]/gm, ''));
206+
} else {
207+
provProfileDetails = data.toString().trim().replace(/[,\n\r\f\v]/gm, '');
208+
}
209+
}
210+
})
211+
await getProvProfileDetailsCmd.exec();
212+
213+
if (provProfileDetails) {
214+
//write the provisioning profile to a plist
215+
var tmpPlist = '_xcodetasktmp.plist';
216+
fs.writeFileSync(tmpPlist, provProfileDetails);
217+
} else {
218+
throw tl.loc('ProvProfileDetailsNotFound', provProfilePath);
219+
}
220+
221+
//get ProvisionsAllDevices - this will exist for enterprise profiles
222+
var provisionsAllDevices: string = await printFromPlist('ProvisionsAllDevices', tmpPlist);
223+
tl.debug('provisionsAllDevices = ' + provisionsAllDevices);
224+
if(provisionsAllDevices && provisionsAllDevices.toLowerCase() === 'true') {
225+
//ProvisionsAllDevices = true in enterprise profiles
226+
provProfileType = 'enterprise';
227+
} else {
228+
var getTaskAllow: string = await printFromPlist('Entitlements:get-task-allow', tmpPlist);
229+
tl.debug('getTaskAllow = ' + getTaskAllow);
230+
if (getTaskAllow && getTaskAllow.trim().toLowerCase() === 'true') {
231+
//get-task-allow = true means it is a development profile
232+
provProfileType = 'development';
233+
} else {
234+
var provisionedDevices:string = await printFromPlist('ProvisionedDevices', tmpPlist);
235+
if (!provisionedDevices) {
236+
// no provisioned devices for non-development profile means it is an app-store profile
237+
provProfileType = 'app-store';
238+
} else {
239+
// non-development profile with provisioned devices - use ad-hoc
240+
provProfileType = 'ad-hoc';
241+
}
242+
}
243+
}
244+
245+
//delete the temporary plist file
246+
var deletePlistCommand:ToolRunner = tl.tool(tl.which('rm', true));
247+
deletePlistCommand.arg(['-f', tmpPlist]);
248+
await deletePlistCommand.exec();
249+
} catch (err) {
250+
tl.debug(err);
251+
}
252+
253+
return provProfileType;
254+
}
255+
256+
async function printFromPlist(itemToPrint: string, plistPath: string) {
257+
var plist = tl.which('/usr/libexec/PlistBuddy', true);
258+
var plistTool:ToolRunner = tl.tool(plist);
259+
plistTool.arg(['-c', 'Print ' + itemToPrint, plistPath]);
260+
261+
var printedValue: string;
262+
plistTool.on('stdout', function (data) {
263+
if (data) {
264+
printedValue = data.toString();
265+
}
266+
});
267+
268+
try {
269+
await plistTool.exec();
270+
} catch (err) {
271+
tl.debug('Exception when looking for ' + itemToPrint + ' in plist.');
272+
printedValue = null;
273+
}
274+
275+
return printedValue;
276+
}
277+
200278
/**
201279
* Delete specified iOS keychain
202280
* @param keychainPath
203281
*/
204282
export async function deleteKeychain(keychainPath: string) {
205283
if (fs.existsSync(keychainPath)) {
206-
var deleteKeychainCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
207-
deleteKeychainCommand.arg('delete-keychain');
208-
deleteKeychainCommand.pathArg(keychainPath);
284+
var deleteKeychainCommand : ToolRunner = tl.tool(tl.which('security', true));
285+
deleteKeychainCommand.arg(['delete-keychain', keychainPath]);
209286
await deleteKeychainCommand.exec();
210287
}
211288
}
@@ -217,9 +294,8 @@ export async function deleteKeychain(keychainPath: string) {
217294
*/
218295
export async function unlockKeychain(keychainPath: string, keychainPwd: string) {
219296
//unlock the keychain
220-
var unlockCommand : ToolRunner = tl.createToolRunner(tl.which('security', true));
221-
unlockCommand.arg(['unlock-keychain', '-p', keychainPwd]);
222-
unlockCommand.pathArg(keychainPath);
297+
var unlockCommand : ToolRunner = tl.tool(tl.which('security', true));
298+
unlockCommand.arg(['unlock-keychain', '-p', keychainPwd, keychainPath]);
223299
await unlockCommand.exec();
224300
}
225301

@@ -233,23 +309,22 @@ export async function deleteProvisioningProfile(uuid: string) {
233309
if(fs.existsSync(provProfilePath)) {
234310
tl.warning('Deleting provisioning profile: ' + provProfilePath);
235311

236-
var deleteProfileCommand : ToolRunner = tl.createToolRunner(tl.which('rm', true));
237-
deleteProfileCommand.arg('-f');
238-
deleteProfileCommand.pathArg(provProfilePath);
312+
var deleteProfileCommand : ToolRunner = tl.tool(tl.which('rm', true));
313+
deleteProfileCommand.arg(['-f', provProfilePath]);
239314
await deleteProfileCommand.exec();
240315
}
241316
}
242317

243318
function getProvisioningProfilePath(uuid: string) : string {
244-
return path.join(userProvisioningProfilesPath, uuid.trim().concat('.mobileprovision'));
319+
return tl.resolve(userProvisioningProfilesPath, uuid.trim().concat('.mobileprovision'));
245320
}
246321

247322
/**
248323
* Gets the path to the iOS default keychain
249324
*/
250325
export async function getDefaultKeychainPath() {
251326
var defaultKeychainPath : string;
252-
var getKeychainCmd : ToolRunner = tl.createToolRunner(tl.which('security', true));
327+
var getKeychainCmd : ToolRunner = tl.tool(tl.which('security', true));
253328
getKeychainCmd.arg('default-keychain');
254329
getKeychainCmd.on('stdout', function (data) {
255330
if (data) {

0 commit comments

Comments
 (0)