mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add support for Gitea (#134)
* Add NuGet package * Add Gitea support * Add OS option * Add Gitea test Add test for release check --------- Co-authored-by: Caelan Sayler <git@caesay.com>
This commit is contained in:
188
src/Velopack.Deployment/GiteaRepository.cs
Normal file
188
src/Velopack.Deployment/GiteaRepository.cs
Normal file
@@ -0,0 +1,188 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Gitea.Net.Api;
|
||||
using Gitea.Net.Client;
|
||||
using Gitea.Net.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Velopack.NuGet;
|
||||
using Velopack.Packaging;
|
||||
using Velopack.Packaging.Exceptions;
|
||||
using Velopack.Sources;
|
||||
|
||||
namespace Velopack.Deployment;
|
||||
|
||||
public class GiteaDownloadOptions : RepositoryOptions
|
||||
{
|
||||
public bool Prerelease { get; set; }
|
||||
|
||||
public string RepoUrl { get; set; }
|
||||
|
||||
public string Token { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// Example https://gitea.com
|
||||
///// </summary>
|
||||
//public string ServerUrl { get; set; }
|
||||
|
||||
//public int ServerPort { get; set; }
|
||||
}
|
||||
|
||||
public class GiteaUploadOptions : GiteaDownloadOptions
|
||||
{
|
||||
public bool Publish { get; set; }
|
||||
|
||||
public string ReleaseName { get; set; }
|
||||
|
||||
public string TagName { get; set; }
|
||||
|
||||
public string TargetCommitish { get; set; }
|
||||
|
||||
public bool Merge { get; set; }
|
||||
}
|
||||
public class GiteaRepository : SourceRepository<GiteaDownloadOptions, GiteaSource>, IRepositoryCanUpload<GiteaUploadOptions>
|
||||
{
|
||||
public GiteaRepository(ILogger logger) : base(logger)
|
||||
{
|
||||
}
|
||||
public override GiteaSource CreateSource(GiteaDownloadOptions options)
|
||||
{
|
||||
return new GiteaSource(options.RepoUrl, options.Token, options.Prerelease);
|
||||
}
|
||||
|
||||
public static (string owner, string repo) GetOwnerAndRepo(string repoUrl)
|
||||
{
|
||||
var repoUri = new Uri(repoUrl);
|
||||
var repoParts = repoUri.AbsolutePath.Trim('/').Split('/');
|
||||
if (repoParts.Length != 2)
|
||||
throw new Exception($"Invalid Gitea URL, '{repoUri.AbsolutePath}' should be in the format 'owner/repo'");
|
||||
|
||||
var repoOwner = repoParts[0];
|
||||
var repoName = repoParts[1];
|
||||
return (repoOwner, repoName);
|
||||
}
|
||||
|
||||
public async Task UploadMissingAssetsAsync(GiteaUploadOptions options)
|
||||
{
|
||||
var (repoOwner, repoName) = GetOwnerAndRepo(options.RepoUrl);
|
||||
var helper = new ReleaseEntryHelper(options.ReleaseDir.FullName, options.Channel, Log, options.TargetOs);
|
||||
var build = BuildAssets.Read(options.ReleaseDir.FullName, options.Channel);
|
||||
var latest = helper.GetLatestFullRelease();
|
||||
var latestPath = Path.Combine(options.ReleaseDir.FullName, latest.FileName);
|
||||
var releaseNotes = new ZipPackage(latestPath).ReleaseNotes;
|
||||
var semVer = options.TagName ?? latest.Version.ToString();
|
||||
var releaseName = string.IsNullOrWhiteSpace(options.ReleaseName) ? semVer.ToString() : options.ReleaseName;
|
||||
|
||||
// Setup Gitea config
|
||||
Configuration config = new Configuration();
|
||||
// Example: http://www.Gitea.com/api/v1
|
||||
var uri = new Uri(options.RepoUrl);
|
||||
var baseUri = uri.GetLeftPart(System.UriPartial.Authority);
|
||||
config.BasePath = baseUri + "/api/v1";
|
||||
|
||||
Log.Info($"Preparing to upload {build.Files.Count} asset(s) to Gitea");
|
||||
|
||||
// Set token if provided
|
||||
if (!string.IsNullOrWhiteSpace(options.Token)) {
|
||||
config.ApiKey.Add("token", options.Token);
|
||||
}
|
||||
var apiInstance = new RepositoryApi(config);
|
||||
// Get all releases
|
||||
// Get repository info for total releases
|
||||
List<Release> existingReleases = null;
|
||||
ApiResponse<Repository> repositoryInfo = await apiInstance.RepoGetWithHttpInfoAsync(repoOwner, repoName);
|
||||
if (repositoryInfo != null && repositoryInfo.StatusCode == HttpStatusCode.OK) {
|
||||
// Get all releases
|
||||
var allReleases = await apiInstance.RepoListReleasesWithHttpInfoAsync(repoOwner, repoName, page: 1, limit: (int) repositoryInfo.Data.ReleaseCounter);
|
||||
existingReleases = allReleases.Data;
|
||||
if (allReleases != null && allReleases.StatusCode == HttpStatusCode.OK && allReleases.Data.Any(r => r.Name == releaseName)) {
|
||||
throw new UserInfoException($"There is already an existing release named '{releaseName}'. Please delete this release or provide a new release name.");
|
||||
}
|
||||
} else {
|
||||
throw new UserInfoException("Could not get all releases from server");
|
||||
}
|
||||
|
||||
if (!options.Merge) {
|
||||
if (existingReleases.Any(r => r.TagName == semVer.ToString())) {
|
||||
throw new UserInfoException($"There is already an existing release tagged '{semVer}'. Please delete this release or provide a new version number.");
|
||||
}
|
||||
if (existingReleases.Any(r => r.Name == releaseName)) {
|
||||
throw new UserInfoException($"There is already an existing release named '{releaseName}'. Please delete this release or provide a new release name.");
|
||||
}
|
||||
}
|
||||
|
||||
// create or retrieve github release
|
||||
var release = existingReleases.FirstOrDefault(r => r.TagName == semVer.ToString())
|
||||
?? existingReleases.FirstOrDefault(r => r.Name == releaseName); ;
|
||||
|
||||
if (release != null) {
|
||||
if (release.TagName != semVer.ToString())
|
||||
throw new UserInfoException($"Found existing release matched by name ({release.Name} [{release.TagName}]), but tag name does not match ({semVer}).");
|
||||
Log.Info($"Found existing release ({release.Name} [{release.TagName}]). Merge flag is enabled.");
|
||||
} else {
|
||||
var newReleaseReq = new CreateReleaseOption(
|
||||
body: releaseNotes,
|
||||
draft: true,
|
||||
prerelease: options.Prerelease,
|
||||
name: string.IsNullOrWhiteSpace(options.ReleaseName) ? semVer.ToString() : options.ReleaseName,
|
||||
targetCommitish: options.TargetCommitish,
|
||||
tagName: semVer.ToString()
|
||||
);
|
||||
Log.Info($"Creating draft release titled '{newReleaseReq.Name}'");
|
||||
release = await apiInstance.RepoCreateReleaseAsync(repoOwner, repoName, newReleaseReq);
|
||||
}
|
||||
|
||||
// check if there is an existing releasesFile to merge
|
||||
var releasesFileName = Utility.GetVeloReleaseIndexName(options.Channel);
|
||||
var releaseAsset = release.Assets.FirstOrDefault(a => a.Name == releasesFileName);
|
||||
if (releaseAsset != null) {
|
||||
throw new UserInfoException($"There is already a remote asset named '{releasesFileName}', and merging release files on Gitea is not supported.");
|
||||
}
|
||||
|
||||
// upload all assets (incl packages)
|
||||
foreach (var a in build.Files) {
|
||||
await RetryAsync(() => UploadFileAsAsset(apiInstance, release, repoOwner, repoName, a), $"Uploading asset '{Path.GetFileName(a)}'..");
|
||||
}
|
||||
|
||||
var feed = new VelopackAssetFeed {
|
||||
Assets = build.GetReleaseEntries().ToArray(),
|
||||
};
|
||||
var json = ReleaseEntryHelper.GetAssetFeedJson(feed);
|
||||
|
||||
await RetryAsync(async () => {
|
||||
await apiInstance.RepoCreateReleaseAttachmentAsync(repoOwner, repoName, release.Id, releasesFileName, new MemoryStream(Encoding.UTF8.GetBytes(json)));
|
||||
}, "Uploading " + releasesFileName);
|
||||
|
||||
if (options.Channel == ReleaseEntryHelper.GetDefaultChannel(RuntimeOs.Windows)) {
|
||||
var legacyReleasesContent = ReleaseEntryHelper.GetLegacyMigrationReleaseFeedString(feed);
|
||||
var legacyReleasesBytes = Encoding.UTF8.GetBytes(legacyReleasesContent);
|
||||
await RetryAsync(async () => {
|
||||
await apiInstance.RepoCreateReleaseAttachmentAsync(repoOwner, repoName, release.Id, "RELEASES", new MemoryStream(legacyReleasesBytes));
|
||||
}, "Uploading legacy RELEASES (compatibility)");
|
||||
}
|
||||
|
||||
// convert draft to full release
|
||||
if (options.Publish) {
|
||||
if (release.Draft) {
|
||||
Log.Info("Converting draft to full published release.");
|
||||
var body = new EditReleaseOption(
|
||||
release.Body,
|
||||
false, // Draft
|
||||
release.Name,
|
||||
release.Prerelease,
|
||||
release.TagName,
|
||||
release.TargetCommitish
|
||||
);
|
||||
Release result = await apiInstance.RepoEditReleaseAsync(repoOwner, repoName, release.Id, body);
|
||||
} else {
|
||||
Log.Info("Skipping publish, release is already not a draft.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UploadFileAsAsset(RepositoryApi client, Release release, string repoOwner, string repoName, string filePath)
|
||||
{
|
||||
using var stream = File.OpenRead(filePath);
|
||||
// Create a release attachment
|
||||
await client.RepoCreateReleaseAttachmentAsync(repoOwner, repoName, release.Id, Path.GetFileName(filePath), stream);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.308.8" />
|
||||
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
|
||||
<PackageReference Include="Gitea.Net.API" Version="1.0.0" />
|
||||
<PackageReference Include="Octokit" Version="11.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -21,6 +21,19 @@
|
||||
"System.Text.Json": "4.7.2"
|
||||
}
|
||||
},
|
||||
"Gitea.Net.API": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.0, )",
|
||||
"resolved": "1.0.0",
|
||||
"contentHash": "5ZhKnsZfIjJ/aFeZFibi1VY8oOam0rQFf30A5gqxM5F3yoxpr1qHxeks10hvdgerGFMHSXgV8FDvtTHM4OA3Qw==",
|
||||
"dependencies": {
|
||||
"JsonSubTypes": "2.0.1",
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": "1.3.0",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Polly": "8.4.0",
|
||||
"RestSharp": "111.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
@@ -72,16 +85,40 @@
|
||||
"System.IO.Hashing": "6.0.0"
|
||||
}
|
||||
},
|
||||
"JsonSubTypes": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.1",
|
||||
"contentHash": "1Po+Ypf0SjCeEKx5+C89Nb5OgTcqNvfS3uTI46MUM+KEp6Rq/M0h+vVsTUt/6DFRwZMTpsAJM4yJrZmEObVANA==",
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "13.0.1"
|
||||
}
|
||||
},
|
||||
"Markdig": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.37.0",
|
||||
"contentHash": "biiu4MTPFjW55qw6v5Aphtj0MjDLJ14x8ndZwkJUHIeqvaSGKeqhLY7S7Vu/S3k7/c9KwhhnaCDP9hdFNUhcNA=="
|
||||
},
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "1gomLUkk2dfZbznBAPb/HCZzlA+7QNKb08v5GzPh/tqhkUaKZHR8PHh0vmJlZGAj8vnvNLnzpfIwwCdq/9BHWQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.Caching": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
||||
},
|
||||
"Microsoft.Bcl.TimeProvider": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "f5Kr5JepAbiGo7uDmhgvMqhntwxqXNn6/IpTBSSI4cuHhgnJGrLxFRhMjVpRkLPp6zJXO0/G0l3j9p9zSJxa+w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -144,11 +181,42 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||
},
|
||||
"NuGet.Versioning": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.10.0",
|
||||
"contentHash": "ytTA08tgZWo/Pbk333hnzQfiMyyynkkwMt4GyC5T0bzExYYSRNrkwv4jT8jmWr5LUOYsumEZvXdoven2SA7YZw=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "z2EeUutuy49jBQyZ5s2FUuTCGx3GCzJ0cJ2HbjWwks94TsC6bKTtAHKBkMZOa/DyYRl5yIX7MshvMTWl1J6RNg==",
|
||||
"dependencies": {
|
||||
"Polly.Core": "8.4.0"
|
||||
}
|
||||
},
|
||||
"Polly.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "3AZxuP//pxOeBo9tQs7/tz4Z5TTbu4BYfjpaXZD0JYKJo98ngN9TMUz1nybh4k0ykWkMBpGZALV/AmVIE3ew7A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.TimeProvider": "8.0.0"
|
||||
}
|
||||
},
|
||||
"RestSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "111.2.0",
|
||||
"contentHash": "OkWr6AGM0zirdkRpxVOxXMWx9OHEIWrDzrpx1XIx5KyvTcmtjJVsKBscVkYTcFerhj5w5Bny7boRIV4a0ENGaQ=="
|
||||
},
|
||||
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.2",
|
||||
@@ -283,6 +351,15 @@
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "6.0.0",
|
||||
"System.Security.Permissions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -311,6 +388,14 @@
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Globalization": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -506,6 +591,14 @@
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Caching": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==",
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -555,6 +648,11 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ=="
|
||||
},
|
||||
"System.Security.Cryptography.Algorithms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -669,8 +767,8 @@
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q=="
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ=="
|
||||
},
|
||||
"System.Security.Cryptography.X509Certificates": {
|
||||
"type": "Transitive",
|
||||
@@ -704,6 +802,15 @@
|
||||
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "6.0.0",
|
||||
"System.Windows.Extensions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -748,6 +855,14 @@
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
|
||||
},
|
||||
"System.Windows.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "6.0.0"
|
||||
}
|
||||
},
|
||||
"velopack": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
|
||||
19
src/Velopack.Vpk/Commands/Deployment/GiteaBaseCommand.cs
Normal file
19
src/Velopack.Vpk/Commands/Deployment/GiteaBaseCommand.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace Velopack.Vpk.Commands.Deployment;
|
||||
public abstract class GiteaBaseCommand : OutputCommand
|
||||
{
|
||||
public string RepoUrl { get; private set; }
|
||||
|
||||
public string Token { get; private set; }
|
||||
|
||||
protected GiteaBaseCommand(string name, string description)
|
||||
: base(name, description)
|
||||
{
|
||||
var repoUrl = AddOption<Uri>((v) => RepoUrl = v.ToAbsoluteOrNull(), "--repoUrl")
|
||||
.SetDescription("Full url to the gitea repository (eg. 'https://gitea.com/myname/myrepo').")
|
||||
.SetRequired()
|
||||
.MustBeValidHttpUri();
|
||||
|
||||
AddOption<string>((v) => Token = v, "--token")
|
||||
.SetDescription("OAuth token to use as login credentials.");
|
||||
}
|
||||
}
|
||||
12
src/Velopack.Vpk/Commands/Deployment/GiteaDownloadCommand.cs
Normal file
12
src/Velopack.Vpk/Commands/Deployment/GiteaDownloadCommand.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Velopack.Vpk.Commands.Deployment;
|
||||
public class GiteaDownloadCommand : GiteaBaseCommand
|
||||
{
|
||||
public bool Prerelease { get; private set; }
|
||||
|
||||
public GiteaDownloadCommand()
|
||||
: base("gitea", "Download latest release from Gitea repository.")
|
||||
{
|
||||
AddOption<bool>((v) => Prerelease = v, "--pre")
|
||||
.SetDescription("Get latest pre-release instead of stable.");
|
||||
}
|
||||
}
|
||||
49
src/Velopack.Vpk/Commands/Deployment/GiteaUploadCommand.cs
Normal file
49
src/Velopack.Vpk/Commands/Deployment/GiteaUploadCommand.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Velopack.Vpk.Commands.Deployment;
|
||||
public class GiteaUploadCommand : GiteaBaseCommand
|
||||
{
|
||||
public bool Publish { get; private set; }
|
||||
|
||||
public string ReleaseName { get; private set; }
|
||||
|
||||
public string TagName { get; private set; }
|
||||
|
||||
public string TargetCommitish { get; private set; }
|
||||
|
||||
public bool Prerelease { get; private set; }
|
||||
|
||||
public bool Merge { get; private set; }
|
||||
|
||||
public GiteaUploadCommand()
|
||||
: base("gitea", "Upload releases to a Gitea repository.")
|
||||
{
|
||||
AddOption<bool>((v) => Publish = v, "--publish")
|
||||
.SetDescription("Create and publish instead of leaving as draft.");
|
||||
|
||||
AddOption<bool>((v) => Prerelease = v, "--pre")
|
||||
.SetDescription("Create as pre-release instead of stable.");
|
||||
|
||||
AddOption<bool>((v) => Merge = v, "--merge")
|
||||
.SetDescription("Allow merging this upload with an existing release.");
|
||||
|
||||
AddOption<string>((v) => ReleaseName = v, "--releaseName")
|
||||
.SetDescription("A custom name for the release.")
|
||||
.SetArgumentHelpName("NAME");
|
||||
|
||||
AddOption<string>((v) => TagName = v, "--tag")
|
||||
.SetDescription("A custom tag for the release.")
|
||||
.SetArgumentHelpName("NAME");
|
||||
|
||||
AddOption<string>((v) => TargetCommitish = v, "--targetCommitish")
|
||||
.SetDescription("A commitish value for tag (branch or commit SHA).")
|
||||
.SetArgumentHelpName("NAME");
|
||||
|
||||
ReleaseDirectoryOption.SetRequired();
|
||||
ReleaseDirectoryOption.MustNotBeEmpty();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@ public static partial class OptionMapper
|
||||
public static partial OsxBundleOptions ToOptions(this OsxBundleCommand cmd);
|
||||
public static partial GitHubDownloadOptions ToOptions(this GitHubDownloadCommand cmd);
|
||||
public static partial GitHubUploadOptions ToOptions(this GitHubUploadCommand cmd);
|
||||
public static partial GiteaDownloadOptions ToOptions(this GiteaDownloadCommand cmd);
|
||||
public static partial GiteaUploadOptions ToOptions(this GiteaUploadCommand cmd);
|
||||
public static partial HttpDownloadOptions ToOptions(this HttpDownloadCommand cmd);
|
||||
public static partial LocalDownloadOptions ToOptions(this LocalDownloadCommand cmd);
|
||||
public static partial LocalUploadOptions ToOptions(this LocalUploadCommand cmd);
|
||||
|
||||
@@ -132,6 +132,7 @@ public class Program
|
||||
|
||||
var downloadCommand = new CliCommand("download", "Download's the latest release from a remote update source.");
|
||||
downloadCommand.AddRepositoryDownload<GitHubDownloadCommand, GitHubRepository, GitHubDownloadOptions>(provider);
|
||||
downloadCommand.AddRepositoryDownload<GiteaDownloadCommand, GiteaRepository, GiteaDownloadOptions>(provider);
|
||||
downloadCommand.AddRepositoryDownload<S3DownloadCommand, S3Repository, S3DownloadOptions>(provider);
|
||||
downloadCommand.AddRepositoryDownload<AzureDownloadCommand, AzureRepository, AzureDownloadOptions>(provider);
|
||||
downloadCommand.AddRepositoryDownload<LocalDownloadCommand, LocalRepository, LocalDownloadOptions>(provider);
|
||||
@@ -140,6 +141,7 @@ public class Program
|
||||
|
||||
var uploadCommand = new CliCommand("upload", "Upload local package(s) to a remote update source.");
|
||||
uploadCommand.AddRepositoryUpload<GitHubUploadCommand, GitHubRepository, GitHubUploadOptions>(provider);
|
||||
uploadCommand.AddRepositoryUpload<GiteaUploadCommand, GiteaRepository, GiteaUploadOptions>(provider);
|
||||
uploadCommand.AddRepositoryUpload<S3UploadCommand, S3Repository, S3UploadOptions>(provider);
|
||||
uploadCommand.AddRepositoryUpload<AzureUploadCommand, AzureRepository, AzureUploadOptions>(provider);
|
||||
uploadCommand.AddRepositoryUpload<LocalUploadCommand, LocalRepository, LocalUploadOptions>(provider);
|
||||
|
||||
@@ -218,16 +218,52 @@
|
||||
"resolved": "2.17.3",
|
||||
"contentHash": "BFKpnrs3yKH/jo1yewQdvLKMkEaxE6Wj3Lu5LHRNJfcAdOQ9YiY4dfQ5+5kz6ji1E/Xcxy5ta+qqKGA6KiVQMw=="
|
||||
},
|
||||
"Gitea.Net.API": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.0",
|
||||
"contentHash": "5ZhKnsZfIjJ/aFeZFibi1VY8oOam0rQFf30A5gqxM5F3yoxpr1qHxeks10hvdgerGFMHSXgV8FDvtTHM4OA3Qw==",
|
||||
"dependencies": {
|
||||
"JsonSubTypes": "2.0.1",
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": "1.3.0",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Polly": "8.4.0",
|
||||
"RestSharp": "111.2.0"
|
||||
}
|
||||
},
|
||||
"JsonSubTypes": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.1",
|
||||
"contentHash": "1Po+Ypf0SjCeEKx5+C89Nb5OgTcqNvfS3uTI46MUM+KEp6Rq/M0h+vVsTUt/6DFRwZMTpsAJM4yJrZmEObVANA==",
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "13.0.1"
|
||||
}
|
||||
},
|
||||
"Markdig": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.37.0",
|
||||
"contentHash": "biiu4MTPFjW55qw6v5Aphtj0MjDLJ14x8ndZwkJUHIeqvaSGKeqhLY7S7Vu/S3k7/c9KwhhnaCDP9hdFNUhcNA=="
|
||||
},
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "1gomLUkk2dfZbznBAPb/HCZzlA+7QNKb08v5GzPh/tqhkUaKZHR8PHh0vmJlZGAj8vnvNLnzpfIwwCdq/9BHWQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.Caching": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
|
||||
},
|
||||
"Microsoft.Bcl.TimeProvider": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "f5Kr5JepAbiGo7uDmhgvMqhntwxqXNn6/IpTBSSI4cuHhgnJGrLxFRhMjVpRkLPp6zJXO0/G0l3j9p9zSJxa+w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Build.Tasks.Git": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -543,6 +579,11 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
@@ -591,6 +632,27 @@
|
||||
"resolved": "11.0.1",
|
||||
"contentHash": "fpwF/DxMJyGS+pIXDKQozx0wCIpOfG8VDr10ls+m9Gn9Lz8GslhhApxkKD9JCNO60HRUeMJsedsAS24gCjTD7Q=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "z2EeUutuy49jBQyZ5s2FUuTCGx3GCzJ0cJ2HbjWwks94TsC6bKTtAHKBkMZOa/DyYRl5yIX7MshvMTWl1J6RNg==",
|
||||
"dependencies": {
|
||||
"Polly.Core": "8.4.0"
|
||||
}
|
||||
},
|
||||
"Polly.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "3AZxuP//pxOeBo9tQs7/tz4Z5TTbu4BYfjpaXZD0JYKJo98ngN9TMUz1nybh4k0ykWkMBpGZALV/AmVIE3ew7A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.TimeProvider": "8.0.0"
|
||||
}
|
||||
},
|
||||
"RestSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "111.2.0",
|
||||
"contentHash": "OkWr6AGM0zirdkRpxVOxXMWx9OHEIWrDzrpx1XIx5KyvTcmtjJVsKBscVkYTcFerhj5w5Bny7boRIV4a0ENGaQ=="
|
||||
},
|
||||
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.2",
|
||||
@@ -753,6 +815,15 @@
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "6.0.0",
|
||||
"System.Security.Permissions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -786,6 +857,14 @@
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Formats.Asn1": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -991,6 +1070,14 @@
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Caching": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==",
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -1040,6 +1127,11 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ=="
|
||||
},
|
||||
"System.Security.Cryptography.Algorithms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -1162,8 +1254,8 @@
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q=="
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ=="
|
||||
},
|
||||
"System.Security.Cryptography.X509Certificates": {
|
||||
"type": "Transitive",
|
||||
@@ -1197,6 +1289,15 @@
|
||||
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "6.0.0",
|
||||
"System.Windows.Extensions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -1256,6 +1357,14 @@
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
|
||||
},
|
||||
"System.Windows.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "6.0.0"
|
||||
}
|
||||
},
|
||||
"velopack": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
@@ -1268,6 +1377,7 @@
|
||||
"dependencies": {
|
||||
"AWSSDK.S3": "[3.7.308.8, )",
|
||||
"Azure.Storage.Blobs": "[12.20.0, )",
|
||||
"Gitea.Net.API": "[1.0.0, )",
|
||||
"Octokit": "[11.0.1, )",
|
||||
"Velopack.Packaging": "[1.0.0, )"
|
||||
}
|
||||
@@ -1523,11 +1633,39 @@
|
||||
"resolved": "2.17.3",
|
||||
"contentHash": "BFKpnrs3yKH/jo1yewQdvLKMkEaxE6Wj3Lu5LHRNJfcAdOQ9YiY4dfQ5+5kz6ji1E/Xcxy5ta+qqKGA6KiVQMw=="
|
||||
},
|
||||
"Gitea.Net.API": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.0",
|
||||
"contentHash": "5ZhKnsZfIjJ/aFeZFibi1VY8oOam0rQFf30A5gqxM5F3yoxpr1qHxeks10hvdgerGFMHSXgV8FDvtTHM4OA3Qw==",
|
||||
"dependencies": {
|
||||
"JsonSubTypes": "2.0.1",
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": "1.3.0",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Polly": "8.4.0",
|
||||
"RestSharp": "111.2.0"
|
||||
}
|
||||
},
|
||||
"JsonSubTypes": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.1",
|
||||
"contentHash": "1Po+Ypf0SjCeEKx5+C89Nb5OgTcqNvfS3uTI46MUM+KEp6Rq/M0h+vVsTUt/6DFRwZMTpsAJM4yJrZmEObVANA==",
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "13.0.1"
|
||||
}
|
||||
},
|
||||
"Markdig": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.37.0",
|
||||
"contentHash": "biiu4MTPFjW55qw6v5Aphtj0MjDLJ14x8ndZwkJUHIeqvaSGKeqhLY7S7Vu/S3k7/c9KwhhnaCDP9hdFNUhcNA=="
|
||||
},
|
||||
"Microsoft.AspNetCore.SystemWebAdapters": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.3.0",
|
||||
"contentHash": "1gomLUkk2dfZbznBAPb/HCZzlA+7QNKb08v5GzPh/tqhkUaKZHR8PHh0vmJlZGAj8vnvNLnzpfIwwCdq/9BHWQ==",
|
||||
"dependencies": {
|
||||
"System.Runtime.Caching": "6.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -1843,6 +1981,11 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A=="
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
@@ -1891,6 +2034,24 @@
|
||||
"resolved": "11.0.1",
|
||||
"contentHash": "fpwF/DxMJyGS+pIXDKQozx0wCIpOfG8VDr10ls+m9Gn9Lz8GslhhApxkKD9JCNO60HRUeMJsedsAS24gCjTD7Q=="
|
||||
},
|
||||
"Polly": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "z2EeUutuy49jBQyZ5s2FUuTCGx3GCzJ0cJ2HbjWwks94TsC6bKTtAHKBkMZOa/DyYRl5yIX7MshvMTWl1J6RNg==",
|
||||
"dependencies": {
|
||||
"Polly.Core": "8.4.0"
|
||||
}
|
||||
},
|
||||
"Polly.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.4.0",
|
||||
"contentHash": "3AZxuP//pxOeBo9tQs7/tz4Z5TTbu4BYfjpaXZD0JYKJo98ngN9TMUz1nybh4k0ykWkMBpGZALV/AmVIE3ew7A=="
|
||||
},
|
||||
"RestSharp": {
|
||||
"type": "Transitive",
|
||||
"resolved": "111.2.0",
|
||||
"contentHash": "OkWr6AGM0zirdkRpxVOxXMWx9OHEIWrDzrpx1XIx5KyvTcmtjJVsKBscVkYTcFerhj5w5Bny7boRIV4a0ENGaQ=="
|
||||
},
|
||||
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.2",
|
||||
@@ -2053,6 +2214,15 @@
|
||||
"System.Threading.Tasks": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "6.0.0",
|
||||
"System.Security.Permissions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -2083,6 +2253,14 @@
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Formats.Asn1": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -2283,6 +2461,14 @@
|
||||
"Microsoft.NETCore.Targets": "1.1.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.Caching": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==",
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
@@ -2332,6 +2518,11 @@
|
||||
"System.Runtime.Extensions": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.AccessControl": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ=="
|
||||
},
|
||||
"System.Security.Cryptography.Algorithms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -2454,8 +2645,8 @@
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q=="
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ=="
|
||||
},
|
||||
"System.Security.Cryptography.X509Certificates": {
|
||||
"type": "Transitive",
|
||||
@@ -2489,6 +2680,15 @@
|
||||
"runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0"
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "6.0.0",
|
||||
"System.Windows.Extensions": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.3.0",
|
||||
@@ -2544,6 +2744,14 @@
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg=="
|
||||
},
|
||||
"System.Windows.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "6.0.0"
|
||||
}
|
||||
},
|
||||
"velopack": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
@@ -2556,6 +2764,7 @@
|
||||
"dependencies": {
|
||||
"AWSSDK.S3": "[3.7.308.8, )",
|
||||
"Azure.Storage.Blobs": "[12.20.0, )",
|
||||
"Gitea.Net.API": "[1.0.0, )",
|
||||
"Octokit": "[11.0.1, )",
|
||||
"Velopack.Packaging": "[1.0.0, )"
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Velopack.Json
|
||||
|
||||
[JsonSerializable(typeof(List<GithubRelease>))]
|
||||
[JsonSerializable(typeof(List<GitlabRelease>))]
|
||||
[JsonSerializable(typeof(List<GiteaRelease>))]
|
||||
[JsonSerializable(typeof(VelopackAssetFeed))]
|
||||
[JsonSerializable(typeof(VelopackFlowReleaseAsset[]))]
|
||||
#if NET8_0_OR_GREATER
|
||||
@@ -60,6 +61,11 @@ namespace Velopack.Json
|
||||
return JsonSerializer.Deserialize(json, Context.ListGithubRelease);
|
||||
}
|
||||
|
||||
public static List<GiteaRelease>? DeserializeGiteaReleaseList(string json)
|
||||
{
|
||||
return JsonSerializer.Deserialize(json, Context.ListGiteaRelease);
|
||||
}
|
||||
|
||||
public static List<GitlabRelease>? DeserializeGitlabReleaseList(string json)
|
||||
{
|
||||
return JsonSerializer.Deserialize(json, Context.ListGitlabRelease);
|
||||
@@ -119,6 +125,11 @@ namespace Velopack.Json
|
||||
return JsonConvert.DeserializeObject<List<GithubRelease>>(json, Options);
|
||||
}
|
||||
|
||||
public static List<GiteaRelease>? DeserializeGiteaReleaseList(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<List<GiteaRelease>>(json, Options);
|
||||
}
|
||||
|
||||
public static List<GitlabRelease>? DeserializeGitlabReleaseList(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<List<GitlabRelease>>(json, Options);
|
||||
|
||||
135
src/Velopack/Sources/GiteaSource.cs
Normal file
135
src/Velopack/Sources/GiteaSource.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Velopack.Json;
|
||||
namespace Velopack.Sources
|
||||
{
|
||||
/// <summary> Describes a Gitea release, including attached assets. </summary>
|
||||
public class GiteaRelease
|
||||
{
|
||||
/// <summary> The name of this release. </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary> True if this release is a prerelease. </summary>
|
||||
[JsonPropertyName("prerelease")]
|
||||
public bool Prerelease { get; set; }
|
||||
|
||||
/// <summary> The date which this release was published publicly. </summary>
|
||||
[JsonPropertyName("published_at")]
|
||||
public DateTime? PublishedAt { get; set; }
|
||||
|
||||
/// <summary> A list of assets (files) uploaded to this release. </summary>
|
||||
[JsonPropertyName("assets")]
|
||||
public GiteaReleaseAsset[] Assets { get; set; } = new GiteaReleaseAsset[0];
|
||||
}
|
||||
/// <summary> Describes a asset (file) uploaded to a Gitea release. </summary>
|
||||
public class GiteaReleaseAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// The asset URL for this release asset. Requests to this URL will use API
|
||||
/// quota and return JSON unless the 'Accept' header is "application/octet-stream".
|
||||
/// </summary>
|
||||
[JsonPropertyName("url")]
|
||||
public string? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The browser URL for this release asset. This does not use API quota,
|
||||
/// however this URL only works for public repositories. If downloading
|
||||
/// assets from a private repository, the <see cref="Url"/> property must
|
||||
/// be used with an appropriate access token.
|
||||
/// </summary>
|
||||
[JsonPropertyName("browser_download_url")]
|
||||
public string? BrowserDownloadUrl { get; set; }
|
||||
|
||||
/// <summary> The name of this release asset. </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves available releases from a Gitea repository.
|
||||
/// </summary>
|
||||
public class GiteaSource : GitBase<GiteaRelease>
|
||||
{
|
||||
/// <inheritdoc cref="GiteaSource" />
|
||||
/// <param name="repoUrl">
|
||||
/// The URL of the Gitea repository to download releases from
|
||||
/// (e.g. https://Gitea.com/myuser/myrepo)
|
||||
/// </param>
|
||||
/// <param name="accessToken">
|
||||
/// The Gitea access token to use with the request to download releases.
|
||||
/// If left empty, the Gitea rate limit for unauthenticated requests allows
|
||||
/// for up to 60 requests per hour, limited by IP address.
|
||||
/// </param>
|
||||
/// <param name="prerelease">
|
||||
/// If true, pre-releases will be also be searched / downloaded. If false, only
|
||||
/// stable releases will be considered.
|
||||
/// </param>
|
||||
/// <param name="downloader">
|
||||
/// The file downloader used to perform HTTP requests.
|
||||
/// </param>
|
||||
public GiteaSource(string repoUrl, string? accessToken, bool prerelease, IFileDownloader? downloader = null)
|
||||
: base(repoUrl, accessToken, prerelease, downloader)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// The authorization token used in the request.
|
||||
/// Overwrite it to token
|
||||
/// </summary>
|
||||
protected override string? Authorization => string.IsNullOrWhiteSpace(AccessToken) ? null : "token " + AccessToken;
|
||||
/// <inheritdoc />
|
||||
protected override async Task<GiteaRelease[]> GetReleases(bool includePrereleases)
|
||||
{
|
||||
// https://gitea.com/api/swagger#/repository/repoListReleases
|
||||
// https://docs.gitea.com/api/1.22/#tag/repository/operation/repoListReleases
|
||||
|
||||
const int perPage = 10;
|
||||
const int page = 1;
|
||||
var releasesPath = $"repos{RepoUri.AbsolutePath}/releases?limit={perPage}&page={page}&draft=false";
|
||||
var baseUri = GetApiBaseUrl(RepoUri);
|
||||
var getReleasesUri = new Uri(baseUri, releasesPath);
|
||||
var response = await Downloader.DownloadString(getReleasesUri.ToString(), Authorization, "application/json").ConfigureAwait(false);
|
||||
var releases = CompiledJson.DeserializeGiteaReleaseList(response);
|
||||
if (releases == null) return new GiteaRelease[0];
|
||||
return releases.OrderByDescending(d => d.PublishedAt).Where(x => includePrereleases || !x.Prerelease).ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetAssetUrlFromName(GiteaRelease release, string assetName)
|
||||
{
|
||||
if (release.Assets == null || release.Assets.Count() == 0) {
|
||||
throw new ArgumentException($"No assets found in Gitea Release '{release.Name}'.");
|
||||
}
|
||||
|
||||
IEnumerable<GiteaReleaseAsset> allReleasesFiles = release.Assets.Where(a => a.Name?.Equals(assetName, StringComparison.InvariantCultureIgnoreCase) == true);
|
||||
if (allReleasesFiles == null || allReleasesFiles.Count() == 0) {
|
||||
throw new ArgumentException($"Could not find asset called '{assetName}' in Gitea Release '{release.Name}'.");
|
||||
}
|
||||
|
||||
var asset = allReleasesFiles.First();
|
||||
|
||||
if (asset.BrowserDownloadUrl != null) {
|
||||
return asset.BrowserDownloadUrl;
|
||||
} else {
|
||||
throw new ArgumentException("Could not find a valid asset url for the specified asset.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a repository URL (e.g. https://Gitea.com/myuser/myrepo) this function
|
||||
/// returns the API base for performing requests. (eg. "https://api.Gitea.com/"
|
||||
/// or http://internal.Gitea.server.local/api/v1)
|
||||
/// </summary>
|
||||
/// <param name="repoUrl"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Uri GetApiBaseUrl(Uri repoUrl)
|
||||
{
|
||||
Uri baseAddress = new Uri(string.Format("{0}{1}{2}/api/v1/", repoUrl.Scheme, Uri.SchemeDelimiter, repoUrl.Host));
|
||||
// above ^^ notice the end slashes for the baseAddress, explained here: http://stackoverflow.com/a/23438417/162694
|
||||
return baseAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,15 +8,6 @@
|
||||
"resolved": "2.2.0",
|
||||
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.0.3, )",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.0, )",
|
||||
@@ -50,11 +41,6 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies.net462": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.0.3",
|
||||
"contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
@@ -159,9 +145,9 @@
|
||||
},
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.1, )",
|
||||
"resolved": "8.0.1",
|
||||
"contentHash": "ADdJXuKNjwZDfBmybMnpvwd5CK3gp92WkWqqeQhW4W+q4MO3Qaa9QyW2DcFLAvCDMcCWxT5hRXqGdv13oon7nA=="
|
||||
"requested": "[8.0.6, )",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "E+lDylsTeP4ZiDmnEkiJ5wobnGaIJzFhOgZppznJCb69UZgbh6G3cfv1pnLDLLBx6JAgl0kAlnINDeT3uCuczQ=="
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -389,7 +389,6 @@ public class UpdateManagerTests
|
||||
Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version);
|
||||
Assert.Equal(0, info.DeltasToTarget.Count());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Consumes API Quota")]
|
||||
public void CheckGithubWithNonExistingChannel()
|
||||
{
|
||||
@@ -402,7 +401,20 @@ public class UpdateManagerTests
|
||||
var um = new UpdateManager(source, opt, logger, locator);
|
||||
Assert.Throws<ArgumentException>(() => um.CheckForUpdates());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Consumes API Quota")]
|
||||
public void CheckGitea()
|
||||
{
|
||||
// https://github.com/caesay/SquirrelCustomLauncherTestApp
|
||||
using var logger = _output.BuildLoggerFor<UpdateManagerTests>();
|
||||
using var _1 = Utility.GetTempDirectory(out var tempPath);
|
||||
var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger);
|
||||
var source = new GiteaSource("https://gitea.com/remco1271/VeloPackTest", null, false);
|
||||
var um = new UpdateManager(source, null, logger, locator);
|
||||
var info = um.CheckForUpdates();
|
||||
Assert.NotNull(info);
|
||||
Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version);
|
||||
Assert.Equal(0, info.DeltasToTarget.Count());
|
||||
}
|
||||
[Fact]
|
||||
public void CheckFromEmptyFileSource()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user