Skip to content

Commit 3114a4d

Browse files
authored
fix: provisioning profile file path after Xcode 16 (#1471)
1 parent 72af42d commit 3114a4d

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

documentation/docs/ios-signing.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ If you want to provide the custom path of WebDriverAgent project then set _WDA_P
9595
appium plugin run device-farm prepare-wda --wda-project-path=<path-to-WDA-project> --mobile-provisioning-file=<path-to-provision-profile>
9696
```
9797

98-
You should have all the provision certificates installed on your machine to build the WebDriverAgent from source in path.
98+
You should have all the provision certificates installed on your machine before building the WebDriverAgent from source. For Xcode versions 15 or below, ensure they are located in:
9999
```
100100
~/Library/MobileDevice/Provisioning\ Profiles
101101
```
102+
103+
For Xcode versions 16 and above, place them in:
104+
```
105+
~/Library/Developer/Xcode/UserData/Provisioning\ Profiles
106+
```

src/scripts/ios-sign.ts

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,31 @@ import { select } from '@inquirer/prompts';
1818

1919
const execAsync = util.promisify(exec);
2020
const WDA_BUILD_PATH = '/appium_wda_ios/Build/Products/Debug-iphoneos';
21-
const PROVISION_FILE_PATH_PREFIX = path.join(
22-
os.homedir(),
23-
'Library/MobileDevice/Provisioning Profiles',
24-
);
21+
22+
async function getXcodeMajorVersion(): Promise<number> {
23+
const { stdout } = await execAsync('xcodebuild -version');
24+
const match = stdout.match(/Xcode (\d+)\./);
25+
if (!match) {
26+
throw new Error('Unable to determine Xcode version');
27+
}
28+
return parseInt(match[1], 10);
29+
}
30+
31+
async function getProvisioningProfilePath(): Promise<string> {
32+
const xcodeVersion = await getXcodeMajorVersion();
33+
34+
if (xcodeVersion <= 15) {
35+
return path.join(
36+
os.homedir(),
37+
'Library/MobileDevice/Provisioning Profiles'
38+
);
39+
} else {
40+
return path.join(
41+
os.homedir(),
42+
'Library/Developer/Xcode/UserData/Provisioning Profiles'
43+
);
44+
}
45+
}
2546

2647
type Context = ListrContext & CliOptions;
2748

@@ -55,7 +76,21 @@ const getMobileProvisioningFile = async (mobileProvisioningFile?: string) => {
5576
}
5677
return mobileProvisioningFile;
5778
} else {
58-
const provisioningFiles = provision.read();
79+
const provisionFileDir = await getProvisioningProfilePath();
80+
81+
if (!fs.existsSync(provisionFileDir)) {
82+
throw new Error(`Provisioning directory does not exist: ${provisionFileDir}`);
83+
}
84+
85+
const files = fs.readdirSync(provisionFileDir, { encoding: 'utf8' })
86+
.filter(file => file.endsWith('.mobileprovision'));
87+
88+
const provisioningFiles = files.map(file => {
89+
const fullPath = path.join(provisionFileDir, file);
90+
const mp = provision.readFromFile(fullPath);
91+
return { ...mp, _filePath: fullPath };
92+
});
93+
5994
if (!provisioningFiles || !provisioningFiles.length) {
6095
throw new Error('No mobileprovision file found on the machine');
6196
}
@@ -66,8 +101,8 @@ const getMobileProvisioningFile = async (mobileProvisioningFile?: string) => {
66101
name: `${file.Name.split(':')[1] || file.Name} (Team: ${file.TeamName}) (${file.UUID})`,
67102
})),
68103
});
69-
70-
return path.join(PROVISION_FILE_PATH_PREFIX, `${prompt}.mobileprovision`);
104+
105+
return path.join(await getProvisioningProfilePath(), `${prompt}.mobileprovision`);
71106
}
72107
};
73108

0 commit comments

Comments
 (0)