diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj index 8ac1659..dbf8ff6 100644 --- a/Sdk/Sdk.csproj +++ b/Sdk/Sdk.csproj @@ -43,8 +43,8 @@ By integrating this SDK into your build process, you can easily generate install - - + + diff --git a/Sdk/Tasks/CatalogInformation.cs b/Sdk/Tasks/CatalogInformation.cs index 7e2fcf9..d57f373 100644 --- a/Sdk/Tasks/CatalogInformation.cs +++ b/Sdk/Tasks/CatalogInformation.cs @@ -5,14 +5,22 @@ namespace Skyline.DataMiner.Sdk.Tasks { using System; + using System.Collections.Generic; using System.Diagnostics; using System.IO.Compression; + using System.Linq; + using System.Threading; using Microsoft.Build.Framework; + using Microsoft.CodeAnalysis; + + using NuGet.Packaging; using Skyline.DataMiner.CICD.FileSystem; using Skyline.DataMiner.Sdk.Helpers; + using static NuGet.Packaging.PackagingConstants; + using Task = Microsoft.Build.Utilities.Task; public class CatalogInformation : Task, ICancelableTask @@ -61,20 +69,33 @@ public override bool Execute() return true; } - string outputDirectory = BuildOutputHandler.GetOutputPath(Output, ProjectDirectory); - string destinationFilePath = fs.Path.Combine(outputDirectory, $"{PackageId}.{PackageVersion}.CatalogInformation.zip"); + // make a temporary directory to work in and make changes + string tempDirectory = FileSystem.Instance.Directory.CreateTemporaryDirectory(); + try + { + FileSystem.Instance.Directory.CopyRecursive(catalogInformationFolder, tempDirectory); - fs.File.DeleteFile(destinationFilePath); - ZipFile.CreateFromDirectory(catalogInformationFolder, destinationFilePath, CompressionLevel.Optimal, includeBaseDirectory: false); + AddOfficialNotices(fs, tempDirectory); - Log.LogMessage(MessageImportance.High, $"Successfully created zip '{destinationFilePath}'."); + string outputDirectory = BuildOutputHandler.GetOutputPath(Output, ProjectDirectory); + string destinationFilePath = fs.Path.Combine(outputDirectory, $"{PackageId}.{PackageVersion}.CatalogInformation.zip"); - if (cancel) + fs.File.DeleteFile(destinationFilePath); + ZipFile.CreateFromDirectory(tempDirectory, destinationFilePath, CompressionLevel.Optimal, includeBaseDirectory: false); + + Log.LogMessage(MessageImportance.High, $"Successfully created zip '{destinationFilePath}'."); + + if (cancel) + { + return false; + } + + return !Log.HasLoggedErrors; + } + finally { - return false; + FileSystem.Instance.Directory.DeleteDirectory(tempDirectory); } - - return !Log.HasLoggedErrors; } catch (Exception e) { @@ -87,5 +108,51 @@ public override bool Execute() Log.LogMessage(MessageImportance.High, $"Catalog information creation for '{PackageId}' took {timer.ElapsedMilliseconds} ms."); } } + + private void AddOfficialNotices(IFileSystem fs, string catalogInformationFolder) + { + // example D:\GITHUB\Skyline-QAOps\Skyline-QAOps-Package\PackageContent\CompanionFiles + var pathToPublicDirectoryOnSystem = fs.Path.Combine(@"C:\", "Skyline DataMiner", "Webpages", "Public"); + var webpagesPublicDirectory = fs.Path.Combine(ProjectDirectory, "PackageContent", "CompanionFiles", "Skyline DataMiner", "Webpages", "Public"); + if (fs.Directory.Exists(webpagesPublicDirectory)) + { + // Get all files and folders directly under webpagesPublicDirectory + var entries = fs.Directory + .EnumerateDirectories(webpagesPublicDirectory) + .Select(path => fs.Path.Combine(pathToPublicDirectoryOnSystem, fs.Path.GetFileName(path))) + .OrderBy(name => name) + .ToList(); + + entries.AddRange(fs.Directory + .EnumerateFiles(webpagesPublicDirectory) + .Select(path => fs.Path.Combine(pathToPublicDirectoryOnSystem, fs.Path.GetFileName(path))) + .OrderBy(name => name) + .ToList()); + + if (entries.Count > 0) + { + var readmeFilePath = fs.Path.Combine(catalogInformationFolder, "README.md"); + if (fs.File.Exists(readmeFilePath)) + { + var noticeLines = new List + { + "", + "", + "> [!IMPORTANT]", + ">", + $"> - For DataMiner versions prior to 10.5.10, this package includes files located in `{pathToPublicDirectoryOnSystem}` that are **not automatically deployed** to all Agents in a DataMiner System.", + "> - To ensure proper functionality across the entire cluster, manually copy the following files and folders to the corresponding location on each Agent after installation:", + ">", + }; + + noticeLines.AddRange(entries.Select(e => $"> - `{e}`")); + noticeLines.Add(""); // final newline for clean formatting + + var noticeText = string.Join(Environment.NewLine, noticeLines); + fs.File.AppendAllText(readmeFilePath, noticeText); + } + } + } + } } } \ No newline at end of file diff --git a/SdkTests/SdkTests.csproj b/SdkTests/SdkTests.csproj index 8790916..f4ad545 100644 --- a/SdkTests/SdkTests.csproj +++ b/SdkTests/SdkTests.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/SdkTests/Tasks/DmappCreationTests.cs b/SdkTests/Tasks/DmappCreationTests.cs index 07b5067..883a87a 100644 --- a/SdkTests/Tasks/DmappCreationTests.cs +++ b/SdkTests/Tasks/DmappCreationTests.cs @@ -1,5 +1,7 @@ namespace SdkTests.Tasks { + using System.IO.Compression; + using FluentAssertions; using Microsoft.Build.Framework; @@ -95,5 +97,126 @@ public void ExecuteTest_Package6() FileSystem.Instance.Directory.DeleteDirectory(tempDirectory); } } + + [TestMethod] + public void ExecuteCatalogInformation_NoNotice() + { + string tempDirectory = FileSystem.Instance.Directory.CreateTemporaryDirectory(); + try + { + string projectDir = FileSystem.Instance.Path.Combine(TestHelper.GetTestFilesDirectory(), "Package 6", "My Package"); + + CatalogInformation info = new CatalogInformation() + { + ProjectDirectory = projectDir, + Output = tempDirectory, + PackageId = "My Package", + PackageVersion = "1.0.0", + BuildEngine = buildEngine.Object + }; + + string expectedDestinationFilePath = FileSystem.Instance.Path.Combine( + tempDirectory, + BuildOutputHandler.BuildDirectoryName, + $"{info.PackageId}.{info.PackageVersion}.CatalogInformation.zip"); + + // LOAD original README.md + string expectedReadmePath = FileSystem.Instance.Path.Combine(projectDir, "CatalogInformation", "README.md"); + FileSystem.Instance.File.Exists(expectedReadmePath).Should().BeTrue("expected README.md must exist"); + string expectedReadmeContent = FileSystem.Instance.File.ReadAllText(expectedReadmePath); + + // Act + bool result = info.Execute(); + errors.Should().BeEmpty(); + result.Should().BeTrue(); + FileSystem.Instance.File.Exists(expectedDestinationFilePath).Should().BeTrue(); + + // UNZIP to a temporary folder + string unzipDir = FileSystem.Instance.Path.Combine(tempDirectory, "unzipped"); + ZipFile.ExtractToDirectory(expectedDestinationFilePath, unzipDir); + + // FIND README.md inside the unzipped content + string[] readmeFiles = Directory.GetFiles(unzipDir, "README.md", SearchOption.AllDirectories); + readmeFiles.Length.Should().Be(1, "there should be exactly one README.md in the zipped output"); + string actualReadmeContent = File.ReadAllText(readmeFiles[0]); + + // COMPARE + actualReadmeContent.Should().Be(expectedReadmeContent, "README.md content in zip should match source"); + } + finally + { + FileSystem.Instance.Directory.DeleteDirectory(tempDirectory); + } + } + + + [TestMethod] + public void ExecuteCatalogInformation_WithNotice() + { + string tempDirectory = FileSystem.Instance.Directory.CreateTemporaryDirectory(); + try + { + // Arrange + string projectDir = FileSystem.Instance.Path.Combine(TestHelper.GetTestFilesDirectory(), "Package 7", "My Package"); + + CatalogInformation info = new CatalogInformation() + { + ProjectDirectory = projectDir, + Output = tempDirectory, + PackageId = "My Package", + PackageVersion = "1.0.0", + BuildEngine = buildEngine.Object + }; + + string expectedDestinationFilePath = FileSystem.Instance.Path.Combine( + tempDirectory, + BuildOutputHandler.BuildDirectoryName, + $"{info.PackageId}.{info.PackageVersion}.CatalogInformation.zip"); + + // LOAD original README.md + string expectedReadmePath = FileSystem.Instance.Path.Combine(projectDir, "CatalogInformation", "README.md"); + FileSystem.Instance.File.Exists(expectedReadmePath).Should().BeTrue("expected README.md must exist"); + string expectedReadmeContent = FileSystem.Instance.File.ReadAllText(expectedReadmePath); + + // Act + bool result = info.Execute(); + errors.Should().BeEmpty(); + result.Should().BeTrue(); + FileSystem.Instance.File.Exists(expectedDestinationFilePath).Should().BeTrue(); + + // UNZIP to a temporary folder + string unzipDir = FileSystem.Instance.Path.Combine(tempDirectory, "unzipped"); + ZipFile.ExtractToDirectory(expectedDestinationFilePath, unzipDir); + + // FIND README.md inside the unzipped content + string[] readmeFiles = Directory.GetFiles(unzipDir, "README.md", SearchOption.AllDirectories); + readmeFiles.Length.Should().Be(1, "there should be exactly one README.md in the zipped output"); + string actualReadmeContent = File.ReadAllText(readmeFiles[0]); + string expectedOriginalReadmeContent = FileSystem.Instance.File.ReadAllText(expectedReadmePath); + + // Normalize line endings to \n and trim + string Normalize(string input) => + input.Replace("\r\n", "\n").Replace("\r", "\n").TrimEnd(); + + string expectedWithNotice = expectedOriginalReadmeContent + + "\n\n" + + "> [!IMPORTANT]\n" + + ">\n" + + "> - For DataMiner versions prior to 10.5.10, this package includes files located in `C:\\Skyline DataMiner\\Webpages\\Public` that are **not automatically deployed** to all Agents in a DataMiner System.\n" + + "> - To ensure proper functionality across the entire cluster, manually copy the following files and folders to the corresponding location on each Agent after installation:\n" + + ">\n" + + "> - `C:\\Skyline DataMiner\\Webpages\\Public\\MyDirectory`\n" + + "> - `C:\\Skyline DataMiner\\Webpages\\Public\\MyFile1.txt`\n" + + "> - `C:\\Skyline DataMiner\\Webpages\\Public\\XMLFile1.xml`"; + + + Normalize(actualReadmeContent) + .Should().Be(Normalize(expectedWithNotice), "README.md content in zip should match source with a notice appended to it."); + } + finally + { + FileSystem.Instance.Directory.DeleteDirectory(tempDirectory); + } + } } } \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/.editorconfig b/SdkTests/Test Files/Package 7/.editorconfig new file mode 100644 index 0000000..a612a7a --- /dev/null +++ b/SdkTests/Test Files/Package 7/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +indent_style = tab +indent_size = 4 +tab_width = 4 +end_of_line = crlf +trim_trailing_whitespace = true + +[*.cs] +dotnet_sort_system_directives_first = true \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/Directory.Build.props b/SdkTests/Test Files/Package 7/Directory.Build.props new file mode 100644 index 0000000..ef01745 --- /dev/null +++ b/SdkTests/Test Files/Package 7/Directory.Build.props @@ -0,0 +1,24 @@ + + + full + ..\Internal\Code Analysis\qaction-debug.ruleset + + + pdbonly + ..\Internal\Code Analysis\qaction-release.ruleset + + + + Properties\stylecop.json + + + Properties\.editorconfig + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-debug.ruleset b/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-debug.ruleset new file mode 100644 index 0000000..26e7d46 --- /dev/null +++ b/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-debug.ruleset @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-release.ruleset b/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-release.ruleset new file mode 100644 index 0000000..de0890a --- /dev/null +++ b/SdkTests/Test Files/Package 7/Internal/Code Analysis/qaction-release.ruleset @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/Internal/Code Analysis/stylecop.json b/SdkTests/Test Files/Package 7/Internal/Code Analysis/stylecop.json new file mode 100644 index 0000000..b2d519d --- /dev/null +++ b/SdkTests/Test Files/Package 7/Internal/Code Analysis/stylecop.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "indentation": { + "useTabs": true, + "tabSize": 4 + }, + "namingRules": { + "allowCommonHungarianPrefixes": false, + "allowedHungarianPrefixes": [ + "ab", + "ac", + "ad", + "af", + "ai", + "al", + "ao", + "as", + "ax", + "b", + "by", + "c", + "d", + "dt", + "e", + "f", + "hs", + "i", + "ip", + "is", + "l", + "lb", + "lc", + "ld", + "lf", + "li", + "ll", + "lo", + "ls", + "lx", + "my", + "no", + "o", + "qb", + "qc", + "qd", + "qf", + "qi", + "ql", + "qo", + "qs", + "qx", + "rx", + "s", + "sb", + "sc", + "sd", + "sf", + "sh", + "si", + "sl", + "so", + "ss", + "sx", + "to", + "ts", + "tx", + "ui", + "ul", + "x" + ] + } + } +} diff --git a/SdkTests/Test Files/Package 7/My Package/CatalogInformation/Images/wip.png b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/Images/wip.png new file mode 100644 index 0000000..2413c2d Binary files /dev/null and b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/Images/wip.png differ diff --git a/SdkTests/Test Files/Package 7/My Package/CatalogInformation/README.md b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/README.md new file mode 100644 index 0000000..0ef542d --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/README.md @@ -0,0 +1,3 @@ +# My Package + +![WIP](./Images/wip.png) \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/CatalogInformation/manifest.yml b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/manifest.yml new file mode 100644 index 0000000..1bd7ec5 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/CatalogInformation/manifest.yml @@ -0,0 +1,67 @@ +# [Required] +# Possible values for the Catalog item that can be deployed on a DataMiner System: +# - Automation: If the Catalog item is a general-purpose DataMiner Automation script. +# - Ad Hoc Data Source: If the Catalog item is a DataMiner Automation script designed for an ad hoc data source integration. +# - ChatOps Extension: If the Catalog item is a DataMiner Automation script designed as a ChatOps extension. +# - Connector: If the Catalog item is a DataMiner XML connector. +# - Custom Solution: If the Catalog item is a DataMiner Solution. +# - Data Query: If the Catalog item is a GQI data query. +# - Data Transformer: Includes a data transformer that enables you to modify data using a GQI data query before making it available to users in low-code apps or dashboards. +# - Dashboard: If the Catalog item is a DataMiner dashboard. +# - DevTool: If the Catalog item is a DevTool. +# - Learning & Sample: If the Catalog item is a sample. +# - Product Solution: If the Catalog item is a DataMiner Solution that is an out-of-the-box solution for a specific product. +# - Scripted Connector: If the Catalog item is a DataMiner scripted connector. +# - Standard Solution: If the Catalog item is a DataMiner Solution that is an out-of-the-box solution for a specific use case or application. +# - System Health: If the Catalog item is intended to monitor the health of a system. +# - User-Defined API: If the Catalog item is a DataMiner Automation script designed as a user-defined API. +# - Visual Overview: If the Catalog item is a Microsoft Visio design. +# +type: Custom Solution +# [Required] +# The ID of the Catalog item. +# All registered versions for the same ID are shown together in the Catalog. +# This ID cannot be changed. +# If the ID is not filled in, the registration will fail with HTTP status code 500. +# If the ID is filled in but does not exist yet, a new Catalog item will be registered with this ID. +# If the ID is filled in but does exist, properties of the item will be overwritten. +# Must be a valid GUID. +id: e9ef5f60-fa3f-4081-b879-39ffb031255a +# [Required] +# The human-friendly name of the Catalog item. +# Can be changed at any time. +# Max length: 100 characters. +# Cannot contain newlines. +# Cannot contain leading or trailing whitespace characters. +title: My Package +# [Optional] +# General information about the Catalog item. +# Max length: 100,000 characters +short_description: This is a custom solution for DataMiner. +# [Optional] +# A valid URL that points to the source code. +# A valid URL +# Max length: 2048 characters +# Note: When Skyline Communications Reusable GitHub workflows are used, this will be automatically filled in. +source_code_url: +# [Optional] +# A valid URL that points to documentation. +# A valid URL +# Max length: 2048 characters +# Note: When Skyline Communications Reusable GitHub workflows are used, this will be automatically filled in. +documentation_url: +# [Optional] +# People who are responsible for this Catalog item. Might be developers, but this is not required. +# Format: 'name (URL)' +# The name is required; max 256 characters. +# The email and URL are optional, and should be in valid email/URL formats. +owners: + - name: 'MOD' +# [Optional] +# Tags that allow you to categorize your Catalog items. +# Max number of tags: 5 +# Max length: 50 characters. +# Cannot contain newlines. +# Cannot contain leading or trailing whitespace characters. +tags: + - dataminer diff --git a/SdkTests/Test Files/Package 7/My Package/GettingStarted.md b/SdkTests/Test Files/Package 7/My Package/GettingStarted.md new file mode 100644 index 0000000..ab44a75 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/GettingStarted.md @@ -0,0 +1,110 @@ +# Getting Started with Skyline DataMiner DevOps + +Welcome to the Skyline DataMiner DevOps environment! +This quick-start guide will help you get up and running. +For more details and comprehensive instructions, please visit [DataMiner Docs](https://docs.dataminer.services/). + +## Creating a DataMiner Application Package + +This project is configured to create a `.dmapp` file every time you build the project. +When you compile or build the project, you will find the generated `.dmapp` in the standard output folder, typically the `bin` folder of your project. + +When you publish the project, a corresponding item will be created in the online DataMiner Catalog. + +## The DataMiner Package Project + +This project is designed to create multi-artifact packages in a straightforward manner. + +### Adding Extra Artifacts in the Same Solution + +You can right-click the solution and select **Add** and then **New Project**. This will allow you to select DataMiner project templates (e.g. adding additional Automation scripts). + +> [!NOTE] +> Connectors are currently not supported. + +Every **Skyline.DataMiner.SDK** project, except other DataMiner package projects, will by default be included within the `.dmapp` created by this project. +You can customize this behavior using the **PackageContent/ProjectReferences.xml** file. This allows you to add filters to include or exclude projects as needed. + + + +### Importing from DataMiner + +You can import specific items directly from a DataMiner Agent: + +1. Connect to an Agent via **Extensions > DIS > DMA > Connect**. + +1. If your Agent is not listed, add it by going to **Extensions > DIS > Settings** and clicking **Add** on the DMA tab. + +1. Once connected, you can import specific DataMiner artifacts: in your **Solution Explorer**, navigate to folders such as **PackageContent/Dashboards** or **PackageContent/LowCodeApps**, right-click, select **Add**, and select **Import DataMiner Dashboard/Low Code App** or the equivalent. + +## Executing Additional Code on Installation + +Open the **My Package.cs** file to write custom installation code. Common actions include creating elements, services, or views. + +**Quick tip:** Type `clGetDms` in the `.cs` file and press **Tab** twice to insert a snippet that gives you access to the **IDms** classes, making DataMiner manipulation easier. + +## Does Your Installation Code Need Configuration Files? + +You can add configuration files (e.g. `.json`, `.xml`) to the **SetupContent** folder, which can be accessed during installation. + +Access them in your code using: + +```csharp +string setupContentPath = installer.GetSetupContentDirectory(); +``` + + +## Publishing to the Catalog + +This project was created with support for publishing to the DataMiner Catalog. +You can publish your artifact manually through Visual Studio or by setting up a CI/CD workflow. + +### Manual Publishing + +1. Obtain an **Organization Key** from [admin.dataminer.services](https://admin.dataminer.services/) with the following scopes: + - **Register Catalog items** + - **Read Catalog items** + +1. Securely store the key using Visual Studio User Secrets: + + 1. Right-click the project and select **Manage User Secrets**. + + 1. Add the key in the following format: + + ```json + { + "skyline": { + "sdk": { + "catalogpublishtoken": "MyKeyHere" + } + } + } + ``` + +1. Publish the package by right-clicking your project in Visual Studio and then selecting the **Publish** option. + + This will open a new window, where you will find a Publish button and a link where your item will eventually be registered. + +**Recommendation:** To safeguard the quality of your product, consider using a CI/CD setup to run **dotnet publish** only after passing quality checks. + +### Changing the Version + +1. Navigate to your project in Visual Studio, right-click, and select Properties. + +1. Search for Package Version. + +1. Adjust the value as needed. + +### Changing the Version - Alternative + +1. Navigate to your project in Visual Studio and double-click it. + +1. Adjust the "Version" XML tag to the version you want to register. + + ```xml + 1.0.1 + ``` diff --git a/SdkTests/Test Files/Package 7/My Package/My Package.cs b/SdkTests/Test Files/Package 7/My Package/My Package.cs new file mode 100644 index 0000000..f0b440a --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/My Package.cs @@ -0,0 +1,36 @@ +using System; + +using Skyline.AppInstaller; +using Skyline.DataMiner.Automation; +using Skyline.DataMiner.Net.AppPackages; + +/// +/// DataMiner Script Class. +/// +internal class Script +{ + /// + /// The script entry point. + /// + /// Provides access to the Automation engine. + /// Provides access to the installation context. + [AutomationEntryPoint(AutomationEntryPointType.Types.InstallAppPackage)] + public void Install(IEngine engine, AppInstallContext context) + { + try + { + engine.Timeout = new TimeSpan(0, 10, 0); + engine.GenerateInformation("Starting installation"); + var installer = new AppInstaller(Engine.SLNetRaw, context); + installer.InstallDefaultContent(); + + string setupContentPath = installer.GetSetupContentDirectory(); + + // Custom installation logic can be added here for each individual install package. + } + catch (Exception e) + { + engine.ExitFail($"Exception encountered during installation: {e}"); + } + } +} \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/My Package.csproj b/SdkTests/Test Files/Package 7/My Package/My Package.csproj new file mode 100644 index 0000000..47f95d0 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/My Package.csproj @@ -0,0 +1,23 @@ + + + net48 + true + + + Package + True + 1.0.0 + Initial Version + + skyline:sdk:catalogpublishtoken + skyline:sdk:catalogdownloadtoken + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/My Package.xml b/SdkTests/Test Files/Package 7/My Package/My Package.xml new file mode 100644 index 0000000..c890fab --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/My Package.xml @@ -0,0 +1,26 @@ + + + My Package + + Automation + MOD + FALSE + + + + + + + + + + + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/CatalogReferences.xml b/SdkTests/Test Files/Package 7/My Package/PackageContent/CatalogReferences.xml new file mode 100644 index 0000000..4b6f754 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/CatalogReferences.xml @@ -0,0 +1,20 @@ + + + Microsoft Platform + + 1.1.3.25 + + + + Microsoft Platform + + 5.0.0 + + + + Microsoft Platform + + 6.0.0 + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/AboutThisFolder.md b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/AboutThisFolder.md new file mode 100644 index 0000000..fdf2173 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/AboutThisFolder.md @@ -0,0 +1 @@ +This folder can contain any file you would like to add under the Skyline DataMiner folder. Warning: it will overwrite any file with the same name. \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/MyDirectory/MyStuff.txt b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/MyDirectory/MyStuff.txt new file mode 100644 index 0000000..e69de29 diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/MyFile1.txt b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/MyFile1.txt new file mode 100644 index 0000000..05eac02 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/MyFile1.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/XMLFile1.xml b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/XMLFile1.xml new file mode 100644 index 0000000..7dde50e --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/CompanionFiles/Skyline DataMiner/Webpages/Public/XMLFile1.xml @@ -0,0 +1 @@ + diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/Dashboards/AboutThisFolder.md b/SdkTests/Test Files/Package 7/My Package/PackageContent/Dashboards/AboutThisFolder.md new file mode 100644 index 0000000..5ad682f --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/Dashboards/AboutThisFolder.md @@ -0,0 +1 @@ +This folder can contain .zip files containing dashboards exported from DataMiner. They will be imported during installation of a .dmapp. \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/LowCodeApps/AboutThisFolder.md b/SdkTests/Test Files/Package 7/My Package/PackageContent/LowCodeApps/AboutThisFolder.md new file mode 100644 index 0000000..0cf0cc3 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/LowCodeApps/AboutThisFolder.md @@ -0,0 +1 @@ +This folder can contain .zip files containing low-code apps exported from DataMiner. They will be imported during installation of a .dmapp. \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/PackageContent/ProjectReferences.xml b/SdkTests/Test Files/Package 7/My Package/PackageContent/ProjectReferences.xml new file mode 100644 index 0000000..da65000 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/PackageContent/ProjectReferences.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/README.md b/SdkTests/Test Files/Package 7/My Package/README.md new file mode 100644 index 0000000..98876b1 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/README.md @@ -0,0 +1 @@ +# Technical Documentation for My Package \ No newline at end of file diff --git a/SdkTests/Test Files/Package 7/My Package/SetupContent/AboutThisFolder.md b/SdkTests/Test Files/Package 7/My Package/SetupContent/AboutThisFolder.md new file mode 100644 index 0000000..100db93 --- /dev/null +++ b/SdkTests/Test Files/Package 7/My Package/SetupContent/AboutThisFolder.md @@ -0,0 +1 @@ +This directory contains files that can be used by the installer, e.g. by the install script. The files will be put in the C:\Skyline DataMiner\AppPackages\Installed\.\SetupContent directory. diff --git a/SdkTests/Test Files/Package 7/Package 7.sln b/SdkTests/Test Files/Package 7/Package 7.sln new file mode 100644 index 0000000..3536f2c --- /dev/null +++ b/SdkTests/Test Files/Package 7/Package 7.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35514.174 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "My Package", "My Package\My Package.csproj", "{389C15E0-FFB3-40C3-94B6-8B99886F0A04}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{83D48836-5BD5-4084-A12A-C2F663BD9002}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{79CFE612-F7E5-40FD-A6AC-26FABE6091E2}" + ProjectSection(SolutionItems) = preProject + Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset + Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset + Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {389C15E0-FFB3-40C3-94B6-8B99886F0A04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {389C15E0-FFB3-40C3-94B6-8B99886F0A04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {389C15E0-FFB3-40C3-94B6-8B99886F0A04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {389C15E0-FFB3-40C3-94B6-8B99886F0A04}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {79CFE612-F7E5-40FD-A6AC-26FABE6091E2} = {83D48836-5BD5-4084-A12A-C2F663BD9002} + EndGlobalSection +EndGlobal