diff --git a/.github/workflows/BuildPublishPipeline.yml b/.github/workflows/BuildPublishPipeline.yml index ab94c3e..72d732f 100644 --- a/.github/workflows/BuildPublishPipeline.yml +++ b/.github/workflows/BuildPublishPipeline.yml @@ -108,6 +108,8 @@ jobs: runs-on: ubuntu-latest strategy: + # Keep building even if a job fails, helps with troubleshooting + fail-fast: false # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs matrix: images: ${{ fromJson(needs.setmatrix.outputs.matrix).images }} diff --git a/CreateMatrix/CreateMatrix.csproj b/CreateMatrix/CreateMatrix.csproj index be34107..980a503 100644 --- a/CreateMatrix/CreateMatrix.csproj +++ b/CreateMatrix/CreateMatrix.csproj @@ -8,11 +8,14 @@ - - + + + + + diff --git a/CreateMatrix/JSON/Matrix.schema.json b/CreateMatrix/JSON/Matrix.schema.json index deaa681..5a45991 100644 --- a/CreateMatrix/JSON/Matrix.schema.json +++ b/CreateMatrix/JSON/Matrix.schema.json @@ -1,79 +1,46 @@ { - "$schema": "https://json-schema.org/draft-06/schema", - "$id": "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Matrix.schema.json", - "title": "CreateMatrix Matrix Schema", - "definitions": { - "ImageInfo": { - "type": [ - "object", - "null" - ], - "properties": { - "Name": { - "type": [ - "string", - "null" - ] - }, - "Branch": { - "type": [ - "string", - "null" - ] - }, - "CacheScope": { - "type": [ - "string", - "null" - ] - }, - "Tags": { - "type": [ - "array", - "null" - ], - "items": { - "type": [ - "string", - "null" - ] - } - }, - "Args": { - "type": [ - "array", - "null" - ], - "items": { - "type": [ - "string", - "null" - ] + "type": "object", + "properties": { + "Images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Args": { + "$ref": "#/$defs/listOfString" + }, + "Branch": { + "type": "string" + }, + "CacheScope": { + "type": "string" + }, + "Name": { + "type": "string" + }, + "Tags": { + "$ref": "#/$defs/listOfString" } } } - } - }, - "type": "object", - "properties": { + }, "$schema": { - "type": [ - "string", - "null" - ] + "type": "string", + "readOnly": true }, "SchemaVersion": { - "type": "integer", - "default": 0 - }, - "Images": { + "type": "integer" + } + }, + "$defs": { + "listOfString": { "type": "array", "items": { - "$ref": "#/definitions/ImageInfo" + "type": "string" } } }, - "required": [ - "Images" - ] + "title": "CreateMatrix Matrix Schema", + "$id": "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Matrix.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema" } \ No newline at end of file diff --git a/CreateMatrix/JSON/Version.schema.json b/CreateMatrix/JSON/Version.schema.json index 447ff9e..12d5c56 100644 --- a/CreateMatrix/JSON/Version.schema.json +++ b/CreateMatrix/JSON/Version.schema.json @@ -1,80 +1,60 @@ { - "$schema": "https://json-schema.org/draft-06/schema", - "$id": "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Version.schema.json", - "title": "CreateMatrix Version Schema", - "definitions": { - "ProductInfo": { - "type": [ - "object", - "null" - ], - "properties": { - "Product": {}, - "Versions": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/VersionInfo" + "type": "object", + "properties": { + "Products": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Product": { + "enum": [ + "None", + "NxMeta", + "NxWitness", + "DWSpectrum" + ] + }, + "Versions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Labels": { + "type": "array", + "items": { + "enum": [ + "None", + "Stable", + "Latest", + "Beta", + "RC" + ] + } + }, + "UriArm64": { + "type": "string" + }, + "UriX64": { + "type": "string" + }, + "Version": { + "type": "string" + } + } + } } } } }, - "VersionInfo": { - "type": [ - "object", - "null" - ], - "properties": { - "Version": { - "type": [ - "string", - "null" - ] - }, - "UriX64": { - "type": [ - "string", - "null" - ] - }, - "UriArm64": { - "type": [ - "string", - "null" - ] - }, - "Labels": { - "type": [ - "array", - "null" - ], - "items": {} - } - } - } - }, - "type": "object", - "properties": { "$schema": { - "type": [ - "string", - "null" - ] + "type": "string", + "readOnly": true }, "SchemaVersion": { - "type": "integer", - "default": 0 - }, - "Products": { - "type": "array", - "items": { - "$ref": "#/definitions/ProductInfo" - } + "type": "integer" } }, - "required": [ - "Products" - ] + "title": "CreateMatrix Version Schema", + "$id": "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Version.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema" } \ No newline at end of file diff --git a/CreateMatrix/MatrixJsonSchema.cs b/CreateMatrix/MatrixJsonSchema.cs index ea9207e..b5d498f 100644 --- a/CreateMatrix/MatrixJsonSchema.cs +++ b/CreateMatrix/MatrixJsonSchema.cs @@ -1,38 +1,30 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Schema.Generation; -// ReSharper disable PropertyCanBeMadeInitOnly.Global +using Json.Schema.Generation; +using Json.Schema; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; namespace CreateMatrix; public class MatrixJsonSchemaBase { - protected const string SchemaUri = "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Matrix.schema.json"; - // Schema reference - [JsonProperty(PropertyName = "$schema", Order = -3)] + [JsonPropertyName("$schema")] + [JsonPropertyOrder(-3)] public string Schema { get; } = SchemaUri; - // Default to 0 if no value specified, and always write the version first - [DefaultValue(0)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate, Order = -2)] + [JsonRequired] + [JsonPropertyOrder(-2)] public int SchemaVersion { get; set; } = MatrixJsonSchema.Version; + + protected const string SchemaUri = "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Matrix.schema.json"; } public class MatrixJsonSchema : MatrixJsonSchemaBase { public const int Version = 2; - private static readonly JsonSerializerSettings Settings = new() - { - Formatting = Formatting.Indented, - StringEscapeHandling = StringEscapeHandling.EscapeNonAscii, - NullValueHandling = NullValueHandling.Ignore, - ObjectCreationHandling = ObjectCreationHandling.Replace - }; - - [Required] + [JsonRequired] public List Images { get; set; } = []; public static MatrixJsonSchema FromFile(string path) @@ -47,12 +39,12 @@ public static void ToFile(string path, MatrixJsonSchema jsonSchema) private static string ToJson(MatrixJsonSchema jsonSchema) { - return JsonConvert.SerializeObject(jsonSchema, Settings); + return JsonSerializer.Serialize(jsonSchema, JsonWriteOptions); } private static MatrixJsonSchema FromJson(string jsonString) { - var matrixJsonSchemaBase = JsonConvert.DeserializeObject(jsonString, Settings); + var matrixJsonSchemaBase = JsonSerializer.Deserialize(jsonString, JsonReadOptions); ArgumentNullException.ThrowIfNull(matrixJsonSchemaBase); // Deserialize the correct version @@ -61,29 +53,60 @@ private static MatrixJsonSchema FromJson(string jsonString) { // Current version case Version: - var schema = JsonConvert.DeserializeObject(jsonString, Settings); + var schema = JsonSerializer.Deserialize(jsonString, JsonReadOptions); ArgumentNullException.ThrowIfNull(schema); return schema; - case 1: + // case 1: // VersionInfo::Uri was replaced with UriX64 and UriArm64 was added // Breaking change, UriArm64 is required in ARM64 docker builds - throw new InvalidEnumArgumentException($"Unsupported SchemaVersion: {schemaVersion}"); // Unknown version default: - throw new InvalidEnumArgumentException($"Unknown SchemaVersion: {schemaVersion}"); + throw new NotImplementedException(); } } public static void GenerateSchema(string path) { - var generator = new JSchemaGenerator + const string schemaVersion = "https://json-schema.org/draft/2020-12/schema"; + var schemaBuilder = new JsonSchemaBuilder().FromType(new SchemaGeneratorConfiguration { PropertyOrder = PropertyOrder.ByName }) + .Title("CreateMatrix Matrix Schema") + .Id(new Uri(SchemaUri)) + .Schema(new Uri(schemaVersion)) + .Build(); + var jsonSchema = JsonSerializer.Serialize(schemaBuilder, JsonWriteOptions); + File.WriteAllText(path, jsonSchema); + } + + public static readonly JsonSerializerOptions JsonReadOptions = new() + { + AllowTrailingCommas = true, + IncludeFields = true, + NumberHandling = JsonNumberHandling.AllowReadingFromString, + PreferredObjectCreationHandling = JsonObjectCreationHandling.Replace, + ReadCommentHandling = JsonCommentHandling.Skip + }; + + public static readonly JsonSerializerOptions JsonWriteOptions = new() + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + IncludeFields = true, + TypeInfoResolver = new DefaultJsonTypeInfoResolver() + .WithAddedModifier(ExcludeObsoletePropertiesModifier), + WriteIndented = true + }; + + private static void ExcludeObsoletePropertiesModifier(JsonTypeInfo typeInfo) + { + // Only process objects + if (typeInfo.Kind != JsonTypeInfoKind.Object) + return; + + // Iterate over all properties + foreach (var property in typeInfo.Properties) { - DefaultRequired = Required.Default - }; - var schema = generator.Generate(typeof(MatrixJsonSchema)); - schema.Title = "CreateMatrix Matrix Schema"; - schema.SchemaVersion = new Uri("https://json-schema.org/draft-06/schema"); - schema.Id = new Uri(SchemaUri); - File.WriteAllText(path, schema.ToString()); + // Do not serialize [Obsolete] items + if (property.AttributeProvider?.IsDefined(typeof(ObsoleteAttribute), true) == true) + property.ShouldSerialize = (_, _) => false; + } } -} \ No newline at end of file +} diff --git a/CreateMatrix/PackagesJsonSchema.cs b/CreateMatrix/PackagesJsonSchema.cs index 17c2f90..a81c41a 100644 --- a/CreateMatrix/PackagesJsonSchema.cs +++ b/CreateMatrix/PackagesJsonSchema.cs @@ -1,5 +1,6 @@ using System.Diagnostics; -using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; using Serilog; namespace CreateMatrix; @@ -8,78 +9,57 @@ namespace CreateMatrix; // https://updates.networkoptix.com/metavms/35134/packages.json // https://updates.networkoptix.com/default/35270/packages.json // https://updates.networkoptix.com/digitalwatchdog/35271/packages.json -public class PackagesJsonSchema -{ - private static readonly JsonSerializerSettings Settings = new() - { - Formatting = Formatting.Indented, - StringEscapeHandling = StringEscapeHandling.EscapeNonAscii, - NullValueHandling = NullValueHandling.Ignore, - ObjectCreationHandling = ObjectCreationHandling.Replace - }; - - public class Variant - { - [JsonProperty("name")] public string Name { get; set; } = ""; - - [JsonProperty("minimumVersion")] public string MinimumVersion { get; set; } = ""; - } - - public class Package - { - [JsonProperty("component")] public string Component { get; set; } = ""; - [JsonProperty("platform")] public string PlatformName { get; set; } = ""; - - [JsonProperty("file")] public string File { get; set; } = ""; - - [JsonProperty("size")] public long Size { get; set; } +public class Variant +{ + [JsonPropertyName("name")] + public string Name { get; set; } = ""; +} - [JsonProperty("md5")] public string Md5 { get; set; } = ""; +public class Package +{ + [JsonPropertyName("component")] + public string Component { get; set; } = ""; - [JsonProperty("signature")] public string Signature { get; set; } = ""; + [JsonPropertyName("platform")] + public string PlatformName { get; set; } = ""; - [JsonProperty("variants")] public List Variants { get; set; } = []; + [JsonPropertyName("file")] + public string File { get; set; } = ""; - internal bool IsX64Server() - { - // Test for Server and x64 and Ubuntu - return Component.Equals("server", StringComparison.OrdinalIgnoreCase) && - PlatformName.Equals("linux_x64", StringComparison.OrdinalIgnoreCase) && - Variants.Any(variant => variant.Name.Equals("ubuntu", StringComparison.OrdinalIgnoreCase)); - } + [JsonPropertyName("variants")] + public List Variants { get; set; } = []; - internal bool IsArm64Server() - { - // Test for Server and Arm64 and Ubuntu - return Component.Equals("server", StringComparison.OrdinalIgnoreCase) && - PlatformName.Equals("linux_arm64", StringComparison.OrdinalIgnoreCase) && - Variants.Any(variant => variant.Name.Equals("ubuntu", StringComparison.OrdinalIgnoreCase)); - } + public bool IsX64Server() + { + // Test for Server and x64 and Ubuntu + return Component.Equals("server", StringComparison.OrdinalIgnoreCase) && + PlatformName.Equals("linux_x64", StringComparison.OrdinalIgnoreCase) && + Variants.Any(variant => variant.Name.Equals("ubuntu", StringComparison.OrdinalIgnoreCase)); } - [JsonProperty("version")] public string Version { get; set; } = ""; - - [JsonProperty("cloudHost")] public string CloudHost { get; set; } = ""; - - [JsonProperty("releaseNotesUrl")] public string ReleaseNotesUrl { get; set; } = ""; - - [JsonProperty("description")] public string Description { get; set; } = ""; - - [JsonProperty("eula")] public string Eula { get; set; } = ""; - - [JsonProperty("eulaVersion")] public long EulaVersion { get; set; } + public bool IsArm64Server() + { + // Test for Server and Arm64 and Ubuntu + return Component.Equals("server", StringComparison.OrdinalIgnoreCase) && + PlatformName.Equals("linux_arm64", StringComparison.OrdinalIgnoreCase) && + Variants.Any(variant => variant.Name.Equals("ubuntu", StringComparison.OrdinalIgnoreCase)); + } +} - [JsonProperty("packages")] public List Packages { get; set; } = []; +public class PackagesJsonSchema +{ + [JsonPropertyName("packages")] + public List Packages { get; set; } = []; private static PackagesJsonSchema FromJson(string jsonString) { - var jsonSchema = JsonConvert.DeserializeObject(jsonString, Settings); + var jsonSchema = JsonSerializer.Deserialize(jsonString, MatrixJsonSchema.JsonReadOptions); ArgumentNullException.ThrowIfNull(jsonSchema); return jsonSchema; } - internal static List GetPackages(HttpClient httpClient, string productName, int buildNumber) + public static List GetPackages(HttpClient httpClient, string productName, int buildNumber) { // Load packages JSON // https://updates.networkoptix.com/{product}/{build}/packages.json diff --git a/CreateMatrix/ProductInfo.cs b/CreateMatrix/ProductInfo.cs index 88bc2e3..a1f657f 100644 --- a/CreateMatrix/ProductInfo.cs +++ b/CreateMatrix/ProductInfo.cs @@ -1,21 +1,14 @@ using System.ComponentModel; using System.Diagnostics; using System.Reflection; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using System.Text.Json.Serialization; using Serilog; -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable PropertyCanBeMadeInitOnly.Global namespace CreateMatrix; public class ProductInfo { - // JSON serialized must be public get and set - - // Serialize enums as strings - // Use same spelling as used in Makefile - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum ProductType { None, @@ -41,7 +34,7 @@ private string GetProductShortName() }; } - internal static IEnumerable GetProductTypes() + public static IEnumerable GetProductTypes() { // Create list of product types return Enum.GetValues(typeof(ProductType)).Cast().Where(productType => productType != ProductType.None).ToList(); @@ -55,6 +48,9 @@ public static List GetProducts() public void GetVersions() { + // Match the logic with ReleasesTests.CreateProductInfo() + // TODO: Refactor to reduce duplication and chance of divergence + // Get version information using releases.json and package.json Log.Logger.Information("{Product}: Getting online release information...", Product); try @@ -67,7 +63,7 @@ public void GetVersions() foreach (var release in releasesList) { // We expect only "vms" products - Debug.Assert(release.Product.Equals("vms", StringComparison.OrdinalIgnoreCase)); + Debug.Assert(release.Product.Equals(Release.VmsProduct, StringComparison.OrdinalIgnoreCase)); // Set version VersionInfo versionInfo = new(); @@ -85,10 +81,10 @@ public void GetVersions() // Get the x64 and arm64 server ubuntu server packages var packageX64 = packageList.Find(item => item.IsX64Server()); - Debug.Assert(packageX64 != default(PackagesJsonSchema.Package)); + Debug.Assert(packageX64 != default(Package)); Debug.Assert(!string.IsNullOrEmpty(packageX64.File)); var packageArm64 = packageList.Find(item => item.IsArm64Server()); - Debug.Assert(packageArm64 != default(PackagesJsonSchema.Package)); + Debug.Assert(packageArm64 != default(Package)); Debug.Assert(!string.IsNullOrEmpty(packageArm64.File)); // Create the download URLs @@ -123,7 +119,7 @@ private bool VerifyVersion(VersionInfo versionInfo) return false; } - private void AddLabel(VersionInfo versionInfo, VersionInfo.LabelType label) + public void AddLabel(VersionInfo versionInfo, VersionInfo.LabelType label) { // Ignore if label is None if (label == VersionInfo.LabelType.None) @@ -164,7 +160,7 @@ private void AddLabel(VersionInfo versionInfo, VersionInfo.LabelType label) return default; } - private void VerifyLabels() + public void VerifyLabels() { // Sort by version number Versions.Sort(new VersionInfoComparer()); diff --git a/CreateMatrix/Program.cs b/CreateMatrix/Program.cs index c9bc5e6..af73715 100644 --- a/CreateMatrix/Program.cs +++ b/CreateMatrix/Program.cs @@ -10,7 +10,7 @@ namespace CreateMatrix; -internal static class Program +public static class Program { private static async Task Main(string[] args) { diff --git a/CreateMatrix/Properties/launchSettings.json b/CreateMatrix/Properties/launchSettings.json index f9a2edf..ba72c33 100644 --- a/CreateMatrix/Properties/launchSettings.json +++ b/CreateMatrix/Properties/launchSettings.json @@ -17,7 +17,7 @@ "Schema": { "commandName": "Project", "commandLineArgs": "schema --schemaversion ./JSON/Version.schema.json --schemamatrix ./JSON/Matrix.schema.json", - "workingDirectory": "$(SolutionDir)" + "workingDirectory": "$(ProjectDir)" }, "Make": { "commandName": "Project", diff --git a/CreateMatrix/ReleaseVersionForward.cs b/CreateMatrix/ReleaseVersionForward.cs index 7acbafd..e0e0cbf 100644 --- a/CreateMatrix/ReleaseVersionForward.cs +++ b/CreateMatrix/ReleaseVersionForward.cs @@ -2,30 +2,32 @@ namespace CreateMatrix; -internal static class ReleaseVersionForward +public static class ReleaseVersionForward { - internal static void Verify(List oldProductList, List newProductList) + public static void Verify(List oldProductList, List newProductList) { // newProductList will be updated in-place - // Verify all products - foreach (var product in ProductInfo.GetProductTypes()) + // Verify against all products in the old list + foreach (var oldProduct in oldProductList) { - // Find matching products - var oldProduct = oldProductList.First(item => item.Product == product); - var newProduct = newProductList.First(item => item.Product == product); + // Find matching new product, must be present + var newProduct = newProductList.First(item => item.Product == oldProduct.Product); - // Verify only Stable and Latest, other labels are optional - List< VersionInfo.LabelType> labels = [ VersionInfo.LabelType.Stable, VersionInfo.LabelType.Latest ]; - foreach (var label in labels) + // Verify all labels + foreach (var label in VersionInfo.GetLabelTypes()) Verify(oldProduct, newProduct, label); } } private static void Verify(ProductInfo oldProduct, ProductInfo newProduct, VersionInfo.LabelType label) { - // Find matching versions - var oldVersion = oldProduct.Versions.First(item => item.Labels.Contains(label)); + // Find label in old product, skip if not present + var oldVersion = oldProduct.Versions.FirstOrDefault(item => item.Labels.Contains(label)); + if (oldVersion == default(VersionInfo)) + return; + + // New product must have the same label var newVersion = newProduct.Versions.First(item => item.Labels.Contains(label)); // New version must be >= old version diff --git a/CreateMatrix/ReleasesJsonSchema.cs b/CreateMatrix/ReleasesJsonSchema.cs index 8908030..3323790 100644 --- a/CreateMatrix/ReleasesJsonSchema.cs +++ b/CreateMatrix/ReleasesJsonSchema.cs @@ -1,7 +1,8 @@ -using Newtonsoft.Json; -using System.Diagnostics; -using Serilog; +using System.Diagnostics; +using System.Text.Json; +using System.Text.Json.Serialization; using System.ComponentModel; +using Serilog; namespace CreateMatrix; @@ -9,64 +10,63 @@ namespace CreateMatrix; // https://updates.vmsproxy.com/default/releases.json // https://updates.vmsproxy.com/metavms/releases.json // https://updates.vmsproxy.com/digitalwatchdog/releases.json -public class ReleasesJsonSchema -{ - private static readonly JsonSerializerSettings Settings = new() - { - Formatting = Formatting.Indented, - StringEscapeHandling = StringEscapeHandling.EscapeNonAscii, - NullValueHandling = NullValueHandling.Ignore, - MissingMemberHandling = MissingMemberHandling.Ignore, - ObjectCreationHandling = ObjectCreationHandling.Replace - }; - - public class Release - { - [JsonProperty("product")] public string Product { get; set; } = ""; - [JsonProperty("version")] public string Version { get; set; } = ""; +public class Release +{ + [JsonPropertyName("product")] + public string Product { get; set; } = ""; - [JsonProperty("protocol_version")] public int ProtocolVersion { get; set; } + [JsonPropertyName("version")] + public string Version { get; set; } = ""; - [JsonProperty("publication_type")] public string PublicationType { get; set; } = ""; + [JsonPropertyName("publication_type")] + public string PublicationType { get; set; } = ""; - [JsonProperty("release_date")] public long ReleaseDate { get; set; } + [JsonPropertyName("release_date")] + public long? ReleaseDate { get; set; } - [JsonProperty("release_delivery_days")] public int ReleaseDeliveryDays { get; set; } + [JsonPropertyName("release_delivery_days")] + public long? ReleaseDeliveryDays { get; set; } - internal VersionInfo.LabelType GetLabel() - { - // Determine the equivalent label - return PublicationType switch - { - // Use Stable or Latest based on if published or not - "release" => IsPublished() ? VersionInfo.LabelType.Stable : VersionInfo.LabelType.Latest, - "rc" => VersionInfo.LabelType.RC, - "beta" => VersionInfo.LabelType.Beta, - _ => throw new InvalidEnumArgumentException($"Unknown PublicationType: {PublicationType}") - }; - } - private bool IsPublished() + public VersionInfo.LabelType GetLabel() + { + // Determine the equivalent label + return PublicationType switch { - // Logic follows similar patterns as used in C++ Desktop Client - // https://github.com/networkoptix/nx_open/blob/526967920636d3119c92a5220290ecc10957bf12/vms/libs/nx_vms_update/src/nx/vms/update/releases_info.cpp#L57 - // releases_info.cpp: ReleasesInfo::selectVmsRelease(), isBuildPublished(), canReceiveUnpublishedBuild() - return ReleaseDate > 0 && ReleaseDeliveryDays >= 0; - } + // Use Stable or Latest based on if published or not + ReleasePublication => IsPublished() ? VersionInfo.LabelType.Stable : VersionInfo.LabelType.Latest, + RcPublication => VersionInfo.LabelType.RC, + BetaPublication => VersionInfo.LabelType.Beta, + _ => throw new InvalidEnumArgumentException($"Unknown PublicationType: {PublicationType}") + }; } + public const string ReleasePublication = "release"; + public const string RcPublication = "rc"; + public const string BetaPublication = "beta"; + public const string VmsProduct = "vms"; - [JsonProperty("packages_urls")] public List PackagesUrls { get; set; } = []; + private bool IsPublished() + { + // Logic follows similar patterns as used in C++ Desktop Client + // https://github.com/networkoptix/nx_open/blob/526967920636d3119c92a5220290ecc10957bf12/vms/libs/nx_vms_update/src/nx/vms/update/releases_info.cpp#L57 + // releases_info.cpp: ReleasesInfo::selectVmsRelease(), isBuildPublished(), canReceiveUnpublishedBuild() + return ReleaseDate > 0 && ReleaseDeliveryDays >= 0; + } +} - [JsonProperty("releases")] public List Releases { get; set; } = []; +public class ReleasesJsonSchema +{ + [JsonPropertyName("releases")] + public List Releases { get; set; } = []; private static ReleasesJsonSchema FromJson(string jsonString) { - var jsonSchema = JsonConvert.DeserializeObject(jsonString, Settings); + var jsonSchema = JsonSerializer.Deserialize(jsonString, MatrixJsonSchema.JsonReadOptions); ArgumentNullException.ThrowIfNull(jsonSchema); return jsonSchema; } - internal static List GetReleases(HttpClient httpClient, string productName) + public static List GetReleases(HttpClient httpClient, string productName) { // Load releases JSON // https://updates.vmsproxy.com/{product}/releases.json diff --git a/CreateMatrix/VersionInfo.cs b/CreateMatrix/VersionInfo.cs index 88113e8..b8c5c7e 100644 --- a/CreateMatrix/VersionInfo.cs +++ b/CreateMatrix/VersionInfo.cs @@ -1,17 +1,10 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +using System.Text.Json.Serialization; namespace CreateMatrix; public class VersionInfo { - // JSON serialized must be public get and set - - // Serialize enums as strings - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof(JsonStringEnumConverter))] public enum LabelType { None, @@ -54,7 +47,7 @@ public int CompareTo(string rhs) return Compare(Version, rhs); } - internal static int Compare(string lhs, string rhs) + public static int Compare(string lhs, string rhs) { // Compare version numbers using Version class var lhsVersion = new Version(lhs); diff --git a/CreateMatrix/VersionJsonSchema.cs b/CreateMatrix/VersionJsonSchema.cs index b382264..463ff01 100644 --- a/CreateMatrix/VersionJsonSchema.cs +++ b/CreateMatrix/VersionJsonSchema.cs @@ -1,38 +1,28 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Schema.Generation; -// ReSharper disable PropertyCanBeMadeInitOnly.Global +using Json.Schema.Generation; +using Json.Schema; +using System.Text.Json; +using System.Text.Json.Serialization; namespace CreateMatrix; public class VersionJsonSchemaBase { - protected const string SchemaUri = "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Version.schema.json"; - - // Schema reference - [JsonProperty(PropertyName = "$schema", Order = -3)] + [JsonPropertyName("$schema")] + [JsonPropertyOrder(-3)] public string Schema { get; } = SchemaUri; - // Default to 0 if no value specified, and always write the version first - [DefaultValue(0)] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate, Order = -2)] + [JsonRequired] + [JsonPropertyOrder(-2)] public int SchemaVersion { get; set; } = VersionJsonSchema.Version; + + protected const string SchemaUri = "https://raw.githubusercontent.com/ptr727/NxWitness/main/CreateMatrix/JSON/Version.schema.json"; } public class VersionJsonSchema : VersionJsonSchemaBase { public const int Version = 2; - private static readonly JsonSerializerSettings Settings = new() - { - Formatting = Formatting.Indented, - StringEscapeHandling = StringEscapeHandling.EscapeNonAscii, - NullValueHandling = NullValueHandling.Ignore, - ObjectCreationHandling = ObjectCreationHandling.Replace - }; - - [Required] + [JsonRequired] public List Products { get; set; } = []; public static VersionJsonSchema FromFile(string path) @@ -48,43 +38,40 @@ public static void ToFile(string path, VersionJsonSchema jsonSchema) private static string ToJson(VersionJsonSchema jsonSchema) { - return JsonConvert.SerializeObject(jsonSchema, Settings); + return JsonSerializer.Serialize(jsonSchema, MatrixJsonSchema.JsonWriteOptions); } private static VersionJsonSchema FromJson(string jsonString) { - var versionJsonSchemaBase = JsonConvert.DeserializeObject(jsonString, Settings); + var versionJsonSchemaBase = JsonSerializer.Deserialize(jsonString, MatrixJsonSchema.JsonReadOptions); ArgumentNullException.ThrowIfNull(versionJsonSchemaBase); // Deserialize the correct version var schemaVersion = versionJsonSchemaBase.SchemaVersion; switch (schemaVersion) { - // Current version case Version: - var schema = JsonConvert.DeserializeObject(jsonString, Settings); + var schema = JsonSerializer.Deserialize(jsonString, MatrixJsonSchema.JsonReadOptions); ArgumentNullException.ThrowIfNull(schema); return schema; - case 1: + // case 1: // VersionInfo::Uri was replaced with UriX64 and UriArm64 was added // Breaking change, UriArm64 is required in ARM64 docker builds - throw new InvalidEnumArgumentException($"Unsupported SchemaVersion: {schemaVersion}"); // Unknown version default: - throw new InvalidEnumArgumentException($"Unknown SchemaVersion: {schemaVersion}"); + throw new NotImplementedException(); } } public static void GenerateSchema(string path) { - var generator = new JSchemaGenerator - { - DefaultRequired = Required.Default - }; - var schema = generator.Generate(typeof(VersionJsonSchema)); - schema.Title = "CreateMatrix Version Schema"; - schema.SchemaVersion = new Uri("https://json-schema.org/draft-06/schema"); - schema.Id = new Uri(SchemaUri); - File.WriteAllText(path, schema.ToString()); + const string schemaVersion = "https://json-schema.org/draft/2020-12/schema"; + var schemaBuilder = new JsonSchemaBuilder().FromType(new SchemaGeneratorConfiguration { PropertyOrder = PropertyOrder.ByName }) + .Title("CreateMatrix Version Schema") + .Id(new Uri(SchemaUri)) + .Schema(new Uri(schemaVersion)) + .Build(); + var jsonSchema = JsonSerializer.Serialize(schemaBuilder, MatrixJsonSchema.JsonWriteOptions); + File.WriteAllText(path, jsonSchema); } } \ No newline at end of file diff --git a/CreateMatrixTests/CreateMatrixTests.csproj b/CreateMatrixTests/CreateMatrixTests.csproj new file mode 100644 index 0000000..1b29a0a --- /dev/null +++ b/CreateMatrixTests/CreateMatrixTests.csproj @@ -0,0 +1,33 @@ + + + + net8.0 + enable + enable + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/CreateMatrixTests/ReleasesTests.cs b/CreateMatrixTests/ReleasesTests.cs new file mode 100644 index 0000000..7f15997 --- /dev/null +++ b/CreateMatrixTests/ReleasesTests.cs @@ -0,0 +1,178 @@ +using CreateMatrix; + +namespace CreateMatrixTests; + +public class ReleasesTests +{ + [Fact] + public void MatchLabels() + { + // Create test releases + var releasesSchema = new ReleasesJsonSchema + { + Releases = [ + // Stable, published and released + new Release { PublicationType = Release.ReleasePublication, ReleaseDate = 1, ReleaseDeliveryDays = 1, Version = "1.0" }, + // Latest, published not released + new Release { PublicationType = Release.ReleasePublication, Version = "2.0" }, + // RC + new Release { PublicationType = Release.RcPublication, Version = "3.0" }, + // Beta + new Release { PublicationType = Release.BetaPublication, Version = "4.0" } + ] + }; + + // Create ProductInfo from schema + var productInfo = CreateProductInfo(releasesSchema); + + // 4 versions + Assert.Equal(4, productInfo.Versions.Count); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + // 1 RC + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.RC))); + // 1 Beta + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Beta))); + // 1 label per version + Assert.Equal(4, productInfo.Versions.Count(item => item.Labels.Count == 1)); + } + + [Fact] + public void MissingLatest() + { + // Similar to MissingStable() + + // Create test releases + var releasesSchema = new ReleasesJsonSchema + { + Releases = [ + // Stable, published and released + new Release { PublicationType = Release.ReleasePublication, ReleaseDate = 1, ReleaseDeliveryDays = 1, Version = "1.0" }, + // RC + new Release { PublicationType = Release.RcPublication, Version = "3.0" }, + // Beta + new Release { PublicationType = Release.BetaPublication, Version = "4.0" } + ] + }; + + // Create ProductInfo from schema + var productInfo = CreateProductInfo(releasesSchema); + + // 3 versions + Assert.Equal(3, productInfo.Versions.Count); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + // 1 RC + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.RC))); + // 1 Beta + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Beta))); + + // Select all Latest or Stable labels + var latestVersions = productInfo.Versions.Where(item => item.Labels.Contains(VersionInfo.LabelType.Latest) || item.Labels.Contains(VersionInfo.LabelType.Stable)); + // Should just be 1 entry + Assert.Single(latestVersions); + // Should have Latest and Stable labels + var version = latestVersions.First(); + Assert.Equal(2, version.Labels.Count); + } + + [Fact] + public void MissingStable() + { + // Similar to MissingLatest() + + // Create test releases + var releasesSchema = new ReleasesJsonSchema + { + Releases = [ + // Latest, published not released + new Release { PublicationType = Release.ReleasePublication, Version = "1.0" }, + // RC + new Release { PublicationType = Release.RcPublication, Version = "3.0" }, + // Beta + new Release { PublicationType = Release.BetaPublication, Version = "4.0" } + ] + }; + + // Create ProductInfo from schema + var productInfo = CreateProductInfo(releasesSchema); + + // 3 versions + Assert.Equal(3, productInfo.Versions.Count); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + // 1 RC + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.RC))); + // 1 Beta + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Beta))); + + // Select all Latest or Stable labels + var latestVersions = productInfo.Versions.Where(item => item.Labels.Contains(VersionInfo.LabelType.Latest) || item.Labels.Contains(VersionInfo.LabelType.Stable)); + // Should just be 1 entry + Assert.Single(latestVersions); + // Should have Latest and Stable labels + var version = latestVersions.First(); + Assert.Equal(2, version.Labels.Count); + } + + [Fact] + public void MultipleReleases() + { + // Create test releases + var releasesSchema = new ReleasesJsonSchema + { + Releases = [ + // Published not released + new Release { PublicationType = Release.ReleasePublication, Version = "2.0" }, + new Release { PublicationType = Release.ReleasePublication, Version = "3.0" }, + new Release { PublicationType = Release.ReleasePublication, Version = "4.0" } + ] + }; + + // Create ProductInfo from schema + var productInfo = CreateProductInfo(releasesSchema); + + // 1 version + Assert.Single(productInfo.Versions); + // 2 labels per version + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Count == 2)); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + + // Select all Latest or Stable labels + var latestVersions = productInfo.Versions.Where(item => item.Labels.Contains(VersionInfo.LabelType.Latest) || item.Labels.Contains(VersionInfo.LabelType.Stable)); + // Should just be 1 entry + Assert.Single(latestVersions); + // Should have Latest and Stable labels + var version = latestVersions.First(); + Assert.Equal(2, version.Labels.Count); + + // Should be the v4.0 version + Assert.Equal("4.0", version.Version); + } + + private static ProductInfo CreateProductInfo(ReleasesJsonSchema releasesSchema) + { + // Match the logic with ProductInfo.GetVersions() + // TODO: Refactor to reduce duplication and chance of divergence + ProductInfo productInfo = new(); + foreach (var release in releasesSchema.Releases) + { + VersionInfo versionInfo = new(); + versionInfo.SetVersion(release.Version); + productInfo.AddLabel(versionInfo, release.GetLabel()); + productInfo.Versions.Add(versionInfo); + } + productInfo.VerifyLabels(); + + return productInfo; + } +} \ No newline at end of file diff --git a/CreateMatrixTests/VersionForwardTests.cs b/CreateMatrixTests/VersionForwardTests.cs new file mode 100644 index 0000000..f95dc39 --- /dev/null +++ b/CreateMatrixTests/VersionForwardTests.cs @@ -0,0 +1,130 @@ +using CreateMatrix; + +namespace CreateMatrixTests; + +public class VersionForwardTests +{ + [Fact] + public void VersionForward() + { + // Create test releases + var oldProductList = new List + { + new() + { + Product = ProductInfo.ProductType.NxMeta, + Versions = + [ + new VersionInfo { Version = "1.0", Labels = [VersionInfo.LabelType.Stable] }, + new VersionInfo { Version = "2.0", Labels = [VersionInfo.LabelType.Latest] }, + new VersionInfo { Version = "3.0", Labels = [VersionInfo.LabelType.RC] }, + new VersionInfo { Version = "4.0", Labels = [VersionInfo.LabelType.Beta] } + ] + } + }; + var newProductList = new List + { + new() + { + Product = ProductInfo.ProductType.NxMeta, + Versions = + [ + new VersionInfo { Version = "1.1", Labels = [VersionInfo.LabelType.Stable] }, + new VersionInfo { Version = "2.1", Labels = [VersionInfo.LabelType.Latest] }, + new VersionInfo { Version = "3.1", Labels = [VersionInfo.LabelType.RC] }, + new VersionInfo { Version = "4.1", Labels = [VersionInfo.LabelType.Beta] } + ] + } + }; + + // newProductList will be updated in-place + // Only Stable and Latest is tested + // Versions with multiple labels will update the version not the individual labels + ReleaseVersionForward.Verify(oldProductList, newProductList); + var productInfo = newProductList.First(); + + // 4 versions + Assert.Equal(4, productInfo.Versions.Count); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + // 1 RC + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.RC))); + // 1 Beta + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Beta))); + // 1 label per version + Assert.Equal(4, productInfo.Versions.Count(item => item.Labels.Count == 1)); + + // Stable 1.1 + Assert.Equal("1.1", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Stable))?.Version); + // Latest 2.1 + Assert.Equal("2.1", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Latest))?.Version); + // RC 3.1 + Assert.Equal("3.1", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.RC))?.Version); + // Beta 4.1 + Assert.Equal("4.1", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Beta))?.Version); + } + + [Fact] + public void VersionRegress() + { + // Create test releases + var oldProductList = new List + { + new() + { + Product = ProductInfo.ProductType.NxMeta, + Versions = + [ + new VersionInfo { Version = "1.0", Labels = [VersionInfo.LabelType.Stable] }, + new VersionInfo { Version = "2.0", Labels = [VersionInfo.LabelType.Latest] }, + new VersionInfo { Version = "3.0", Labels = [VersionInfo.LabelType.RC] }, + new VersionInfo { Version = "4.0", Labels = [VersionInfo.LabelType.Beta] } + ] + } + }; + var newProductList = new List + { + new() + { + Product = ProductInfo.ProductType.NxMeta, + Versions = + [ + new VersionInfo { Version = "0.9", Labels = [VersionInfo.LabelType.Stable] }, + new VersionInfo { Version = "1.9", Labels = [VersionInfo.LabelType.Latest] }, + new VersionInfo { Version = "2.9", Labels = [VersionInfo.LabelType.RC] }, + new VersionInfo { Version = "3.9", Labels = [VersionInfo.LabelType.Beta] } + ] + } + }; + + // newProductList will be updated in-place + // Only Stable and Latest is tested + // Versions with multiple labels will update the version not the individual labels + ReleaseVersionForward.Verify(oldProductList, newProductList); + var productInfo = newProductList.First(); + + // 4 versions + Assert.Equal(4, productInfo.Versions.Count); + // 1 Latest + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Latest))); + // 1 Stable + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Stable))); + // 1 RC + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.RC))); + // 1 Beta + Assert.Equal(1, productInfo.Versions.Count(item => item.Labels.Contains(VersionInfo.LabelType.Beta))); + // 1 label per version + Assert.Equal(4, productInfo.Versions.Count(item => item.Labels.Count == 1)); + + // Stable 1.0 + Assert.Equal("1.0", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Stable))?.Version); + // Latest 2.0 + Assert.Equal("2.0", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Latest))?.Version); + // RC 3.0 + Assert.Equal("3.0", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.RC))?.Version); + // Beta 4.0 + Assert.Equal("4.0", productInfo.Versions.Find(item => item.Labels.Contains(VersionInfo.LabelType.Beta))?.Version); + } +} \ No newline at end of file diff --git a/Docker/DWSpectrum-LSIO.Dockerfile b/Docker/DWSpectrum-LSIO.Dockerfile index 37653f2..35be5d5 100644 --- a/Docker/DWSpectrum-LSIO.Dockerfile +++ b/Docker/DWSpectrum-LSIO.Dockerfile @@ -82,6 +82,7 @@ RUN usermod -l ${COMPANY_NAME} abc \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ ./vms_server.deb \ # Cleanup diff --git a/Docker/DWSpectrum.Dockerfile b/Docker/DWSpectrum.Dockerfile index 18b10c5..24e1c30 100644 --- a/Docker/DWSpectrum.Dockerfile +++ b/Docker/DWSpectrum.Dockerfile @@ -69,6 +69,7 @@ RUN chmod +x download.sh \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ sudo \ ./vms_server.deb \ diff --git a/Docker/NxMeta-LSIO.Dockerfile b/Docker/NxMeta-LSIO.Dockerfile index 70dda07..a7b7b8c 100644 --- a/Docker/NxMeta-LSIO.Dockerfile +++ b/Docker/NxMeta-LSIO.Dockerfile @@ -82,6 +82,7 @@ RUN usermod -l ${COMPANY_NAME} abc \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ ./vms_server.deb \ # Cleanup diff --git a/Docker/NxMeta.Dockerfile b/Docker/NxMeta.Dockerfile index 7113e43..e7c57e5 100644 --- a/Docker/NxMeta.Dockerfile +++ b/Docker/NxMeta.Dockerfile @@ -69,6 +69,7 @@ RUN chmod +x download.sh \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ sudo \ ./vms_server.deb \ diff --git a/Docker/NxWitness-LSIO.Dockerfile b/Docker/NxWitness-LSIO.Dockerfile index a67127e..d9d535e 100644 --- a/Docker/NxWitness-LSIO.Dockerfile +++ b/Docker/NxWitness-LSIO.Dockerfile @@ -82,6 +82,7 @@ RUN usermod -l ${COMPANY_NAME} abc \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ ./vms_server.deb \ # Cleanup diff --git a/Docker/NxWitness.Dockerfile b/Docker/NxWitness.Dockerfile index 8fdc205..ed119ce 100644 --- a/Docker/NxWitness.Dockerfile +++ b/Docker/NxWitness.Dockerfile @@ -69,6 +69,7 @@ RUN chmod +x download.sh \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ sudo \ ./vms_server.deb \ diff --git a/Make/Build.sh b/Make/Build.sh index 4080a67..282d5bc 100755 --- a/Make/Build.sh +++ b/Make/Build.sh @@ -12,10 +12,10 @@ set -e # docker run -it --rm lsiobase/ubuntu:jammy /bin/bash # export DEBIAN_FRONTEND=noninteractive # apt-get update && apt-get upgrade --yes -# apt-get install --no-install-recommends --yes mc nano strace wget gdb -# wget --no-verbose --output-document=./vms_server.zip https://updates.networkoptix.com/metavms/37996/metavms-server_update-5.1.2.37996-linux_x64.zip +# apt-get install --no-install-recommends --yes ca-certificates unzip wget mc nano strace gdb +# wget --output-document=./vms_server.zip https://updates.networkoptix.com/metavms/38488/metavms-server_update-6.0.0.38488-linux_x64-beta.zip # unzip -d ./download_zip ./vms_server.zip -# cp ./download_zip/metavms-server-5.1.2.37996-linux_x64.deb ./vms_server.deb +# cp ./download_zip/metavms-server-6.0.0.38488-linux_x64-beta.deb ./vms_server.deb # Install: # apt-get install --no-install-recommends --yes ./vms_server.deb # Extract DEB package: diff --git a/Make/body-entrypoint.docker b/Make/body-entrypoint.docker index ae9da67..a00671c 100644 --- a/Make/body-entrypoint.docker +++ b/Make/body-entrypoint.docker @@ -1,6 +1,7 @@ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ sudo \ ./vms_server.deb \ diff --git a/Make/body-lsio.docker b/Make/body-lsio.docker index 1f95205..8f525a2 100644 --- a/Make/body-lsio.docker +++ b/Make/body-lsio.docker @@ -14,6 +14,7 @@ RUN usermod -l ${COMPANY_NAME} abc \ # Install the mediaserver and dependencies RUN apt-get update \ && apt-get install --no-install-recommends --yes \ + file \ gdb \ ./vms_server.deb \ # Cleanup diff --git a/NxWitness.code-workspace b/NxWitness.code-workspace index 77f8b81..a491c46 100644 --- a/NxWitness.code-workspace +++ b/NxWitness.code-workspace @@ -4,9 +4,7 @@ "path": "." } ], - "remoteAuthority": "wsl+ubuntu-20.04", "settings": { - "makefile.extensionOutputFolder": "./.vscode", "cSpell.words": [ "adduser", "appdata", @@ -60,12 +58,6 @@ "Viljoen", "WORKDIR", "xattr" - ], - "cSpell.ignoreWords": [ - "Repot" - ], - "yaml.schemas": { - "https://json.schemastore.org/github-issue-config.json": "file:///home/pieter/NxWitness/.github/ISSUE_TEMPLATE/config.yml" - } + ] } } \ No newline at end of file diff --git a/NxWitness.sln b/NxWitness.sln index 78abefd..c3c82da 100644 --- a/NxWitness.sln +++ b/NxWitness.sln @@ -9,8 +9,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .dockerignore = .dockerignore .gitignore = .gitignore + HubREADME.md = HubREADME.md LICENSE = LICENSE README.md = README.md + version.json = version.json EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Make", "Make", "{486D3D04-33A6-4311-9E86-A8FFD8610330}" @@ -20,6 +22,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Make", "Make", "{486D3D04-3 Make\body-entrypoint.docker = Make\body-entrypoint.docker Make\body-lsio.docker = Make\body-lsio.docker Make\body.docker = Make\body.docker + Make\Build.sh = Make\Build.sh + Make\Clean.sh = Make\Clean.sh + Make\Create.sh = Make\Create.sh Make\Down-develop.sh = Make\Down-develop.sh Make\Down.sh = Make\Down.sh Make\DWSpectrum-LSIO.m4 = Make\DWSpectrum-LSIO.m4 @@ -34,6 +39,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Make", "Make", "{486D3D04-3 Make\nxwitness.docker = Make\nxwitness.docker Make\NxWitness.m4 = Make\NxWitness.m4 Make\Test-develop.yml = Make\Test-develop.yml + Make\Test.sh = Make\Test.sh Make\Test.yml = Make\Test.yml Make\Up-develop.sh = Make\Up-develop.sh Make\Up.sh = Make\Up.sh @@ -55,6 +61,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7616 .github\workflows\DockerHubDescription.yml = .github\workflows\DockerHubDescription.yml EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docker", "Docker", "{7D1EA36A-E59A-4144-9014-D5ABFE44C432}" + ProjectSection(SolutionItems) = preProject + Docker\download.sh = Docker\download.sh + Docker\DWSpectrum-LSIO.Dockerfile = Docker\DWSpectrum-LSIO.Dockerfile + Docker\DWSpectrum.Dockerfile = Docker\DWSpectrum.Dockerfile + Docker\entrypoint.sh = Docker\entrypoint.sh + Docker\NxMeta-LSIO.Dockerfile = Docker\NxMeta-LSIO.Dockerfile + Docker\NxMeta.Dockerfile = Docker\NxMeta.Dockerfile + Docker\NxWitness-LSIO.Dockerfile = Docker\NxWitness-LSIO.Dockerfile + Docker\NxWitness.Dockerfile = Docker\NxWitness.Dockerfile + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreateMatrixTests", "CreateMatrixTests\CreateMatrixTests.csproj", "{2524A282-16D8-44FD-8704-40548C96A5C3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -65,6 +85,10 @@ Global {71CFB3CE-153B-4B61-975D-9FDE9ECD4136}.Debug|Any CPU.Build.0 = Debug|Any CPU {71CFB3CE-153B-4B61-975D-9FDE9ECD4136}.Release|Any CPU.ActiveCfg = Release|Any CPU {71CFB3CE-153B-4B61-975D-9FDE9ECD4136}.Release|Any CPU.Build.0 = Release|Any CPU + {2524A282-16D8-44FD-8704-40548C96A5C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2524A282-16D8-44FD-8704-40548C96A5C3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2524A282-16D8-44FD-8704-40548C96A5C3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2524A282-16D8-44FD-8704-40548C96A5C3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index db5dc23..e4bce0e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ Licensed under the [MIT License][license]. ## Release Notes +- Version 2.3: + - Added unit test project to verify the release and upgrade control logic. + - Switched from `Newtonsoft.Json` to .NET native `Text.Json`. - Version 2.2: - Simplified `Dockerfile` creation by using shell scripts instead of a `Makefile` (that I found too difficult to maintain and debug). - Version 2.1: diff --git a/version.json b/version.json index cffd46d..c0eecec 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "2.2", + "version": "2.3", "publicReleaseRefSpec": [ "^refs/heads/main$" ],