diff --git a/kiota.sln b/kiota.sln index 0f9857aaac..2ec6ecf0ac 100644 --- a/kiota.sln +++ b/kiota.sln @@ -19,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EAAC5CEA-33B EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KiotaGenerated", "src\Kiota.Generated\KiotaGenerated.csproj", "{01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginsManifest", "..\Microsoft.Plugins.Manifest\src\PluginsManifest\PluginsManifest.csproj", "{55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,6 +51,10 @@ Global {01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {01ABDF23-60CD-4CE3-8DC7-8654C4BA1EE8}.Release|Any CPU.Build.0 = Release|Any CPU + {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55D60842-09BB-4EA8-9DF6-4ED9D2B1AA05}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj index 3f54277d82..c807dd39ac 100644 --- a/src/Kiota.Builder/Kiota.Builder.csproj +++ b/src/Kiota.Builder/Kiota.Builder.csproj @@ -47,7 +47,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -62,4 +62,7 @@ + + + diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index ef638601fa..0b5c166811 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -10,10 +10,12 @@ using Kiota.Builder.Extensions; using Kiota.Builder.OpenApiExtensions; using Microsoft.OpenApi.ApiManifest; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; using Microsoft.OpenApi.Writers; using Microsoft.Plugins.Manifest; +using ValidationRuleSet = Microsoft.OpenApi.Validations.ValidationRuleSet; namespace Kiota.Builder.Plugins; @@ -258,13 +260,29 @@ private OpenApiDocument GetDocumentWithTrimmedComponentsAndResponses(OpenApiDocu private PluginManifestDocument GetManifestDocument(string openApiDocumentPath) { + // Validate OpenAPI + var ruleSet = new ValidationRuleSet + { + Microsoft.Plugins.Manifest.OpenApiRules.OpenApiServerUrlRule.ServerUrlMustBeHttps, + Microsoft.Plugins.Manifest.OpenApiRules.OpenApiCombinedAuthFlowRule + .PathsCanOnlyHaveOneSecuritySchemePerOperation(OAIDocument.SecurityRequirements), + Microsoft.Plugins.Manifest.OpenApiRules.OpenApiRequestBodySchemaRule.RequestBodySchemaObjectsMustNeverBeNested, + Microsoft.Plugins.Manifest.OpenApiRules.OpenApiApiKeyBearerRule.ApiKeyNotSupportedOnlyBearerPlusHttp(OAIDocument.SecurityRequirements) + }; + var errors = OAIDocument.Validate(ruleSet)?.ToArray(); + if (errors != null && errors.Length != 0) + { + var message = string.Join(Environment.NewLine, errors.Select(e => $"{e.Pointer}: {e.Message}")); + throw new InvalidOperationException(message); + } var (runtimes, functions, conversationStarters) = GetRuntimesFunctionsAndConversationStartersFromTree(OAIDocument, Configuration.PluginAuthInformation, TreeNode, openApiDocumentPath); var descriptionForHuman = OAIDocument.Info?.Description is string d && !string.IsNullOrEmpty(d) ? d : $"Description for {OAIDocument.Info?.Title}"; var manifestInfo = ExtractInfoFromDocument(OAIDocument.Info); + const string schemaVersion = "v2.1"; var pluginManifestDocument = new PluginManifestDocument { Schema = "https://developer.microsoft.com/json-schemas/copilot/plugin/v2.1/schema.json", - SchemaVersion = "v2.1", + SchemaVersion = schemaVersion, NameForHuman = OAIDocument.Info?.Title.CleanupXMLString(), DescriptionForHuman = descriptionForHuman, DescriptionForModel = manifestInfo.DescriptionForModel ?? descriptionForHuman, @@ -295,6 +313,7 @@ private PluginManifestDocument GetManifestDocument(string openApiDocumentPath) }) .ToList() }; + return pluginManifestDocument; }