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$"
],