1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge branch 'development'

This commit is contained in:
SpoinkyNL 2021-02-05 20:51:04 +01:00
commit 81b8f5bf48
10 changed files with 700 additions and 63 deletions

View File

@ -7,6 +7,8 @@ namespace Artemis.Core
{
private bool _valid;
private bool _disposed;
private SKRect _lastBounds;
private SKRect _lastParentBounds;
public SKBitmap? Bitmap { get; private set; }
public SKCanvas? Canvas { get; private set; }
public SKPaint? Paint { get; private set; }
@ -26,6 +28,9 @@ namespace Artemis.Core
if (IsOpen)
throw new ArtemisCoreException("Cannot open render context because it is already open");
if (path.Bounds != _lastBounds || (parent != null && parent.Bounds != _lastParentBounds))
Invalidate();
if (!_valid || Canvas == null)
{
SKRect pathBounds = path.Bounds;
@ -43,6 +48,8 @@ namespace Artemis.Core
Canvas.ClipPath(Path);
_lastParentBounds = parent?.Bounds ?? new SKRect();
_lastBounds = path.Bounds;
_valid = true;
}
@ -58,7 +65,7 @@ namespace Artemis.Core
{
if (_disposed)
throw new ObjectDisposedException("Renderer");
Canvas?.Restore();
Paint?.Dispose();
Paint = null;

View File

@ -253,13 +253,13 @@ namespace Artemis.Core.Services
PluginInfo pluginInfo = CoreJson.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile))!;
if (pluginInfo.Guid == Constants.CorePluginInfo.Guid)
throw new ArtemisPluginException($"Plugin cannot use reserved GUID {pluginInfo.Guid}");
throw new ArtemisPluginException($"Plugin {pluginInfo} cannot use reserved GUID {pluginInfo.Guid}");
lock (_plugins)
{
// Ensure the plugin is not already loaded
if (_plugins.Any(p => p.Guid == pluginInfo.Guid))
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
throw new ArtemisCoreException($"Cannot load plugin {pluginInfo} because it is using a GUID already used by another plugin");
}
// Load the entity and fall back on creating a new one

View File

@ -133,6 +133,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="9.3.0" />
<PackageReference Include="Flurl.Http" Version="3.0.1" />
<PackageReference Include="gong-wpf-dragdrop" Version="2.3.2" />
<PackageReference Include="Hardcodet.NotifyIcon.Wpf.NetCore" Version="1.0.14" />
<PackageReference Include="Humanizer.Core" Version="2.8.26" />

View File

@ -7,18 +7,39 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Margin="16">
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" TextWrapping="Wrap">
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" TextWrapping="Wrap" Margin="0 0 0 20">
Update available
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
Margin="0 20 0 20"
TextWrapping="Wrap">
A new Artemis update is available! 🥳<LineBreak/>
You are currently running build <Run Text="{Binding CurrentBuild, Mode=OneWay}" /> while the latest build is <Run Text="{Binding LatestBuild, Mode=OneWay}" />. <LineBreak/> <LineBreak/>
Updating Artemis will give you the latest bug(fixes), features and improvements.
</TextBlock>
<TextBlock Style="{StaticResource MaterialDesignHeadline6TextBlock}" TextWrapping="Wrap" Margin="0 20">
Changes
</TextBlock>
<StackPanel Visibility="{Binding RetrievingChanges, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
<TextBlock Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
Foreground="{DynamicResource MaterialDesignBodyLight}"
HorizontalAlignment="Center"
Margin="0 10">
Retrieving changes...
</TextBlock>
<ProgressBar IsIndeterminate="True" />
</StackPanel>
<ItemsControl ItemsSource="{Binding Changes}" Visibility="{Binding RetrievingChanges, Converter={x:Static s:BoolToVisibilityConverter.InverseInstance}, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Style="{StaticResource MaterialDesignSubtitle1TextBlock}" Foreground="{DynamicResource MaterialDesignBodyLight}"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 8 0 0">
<Button Style="{StaticResource MaterialDesignFlatButton}"
Focusable="False"

View File

@ -1,31 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.UI.Services;
using Artemis.UI.Services.Models.UpdateService;
using Artemis.UI.Shared.Services;
using Newtonsoft.Json.Linq;
using Stylet;
namespace Artemis.UI.Screens.Settings.Dialogs
{
public class UpdateDialogViewModel : DialogViewModelBase
{
private readonly JToken _buildInfo;
private readonly DevOpsBuild _buildInfo;
private readonly IDialogService _dialogService;
private readonly IMessageService _messageService;
private readonly IUpdateService _updateService;
private bool _canUpdate = true;
private bool _retrievingChanges;
public UpdateDialogViewModel(JToken buildInfo, IUpdateService updateService, IDialogService dialogService)
public UpdateDialogViewModel(DevOpsBuild buildInfo, IUpdateService updateService, IDialogService dialogService, IMessageService messageService)
{
_buildInfo = buildInfo;
_updateService = updateService;
_dialogService = dialogService;
_messageService = messageService;
CurrentBuild = Constants.BuildInfo.BuildNumberDisplay;
LatestBuild = buildInfo?.SelectToken("value[0].buildNumber")?.Value<string>();
LatestBuild = buildInfo.BuildNumber;
Changes = new BindableCollection<string>();
Task.Run(GetBuildChanges);
}
public string CurrentBuild { get; }
public string LatestBuild { get; }
public BindableCollection<string> Changes { get; }
public bool RetrievingChanges
{
get => _retrievingChanges;
set => SetAndNotify(ref _retrievingChanges, value);
}
public bool CanUpdate
{
@ -33,6 +50,41 @@ namespace Artemis.UI.Screens.Settings.Dialogs
set => SetAndNotify(ref _canUpdate, value);
}
private async Task GetBuildChanges()
{
try
{
RetrievingChanges = true;
Task<DevOpsBuild> currentTask = _updateService.GetBuildInfo(1, CurrentBuild);
Task<DevOpsBuild> latestTask = _updateService.GetBuildInfo(1, LatestBuild);
DevOpsBuild current = await currentTask;
DevOpsBuild latest = await latestTask;
if (current != null && latest != null)
{
GitHubDifference difference = await _updateService.GetBuildDifferences(current, latest);
// Only take commits with one parents (no merges)
Changes.Clear();
Changes.AddRange(difference.Commits.Where(c => c.Parents.Count == 1)
.SelectMany(c => c.Commit.Message.Split("\n"))
.Select(m => m.Trim())
.Where(m => !string.IsNullOrWhiteSpace(m))
.OrderBy(m => m)
);
}
}
catch (Exception e)
{
_messageService.ShowMessage($"Failed to retrieve build changes - {e.Message}");
}
finally
{
RetrievingChanges = false;
}
}
public async Task Update()
{
try

View File

@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Artemis.UI.Services.Models.UpdateService
{
public class DevOpsBuilds
{
[JsonProperty("count")]
public long Count { get; set; }
[JsonProperty("value")]
public List<DevOpsBuild> Builds { get; set; }
}
public class DevOpsBuild
{
[JsonProperty("_links")]
public BuildLinks Links { get; set; }
[JsonProperty("properties")]
public Properties Properties { get; set; }
[JsonProperty("tags")]
public List<object> Tags { get; set; }
[JsonProperty("validationResults")]
public List<object> ValidationResults { get; set; }
[JsonProperty("plans")]
public List<Plan> Plans { get; set; }
[JsonProperty("triggerInfo")]
public TriggerInfo TriggerInfo { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("buildNumber")]
public string BuildNumber { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("result")]
public string Result { get; set; }
[JsonProperty("queueTime")]
public DateTimeOffset QueueTime { get; set; }
[JsonProperty("startTime")]
public DateTimeOffset StartTime { get; set; }
[JsonProperty("finishTime")]
public DateTimeOffset FinishTime { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("definition")]
public Definition Definition { get; set; }
[JsonProperty("buildNumberRevision")]
public long BuildNumberRevision { get; set; }
[JsonProperty("project")]
public Project Project { get; set; }
[JsonProperty("uri")]
public string Uri { get; set; }
[JsonProperty("sourceBranch")]
public string SourceBranch { get; set; }
[JsonProperty("sourceVersion")]
public string SourceVersion { get; set; }
[JsonProperty("priority")]
public string Priority { get; set; }
[JsonProperty("reason")]
public string Reason { get; set; }
[JsonProperty("requestedFor")]
public LastChangedBy RequestedFor { get; set; }
[JsonProperty("requestedBy")]
public LastChangedBy RequestedBy { get; set; }
[JsonProperty("lastChangedDate")]
public DateTimeOffset LastChangedDate { get; set; }
[JsonProperty("lastChangedBy")]
public LastChangedBy LastChangedBy { get; set; }
[JsonProperty("orchestrationPlan")]
public Plan OrchestrationPlan { get; set; }
[JsonProperty("logs")]
public Logs Logs { get; set; }
[JsonProperty("repository")]
public Repository Repository { get; set; }
[JsonProperty("keepForever")]
public bool KeepForever { get; set; }
[JsonProperty("retainedByRelease")]
public bool RetainedByRelease { get; set; }
[JsonProperty("triggeredByBuild")]
public object TriggeredByBuild { get; set; }
}
public class Definition
{
[JsonProperty("drafts")]
public List<object> Drafts { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("uri")]
public string Uri { get; set; }
[JsonProperty("path")]
public string Path { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("queueStatus")]
public string QueueStatus { get; set; }
[JsonProperty("revision")]
public long Revision { get; set; }
[JsonProperty("project")]
public Project Project { get; set; }
}
public class Project
{
[JsonProperty("id")]
public Guid Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("state")]
public string State { get; set; }
[JsonProperty("revision")]
public long Revision { get; set; }
[JsonProperty("visibility")]
public string Visibility { get; set; }
[JsonProperty("lastUpdateTime")]
public DateTimeOffset LastUpdateTime { get; set; }
}
public class LastChangedBy
{
[JsonProperty("displayName")]
public string DisplayName { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("_links")]
public LastChangedByLinks Links { get; set; }
[JsonProperty("id")]
public Guid Id { get; set; }
[JsonProperty("uniqueName")]
public object UniqueName { get; set; }
[JsonProperty("imageUrl")]
public object ImageUrl { get; set; }
[JsonProperty("descriptor")]
public string Descriptor { get; set; }
}
public class LastChangedByLinks
{
[JsonProperty("avatar")]
public Badge Avatar { get; set; }
}
public class Badge
{
[JsonProperty("href")]
public Uri Href { get; set; }
}
public class BuildLinks
{
[JsonProperty("self")]
public Badge Self { get; set; }
[JsonProperty("web")]
public Badge Web { get; set; }
[JsonProperty("sourceVersionDisplayUri")]
public Badge SourceVersionDisplayUri { get; set; }
[JsonProperty("timeline")]
public Badge Timeline { get; set; }
[JsonProperty("badge")]
public Badge Badge { get; set; }
}
public class Logs
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
}
public class Plan
{
[JsonProperty("planId")]
public Guid PlanId { get; set; }
}
public class Properties
{
}
public class Repository
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("clean")]
public object Clean { get; set; }
[JsonProperty("checkoutSubmodules")]
public bool CheckoutSubmodules { get; set; }
}
public class TriggerInfo
{
[JsonProperty("ci.sourceBranch")]
public string CiSourceBranch { get; set; }
[JsonProperty("ci.sourceSha")]
public string CiSourceSha { get; set; }
[JsonProperty("ci.message")]
public string CiMessage { get; set; }
[JsonProperty("ci.triggerRepository")]
public string CiTriggerRepository { get; set; }
}
}

View File

@ -0,0 +1,243 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Artemis.UI.Services.Models.UpdateService
{
public class GitHubDifference
{
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("html_url")]
public Uri HtmlUrl { get; set; }
[JsonProperty("permalink_url")]
public Uri PermalinkUrl { get; set; }
[JsonProperty("diff_url")]
public Uri DiffUrl { get; set; }
[JsonProperty("patch_url")]
public Uri PatchUrl { get; set; }
[JsonProperty("base_commit")]
public BaseCommitClass BaseCommit { get; set; }
[JsonProperty("merge_base_commit")]
public BaseCommitClass MergeBaseCommit { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("ahead_by")]
public long AheadBy { get; set; }
[JsonProperty("behind_by")]
public long BehindBy { get; set; }
[JsonProperty("total_commits")]
public long TotalCommits { get; set; }
[JsonProperty("commits")]
public List<BaseCommitClass> Commits { get; set; }
[JsonProperty("files")]
public List<File> Files { get; set; }
}
public class BaseCommitClass
{
[JsonProperty("sha")]
public string Sha { get; set; }
[JsonProperty("node_id")]
public string NodeId { get; set; }
[JsonProperty("commit")]
public BaseCommitCommit Commit { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("html_url")]
public Uri HtmlUrl { get; set; }
[JsonProperty("comments_url")]
public Uri CommentsUrl { get; set; }
[JsonProperty("author")]
public BaseCommitAuthor Author { get; set; }
[JsonProperty("committer")]
public BaseCommitAuthor Committer { get; set; }
[JsonProperty("parents")]
public List<Parent> Parents { get; set; }
}
public class BaseCommitAuthor
{
[JsonProperty("login")]
public string Login { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("node_id")]
public string NodeId { get; set; }
[JsonProperty("avatar_url")]
public Uri AvatarUrl { get; set; }
[JsonProperty("gravatar_id")]
public string GravatarId { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("html_url")]
public Uri HtmlUrl { get; set; }
[JsonProperty("followers_url")]
public Uri FollowersUrl { get; set; }
[JsonProperty("following_url")]
public string FollowingUrl { get; set; }
[JsonProperty("gists_url")]
public string GistsUrl { get; set; }
[JsonProperty("starred_url")]
public string StarredUrl { get; set; }
[JsonProperty("subscriptions_url")]
public Uri SubscriptionsUrl { get; set; }
[JsonProperty("organizations_url")]
public Uri OrganizationsUrl { get; set; }
[JsonProperty("repos_url")]
public Uri ReposUrl { get; set; }
[JsonProperty("events_url")]
public string EventsUrl { get; set; }
[JsonProperty("received_events_url")]
public Uri ReceivedEventsUrl { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("site_admin")]
public bool SiteAdmin { get; set; }
}
public class BaseCommitCommit
{
[JsonProperty("author")]
public PurpleAuthor Author { get; set; }
[JsonProperty("committer")]
public PurpleAuthor Committer { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("tree")]
public Tree Tree { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("comment_count")]
public long CommentCount { get; set; }
[JsonProperty("verification")]
public Verification Verification { get; set; }
}
public class PurpleAuthor
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("date")]
public DateTimeOffset Date { get; set; }
}
public class Tree
{
[JsonProperty("sha")]
public string Sha { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
}
public class Verification
{
[JsonProperty("verified")]
public bool Verified { get; set; }
[JsonProperty("reason")]
public string Reason { get; set; }
[JsonProperty("signature")]
public string Signature { get; set; }
[JsonProperty("payload")]
public string Payload { get; set; }
}
public class Parent
{
[JsonProperty("sha")]
public string Sha { get; set; }
[JsonProperty("url")]
public Uri Url { get; set; }
[JsonProperty("html_url")]
public Uri HtmlUrl { get; set; }
}
public class File
{
[JsonProperty("sha")]
public string Sha { get; set; }
[JsonProperty("filename")]
public string Filename { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("additions")]
public long Additions { get; set; }
[JsonProperty("deletions")]
public long Deletions { get; set; }
[JsonProperty("changes")]
public long Changes { get; set; }
[JsonProperty("blob_url")]
public Uri BlobUrl { get; set; }
[JsonProperty("raw_url")]
public Uri RawUrl { get; set; }
[JsonProperty("contents_url")]
public Uri ContentsUrl { get; set; }
[JsonProperty("patch")]
public string Patch { get; set; }
[JsonProperty("previous_filename", NullValueHandling = NullValueHandling.Ignore)]
public string PreviousFilename { get; set; }
}
}

View File

@ -4,16 +4,21 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.Exceptions;
using Artemis.UI.Screens.Settings.Dialogs;
using Artemis.UI.Services.Models.UpdateService;
using Artemis.UI.Shared.Services;
using Flurl;
using Flurl.Http;
using MaterialDesignThemes.Wpf;
using Newtonsoft.Json.Linq;
using Serilog;
using File = System.IO.File;
namespace Artemis.UI.Services
{
@ -53,12 +58,8 @@ namespace Artemis.UI.Services
{
_logger.Information("Checking for updates");
JToken buildInfo = await GetBuildInfo(1);
JToken buildNumberToken = buildInfo?.SelectToken("value[0].buildNumber");
if (buildNumberToken == null)
throw new ArtemisUIException("Failed to find build number at \"value[0].buildNumber\"");
double buildNumber = buildNumberToken.Value<double>();
DevOpsBuild buildInfo = await GetBuildInfo(1);
double buildNumber = double.Parse(buildInfo.BuildNumber, CultureInfo.InvariantCulture);
string buildNumberDisplay = buildNumber.ToString(CultureInfo.InvariantCulture);
_logger.Information("Latest build is {buildNumber}, we're running {localBuildNumber}", buildNumberDisplay, Constants.BuildInfo.BuildNumberDisplay);
@ -91,21 +92,16 @@ namespace Artemis.UI.Services
return true;
}
private async Task OfferUpdate(JToken buildInfo)
private async Task OfferUpdate(DevOpsBuild buildInfo)
{
await _dialogService.ShowDialog<UpdateDialogViewModel>(new Dictionary<string, object> {{"buildInfo", buildInfo}});
}
public async Task<bool> IsUpdateAvailable()
{
JToken buildInfo = await GetBuildInfo(1);
JToken buildNumberToken = buildInfo?.SelectToken("value[0].buildNumber");
if (buildNumberToken != null)
return buildNumberToken.Value<double>() > Constants.BuildInfo.BuildNumber;
_logger.Warning("IsUpdateAvailable: Failed to find build number at \"value[0].buildNumber\"");
return false;
DevOpsBuild buildInfo = await GetBuildInfo(1);
double buildNumber = double.Parse(buildInfo.BuildNumber, CultureInfo.InvariantCulture);
return buildNumber > Constants.BuildInfo.BuildNumber;
}
public async Task ApplyUpdate()
@ -113,8 +109,7 @@ namespace Artemis.UI.Services
_logger.Information("ApplyUpdate: Applying update");
// Ensure the installer is up-to-date, get installer build info
JToken buildInfo = await GetBuildInfo(6);
JToken finishTimeToken = buildInfo?.SelectToken("value[0].finishTime");
DevOpsBuild buildInfo = await GetBuildInfo(6);
string installerPath = Path.Combine(Constants.ApplicationFolder, "Installer", "Artemis.Installer.exe");
// Always update installer if it is missing ^^
@ -123,9 +118,7 @@ namespace Artemis.UI.Services
// Compare the creation date of the installer with the build date and update if needed
else
{
if (finishTimeToken == null)
_logger.Warning("ApplyUpdate: Failed to find build finish time at \"value[0].finishTime\", not updating the installer.");
else if (File.GetLastWriteTime(installerPath) < finishTimeToken.Value<DateTime>())
if (File.GetLastWriteTime(installerPath) < buildInfo.FinishTime)
await UpdateInstaller();
}
@ -146,7 +139,47 @@ namespace Artemis.UI.Services
else
throw;
}
}
public async Task<DevOpsBuild> GetBuildInfo(int buildDefinition, string buildNumber = null)
{
Url request = ApiUrl.AppendPathSegments("build", "builds")
.SetQueryParam("definitions", buildDefinition)
.SetQueryParam("resultFilter", "succeeded")
.SetQueryParam("$top", 1)
.SetQueryParam("api-version", "6.1-preview.6");
if (buildNumber != null)
request = request.SetQueryParam("buildNumber", buildNumber);
try
{
DevOpsBuilds result = await request.GetJsonAsync<DevOpsBuilds>();
try
{
return result.Builds.FirstOrDefault();
}
catch (Exception e)
{
_logger.Warning(e, "GetBuildInfo: Failed to retrieve build info JSON");
return null;
}
}
catch (FlurlHttpException e)
{
_logger.Warning("GetBuildInfo: Getting build info, request returned {statusCode}", e.StatusCode);
return null;
}
}
public async Task<GitHubDifference> GetBuildDifferences(DevOpsBuild a, DevOpsBuild b)
{
return await "https://api.github.com"
.AppendPathSegments("repos", "Artemis-RGB", "Artemis", "compare")
.AppendPathSegment(a.SourceVersion + "..." + b.SourceVersion)
.WithHeader("User-Agent", "Artemis 2")
.WithHeader("Accept", "application/vnd.github.v3+json")
.GetJsonAsync<GitHubDifference>();
}
private async Task UpdateInstaller()
@ -170,35 +203,6 @@ namespace Artemis.UI.Services
await httpResponseMessage.Content.CopyToAsync(fs);
}
private async Task<JObject> GetBuildInfo(int buildDefinition)
{
string latestBuildUrl = ApiUrl + $"build/builds?definitions={buildDefinition}&resultFilter=succeeded&$top=1&api-version=6.1-preview.6";
_logger.Debug("GetBuildInfo: Getting build info from {latestBuildUrl}", latestBuildUrl);
// Make the request
using HttpClient client = new();
HttpResponseMessage httpResponseMessage = await client.GetAsync(latestBuildUrl);
// Ensure it returned correctly
if (!httpResponseMessage.IsSuccessStatusCode)
{
_logger.Warning("GetBuildInfo: Getting build info, request returned {statusCode}", httpResponseMessage.StatusCode);
return null;
}
// Parse the response
string response = await httpResponseMessage.Content.ReadAsStringAsync();
try
{
return JObject.Parse(response);
}
catch (Exception e)
{
_logger.Warning(e, "GetBuildInfo: Failed to retrieve build info JSON");
return null;
}
}
#region Event handlers
private void CheckForUpdatesOnSettingChanged(object sender, EventArgs e)
@ -225,6 +229,8 @@ namespace Artemis.UI.Services
Task<bool> OfferUpdateIfFound();
Task<bool> IsUpdateAvailable();
Task<DevOpsBuild> GetBuildInfo(int buildDefinition, string buildNumber = null);
Task<GitHubDifference> GetBuildDifferences(DevOpsBuild a, DevOpsBuild b);
Task ApplyUpdate();
}
}

View File

@ -1,6 +1,6 @@
{
"BuildId": 0,
"BuildNumber": 13370101.1,
"SourceBranch": "local",
"SourceVersion": "local"
"BuildId": 442,
"BuildNumber": 20210130.3,
"SourceBranch": "refs/heads/master",
"SourceVersion": "b29ab064ae46d93141f31afaa8ee3ea9063c6263"
}

View File

@ -8,6 +8,17 @@
"resolved": "9.3.0",
"contentHash": "C44l6Ih+YwpED/TsXfl6LIq6Z4wLXahstnr6T70uUg1Hs7/bLBKKAo9Nl0sLhVjDE8TA+fF+O3IM4nDrwabcSQ=="
},
"Flurl.Http": {
"type": "Direct",
"requested": "[3.0.1, )",
"resolved": "3.0.1",
"contentHash": "wt4RrmYOPWu8v0sjuuSfhYBFzjfrCz4nJP48Kw2HFGssq0U6pMBPFHcL3zbsBFALJipAjgRET5mf+0Xz4ZnZpQ==",
"dependencies": {
"Flurl": "3.0.1",
"Newtonsoft.Json": "12.0.2",
"System.Text.Encoding.CodePages": "4.5.1"
}
},
"gong-wpf-dragdrop": {
"type": "Direct",
"requested": "[2.3.2, )",
@ -209,6 +220,11 @@
"Unosquare.Swan.Lite": "3.0.0"
}
},
"Flurl": {
"type": "Transitive",
"resolved": "3.0.1",
"contentHash": "i7CuPSikVroBaWG8sPvO707Ex9C6BP5+r4JufKNU1FGMmiFgLJvNo1ttUg6ZiXIzUNknvIb1VUTIO9iEDucibg=="
},
"HidSharp": {
"type": "Transitive",
"resolved": "2.1.0",
@ -1029,6 +1045,11 @@
"Microsoft.NETCore.Targets": "1.1.0"
}
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "4.5.2",
"contentHash": "wprSFgext8cwqymChhrBLu62LMg/1u92bU+VOwyfBimSPVFXtsNqEWC92Pf9ofzJFlk4IHmJA75EDJn1b2goAQ=="
},
"System.Runtime.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",
@ -1255,6 +1276,15 @@
"System.Runtime": "4.3.0"
}
},
"System.Text.Encoding.CodePages": {
"type": "Transitive",
"resolved": "4.5.1",
"contentHash": "4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==",
"dependencies": {
"Microsoft.NETCore.Platforms": "2.1.2",
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
}
},
"System.Text.Encoding.Extensions": {
"type": "Transitive",
"resolved": "4.3.0",