Skip to content

feat(publish): ability to publish applications using Xcode 11 #4965

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions lib/commands/appstore-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,12 @@ export class PublishIOS implements ICommand {
}

public async execute(args: string[]): Promise<void> {
let username = args[0];
let password = args[1];
await this.$itmsTransporterService.validate();

const username = args[0] || await this.$prompter.getString("Apple ID", { allowEmpty: false });
const password = args[1] || await this.$prompter.getPassword("Apple ID password");
const mobileProvisionIdentifier = args[2];
const codeSignIdentity = args[3];
let ipaFilePath = this.$options.ipa ? path.resolve(this.$options.ipa) : null;

if (!username) {
username = await this.$prompter.getString("Apple ID", { allowEmpty: false });
}

if (!password) {
password = await this.$prompter.getPassword("Apple ID password");
}

const user = await this.$applePortalSessionService.createUserSession({ username, password }, {
applicationSpecificPassword: this.$options.appleApplicationSpecificPassword,
Expand All @@ -49,6 +42,8 @@ export class PublishIOS implements ICommand {
this.$errors.fail(`Invalid username and password combination. Used '${username}' as the username.`);
}

let ipaFilePath = this.$options.ipa ? path.resolve(this.$options.ipa) : null;

if (!mobileProvisionIdentifier && !ipaFilePath) {
this.$logger.warn("No mobile provision identifier set. A default mobile provision will be used. You can set one in app/App_Resources/iOS/build.xcconfig");
}
Expand All @@ -58,9 +53,9 @@ export class PublishIOS implements ICommand {
}

this.$options.release = true;
const platform = this.$devicePlatformsConstants.iOS.toLowerCase();

if (!ipaFilePath) {
const platform = this.$devicePlatformsConstants.iOS.toLowerCase();
// No .ipa path provided, build .ipa on out own.
if (mobileProvisionIdentifier || codeSignIdentity) {
// This is not very correct as if we build multiple targets we will try to sign all of them using the signing identity here.
Expand Down
12 changes: 3 additions & 9 deletions lib/common/services/xcode-select-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,9 @@ export class XcodeSelectService implements IXcodeSelectService {
this.$errors.fail("xcodebuild execution failed. Make sure that you have latest Xcode and tools installed.");
}

const xcodeVersionMatch = xcodeVer.match(/Xcode (.*)/),
xcodeVersionGroup = xcodeVersionMatch && xcodeVersionMatch[1],
xcodeVersionSplit = xcodeVersionGroup && xcodeVersionGroup.split(".");

return {
major: xcodeVersionSplit && xcodeVersionSplit[0],
minor: xcodeVersionSplit && xcodeVersionSplit[1],
patch: xcodeVersionSplit && xcodeVersionSplit[2]
};
const [ major, minor, patch ] = xcodeVer.split(".");

return { major, minor, patch };
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/common/test/unit-tests/xcode-select-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe("xcode-select-service", () => {
});

it("gets correct Xcode version", async () => {
injector = createTestInjector({ xcodeSelectStdout: null, isDarwin: true, xcodeVersionOutput: "Xcode 7.3\nBuild version 7D175" });
injector = createTestInjector({ xcodeSelectStdout: null, isDarwin: true, xcodeVersionOutput: "7.3" });
service = injector.resolve("$xcodeSelectService");

const xcodeVersion = await service.getXcodeVersion();
Expand Down
1 change: 1 addition & 0 deletions lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ interface IITMSData {
* Used for communicating with Xcode's iTMS Transporter tool.
*/
interface IITMSTransporterService {
validate(): Promise<void>;
/**
* Uploads an .ipa package to iTunes Connect.
* @param {IITMSData} data Data needed to upload the package
Expand Down
16 changes: 12 additions & 4 deletions lib/services/itmstransporter-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export class ITMSTransporterService implements IITMSTransporterService {
return this.$injector.resolve("projectData");
}

public async validate(): Promise<void> {
const itmsTransporterPath = await this.getITMSTransporterPath();
if (!this.$fs.exists(itmsTransporterPath)) {
this.$errors.fail('iTMS Transporter not found on this machine - make sure your Xcode installation is not damaged.');
}
}

public async upload(data: IITMSData): Promise<void> {
temp.track();
const itmsTransporterPath = await this.getITMSTransporterPath();
Expand Down Expand Up @@ -96,11 +103,12 @@ export class ITMSTransporterService implements IITMSTransporterService {
@cache()
private async getITMSTransporterPath(): Promise<string> {
const xcodePath = await this.$xcodeSelectService.getContentsDirectoryPath();
const loaderAppContentsPath = path.join(xcodePath, "Applications", "Application Loader.app", "Contents");
const itmsTransporterPath = path.join(loaderAppContentsPath, ITMSConstants.iTMSDirectoryName, "bin", ITMSConstants.iTMSExecutableName);
let itmsTransporterPath = path.join(xcodePath, "..", "Contents", "SharedFrameworks", "ContentDeliveryServices.framework", "Versions", "A", "itms", "bin", ITMSConstants.iTMSExecutableName);

if (!this.$fs.exists(itmsTransporterPath)) {
this.$errors.fail('iTMS Transporter not found on this machine - make sure your Xcode installation is not damaged.');
const xcodeVersionData = await this.$xcodeSelectService.getXcodeVersion();
if (+xcodeVersionData.major < 11) {
const loaderAppContentsPath = path.join(xcodePath, "Applications", "Application Loader.app", "Contents");
itmsTransporterPath = path.join(loaderAppContentsPath, ITMSConstants.iTMSDirectoryName, "bin", ITMSConstants.iTMSExecutableName);
}

return itmsTransporterPath;
Expand Down
1 change: 1 addition & 0 deletions test/tns-appstore-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class AppStore {

expectITMSTransporterUpload() {
this.expectedItmsTransporterServiceUploadCalls = 1;
this.itmsTransporterService.validate = () => Promise.resolve();
this.itmsTransporterService.upload = (options: IITMSData) => {
this.itmsTransporterServiceUploadCalls++;
chai.assert.equal(options.ipaFilePath, "/Users/person/git/MyProject/platforms/ios/archive/MyProject.ipa");
Expand Down