From e756da0ae2756cc6da4635fdd6f38395986bfa39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:29:48 +0000 Subject: [PATCH 1/3] Initial plan From f0902218a379709a07333dbeacb9cc8d0428b4e1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 09:47:19 +0000 Subject: [PATCH 2/3] Order yaml type meta fields first Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --- src/KubernetesClient/KubernetesYaml.cs | 30 ++++++++++++++-- .../KubernetesYamlTests.cs | 34 +++++++++++++++---- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/KubernetesClient/KubernetesYaml.cs b/src/KubernetesClient/KubernetesYaml.cs index ef5384c72..8c491e291 100644 --- a/src/KubernetesClient/KubernetesYaml.cs +++ b/src/KubernetesClient/KubernetesYaml.cs @@ -293,6 +293,7 @@ public static string Serialize(object value) private static TBuilder WithOverridesFromJsonPropertyAttributes(this TBuilder builder) where TBuilder : BuilderSkeleton { + var preferredPropertyOrder = new[] { "ApiVersion", "Kind", "Metadata" }; // Use VersionInfo from the model namespace as that should be stable. // If this is not generated in the future we will get an obvious compiler error. var targetNamespace = typeof(VersionInfo).Namespace; @@ -307,15 +308,38 @@ private static TBuilder WithOverridesFromJsonPropertyAttributes(this T // Map any JsonPropertyAttribute instances to YamlMemberAttribute instances. foreach (var type in types) { - foreach (var property in type.GetProperties()) + var properties = type.GetProperties() + .OrderBy(property => property.MetadataToken) + .ToArray(); + var usePreferredOrder = properties.Any(property => + property.Name == "ApiVersion" || + property.Name == "Kind"); + var nextOrder = usePreferredOrder ? preferredPropertyOrder.Length : 0; + foreach (var property in properties) { var jsonAttribute = property.GetCustomAttribute(); - if (jsonAttribute == null) + if (jsonAttribute == null && !usePreferredOrder) { continue; } - var yamlAttribute = new YamlMemberAttribute { Alias = jsonAttribute.Name, ApplyNamingConventions = false }; + var yamlAttribute = new YamlMemberAttribute(); + if (usePreferredOrder) + { + var order = Array.IndexOf(preferredPropertyOrder, property.Name); + if (order < 0) + { + order = nextOrder++; + } + + yamlAttribute.Order = order; + } + + if (jsonAttribute != null) + { + yamlAttribute.Alias = jsonAttribute.Name; + yamlAttribute.ApplyNamingConventions = false; + } builder.WithAttributeOverride(type, property.Name, yamlAttribute); } } diff --git a/tests/KubernetesClient.Tests/KubernetesYamlTests.cs b/tests/KubernetesClient.Tests/KubernetesYamlTests.cs index 95440e9e2..501d2d14c 100644 --- a/tests/KubernetesClient.Tests/KubernetesYamlTests.cs +++ b/tests/KubernetesClient.Tests/KubernetesYamlTests.cs @@ -822,12 +822,12 @@ public void WriteSecret() { var kManifest = """ apiVersion: v1 -data: - username: YlhrdFlYQnc= - password: TXprMU1qZ2tkbVJuTjBwaQ== kind: Secret metadata: name: test-secret +data: + username: YlhrdFlYQnc= + password: TXprMU1qZ2tkbVJuTjBwaQ== """; var result = KubernetesYaml.Deserialize(kManifest, true); @@ -860,13 +860,13 @@ public void WriteConfigMap() { var kManifest = """ apiVersion: v1 +kind: ConfigMap +metadata: + name: test-configmap binaryData: username: YlhrdFlYQnc= data: password: Mzk1MjgkdmRnN0pi -kind: ConfigMap -metadata: - name: test-configmap """; var result = KubernetesYaml.Deserialize(kManifest, true); @@ -875,6 +875,28 @@ public void WriteConfigMap() Assert.Equal(kManifest, yaml); } + [Fact] + public void WriteConfigMapOrdersTypeMetaFirst() + { + var configMap = new V1ConfigMap + { + ApiVersion = "v1", + Kind = "ConfigMap", + Metadata = new V1ObjectMeta { Name = "my-configmap", NamespaceProperty = "my-namespace" }, + Data = new Dictionary { { "array.json", "value" } }, + }; + + var yaml = KubernetesYaml.Serialize(configMap); + + Assert.Equal(ToLines(@"apiVersion: v1 +kind: ConfigMap +metadata: + name: my-configmap + namespace: my-namespace +data: + array.json: value"), ToLines(yaml)); + } + [Fact] public void DeserializeWithJsonPropertyName() { From 38a5ce38e0303c2b3bb5df77bd7bd1403ec9301b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 15:06:49 +0000 Subject: [PATCH 3/3] Fix StyleCop blank line in KubernetesYaml Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --- src/KubernetesClient/KubernetesYaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KubernetesClient/KubernetesYaml.cs b/src/KubernetesClient/KubernetesYaml.cs index 8c491e291..4891ce5fe 100644 --- a/src/KubernetesClient/KubernetesYaml.cs +++ b/src/KubernetesClient/KubernetesYaml.cs @@ -340,6 +340,7 @@ private static TBuilder WithOverridesFromJsonPropertyAttributes(this T yamlAttribute.Alias = jsonAttribute.Name; yamlAttribute.ApplyNamingConventions = false; } + builder.WithAttributeOverride(type, property.Name, yamlAttribute); } }