diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index f9b3edea2..c2188b913 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -24,6 +24,11 @@ jobs:
steps:
- uses: actions/checkout@v4
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3.2.0
+ with:
+ dotnet-version: 8.0.x
+
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 7562447fc..41930943b 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -21,7 +21,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 6.0.201
+ dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
@@ -37,9 +37,9 @@ jobs:
shell: bash
run: |
mkdir -p artifacts/bin
- mv out/windows/Installer.Windows/bin/Release/net472/win-x86 artifacts/bin/
- cp out/windows/Installer.Windows/bin/Release/net472/win-x86.sym/* artifacts/bin/win-x86/
- mv out/windows/Installer.Windows/bin/Release/net472/gcm*.exe artifacts/
+ mv out/windows/Installer.Windows/bin/Release/net8.0/win-x86 artifacts/bin/
+ cp out/windows/Installer.Windows/bin/Release/net8.0/win-x86.sym/* artifacts/bin/win-x86/
+ mv out/windows/Installer.Windows/bin/Release/net8.0/gcm*.exe artifacts/
- name: Upload artifacts
uses: actions/upload-artifact@v3
@@ -61,7 +61,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 6.0.201
+ dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
@@ -102,7 +102,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 6.0.201
+ dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 82ec3b1b6..ce21cf277 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,7 +37,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Build
run: |
@@ -152,7 +152,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Build
run: |
@@ -192,7 +192,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Build with signed payload
run: |
@@ -200,7 +200,7 @@ jobs:
/p:PayloadPath=$env:GITHUB_WORKSPACE\payload /p:NoLayout=true `
--configuration=WindowsRelease
mkdir installers
- Move-Item -Path .\out\windows\Installer.Windows\bin\Release\net472\*.exe `
+ Move-Item -Path .\out\windows\Installer.Windows\bin\Release\net8.0\*.exe `
-Destination $env:GITHUB_WORKSPACE\installers
- name: Sign installers with Azure Code Signing
@@ -238,7 +238,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Build
run: dotnet build --configuration=LinuxRelease
@@ -316,7 +316,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Build .NET tool
run: |
@@ -410,7 +410,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Package tool
run: |
@@ -523,7 +523,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Download artifacts
uses: actions/download-artifact@v3
@@ -593,7 +593,7 @@ jobs:
- name: Set up .NET
uses: actions/setup-dotnet@v3.2.0
with:
- dotnet-version: 7.0.x
+ dotnet-version: 8.0.x
- name: Download artifacts
uses: actions/download-artifact@v3
diff --git a/.vscode/launch.json b/.vscode/launch.json
index af72a8e27..d9b004b86 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -10,7 +10,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/out/shared/Git-Credential-Manager/bin/Debug/net7.0/git-credential-manager.dll",
+ "program": "${workspaceFolder}/out/shared/Git-Credential-Manager/bin/Debug/net8.0/git-credential-manager.dll",
"args": ["get"],
"cwd": "${workspaceFolder}/out/shared/Git-Credential-Manager",
"console": "integratedTerminal",
@@ -22,7 +22,7 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
- "program": "${workspaceFolder}/out/shared/Git-Credential-Manager/bin/Debug/net7.0/git-credential-manager.dll",
+ "program": "${workspaceFolder}/out/shared/Git-Credential-Manager/bin/Debug/net8.0/git-credential-manager.dll",
"args": ["store"],
"cwd": "${workspaceFolder}/out/shared/Git-Credential-Manager",
"console": "integratedTerminal",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index e47892848..c559b17b8 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -56,7 +56,7 @@
"type": "shell",
"group": "test",
"args": [
- "~/.nuget/packages/reportgenerator/*/*/net7.0/ReportGenerator.dll",
+ "~/.nuget/packages/reportgenerator/*/*/net8.0/ReportGenerator.dll",
"-reports:${workspaceFolder}/**/TestResults/**/coverage.cobertura.xml",
"-targetdir:${workspaceFolder}/out/code-coverage"
],
@@ -71,7 +71,7 @@
"type": "shell",
"group": "test",
"args": [
- "${env:USERROFILE}/.nuget/packages/reportgenerator/*/*/net7.0/ReportGenerator.dll",
+ "${env:USERROFILE}/.nuget/packages/reportgenerator/*/*/net8.0/ReportGenerator.dll",
"-reports:${workspaceFolder}/**/TestResults/**/coverage.cobertura.xml",
"-targetdir:${workspaceFolder}/out/code-coverage"
],
diff --git a/Directory.Build.props b/Directory.Build.props
index 8c94238ca..d8c53e0bb 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -26,10 +26,4 @@
true
-
-
- 7.0.2
-
-
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 72d4712e7..690a82653 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -33,4 +33,9 @@
+
+
+ $(NoWarn);CA1416
+
+
diff --git a/build/GCM.MSBuild.csproj b/build/GCM.MSBuild.csproj
index 02f5a8444..3df4909e6 100644
--- a/build/GCM.MSBuild.csproj
+++ b/build/GCM.MSBuild.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
diff --git a/docs/development.md b/docs/development.md
index 31350192a..75f9fd0cf 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -40,9 +40,9 @@ To build from the command line, run:
dotnet build -c WindowsDebug
```
-You can find a copy of the installer .exe file in `out\windows\Installer.Windows\bin\Debug\net472`.
+You can find a copy of the installer .exe file in `out\windows\Installer.Windows\bin\Debug\net8.0`.
-The flat binaries can also be found in `out\windows\Payload.Windows\bin\Debug\net472\win-x86`.
+The flat binaries can also be found in `out\windows\Payload.Windows\bin\Debug\net8.0\win-x86`.
### Linux
@@ -209,13 +209,13 @@ HTML reports can be generated using ReportGenerator, this should be installed
during the build process, from the command line:
```shell
-dotnet ~/.nuget/packages/reportgenerator/*/*/net7.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage
+dotnet ~/.nuget/packages/reportgenerator/*/*/net8.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage
```
or
```shell
-dotnet {$env:USERPROFILE}/.nuget/packages/reportgenerator/*/*/net7.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage
+dotnet {$env:USERPROFILE}/.nuget/packages/reportgenerator/*/*/net8.0/ReportGenerator.dll -reports:./**/TestResults/**/coverage.cobertura.xml -targetdir:./out/code-coverage
```
Or via VSCode Terminal/Run Task:
diff --git a/src/linux/Packaging.Linux/Packaging.Linux.csproj b/src/linux/Packaging.Linux/Packaging.Linux.csproj
index 362ffc230..8b9755c78 100644
--- a/src/linux/Packaging.Linux/Packaging.Linux.csproj
+++ b/src/linux/Packaging.Linux/Packaging.Linux.csproj
@@ -3,7 +3,7 @@
- net7.0
+ net8.0
false
diff --git a/src/linux/Packaging.Linux/install-from-source.sh b/src/linux/Packaging.Linux/install-from-source.sh
index 98fe7bc4d..c6a7a10fc 100755
--- a/src/linux/Packaging.Linux/install-from-source.sh
+++ b/src/linux/Packaging.Linux/install-from-source.sh
@@ -157,7 +157,7 @@ case "$distribution" in
# Install dotnet packages and dependencies if needed.
if [ -z "$(verify_existing_dotnet_installation)" ]; then
# First try to use native feeds (Ubuntu 22.04 and later).
- if ! apt_install dotnet7; then
+ if ! apt_install dotnet8; then
# If the native feeds fail, we fall back to
# packages.microsoft.com. We begin by adding the dotnet package
# repository/signing key.
diff --git a/src/linux/Packaging.Linux/layout.sh b/src/linux/Packaging.Linux/layout.sh
index 5f3ba8ca8..0f174636b 100755
--- a/src/linux/Packaging.Linux/layout.sh
+++ b/src/linux/Packaging.Linux/layout.sh
@@ -38,7 +38,7 @@ GCM_SRC="$SRC/shared/Git-Credential-Manager"
PROJ_OUT="$OUT/linux/Packaging.Linux"
# Build parameters
-FRAMEWORK=net7.0
+FRAMEWORK=net8.0
RUNTIME=linux-x64
# Perform pre-execution checks
@@ -74,7 +74,6 @@ $DOTNET_ROOT/dotnet publish "$GCM_SRC" \
--framework="$FRAMEWORK" \
--runtime="$RUNTIME" \
--self-contained \
- -p:PublishSingleFile=true \
--output="$(make_absolute "$PAYLOAD")" || exit 1
# Collect symbols
diff --git a/src/osx/Installer.Mac/Installer.Mac.csproj b/src/osx/Installer.Mac/Installer.Mac.csproj
index e46022374..daabd20d4 100644
--- a/src/osx/Installer.Mac/Installer.Mac.csproj
+++ b/src/osx/Installer.Mac/Installer.Mac.csproj
@@ -3,7 +3,7 @@
- net7.0
+ net8.0
false
diff --git a/src/osx/Installer.Mac/layout.sh b/src/osx/Installer.Mac/layout.sh
index 544b7e106..293c3a43a 100755
--- a/src/osx/Installer.Mac/layout.sh
+++ b/src/osx/Installer.Mac/layout.sh
@@ -21,10 +21,9 @@ SRC="$ROOT/src"
OUT="$ROOT/out"
INSTALLER_SRC="$SRC/osx/Installer.Mac"
GCM_SRC="$SRC/shared/Git-Credential-Manager"
-GCM_UI_SRC="$SRC/shared/Git-Credential-Manager.UI.Avalonia"
# Build parameters
-FRAMEWORK=net7.0
+FRAMEWORK=net8.0
# Parse script arguments
for i in "$@"
diff --git a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj
index 0e3c94c22..d5d08797c 100644
--- a/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj
+++ b/src/shared/Atlassian.Bitbucket.Tests/Atlassian.Bitbucket.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
true
latest
diff --git a/src/shared/Atlassian.Bitbucket/Atlassian.Bitbucket.csproj b/src/shared/Atlassian.Bitbucket/Atlassian.Bitbucket.csproj
index af8285c72..d50785fa7 100644
--- a/src/shared/Atlassian.Bitbucket/Atlassian.Bitbucket.csproj
+++ b/src/shared/Atlassian.Bitbucket/Atlassian.Bitbucket.csproj
@@ -1,8 +1,7 @@
- net7.0
- net7.0;net472
+ net8.0
Atlassian.Bitbucket
Atlassian.Bitbucket
false
@@ -13,10 +12,6 @@
-
-
-
-
diff --git a/src/shared/Atlassian.Bitbucket/BitbucketJsonSerializerContext.cs b/src/shared/Atlassian.Bitbucket/BitbucketJsonSerializerContext.cs
new file mode 100644
index 000000000..08436a42d
--- /dev/null
+++ b/src/shared/Atlassian.Bitbucket/BitbucketJsonSerializerContext.cs
@@ -0,0 +1,15 @@
+using System.Text.Json.Serialization;
+
+namespace Atlassian.Bitbucket;
+
+[JsonSourceGenerationOptions(
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNameCaseInsensitive = true
+)]
+[JsonSerializable(typeof(BitbucketTokenEndpointResponseJson))]
+[JsonSerializable(typeof(Cloud.UserInfo), TypeInfoPropertyName = "Cloud_UserInfo")]
+[JsonSerializable(typeof(DataCenter.UserInfo), TypeInfoPropertyName = "DataCenter_UserInfo")]
+[JsonSerializable(typeof(DataCenter.LoginOptions))]
+internal partial class BitbucketJsonSerializerContext : JsonSerializerContext
+{
+}
diff --git a/src/shared/Atlassian.Bitbucket/BitbucketOAuth2Client.cs b/src/shared/Atlassian.Bitbucket/BitbucketOAuth2Client.cs
index 1ca23d0f5..2311de44d 100644
--- a/src/shared/Atlassian.Bitbucket/BitbucketOAuth2Client.cs
+++ b/src/shared/Atlassian.Bitbucket/BitbucketOAuth2Client.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
+using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using GitCredentialManager;
@@ -42,7 +43,7 @@ protected override bool TryCreateTokenEndpointResult(string json, out OAuth2Toke
// We override the token endpoint response parsing because the Bitbucket authority returns
// the non-standard 'scopes' property for the list of scopes, rather than the (optional)
// 'scope' (note the singular vs plural) property as outlined in the standard.
- if (TryDeserializeJson(json, out BitbucketTokenEndpointResponseJson jsonObj))
+ if (TryDeserializeJson(json, BitbucketJsonSerializerContext.Default, out BitbucketTokenEndpointResponseJson jsonObj))
{
result = jsonObj.ToResult();
return true;
diff --git a/src/shared/Atlassian.Bitbucket/Cloud/BitbucketRestApi.cs b/src/shared/Atlassian.Bitbucket/Cloud/BitbucketRestApi.cs
index 94021e14d..c32f0aa9a 100644
--- a/src/shared/Atlassian.Bitbucket/Cloud/BitbucketRestApi.cs
+++ b/src/shared/Atlassian.Bitbucket/Cloud/BitbucketRestApi.cs
@@ -43,11 +43,7 @@ public async Task> GetUserInformationAsync(string userN
if (response.IsSuccessStatusCode)
{
- var obj = JsonSerializer.Deserialize(json,
- new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true,
- });
+ UserInfo obj = JsonSerializer.Deserialize(json, BitbucketJsonSerializerContext.Default.Cloud_UserInfo);
return new RestApiResult(response.StatusCode, obj);
}
diff --git a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs
index 159229885..d6a128906 100644
--- a/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs
+++ b/src/shared/Atlassian.Bitbucket/DataCenter/BitbucketRestApi.cs
@@ -107,12 +107,7 @@ public async Task> GetAuthenticationMethodsAsync()
if (response.IsSuccessStatusCode)
{
- var loginOptions = JsonSerializer.Deserialize(json,
- new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true,
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
- });
+ LoginOptions loginOptions = JsonSerializer.Deserialize(json, BitbucketJsonSerializerContext.Default.LoginOptions);
if (loginOptions.Results.Any(r => "LOGIN_FORM".Equals(r.Type)))
{
@@ -151,4 +146,4 @@ private Uri ApiUri
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/shared/Atlassian.Bitbucket/UI/Views/CredentialsView.axaml b/src/shared/Atlassian.Bitbucket/UI/Views/CredentialsView.axaml
index f74161a5c..126d0ebff 100644
--- a/src/shared/Atlassian.Bitbucket/UI/Views/CredentialsView.axaml
+++ b/src/shared/Atlassian.Bitbucket/UI/Views/CredentialsView.axaml
@@ -5,6 +5,8 @@
xmlns:vm="clr-namespace:Atlassian.Bitbucket.UI.ViewModels;assembly=Atlassian.Bitbucket"
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ x:DataType="vm:CredentialsViewModel"
+ x:CompileBindings="True"
x:Class="Atlassian.Bitbucket.UI.Views.CredentialsView">
diff --git a/src/shared/Core.Tests/Core.Tests.csproj b/src/shared/Core.Tests/Core.Tests.csproj
index 4ee2d350e..db045a83b 100644
--- a/src/shared/Core.Tests/Core.Tests.csproj
+++ b/src/shared/Core.Tests/Core.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
true
latest
diff --git a/src/shared/Core/Authentication/AuthenticationBase.cs b/src/shared/Core/Authentication/AuthenticationBase.cs
index 03e4d8ca6..ca3be4173 100644
--- a/src/shared/Core/Authentication/AuthenticationBase.cs
+++ b/src/shared/Core/Authentication/AuthenticationBase.cs
@@ -60,11 +60,7 @@ protected internal virtual async Task> InvokeHelperA
// Write the standard input to the process if we have any to write
if (standardInput is not null)
{
-#if NETFRAMEWORK
- await standardInput.BaseStream.CopyToAsync(process.StandardInput.BaseStream);
-#else
await standardInput.BaseStream.CopyToAsync(process.StandardInput.BaseStream, ct);
-#endif
process.StandardInput.Close();
}
diff --git a/src/shared/Core/Authentication/MicrosoftAuthentication.cs b/src/shared/Core/Authentication/MicrosoftAuthentication.cs
index b39cc1a73..da6a979be 100644
--- a/src/shared/Core/Authentication/MicrosoftAuthentication.cs
+++ b/src/shared/Core/Authentication/MicrosoftAuthentication.cs
@@ -15,10 +15,7 @@
using GitCredentialManager.UI.ViewModels;
using GitCredentialManager.UI.Views;
using Microsoft.Identity.Client.AppConfig;
-
-#if NETFRAMEWORK
using Microsoft.Identity.Client.Broker;
-#endif
namespace GitCredentialManager.Authentication
{
@@ -501,7 +498,6 @@ private async Task CreatePublicClientApplicationAsync(
// to save on the distribution size of the .NET builds (no need for MSALRuntime bits).
if (enableBroker)
{
-#if NETFRAMEWORK
appBuilder.WithBroker(
new BrokerOptions(BrokerOptions.OperatingSystems.Windows)
{
@@ -509,7 +505,6 @@ private async Task CreatePublicClientApplicationAsync(
MsaPassthrough = msaPt,
}
);
-#endif
}
IPublicClientApplication app = appBuilder.Build();
@@ -801,7 +796,6 @@ public HttpClient GetHttpClient()
public bool CanUseBroker()
{
-#if NETFRAMEWORK
// We only support the broker on Windows 10+ and in an interactive session
if (!Context.SessionManager.IsDesktopSession || !PlatformUtils.IsWindowsBrokerSupported())
{
@@ -820,34 +814,27 @@ public bool CanUseBroker()
}
return defaultValue;
-#else
- // OS broker requires .NET Framework right now until we migrate to .NET 5.0 (net5.0-windows10.x.y.z)
- return false;
-#endif
}
private bool CanUseEmbeddedWebView()
{
- // If we're in an interactive session and on .NET Framework then MSAL can show the WinForms-based embedded UI
-#if NETFRAMEWORK
- return Context.SessionManager.IsDesktopSession;
-#else
- return false;
-#endif
+ // If we're in an interactive session and on Windows then MSAL can show the WinForms-based embedded UI
+ return PlatformUtils.IsWindows() && Context.SessionManager.IsDesktopSession;
}
private void EnsureCanUseEmbeddedWebView()
{
-#if NETFRAMEWORK
if (!Context.SessionManager.IsDesktopSession)
{
throw new Trace2InvalidOperationException(Context.Trace2,
"Embedded web view is not available without a desktop session.");
}
-#else
- throw new Trace2InvalidOperationException(Context.Trace2,
- "Embedded web view is not available on .NET Core.");
-#endif
+
+ if (!PlatformUtils.IsWindows())
+ {
+ throw new Trace2InvalidOperationException(Context.Trace2,
+ "Embedded web view is only available on Windows.");
+ }
}
private bool CanUseSystemWebView(IPublicClientApplication app, Uri redirectUri)
diff --git a/src/shared/Core/Authentication/OAuth/Json/OAuthJsonSerializerContext.cs b/src/shared/Core/Authentication/OAuth/Json/OAuthJsonSerializerContext.cs
new file mode 100644
index 000000000..13ac886c8
--- /dev/null
+++ b/src/shared/Core/Authentication/OAuth/Json/OAuthJsonSerializerContext.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace GitCredentialManager.Authentication.OAuth.Json;
+
+[JsonSourceGenerationOptions(
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNameCaseInsensitive = true
+)]
+[JsonSerializable(typeof(DeviceAuthorizationEndpointResponseJson))]
+[JsonSerializable(typeof(ErrorResponseJson))]
+[JsonSerializable(typeof(TokenEndpointResponseJson))]
+public partial class OAuthJsonSerializerContext : JsonSerializerContext
+{
+}
diff --git a/src/shared/Core/Authentication/OAuth/OAuth2Client.cs b/src/shared/Core/Authentication/OAuth/OAuth2Client.cs
index 27834d2aa..8549d5abb 100644
--- a/src/shared/Core/Authentication/OAuth/OAuth2Client.cs
+++ b/src/shared/Core/Authentication/OAuth/OAuth2Client.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using GitCredentialManager.Authentication.OAuth.Json;
using System.Text.Json;
+using System.Text.Json.Serialization;
namespace GitCredentialManager.Authentication.OAuth
{
@@ -213,7 +214,8 @@ public async Task GetDeviceCodeAsync(IEnumerable
{
string json = await response.Content.ReadAsStringAsync();
- if (response.IsSuccessStatusCode && TryDeserializeJson(json, out DeviceAuthorizationEndpointResponseJson jsonObj))
+ if (response.IsSuccessStatusCode && TryDeserializeJson(json, OAuthJsonSerializerContext.Default,
+ out DeviceAuthorizationEndpointResponseJson jsonObj))
{
return jsonObj.ToResult();
}
@@ -321,12 +323,9 @@ public async Task GetTokenByDeviceCodeAsync(OAuth2DeviceCodeR
return result;
}
- var error = JsonSerializer.Deserialize(json, new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true
- });
+ TryDeserializeJson(json, OAuthJsonSerializerContext.Default, out ErrorResponseJson error);
- switch (error.Error)
+ switch (error?.Error)
{
case OAuth2Constants.DeviceAuthorization.Errors.AuthorizationPending:
// Retry with the current polling interval value
@@ -358,7 +357,7 @@ public async Task GetTokenByDeviceCodeAsync(OAuth2DeviceCodeR
protected virtual bool TryCreateTokenEndpointResult(string json, out OAuth2TokenResult result)
{
- if (TryDeserializeJson(json, out TokenEndpointResponseJson jsonObj))
+ if (TryDeserializeJson(json, OAuthJsonSerializerContext.Default, out TokenEndpointResponseJson jsonObj))
{
result = jsonObj.ToResult();
return true;
@@ -368,9 +367,9 @@ protected virtual bool TryCreateTokenEndpointResult(string json, out OAuth2Token
return false;
}
- protected virtual bool TryCreateExceptionFromResponse(string json, out OAuth2Exception exception)
+ private static bool TryCreateExceptionFromResponse(string json, out OAuth2Exception exception)
{
- if (TryDeserializeJson(json, out ErrorResponseJson obj))
+ if (TryDeserializeJson(json, OAuthJsonSerializerContext.Default, out ErrorResponseJson obj))
{
exception = obj.ToException();
return true;
@@ -397,7 +396,7 @@ private HttpRequestMessage CreateRequestMessage(HttpMethod method, Uri requestUr
return request;
}
- protected Exception CreateExceptionFromResponse(string json)
+ private Exception CreateExceptionFromResponse(string json)
{
if (TryCreateExceptionFromResponse(json, out OAuth2Exception exception))
{
@@ -410,11 +409,11 @@ protected Exception CreateExceptionFromResponse(string json)
return new Trace2OAuth2Exception(_trace2, message, format);
}
- protected static bool TryDeserializeJson(string json, out T obj)
+ protected static bool TryDeserializeJson(string json, JsonSerializerContext context, out T obj)
{
try
{
- obj = JsonSerializer.Deserialize(json);
+ obj = (T)JsonSerializer.Deserialize(json, typeof(T), context);
return true;
}
catch
diff --git a/src/shared/Core/Constants.cs b/src/shared/Core/Constants.cs
index 03f41647a..e41bfb64f 100644
--- a/src/shared/Core/Constants.cs
+++ b/src/shared/Core/Constants.cs
@@ -16,6 +16,10 @@ public static class Constants
public const string GcmDataDirectoryName = ".gcm";
+ public const string WindowsPlatformName = "windows";
+ public const string LinuxPlatformName = "linux";
+ public const string MacOSPlatformName = "osx";
+
public static readonly Guid DevBoxPartnerId = new("e3171dd9-9a5f-e5be-b36c-cc7c4f3f3bcf");
///
diff --git a/src/shared/Core/Core.csproj b/src/shared/Core/Core.csproj
index 644d07e4e..b344ccf91 100644
--- a/src/shared/Core/Core.csproj
+++ b/src/shared/Core/Core.csproj
@@ -1,8 +1,7 @@
- net7.0
- net7.0;net472
+ net8.0
gcmcore
GitCredentialManager
false
@@ -10,22 +9,13 @@
true
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/src/shared/Core/CurlCookie.cs b/src/shared/Core/CurlCookie.cs
index e3a5fa140..c9ba2b7bd 100644
--- a/src/shared/Core/CurlCookie.cs
+++ b/src/shared/Core/CurlCookie.cs
@@ -66,18 +66,12 @@ public IList Parse(string content)
private static DateTime ParseExpires(string expires)
{
-#if NETFRAMEWORK
- DateTime epoch = new DateTime(1970, 01, 01, 0, 0, 0, DateTimeKind.Utc);
-#else
- DateTime epoch = DateTime.UnixEpoch;
-#endif
-
if (long.TryParse(expires, out long i))
{
- return epoch.AddSeconds(i);
+ return DateTime.UnixEpoch.AddSeconds(i);
}
- return epoch;
+ return DateTime.UnixEpoch;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/shared/Core/HttpClientFactory.cs b/src/shared/Core/HttpClientFactory.cs
index c48e277e5..dc8f29f7c 100644
--- a/src/shared/Core/HttpClientFactory.cs
+++ b/src/shared/Core/HttpClientFactory.cs
@@ -99,11 +99,7 @@ public HttpClient CreateClient()
_streams.Error.WriteLine("warning: ---------------------------------------------------");
_streams.Error.WriteLine($"warning: HTTPS connections may not be secure. See {Constants.HelpUrls.GcmTlsVerification} for more information.");
-#if NETFRAMEWORK
- ServicePointManager.ServerCertificateValidationCallback = (req, cert, chain, errors) => true;
-#else
handler.ServerCertificateCustomValidationCallback = (req, cert, chain, errors) => true;
-#endif
}
// If schannel is the TLS backend, custom certificate usage must be explicitly enabled
else if (!string.IsNullOrWhiteSpace(_settings.CustomCertificateBundlePath) &&
@@ -178,23 +174,7 @@ public HttpClient CreateClient()
// Set the custom server certificate validation callback.
// NOTE: this is executed after the default platform server certificate validation is performed
-#if NETFRAMEWORK
- ServicePointManager.ServerCertificateValidationCallback = (_, cert, chain, errors) =>
- {
- // Fail immediately if the cert or chain isn't present
- if (cert is null || chain is null)
- {
- return false;
- }
-
- using (X509Certificate2 cert2 = new X509Certificate2(cert))
- {
- return validationCallback(cert2, chain, errors);
- }
- };
-#else
handler.ServerCertificateCustomValidationCallback = (_, cert, chain, errors) => validationCallback(cert, chain, errors);
-#endif
}
// If CustomCookieFilePath is set, set Cookie header from cookie file, which is written by libcurl
diff --git a/src/shared/Core/Interop/Linux/LinuxFileSystem.cs b/src/shared/Core/Interop/Linux/LinuxFileSystem.cs
index aa064886d..fb76641a3 100644
--- a/src/shared/Core/Interop/Linux/LinuxFileSystem.cs
+++ b/src/shared/Core/Interop/Linux/LinuxFileSystem.cs
@@ -1,9 +1,11 @@
using System;
using System.IO;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Posix;
namespace GitCredentialManager.Interop.Linux
{
+ [SupportedOSPlatform(Constants.LinuxPlatformName)]
public class LinuxFileSystem : PosixFileSystem
{
public override bool IsSamePath(string a, string b)
diff --git a/src/shared/Core/Interop/Linux/LinuxSessionManager.cs b/src/shared/Core/Interop/Linux/LinuxSessionManager.cs
index 2147289ac..6e7f12c61 100644
--- a/src/shared/Core/Interop/Linux/LinuxSessionManager.cs
+++ b/src/shared/Core/Interop/Linux/LinuxSessionManager.cs
@@ -1,7 +1,9 @@
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Posix;
namespace GitCredentialManager.Interop.Linux;
+[SupportedOSPlatform(Constants.LinuxPlatformName)]
public class LinuxSessionManager : PosixSessionManager
{
private bool? _isWebBrowserAvailable;
diff --git a/src/shared/Core/Interop/Linux/LinuxTerminal.cs b/src/shared/Core/Interop/Linux/LinuxTerminal.cs
index f7ea6f89a..1697ae7e2 100644
--- a/src/shared/Core/Interop/Linux/LinuxTerminal.cs
+++ b/src/shared/Core/Interop/Linux/LinuxTerminal.cs
@@ -1,10 +1,12 @@
using System;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Linux.Native;
using GitCredentialManager.Interop.Posix;
using GitCredentialManager.Interop.Posix.Native;
namespace GitCredentialManager.Interop.Linux
{
+ [SupportedOSPlatform(Constants.LinuxPlatformName)]
public class LinuxTerminal : PosixTerminal
{
public LinuxTerminal(ITrace trace, ITrace2 trace2)
diff --git a/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs b/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs
index 256e81cb9..4e88e4b55 100644
--- a/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs
+++ b/src/shared/Core/Interop/MacOS/MacOSEnvironment.cs
@@ -2,11 +2,13 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Runtime.Versioning;
using System.Threading;
using GitCredentialManager.Interop.Posix;
namespace GitCredentialManager.Interop.MacOS
{
+ [SupportedOSPlatform(Constants.MacOSPlatformName)]
public class MacOSEnvironment : PosixEnvironment
{
private ICollection _pathsToIgnore;
diff --git a/src/shared/Core/Interop/MacOS/MacOSFileSystem.cs b/src/shared/Core/Interop/MacOS/MacOSFileSystem.cs
index 1f2e1e666..af80fcacf 100644
--- a/src/shared/Core/Interop/MacOS/MacOSFileSystem.cs
+++ b/src/shared/Core/Interop/MacOS/MacOSFileSystem.cs
@@ -1,9 +1,11 @@
using System;
using System.IO;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Posix;
namespace GitCredentialManager.Interop.MacOS
{
+ [SupportedOSPlatform(Constants.MacOSPlatformName)]
public class MacOSFileSystem : PosixFileSystem
{
public override bool IsSamePath(string a, string b)
diff --git a/src/shared/Core/Interop/MacOS/MacOSSessionManager.cs b/src/shared/Core/Interop/MacOS/MacOSSessionManager.cs
index 584965ca1..cffcdd6c0 100644
--- a/src/shared/Core/Interop/MacOS/MacOSSessionManager.cs
+++ b/src/shared/Core/Interop/MacOS/MacOSSessionManager.cs
@@ -1,8 +1,10 @@
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.MacOS.Native;
using GitCredentialManager.Interop.Posix;
namespace GitCredentialManager.Interop.MacOS
{
+ [SupportedOSPlatform(Constants.MacOSPlatformName)]
public class MacOSSessionManager : PosixSessionManager
{
public MacOSSessionManager(IEnvironment env, IFileSystem fs) : base(env, fs)
diff --git a/src/shared/Core/Interop/MacOS/MacOSTerminal.cs b/src/shared/Core/Interop/MacOS/MacOSTerminal.cs
index a4c9d2120..1357d3b16 100644
--- a/src/shared/Core/Interop/MacOS/MacOSTerminal.cs
+++ b/src/shared/Core/Interop/MacOS/MacOSTerminal.cs
@@ -1,10 +1,12 @@
using System;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.MacOS.Native;
using GitCredentialManager.Interop.Posix;
using GitCredentialManager.Interop.Posix.Native;
namespace GitCredentialManager.Interop.MacOS
{
+ [SupportedOSPlatform(Constants.MacOSPlatformName)]
public class MacOSTerminal : PosixTerminal
{
public MacOSTerminal(ITrace trace, ITrace2 trace2)
diff --git a/src/shared/Core/Interop/Posix/PosixEnvironment.cs b/src/shared/Core/Interop/Posix/PosixEnvironment.cs
index ec3d91c92..e3140daf4 100644
--- a/src/shared/Core/Interop/Posix/PosixEnvironment.cs
+++ b/src/shared/Core/Interop/Posix/PosixEnvironment.cs
@@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.Versioning;
namespace GitCredentialManager.Interop.Posix
{
+ [SupportedOSPlatform(Constants.LinuxPlatformName)]
+ [SupportedOSPlatform(Constants.MacOSPlatformName)]
public class PosixEnvironment : EnvironmentBase
{
public PosixEnvironment(IFileSystem fileSystem)
diff --git a/src/shared/Core/Interop/Posix/PosixFileSystem.cs b/src/shared/Core/Interop/Posix/PosixFileSystem.cs
index ec7ff8d50..06660bc2f 100644
--- a/src/shared/Core/Interop/Posix/PosixFileSystem.cs
+++ b/src/shared/Core/Interop/Posix/PosixFileSystem.cs
@@ -13,13 +13,6 @@ public abstract class PosixFileSystem : FileSystem
/// Path is not absolute.
protected internal static string ResolveSymbolicLinks(string path)
{
-#if NETFRAMEWORK
- // Support for symlinks only exists in .NET 6+.
- // Since we're still targeting .NET Framework on Windows it
- // doesn't matter if we don't resolve symlinks for POSIX here
- // (unless we're running on Mono.. but why do that?)
- return path;
-#else
if (!Path.IsPathRooted(path))
{
throw new ArgumentException("Path must be absolute", nameof(path));
@@ -54,10 +47,8 @@ protected internal static string ResolveSymbolicLinks(string path)
}
return Path.Combine("/", partialPath);
-#endif
}
-#if !NETFRAMEWORK
private static bool TryResolveFileLink(string path, out string target)
{
FileSystemInfo fsi = File.ResolveLinkTarget(path, true);
@@ -71,6 +62,5 @@ private static bool TryResolveDirectoryLink(string path, out string target)
target = fsi?.FullName;
return fsi != null;
}
-#endif
}
}
diff --git a/src/shared/Core/Interop/Windows/WindowsEnvironment.cs b/src/shared/Core/Interop/Windows/WindowsEnvironment.cs
index 6c3450a38..246a44250 100644
--- a/src/shared/Core/Interop/Windows/WindowsEnvironment.cs
+++ b/src/shared/Core/Interop/Windows/WindowsEnvironment.cs
@@ -3,10 +3,12 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Runtime.Versioning;
using System.Text;
namespace GitCredentialManager.Interop.Windows
{
+ [SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsEnvironment : EnvironmentBase
{
public WindowsEnvironment(IFileSystem fileSystem)
diff --git a/src/shared/Core/Interop/Windows/WindowsFileSystem.cs b/src/shared/Core/Interop/Windows/WindowsFileSystem.cs
index c1a64631c..6de36c718 100644
--- a/src/shared/Core/Interop/Windows/WindowsFileSystem.cs
+++ b/src/shared/Core/Interop/Windows/WindowsFileSystem.cs
@@ -1,8 +1,10 @@
using System;
using System.IO;
+using System.Runtime.Versioning;
namespace GitCredentialManager.Interop.Windows
{
+ [SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsFileSystem : FileSystem
{
public override bool IsSamePath(string a, string b)
diff --git a/src/shared/Core/Interop/Windows/WindowsProcessManager.cs b/src/shared/Core/Interop/Windows/WindowsProcessManager.cs
index 85d47b0de..4b55e8e92 100644
--- a/src/shared/Core/Interop/Windows/WindowsProcessManager.cs
+++ b/src/shared/Core/Interop/Windows/WindowsProcessManager.cs
@@ -1,5 +1,8 @@
+using System.Runtime.Versioning;
+
namespace GitCredentialManager.Interop.Windows;
+[SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsProcessManager : ProcessManager
{
public WindowsProcessManager(ITrace2 trace2) : base(trace2)
diff --git a/src/shared/Core/Interop/Windows/WindowsSessionManager.cs b/src/shared/Core/Interop/Windows/WindowsSessionManager.cs
index d87d76347..4bb1a2dd3 100644
--- a/src/shared/Core/Interop/Windows/WindowsSessionManager.cs
+++ b/src/shared/Core/Interop/Windows/WindowsSessionManager.cs
@@ -1,8 +1,10 @@
using System;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Windows.Native;
namespace GitCredentialManager.Interop.Windows
{
+ [SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsSessionManager : SessionManager
{
public WindowsSessionManager(IEnvironment env, IFileSystem fs) : base(env, fs)
diff --git a/src/shared/Core/Interop/Windows/WindowsSettings.cs b/src/shared/Core/Interop/Windows/WindowsSettings.cs
index abdd9ee0e..8566726bd 100644
--- a/src/shared/Core/Interop/Windows/WindowsSettings.cs
+++ b/src/shared/Core/Interop/Windows/WindowsSettings.cs
@@ -1,9 +1,12 @@
+using System.Runtime.Versioning;
+
namespace GitCredentialManager.Interop.Windows
{
///
/// Reads settings from Git configuration, environment variables, and defaults from the Windows Registry.
///
+ [SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsSettings : Settings
{
private readonly ITrace _trace;
@@ -21,7 +24,6 @@ protected override bool TryGetExternalDefault(string section, string scope, stri
{
value = null;
-#if NETFRAMEWORK
// Check for machine (HKLM) registry keys that match the Git configuration name.
// These can be set by system administrators via Group Policy, so make useful defaults.
using (Microsoft.Win32.RegistryKey configKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(Constants.WindowsRegistry.HKConfigurationPath))
@@ -48,9 +50,6 @@ protected override bool TryGetExternalDefault(string section, string scope, stri
return true;
}
-#else
- return base.TryGetExternalDefault(section, scope, property, out value);
-#endif
}
}
}
diff --git a/src/shared/Core/Interop/Windows/WindowsTerminal.cs b/src/shared/Core/Interop/Windows/WindowsTerminal.cs
index b8f5f3475..09da26275 100644
--- a/src/shared/Core/Interop/Windows/WindowsTerminal.cs
+++ b/src/shared/Core/Interop/Windows/WindowsTerminal.cs
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Text;
using GitCredentialManager.Interop.Windows.Native;
using Microsoft.Win32.SafeHandles;
@@ -9,6 +10,7 @@ namespace GitCredentialManager.Interop.Windows
///
/// Represents a thin wrapper around the Windows console device.
///
+ [SupportedOSPlatform(Constants.WindowsPlatformName)]
public class WindowsTerminal : ITerminal
{
// ReadConsole 32768 fail, 32767 OK @linquize [https://github.com/Microsoft/Git-Credential-Manager-for-Windows/commit/a62b9a19f430d038dcd85a610d97e5f763980f85]
diff --git a/src/shared/Core/PlatformUtils.cs b/src/shared/Core/PlatformUtils.cs
index 212c13219..5bae4aa8d 100644
--- a/src/shared/Core/PlatformUtils.cs
+++ b/src/shared/Core/PlatformUtils.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using GitCredentialManager.Interop.Posix.Native;
namespace GitCredentialManager
@@ -24,6 +26,7 @@ public static PlatformInformation GetPlatformInformation(ITrace2 trace2)
return new PlatformInformation(osType, osVersion, cpuArch, clrVersion);
}
+ [SupportedOSPlatformGuard(Constants.WindowsPlatformName)]
public static bool IsDevBox()
{
if (!IsWindows())
@@ -31,7 +34,6 @@ public static bool IsDevBox()
return false;
}
-#if NETFRAMEWORK
// Check for machine (HKLM) registry keys for Cloud PC indicators
// Note that the keys are only found in the 64-bit registry view
using (Microsoft.Win32.RegistryKey hklm64 = Microsoft.Win32.RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, Microsoft.Win32.RegistryView.Registry64))
@@ -48,11 +50,9 @@ public static bool IsDevBox()
return w365Value is not null && Guid.TryParse(partnerValue, out Guid partnerId) && partnerId == Constants.DevBoxPartnerId;
}
-#else
- return false;
-#endif
}
+ [SupportedOSPlatformGuard(Constants.WindowsPlatformName)]
public static bool IsWindowsBrokerSupported()
{
if (!IsWindows())
@@ -97,45 +97,38 @@ public static bool IsWindowsBrokerSupported()
/// Check if the current Operating System is macOS.
///
/// True if running on macOS, false otherwise.
+ [SupportedOSPlatformGuard(Constants.MacOSPlatformName)]
public static bool IsMacOS()
{
-#if NETFRAMEWORK
- return Environment.OSVersion.Platform == PlatformID.MacOSX;
-#else
- return RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
-#endif
+ return OperatingSystem.IsMacOS();
}
///
/// Check if the current Operating System is Windows.
///
/// True if running on Windows, false otherwise.
+ [SupportedOSPlatformGuard(Constants.WindowsPlatformName)]
public static bool IsWindows()
{
-#if NETFRAMEWORK
- return Environment.OSVersion.Platform == PlatformID.Win32NT;
-#else
- return RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
-#endif
+ return OperatingSystem.IsWindows();
}
///
/// Check if the current Operating System is Linux-based.
///
/// True if running on a Linux distribution, false otherwise.
+ [SupportedOSPlatformGuard(Constants.LinuxPlatformName)]
public static bool IsLinux()
{
-#if NETFRAMEWORK
- return Environment.OSVersion.Platform == PlatformID.Unix;
-#else
- return RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
-#endif
+ return OperatingSystem.IsLinux();
}
///
/// Check if the current Operating System is POSIX-compliant.
///
/// True if running on a POSIX-compliant Operating System, false otherwise.
+ [SupportedOSPlatformGuard(Constants.LinuxPlatformName)]
+ [SupportedOSPlatformGuard(Constants.MacOSPlatformName)]
public static bool IsPosix()
{
return IsMacOS() || IsLinux();
@@ -145,6 +138,7 @@ public static bool IsPosix()
/// Ensure the current Operating System is macOS, fail otherwise.
///
/// Thrown if the current OS is not macOS.
+ [SupportedOSPlatformGuard(Constants.MacOSPlatformName)]
public static void EnsureMacOS()
{
if (!IsMacOS())
@@ -157,6 +151,7 @@ public static void EnsureMacOS()
/// Ensure the current Operating System is Windows, fail otherwise.
///
/// Thrown if the current OS is not Windows.
+ [SupportedOSPlatformGuard(Constants.WindowsPlatformName)]
public static void EnsureWindows()
{
if (!IsWindows())
@@ -169,6 +164,7 @@ public static void EnsureWindows()
/// Ensure the current Operating System is Linux-based, fail otherwise.
///
/// Thrown if the current OS is not Linux-based.
+ [SupportedOSPlatformGuard(Constants.LinuxPlatformName)]
public static void EnsureLinux()
{
if (!IsLinux())
@@ -181,6 +177,8 @@ public static void EnsureLinux()
/// Ensure the current Operating System is POSIX-compliant, fail otherwise.
///
/// Thrown if the current OS is not POSIX-compliant.
+ [SupportedOSPlatformGuard(Constants.LinuxPlatformName)]
+ [SupportedOSPlatformGuard(Constants.MacOSPlatformName)]
public static void EnsurePosix()
{
if (!IsPosix())
@@ -193,11 +191,9 @@ public static bool IsElevatedUser()
{
if (IsWindows())
{
-#if NETFRAMEWORK
var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
var principal = new System.Security.Principal.WindowsPrincipal(identity);
return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
-#endif
}
else if (IsPosix())
{
@@ -283,9 +279,6 @@ private static string GetLinuxEntryPath()
}
}
-#if NETFRAMEWORK
- return null;
-#else
//
// We cannot determine the absolute file path from argv[0]
// (how we were launched), so let's now try to extract the
@@ -295,7 +288,6 @@ private static string GetLinuxEntryPath()
//
FileSystemInfo fsi = File.ResolveLinkTarget("/proc/self/exe", returnFinalTarget: false);
return fsi?.FullName;
-#endif
}
private static string GetMacOSEntryPath()
@@ -364,12 +356,11 @@ private static string GetOSVersion(ITrace2 trace2)
// However, we still need to use the old method for Windows on .NET Framework
// and call into the Win32 API to get the correct version (regardless of app
// compatibility settings).
-#if NETFRAMEWORK
if (IsWindows() && RtlGetVersionEx(out RTL_OSVERSIONINFOEX osvi) == 0)
{
return $"{osvi.dwMajorVersion}.{osvi.dwMinorVersion} (build {osvi.dwBuildNumber})";
}
-#endif
+
if (IsWindows() || IsMacOS())
{
return Environment.OSVersion.Version.ToString();
@@ -459,9 +450,6 @@ string GetLinuxDistroVersion()
private static string GetCpuArchitecture()
{
-#if NETFRAMEWORK
- return Environment.Is64BitOperatingSystem ? "x86-64" : "x86";
-#else
switch (RuntimeInformation.OSArchitecture)
{
case Architecture.Arm:
@@ -475,16 +463,11 @@ private static string GetCpuArchitecture()
default:
return RuntimeInformation.OSArchitecture.ToString();
}
-#endif
}
private static string GetClrVersion()
{
-#if NETFRAMEWORK
- return $".NET Framework {Environment.Version}";
-#else
return RuntimeInformation.FrameworkDescription;
-#endif
}
#endregion
diff --git a/src/shared/Core/Trace2Message.cs b/src/shared/Core/Trace2Message.cs
index cbbe48288..75d8e2ed1 100644
--- a/src/shared/Core/Trace2Message.cs
+++ b/src/shared/Core/Trace2Message.cs
@@ -6,17 +6,46 @@
namespace GitCredentialManager;
+public class Trace2EventEnumConverter : JsonStringEnumConverter
+{
+ public Trace2EventEnumConverter()
+ : base(JsonNamingPolicy.SnakeCaseLower, false) { }
+}
+
+public class Trace2ProcessClassEnumConverter : JsonStringEnumConverter
+{
+ public Trace2ProcessClassEnumConverter()
+ : base(JsonNamingPolicy.SnakeCaseLower, false) { }
+}
+
+[JsonSourceGenerationOptions(
+ PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower,
+ PropertyNameCaseInsensitive = true,
+ Converters = new[]
+ {
+ typeof(Trace2EventEnumConverter),
+ typeof(Trace2ProcessClassEnumConverter)
+ }
+)]
+[JsonSerializable(typeof(VersionMessage))]
+[JsonSerializable(typeof(StartMessage))]
+[JsonSerializable(typeof(ExitMessage))]
+[JsonSerializable(typeof(ExitMessage))]
+[JsonSerializable(typeof(ChildStartMessage))]
+[JsonSerializable(typeof(ChildExitMessage))]
+[JsonSerializable(typeof(ErrorMessage))]
+[JsonSerializable(typeof(RegionEnterMessage))]
+[JsonSerializable(typeof(RegionLeaveMessage))]
+internal partial class Trace2JsonSerializerContext : JsonSerializerContext
+{
+}
+
public abstract class Trace2Message
{
private const int SourceColumnMaxWidth = 23;
private const string NormalPerfTimeFormat = "HH:mm:ss.ffffff";
protected const string EmptyPerformanceSpan = "| | | | ";
- protected static readonly JsonSerializerOptions JsonSerializerOptions = new()
- {
- PropertyNameCaseInsensitive = true,
- Converters = { new JsonStringEnumConverter(new SnakeCaseNamingPolicy()) }
- };
[JsonPropertyName("event")]
[JsonPropertyOrder(1)]
@@ -194,7 +223,7 @@ public class VersionMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.VersionMessage);
}
public override string ToNormalString()
@@ -230,7 +259,7 @@ public class StartMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.StartMessage);
}
public override string ToNormalString()
@@ -266,7 +295,7 @@ public class ExitMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.ExitMessage);
}
public override string ToNormalString()
@@ -314,7 +343,7 @@ public class ChildStartMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.ChildStartMessage);
}
public override string ToNormalString()
@@ -371,7 +400,7 @@ public class ChildExitMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.ChildExitMessage);
}
public override string ToNormalString()
@@ -415,7 +444,7 @@ public class ErrorMessage : Trace2Message
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.ErrorMessage);
}
public override string ToNormalString()
@@ -473,7 +502,7 @@ public class RegionEnterMessage : RegionMessage
{
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.RegionEnterMessage);
}
public override string ToNormalString()
@@ -504,7 +533,7 @@ public class RegionLeaveMessage : RegionMessage
public override string ToJson()
{
- return JsonSerializer.Serialize(this, JsonSerializerOptions);
+ return JsonSerializer.Serialize(this, Trace2JsonSerializerContext.Default.RegionLeaveMessage);
}
public override string ToNormalString()
@@ -527,9 +556,3 @@ protected override string GetEventMessage(Trace2FormatTarget formatTarget)
return Message;
}
}
-
-public class SnakeCaseNamingPolicy : JsonNamingPolicy
-{
- public override string ConvertName(string name) =>
- name.ToSnakeCase();
-}
diff --git a/src/shared/Core/UI/AvaloniaUi.cs b/src/shared/Core/UI/AvaloniaUi.cs
index 65b681884..7b23644fe 100644
--- a/src/shared/Core/UI/AvaloniaUi.cs
+++ b/src/shared/Core/UI/AvaloniaUi.cs
@@ -47,12 +47,7 @@ public static Task ShowWindowAsync(Func windowFunc, object dataContext,
Dispatcher.MainThread.Post(appCancelToken =>
{
AppBuilder.Configure()
-#if NETFRAMEWORK
- .UseWin32()
- .UseSkia()
-#else
.UsePlatformDetect()
-#endif
.LogToTrace()
// Workaround https://github.com/AvaloniaUI/Avalonia/issues/10296
// by always setting a application lifetime.
diff --git a/src/shared/Core/UI/Controls/AboutWindow.axaml b/src/shared/Core/UI/Controls/AboutWindow.axaml
index bccc1217d..8d7e63f17 100644
--- a/src/shared/Core/UI/Controls/AboutWindow.axaml
+++ b/src/shared/Core/UI/Controls/AboutWindow.axaml
@@ -3,11 +3,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:gcm="clr-namespace:GitCredentialManager"
+ xmlns:controls="clr-namespace:GitCredentialManager.UI.Controls"
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="450"
x:Class="GitCredentialManager.UI.Controls.AboutWindow"
Title="About Git Credential Manager"
CanResize="False" Width="300" SizeToContent="Height"
x:Name="window"
+ x:DataType="controls:AboutWindow"
+ x:CompileBindings="True"
Background="{DynamicResource WindowBackgroundBrush}">
+ KeyUp="Window_KeyUp"
+ x:DataType="vm:WindowViewModel"
+ x:CompileBindings="True">
diff --git a/src/shared/Core/UI/Controls/ProgressWindow.axaml b/src/shared/Core/UI/Controls/ProgressWindow.axaml
index 3bfc20f5c..962c0b73c 100644
--- a/src/shared/Core/UI/Controls/ProgressWindow.axaml
+++ b/src/shared/Core/UI/Controls/ProgressWindow.axaml
@@ -6,6 +6,7 @@
SizeToContent="WidthAndHeight" CanResize="False" Topmost="True"
ExtendClientAreaChromeHints="NoChrome" ExtendClientAreaToDecorationsHint="True"
ShowInTaskbar="False" Title="Git Credential Manager" WindowStartupLocation="CenterScreen"
+ x:CompileBindings="True"
x:Class="GitCredentialManager.UI.Controls.ProgressWindow">
diff --git a/src/shared/Core/UI/Views/DefaultAccountView.axaml b/src/shared/Core/UI/Views/DefaultAccountView.axaml
index 83a677220..39b9133aa 100644
--- a/src/shared/Core/UI/Views/DefaultAccountView.axaml
+++ b/src/shared/Core/UI/Views/DefaultAccountView.axaml
@@ -5,6 +5,8 @@
xmlns:vm="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=gcmcore"
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:DefaultAccountViewModel"
+ x:CompileBindings="True"
x:Class="GitCredentialManager.UI.Views.DefaultAccountView">
diff --git a/src/shared/Core/UI/Views/DeviceCodeView.axaml b/src/shared/Core/UI/Views/DeviceCodeView.axaml
index ea14072cf..79e02abab 100644
--- a/src/shared/Core/UI/Views/DeviceCodeView.axaml
+++ b/src/shared/Core/UI/Views/DeviceCodeView.axaml
@@ -2,11 +2,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:sharedVms="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=gcmcore"
+ xmlns:vm="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:DeviceCodeViewModel"
+ x:CompileBindings="True"
x:Class="GitCredentialManager.UI.Views.DeviceCodeView">
-
+
diff --git a/src/shared/Core/UI/Views/OAuthView.axaml b/src/shared/Core/UI/Views/OAuthView.axaml
index abf9afc5e..465e860cd 100644
--- a/src/shared/Core/UI/Views/OAuthView.axaml
+++ b/src/shared/Core/UI/Views/OAuthView.axaml
@@ -4,6 +4,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:GitCredentialManager.UI.ViewModels;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:OAuthViewModel"
+ x:CompileBindings="True"
x:Class="GitCredentialManager.UI.Views.OAuthView">
diff --git a/src/shared/DotnetTool/DotnetTool.csproj b/src/shared/DotnetTool/DotnetTool.csproj
index a951303bb..a1107a4b6 100644
--- a/src/shared/DotnetTool/DotnetTool.csproj
+++ b/src/shared/DotnetTool/DotnetTool.csproj
@@ -1,6 +1,6 @@
- net7.0
+ net8.0
true
dotnet-tool.nuspec
diff --git a/src/shared/DotnetTool/dotnet-tool.nuspec b/src/shared/DotnetTool/dotnet-tool.nuspec
index e707ba27e..cf9ba7444 100644
--- a/src/shared/DotnetTool/dotnet-tool.nuspec
+++ b/src/shared/DotnetTool/dotnet-tool.nuspec
@@ -12,7 +12,7 @@
-
+
diff --git a/src/shared/DotnetTool/layout.sh b/src/shared/DotnetTool/layout.sh
index 44c712650..f5244dbbd 100755
--- a/src/shared/DotnetTool/layout.sh
+++ b/src/shared/DotnetTool/layout.sh
@@ -39,7 +39,7 @@ PROJ_OUT="$OUT/$DOTNET_TOOL"
CONFIGURATION="${CONFIGURATION:=Debug}"
# Build parameters
-FRAMEWORK=net7.0
+FRAMEWORK=net8.0
# Outputs
OUTDIR="$PROJ_OUT/nupkg/$CONFIGURATION"
diff --git a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj
index bc6dcb061..fb2735a8f 100644
--- a/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj
+++ b/src/shared/Git-Credential-Manager/Git-Credential-Manager.csproj
@@ -2,16 +2,44 @@
Exe
- net7.0
- net472;net7.0
+ net8.0
win-x86;osx-x64;linux-x64;osx-arm64
- x86
git-credential-manager
GitCredentialManager
$(RepoAssetsPath)gcmicon.ico
false
latest
true
+ true
+ true
+ true
+
+
+
+
+ true
+
+
+ true
diff --git a/src/shared/Git-Credential-Manager/Program.cs b/src/shared/Git-Credential-Manager/Program.cs
index 59f579b9f..b8aa0eb7c 100644
--- a/src/shared/Git-Credential-Manager/Program.cs
+++ b/src/shared/Git-Credential-Manager/Program.cs
@@ -76,12 +76,7 @@ private static void AppMain(object o)
// Required for Avalonia designer
static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure()
-#if NETFRAMEWORK
- .UseWin32()
- .UseSkia()
-#else
.UsePlatformDetect()
-#endif
.LogToTrace();
}
}
diff --git a/src/shared/GitHub.Tests/GitHub.Tests.csproj b/src/shared/GitHub.Tests/GitHub.Tests.csproj
index a5cda349e..1b892075e 100644
--- a/src/shared/GitHub.Tests/GitHub.Tests.csproj
+++ b/src/shared/GitHub.Tests/GitHub.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
true
latest
diff --git a/src/shared/GitHub/GitHub.csproj b/src/shared/GitHub/GitHub.csproj
index 1de18e7a5..2d550fef1 100644
--- a/src/shared/GitHub/GitHub.csproj
+++ b/src/shared/GitHub/GitHub.csproj
@@ -1,8 +1,7 @@
- net7.0
- net7.0;net472
+ net8.0
GitHub
GitHub
false
@@ -13,8 +12,4 @@
-
-
-
-
diff --git a/src/shared/GitHub/GitHubJsonSerializerContext.cs b/src/shared/GitHub/GitHubJsonSerializerContext.cs
new file mode 100644
index 000000000..4ef75602e
--- /dev/null
+++ b/src/shared/GitHub/GitHubJsonSerializerContext.cs
@@ -0,0 +1,13 @@
+namespace GitHub;
+
+using System.Text.Json.Serialization;
+
+[JsonSourceGenerationOptions(
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
+ PropertyNameCaseInsensitive = true
+)]
+[JsonSerializable(typeof(GitHubUserInfo))]
+[JsonSerializable(typeof(GitHubMetaInfo))]
+internal partial class GitHubJsonSerializerContext : JsonSerializerContext
+{
+}
diff --git a/src/shared/GitHub/GitHubRestApi.cs b/src/shared/GitHub/GitHubRestApi.cs
index 5051ed2bb..8baac581f 100644
--- a/src/shared/GitHub/GitHubRestApi.cs
+++ b/src/shared/GitHub/GitHubRestApi.cs
@@ -106,7 +106,7 @@ public async Task GetUserInfoAsync(Uri targetUri, string accessT
string json = await response.Content.ReadAsStringAsync();
- return JsonSerializer.Deserialize(json);
+ return JsonSerializer.Deserialize(json, GitHubJsonSerializerContext.Default.GitHubUserInfo);
}
}
}
@@ -125,7 +125,7 @@ public async Task GetMetaInfoAsync(Uri targetUri)
string json = await response.Content.ReadAsStringAsync();
- return JsonSerializer.Deserialize(json);
+ return JsonSerializer.Deserialize(json, GitHubJsonSerializerContext.Default.GitHubMetaInfo);
}
}
diff --git a/src/shared/GitHub/UI/Views/CredentialsView.axaml b/src/shared/GitHub/UI/Views/CredentialsView.axaml
index ccf96bf7b..ba2449d10 100644
--- a/src/shared/GitHub/UI/Views/CredentialsView.axaml
+++ b/src/shared/GitHub/UI/Views/CredentialsView.axaml
@@ -6,6 +6,8 @@
xmlns:vm="clr-namespace:GitHub.UI.ViewModels"
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:CredentialsViewModel"
+ x:CompileBindings="True"
x:Class="GitHub.UI.Views.CredentialsView">
diff --git a/src/shared/GitHub/UI/Views/DeviceCodeView.axaml b/src/shared/GitHub/UI/Views/DeviceCodeView.axaml
index c4f320411..afd0a0327 100644
--- a/src/shared/GitHub/UI/Views/DeviceCodeView.axaml
+++ b/src/shared/GitHub/UI/Views/DeviceCodeView.axaml
@@ -5,6 +5,8 @@
xmlns:controls="clr-namespace:GitHub.UI.Controls"
xmlns:vm="clr-namespace:GitHub.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:DeviceCodeViewModel"
+ x:CompileBindings="True"
x:Class="GitHub.UI.Views.DeviceCodeView">
diff --git a/src/shared/GitHub/UI/Views/SelectAccountView.axaml b/src/shared/GitHub/UI/Views/SelectAccountView.axaml
index 417d58387..d7e728b56 100644
--- a/src/shared/GitHub/UI/Views/SelectAccountView.axaml
+++ b/src/shared/GitHub/UI/Views/SelectAccountView.axaml
@@ -5,6 +5,8 @@
xmlns:controls="clr-namespace:GitHub.UI.Controls"
xmlns:vm="clr-namespace:GitHub.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:SelectAccountViewModel"
+ x:CompileBindings="True"
x:Class="GitHub.UI.Views.SelectAccountView">
diff --git a/src/shared/GitHub/UI/Views/TwoFactorView.axaml b/src/shared/GitHub/UI/Views/TwoFactorView.axaml
index d02598855..be4eec7ab 100644
--- a/src/shared/GitHub/UI/Views/TwoFactorView.axaml
+++ b/src/shared/GitHub/UI/Views/TwoFactorView.axaml
@@ -5,6 +5,8 @@
xmlns:controls="clr-namespace:GitHub.UI.Controls"
xmlns:vm="clr-namespace:GitHub.UI.ViewModels"
mc:Ignorable="d" d:DesignWidth="420"
+ x:DataType="vm:TwoFactorViewModel"
+ x:CompileBindings="True"
x:Class="GitHub.UI.Views.TwoFactorView">
diff --git a/src/shared/GitLab.Tests/GitLab.Tests.csproj b/src/shared/GitLab.Tests/GitLab.Tests.csproj
index bcd5fe7e8..253c36db4 100644
--- a/src/shared/GitLab.Tests/GitLab.Tests.csproj
+++ b/src/shared/GitLab.Tests/GitLab.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
true
latest
diff --git a/src/shared/GitLab/GitLab.csproj b/src/shared/GitLab/GitLab.csproj
index 66017d55e..23086c8ee 100644
--- a/src/shared/GitLab/GitLab.csproj
+++ b/src/shared/GitLab/GitLab.csproj
@@ -1,8 +1,7 @@
- net7.0
- net7.0;net472
+ net8.0
GitLab
GitLab
false
@@ -13,8 +12,4 @@
-
-
-
-
diff --git a/src/shared/GitLab/UI/Views/CredentialsView.axaml b/src/shared/GitLab/UI/Views/CredentialsView.axaml
index eac9318be..a1ce5ce45 100644
--- a/src/shared/GitLab/UI/Views/CredentialsView.axaml
+++ b/src/shared/GitLab/UI/Views/CredentialsView.axaml
@@ -6,6 +6,8 @@
xmlns:converters="clr-namespace:GitCredentialManager.UI.Converters;assembly=gcmcore"
mc:Ignorable="d" d:DesignWidth="420"
x:Class="GitLab.UI.Views.CredentialsView"
+ x:DataType="vm:CredentialsViewModel"
+ x:CompileBindings="True"
x:Name="view">
diff --git a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj
index 8a475c370..01ec9d411 100644
--- a/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj
+++ b/src/shared/Microsoft.AzureRepos.Tests/Microsoft.AzureRepos.Tests.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
false
true
latest
diff --git a/src/shared/Microsoft.AzureRepos/Microsoft.AzureRepos.csproj b/src/shared/Microsoft.AzureRepos/Microsoft.AzureRepos.csproj
index c99f102b3..1408d63db 100644
--- a/src/shared/Microsoft.AzureRepos/Microsoft.AzureRepos.csproj
+++ b/src/shared/Microsoft.AzureRepos/Microsoft.AzureRepos.csproj
@@ -1,8 +1,7 @@
- net7.0
- net7.0;net472
+ net8.0
Microsoft.AzureRepos
Microsoft.AzureRepos
false
@@ -13,8 +12,4 @@
-
-
-
-
diff --git a/src/shared/TestInfrastructure/TestInfrastructure.csproj b/src/shared/TestInfrastructure/TestInfrastructure.csproj
index 467df5c3c..569b64cd5 100644
--- a/src/shared/TestInfrastructure/TestInfrastructure.csproj
+++ b/src/shared/TestInfrastructure/TestInfrastructure.csproj
@@ -1,7 +1,7 @@
- net7.0
+ net8.0
GitCredentialManager.Tests
false
false
diff --git a/src/windows/Installer.Windows/Installer.Windows.csproj b/src/windows/Installer.Windows/Installer.Windows.csproj
index 99253c445..312866484 100644
--- a/src/windows/Installer.Windows/Installer.Windows.csproj
+++ b/src/windows/Installer.Windows/Installer.Windows.csproj
@@ -3,10 +3,10 @@
- net472
+ net8.0
false
false
- $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\win-x86
+ $(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net8.0\win-x86
diff --git a/src/windows/Installer.Windows/layout.ps1 b/src/windows/Installer.Windows/layout.ps1
index 070c9bf49..940194e27 100644
--- a/src/windows/Installer.Windows/layout.ps1
+++ b/src/windows/Installer.Windows/layout.ps1
@@ -37,7 +37,8 @@ mkdir -p "$PAYLOAD","$SYMBOLS"
# Publish core application executables
Write-Output "Publishing core application..."
dotnet publish "$GCM_SRC" `
- --framework net472 `
+ --framework net8.0 `
+ --self-contained `
--configuration "$CONFIGURATION" `
--runtime win-x86 `
--output "$PAYLOAD"
@@ -46,21 +47,6 @@ dotnet publish "$GCM_SRC" `
# into the publish output.
Remove-Item -Path "$PAYLOAD/*.dylib" -Force
-# Delete extraneous files that get included for other architectures
-# We only care about x86 as the core GCM executable is only targeting x86
-Remove-Item -Path "$PAYLOAD/arm/" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/arm64/" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/x64/" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/musl-x64/" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/runtimes/win-arm64/" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/runtimes/win-x64/" -Recurse -Force
-
-# The Avalonia and MSAL binaries in these directories are already included in
-# the $PAYLOAD directory directly, so we can delete these extra copies.
-Remove-Item -Path "$PAYLOAD/x86/libSkiaSharp.dll" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/x86/libHarfBuzzSharp.dll" -Recurse -Force
-Remove-Item -Path "$PAYLOAD/runtimes/win-x86/native/msalruntime_x86.dll" -Recurse -Force
-
# Delete localized resource assemblies - we don't localize the core GCM assembly anyway
Get-ChildItem "$PAYLOAD" -Recurse -Include "*.resources.dll" | Remove-Item -Force