diff --git a/Sources/ReleaseTools/Commands/NotarizeCommand.swift b/Sources/ReleaseTools/Commands/NotarizeCommand.swift index a984ef2..b2fe048 100644 --- a/Sources/ReleaseTools/Commands/NotarizeCommand.swift +++ b/Sources/ReleaseTools/Commands/NotarizeCommand.swift @@ -34,10 +34,9 @@ class NotarizeCommand: RTCommand { } shell.log("Creating archive for notarization.") - let exportedAppPath = exportURL.appendingPathComponent(archive.name) let ditto = DittoRunner(shell: shell) - let zipResult = try ditto.zip(exportedAppPath, as: exportedZipURL) + let zipResult = try ditto.zip(exportedAppURL, as: exportedZipURL) if zipResult.status != 0 { return Result.exportFailed.adding(runnerResult: zipResult) } diff --git a/Sources/ReleaseTools/Commands/UploadCommand.swift b/Sources/ReleaseTools/Commands/UploadCommand.swift new file mode 100644 index 0000000..e7c34b6 --- /dev/null +++ b/Sources/ReleaseTools/Commands/UploadCommand.swift @@ -0,0 +1,54 @@ +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +// Created by Sam Deane on 25/02/20. +// All code (c) 2020 - present day, Elegant Chaos Limited. +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +import Foundation +import CommandShell +import Runner + +extension Result { + static let uploadingFailed = Result(620, "Uploading failed.") + static let savingUploadReceiptFailed = Result(621, "Saving upload receipt failed.") +} + +class UploadCommand: RTCommand { + + override var description: Command.Description { + return Description( + name: "upload", + help: "Upload the archived app to Apple Connect portal for processing.", + usage: ["[\(userOption) [\(setDefaultOption)]] [\(platformOption)]"], + options: [ + platformOption: platformOptionHelp, + userOption: userOptionHelp, + setDefaultOption: setDefaultOptionHelp + ], + returns: [.uploadingFailed, .savingUploadReceiptFailed] + ) + } + + override func run(shell: Shell) throws -> Result { + + let gotRequirements = require([.workspace, .user, .archive, .scheme]) + guard gotRequirements == .ok else { + return gotRequirements + } + + shell.log("Uploading archive to Apple Connect.") + let xcrun = XCRunRunner(shell: shell) + let result = try xcrun.run(arguments: ["altool", "--upload-app", "--username", user, "--password", "@keychain:AC_PASSWORD", "--file", exportedIPAURL.path, "--output-format", "xml"]) + if result.status != 0 { + return Result.uploadingFailed.adding(runnerResult: result) + } + + shell.log("Finished uploading.") + do { + try result.stdout.write(to: uploadingReceiptURL, atomically: true, encoding: .utf8) + } catch { + return Result.savingUploadReceiptFailed.adding(supplementary: "\(error)") + } + + return .ok + } +} diff --git a/Sources/ReleaseTools/RTCommand.swift b/Sources/ReleaseTools/RTCommand.swift index 4568cd8..ea1b8ea 100644 --- a/Sources/ReleaseTools/RTCommand.swift +++ b/Sources/ReleaseTools/RTCommand.swift @@ -51,8 +51,14 @@ class RTCommand: Command { let rootURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) var exportedZipURL: URL { return exportURL.appendingPathComponent("exported.zip") } + + var exportedAppURL: URL { return exportURL.appendingPathComponent(archive.name) } + var exportedIPAURL: URL { return exportURL.appendingPathComponent(scheme).appendingPathExtension("ipa") } + var notarizingReceiptURL: URL { return exportURL.appendingPathComponent("receipt.xml") } + var uploadingReceiptURL: URL { return exportURL.appendingPathComponent("receipt.xml") } + var buildURL: URL { return rootURL.appendingPathComponents([".build", platform]) } diff --git a/Sources/ReleaseTools/main.swift b/Sources/ReleaseTools/main.swift index 07e2093..f1f5a19 100644 --- a/Sources/ReleaseTools/main.swift +++ b/Sources/ReleaseTools/main.swift @@ -22,7 +22,8 @@ let shell = Shell(commands: [ NotarizeCommand(), PublishCommand(), UpdateBuildCommand(), - WaitForNotarizationCommand() + UploadCommand(), + WaitForNotarizationCommand(), ] )