Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 23, 2025

Overview

This PR introduces a centralized MES version validation system that eliminates repetitive version check code from individual commands. Instead of manually validating MES versions in each command's execute method, commands can now declaratively specify their minimum required MES version using the MinimumMESVersion property on the CmfCommand attribute.

Problem

Previously, commands requiring a minimum MES version had to implement manual validation logic:

[CmfCommand("taskLibrary", ParentId = "new_iot", Id = "iot_tasklibrary")]
public class GenerateTaskLibraryCommand : TemplateCommand
{
    public void Execute(IDirectoryInfo workingDir)
    {
        if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 11)
        {
            throw new CliException("This command is only valid for versions above 11.0.0");
        }
        
        // Command implementation...
    }
}

This approach had several drawbacks:

  • Code duplication - Same validation logic repeated across multiple commands
  • Inconsistent error messages - Different commands used slightly different wording
  • Maintenance burden - Version requirements scattered throughout the codebase
  • Reduced clarity - Version requirements hidden in method bodies

Solution

Commands can now declaratively specify minimum MES version requirements:

[CmfCommand("taskLibrary", ParentId = "new_iot", Id = "iot_tasklibrary", MinimumMESVersion = "11.0.0")]
public class GenerateTaskLibraryCommand : TemplateCommand
{
    public void Execute(IDirectoryInfo workingDir)
    {
        // Command implementation - no manual validation needed!
    }
}

The validation happens automatically before command execution, providing consistent error messages to users:

This command requires MES version 11.0.0 or higher. Current version: 10.5.0

Implementation Details

Core Components

  1. MESVersionValidationService (core/Objects/MESVersionValidationService.cs)

    • Service interface IMESVersionValidationService with validation methods
    • Implementation supporting semantic version comparison
    • Custom exception MESVersionValidationException for clear error handling
  2. CmfCommandAttribute Enhancement (core/Attributes/CmfCommandAttribute.cs)

    • Added MinimumMESVersion property (string)
    • Supports semantic versioning format (e.g., "11.0.0", "11.1.5")
  3. Automatic Validation Integration (core/Commands/BaseCommand.cs)

    • Modified FindChildCommands() to automatically add validators when MinimumMESVersion is specified
    • Validators execute before command handlers
    • Graceful error handling with user-friendly messages
  4. Service Registration (core/StartupModule.cs)

    • Registered IMESVersionValidationService in the DI container

Commands Migrated

Five IoT commands have been migrated from manual to declarative validation:

  • GenerateTaskLibraryCommand - requires MES 11.0.0+
  • GenerateConverterCommand - requires MES 11.0.0+
  • GenerateBusinessScenarioCommand - requires MES 11.1.0+
  • GenerateDotnetFrameworkDriverCommand - requires MES 11.0.0+
  • GenerateDriverCommand - requires MES 11.0.0+

Testing

Comprehensive test coverage ensures reliability:

  • 17 unit tests (tests/Specs/MESVersionValidation.cs)

    • Version comparison logic for all scenarios
    • Edge case handling (null, empty, invalid formats)
    • ExecutionContext integration
  • 2 integration tests (tests/Specs/MESVersionCommandValidation.cs)

    • End-to-end command validation with System.CommandLine
    • Error message validation

All 19 tests passing ✅

Documentation

Complete documentation provided in docs/MES-Version-Validation.md:

  • Feature overview and architecture
  • Usage examples and migration guide
  • Best practices for when to use attribute vs manual validation

Benefits

  1. Eliminates Code Duplication - Removed ~31 lines of repetitive validation code
  2. Improves Maintainability - Single source of truth for validation logic
  3. Ensures Consistency - Uniform error messages across all commands
  4. Enhances Testability - Centralized service is easier to test and mock
  5. Increases Clarity - Version requirements visible at command declaration level
  6. Simplifies Development - New commands just add one property to the attribute

Backward Compatibility

100% Backward Compatible

  • Commands without MinimumMESVersion work exactly as before
  • Existing manual version checks continue to function
  • No breaking changes to public APIs
  • Old and new validation approaches can coexist

Usage for Future Commands

To add version requirements to new commands:

[CmfCommand("mycommand", ParentId = "parent", Id = "my_cmd", MinimumMESVersion = "11.0.0")]
public class MyCommand : BaseCommand
{
    // Implementation - validation happens automatically
}

Files Changed

  • Core Framework (4 files): Service implementation, attribute, base command, DI registration
  • Commands (5 files): Migrated IoT commands
  • Tests (2 files): Unit and integration tests
  • Documentation (1 file): Complete feature guide

Fixes #[issue-number]

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 0t3vsblobprodcus362.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • 1javsblobprodcus364.vsblob.vsassets.io
  • 1k9vsblobprodcus379.vsblob.vsassets.io
  • 1p7vsblobprodcus324.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • 1s1vsblobprodcus386.vsblob.vsassets.io
  • 2zrvsblobprodcus388.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • 37bvsblobprodcus311.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • 4m6vsblobprodcus384.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • 4vyvsblobprodcus361.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • 4zjvsblobprodcus390.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • 51yvsblobprodcus36.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • 5rqvsblobprodcus385.vsblob.vsassets.io
  • 7k6vsblobprodcus337.vsblob.vsassets.io
  • 80zvsblobprodcus35.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • 96bvsblobprodcus338.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • bcnvsblobprodcus378.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • c50vsblobprodcus330.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • c78vsblobprodcus322.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • cmf-nuget
    • Triggering command: npm install (dns block)
  • d0svsblobprodcus381.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • frdvsblobprodcus327.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (dns block)
  • gbsvsblobprodcus365.vsblob.vsassets.io
  • gervsblobprodcus329.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • h6tvsblobprodcus346.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • i1qvsblobprodcus353.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • jd4vsblobprodcus366.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • josvsblobprodcus372.vsblob.vsassets.io
  • jrqvsblobprodcus343.vsblob.vsassets.io
  • kgfvsblobprodcus314.vsblob.vsassets.io
  • kh4vsblobprodcus325.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • kijvsblobprodcus387.vsblob.vsassets.io
  • kmuvsblobprodcus389.vsblob.vsassets.io
  • kxqvsblobprodcus376.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • ljcvsblobprodcus317.vsblob.vsassets.io
  • m16vsblobprodcus374.vsblob.vsassets.io
  • m8dvsblobprodcus37.vsblob.vsassets.io
  • mfjvsblobprodcus373.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • nn8vsblobprodcus340.vsblob.vsassets.io
  • ofvvsblobprodcus315.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • p2ovsblobprodcus312.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • pc2vsblobprodcus360.vsblob.vsassets.io
  • pe3vsblobprodcus354.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • pe4vsblobprodcus351.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • pkvvsblobprodcus321.vsblob.vsassets.io
  • rcxvsblobprodcus328.vsblob.vsassets.io
  • s4uvsblobprodcus326.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • s8mvsblobprodcus38.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • se1vsblobprodcus349.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • tphvsblobprodcus375.vsblob.vsassets.io
  • ukkvsblobprodcus352.vsblob.vsassets.io
  • uy6vsblobprodcus34.vsblob.vsassets.io
    • Triggering command: dotnet build cmf-cli.sln (dns block)
  • v53vsblobprodcus320.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • vb4vsblobprodcus33.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • vwvvsblobprodcus334.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • x3yvsblobprodcus370.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • xupvsblobprodcus332.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
  • yluvsblobprodcus367.vsblob.vsassets.io
  • ytvvsblobprodcus310.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/tests/bin/Debug/net8.0/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/bin/Debug/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)
    • Triggering command: /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/cli/cli/cmf-cli/resources/template_feed/iot/driver-dotnet-framework/src/%directoryname%/dotnet/Cmf.Connect.IoT.Driver.%driveridentifier%/Cmf.Connect.IoT.Driver.%driveridentifier%.csproj --packages /home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/cli/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Centralized MES Version Validation</issue_title>
<issue_description>We are currently adding MES version validation logic individually to all commands that require a minimum MES version, using the following pattern:

if (ExecutionContext.Instance.ProjectConfig.MESVersion.Major < 11)
{
    throw new CliException("This command is only valid for versions above 11.0.0");
}

To improve maintainability and reduce code duplication, I propose introducing a centralized validation service that can be executed automatically for all commands.

Additionally, I suggest extending the CmfCommand definition to include a new attribute, e.g., compatibleMES="11.0.0", to declaratively specify the minimum required MES version for each command.

This approach would:

  • Simplify command implementation by removing repetitive validation logic.
  • Ensure consistency across all commands.
  • Make version compatibility easier to manage and update in the future.
    </issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #504


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits October 23, 2025 14:29
Co-authored-by: joaoopereira <3718704+joaoopereira@users.noreply.github.com>
Co-authored-by: joaoopereira <3718704+joaoopereira@users.noreply.github.com>
Co-authored-by: joaoopereira <3718704+joaoopereira@users.noreply.github.com>
Co-authored-by: joaoopereira <3718704+joaoopereira@users.noreply.github.com>
Copilot AI changed the title [WIP] Add centralized MES version validation service Add centralized MES version validation with declarative attribute support Oct 23, 2025
Copilot AI requested a review from joaoopereira October 23, 2025 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants