diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d9dca36..22456b0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,9 @@ on: - main workflow_dispatch: + schedule: + - cron: "0 2 15-21 * 3" # Runs at 02:00 UTC on the 3rd Wednesday of every month + jobs: build: runs-on: windows-latest diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..6224b54 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,82 @@ +name: Deploy content to Pages + +on: + push: + branches: ["main"] + + workflow_dispatch: + + schedule: + - cron: "0 2 15-21 * 3" # Runs at 02:00 UTC on the 3rd Wednesday of every month + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + deploy: + environment: + name: github-pages + #url: ${{ steps.deployment.outputs.page_url }} + + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Download DocFX + shell: pwsh + run: | + Invoke-WebRequest -Uri https://github.com/dotnet/docfx/releases/download/v2.77.0/docfx-win-x64-v2.77.0.zip -OutFile docfx.zip + + - name: Extract DocFX + shell: pwsh + run: | + Expand-Archive -Path docfx.zip -DestinationPath ./docfx + + - name: Download material.zip + shell: pwsh + run: | + Invoke-WebRequest -Uri https://github.com/ovasquez/docfx-material/releases/download/1.0.0/material.zip -OutFile material.zip + + - name: Extract material.zip + shell: pwsh + run: | + Expand-Archive -Path material.zip -DestinationPath ./ + + - name: Add header to README.md + shell: pwsh + run: | + Add-Content -Path temp.md -Value "---" + Add-Content -Path temp.md -Value "outputFileName: index.html" + Add-Content -Path temp.md -Value "---" + Get-Content -Path README.md | Add-Content -Path temp.md + Move-Item -Path temp.md -Destination README.md -Force + + - name: Build documentation + shell: pwsh + run: .\docfx\docfx.exe docfx.json + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: Documentation + path: | + ./_site + + - name: Upload to Pages + uses: actions/upload-pages-artifact@v3 + with: + path: '_site/' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 80541ad..dda79a5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ **/.vs/** *.nupkg output*.json +_site/ +docs/ +src/.manifest diff --git a/README.md b/README.md index bc44db1..9f253ab 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,9 @@ -# AggregateConfigBuildTask +# Aggregate Config Build Task -**AggregateConfigBuildTask** is an MSBuild task that aggregates and transforms configuration files into more consumable formats like JSON, Azure ARM template parameters, YAML during the build process. +[![NuGet Version](https://img.shields.io/nuget/v/AggregateConfigBuildTask)](https://www.nuget.org/packages/AggregateConfigBuildTask) [![GitHub Build Status](https://img.shields.io/github/actions/workflow/status/richardsondev/AggregateConfigBuildTask/build.yml?branch=main +)](https://github.com/richardsondev/AggregateConfigBuildTask/actions/workflows/build.yml?query=branch%3Amain) -## Links - -* NuGet.org: https://www.nuget.org/packages/AggregateConfigBuildTask -* GitHub: https://github.com/richardsondev/AggregateConfigBuildTask +**AggregateConfigBuildTask** is a cross-platform MSBuild task that aggregates and transforms configuration files into more consumable formats like JSON, Azure ARM template parameters, YAML during the build process. ## Features @@ -14,6 +12,11 @@ - Optionally include the source file name in each configuration entry. - Embed output files as resources in the assembly for easy inclusion in your project. +## Links + +* NuGet.org: https://www.nuget.org/packages/AggregateConfigBuildTask +* GitHub: https://github.com/richardsondev/AggregateConfigBuildTask + ## Installation To install the `AggregateConfigBuildTask` NuGet package, run the following command: @@ -42,13 +45,15 @@ Alternatively, add the following line to your `.csproj` file: | **AdditionalProperties** | A set of custom top-level properties to include in the final output. Use `ItemGroup` syntax to define key-value pairs. See [below](#additional-properties) for usage details. | | | | **IsQuietMode** | When true, only warning and error logs are generated by the task, suppressing standard informational output. | `true`, `false` | `false` | -## File Types +### File Types -| File Type | Extensions | -|-------------|----------------------| -| **Json** | `.json` | -| **Arm** | `.json` | -| **Yaml** | `.yml`, `.yaml` | +The `InputDirectory` will be scanned for files based on the specified `InputType`. The following table lists the file extensions that will be considered for each `InputType`: + +| **InputType** | **Extensions Scanned** | +|---------------|------------------------| +| `Json` | `.json` | +| `Arm` | `.json` | +| `Yaml` | `.yml`, `.yaml` | ## Usage @@ -249,13 +254,117 @@ resources: } ``` +## Accessing Embedded Resources in C# Assemblies + +Embedding resources such as configuration files into your assembly allows you to package all necessary data within a single executable or library. + +In the following example, we'll demonstrate how to read and deserialize an embedded resource at runtime. + +### Embedded resource + +Consider the following YML configuration files that you want to merge and embed into your assembly: + +**configs/global.yml** +```yml +enabled: true +``` + +**configs/prod.yml** +```yml +environment: Production +``` + +### Project file reference + +Your project should contain a reference similar to below: + +**application.csproj** +```xml + + + + + + + +``` + +### Reading the embedded resource + +To access and deserialize the embedded JSON resource, use the following method: + +**application.cs** +```csharp +using System; +using System.IO; +using System.Reflection; +using System.Text.Json; + +public static T LoadFromEmbeddedResource(string resourceName) +{ + var assembly = Assembly.GetExecutingAssembly(); + using var stream = assembly.GetManifestResourceStream(resourceName) + ?? throw new FileNotFoundException($"Resource '{resourceName}' not found in assembly."); + + return JsonSerializer.Deserialize(stream, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }) ?? throw new InvalidOperationException("Failed to deserialize resource."); +} +``` + +### Defining the Configuration Class + +Create a class that matches the structure of your configuration: + +```csharp +public class AppConfig +{ + public bool Enabled { get; set; } + public string Environment { get; set; } +} +``` + +### Loading and Using the Configuration + +You can now load and use the configuration data as follows: + +```csharp +var applicationConfig = LoadFromEmbeddedResource("YourAssemblyName.output.json"); + +bool enabled = applicationConfig.Enabled; +Console.WriteLine($"Enabled: {enabled}"); // Outputs "True" + +string environment = applicationConfig.Environment; +Console.WriteLine($"Environment: {environment}"); // Outputs "Production" +``` + +**Note:** Replace `"YourAssemblyName.output.json"` with the actual resource name, which typically includes the assembly name and the output file name. + +### Finding the Correct Resource Name + +If you're unsure about the exact resource name, you can retrieve all resource names in the assembly by adding the following code and inspecting the output: + +```csharp +string[] resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); +foreach (var name in resourceNames) +{ + Console.WriteLine(name); +} +``` + +This will list all embedded resources, allowing you to confirm the correct name to use when loading the resource. + ## License This project is licensed under the MIT License. See the [LICENSE](https://github.com/richardsondev/AggregateConfigBuildTask/blob/main/LICENSE) file for details. ## Third-Party Libraries -This project leverages the following third-party libraries: +This project leverages the following third-party libraries that are bundled with the package: - **[YamlDotNet](https://github.com/aaubry/YamlDotNet)**\ __Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors__\ diff --git a/docfx.json b/docfx.json new file mode 100644 index 0000000..cdf4396 --- /dev/null +++ b/docfx.json @@ -0,0 +1,66 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "src/**/*.csproj", + "images/icon/*" + ], + "exclude": [ + "**/bin/**", + "**/obj/**" + ] + } + ], + "dest": "./docs" + } + ], + "build": { + "globalMetadata": { + "_appTitle": "Aggregate Config Build Task", + "_appName": "AggregateConfigBuildTask", + "_enableSearch": "true", + "_appLogoPath": "image/icon/icon_50.png", + "_appFaviconPath": "image/icon/favicon.ico", + "_enableNewTab": "true", + "_disableContribution": "false", + "includePrivateMembers": "true", + "_appFooter": "Copyright © 2024 Billy Richardson. Generated with DocFX" + }, + "resource": [ + { + "files": [ + "image/**" + ] + } + ], + "content": [ + { + "files": "docs/*.yml", + "dest": "./" + }, + { + "files": [ + "README.md", + "toc.yml" + ], + "dest": "./" + } + ], + "dest": "_site", + "sitemap": { + "baseUrl": "https://richardsondev.github.io/AggregateConfigBuildTask", + "priority": 0.1, + "changefreq": "monthly" + }, + "postProcessors": [ + "ExtractSearchIndex" + ], + "template": [ + "statictoc", + "modern", + "material" + ] + } +} diff --git a/image/icon/favicon.ico b/image/icon/favicon.ico new file mode 100644 index 0000000..62c295e Binary files /dev/null and b/image/icon/favicon.ico differ diff --git a/image/icon/icon_128.png b/image/icon/icon_128.png index 24acfb3..1a6adb2 100644 Binary files a/image/icon/icon_128.png and b/image/icon/icon_128.png differ diff --git a/image/icon/icon_50.png b/image/icon/icon_50.png new file mode 100644 index 0000000..8a4f8c0 Binary files /dev/null and b/image/icon/icon_50.png differ diff --git a/src/Task/AggregateConfigBuildTask.csproj b/src/Task/AggregateConfigBuildTask.csproj index ae59098..78079ea 100644 --- a/src/Task/AggregateConfigBuildTask.csproj +++ b/src/Task/AggregateConfigBuildTask.csproj @@ -16,9 +16,9 @@ AggregateConfigBuildTask 0.0.1 - richardsondev + Billy Richardson richardsondev - richardsondev + https://richardson.software Merges configuration files at build time, allowing them to be embedded as resources for streamlined deployment and access. yaml, json, arm, build, configuration, msbuild MIT @@ -53,11 +53,9 @@ - - licenses/YamlDotNet/LICENSE.txt - + licenses/LICENSE diff --git a/src/Task/AssemblyInfo.cs b/src/Task/AssemblyInfo.cs index 55e8f40..eedf9fc 100644 --- a/src/Task/AssemblyInfo.cs +++ b/src/Task/AssemblyInfo.cs @@ -4,5 +4,5 @@ [assembly: InternalsVisibleTo("AggregateConfig.Tests.Unit")] [assembly: AssemblyMetadata("Copyright", "2024")] -[assembly: AssemblyMetadata("Author", "richardsondev")] +[assembly: AssemblyMetadata("Author", "Billy Richardson")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/richardsondev/AggregateConfigBuildTask")] diff --git a/src/ThirdPartyNotices.txt b/src/ThirdPartyNotices.txt new file mode 100644 index 0000000..b78dc9a --- /dev/null +++ b/src/ThirdPartyNotices.txt @@ -0,0 +1,60 @@ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION + +AggregateConfigBuildTask is based on or incorporates material from the projects listed below. + +1. YamlDotNet (https://github.com/aaubry/YamlDotNet) +2. YamlDotNet.System.Text.Json (https://github.com/adamabdelhamed/PowerArgs) + + +%% YamlDotNet NOTICES AND INFORMATION BEGIN HERE +========================================= +Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +========================================= +END OF YamlDotNet NOTICES AND INFORMATION + +%% YamlDotNet.System.Text.Json NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT License + +Copyright (c) 2022 Ivan Josipovic + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +========================================= +END OF YamlDotNet.System.Text.Json NOTICES AND INFORMATION diff --git a/src/UnitTests/AssemblyInfo.cs b/src/UnitTests/AssemblyInfo.cs new file mode 100644 index 0000000..75f608b --- /dev/null +++ b/src/UnitTests/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] + +[assembly: AssemblyMetadata("Copyright", "2024")] +[assembly: AssemblyMetadata("Author", "Billy Richardson")] +[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/richardsondev/AggregateConfigBuildTask")] diff --git a/toc.yml b/toc.yml new file mode 100644 index 0000000..0d9c313 --- /dev/null +++ b/toc.yml @@ -0,0 +1,7 @@ +### YamlMime:TableOfContent +items: +- name: Home + href: README.md +- name: Code Docs + href: docs/ +memberLayout: memberpage