From d5c88c5e5bf583c5c7e3e13b13e25d828ced3d3a Mon Sep 17 00:00:00 2001 From: Decheng Date: Tue, 13 Oct 2020 17:30:23 +1100 Subject: [PATCH] Wire up removing API calls in sync push command --- .../Sync/TestFlightPushCommand.swift | 32 ++++++++++++++++--- .../Services/AppStoreConnectService.swift | 24 ++++++++++++++ .../Operations/RemoveTesterOperation.swift | 3 ++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift index d336c110..0225293b 100644 --- a/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift +++ b/Sources/AppStoreConnectCLI/Commands/TestFlight/Sync/TestFlightPushCommand.swift @@ -20,6 +20,9 @@ struct TestFlightPushCommand: CommonParsableCommand { help: "Path to read in the TestFlight configuration." ) var inputPath: String + @Flag(help: "Perform a dry run.") + var dryRun: Bool + func run() throws { let service = try makeService() @@ -28,11 +31,32 @@ struct TestFlightPushCommand: CommonParsableCommand { let difference = TestFlightProgramDifference(local: local, remote: remote) - difference.changes.forEach { print($0.description) } - - // TODO: Push the testflight program to the API + if dryRun { + difference.changes.forEach { print($0.description) } + } else { + try difference.changes.forEach { + try performChange(change: $0, with: service) + } + } + } - throw CommandError.unimplemented + func performChange(change: TestFlightProgramDifference.Change, with service: AppStoreConnectService) throws { + switch change { + case .removeBetaGroup(let betagroup): + guard let groupId = betagroup.id else { return } + try service.deleteBetaGroup(id: groupId) + print("✅ \(change.description)") + case .removeBetaTesterFromApps(let tester, let apps): + guard let email = tester.email else { return } + try service.removeTesterFromApps(email: email, appIds: apps.map(\.id)) + print("✅ \(change.description)") + case .removeBetaTesterFromGroups(let tester, let groups): + guard let email = tester.email else { return } + try service.removeTesterFromGroups(email: email, groupNames: groups.compactMap(\.groupName)) + print("✅ \(change.description)") + default: + print("❌ \(change.description): this operation has not been implemented") + } } } diff --git a/Sources/AppStoreConnectCLI/Services/AppStoreConnectService.swift b/Sources/AppStoreConnectCLI/Services/AppStoreConnectService.swift index 0ea02a90..1ab40450 100644 --- a/Sources/AppStoreConnectCLI/Services/AppStoreConnectService.swift +++ b/Sources/AppStoreConnectCLI/Services/AppStoreConnectService.swift @@ -419,6 +419,24 @@ class AppStoreConnectService { try operation.execute(with: requestor).await() } + func removeTesterFromApps(email: String, appIds: [String]) throws { + let testerId = try GetBetaTesterOperation( + options: .init(identifier: .email(email)) + ) + .execute(with: requestor) + .await() + .betaTester + .id + + let operation = RemoveTesterOperation( + options: .init( + removeStrategy: .removeTesterFromApps(testerId: testerId, appIds: appIds) + ) + ) + + try operation.execute(with: requestor).await() + } + func readBetaGroup(bundleId: String, groupName: String) throws -> Model.BetaGroup { let app = try ReadAppOperation(options: .init(identifier: .bundleId(bundleId))) .execute(with: requestor) @@ -472,6 +490,12 @@ class AppStoreConnectService { .await() } + func deleteBetaGroup(id: String) throws { + try DeleteBetaGroupOperation(options: .init(betaGroupId: id)) + .execute(with: requestor) + .await() + } + func listBetaGroups( filterIdentifiers: [AppLookupIdentifier] = [], names: [String] = [], diff --git a/Sources/AppStoreConnectCLI/Services/Operations/RemoveTesterOperation.swift b/Sources/AppStoreConnectCLI/Services/Operations/RemoveTesterOperation.swift index 84222210..8cdc579b 100644 --- a/Sources/AppStoreConnectCLI/Services/Operations/RemoveTesterOperation.swift +++ b/Sources/AppStoreConnectCLI/Services/Operations/RemoveTesterOperation.swift @@ -10,6 +10,7 @@ struct RemoveTesterOperation: APIOperation { enum RemoveStrategy { case removeTestersFromGroup(testerIds: [String], groupId: String) case removeTesterFromGroups(testerId: String, groupIds: [String]) + case removeTesterFromApps(testerId: String, appIds: [String]) } let removeStrategy: RemoveStrategy @@ -23,6 +24,8 @@ struct RemoveTesterOperation: APIOperation { return APIEndpoint.remove(betaTesterWithId: testerId, fromBetaGroupsWithIds: groupIds) case .removeTestersFromGroup(let testerIds, let groupId): return APIEndpoint.remove(betaTestersWithIds: testerIds, fromBetaGroupWithId: groupId) + case .removeTesterFromApps(let testerId, let appIds): + return APIEndpoint.remove(accessOfBetaTesterWithId: testerId, toAppsWithIds: appIds) } }