Estuve observando este código aleatorio en GitHub:
https://github.com/HearthSim/HDT-Voice/blob/master/HDT-Voice/HDTPlugin/Github.vb y a raíz de eso se me ocurrió la idea de implementar un sistema reutilizable y sofisticado (o al menos yo creo que lo es) para obtener las releases de GitHub, con lo que poder determinar si existe una nueva release y por ende nuestro programa debe actualizarse...
Para comenzar la implementación de dicho sistema declaré las siguientes clases:
GitHubRelease,
GitHubAsset y
GitHubAuthor las cuales servirán para representar información de una release, un asset y un author/uploader. Y por último declaré una clase con nombre
GitHubUtil en donde declaré varias funciones sincrónicas y asincrónicas para implementar las siguientes funcionalidades: obtener todas las releases de un repositorio, obtener la última release, obtener una release con versión específica, y comprobar si existe una versión más reciente (para actualizar nuestro programa).
Estoy seguro que les servirá para sus aplicaciones de código abierto y le podrán sacar varias utilidades con diferentes fines que se ajusten a sus necesidades...
Aquí lo tienen todo:
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.IO
Imports System.Net
Imports System.Net.Mime
Imports System.Runtime.Serialization.Json
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Web
Imports System.Xml
GitHubRelease.vb''' <summary>
''' Represents a release on GitHub.
''' </summary>
''' <seealso href="https://github.com"/>
Public NotInheritable Class GitHubRelease
''' <summary>
''' Gets the GitHub's unique identifier for this release.
''' </summary>
Public ReadOnly Property Id As String
''' <summary>
''' Gets the release name.
''' </summary>
Public ReadOnly Property Name As String
''' <summary>
''' Gets the release tag name.
''' </summary>
Public ReadOnly Property TagName As String
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Gets the release version.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' The version is derived from <see cref="GitHubRelease.TagName"/>, which should follow semantic versioning guidelines.
''' <para></para>
''' See for more info about semantic versioning:
''' <para></para>
''' <see href="https://semver.org/"/>
''' <para></para>
''' <see href="https://help.github.com/articles/about-releases/"/>
''' <para></para>
''' <see href="https://git-scm.com/book/en/v2/Git-Basics-Tagging"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
Public ReadOnly Property Version As Version
Get
' Remove prefixes and suffixes from tagname, like: "v1.0", "1.0-alpha" or "1.0-beta".
Dim str As String = Me.TagName.ToLower().
Trim("abcdefghijklmnopqrstuvwxyz !·$%&/()=?\|@#~'^*¨;:,.{}[]+".ToArray())
Dim result As Version = Nothing
Version.TryParse(str, result)
Return result
End Get
End Property
''' <summary>
''' Gets the body, in MarkDown format.
''' </summary>
Public ReadOnly Property Body As String
''' <summary>
''' Gets the commition target.
''' </summary>
Public ReadOnly Property TargetCommitish As String
''' <summary>
''' Gets an <see cref="Uri"/> that points to the release page.
''' </summary>
Public ReadOnly Property UriRelease As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the assets page of this release.
''' </summary>
Public ReadOnly Property UriAssets As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the tarball of this release.
''' </summary>
Public ReadOnly Property UriTarball As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the zipball of this release.
''' </summary>
Public ReadOnly Property UriZipball As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the release page for a web-browser.
''' </summary>
Public ReadOnly Property UriHtml As Uri
''' <summary>
''' Gets a value that determine whether this release is a draft.
''' </summary>
Public ReadOnly Property IsDraft As Boolean
''' <summary>
''' Gets a value that determine whether this release is a pre-release.
''' </summary>
Public ReadOnly Property IsPreRelease As Boolean
''' <summary>
''' Gets the creation datetime.
''' </summary>
Public ReadOnly Property DateCreated As Date
''' <summary>
''' Gets the published datetime.
''' </summary>
Public ReadOnly Property DatePublished As Date
''' <summary>
''' Gets the author of this release.
''' </summary>
Public ReadOnly Property Author As GitHubAuthor
''' <summary>
''' Gets the assets of this release.
''' </summary>
Public ReadOnly Property Assets As ReadOnlyCollection(Of GitHubAsset)
''' <summary>
''' Prevents a default instance of the <see cref="GitHubRelease"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="GitHubRelease"/> class.
''' </summary>
''' <param name="xml">
''' An <see cref="XElement"/> that contains the fields to parse.
''' <para></para>
''' See: <see href="https://api.github.com/repos/{user}/{repo}/releases"/>
''' </param>
Public Sub New(ByVal xml As XElement)
Me.Id = xml.<id>.Value
Me.Name = xml.<name>.Value
Me.TagName = xml.<tag_name>.Value
Me.Body = xml.<body>.Value
Me.TargetCommitish = xml.<target_commitish>.Value
Me.UriRelease = New Uri(xml.<url>.Value, UriKind.Absolute)
Me.UriAssets = New Uri(xml.<assets_url>.Value, UriKind.Absolute)
Me.UriHtml = New Uri(xml.<html_url>.Value, UriKind.Absolute)
Me.UriTarball = New Uri(xml.<tarball_url>.Value, UriKind.Absolute)
Me.UriZipball = New Uri(xml.<zipball_url>.Value, UriKind.Absolute)
Me.IsDraft = xml.<draft>.Value
Me.IsPreRelease = xml.<prerelease>.Value
Me.DateCreated = Date.Parse(xml.<created_at>.Value, CultureInfo.GetCultureInfo("en-US").DateTimeFormat)
Me.DatePublished = Date.Parse(xml.<published_at>.Value, CultureInfo.GetCultureInfo("en-US").DateTimeFormat)
Me.Author = New GitHubAuthor(xml.<author>.SingleOrDefault())
Dim elements As IEnumerable(Of XElement) = xml.<assets>.<item>
For Each element As XElement In elements
Dim asset As New GitHubAsset(element)
assets.Add(asset)
Next
Me.Assets = New ReadOnlyCollection(Of GitHubAsset)(assets)
End Sub
''' <summary>
''' Returns a <see cref="String"/> that represents this release.
''' </summary>
''' <returns>
''' A <see cref="String"/> that represents this release.
''' </returns>
Public Overrides Function ToString() As String
Dim kvPairs As New NameValueCollection(EqualityComparer(Of String).Default) From {
{NameOf(Me.Id), Me.Id},
{NameOf(Me.TagName), Me.TagName},
{NameOf(Me.Name), Me.Name},
{NameOf(Me.TargetCommitish), Me.TargetCommitish},
{NameOf(Me.IsDraft), Me.IsDraft},
{NameOf(Me.IsPreRelease), Me.IsPreRelease},
{NameOf(Me.DateCreated), Me.DateCreated.ToString("MM/dd/yyyy HH:mm:ss")},
{NameOf(Me.DatePublished), Me.DatePublished.ToString("MM/dd/yyyy HH:mm:ss")},
{NameOf(Me.UriHtml), Me.UriHtml.AbsoluteUri}
}
Return String.Format("{{{0}}}", String.Join(", ", (From key In kvPairs.AllKeys, value In kvPairs.GetValues(key)
Select String.Format("{0}={1}", key, value))))
End Function
''' <summary>
''' Implements the operator <>.
''' </summary>
''' <param name="release1">
''' The first <see cref="GitHubRelease"/>.
''' </param>
''' <param name="release2">
''' The second <see cref="GitHubRelease"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator <>(ByVal release1 As GitHubRelease, ByVal release2 As GitHubRelease) As Boolean
Return (release1.Id <> release2.Id)
End Operator
''' <summary>
''' Implements the operator =.
''' </summary>
''' <param name="release1">
''' The first <see cref="GitHubRelease"/>.
''' </param>
''' <param name="release2">
''' The second <see cref="GitHubRelease"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator =(ByVal release1 As GitHubRelease, ByVal release2 As GitHubRelease) As Boolean
Return (release1.Id = release2.Id)
End Operator
End Class
GitHubAsset.vb''' <summary>
''' Represents an asset of a release on GitHub.
''' </summary>
''' <seealso href="https://github.com"/>
Public NotInheritable Class GitHubAsset
''' <summary>
''' Gets the GitHub's unique identifier for this asset.
''' </summary>
Public ReadOnly Property Id As String
''' <summary>
''' Gets the name of this asset.
''' </summary>
Public ReadOnly Property Name As String
''' <summary>
''' Gets the label of this asset.
''' </summary>
Public ReadOnly Property Label As String
''' <summary>
''' Gets the state of this asset.
''' </summary>
Public ReadOnly Property State As String
''' <summary>
''' Gets the size of this asset, in bytes.
''' </summary>
Public ReadOnly Property Size As Long
''' <summary>
''' Gets a value indicating how many times this asset was downloaded.
''' </summary>
Public ReadOnly Property DownloadCount As Integer
''' <summary>
''' Gets the content-type of this asset.
''' </summary>
Public ReadOnly Property ContentType As ContentType
''' <summary>
''' Gets an <see cref="Uri"/> that points to the page of this asset.
''' </summary>
Public ReadOnly Property UriAsset As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the download page of this asset.
''' </summary>
Public ReadOnly Property UriDownload As Uri
''' <summary>
''' Gets the creation datetime.
''' </summary>
Public ReadOnly Property DateCreated As Date
''' <summary>
''' Gets the uploaded datetime.
''' </summary>
Public ReadOnly Property DateUploaded As Date
''' <summary>
''' Gets the uploader of this asset.
''' </summary>
Public ReadOnly Property Uploader As GitHubAuthor
''' <summary>
''' Prevents a default instance of the <see cref="GitHubAsset"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="GitHubAsset"/> class.
''' </summary>
''' <param name="xml">
''' An <see cref="XElement"/> that contains the fields to parse.
''' <para></para>
''' See: <see href="https://api.github.com/repos/{user}/{repo}/releases"/>
''' </param>
Public Sub New(ByVal xml As XElement)
Me.Id = xml.<id>.Value
Me.Name = xml.<name>.Value
Me.Label = xml.<label>.Value
Me.State = xml.<state>.Value
Me.Size = xml.<size>.Value
Me.ContentType = New ContentType(xml.<content_type>.Value)
Me.DownloadCount = xml.<download_count>.Value
Me.DateCreated = Date.Parse(xml.<created_at>.Value, CultureInfo.GetCultureInfo("en-US").DateTimeFormat)
Me.DateUploaded = Date.Parse(xml.<updated_at>.Value, CultureInfo.GetCultureInfo("en-US").DateTimeFormat)
Me.UriAsset = New Uri(xml.<url>.Value, UriKind.Absolute)
Me.UriDownload = New Uri(xml.<browser_download_url>.Value, UriKind.Absolute)
Me.Uploader = New GitHubAuthor(xml.<uploader>.Single())
End Sub
''' <summary>
''' Returns a <see cref="String"/> that represents this asset.
''' </summary>
''' <returns>
''' A <see cref="String"/> that represents this asset.
''' </returns>
Public Overrides Function ToString() As String
Dim kvPairs As New NameValueCollection(EqualityComparer(Of String).Default) From {
{NameOf(Me.Id), Me.Id},
{NameOf(Me.Name), Me.Name},
{NameOf(Me.Label), Me.Label},
{NameOf(Me.State), Me.State},
{NameOf(Me.Size), Me.Size},
{NameOf(Me.ContentType), Me.ContentType.ToString()},
{NameOf(Me.DownloadCount), Me.DownloadCount},
{NameOf(Me.DateCreated), Me.DateCreated.ToString("MM/dd/yyyy HH:mm:ss")},
{NameOf(Me.DateUploaded), Me.DateUploaded.ToString("MM/dd/yyyy HH:mm:ss")},
{NameOf(Me.UriDownload), Me.UriDownload.AbsoluteUri}
}
Return String.Format("{{{0}}}", String.Join(", ", (From key In kvPairs.AllKeys, value In kvPairs.GetValues(key)
Select String.Format("{0}={1}", key, value))))
End Function
''' <summary>
''' Implements the operator <>.
''' </summary>
''' <param name="asset1">
''' The first <see cref="GitHubAsset"/>.
''' </param>
''' <param name="asset2">
''' The second <see cref="GitHubAsset"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator <>(ByVal asset1 As GitHubAsset, ByVal asset2 As GitHubAsset) As Boolean
Return (asset1.Id <> asset2.Id)
End Operator
''' <summary>
''' Implements the operator =.
''' </summary>
''' <param name="asset1">
''' The first <see cref="GitHubAsset"/>.
''' </param>
''' <param name="asset2">
''' The second <see cref="GitHubAsset"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator =(ByVal asset1 As GitHubAsset, ByVal asset2 As GitHubAsset) As Boolean
Return (asset1.Id = asset2.Id)
End Operator
End Class
GitHubAuthor.vb''' <summary>
''' Represents the author of a release or the uploader of an asset on GitHub.
''' </summary>
''' <seealso href="https://github.com"/>
Public NotInheritable Class GitHubAuthor
''' <summary>
''' Gets the GitHub's unique identifier for this author.
''' </summary>
Public ReadOnly Property Id As String
''' <summary>
''' Gets the author name.
''' </summary>
Public ReadOnly Property Name As String
''' <summary>
''' Gets the type of user.
''' </summary>
Public ReadOnly Property [Type] As String
''' <summary>
''' Gets a value that determine whether this author is a site administrator.
''' </summary>
Public ReadOnly Property IsSiteAdministrator As Boolean
''' <summary>
''' Gets the unique identifier of the Gravatar.
''' <para></para>
''' See for more info: <see href="https://gravatar.com/"/>
''' </summary>
Public ReadOnly Property GravatarId As String
''' <summary>
''' Gets an <see cref="Uri"/> that points to the author page.
''' </summary>
Public ReadOnly Property UriAuthor As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the avatar page of this author.
''' </summary>
Public ReadOnly Property UriAvatar As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the followers page of this author.
''' </summary>
Public ReadOnly Property UriFollowers As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the subscriptions page of this author.
''' </summary>
Public ReadOnly Property UriSubscriptions As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the organizations page of this author.
''' </summary>
Public ReadOnly Property UriOrganizations As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the repositories page of this author.
''' </summary>
Public ReadOnly Property UriRepositories As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the received events page of this author.
''' </summary>
Public ReadOnly Property UriReceivedEvents As Uri
''' <summary>
''' Gets an <see cref="Uri"/> that points to the author page for a web-browser.
''' </summary>
Public ReadOnly Property UriHtml As Uri
''' <summary>
''' Prevents a default instance of the <see cref="GitHubAuthor"/> class from being created.
''' </summary>
Private Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="GitHubAuthor"/> class.
''' </summary>
''' <param name="xml">
''' An <see cref="XElement"/> that contains the fields to parse.
''' <para></para>
''' See: <see href="https://api.github.com/repos/{user}/{repo}/releases"/>
''' </param>
Public Sub New(ByVal xml As XElement)
Me.Id = xml.<id>.Value
Me.Name = xml.<login>.Value
Me.Type = xml.<type>.Value
Me.IsSiteAdministrator = xml.<site_admin>.Value
Me.GravatarId = xml.<gravatar_id>.Value
Me.UriAuthor = New Uri(xml.<url>.Value, UriKind.Absolute)
Me.UriAvatar = New Uri(xml.<avatar_url>.Value, UriKind.Absolute)
Me.UriSubscriptions = New Uri(xml.<subscriptions_url>.Value, UriKind.Absolute)
Me.UriOrganizations = New Uri(xml.<organizations_url>.Value, UriKind.Absolute)
Me.UriRepositories = New Uri(xml.<repos_url>.Value, UriKind.Absolute)
Me.UriReceivedEvents = New Uri(xml.<received_events_url>.Value, UriKind.Absolute)
Me.UriHtml = New Uri(xml.<html_url>.Value, UriKind.Absolute)
End Sub
''' <summary>
''' Returns a <see cref="String"/> that represents this author.
''' </summary>
''' <returns>
''' A <see cref="String"/> that represents this author.
''' </returns>
Public Overrides Function ToString() As String
Dim kvPairs As New NameValueCollection(EqualityComparer(Of String).Default) From {
{NameOf(Me.Id), Me.Id},
{NameOf(Me.Name), Me.Name},
{NameOf(Me.Type), Me.Type},
{NameOf(Me.IsSiteAdministrator), Me.IsSiteAdministrator},
{NameOf(Me.UriHtml), Me.UriHtml.AbsoluteUri}
}
Return String.Format("{{{0}}}", String.Join(", ", (From key In kvPairs.AllKeys, value In kvPairs.GetValues(key)
Select String.Format("{0}={1}", key, value))))
End Function
''' <summary>
''' Implements the operator <>.
''' </summary>
''' <param name="author1">
''' The first <see cref="GitHubAuthor"/>.
''' </param>
''' <param name="author2">
''' The second <see cref="GitHubAuthor"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator <>(ByVal author1 As GitHubAuthor, ByVal author2 As GitHubAuthor) As Boolean
Return (author1.Id <> author2.Id)
End Operator
''' <summary>
''' Implements the operator =.
''' </summary>
''' <param name="author1">
''' The first <see cref="GitHubAuthor"/>.
''' </param>
''' <param name="author2">
''' The second <see cref="GitHubAuthor"/>.
''' </param>
''' <returns>
''' The result of the operator.
''' </returns>
Public Shared Operator =(ByVal author1 As GitHubAuthor, ByVal author2 As GitHubAuthor) As Boolean
Return (author1.Id = author2.Id)
End Operator
End Class
GitHubUtil.vbPublic NotInheritable Class GitHubUtil
#Region " Constructors "
''' <summary>
''' Prevents a default instance of the <see cref="GitHubUtil"/> class from being created.
''' </summary>
Private Sub New()
End Sub
#End Region
#Region " Public Methods "
''' <summary>
''' Asynchronously gets the releases from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <returns>
''' A <see cref="Task(Of ReadOnlyCollection(Of GitHubRelease))"/> containing the releases.
''' </returns>
''' <exception cref="HttpException">
''' JSON validation error.
''' </exception>
Public Shared Async Function GetReleasesAsync(ByVal userName As String, ByVal repositoryName As String) As Task(Of ReadOnlyCollection(Of GitHubRelease))
Dim uri As New Uri(String.Format("https://api.github.com/repos/{0}/{1}/releases", userName, repositoryName), UriKind.Absolute)
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest)
request.UserAgent = userName
Using response As WebResponse = Await request.GetResponseAsync(),
sr As New StreamReader(response.GetResponseStream()),
xmlReader As XmlDictionaryReader = JsonReaderWriterFactory.CreateJsonReader(sr.BaseStream, Encoding.UTF8, New XmlDictionaryReaderQuotas, Nothing)
Dim xml As XElement = XElement.Load(xmlReader)
If (xml.IsEmpty) Then
Dim errMsg As String = String.Format("JSON validation error. ""{0}""", uri.ToString())
Throw New HttpException(HttpStatusCode.NotFound, errMsg)
End If
Dim elements As IEnumerable(Of XElement) = xml.<item>
For Each element As XElement In elements
Dim release As New GitHubRelease(element)
releases.Add(release)
Next
Return New ReadOnlyCollection(Of GitHubRelease)(releases)
End Using
End Function
''' <summary>
''' Gets the releases from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <returns>
''' A <see cref="ReadOnlyCollection(Of GitHubRelease)"/> collection containing the releases.
''' </returns>
Public Shared Function GetReleases(ByVal userName As String, ByVal repositoryName As String) As ReadOnlyCollection(Of GitHubRelease)
Dim t As Task(Of ReadOnlyCollection(Of GitHubRelease)) = Task.Run(Function() GitHubUtil.GetReleases(userName, repositoryName))
t.Wait(Timeout.Infinite)
Return t.Result
End Function
''' <summary>
''' Asynchronously gets a release that matches the specified version from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <param name="version">
''' The version of the release.
''' </param>
''' <returns>
''' The resulting <see cref="GitHubRelease"/>.
''' </returns>
Public Shared Async Function GetReleaseAsync(ByVal userName As String, ByVal repositoryName As String, ByVal version As Version) As Task(Of GitHubRelease)
Return (From release As GitHubRelease In Await GetReleasesAsync(userName, repositoryName)
Where release.Version = version).
DefaultIfEmpty(Nothing).
SingleOrDefault()
End Function
''' <summary>
''' Gets a release that matches the specified version from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <param name="version">
''' The version of the release.
''' </param>
''' <returns>
''' The resulting <see cref="GitHubRelease"/>.
''' </returns>
Public Shared Function GetRelease(ByVal userName As String, ByVal repositoryName As String, ByVal version As Version) As GitHubRelease
Dim t As Task(Of GitHubRelease) = Task.Run(Function() GitHubUtil.GetRelease(userName, repositoryName, version))
t.Wait(Timeout.Infinite)
Return t.Result
End Function
''' <summary>
''' Asynchronously gets the latest release from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <returns>
''' The resulting <see cref="GitHubRelease"/>.
''' </returns>
''' <exception cref="HttpException">
''' JSON validation error.
''' </exception>
Public Shared Async Function GetLatestReleaseAsync(ByVal userName As String, ByVal repositoryName As String) As Task(Of GitHubRelease)
Dim uri As New Uri(String.Format("https://api.github.com/repos/{0}/{1}/releases/latest", userName, repositoryName), UriKind.Absolute)
Dim request As HttpWebRequest = WebRequest.Create(uri)
request.UserAgent = userName
Using response As WebResponse = Await request.GetResponseAsync(),
sr As New StreamReader(response.GetResponseStream()),
xmlReader As XmlDictionaryReader = JsonReaderWriterFactory.CreateJsonReader(sr.BaseStream, Encoding.UTF8, New XmlDictionaryReaderQuotas, Nothing)
Dim xml As XElement = XElement.Load(xmlReader)
If (xml.IsEmpty) Then
Dim errMsg As String = String.Format("JSON validation error. ""{0}""", uri.ToString())
Throw New HttpException(HttpStatusCode.NotFound, errMsg)
End If
Return New GitHubRelease(xml)
End Using
End Function
''' <summary>
''' Gets the latest release from the specified repository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <returns>
''' The resulting <see cref="GitHubRelease"/>.
''' </returns>
Public Shared Function GetLatestRelease(ByVal userName As String, ByVal repositoryName As String) As GitHubRelease
Dim t As Task(Of GitHubRelease) = Task.Run(Function() GitHubUtil.GetLatestReleaseAsync(userName, repositoryName))
t.Wait(Timeout.Infinite)
Return t.Result
End Function
''' <summary>
''' Asynchronously gets a value that determine whether exists a new version available of the specified reository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <param name="currentVersion">
''' The current version.
''' </param>
''' <returns>
''' <see langword="True"/> if exists a new version available on GitHub; otherwise, <see langword="False"/>.
''' </returns>
Public Shared Async Function IsUpdateAvailableAsync(ByVal userName As String, ByVal repositoryName As String, ByVal currentVersion As Version) As Task(Of Boolean)
Dim latestRelease As GitHubRelease = Await GitHubUtil.GetLatestReleaseAsync(userName, repositoryName)
Return (latestRelease.Version > currentVersion)
End Function
''' <summary>
''' Gets a value that determine whether exists a new version available of the specified reository on GitHub.
''' </summary>
''' <param name="userName">
''' The user name.
''' </param>
''' <param name="repositoryName">
''' The repository name.
''' </param>
''' <param name="currentVersion">
''' The current version.
''' </param>
''' <returns>
''' <see langword="True"/> if exists a new version available on GitHub; otherwise, <see langword="False"/>.
''' </returns>
Public Shared Function IsUpdateAvailable(ByVal userName As String, ByVal repositoryName As String, ByVal currentVersion As Version) As Boolean
Dim t As Task(Of Boolean) = Task.Run(Function() GitHubUtil.IsUpdateAvailableAsync(userName, repositoryName, currentVersion))
t.Wait(Timeout.Infinite)
Return t.Result
End Function
#End Region
End Class