mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-21 16:14:28 +08:00
fix.继续修ci,ci怎么天天炸
This commit is contained in:
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@@ -32,6 +32,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
@@ -66,12 +67,15 @@ jobs:
|
||||
libx11-6 libxrandr2 libxinerama1 \
|
||||
libxi6 libxcursor1 libxext6 \
|
||||
libxrender1 libxkbcommon-x11-0 \
|
||||
clang zlib1g-dev
|
||||
clang zlib1g-dev \
|
||||
libportaudio2 libasound2 \
|
||||
libwebkit2gtk-4.1-dev
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
@@ -98,10 +102,14 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Install dependencies
|
||||
run: brew install portaudio
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
@@ -132,6 +140,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Pack SDK and template packages
|
||||
shell: pwsh
|
||||
|
||||
1
.github/workflows/code-quality.yml
vendored
1
.github/workflows/code-quality.yml
vendored
@@ -31,6 +31,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
|
||||
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@@ -88,6 +88,7 @@ jobs:
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
@@ -515,12 +516,15 @@ jobs:
|
||||
libx11-6 libxrandr2 libxinerama1 \
|
||||
libxi6 libxcursor1 libxext6 \
|
||||
libxrender1 libxkbcommon-x11-0 \
|
||||
clang zlib1g-dev
|
||||
clang zlib1g-dev \
|
||||
libportaudio2 libasound2 \
|
||||
libwebkit2gtk-4.1-dev
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
@@ -707,10 +711,14 @@ jobs:
|
||||
submodules: recursive
|
||||
ref: ${{ needs.prepare.outputs.checkout_ref }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: brew install portaudio
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
dotnet-quality: 'preview'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore ${{ env.Solution_Name }}
|
||||
|
||||
23
LanMountainDesktop.Launcher/AppJsonContext.cs
Normal file
23
LanMountainDesktop.Launcher/AppJsonContext.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using LanMountainDesktop.Launcher.Models;
|
||||
using LanMountainDesktop.Launcher.Services;
|
||||
using LanMountainDesktop.Shared.Contracts.Launcher;
|
||||
|
||||
namespace LanMountainDesktop.Launcher;
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
||||
[JsonSerializable(typeof(SignedFileMap))]
|
||||
[JsonSerializable(typeof(UpdateFileEntry))]
|
||||
[JsonSerializable(typeof(SnapshotMetadata))]
|
||||
[JsonSerializable(typeof(AppVersionInfo))]
|
||||
[JsonSerializable(typeof(StartupProgressMessage))]
|
||||
[JsonSerializable(typeof(LauncherResult))]
|
||||
[JsonSerializable(typeof(HostDiscoveryConfig))]
|
||||
[JsonSerializable(typeof(PluginManifest))]
|
||||
[JsonSerializable(typeof(PendingUpgrade))]
|
||||
[JsonSerializable(typeof(List<PendingUpgrade>))]
|
||||
[JsonSerializable(typeof(GitHubRelease))]
|
||||
[JsonSerializable(typeof(GitHubAsset))]
|
||||
[JsonSerializable(typeof(List<GitHubRelease>))]
|
||||
internal sealed partial class AppJsonContext : JsonSerializerContext;
|
||||
@@ -56,7 +56,11 @@
|
||||
<!-- 允许 IL 警告 -->
|
||||
<TrimmerSingleWarn>false</TrimmerSingleWarn>
|
||||
|
||||
<!-- FluentAvaloniaUI 需要:启用反射序列化(AOT 兼容模式) -->
|
||||
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
||||
<!-- AOT 模式下禁用反射式 JSON 序列化,强制使用 Source Generator -->
|
||||
<!-- 之前设置为 true 与 AOT 矛盾,导致 IL2026/IL3050 警告和运行时失败 -->
|
||||
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
|
||||
|
||||
<!-- 启用 ISerializable 支持(部分库需要) -->
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -149,10 +149,7 @@ internal static class Commands
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
var json = JsonSerializer.Serialize(result, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true
|
||||
});
|
||||
var json = JsonSerializer.Serialize(result, AppJsonContext.Default.LauncherResult);
|
||||
await File.WriteAllTextAsync(fullPath, json, Encoding.UTF8).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ internal sealed class DeploymentLocator
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(snapshotFile);
|
||||
var snapshot = System.Text.Json.JsonSerializer.Deserialize<SnapshotMetadata>(json);
|
||||
var snapshot = System.Text.Json.JsonSerializer.Deserialize(json, AppJsonContext.Default.SnapshotMetadata);
|
||||
if (snapshot != null && !string.IsNullOrEmpty(snapshot.SourceDirectory))
|
||||
{
|
||||
if (Directory.Exists(snapshot.SourceDirectory))
|
||||
@@ -445,7 +445,7 @@ internal sealed class DeploymentLocator
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(versionFile);
|
||||
var info = JsonSerializer.Deserialize<AppVersionInfo>(json);
|
||||
var info = JsonSerializer.Deserialize(json, AppJsonContext.Default.AppVersionInfo);
|
||||
if (info is not null)
|
||||
{
|
||||
return info;
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace LanMountainDesktop.Launcher.Services;
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(configPath);
|
||||
var config = JsonSerializer.Deserialize<HostDiscoveryConfig>(json);
|
||||
var config = JsonSerializer.Deserialize(json, AppJsonContext.Default.HostDiscoveryConfig);
|
||||
if (config?.HostPath != null && File.Exists(config.HostPath))
|
||||
{
|
||||
return config.HostPath;
|
||||
@@ -617,13 +617,13 @@ namespace LanMountainDesktop.Launcher.Services;
|
||||
public required string AppRoot { get; set; }
|
||||
public required HostDiscoveryOptions Options { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发现配置文件
|
||||
/// </summary>
|
||||
private class HostDiscoveryConfig
|
||||
{
|
||||
public string? HostPath { get; set; }
|
||||
public List<string>? AdditionalPaths { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发现配置文件
|
||||
/// </summary>
|
||||
internal class HostDiscoveryConfig
|
||||
{
|
||||
public string? HostPath { get; set; }
|
||||
public List<string>? AdditionalPaths { get; set; }
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class LauncherIpcServer : IDisposable
|
||||
|
||||
// 3. 反序列化并回调
|
||||
var json = System.Text.Encoding.UTF8.GetString(payloadBuffer, 0, payloadLength);
|
||||
var message = JsonSerializer.Deserialize<StartupProgressMessage>(json);
|
||||
var message = JsonSerializer.Deserialize(json, AppJsonContext.Default.StartupProgressMessage);
|
||||
if (message is not null)
|
||||
{
|
||||
_onProgress(message);
|
||||
|
||||
@@ -73,7 +73,7 @@ internal sealed class PluginInstallerService
|
||||
using var stream = entries[0].Open();
|
||||
using var reader = new StreamReader(stream);
|
||||
var json = reader.ReadToEnd();
|
||||
var manifest = JsonSerializer.Deserialize<PluginManifest>(json);
|
||||
var manifest = JsonSerializer.Deserialize(json, AppJsonContext.Default.PluginManifest);
|
||||
if (manifest == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to deserialize manifest from '{packagePath}'.");
|
||||
|
||||
@@ -29,7 +29,7 @@ internal sealed class PluginUpgradeQueueService
|
||||
}
|
||||
|
||||
var text = File.ReadAllText(pendingPath);
|
||||
var pending = JsonSerializer.Deserialize<List<PendingUpgrade>>(text) ?? [];
|
||||
var pending = JsonSerializer.Deserialize(text, AppJsonContext.Default.ListPendingUpgrade) ?? [];
|
||||
var failures = new List<string>();
|
||||
var succeeded = new List<PendingUpgrade>();
|
||||
|
||||
@@ -63,10 +63,7 @@ internal sealed class PluginUpgradeQueueService
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(pendingPath, JsonSerializer.Serialize(remaining, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true
|
||||
}));
|
||||
File.WriteAllText(pendingPath, JsonSerializer.Serialize(remaining, AppJsonContext.Default.ListPendingUpgrade));
|
||||
}
|
||||
|
||||
return new LauncherResult
|
||||
@@ -79,19 +76,19 @@ internal sealed class PluginUpgradeQueueService
|
||||
: $"Applied {succeeded.Count} upgrades, failed: {string.Join(", ", failures)}."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private sealed record PendingUpgrade(
|
||||
string PluginId,
|
||||
string SourcePackagePath,
|
||||
string TargetVersion,
|
||||
DateTimeOffset CreatedAt)
|
||||
internal sealed record PendingUpgrade(
|
||||
string PluginId,
|
||||
string SourcePackagePath,
|
||||
string TargetVersion,
|
||||
DateTimeOffset CreatedAt)
|
||||
{
|
||||
public bool IsValid()
|
||||
{
|
||||
public bool IsValid()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(PluginId) &&
|
||||
!string.IsNullOrWhiteSpace(SourcePackagePath) &&
|
||||
!string.IsNullOrWhiteSpace(TargetVersion) &&
|
||||
File.Exists(SourcePackagePath);
|
||||
}
|
||||
return !string.IsNullOrWhiteSpace(PluginId) &&
|
||||
!string.IsNullOrWhiteSpace(SourcePackagePath) &&
|
||||
!string.IsNullOrWhiteSpace(TargetVersion) &&
|
||||
File.Exists(SourcePackagePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ internal sealed class UpdateCheckService
|
||||
private readonly string _repoOwner;
|
||||
private readonly string _repoName;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly JsonSerializerOptions _jsonOptions;
|
||||
|
||||
public UpdateCheckService(string repoOwner, string repoName)
|
||||
{
|
||||
@@ -24,12 +23,6 @@ internal sealed class UpdateCheckService
|
||||
_httpClient = new HttpClient();
|
||||
_httpClient.DefaultRequestHeaders.Add("User-Agent", "LanMountainDesktop-Launcher");
|
||||
_httpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.github+json");
|
||||
|
||||
_jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -97,7 +90,7 @@ internal sealed class UpdateCheckService
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync(cancellationToken);
|
||||
var releases = JsonSerializer.Deserialize<List<GitHubRelease>>(json, _jsonOptions);
|
||||
var releases = JsonSerializer.Deserialize(json, AppJsonContext.Default.ListGitHubRelease);
|
||||
|
||||
return releases?.Select(r => new ReleaseInfo
|
||||
{
|
||||
@@ -131,38 +124,38 @@ internal sealed class UpdateCheckService
|
||||
var cleaned = ParseVersionString(versionString);
|
||||
return Version.TryParse(cleaned, out var version) ? version : new Version(0, 0, 0);
|
||||
}
|
||||
|
||||
// GitHub API 响应模型
|
||||
private sealed class GitHubRelease
|
||||
{
|
||||
[JsonPropertyName("tag_name")]
|
||||
public string? TagName { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("prerelease")]
|
||||
public bool Prerelease { get; set; }
|
||||
|
||||
[JsonPropertyName("published_at")]
|
||||
public DateTime PublishedAt { get; set; }
|
||||
|
||||
[JsonPropertyName("body")]
|
||||
public string? Body { get; set; }
|
||||
|
||||
[JsonPropertyName("assets")]
|
||||
public List<GitHubAsset>? Assets { get; set; }
|
||||
}
|
||||
|
||||
private sealed class GitHubAsset
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("browser_download_url")]
|
||||
public string? BrowserDownloadUrl { get; set; }
|
||||
|
||||
[JsonPropertyName("size")]
|
||||
public long Size { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub API 响应模型
|
||||
internal sealed class GitHubRelease
|
||||
{
|
||||
[JsonPropertyName("tag_name")]
|
||||
public string? TagName { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("prerelease")]
|
||||
public bool Prerelease { get; set; }
|
||||
|
||||
[JsonPropertyName("published_at")]
|
||||
public DateTime PublishedAt { get; set; }
|
||||
|
||||
[JsonPropertyName("body")]
|
||||
public string? Body { get; set; }
|
||||
|
||||
[JsonPropertyName("assets")]
|
||||
public List<GitHubAsset>? Assets { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class GitHubAsset
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("browser_download_url")]
|
||||
public string? BrowserDownloadUrl { get; set; }
|
||||
|
||||
[JsonPropertyName("size")]
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ internal sealed class UpdateEngineService
|
||||
}
|
||||
|
||||
var fileMapText = File.ReadAllText(fileMapPath);
|
||||
var fileMap = JsonSerializer.Deserialize<SignedFileMap>(fileMapText);
|
||||
var fileMap = JsonSerializer.Deserialize(fileMapText, AppJsonContext.Default.SignedFileMap);
|
||||
if (fileMap is null)
|
||||
{
|
||||
return Failed("update.check", "invalid_manifest", "files.json is invalid.");
|
||||
@@ -137,7 +137,7 @@ internal sealed class UpdateEngineService
|
||||
}
|
||||
|
||||
var fileMapText = await File.ReadAllTextAsync(fileMapPath);
|
||||
var fileMap = JsonSerializer.Deserialize<SignedFileMap>(fileMapText);
|
||||
var fileMap = JsonSerializer.Deserialize(fileMapText, AppJsonContext.Default.SignedFileMap);
|
||||
if (fileMap is null || fileMap.Files.Count == 0)
|
||||
{
|
||||
return Failed("update.apply", "invalid_manifest", "No update file entries were found.");
|
||||
@@ -438,7 +438,7 @@ internal sealed class UpdateEngineService
|
||||
return Failed("update.rollback", "no_snapshot", "No snapshot found.");
|
||||
}
|
||||
|
||||
var snapshot = JsonSerializer.Deserialize<SnapshotMetadata>(File.ReadAllText(snapshotPath));
|
||||
var snapshot = JsonSerializer.Deserialize(File.ReadAllText(snapshotPath), AppJsonContext.Default.SnapshotMetadata);
|
||||
if (snapshot is null || string.IsNullOrWhiteSpace(snapshot.SourceDirectory))
|
||||
{
|
||||
return Failed("update.rollback", "invalid_snapshot", "Invalid snapshot metadata.");
|
||||
@@ -656,10 +656,7 @@ internal sealed class UpdateEngineService
|
||||
|
||||
private static void SaveSnapshot(string path, SnapshotMetadata snapshot)
|
||||
{
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(snapshot, new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true
|
||||
}));
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(snapshot, AppJsonContext.Default.SnapshotMetadata));
|
||||
}
|
||||
|
||||
private static LauncherResult Failed(string stage, string code, string message)
|
||||
|
||||
Reference in New Issue
Block a user