diff --git a/.github/workflows/manual-release.yml b/.github/workflows/manual-release.yml
index a8aa93a..011a291 100644
--- a/.github/workflows/manual-release.yml
+++ b/.github/workflows/manual-release.yml
@@ -27,9 +27,24 @@ jobs:
bash .agent/setup.sh
bash .agent/quick-build.sh
+ - name: Install Velopack CLI
+ run: dotnet tool install -g vpk
+
+ - name: Publish application
+ run: dotnet publish OpenpilotToolkit/OpenpilotToolkit.csproj -p:PublishProfile=FolderProfile -c Release /p:EnableWindowsTargeting=true
+
+ - name: Download Previous Release for Deltas
+ continue-on-error: true
+ run: |
+ export PATH="$PATH:$HOME/.dotnet/tools"
+ vpk download github --repoUrl https://github.com/spektor56/openpilottoolkit -o ReleasePackages
+
- name: Package application
run: |
- zip -r OpenpilotToolkit-${{ github.event.inputs.version }}.zip OpenpilotToolkit/bin/Release/net10.0-windows10.0.19041/win-x64/
+ export PATH="$PATH:$HOME/.dotnet/tools"
+ VERSION="${{ github.event.inputs.version }}"
+ VERSION="${VERSION#v}"
+ vpk pack -u OpenpilotToolkit -v $VERSION -p OpenpilotToolkit/bin/publish/ -o ReleasePackages -i OpenpilotToolkit/Resources/ic_launcher-web.ico -s OpenpilotToolkit/Resources/ssh.png
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
@@ -37,6 +52,6 @@ jobs:
tag_name: ${{ github.event.inputs.version }}
name: Release ${{ github.event.inputs.version }}
body: ${{ github.event.inputs.release_notes }}
- files: ./OpenpilotToolkit-${{ github.event.inputs.version }}.zip
+ files: ./ReleasePackages/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/OpenpilotToolkit/OpenpilotToolkit.csproj b/OpenpilotToolkit/OpenpilotToolkit.csproj
index 808e022..b5d7a7d 100644
--- a/OpenpilotToolkit/OpenpilotToolkit.csproj
+++ b/OpenpilotToolkit/OpenpilotToolkit.csproj
@@ -618,6 +618,7 @@
+
diff --git a/OpenpilotToolkit/OpenpilotToolkitForm.cs b/OpenpilotToolkit/OpenpilotToolkitForm.cs
index 50da07a..e9b021f 100644
--- a/OpenpilotToolkit/OpenpilotToolkitForm.cs
+++ b/OpenpilotToolkit/OpenpilotToolkitForm.cs
@@ -40,6 +40,8 @@
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.Measure;
+using Velopack;
+using Velopack.Sources;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.SkiaSharpView.Painting.Effects;
using LiveChartsCore.SkiaSharpView.SKCharts;
@@ -330,11 +332,90 @@ private async void Form1_Load(object sender, EventArgs e)
await ScanDevices().ConfigureAwait(false);
//Look for updates
+ _ = Task.Run(CheckForUpdatesAsync);
//TODO: implement self-updater
//var test = await _githubClient.Repository.Release.GetLatest("spektor56", "openpilotToolkit");
}
+ private async Task CheckForUpdatesAsync()
+ {
+ try
+ {
+ var mgr = new UpdateManager(new GithubSource("https://github.com/spektor56/openpilottoolkit", null, false));
+
+ if (!mgr.IsInstalled)
+ {
+ try
+ {
+ var release = await _githubClient.Repository.Release.GetLatest("spektor56", "openpilotToolkit");
+ if (release != null)
+ {
+ var currentVersionStr = Assembly.GetExecutingAssembly().GetName().Version.ToString();
+ if (Version.TryParse(currentVersionStr, out var currentVersion) &&
+ Version.TryParse(release.TagName.TrimStart('v'), out var latestVersion) &&
+ latestVersion > currentVersion)
+ {
+ Invoke(new MethodInvoker(() =>
+ {
+ var result = ToolkitMessageDialog.ShowDialog($"An update to version {release.TagName} is available, but this version of OpenpilotToolkit was not installed via the auto-updating installer. Would you like to open the download page to install the new version?", this, MessageBoxButtons.YesNo);
+ if (result == DialogResult.Yes)
+ {
+ Process.Start(new ProcessStartInfo
+ {
+ FileName = "https://github.com/spektor56/openpilottoolkit/releases/latest",
+ UseShellExecute = true
+ });
+ }
+ }));
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Serilog.Log.Error(ex, "Failed to check for non-Velopack updates from GitHub");
+ }
+ return;
+ }
+
+ var newVersion = await mgr.CheckForUpdatesAsync();
+ if (newVersion == null)
+ {
+ return; // No update available
+ }
+
+ Invoke(new MethodInvoker(() =>
+ {
+ var result = ToolkitMessageDialog.ShowDialog($"An update to version {newVersion.TargetFullRelease.Version} is available. Would you like to update now?", this, MessageBoxButtons.YesNo);
+ if (result == DialogResult.Yes)
+ {
+ Task.Run(async () =>
+ {
+ try
+ {
+ Invoke(new MethodInvoker(() =>
+ {
+ var message = new MaterialSnackBar("Downloading update, the application will restart automatically...", "OK", false);
+ message.Show(this);
+ }));
+ await mgr.DownloadUpdatesAsync(newVersion);
+ mgr.ApplyUpdatesAndRestart(newVersion);
+ }
+ catch (Exception ex)
+ {
+ Serilog.Log.Error(ex, "Failed to download/apply update");
+ Invoke(new MethodInvoker(() => ToolkitMessageDialog.ShowDialog("Failed to apply update: " + ex.Message, this)));
+ }
+ });
+ }
+ }));
+ }
+ catch (Exception ex)
+ {
+ Serilog.Log.Error(ex, "Error checking for updates.");
+ }
+ }
+
private async void FileWatcherOnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Changed && _watchedFiles.Count > 0)
diff --git a/OpenpilotToolkit/Program.cs b/OpenpilotToolkit/Program.cs
index cb8ef2b..596dbc0 100644
--- a/OpenpilotToolkit/Program.cs
+++ b/OpenpilotToolkit/Program.cs
@@ -11,6 +11,7 @@
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
+using Velopack;
namespace OpenpilotToolkit
{
@@ -26,6 +27,15 @@ static class Program
[STAThread]
public static int Main(string[] args)
{
+ try
+ {
+ VelopackApp.Build().Run();
+ }
+ catch (Exception)
+ {
+ // Ignore errors related to Velopack initialization
+ }
+
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.SetHighDpiMode(HighDpiMode.DpiUnaware);
Application.EnableVisualStyles();