diff --git a/src/Squirrel/Squirrel.csproj b/src/Squirrel/Squirrel.csproj
index fc441c529..614396960 100644
--- a/src/Squirrel/Squirrel.csproj
+++ b/src/Squirrel/Squirrel.csproj
@@ -78,6 +78,8 @@
+
+
@@ -106,6 +108,7 @@
+
diff --git a/src/Squirrel/UpdateManager.Factory.cs b/src/Squirrel/UpdateManager.Factory.cs
new file mode 100644
index 000000000..41e96aa3c
--- /dev/null
+++ b/src/Squirrel/UpdateManager.Factory.cs
@@ -0,0 +1,65 @@
+using Splat;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Formatting;
+using System.Net.Http.Headers;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Squirrel
+{
+ public sealed partial class UpdateManager
+ {
+ const string gitHubUrl = "https://api.github.com";
+
+ [DataContract]
+ public class Release
+ {
+ [DataMember(Name = "prerelease")]
+ public bool Prerelease { get; set; }
+
+ [DataMember(Name = "published_at")]
+ public DateTime PublishedAt { get; set; }
+
+ [DataMember(Name = "html_url")]
+ public string HtmlUrl { get; set; }
+ }
+
+ public static async Task GitHubUpdateManager(
+ string repoUrl,
+ string applicationName = null,
+ string rootDirectory = null,
+ IFileDownloader urlDownloader = null,
+ bool prerelease = false)
+ {
+ var repoUri = new Uri(repoUrl);
+ var userAgent = new ProductInfoHeaderValue("Squirrel", Assembly.GetExecutingAssembly().GetName().Version.ToString());
+
+ if (repoUri.Segments.Count() != 3)
+ {
+ throw new Exception("Repo URL must be to the root URL of the repo e.g. https://github.com/myuser/myrepo");
+ }
+
+ using (var client = new HttpClient() { BaseAddress = new Uri(gitHubUrl) })
+ {
+ client.DefaultRequestHeaders.UserAgent.Add(userAgent);
+ var response = await client.GetAsync(String.Format("/repos{0}/releases", repoUri.PathAndQuery));
+ response.EnsureSuccessStatusCode();
+
+ var releases = await response.Content.ReadAsAsync>();
+ var latestRelease = releases
+ .Where(x => prerelease ? x.Prerelease : !x.Prerelease)
+ .OrderByDescending(x => x.PublishedAt)
+ .First();
+
+ var latestReleaseUrl = latestRelease.HtmlUrl.Replace("/tag/", "/download/");
+
+ return new UpdateManager(latestReleaseUrl, applicationName, rootDirectory, urlDownloader);
+ }
+ }
+ }
+}
\ No newline at end of file