Skip to content

Commit

Permalink
[net9.0] Merge main into net9.0. (#21221)
Browse files Browse the repository at this point in the history
  • Loading branch information
rolfbjarne authored Sep 12, 2024
2 parents 10531aa + 81799f1 commit 3c83e65
Show file tree
Hide file tree
Showing 46 changed files with 464 additions and 268 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/update-single-platform-branches.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
set -ex
git config user.email "github-actions-single-platform-branch-updater@xamarin.com"
git config user.name "GitHub Actions Single Platform Branch Updater"
for platform in dotnet-iOS dotnet-tvOS dotnet-MacCatalyst dotnet-macOS dotnet legacy legacy-iOS legacy-macOS; do
for platform in dotnet-iOS dotnet-tvOS dotnet-MacCatalyst dotnet-macOS dotnet; do
git checkout -b release-test/only-$platform origin/release-test/only-$platform
git merge origin/main
git push
Expand Down
2 changes: 2 additions & 0 deletions docs/website/binding_types_reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -2250,6 +2250,8 @@ Currently, these types are supported:

* `nint`
* `nuint`
* `int`, `uint`
* `long`, `ulong`
* `NSNumber`
* `NSString` (this is the default if none is specified)

Expand Down
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<MicrosoftNETRuntimeMonoTargetsSdkPackageVersion>9.0.0-alpha.1.23556.4</MicrosoftNETRuntimeMonoTargetsSdkPackageVersion>
<MicrosoftTemplateEngineTasksVersion>7.0.100-alpha.1.21601.1</MicrosoftTemplateEngineTasksVersion>
<MicrosoftDotNetCecilPackageVersion>0.11.5-alpha.24379.1</MicrosoftDotNetCecilPackageVersion>
<MicrosoftDotNetXHarnessiOSSharedPackageVersion>9.0.0-prerelease.24420.3</MicrosoftDotNetXHarnessiOSSharedPackageVersion>
<MicrosoftDotNetXHarnessiOSSharedPackageVersion>10.0.0-prerelease.24459.1</MicrosoftDotNetXHarnessiOSSharedPackageVersion>
<!-- Manually updated versions -->
<Emscriptennet7WorkloadVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)</Emscriptennet7WorkloadVersion>
<EmscriptenWorkloadVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)</EmscriptenWorkloadVersion>
Expand Down
11 changes: 9 additions & 2 deletions src/avfoundation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11403,9 +11403,10 @@ interface AVCaptureDeviceDiscoverySession {

/// <summary>Enumerates the types of device that can capture audiovisual data.</summary>
[Introduced (PlatformName.MacCatalyst, 14, 0)]
[NoTV, NoWatch]
[TV (17, 0), NoWatch]
enum AVCaptureDeviceType {

[NoTV]
[Field ("AVCaptureDeviceTypeBuiltInMicrophone")]
BuiltInMicrophone,

Expand All @@ -11417,6 +11418,7 @@ enum AVCaptureDeviceType {
[Field ("AVCaptureDeviceTypeBuiltInTelephotoCamera")]
BuiltInTelephotoCamera,

[NoTV]
[NoMac]
[Deprecated (PlatformName.iOS, 10, 2, message: "Use 'BuiltInDualCamera' instead.")]
[MacCatalyst (13, 1)]
Expand Down Expand Up @@ -11453,9 +11455,14 @@ enum AVCaptureDeviceType {
[Field ("AVCaptureDeviceTypeExternalUnknown")]
ExternalUnknown,

[NoWatch, NoTV, NoMac, MacCatalyst (15, 4), iOS (15, 4)]
[NoWatch, TV (17, 0), NoMac, MacCatalyst (15, 4), iOS (15, 4)]
[Field ("AVCaptureDeviceTypeBuiltInLiDARDepthCamera")]
BuiltInLiDarDepthCamera,

[NoWatch]
[iOS (17, 0), MacCatalyst (17, 0), TV (17, 0), Mac (14, 0)]
[Field ("AVCaptureDeviceTypeExternal")]
External,
}

[NoTV, NoWatch] // matches API that uses it.
Expand Down
5 changes: 5 additions & 0 deletions src/bgen/Caches/NamespaceCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class NamespaceCache {
public ICollection<string> UINamespaces { get; private set; }
public ICollection<string> ImplicitNamespaces { get; private set; }
public ICollection<string> NamespacesThatConflictWithTypes { get; private set; }
public ICollection<string> TypesInMultipleNamespaces { get; private set; }

public NamespaceCache (PlatformName currentPlatform, string customObjCRuntimeNS, bool skipSystemDrawing)
{
Expand Down Expand Up @@ -154,6 +155,10 @@ public NamespaceCache (PlatformName currentPlatform, string customObjCRuntimeNS,
"AudioUnit",
};

TypesInMultipleNamespaces = new HashSet<string> {
"NWEndpoint", // Both in Network and NetworkExtension
};

if (!skipSystemDrawing)
ImplicitNamespaces.Add ("System.Drawing");
}
Expand Down
9 changes: 8 additions & 1 deletion src/bgen/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@ void GenerateEnum (Type type)
var isBackingFieldValueType = backingFieldType.IsValueType;
var visibility = is_internal ? "internal" : "public";

if (backingFieldType != TypeCache.System_nint && backingFieldType != TypeCache.System_nuint && backingFieldType != TypeCache.NSString && backingFieldType != TypeCache.NSNumber) {
if (backingFieldType != TypeCache.System_nint &&
backingFieldType != TypeCache.System_nuint &&
backingFieldType != TypeCache.System_Int32 &&
backingFieldType != TypeCache.System_Int64 &&
backingFieldType != TypeCache.System_UInt32 &&
backingFieldType != TypeCache.System_UInt64 &&
backingFieldType != TypeCache.NSString &&
backingFieldType != TypeCache.NSNumber) {
exceptions.Add (ErrorHelper.CreateError (1088 /* The backing field type '{0}' is invalid. Valid backing field types are: "NSString", "NSNumber", "nint" and "nuint". */, backingFieldType.FullName));
backingFieldType = TypeCache.NSString;
}
Expand Down
29 changes: 27 additions & 2 deletions src/bgen/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,22 @@ public bool IsNSObject (Type type)
return false;
}

return type.IsInterface;
// If any of the interfaces this type implements is an NSObject,
// then this type is also an NSObject
var ifaces = type.GetInterfaces ();
foreach (var iface in ifaces)
if (IsNSObject (iface))
return true;

if (type.IsInterface) {
var bta = ReflectionExtensions.GetBaseTypeAttribute (type, this);
if (bta?.BaseType is not null)
return IsNSObject (bta.BaseType);

return false;
}

return false;
}

public string PrimitiveType (Type t, bool formatted = false)
Expand Down Expand Up @@ -604,8 +619,10 @@ public TrampolineInfo MakeTrampoline (Type t)
invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, pi.ParameterType);
} else if (isForced) {
invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, true, {2})!", safe_name, TypeManager.RenderType (pi.ParameterType), isForcedOwns);
} else {
} else if (IsNSObject (pi.ParameterType)) {
invoke.AppendFormat (" Runtime.GetNSObject<{1}> ({0})!", safe_name, TypeManager.RenderType (pi.ParameterType));
} else {
invoke.AppendFormat (" Runtime.GetINativeObject<{1}> ({0}, false)!", safe_name, TypeManager.RenderType (pi.ParameterType));
}
continue;
}
Expand Down Expand Up @@ -716,6 +733,11 @@ public TrampolineInfo MakeTrampoline (Type t)
invoke.AppendFormat ("CFArray.ArrayFromHandle<{0}> ({1})!", TypeManager.FormatType (null, et), safe_name);
continue;
}
if (TypeCache.INativeObject.IsAssignableFrom (et)) {
pars.Add (new TrampolineParameterInfo (NativeHandleType, safe_name));
invoke.AppendFormat ("NSArray.ArrayFromHandle<{0}> ({1})!", TypeManager.FormatType (t, et), safe_name);
continue;
}
}

if (pi.ParameterType.IsPointer && pi.ParameterType.GetElementType ().IsValueType) {
Expand Down Expand Up @@ -894,6 +916,9 @@ public string MarshalParameter (MethodInfo mi, ParameterInfo pi, bool null_allow
return safe_name + ".Handle";
}

if (TypeCache.INativeObject.IsAssignableFrom (pi.ParameterType))
return $"{safe_name}.GetHandle ()";

// This means you need to add a new MarshalType in the method "Go"
throw new BindingException (1002, true, pi.ParameterType.FullName, mi.DeclaringType.FullName, mi.Name.GetSafeParamName ());
}
Expand Down
18 changes: 17 additions & 1 deletion src/bgen/TypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,17 @@ public string FormatTypeUsedIn (string? usedInNamespace, Type? type)

if (t.Namespace is not null) {
string ns = t.Namespace;
if (NamespaceCache.ImplicitNamespaces.Contains (ns) || t.IsGenericType) {
var isImplicitNamespace = NamespaceCache.ImplicitNamespaces.Contains (ns);
var isInMultipleNamespaces = IsInMultipleNamespaces (t);
var nonGlobalCandidate = isImplicitNamespace && !isInMultipleNamespaces;
if (nonGlobalCandidate || t.IsGenericType) {
var targs = t.GetGenericArguments ();
if (targs.Length == 0)
return t.Name + nullable;
return $"global::{t.Namespace}." + t.Name.RemoveArity () + "<" + string.Join (", ", targs.Select (l => FormatTypeUsedIn (null, l)).ToArray ()) + ">" + nullable;
}
if (isInMultipleNamespaces)
return "global::" + t.FullName + nullable;
if (NamespaceCache.NamespacesThatConflictWithTypes.Contains (ns))
return "global::" + t.FullName + nullable;
if (t.Name == t.Namespace)
Expand All @@ -317,6 +322,17 @@ public string FormatTypeUsedIn (string? usedInNamespace, Type? type)
return t.FullName + nullable;
}

bool IsInMultipleNamespaces (Type? type)
{
if (type is null)
return false;

if (NamespaceCache.TypesInMultipleNamespaces.Contains (type.Name))
return true;

return IsInMultipleNamespaces (type.GetElementType ());
}

// TODO: If we ever have an API with nested properties of the same name more than
// 2 deep, we'll need to have this return a list of PropertyInfo and comb through them all.
public PropertyInfo? GetParentTypeWithSameNamedProperty (BaseTypeAttribute bta, string propertyName)
Expand Down
2 changes: 0 additions & 2 deletions system-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,6 @@ function xcodebuild_download_selected_platforms ()
"$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform iOS
log "Executing '$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild -downloadPlatform tvOS' $1"
"$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform tvOS
log "Executing '$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild -downloadPlatform watchOS' $1"
"$XCODE_DEVELOPER_ROOT/usr/bin/xcodebuild" -downloadPlatform watchOS
}

function download_xcode_platforms ()
Expand Down
2 changes: 1 addition & 1 deletion tests/bgen/bgen-tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<RootNamespace>bgen_tests</RootNamespace>

<IsPackable>false</IsPackable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions tests/cecil-tests/Documentation.KnownFailures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5150,6 +5150,7 @@ F:AVFoundation.AVCaptureDeviceType.BuiltInTripleCamera
F:AVFoundation.AVCaptureDeviceType.BuiltInTrueDepthCamera
F:AVFoundation.AVCaptureDeviceType.BuiltInUltraWideCamera
F:AVFoundation.AVCaptureDeviceType.BuiltInWideAngleCamera
F:AVFoundation.AVCaptureDeviceType.External
F:AVFoundation.AVCaptureDeviceType.ExternalUnknown
F:AVFoundation.AVCaptureExposureMode.AutoExpose
F:AVFoundation.AVCaptureExposureMode.ContinuousAutoExposure
Expand Down
54 changes: 54 additions & 0 deletions tests/common/TestRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Runtime.InteropServices;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Versioning;

using AVFoundation;
using CoreBluetooth;
Expand Down Expand Up @@ -116,6 +117,59 @@ public static Version OSXVersion {
}
#endif

public static ApplePlatform CurrentPlatform {
get {
#if __MACCATALYST__
return ApplePlatform.MacCatalyst;
#elif __IOS__
return ApplePlatform.iOS;
#elif __TVOS__
return ApplePlatform.TVOS;
#elif __MACOS__
return ApplePlatform.MacOSX;
#elif __WATCHOS__
return ApplePlatform.WatchOS;
#else
#error Unknown platform
#endif
}
}

// This returns the string for the platform as used in the OSPlatformAttribute's PlatformName property.
public static string GetOSPlatformName (ApplePlatform platform)
{
switch (platform) {
case ApplePlatform.iOS:
return "ios";
case ApplePlatform.MacOSX:
return "macos";
case ApplePlatform.TVOS:
return "tvos";
case ApplePlatform.MacCatalyst:
return "maccatalyst";
default:
throw new Exception ($"Unknown platform: {platform}");
}
}

public static bool HasOSPlatformAttributeForCurrentPlatform<T> (ICustomAttributeProvider provider) where T : OSPlatformAttribute
{
return HasOSPlatformAttribute<T> (provider, CurrentPlatform);
}

public static bool HasOSPlatformAttribute<T> (ICustomAttributeProvider provider, ApplePlatform platform) where T : OSPlatformAttribute
{
var attribs = provider.GetCustomAttributes (false);
var platformName = GetOSPlatformName (platform);
foreach (var attrib in attribs) {
if (attrib is T platformAttribute) {
if (platformAttribute.PlatformName.StartsWith (platformName, StringComparison.OrdinalIgnoreCase))
return true;
}
}
return false;
}

public static Version GetSDKVersion ()
{
var v = dyld_get_program_sdk_version ();
Expand Down
4 changes: 2 additions & 2 deletions tests/common/shared-dotnet.mk
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ endif

ifeq ($(RID),)
ifeq ($(PLATFORM),iOS)
RID=ios-arm64
RID=iossimulator-arm64
else ifeq ($(PLATFORM),tvOS)
RID=tvos-arm64
RID=tvossimulator-arm64
else ifeq ($(PLATFORM),MacCatalyst)
ifeq ($(CONFIG),Release)
RID=maccatalyst-x64;maccatalyst-arm64
Expand Down
43 changes: 34 additions & 9 deletions tests/generator/BGenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,20 @@ public void Bug35176 ()
Assert.AreEqual (expectedAttributes, renderedAttributes, "Introduced attributes");
}

[Test]
[TestCase (Profile.iOS)]
public void INativeObjectsInBlocks (Profile profile)
{
var bgen = new BGenTool ();
bgen.Profile = profile;
bgen.Defines = BGenTool.GetDefaultDefines (bgen.Profile);
bgen.AddTestApiDefinition ("tests/inativeobjects-in-blocks.cs");
bgen.AddExtraSourcesRelativeToGeneratorDirectory ("tests/inativeobjects-in-blocks-sources.cs");
bgen.CreateTemporaryBinding ();
bgen.AssertExecute ("build");
bgen.AssertNoWarnings ();
}

[Test]
public void Bug36457 ()
{
Expand Down Expand Up @@ -526,6 +540,13 @@ public void StackOverflow20696157 ()
BuildFile (Profile.iOS, "sof20696157.cs");
}

[Test]
[TestCase (Profile.iOS)]
public void TypesInMultipleNamespaces (Profile profile)
{
BuildFile (profile, "tests/types-in-multiple-namespaces.cs");
}

[Test]
public void HyphenInName ()
{
Expand Down Expand Up @@ -598,6 +619,14 @@ public void MultipleApiDefinitions2 ()
BuildFile (Profile.iOS, "multiple-api-definitions2-a.cs", "multiple-api-definitions2-b.cs");
}


[Test]
[TestCase (Profile.iOS)]
public void INativeObjectArraysInBlocks (Profile profile)
{
BuildFile (profile, "tests/inativeobject-arrays-in-blocks.cs");
}

[Test]
[TestCase (Profile.iOS)]
public void ClassNameCollision (Profile profile)
Expand Down Expand Up @@ -1669,6 +1698,10 @@ public void BackingFieldType (Profile profile)
new { BackingFieldType = "NSNumber", NullableType = "Foundation.NSNumber", RenderedBackingFieldType = "Foundation.NSNumber", SimplifiedNullableType = "Foundation.NSNumber" },
new { BackingFieldType = "NSInteger", NullableType = $"System.Nullable`1<{nintName}>", RenderedBackingFieldType = nintName, SimplifiedNullableType = "System.Nullable`1" },
new { BackingFieldType = "NSUInteger", NullableType = $"System.Nullable`1<{nuintName}>", RenderedBackingFieldType = nuintName, SimplifiedNullableType = "System.Nullable`1" },
new { BackingFieldType = "Int32", NullableType = $"System.Nullable`1<System.Int32>", RenderedBackingFieldType = "System.Int32", SimplifiedNullableType = "System.Nullable`1" },
new { BackingFieldType = "Int64", NullableType = $"System.Nullable`1<System.Int64>", RenderedBackingFieldType = "System.Int64", SimplifiedNullableType = "System.Nullable`1" },
new { BackingFieldType = "UInt32", NullableType = $"System.Nullable`1<System.UInt32>", RenderedBackingFieldType = "System.UInt32", SimplifiedNullableType = "System.Nullable`1" },
new { BackingFieldType = "UInt64", NullableType = $"System.Nullable`1<System.UInt64>", RenderedBackingFieldType = "System.UInt64", SimplifiedNullableType = "System.Nullable`1" },
};

foreach (var tc in testCases) {
Expand Down Expand Up @@ -1697,15 +1730,7 @@ public void BackingFieldType (Profile profile)
public void UnderlyingFieldType (Profile profile)
{
Configuration.IgnoreIfIgnoredPlatform (profile.AsPlatform ());
var bgen = BuildFile (profile, true, true, "tests/underlyingfieldtype.cs");

#if NET
const string nintName = "System.IntPtr";
const string nuintName = "System.UIntPtr";
#else
const string nintName = "System.nint";
const string nuintName = "System.nuint";
#endif
BuildFile (profile, true, true, "tests/underlyingfieldtype.cs");
}

[Test]
Expand Down
Loading

6 comments on commit 3c83e65

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💻 [CI Build] Tests on macOS X64 - Mac Sonoma (14) passed 💻

All tests on macOS X64 - Mac Sonoma (14) passed.

Pipeline on Agent
Hash: 3c83e65de78e3ec58b6b7c22362658fa83939572 [CI build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📚 [CI Build] Artifacts 📚

Artifacts were not provided.

Pipeline on Agent
Hash: [CI build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💻 [CI Build] Tests on macOS M1 - Mac Ventura (13) passed 💻

All tests on macOS M1 - Mac Ventura (13) passed.

Pipeline on Agent
Hash: 3c83e65de78e3ec58b6b7c22362658fa83939572 [CI build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💻 [CI Build] Tests on macOS M1 - Mac Monterey (12) passed 💻

All tests on macOS M1 - Mac Monterey (12) passed.

Pipeline on Agent
Hash: 3c83e65de78e3ec58b6b7c22362658fa83939572 [CI build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ API diff for current PR / commit

.NET (No breaking changes)

✅ API diff vs stable

.NET (No breaking changes)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 3c83e65de78e3ec58b6b7c22362658fa83939572 [CI build]

@vs-mobiletools-engineering-service2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 [CI Build] Test results 🔥

Test results

❌ Tests failed on VSTS: test results

3 tests crashed, 0 tests failed, 86 tests passed.

Failures

❌ cecil tests

🔥 Failed catastrophically on VSTS: test results - cecil (no summary found).

Html Report (VSDrops) Download

❌ fsharp tests

🔥 Failed catastrophically on VSTS: test results - fsharp (no summary found).

Html Report (VSDrops) Download

❌ monotouch tests (macOS)

🔥 Failed catastrophically on VSTS: test results - monotouch_macos (no summary found).

Html Report (VSDrops) Download

Successes

✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ generator: All 1 tests passed. Html Report (VSDrops) Download
✅ install-source: All 1 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker: All 40 tests passed. Html Report (VSDrops) Download
⚠️ mac-binding-project: No tests selected. Html Report (VSDrops) Download
⚠️ mmp: No tests selected. Html Report (VSDrops) Download
⚠️ mononative: No tests selected. Html Report (VSDrops) Download
✅ monotouch (iOS): All 7 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 8 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 7 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
⚠️ mtouch: No tests selected. Html Report (VSDrops) Download
⚠️ xammac: No tests selected. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

Pipeline on Agent
Hash: 3c83e65de78e3ec58b6b7c22362658fa83939572 [CI build]

Please sign in to comment.