mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-07-15 15:19:57 +00:00
Improve update procedure (#496)
* Improve update procedure * Change release procedure * Fix gh release * Fix release tag * Change release structure to support folders * Revert zip file changes to make them backwards compatible * Change path * Make launcher not contain the entire dependencies * Add downtime after API rate limit * Add rate limit checking before create release * Enumerate through rates * Adjust rate limit call * Change to create release as draft * Add update logic based on azure blobs * Fix publish * Create zip * Disable CD pipeline for prs * Increment version * Fix tests
This commit is contained in:
@@ -83,7 +83,7 @@ jobs:
|
||||
echo "::set-env name=Version::$version"
|
||||
|
||||
- name: Create publish launcher files
|
||||
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:PublishTrimmed --self-contained true -o .\Publish
|
||||
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
|
||||
env:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
@@ -93,7 +93,7 @@ jobs:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
- name: Create publish extractor files
|
||||
run: dotnet publish .\Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
|
||||
run: dotnet publish .\Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
|
||||
env:
|
||||
RuntimeIdentifier: win-${{ matrix.targetplatform }}
|
||||
|
||||
@@ -103,7 +103,13 @@ jobs:
|
||||
.\Scripts\BuildRelease.ps1 -version $env:Version
|
||||
shell: pwsh
|
||||
|
||||
- name: Publish release
|
||||
- name: Publish blob files
|
||||
run: |
|
||||
Write-Host $env
|
||||
.\Scripts\PushFilesToBlobStorage.ps1 -version $env:Version -sourcePath .\Publish\ -connectionString "${{ secrets.BLOBSTORAGE_CONNECTIONSTRING }}"
|
||||
shell: pwsh
|
||||
|
||||
- name: Create release draft
|
||||
uses: Xotl/cool-github-releases@v1.1.8
|
||||
with:
|
||||
mode: update
|
||||
@@ -113,6 +119,14 @@ jobs:
|
||||
github_token: ${{ env.GITHUB_TOKEN }}
|
||||
replace_assets: true
|
||||
body_mrkdwn: ${{ env.Changelog }}
|
||||
isDraft: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish release
|
||||
run: |
|
||||
gh release edit v${{ env.Version }} --draft=false
|
||||
shell: powershell
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<Platforms>AnyCPU;x86</Platforms>
|
||||
<PublishSingleFile>True</PublishSingleFile>
|
||||
<Self-Contained>True</Self-Contained>
|
||||
<PublishReadyToRun>True</PublishReadyToRun>
|
||||
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,33 +1,116 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
static void RenderProgressBar(int currentStep, int totalSteps, int barSize)
|
||||
{
|
||||
Console.CursorLeft = 0; // Reset cursor position to the start of the line
|
||||
Console.Write("["); // Start of the progress bar
|
||||
|
||||
double pctComplete = (double)currentStep / totalSteps;
|
||||
int chars = (int)Math.Round(pctComplete * barSize);
|
||||
|
||||
Console.Write(new string('=', chars)); // The 'completed' part of the bar
|
||||
Console.Write(new string(' ', barSize - chars)); // The 'remaining' part of the bar
|
||||
|
||||
Console.Write("] ");
|
||||
Console.Write($"{pctComplete:P0}"); // Display the percentage completed
|
||||
}
|
||||
|
||||
const string tempFile = "tempfile.zip";
|
||||
const string updatePkg = "update.pkg";
|
||||
const string executableName = "Daybreak.exe";
|
||||
Console.Title = "Daybreak Installer";
|
||||
Console.WriteLine("Starting installation...");
|
||||
if (File.Exists(tempFile) is false)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Unable to find launcher package. Aborting installation");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
while (Process.GetProcesses().Where(p => p.ProcessName == "Daybreak").FirstOrDefault()?.HasExited is false)
|
||||
{
|
||||
Console.WriteLine($"Detected Daybreak process is still running. Waiting 5s and retrying");
|
||||
await Task.Delay(5000);
|
||||
}
|
||||
|
||||
Console.WriteLine("Unpacking files...");
|
||||
try
|
||||
{
|
||||
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
|
||||
}
|
||||
catch
|
||||
if (File.Exists(updatePkg))
|
||||
{
|
||||
Console.WriteLine("Unpacking files...");
|
||||
|
||||
using var fileStream = new FileStream(updatePkg, FileMode.Open);
|
||||
var sizeBuffer = new byte[4];
|
||||
var copyBuffer = new byte[1024];
|
||||
while (fileStream.Position < fileStream.Length - 1)
|
||||
{
|
||||
/*
|
||||
* For each file downloaded, we write to the package the following:
|
||||
* Size of the name string
|
||||
* UTF-8 encoded name string
|
||||
* Size of the relative path string
|
||||
* UTF-8 encoded relative path string
|
||||
* Size of the binary
|
||||
* Binary data
|
||||
*/
|
||||
|
||||
await fileStream.ReadAsync(sizeBuffer, 0, 4);
|
||||
var fileNameSize = BitConverter.ToInt32(sizeBuffer, 0);
|
||||
var fileNameBuffer = new byte[fileNameSize];
|
||||
await fileStream.ReadAsync(fileNameBuffer, 0, fileNameSize);
|
||||
var fileName = Encoding.UTF8.GetString(fileNameBuffer);
|
||||
|
||||
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
|
||||
|
||||
await fileStream.ReadAsync(sizeBuffer, 0, 4);
|
||||
var relativePathSize = BitConverter.ToInt32(sizeBuffer, 0);
|
||||
var relativePathBuffer = new byte[relativePathSize];
|
||||
await fileStream.ReadAsync(relativePathBuffer, 0, relativePathSize);
|
||||
var relativePath = Encoding.UTF8.GetString(relativePathBuffer);
|
||||
|
||||
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
|
||||
|
||||
await fileStream.ReadAsync(sizeBuffer, 0, 4);
|
||||
var binarySize = BitConverter.ToInt32(sizeBuffer, 0);
|
||||
var fileInfo = new FileInfo(relativePath);
|
||||
fileInfo.Directory!.Create();
|
||||
using var destinationStream = new FileStream(relativePath, FileMode.Create);
|
||||
while(binarySize > 0)
|
||||
{
|
||||
var toRead = Math.Min(binarySize, copyBuffer.Length);
|
||||
await fileStream.ReadAsync(copyBuffer, 0, toRead);
|
||||
await destinationStream.WriteAsync(copyBuffer, 0, toRead);
|
||||
binarySize -= toRead;
|
||||
|
||||
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
|
||||
}
|
||||
}
|
||||
|
||||
fileStream.Close();
|
||||
fileStream.Dispose();
|
||||
File.Delete(updatePkg);
|
||||
}
|
||||
else if (File.Exists(tempFile))
|
||||
{
|
||||
Console.WriteLine("Unpacking files...");
|
||||
try
|
||||
{
|
||||
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting package");
|
||||
try
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Unable to find launcher package. Aborting installation");
|
||||
Console.ReadKey();
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting browser caches");
|
||||
@@ -46,16 +129,6 @@ catch(Exception)
|
||||
{
|
||||
}
|
||||
|
||||
Console.WriteLine("Deleting package");
|
||||
try
|
||||
{
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Launching application");
|
||||
var process = new Process
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{41AE
|
||||
Scripts\BuildRelease.ps1 = Scripts\BuildRelease.ps1
|
||||
Scripts\CompareVersions.ps1 = Scripts\CompareVersions.ps1
|
||||
Scripts\GetBuildVersion.ps1 = Scripts\GetBuildVersion.ps1
|
||||
Scripts\PushFilesToBlobStorage.ps1 = Scripts\PushFilesToBlobStorage.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0E30DDA0-2111-4E6C-851E-01DC34124FC2}"
|
||||
@@ -31,7 +32,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
.github\CODEOWNERS = .github\CODEOWNERS
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Daybreak.7ZipExtractor", "Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj", "{CA60F9AC-A496-4DB6-970E-ECE73B051C05}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Daybreak.7ZipExtractor", "Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj", "{CA60F9AC-A496-4DB6-970E-ECE73B051C05}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@@ -49,4 +49,8 @@ public sealed class LauncherOptions
|
||||
[JsonProperty(nameof(PersistentLogging))]
|
||||
[OptionName(Name = "Persistent Logging", Description = "If true, the launcher will save logs in the local database. Otherwise, the launcher will only keep logs in a memory cache")]
|
||||
public bool PersistentLogging { get; set; } = false;
|
||||
|
||||
[JsonProperty(nameof(BetaUpdate))]
|
||||
[OptionName(Name = "Beta Update", Description = "If true, the launcher will use the new update procedure")]
|
||||
public bool BetaUpdate { get; set; } = false;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<Platforms>AnyCPU;x86;x64</Platforms>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
|
||||
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
|
||||
<Version>0.9.8.152</Version>
|
||||
<Version>0.9.8.153</Version>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -4,8 +4,11 @@ using Daybreak.Models.Github;
|
||||
using Daybreak.Models.Progress;
|
||||
using Daybreak.Services.Downloads;
|
||||
using Daybreak.Services.Notifications;
|
||||
using Daybreak.Services.Privilege;
|
||||
using Daybreak.Services.Registry;
|
||||
using Daybreak.Services.Updater.Models;
|
||||
using Daybreak.Services.Updater.PostUpdate;
|
||||
using Daybreak.Views;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -13,11 +16,16 @@ using System.Configuration;
|
||||
using System.Core.Extensions;
|
||||
using System.Diagnostics;
|
||||
using System.Extensions;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static Daybreak.Utils.NativeMethods;
|
||||
using Version = Daybreak.Models.Versioning.Version;
|
||||
|
||||
namespace Daybreak.Services.Updater;
|
||||
@@ -28,12 +36,15 @@ internal sealed class ApplicationUpdater : IApplicationUpdater
|
||||
private const string UpdatedKey = "LauncherUpdating";
|
||||
private const string TempFile = "tempfile.zip";
|
||||
private const string VersionTag = "{VERSION}";
|
||||
private const string FileTag = "{FILE}";
|
||||
private const string RefTagPrefix = "/refs/tags";
|
||||
private const string VersionListUrl = "https://api.github.com/repos/AlexMacocian/Daybreak/git/refs/tags";
|
||||
private const string Url = "https://github.com/AlexMacocian/Daybreak/releases/latest";
|
||||
private const string DownloadUrl = $"https://github.com/AlexMacocian/Daybreak/releases/download/{VersionTag}/Daybreak{VersionTag}.zip";
|
||||
private const string BlobStorageUrl = $"https://daybreak.blob.core.windows.net/{VersionTag}/{FileTag}";
|
||||
|
||||
private readonly CancellationTokenSource updateCancellationTokenSource = new();
|
||||
private readonly IPrivilegeManager privilegeManager;
|
||||
private readonly INotificationService notificationService;
|
||||
private readonly IRegistryService registryService;
|
||||
private readonly IDownloadService downloadService;
|
||||
@@ -45,6 +56,7 @@ internal sealed class ApplicationUpdater : IApplicationUpdater
|
||||
public Version CurrentVersion { get; }
|
||||
|
||||
public ApplicationUpdater(
|
||||
IPrivilegeManager privilegeManager,
|
||||
INotificationService notificationService,
|
||||
IRegistryService registryService,
|
||||
IDownloadService downloadService,
|
||||
@@ -53,6 +65,7 @@ internal sealed class ApplicationUpdater : IApplicationUpdater
|
||||
IHttpClient<ApplicationUpdater> httpClient,
|
||||
ILogger<ApplicationUpdater> logger)
|
||||
{
|
||||
this.privilegeManager = privilegeManager.ThrowIfNull();
|
||||
this.notificationService = notificationService.ThrowIfNull();
|
||||
this.registryService = registryService.ThrowIfNull();
|
||||
this.downloadService = downloadService.ThrowIfNull();
|
||||
@@ -78,17 +91,36 @@ internal sealed class ApplicationUpdater : IApplicationUpdater
|
||||
|
||||
public async Task<bool> DownloadUpdate(Version version, UpdateStatus updateStatus)
|
||||
{
|
||||
updateStatus.CurrentStep = DownloadStatus.InitializingDownload;
|
||||
var uri = DownloadUrl.Replace(VersionTag, version.ToString());
|
||||
if (await this.downloadService.DownloadFile(uri, TempFile, updateStatus) is false)
|
||||
if (!this.privilegeManager.AdminPrivileges)
|
||||
{
|
||||
this.logger.LogError("Failed to download update file");
|
||||
this.privilegeManager.RequestAdminPrivileges<LauncherView>("Daybreak needs Administrator privileges in order to update");
|
||||
return false;
|
||||
}
|
||||
|
||||
updateStatus.CurrentStep = UpdateStatus.PendingRestart;
|
||||
this.logger.LogInformation("Downloaded update file");
|
||||
return true;
|
||||
if (version.HasPrefix is false)
|
||||
{
|
||||
version.HasPrefix = true;
|
||||
}
|
||||
|
||||
if (!this.liveOptions.Value.BetaUpdate)
|
||||
{
|
||||
return await this.DownloadUpdateInternalLegacy(version, updateStatus);
|
||||
}
|
||||
|
||||
var maybeMetadataResponse = await this.httpClient.GetAsync(
|
||||
BlobStorageUrl
|
||||
.Replace(VersionTag, version.ToString().Replace(".", "-"))
|
||||
.Replace(FileTag, "Metadata.json"));
|
||||
if (maybeMetadataResponse.IsSuccessStatusCode)
|
||||
{
|
||||
var metaData = await maybeMetadataResponse.Content.ReadFromJsonAsync<List<Metadata>>();
|
||||
if (metaData is not null)
|
||||
{
|
||||
return await this.DownloadUpdateInternalBlob(metaData, version, updateStatus);
|
||||
}
|
||||
}
|
||||
|
||||
return await this.DownloadUpdateInternalLegacy(version, updateStatus);
|
||||
}
|
||||
|
||||
public async Task<bool> DownloadLatestUpdate(UpdateStatus updateStatus)
|
||||
@@ -177,6 +209,78 @@ internal sealed class ApplicationUpdater : IApplicationUpdater
|
||||
{
|
||||
}
|
||||
|
||||
private async Task<bool> DownloadUpdateInternalBlob(List<Metadata> metadata, Version version, UpdateStatus updateStatus)
|
||||
{
|
||||
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.DownloadUpdateInternalBlob), version.ToString());
|
||||
// Exclude daybreak packed files
|
||||
var daybreakArchive = $"daybreak{version}.zip";
|
||||
var filesToDownload = metadata
|
||||
.Where(m => m.Name != daybreakArchive)
|
||||
.Where(m =>
|
||||
{
|
||||
var fileInfo = new FileInfo(m.RelativePath!);
|
||||
return !fileInfo.Exists || fileInfo.Length != m.Size;
|
||||
})
|
||||
.ToList();
|
||||
|
||||
updateStatus.CurrentStep = DownloadStatus.InitializingDownload;
|
||||
using var packageStream = new FileStream("update.pkg", FileMode.Create);
|
||||
var downloaded = 0d;
|
||||
var downloadBuffer = new byte[1024];
|
||||
var sizeToDownload = (double)filesToDownload.Sum(m => m.Size);
|
||||
var sw = Stopwatch.StartNew();
|
||||
foreach (var file in filesToDownload)
|
||||
{
|
||||
var downloadUrl = BlobStorageUrl.Replace(VersionTag, version.ToString().Replace('.', '-')).Replace(FileTag, file.RelativePath);
|
||||
var response = await this.httpClient.GetAsync(downloadUrl);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
scopedLogger.LogError($"Error {response.StatusCode} when downloading {file.RelativePath}");
|
||||
return false;
|
||||
}
|
||||
|
||||
var fileNameBytes = Encoding.UTF8.GetBytes(file.Name!);
|
||||
var relativePathBytes = Encoding.UTF8.GetBytes(file.RelativePath!);
|
||||
await packageStream.WriteAsync(BitConverter.GetBytes(fileNameBytes.Length));
|
||||
await packageStream.WriteAsync(fileNameBytes);
|
||||
await packageStream.WriteAsync(BitConverter.GetBytes(relativePathBytes.Length));
|
||||
await packageStream.WriteAsync(relativePathBytes);
|
||||
await packageStream.WriteAsync(BitConverter.GetBytes(file.Size));
|
||||
var downloadStream = await response.Content.ReadAsStreamAsync();
|
||||
var fileSize = file.Size;
|
||||
while (fileSize > 0)
|
||||
{
|
||||
var toGet = Math.Min(fileSize, 1024);
|
||||
await downloadStream.ReadAsync(downloadBuffer, 0, toGet);
|
||||
fileSize -= toGet;
|
||||
await packageStream.WriteAsync(downloadBuffer, 0, toGet);
|
||||
|
||||
downloaded += toGet;
|
||||
var etaMillis = sw.ElapsedMilliseconds * (sizeToDownload - downloaded) / downloaded;
|
||||
updateStatus.CurrentStep = DownloadStatus.Downloading(downloaded / sizeToDownload, TimeSpan.FromMilliseconds(etaMillis));
|
||||
}
|
||||
}
|
||||
|
||||
scopedLogger.LogInformation($"Prepared update package at {Path.GetFullPath("update.pkg")}");
|
||||
updateStatus.CurrentStep = UpdateStatus.PendingRestart;
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> DownloadUpdateInternalLegacy(Version version, UpdateStatus updateStatus)
|
||||
{
|
||||
updateStatus.CurrentStep = DownloadStatus.InitializingDownload;
|
||||
var uri = DownloadUrl.Replace(VersionTag, version.ToString());
|
||||
if (await this.downloadService.DownloadFile(uri, TempFile, updateStatus) is false)
|
||||
{
|
||||
this.logger.LogError("Failed to download update file");
|
||||
return false;
|
||||
}
|
||||
|
||||
updateStatus.CurrentStep = UpdateStatus.PendingRestart;
|
||||
this.logger.LogInformation("Downloaded update file");
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<Version?> GetLatestVersion()
|
||||
{
|
||||
using var response = await this.httpClient.GetAsync(Url);
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Daybreak.Services.Updater.Models;
|
||||
internal sealed class Metadata
|
||||
{
|
||||
[JsonProperty(nameof(RelativePath))]
|
||||
public string? RelativePath { get; set; }
|
||||
|
||||
[JsonProperty(nameof(Name))]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonProperty(nameof(Size))]
|
||||
public int Size { get; set; }
|
||||
}
|
||||
@@ -5,4 +5,8 @@
|
||||
Custom launcher for Guildwars.
|
||||
Requires webview2 runtime https://go.microsoft.com/fwlink/p/?LinkId=2124703.
|
||||
|
||||
Download:
|
||||
- Go to [Releases](https://github.com/AlexMacocian/Daybreak/releases/latest)
|
||||
- Download daybreakv[VERSION].zip, where [VERSION] is the version of the release
|
||||
|
||||
Please check the [wiki](https://github.com/AlexMacocian/Daybreak/wiki) for project description and features
|
||||
|
||||
@@ -3,17 +3,36 @@ Param(
|
||||
[string]$version
|
||||
) #end param
|
||||
|
||||
function Get-FileMetadata {
|
||||
param (
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
$fileInfo = Get-Item $Path
|
||||
|
||||
# Temporarily change current location to the folder path
|
||||
$currentLocation = Get-Location
|
||||
Set-Location -Path .\Publish
|
||||
$relativePath = Resolve-Path -Path $Path -Relative
|
||||
Set-Location -Path $currentLocation
|
||||
return @{
|
||||
Name = $fileInfo.Name
|
||||
Size = $fileInfo.Length
|
||||
RelativePath = $relativePath.trim(".\\")
|
||||
}
|
||||
}
|
||||
|
||||
$zipPath = "Publish\daybreakv$version.zip"
|
||||
Write-Output "Deleting pdb file"
|
||||
Remove-item .\Publish\Daybreak.pdb
|
||||
Remove-item .\Publish\Daybreak.Installer.pdb
|
||||
Remove-item .\Publish\Daybreak.7ZipExtractor.pdb
|
||||
Move-Item -Path .\Publish\Daybreak.Installer.exe -Destination .\Publish\Daybreak.Installer.Temp.exe
|
||||
$zipPath = "Publish\daybreakv$version.zip"
|
||||
Write-Output "Compressing binaries to $zipPath"
|
||||
|
||||
Compress-Archive .\Publish\* $zipPath -Force
|
||||
Write-Output "Cleaning up files"
|
||||
foreach ($file in Get-ChildItem -Path .\Publish -Exclude *.zip -Recurse -ErrorAction SilentlyContinue)
|
||||
{
|
||||
Write-Output "Removing $file"
|
||||
Remove-item $file -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$files = Get-ChildItem -Path .\Publish -Recurse -File
|
||||
$metadata = $files | ForEach-Object { Get-FileMetadata $_.FullName }
|
||||
$json = $metadata | ConvertTo-Json
|
||||
$json | Out-File -FilePath ".\Publish\Metadata.json"
|
||||
Write-Host "Metadata written to .\Publish\Metadata.json"
|
||||
@@ -0,0 +1,20 @@
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$version,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$connectionString,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$sourcePath
|
||||
)
|
||||
|
||||
# Create a new blob container
|
||||
$containerName = "v$($version.ToLower().Replace('.', '-'))" # Container names must be lowercase
|
||||
Write-Host "Creating container $($containerName)"
|
||||
az storage container create --name $containerName --connection-string $connectionString
|
||||
|
||||
Write-Host "Uploading files"
|
||||
# Upload all files from the source path to the blob container
|
||||
az storage blob upload-batch --destination $containerName --source $sourcePath --connection-string $connectionString
|
||||
|
||||
Write-Host "Setting public access to container"
|
||||
az storage container set-permission --name $containerName --public-access blob --connection-string $connectionString
|
||||
Reference in New Issue
Block a user