mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Implementing cancellation for MSBuild tasks
This commit is contained in:
@@ -1,13 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
using MSBuildTask = Microsoft.Build.Utilities.Task;
|
using MSBuildTask = Microsoft.Build.Utilities.Task;
|
||||||
|
|
||||||
namespace Velopack.Build;
|
namespace Velopack.Build;
|
||||||
|
|
||||||
public abstract class MSBuildAsyncTask : MSBuildTask
|
public abstract class MSBuildAsyncTask : MSBuildTask, ICancelableTask
|
||||||
{
|
{
|
||||||
protected MSBuildLogger Logger { get; }
|
protected MSBuildLogger Logger { get; }
|
||||||
|
|
||||||
|
private CancellationTokenSource CancellationTokenSource { get; } = new();
|
||||||
|
|
||||||
protected MSBuildAsyncTask()
|
protected MSBuildAsyncTask()
|
||||||
{
|
{
|
||||||
Logger = new MSBuildLogger(Log);
|
Logger = new MSBuildLogger(Log);
|
||||||
@@ -15,8 +19,18 @@ public abstract class MSBuildAsyncTask : MSBuildTask
|
|||||||
|
|
||||||
public sealed override bool Execute()
|
public sealed override bool Execute()
|
||||||
{
|
{
|
||||||
|
CancellationToken token = CancellationTokenSource.Token;
|
||||||
try {
|
try {
|
||||||
return Task.Run(ExecuteAsync).Result;
|
return Task.Run(async () => {
|
||||||
|
try {
|
||||||
|
return await ExecuteAsync(token).ConfigureAwait(false);
|
||||||
|
} catch (OperationCanceledException) {
|
||||||
|
return false;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.LogErrorFromException(ex, true, true, null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, token).Result;
|
||||||
} catch (AggregateException ex) {
|
} catch (AggregateException ex) {
|
||||||
ex.Flatten().Handle((x) => {
|
ex.Flatten().Handle((x) => {
|
||||||
Log.LogError(x.Message);
|
Log.LogError(x.Message);
|
||||||
@@ -26,5 +40,7 @@ public abstract class MSBuildAsyncTask : MSBuildTask
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Task<bool> ExecuteAsync();
|
protected abstract Task<bool> ExecuteAsync(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
public void Cancel() => CancellationTokenSource.Cancel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Build.Framework;
|
using Microsoft.Build.Framework;
|
||||||
using Velopack.Packaging;
|
using Velopack.Packaging;
|
||||||
@@ -90,7 +91,7 @@ public class PackTask : MSBuildAsyncTask
|
|||||||
|
|
||||||
public string? Categories { get; set; }
|
public string? Categories { get; set; }
|
||||||
|
|
||||||
protected override async Task<bool> ExecuteAsync()
|
protected override async Task<bool> ExecuteAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//System.Diagnostics.Debugger.Launch();
|
//System.Diagnostics.Debugger.Launch();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Build.Framework;
|
using Microsoft.Build.Framework;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -9,9 +10,8 @@ namespace Velopack.Build;
|
|||||||
|
|
||||||
public class PublishTask : MSBuildAsyncTask
|
public class PublishTask : MSBuildAsyncTask
|
||||||
{
|
{
|
||||||
private static HttpClient HttpClient { get; } = new(new HmacAuthHttpClientHandler
|
private static HttpClient HttpClient { get; } = new(new HmacAuthHttpClientHandler {
|
||||||
{
|
InnerHandler = new HttpClientHandler()
|
||||||
InnerHandler = new HttpClientHandler()
|
|
||||||
}) {
|
}) {
|
||||||
Timeout = TimeSpan.FromMinutes(10)
|
Timeout = TimeSpan.FromMinutes(10)
|
||||||
};
|
};
|
||||||
@@ -25,29 +25,23 @@ public class PublishTask : MSBuildAsyncTask
|
|||||||
|
|
||||||
public string? ApiKey { get; set; }
|
public string? ApiKey { get; set; }
|
||||||
|
|
||||||
protected override async Task<bool> ExecuteAsync()
|
protected override async Task<bool> ExecuteAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|
||||||
//System.Diagnostics.Debugger.Launch();
|
//System.Diagnostics.Debugger.Launch();
|
||||||
try {
|
IVelopackFlowServiceClient client = new VelopackFlowServiceClient(HttpClient, Logger);
|
||||||
IVelopackFlowServiceClient client = new VelopackFlowServiceClient(HttpClient, Logger);
|
if (!await client.LoginAsync(new() {
|
||||||
if (!await client.LoginAsync(new() {
|
AllowDeviceCodeFlow = false,
|
||||||
AllowDeviceCodeFlow = false,
|
AllowInteractiveLogin = false,
|
||||||
AllowInteractiveLogin = false,
|
VelopackBaseUrl = ServiceUrl,
|
||||||
VelopackBaseUrl = ServiceUrl,
|
ApiKey = ApiKey
|
||||||
ApiKey = ApiKey
|
}, cancellationToken).ConfigureAwait(false)) {
|
||||||
}).ConfigureAwait(false)) {
|
Logger.LogWarning("Not logged into Velopack Flow service, skipping publish. Please run vpk login.");
|
||||||
Logger.LogWarning("Not logged into Velopack Flow service, skipping publish. Please run vpk login.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
await client.UploadLatestReleaseAssetsAsync(Channel, ReleaseDirectory, ServiceUrl)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.LogErrorFromException(ex, true, true, null);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await client.UploadLatestReleaseAssetsAsync(Channel, ReleaseDirectory, ServiceUrl, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ namespace Velopack.Packaging.Flow;
|
|||||||
|
|
||||||
public interface IVelopackFlowServiceClient
|
public interface IVelopackFlowServiceClient
|
||||||
{
|
{
|
||||||
Task<bool> LoginAsync(VelopackLoginOptions? options = null);
|
Task<bool> LoginAsync(VelopackLoginOptions? options, CancellationToken cancellationToken);
|
||||||
Task LogoutAsync(VelopackServiceOptions? options = null);
|
Task LogoutAsync(VelopackServiceOptions? options, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task<Profile?> GetProfileAsync(VelopackServiceOptions? options = null);
|
Task<Profile?> GetProfileAsync(VelopackServiceOptions? options, CancellationToken cancellationToken);
|
||||||
|
|
||||||
Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl);
|
Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : IVelopackFlowServiceClient
|
public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) : IVelopackFlowServiceClient
|
||||||
@@ -30,35 +30,35 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
|
|
||||||
private AuthConfiguration? AuthConfiguration { get; set; }
|
private AuthConfiguration? AuthConfiguration { get; set; }
|
||||||
|
|
||||||
public async Task<bool> LoginAsync(VelopackLoginOptions? options = null)
|
public async Task<bool> LoginAsync(VelopackLoginOptions? options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
options ??= new VelopackLoginOptions();
|
options ??= new VelopackLoginOptions();
|
||||||
Logger.LogInformation("Preparing to login to Velopack ({ServiceUrl})", options.VelopackBaseUrl);
|
Logger.LogInformation("Preparing to login to Velopack ({ServiceUrl})", options.VelopackBaseUrl);
|
||||||
|
|
||||||
var authConfiguration = await GetAuthConfigurationAsync(options);
|
var authConfiguration = await GetAuthConfigurationAsync(options, cancellationToken);
|
||||||
|
|
||||||
var pca = await BuildPublicApplicationAsync(authConfiguration);
|
var pca = await BuildPublicApplicationAsync(authConfiguration);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(options.ApiKey)) {
|
if (!string.IsNullOrWhiteSpace(options.ApiKey)) {
|
||||||
HttpClient.DefaultRequestHeaders.Authorization = new(HmacHelper.HmacScheme, options.ApiKey);
|
HttpClient.DefaultRequestHeaders.Authorization = new(HmacHelper.HmacScheme, options.ApiKey);
|
||||||
var profile = await GetProfileAsync(options);
|
var profile = await GetProfileAsync(options, cancellationToken);
|
||||||
Logger.LogInformation("{UserName} logged into Velopack with API key", profile?.GetDisplayName());
|
Logger.LogInformation("{UserName} logged into Velopack with API key", profile?.GetDisplayName());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
AuthenticationResult? rv = null;
|
AuthenticationResult? rv = null;
|
||||||
if (options.AllowCacheCredentials) {
|
if (options.AllowCacheCredentials) {
|
||||||
rv = await AcquireSilentlyAsync(pca);
|
rv = await AcquireSilentlyAsync(pca, cancellationToken);
|
||||||
}
|
}
|
||||||
if (rv is null && options.AllowInteractiveLogin) {
|
if (rv is null && options.AllowInteractiveLogin) {
|
||||||
rv = await AcquireInteractiveAsync(pca, authConfiguration);
|
rv = await AcquireInteractiveAsync(pca, authConfiguration, cancellationToken);
|
||||||
}
|
}
|
||||||
if (rv is null && options.AllowDeviceCodeFlow) {
|
if (rv is null && options.AllowDeviceCodeFlow) {
|
||||||
rv = await AcquireByDeviceCodeAsync(pca);
|
rv = await AcquireByDeviceCodeAsync(pca, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv != null) {
|
if (rv != null) {
|
||||||
HttpClient.DefaultRequestHeaders.Authorization = new("Bearer", rv.IdToken ?? rv.AccessToken);
|
HttpClient.DefaultRequestHeaders.Authorization = new("Bearer", rv.IdToken ?? rv.AccessToken);
|
||||||
var profile = await GetProfileAsync(options);
|
var profile = await GetProfileAsync(options, cancellationToken);
|
||||||
|
|
||||||
Logger.LogInformation("{UserName} logged into Velopack", profile?.GetDisplayName());
|
Logger.LogInformation("{UserName} logged into Velopack", profile?.GetDisplayName());
|
||||||
return true;
|
return true;
|
||||||
@@ -69,9 +69,9 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task LogoutAsync(VelopackServiceOptions? options = null)
|
public async Task LogoutAsync(VelopackServiceOptions? options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var authConfiguration = await GetAuthConfigurationAsync(options);
|
var authConfiguration = await GetAuthConfigurationAsync(options, cancellationToken);
|
||||||
|
|
||||||
var pca = await BuildPublicApplicationAsync(authConfiguration);
|
var pca = await BuildPublicApplicationAsync(authConfiguration);
|
||||||
|
|
||||||
@@ -83,15 +83,15 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
Logger.LogInformation("Cleared saved login(s) for Velopack");
|
Logger.LogInformation("Cleared saved login(s) for Velopack");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Profile?> GetProfileAsync(VelopackServiceOptions? options = null)
|
public async Task<Profile?> GetProfileAsync(VelopackServiceOptions? options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
AssertAuthenticated();
|
AssertAuthenticated();
|
||||||
var endpoint = GetEndpoint("v1/user/profile", options);
|
var endpoint = GetEndpoint("v1/user/profile", options);
|
||||||
|
|
||||||
return await HttpClient.GetFromJsonAsync<Profile>(endpoint);
|
return await HttpClient.GetFromJsonAsync<Profile>(endpoint, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl)
|
public async Task UploadLatestReleaseAssetsAsync(string? channel, string releaseDirectory, string? serviceUrl, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
channel ??= ReleaseEntryHelper.GetDefaultChannel(VelopackRuntimeInfo.SystemOs);
|
channel ??= ReleaseEntryHelper.GetDefaultChannel(VelopackRuntimeInfo.SystemOs);
|
||||||
ReleaseEntryHelper helper = new(releaseDirectory, channel, Logger);
|
ReleaseEntryHelper helper = new(releaseDirectory, channel, Logger);
|
||||||
@@ -130,7 +130,7 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
VelopackBaseUrl = serviceUrl
|
VelopackBaseUrl = serviceUrl
|
||||||
};
|
};
|
||||||
|
|
||||||
await UploadReleaseAssetAsync(options).ConfigureAwait(false);
|
await UploadReleaseAssetAsync(options, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
Logger.LogInformation("Uploaded {FileName} to Velopack", assetFileName);
|
Logger.LogInformation("Uploaded {FileName} to Velopack", assetFileName);
|
||||||
}
|
}
|
||||||
@@ -143,13 +143,13 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
VelopackBaseUrl = serviceUrl
|
VelopackBaseUrl = serviceUrl
|
||||||
};
|
};
|
||||||
|
|
||||||
await UploadInstallerAssetAsync(options).ConfigureAwait(false);
|
await UploadInstallerAssetAsync(options, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
Logger.LogInformation("Uploaded {FileName} installer to Velopack", installerFile);
|
Logger.LogInformation("Uploaded {FileName} installer to Velopack", installerFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UploadReleaseAssetAsync(UploadOptions options)
|
private async Task UploadReleaseAssetAsync(UploadOptions options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
AssertAuthenticated();
|
AssertAuthenticated();
|
||||||
|
|
||||||
@@ -163,12 +163,12 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
|
|
||||||
var endpoint = GetEndpoint("v1/upload-release", options);
|
var endpoint = GetEndpoint("v1/upload-release", options);
|
||||||
|
|
||||||
var response = await HttpClient.PostAsync(endpoint, formData);
|
var response = await HttpClient.PostAsync(endpoint, formData, cancellationToken);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UploadInstallerAssetAsync(UploadInstallerOptions options)
|
private async Task UploadInstallerAssetAsync(UploadInstallerOptions options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
AssertAuthenticated();
|
AssertAuthenticated();
|
||||||
|
|
||||||
@@ -184,19 +184,19 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
|
|
||||||
var endpoint = GetEndpoint("v1/upload-installer", options);
|
var endpoint = GetEndpoint("v1/upload-installer", options);
|
||||||
|
|
||||||
var response = await HttpClient.PostAsync(endpoint, formData);
|
var response = await HttpClient.PostAsync(endpoint, formData, cancellationToken);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<AuthConfiguration> GetAuthConfigurationAsync(VelopackServiceOptions? options)
|
private async Task<AuthConfiguration> GetAuthConfigurationAsync(VelopackServiceOptions? options, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (AuthConfiguration is not null)
|
if (AuthConfiguration is not null)
|
||||||
return AuthConfiguration;
|
return AuthConfiguration;
|
||||||
|
|
||||||
var endpoint = GetEndpoint("v1/auth/config", options);
|
var endpoint = GetEndpoint("v1/auth/config", options);
|
||||||
|
|
||||||
var authConfig = await HttpClient.GetFromJsonAsync<AuthConfiguration>(endpoint);
|
var authConfig = await HttpClient.GetFromJsonAsync<AuthConfiguration>(endpoint, cancellationToken);
|
||||||
if (authConfig is null)
|
if (authConfig is null)
|
||||||
throw new Exception("Failed to get auth configuration.");
|
throw new Exception("Failed to get auth configuration.");
|
||||||
if (authConfig.B2CAuthority is null)
|
if (authConfig.B2CAuthority is null)
|
||||||
@@ -223,13 +223,13 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<AuthenticationResult?> AcquireSilentlyAsync(IPublicClientApplication pca)
|
private static async Task<AuthenticationResult?> AcquireSilentlyAsync(IPublicClientApplication pca, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
foreach (var account in await pca.GetAccountsAsync()) {
|
foreach (var account in await pca.GetAccountsAsync()) {
|
||||||
try {
|
try {
|
||||||
if (account is not null) {
|
if (account is not null) {
|
||||||
return await pca.AcquireTokenSilent(Scopes, account)
|
return await pca.AcquireTokenSilent(Scopes, account)
|
||||||
.ExecuteAsync();
|
.ExecuteAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
} catch (MsalException) {
|
} catch (MsalException) {
|
||||||
await pca.RemoveAsync(account);
|
await pca.RemoveAsync(account);
|
||||||
@@ -239,18 +239,18 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<AuthenticationResult?> AcquireInteractiveAsync(IPublicClientApplication pca, AuthConfiguration authConfiguration)
|
private static async Task<AuthenticationResult?> AcquireInteractiveAsync(IPublicClientApplication pca, AuthConfiguration authConfiguration, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return await pca.AcquireTokenInteractive(Scopes)
|
return await pca.AcquireTokenInteractive(Scopes)
|
||||||
.WithB2CAuthority(authConfiguration.B2CAuthority)
|
.WithB2CAuthority(authConfiguration.B2CAuthority)
|
||||||
.ExecuteAsync();
|
.ExecuteAsync(cancellationToken);
|
||||||
} catch (MsalException) {
|
} catch (MsalException) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<AuthenticationResult?> AcquireByDeviceCodeAsync(IPublicClientApplication pca)
|
private async Task<AuthenticationResult?> AcquireByDeviceCodeAsync(IPublicClientApplication pca, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
var result = await pca.AcquireTokenWithDeviceCode(Scopes,
|
var result = await pca.AcquireTokenWithDeviceCode(Scopes,
|
||||||
@@ -267,7 +267,7 @@ public class VelopackFlowServiceClient(HttpClient HttpClient, ILogger Logger) :
|
|||||||
// If this occurs, an OperationCanceledException will be thrown (see catch below for more details).
|
// If this occurs, an OperationCanceledException will be thrown (see catch below for more details).
|
||||||
Logger.LogInformation(deviceCodeResult.Message);
|
Logger.LogInformation(deviceCodeResult.Message);
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}).ExecuteAsync();
|
}).ExecuteAsync(cancellationToken);
|
||||||
|
|
||||||
Logger.LogInformation(result.Account.Username);
|
Logger.LogInformation(result.Account.Username);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Velopack.Packaging.Abstractions;
|
using System.Threading;
|
||||||
|
using Velopack.Packaging.Abstractions;
|
||||||
using Velopack.Packaging.Flow;
|
using Velopack.Packaging.Flow;
|
||||||
|
|
||||||
namespace Velopack.Vpk.Commands.Flow;
|
namespace Velopack.Vpk.Commands.Flow;
|
||||||
@@ -11,6 +12,6 @@ public class LoginCommandRunner(IVelopackFlowServiceClient Client) : ICommand<Lo
|
|||||||
await Client.LoginAsync(new() {
|
await Client.LoginAsync(new() {
|
||||||
VelopackBaseUrl = options.VelopackBaseUrl,
|
VelopackBaseUrl = options.VelopackBaseUrl,
|
||||||
ApiKey = options.ApiKey,
|
ApiKey = options.ApiKey,
|
||||||
});
|
}, CancellationToken.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Velopack.Packaging.Abstractions;
|
using System.Threading;
|
||||||
|
using Velopack.Packaging.Abstractions;
|
||||||
using Velopack.Packaging.Flow;
|
using Velopack.Packaging.Flow;
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
@@ -8,6 +9,6 @@ internal class LogoutCommandRunner(IVelopackFlowServiceClient Client) : ICommand
|
|||||||
{
|
{
|
||||||
public async Task Run(LogoutOptions options)
|
public async Task Run(LogoutOptions options)
|
||||||
{
|
{
|
||||||
await Client.LogoutAsync(options);
|
await Client.LogoutAsync(options, CancellationToken.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Velopack.Packaging.Abstractions;
|
using System.Threading;
|
||||||
|
using Velopack.Packaging.Abstractions;
|
||||||
using Velopack.Packaging.Flow;
|
using Velopack.Packaging.Flow;
|
||||||
|
|
||||||
namespace Velopack.Vpk.Commands.Flow;
|
namespace Velopack.Vpk.Commands.Flow;
|
||||||
@@ -7,16 +8,17 @@ public class PublishCommandRunner(IVelopackFlowServiceClient Client) : ICommand<
|
|||||||
{
|
{
|
||||||
public async Task Run(PublishOptions options)
|
public async Task Run(PublishOptions options)
|
||||||
{
|
{
|
||||||
|
CancellationToken token = CancellationToken.None;
|
||||||
if (!await Client.LoginAsync(new VelopackLoginOptions() {
|
if (!await Client.LoginAsync(new VelopackLoginOptions() {
|
||||||
AllowCacheCredentials = true,
|
AllowCacheCredentials = true,
|
||||||
AllowDeviceCodeFlow = false,
|
AllowDeviceCodeFlow = false,
|
||||||
AllowInteractiveLogin = false,
|
AllowInteractiveLogin = false,
|
||||||
ApiKey = options.ApiKey,
|
ApiKey = options.ApiKey,
|
||||||
VelopackBaseUrl = options.VelopackBaseUrl
|
VelopackBaseUrl = options.VelopackBaseUrl
|
||||||
})) {
|
}, token)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Client.UploadLatestReleaseAssetsAsync(options.Channel, options.ReleaseDirectory, options.VelopackBaseUrl);
|
await Client.UploadLatestReleaseAssetsAsync(options.Channel, options.ReleaseDirectory, options.VelopackBaseUrl, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user