Ed's Site
Home
Septa
Stocks
Weather
Code
Code Example
Imports System Imports System.IO Imports System.Net Imports System.Security.Cryptography Imports System.IdentityModel.Tokens.Jwt Imports Microsoft.IdentityModel.Tokens Imports Org.BouncyCastle.OpenSsl Imports Org.BouncyCastle.Crypto.Parameters Imports Org.BouncyCastle.Security Module Program '=== YOUR APP CONFIGURATION === Const AppId As String = "2203300" ' GitHub App ID (numeric) Const InstallationId As String = "92200261" ' Installation ID Const PemFileName As String = "myworksandbox.2025-10-29.private-key.pem" ' PEM file in output folder Sub Main() Try Console.WriteLine("Checking if tag exists...") Dim owner As String = "your-owner-here" ' e.g. "elync" Dim repo As String = "your-repo-here" ' e.g. "GitHubAppTest" Dim tagName As String = "v1.0.0" ' e.g. "v1.0.0" Dim exists As Boolean = TagExists(owner, repo, tagName) Console.WriteLine($"Tag '{tagName}' exists on {owner}/{repo}: {exists}") Catch ex As Exception Console.WriteLine("ERROR: " & ex.Message) End Try Console.WriteLine(vbCrLf & "Done. Press any key to exit.") Console.ReadKey() End Sub '===================== ' MAIN FUNCTION '===================== Public Function TagExists(owner As String, repo As String, tagName As String) As Boolean Dim token As String = GetInstallationToken() Dim url As String = $"https://api.github.com/repos/{owner}/{repo}/git/ref/tags/{tagName}" Dim request = CType(WebRequest.Create(url), HttpWebRequest) request.Method = "GET" request.UserAgent = "GitHubAppTest" request.Headers.Add("Authorization", "Bearer " & token) request.Accept = "application/vnd.github+json" Try Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse) If response.StatusCode = HttpStatusCode.OK Then Return True End If End Using Catch ex As WebException If ex.Response IsNot Nothing Then Dim httpResp = CType(ex.Response, HttpWebResponse) If httpResp.StatusCode = HttpStatusCode.NotFound Then Return False ' Tag does not exist ElseIf httpResp.StatusCode = HttpStatusCode.Unauthorized Then Throw New Exception("Unauthorized. Check token permissions or app installation.") End If End If Throw End Try Return False End Function '===================== ' INSTALLATION TOKEN '===================== Private Function GetInstallationToken() As String Dim pem As String = File.ReadAllText(PemFileName) Using rsa As RSA = LoadRsaFromPem(pem) Dim jwt As String = GenerateJwt(AppId, rsa) Dim url As String = $"https://api.github.com/app/installations/{InstallationId}/access_tokens" Dim request = CType(WebRequest.Create(url), HttpWebRequest) request.Method = "POST" request.UserAgent = "GitHubAppTest" request.Headers.Add("Authorization", "Bearer " & jwt) request.Accept = "application/vnd.github+json" Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse) Using reader As New StreamReader(response.GetResponseStream()) Dim json = reader.ReadToEnd() Dim token = Newtonsoft.Json.Linq.JObject.Parse(json)("token")?.ToString() If token Is Nothing Then Throw New Exception("Could not retrieve installation token.") Return token End Using End Using End Using End Function '===================== ' JWT GENERATOR '===================== Private Function GenerateJwt(appId As String, rsa As RSA) As String Dim securityKey As New RsaSecurityKey(rsa) Dim credentials As New SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256) Dim handler As New JwtSecurityTokenHandler() Dim now = DateTimeOffset.UtcNow Dim claims = New List(Of System.Security.Claims.Claim) From { New System.Security.Claims.Claim(JwtRegisteredClaimNames.Iat, now.ToUnixTimeSeconds().ToString(), System.Security.Claims.ClaimValueTypes.Integer64) } Dim token As New JwtSecurityToken( issuer:=appId, audience:=Nothing, claims:=claims, notBefore:=now.UtcDateTime, expires:=now.AddMinutes(9).UtcDateTime, signingCredentials:=credentials ) Return handler.WriteToken(token) End Function '===================== ' PEM PARSING '===================== Private Function LoadRsaFromPem(pem As String) As RSA Using reader As New StringReader(pem) Dim pemReader As New PemReader(reader) Dim keyObject = pemReader.ReadObject() If TypeOf keyObject Is Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair Then Dim privateKeyParams = CType(keyObject, Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair).Private Return CreateRsa(CType(privateKeyParams, RsaPrivateCrtKeyParameters)) ElseIf TypeOf keyObject Is RsaPrivateCrtKeyParameters Then Return CreateRsa(CType(keyObject, RsaPrivateCrtKeyParameters)) Else Throw New Exception("Unsupported PEM format.") End If End Using End Function Private Function CreateRsa(privateKey As RsaPrivateCrtKeyParameters) As RSA Dim rsaParams As RSAParameters = DotNetUtilities.ToRSAParameters(privateKey) Dim rsa As RSA = RSA.Create() rsa.ImportParameters(rsaParams) Return rsa End Function End Module