From b107d29d6f6d4548eb5ebb3162c9af83f07e3ec7 Mon Sep 17 00:00:00 2001 From: Honza Dvorsky Date: Mon, 4 May 2015 13:29:48 +0100 Subject: [PATCH] added support for cross-fork pull requests --- Buildasaur/HDGitHubXCBotSyncer.swift | 24 +++++++++++++++++++++-- Buildasaur/LocalSource.swift | 29 ++++++++++++++++++++++++++-- Buildasaur/XcodeLocalSource.swift | 3 +-- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/Buildasaur/HDGitHubXCBotSyncer.swift b/Buildasaur/HDGitHubXCBotSyncer.swift index e66868a..b00f4f2 100644 --- a/Buildasaur/HDGitHubXCBotSyncer.swift +++ b/Buildasaur/HDGitHubXCBotSyncer.swift @@ -761,11 +761,31 @@ public class HDGitHubXCBotSyncer : Syncer { let schedule = BotSchedule.manualBotSchedule() let botName = self.nameForBotWithPR(pr, repoName: self.repoName()!) let template = self.currentBuildTemplate() - let project = self.localSource + + //to handle forks + let headOriginUrl = pr.head.repo.repoUrlSSH + let localProjectOriginUrl = self.localSource.projectURL!.absoluteString + + let project: LocalSource + if headOriginUrl != localProjectOriginUrl { + + //we have a fork, duplicate the metadata with the fork's origin + if let source = self.localSource.duplicateForForkAtOriginURL(headOriginUrl) { + project = source + } else { + self.notifyError(Errors.errorWithInfo("Couldn't create a LocalSource for fork with origin at url \(headOriginUrl)"), context: "Creating a bot from a PR") + completion() + return + } + } else { + //a normal PR in the same repo, no need to duplicate, just use the existing localSource + project = self.localSource + } + let xcodeServer = self.xcodeServer let branch = pr.head.ref - XcodeServerSyncerUtils.createBotFromBuildTemplate(botName, template: template, project: self.localSource, branch: branch, scheduleOverride: schedule, xcodeServer: xcodeServer) { (bot, error) -> () in + XcodeServerSyncerUtils.createBotFromBuildTemplate(botName, template: template, project: project, branch: branch, scheduleOverride: schedule, xcodeServer: xcodeServer) { (bot, error) -> () in if error != nil { self.notifyError(error, context: "Failed to create bot with name \(botName)") diff --git a/Buildasaur/LocalSource.swift b/Buildasaur/LocalSource.swift index 1b2e719..b367af3 100644 --- a/Buildasaur/LocalSource.swift +++ b/Buildasaur/LocalSource.swift @@ -34,7 +34,8 @@ public class LocalSource : JSONSerializable { var availabilityState: AvailabilityCheckState private(set) var workspaceMetadata: NSDictionary? - + let forkOriginURL: String? + //convenience getters var projectName: String? { get { return self.pullValueForKey("IDESourceControlProjectName") }} var projectPath: String? { get { return self.pullValueForKey("IDESourceControlProjectPath") }} @@ -61,7 +62,8 @@ public class LocalSource : JSONSerializable { get { if let urlString = self.pullValueForKey("IDESourceControlProjectURL") { - var finalUrlString = urlString + //if we have a fork, chose its URL, otherwise fallback to the loaded URL from the Checkout file + var finalUrlString = self.forkOriginURL ?? urlString let type = self.checkoutType! if type == .SSH { if !finalUrlString.hasPrefix("git@") { @@ -91,6 +93,8 @@ public class LocalSource : JSONSerializable { } init?(url: NSURL) { + + self.forkOriginURL = nil self.url = url self.preferredTemplateId = nil self.githubToken = nil @@ -103,6 +107,26 @@ public class LocalSource : JSONSerializable { } } + private init?(original: LocalSource, forkOriginURL: String) { + + self.forkOriginURL = forkOriginURL + self.url = original.url + self.preferredTemplateId = original.preferredTemplateId + self.githubToken = original.githubToken + self.availabilityState = original.availabilityState + self.publicSSHKeyUrl = original.publicSSHKeyUrl + self.privateSSHKeyUrl = original.privateSSHKeyUrl + let (parsed, error) = self.refreshMetadata() + if !parsed { + return nil + } + } + + public func duplicateForForkAtOriginURL(forkURL: String) -> LocalSource? { + + return LocalSource(original: self, forkOriginURL: forkURL) + } + public class func attemptToParseFromUrl(url: NSURL) -> (Bool, NSDictionary?, NSError?) { let (meta, error) = LocalSource.loadWorkspaceMetadata(url) @@ -167,6 +191,7 @@ public class LocalSource : JSONSerializable { public required init?(json: NSDictionary) { + self.forkOriginURL = nil self.availabilityState = .Unchecked if diff --git a/Buildasaur/XcodeLocalSource.swift b/Buildasaur/XcodeLocalSource.swift index 64f72c9..ce4f744 100644 --- a/Buildasaur/XcodeLocalSource.swift +++ b/Buildasaur/XcodeLocalSource.swift @@ -16,8 +16,7 @@ extension LocalSource { let projectWCCIdentifier = self.projectWCCIdentifier! let wccName = self.projectWCCName! let projectName = self.projectName! - let projectURLOrig = self.projectURL! - let projectURL = projectURLOrig.absoluteString! + let projectURL = self.projectURL!.absoluteString! let projectPath = self.projectPath! let publicSSHKey = self.publicSSHKey let privateSSHKey = self.privateSSHKey