diff --git a/.azure-devops/build-all-lib.yml b/.azure-devops/build-all-lib.yml deleted file mode 100644 index dd13bd1b28..0000000000 --- a/.azure-devops/build-all-lib.yml +++ /dev/null @@ -1,23 +0,0 @@ -# Build all projects. - -# Build only manually -pr: none # Disable pull request triggers. -trigger: none # Disable dev and main branches. - -# Build.BuildNumber (see versioning.yml) -name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) - -pool: - name: Fluent-Blazor-1ESPT - -extends: - template: common/template-to-build-projects.yml - parameters: - Projects: | - **/Microsoft.FluentUI.AspNetCore.Components.csproj - **/Microsoft.FluentUI.AspNetCore.Components.Icons.csproj - **/Microsoft.FluentUI.AspNetCore.Components.Emoji.csproj - **/Microsoft.FluentUI.AspNetCore.Templates.csproj - **/Microsoft.FluentUI.AspNetCore.Components.DataGrid.EntityFrameworkAdapter.csproj - Tests: | - **/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj diff --git a/.azure-devops/build-core-lib.yml b/.azure-devops/build-core-lib.yml deleted file mode 100644 index 9998600a1d..0000000000 --- a/.azure-devops/build-core-lib.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Build and test Core project. - -pr: -- main -- dev -trigger: -- main -- dev - -# Build.BuildNumber (see versioning.yml) -name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) - -pool: - name: Fluent-Blazor-1ESPT - -extends: - template: common/template-to-build-projects.yml - parameters: - Projects: | - **/Microsoft.FluentUI.AspNetCore.Components.csproj - Tests: | - **/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj diff --git a/.azure-devops/build-demo.yml b/.azure-devops/build-demo.yml deleted file mode 100644 index 586b5b08e1..0000000000 --- a/.azure-devops/build-demo.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Build Demo project. - -pr: none # Disable pull request triggers. -trigger: -- main -- dev - -# Build.BuildNumber (see versioning.yml) -name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) - -pool: - name: Fluent-Blazor-1ESPT - -extends: - template: common/template-to-build-projects.yml - parameters: - Projects: | - **/FluentUI.Demo.Client.csproj - IsDemo: true diff --git a/.azure-devops/common/template-to-build-projects.yml b/.azure-devops/common/template-to-build-projects.yml deleted file mode 100644 index c591a556f8..0000000000 --- a/.azure-devops/common/template-to-build-projects.yml +++ /dev/null @@ -1,300 +0,0 @@ -parameters: -- name: Projects # List of projects to build - type: string - default: '' - -- name: Tests # List of Unit-Test projects to run - type: string - default: '' - -- name: IsDemo # Projects to publish - type: boolean - default: false - -variables: -- template: versioning.yml # Versions - -steps: - - # Compute AssemblyVersion and PackageVersion - # -> Update Versioning.yml - - powershell: | - - # Example with FileVersion: "1.2.4" and PackageSuffix: "RC.1" - # Build.BuildNumber = 1.2.4.23296.1 - # = $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) - - # Defaut values - $branch = "PR" - $package = "" - $demo = "${{ parameters.IsDemo }}".toLower() - - # To Sign and To Test - $sign = "false" - $toTest = "true" - - # BranchName = dev, main, archive or PR - if ("$(Build.SourceBranch)" -eq "refs/heads/main") - { - $branch = "main" - } - elseif ("$(Build.SourceBranch)" -eq "refs/heads/dev") - { - $branch = "dev" - } - elseif ("$(Build.SourceBranch)" -like "refs/heads/archives/*") - { - $branch = "archive" - } - else - { - $branch = "PR" - } - - # Debug Only - To remove - # if ("$(PublicVersion)" -ne "") - # { - # $branch = "$(PublicVersion)" - # } - - # [1, 2, 4, 23296, 1] - $builds = "$(Build.BuildNumber)".Split('.') - - # 1.2.4.23296 - $assembly = "$($builds[0]).$($builds[1]).$($builds[2]).$($builds[3])" - - # Main or Archive without PackageSuffix: 1.2.4 - # Main or Archive with PackageSuffix: 1.2.4-rc.1 - if ("$branch" -eq "main" -or "$branch" -eq "archive") - { - # Main without PackageSuffix - if ("$(PackageSuffix)" -eq "") - { - $package = "$($builds[0]).$($builds[1]).$($builds[2])" - } - - # Main with PackageSuffix - else - { - $package = "$($builds[0]).$($builds[1]).$($builds[2])-$(PackageSuffix)" - } - - $sign = "true" - $toTest = "true" - } - - # Dev: 1.2.4-preview-23296-1 - elseif ("$branch" -eq "dev") - { - $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" - $sign = "true" - $toTest = "true" - } - - # Other branches: 1.2.4-preview-23296-1 - else - { - $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" - $sign = "false" - $toTest = "true" - } - - if ("${{ parameters.Tests }}" -eq "") - { - $toTest = "false" - } - - if ("$demo" -eq "true") - { - $sign = "false" - } - - # Set the output variable for use in other tasks. - Write-Host "##vso[task.setvariable variable=BranchName]${branch}" - Write-Host "##vso[task.setvariable variable=AssemblyVersion]${assembly}" - Write-Host "##vso[task.setvariable variable=PackageVersion]${package}" - Write-Host "##vso[task.setvariable variable=ShouldSign]${sign}" - Write-Host "##vso[task.setvariable variable=ShouldTest]${toTest}" - Write-Host "##vso[task.setvariable variable=ShouldPublish]${demo}" - displayName: Compute AssemblyVersion and PackageVersion - - # Display computed variables - - script: | - echo 🔸 FileVersion = $(FileVersion) - echo 🔸 PackageSuffix = $(PackageSuffix) - echo 🔸 Build.BuildNumber = $(Build.BuildNumber) - echo 🔸 Build.SourceBranch = $(Build.SourceBranch) - echo ----------------------------------------------- - echo 🔸 BranchName = $(BranchName) - echo 🔸 AssemblyVersion = $(AssemblyVersion) - echo 🔸 PackageVersion = $(PackageVersion) - echo ----------------------------------------------- - echo 🔸 ShouldSign = $(ShouldSign) - echo 🔸 ShouldTest = $(ShouldTest) - echo 🔸 ShouldPublish = $(ShouldPublish) - displayName: Display computed variables - - # Install NuGet tools - - task: NuGetToolInstaller@1 - displayName: Install NuGet tools - - # Install .NET 6.0 - - task: UseDotNet@2 - displayName: Install .NET 6.0 - inputs: - version: 6.0.x - includePreviewVersions: true - - # Install .NET 7.0 - - task: UseDotNet@2 - displayName: 'Install .NET 7.0' - inputs: - version: 7.0.x - includePreviewVersions: true - - # Install .NET 8.0 - - task: UseDotNet@2 - displayName: 'Install .NET 8.0' - inputs: - version: 8.0.x - includePreviewVersions: true - - # Install nodejs - - task: NodeTool@0 - displayName: 'Install nodejs' - inputs: - versionSpec: '20.x' - - # Set version number (exclude Templates/content) - - task: Assembly-Info-NetCore@3 - displayName: 'Versioning $(Build.BuildNumber)' - inputs: - Path: '$(Build.SourcesDirectory)' - FileNames: | - **/*.csproj - !**/src/Templates/content/**/*.csproj - InsertAttributes: true - FileEncoding: 'auto' - WriteBOM: false - VersionNumber: '$(AssemblyVersion)' - FileVersionNumber: '$(AssemblyVersion)' - InformationalVersion: '$(AssemblyVersion)' - PackageVersion: '$(PackageVersion)' - LogLevel: 'verbose' - FailOnWarning: false - DisableTelemetry: false - - # Install dependencies - - task: DotNetCoreCLI@2 - displayName: Install dependencies - inputs: - command: 'restore' - projects: ${{ parameters.Projects }} - - # Build the projects - - task: DotNetCoreCLI@2 - displayName: 'Build $(Build.BuildNumber)' - condition: eq(variables['ShouldPublish'], 'false') - inputs: - command: 'build' - projects: ${{ parameters.Projects }} - arguments: '--configuration Release' - - # Test and generate Code Coverage - - task: DotNetCoreCLI@2 - condition: eq(variables['ShouldTest'], 'true') - displayName: 'Test and Code Coverage' - inputs: - command: test - projects: ${{ parameters.Tests }} - arguments: '--configuration Release /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:DebugType=Full' - publishTestResults: true - - # Coverage Generation - - task: reportgenerator@5 - condition: eq(variables['ShouldTest'], 'true') - displayName: Generate reports - inputs: - reports: '**/*.cobertura.xml' - targetdir: 'CoverageFolder' - reporttypes: 'HtmlInline_AzurePipelines' - - # Publish code coverage - - task: PublishCodeCoverageResults@2 - condition: eq(variables['ShouldTest'], 'true') - displayName: 'Publish code coverage' - inputs: - codeCoverageTool: Cobertura - summaryFileLocation: '**/*.cobertura.xml' - reportDirectory: CoverageFolder - - # Not currently used (kept for archives) - # - task: DotNetCoreCLI@2 - # displayName: Pack $(Build.BuildNumber) - # inputs: - # command: 'pack' - # packagesToPack: ${{ parameters.Projects }} - # versioningScheme: 'off' - # nobuild: true - # verbosityPack: 'Normal' - # feedsToUse: 'config' - # nugetConfigPath: - - # Since NuGet packages are generated during the build, we need to copy them to the artifacts folder. - - task: CopyFiles@2 - displayName: 'Pack $(Build.BuildNumber)' - condition: eq(variables['ShouldPublish'], 'false') - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: '**/*$(PackageVersion).nupkg' - TargetFolder: '$(Build.ArtifactStagingDirectory)' - CleanTargetFolder: true - OverWrite: true - flattenFolders: true - - # ESRP Code Signing SC - - task: EsrpCodeSigning@3 - condition: eq(variables['ShouldSign'], 'true') - inputs: - ConnectedServiceName: 'ESRP Code Signing SC' - FolderPath: '$(Build.ArtifactStagingDirectory)' - Pattern: '**/*.nupkg' - UseMinimatch: true - signConfigType: 'inlineSignParams' - inlineOperation: | - [ - { - "KeyCode" : "CP-401405", - "OperationCode" : "NuGetSign", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-401405", - "OperationCode" : "NuGetVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] - SessionTimeout: '60' - MaxConcurrency: '200' - MaxRetryAttempts: '5' - - # Publish the projects - - task: DotNetCoreCLI@2 - displayName: 'Publish $(Build.BuildNumber)' - condition: eq(variables['ShouldPublish'], 'true') - inputs: - command: 'publish' - publishWebProjects: false # True to build all Web Projects - projects: ${{ parameters.Projects }} - arguments: '--configuration Release --output $(Build.ArtifactStagingDirectory)' - zipAfterPublish: false - workingDirectory: '$(Build.SourcesDirectory)' - - # Publish the Artifacts - - task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)' diff --git a/.vscode/settings.json b/.vscode/settings.json index 8e622e3100..f65e35ba93 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "dotnet.defaultSolution": "Microsoft.FluentUI.sln" -} \ No newline at end of file + "dotnet.defaultSolution": "Microsoft.FluentUI.sln", + "azure-pipelines.1ESPipelineTemplatesSchemaFile": true +} diff --git a/Directory.Build.props b/Directory.Build.props index 5ad7b62352..25228bf343 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,16 +12,15 @@ $(MSBuildThisFileDirectory) true - 4.5.0 - 4.5.0 + 4.6.0 + 4.6.0 $(VersionFile) $(VersionFile) - - true - - + + true + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000000..cbbc09d471 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,18 @@ + + + + + false + <_TranslateUrlPattern>(https://dev\.azure\.com/dnceng/internal/_git)/([^/-]+)-(.+) + <_TranslateUrlReplacement>https://github.com/$2/$3 + + + + + + $([System.Text.RegularExpressions.Regex]::Replace(%(SourceRoot.ScmRepositoryUrl), $(_TranslateUrlPattern), $(_TranslateUrlReplacement))) + + + + + diff --git a/Directory.Packages.props b/Directory.Packages.props index 55a37c3bd8..d86f32f0a9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,39 +2,40 @@ true 8.0.0 - 8.0.1 - 8.0.1 + 8.0.3 + 8.0.3 - - - + + + - - - - + + + + - - + + - + + - + - + - - - - - + + + + + - \ No newline at end of file + diff --git a/Microsoft.FluentUI.signproj b/Microsoft.FluentUI.signproj new file mode 100644 index 0000000000..6e000ea8b5 --- /dev/null +++ b/Microsoft.FluentUI.signproj @@ -0,0 +1,28 @@ + + + + ..\..\ + $(SolutionDir)\ + $(SolutionDir)bin\$(Configuration)\ + $(OutDir)\ + $(SolutionDir)obj\$(Configuration)\ + $(IntermediateOutputPath)\ + net8.0 + + + + + + + + + $(OutDir)\ + $(IntermediateOutputPath)\ + + + + NuGet + + + + diff --git a/Microsoft.FluentUI.sln b/Microsoft.FluentUI.sln index 3852ffa4b7..2c092240f9 100644 --- a/Microsoft.FluentUI.sln +++ b/Microsoft.FluentUI.sln @@ -3,19 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.7.33808.371 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{805140F8-CC9F-4C32-BB72-3D67D13BEBA7}" - ProjectSection(SolutionItems) = preProject - CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md - CONTRIBUTING.md = CONTRIBUTING.md - LICENSE = LICENSE - README.md = README.md - SECURITY.md = SECURITY.md - unit-tests.md = unit-tests.md - WHATSNEW.md = WHATSNEW.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{558E0FEA-094D-4AA4-994A-8ED67ABEDED4}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{141FEF3E-C665-4D50-8E51-B9507C98040E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demo", "demo", "{9468ADD1-3660-410D-8231-6F89384D135D}" @@ -54,17 +41,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AssetExplorer", "AssetExplo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentUI.Demo.AssetExplorer", "examples\Demo\AssetExplorer\FluentUI.Demo.AssetExplorer.csproj", "{E4E62EAA-38FC-48FE-B63E-EB4ABAD660D2}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B89F06FD-2497-4041-B9EE-EDD889A2C14C}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - Directory.Build.props = Directory.Build.props - Directory.Packages.props = Directory.Packages.props - global.json = global.json - LICENSE = LICENSE - NuGet.config = NuGet.config - spelling.dic = spelling.dic - EndProjectSection -EndProject Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "Microsoft.FluentUI.AspNetCore.Components.Assets", "src\Core.Assets\Microsoft.FluentUI.AspNetCore.Components.Assets.esproj", "{292081C2-5076-467C-AEFF-12DC0617531A}" EndProject Global diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT new file mode 100644 index 0000000000..c7ad816be9 --- /dev/null +++ b/THIRD-PARTY-NOTICES.TXT @@ -0,0 +1,34 @@ +We uses third-party libraries or other resources that may be +distributed under licenses different than the Fluent UI Blazor library software. + +In the event that we accidentally failed to list a required notice, please +bring it to our attention. Post an issue or email us: + + fluentui-blazor@microsoft.com + +The attached notices are provided for information only. + +License notice for Bootstrap +--------------------------- + +The MIT License (MIT) + +Copyright (c) 2011-2023 The Bootstrap Authors + +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. diff --git a/WHATSNEW.md b/WHATSNEW.md index 021331335c..efe37e4d76 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,70 +1,149 @@ +## V4.6.0 + +### Demo site, documentation and miscellaneous +- [Demo & docs] Add InputFile 'known issues' section ([#1680](https://github.com/microsoft/fluentui-blazor/pull/1680)) +- [Demo & docs] Corrects spelling and grammar in templates page ([#1716](https://github.com/microsoft/fluentui-blazor/pull/1716)) +- [Demo & docs] Fix Wizard link in navigation menu ([#1660](https://github.com/microsoft/fluentui-blazor/pull/1660)) +- [Demo & docs] Minor corrections to CONTRIBUTING.md ([#1681](https://github.com/microsoft/fluentui-blazor/pull/1681)) +- [MarkdownSection] Fixes border not showing in Markdown tables ([#1721](https://github.com/microsoft/fluentui-blazor/pull/1721)) +- [MarkdownSection] Adds code highlighting ([#1737](https://github.com/microsoft/fluentui-blazor/pull/1737)) +- [MarkdownSection] Fixes and enhancements ([#1751](https://github.com/microsoft/fluentui-blazor/pull/1751)) +- [Misc] Add required .csproj settings for generating snupkg packages ([#1675](https://github.com/microsoft/fluentui-blazor/pull/1675)) +- [Misc] Add ToColorHex extension to Swatch ([#1691](https://github.com/microsoft/fluentui-blazor/pull/1691)) + +### Components +- [Accordion] Add expanded value to custom event handler ([#1689](https://github.com/microsoft/fluentui-blazor/pull/1689)) +- [AppBarItem] Add OnClick event callback ([#1698](https://github.com/microsoft/fluentui-blazor/pull/1698)) +- [Button] Avoid padding on loading spinner when no text is shown ([#1714](https://github.com/microsoft/fluentui-blazor/pull/1714)) +- [InputFile] Replace OnInitializedAsync with OnAfterRenderAsync ([#1661](https://github.com/microsoft/fluentui-blazor/pull/1661)) +- [KeyCode] Allow content to avoid using the Anchor property ([#1743](https://github.com/microsoft/fluentui-blazor/pull/1743)) +- **[KeyCodeProvider]** Add a global service to capture keystrokes ([#1740](https://github.com/microsoft/fluentui-blazor/pull/1740)) +- [MenuButton] Make the menu anchored to the button so can float ([#1676](https://github.com/microsoft/fluentui-blazor/pull/1676)) +- [Pagination] Add Disabled parameter ([#1713](https://github.com/microsoft/fluentui-blazor/pull/1713)) +- [Persona] Manage the empty Name ([#1710](https://github.com/microsoft/fluentui-blazor/pull/1710)) +- **[ProfileMenu]** Add a new `FluentProfileMenu` ([#1705](https://github.com/microsoft/fluentui-blazor/pull/1705)) +- **[PullToRefresh]** Add a new `FluentPullToRefresh` ([#1679](https://github.com/microsoft/fluentui-blazor/pull/1679)) +- [Wizard] Add the ability to automatically validate an EditForm ([#1663](https://github.com/microsoft/fluentui-blazor/pull/1663)) + + +- Update Fluent UI System Icons to 1.1.233 + + **What's new (Name / Size(s) / Variant(s))** + - Classification / 32 / Filled & Regular + - Document Target / 20, 24, 32 / Filled & Regular + - Emoji Meme / 16, 20, 24 / Filled & Regular + - Hand Point / 16, 20, 24, 28, 32, 48 / Filled & Regular + - Mail Read Briefcase / 48 / Filled & Regular + - People Subtract / 20, 24, 32 / Filled & Regular + - Person Alert Off / 16, 20, 24, 32 / Filled & Regular + - Shopping Bag Add / 16 / Filled & Regular + - Spatula Spoon / 16, 20, 24, 28, 32, 48 / Filled & Regular + - Accessibility Error / 20, 24 / Filled & Regular + - Accessibility Question Mark / 20, 24 / Filled & Regular + - Arrow Down Exclamation / 24 / Filled & Regular + - Arrow Sort Up Lines / 16, 20, 24 / Filled & Regular + - Arrow Up Exclamation / 16, 20, 24 / Filled & Regular + - Bench / 20, 24 / Filled & Regular + - Building Lighthouse / 28 / Filled & Regular + - Clock Bill / 16, 20, 24, 32 / Filled & Regular + - Data Usage Settings / 16, 24 / Filled & Regular + - Data Usage / 16 / Filled & Regular + - Edit Person / 20, 24 / Filled & Regular + - Highway / 20, 24 / Filled & Regular + - Laptop Person / 20, 24, 48 / Filled & Regular + - Location Ripple / 16, 20, 24 / Filled & Regular + - Mail Arrow Double Back / 32 / Filled & Regular + - Mail Briefcase / 48 / Filled & Regular + - People Add / 32 / Filled & Regular + - Person Alert / 32 / Filled & Regular + - Road / 20, 24 / Filled & Regular + - Save / 32 / Filled & Regular + - Tab Desktop Multiple Sparkle / 16, 20, 24 / Filled & Regular + - Tab Desktop Multiple / 24 / Filled & Regular + - Vehicle Tractor / 20, 24 / Filled & Regular + + **What's updated (Name / Size(s) / Variant(s))** + - Classification / 20, 24 / Filled & Regular + - Emoji Add / 20 / Filled & Regular + - Emoji Edit / 20 / Filled & Regular + - Emoji Sparkle / 20 / Filled & Regular + - Emoji / 20 / Filled & Regular + - Accessibility Checkmark / 24 / Filled & Regular + - Arrow Down Exclamation / 16, 20 / Filled & Regular + - Arrow Sort Down Lines / 16, 20, 24 / Filled & Regular + - Building Lighthouse / 48 / Filled & Regular + - Calendar Video / 20, 24, 28 / Filled & Regular + - Options / 16, 28, 32 / Filled & Regular + - Person Alert / 16, 20, 24 / Filled & Regular + - Tab Desktop Multiple Bottom / 24 / Filled + ## V4.5.0 From now on we will just list the PRs that have been merged. The related issues can be found by looking at the PR details on GitHub. Titles have been altered and sorted here to provide a bit more uniformity. ### Demo site, documentation and miscellaneous -* [Demo & docs] Add global search bar ([#1583](https://github.com/microsoft/fluentui-blazor/pull/1583)) -* [Demo & docs] Add video on Demo site ([#1586](https://github.com/microsoft/fluentui-blazor/pull/1586)) -* [Demo & docs] Migrate Demo Search to use FluentAutocomplete ([#1599](https://github.com/microsoft/fluentui-blazor/pull/1599)) -* [Demo & docs] Nuget badge links to nuget ([#1529](https://github.com/microsoft/fluentui-blazor/pull/1529)) -* [Demo & docs] Update NavMenuPage.razor - corrects grammar ([#1518](https://github.com/microsoft/fluentui-blazor/pull/1518)) -* [Misc] Rider files not ignored ([#1649](https://github.com/microsoft/fluentui-blazor/pull/1649)) -* [Misc] Update devcontainer to Dotnet 8 ([#1630](https://github.com/microsoft/fluentui-blazor/pull/1630)) +- [Demo & docs] Add global search bar ([#1583](https://github.com/microsoft/fluentui-blazor/pull/1583)) +- [Demo & docs] Add video on Demo site ([#1586](https://github.com/microsoft/fluentui-blazor/pull/1586)) +- [Demo & docs] Migrate Demo Search to use FluentAutocomplete ([#1599](https://github.com/microsoft/fluentui-blazor/pull/1599)) +- [Demo & docs] Nuget badge links to nuget ([#1529](https://github.com/microsoft/fluentui-blazor/pull/1529)) +- [Demo & docs] Update NavMenuPage.razor - corrects grammar ([#1518](https://github.com/microsoft/fluentui-blazor/pull/1518)) +- [Misc] Rider files not ignored ([#1649](https://github.com/microsoft/fluentui-blazor/pull/1649)) +- [Misc] Update devcontainer to Dotnet 8 ([#1630](https://github.com/microsoft/fluentui-blazor/pull/1630)) ### Components -* [AppBar] Adding .NET Aspire's AppBar ([#1527](https://github.com/microsoft/fluentui-blazor/pull/1527)) -* [Autocomplete] Add IconDismiss adn IconSearch ([#1573](https://github.com/microsoft/fluentui-blazor/pull/1573)) -* [Autocomplete] Add 'required' binding to the autocomplete label ([#1543](https://github.com/microsoft/fluentui-blazor/pull/1543)) -* [Autocomplete] Fix Backspace usage ([#1544](https://github.com/microsoft/fluentui-blazor/pull/1544)) -* [Autocomplete] Fix the left-right navigation (v3) ([#1491](https://github.com/microsoft/fluentui-blazor/pull/1491)) -* [Autocomplete] Add autofocus to Autocomplete & Combobox [#1650](https://github.com/microsoft/fluentui-blazor/pull/1650) -* [Autocomplete] Add Virtualization [#1647](https://github.com/microsoft/fluentui-blazor/pull/1647) -* [Button] Update the Button custom style for BackgroundColor and Color properties ([#1603](https://github.com/microsoft/fluentui-blazor/pull/1603)) -* [Card] Add MinimalStyle property ([#1595](https://github.com/microsoft/fluentui-blazor/pull/1595)) -* [Combobox] Allow FluentCombobox to be cleared from code ([#1613](https://github.com/microsoft/fluentui-blazor/pull/1613)) -* [Combobox] Fix 1485 by overriding SetParametersAsync ([#1506](https://github.com/microsoft/fluentui-blazor/pull/1506)) -* [Combobox] Re-use/re-purpose FluentTextField script for FluentCombobox (browser autocomplete) ([#1629](https://github.com/microsoft/fluentui-blazor/pull/1629)) -* [DatagGrid] Remove Expression from TooltipText ([#1635](https://github.com/microsoft/fluentui-blazor/pull/1635)) -* [DataGrid] Adds a Filtered property and visual indicator to PropretyColumn in FluentDataGrid ([#1625](https://github.com/microsoft/fluentui-blazor/pull/1625)) -* [DataGrid] Fix #1582 by adding pointercancel and pointerleave event listeners ([#1591](https://github.com/microsoft/fluentui-blazor/pull/1591)) -* [DataGrid] Fix #1616 by adding a try..catch block ([#1637](https://github.com/microsoft/fluentui-blazor/pull/1637)) -* [DataGrid] Fix Loading issues ([#1512](https://github.com/microsoft/fluentui-blazor/pull/1512)) -* [DataGrid] Fix OnRowwFocus and sorting for DataGrid ([#1577](https://github.com/microsoft/fluentui-blazor/pull/1577)) -* [DataGrid] Use specific ids for rows and cells ([#1480](https://github.com/microsoft/fluentui-blazor/pull/1480)) -* [DatePicker] Add DateOnly and TimeOnly extensions ([#1500](https://github.com/microsoft/fluentui-blazor/pull/1500)) -* [DatePicker] Allow to select the existing selected month ([#1545](https://github.com/microsoft/fluentui-blazor/pull/1545)) -* [DesignTheme] Fix the Random color annoys other fillers ([#1475](https://github.com/microsoft/fluentui-blazor/pull/1475)) -* [Dialog] Allows showing a dialog by only providing a RenderFragment. ([#1496](https://github.com/microsoft/fluentui-blazor/pull/1496)) -* [Grid] Fix the Grid "external margins" ([#1646](https://github.com/microsoft/fluentui-blazor/pull/1646)) -* [Icons] Fix Icon color using `ColorWith` and a `CustomColor` attribute ([#1539](https://github.com/microsoft/fluentui-blazor/pull/1539)) -* [Icons] Update Fluent UI System Icons to v1.1.230 ([#1648](https://github.com/microsoft/fluentui-blazor/pull/1648)) -* [Icons] Update to Fluent UI System Icons 1.1.227 ([#1513](https://github.com/microsoft/fluentui-blazor/pull/1513)) -* [Lists] Small performance update for rendering list items ([#1476](https://github.com/microsoft/fluentui-blazor/pull/1476)) -* [Menu] Add Threshold attributes ([#1644](https://github.com/microsoft/fluentui-blazor/pull/1644)) -* [Menu] Several fixes ([#1574](https://github.com/microsoft/fluentui-blazor/pull/1574)) -* [MenuButton] Changes and additions ([#1602](https://github.com/microsoft/fluentui-blazor/pull/1602)) -* [MessageBar] Allow the ability to hide the dismissal button ([#1495](https://github.com/microsoft/fluentui-blazor/pull/1495)) -* [NavMenu] Fix FluentNavMenu.razor.js for non SSR ([#1560](https://github.com/microsoft/fluentui-blazor/pull/1560)) -* [NavMenu] Render out Id for FluentNavLink + add test ([#1580](https://github.com/microsoft/fluentui-blazor/pull/1580)) -* [NumberField] Fix #1531 by using web components current-value instead of value. ([#1576](https://github.com/microsoft/fluentui-blazor/pull/1576)) -* [Overflow] Better samples and better selector detection ([#1645](https://github.com/microsoft/fluentui-blazor/pull/1645)) -* [Overflow] Misc work ([#1523](https://github.com/microsoft/fluentui-blazor/pull/1523)) -* [Pagination] Fix #1596 (very long title, see description) ([#1606](https://github.com/microsoft/fluentui-blazor/pull/1606)) -* [Paginator] Remove background color ([#1503](https://github.com/microsoft/fluentui-blazor/pull/1503)) -* [Persona] Add support for icons ([#1546](https://github.com/microsoft/fluentui-blazor/pull/1546)) -* [Persona] Fix bug in FluentPersona when the names contains more than one space. ([#1623](https://github.com/microsoft/fluentui-blazor/pull/1623)) -* [Script] Fix #1652 by also checking for OperationCanceledException ([#1653](https://github.com/microsoft/fluentui-blazor/pull/1653)) -* [SortableList] Fix typo/spelling errors for Sortable List Page ([#1600](https://github.com/microsoft/fluentui-blazor/pull/1600)) -* [SplashScreen] Add WaitingMilliseconds and UpdateLabels ([#1570](https://github.com/microsoft/fluentui-blazor/pull/1570)) -* [Splitter] Fix adoptedStyleSheets is frozen in earlier versions by @CV-souryu ([#1557](https://github.com/microsoft/fluentui-blazor/pull/1557)) -* [Splitter] Update SplitPanels.ts ([#1520](https://github.com/microsoft/fluentui-blazor/pull/1520)) -* [Tabs] Add LoadingContent parameter to FluentTab ([#1587](https://github.com/microsoft/fluentui-blazor/pull/1587)) -* [Templates] Makes code created from fluentblazorwasm template neater ([#1501](https://github.com/microsoft/fluentui-blazor/pull/1501)) -* [Templates] Minor clean up ([#1488](https://github.com/microsoft/fluentui-blazor/pull/1488)) -* [Tooltip] Add the HideTooltipOnCursorLeave property ([#1571](https://github.com/microsoft/fluentui-blazor/pull/1571)) -* [ValidationMessage] Adds FieldIdentifier parameter ([#1489](https://github.com/microsoft/fluentui-blazor/pull/1489)) -* [Wizard] Fix ValueChanged never trigerred in FluentWizard ([#1538](https://github.com/microsoft/fluentui-blazor/pull/1538)) +- [AppBar] Adding .NET Aspire's AppBar ([#1527](https://github.com/microsoft/fluentui-blazor/pull/1527)) +- [Autocomplete] Add IconDismiss adn IconSearch ([#1573](https://github.com/microsoft/fluentui-blazor/pull/1573)) +- [Autocomplete] Add 'required' binding to the autocomplete label ([#1543](https://github.com/microsoft/fluentui-blazor/pull/1543)) +- [Autocomplete] Fix Backspace usage ([#1544](https://github.com/microsoft/fluentui-blazor/pull/1544)) +- [Autocomplete] Fix the left-right navigation (v3) ([#1491](https://github.com/microsoft/fluentui-blazor/pull/1491)) +- [Autocomplete] Add autofocus to Autocomplete & Combobox [#1650](https://github.com/microsoft/fluentui-blazor/pull/1650) +- [Autocomplete] Add Virtualization [#1647](https://github.com/microsoft/fluentui-blazor/pull/1647) +- [Button] Update the Button custom style for BackgroundColor and Color properties ([#1603](https://github.com/microsoft/fluentui-blazor/pull/1603)) +- [Card] Add MinimalStyle property ([#1595](https://github.com/microsoft/fluentui-blazor/pull/1595)) +- [Combobox] Allow FluentCombobox to be cleared from code ([#1613](https://github.com/microsoft/fluentui-blazor/pull/1613)) +- [Combobox] Fix 1485 by overriding SetParametersAsync ([#1506](https://github.com/microsoft/fluentui-blazor/pull/1506)) +- [Combobox] Re-use/re-purpose FluentTextField script for FluentCombobox (browser autocomplete) ([#1629](https://github.com/microsoft/fluentui-blazor/pull/1629)) +- [DatagGrid] Remove Expression from TooltipText ([#1635](https://github.com/microsoft/fluentui-blazor/pull/1635)) +- [DataGrid] Adds a Filtered property and visual indicator to PropretyColumn in FluentDataGrid ([#1625](https://github.com/microsoft/fluentui-blazor/pull/1625)) +- [DataGrid] Fix #1582 by adding pointercancel and pointerleave event listeners ([#1591](https://github.com/microsoft/fluentui-blazor/pull/1591)) +- [DataGrid] Fix #1616 by adding a try..catch block ([#1637](https://github.com/microsoft/fluentui-blazor/pull/1637)) +- [DataGrid] Fix Loading issues ([#1512](https://github.com/microsoft/fluentui-blazor/pull/1512)) +- [DataGrid] Fix OnRowwFocus and sorting for DataGrid ([#1577](https://github.com/microsoft/fluentui-blazor/pull/1577)) +- [DataGrid] Use specific ids for rows and cells ([#1480](https://github.com/microsoft/fluentui-blazor/pull/1480)) +- [DatePicker] Add DateOnly and TimeOnly extensions ([#1500](https://github.com/microsoft/fluentui-blazor/pull/1500)) +- [DatePicker] Allow to select the existing selected month ([#1545](https://github.com/microsoft/fluentui-blazor/pull/1545)) +- [DesignTheme] Fix the Random color annoys other fillers ([#1475](https://github.com/microsoft/fluentui-blazor/pull/1475)) +- [Dialog] Allows showing a dialog by only providing a RenderFragment. ([#1496](https://github.com/microsoft/fluentui-blazor/pull/1496)) +- [Grid] Fix the Grid "external margins" ([#1646](https://github.com/microsoft/fluentui-blazor/pull/1646)) +- [Icons] Fix Icon color using `ColorWith` and a `CustomColor` attribute ([#1539](https://github.com/microsoft/fluentui-blazor/pull/1539)) +- [Icons] Update Fluent UI System Icons to v1.1.230 ([#1648](https://github.com/microsoft/fluentui-blazor/pull/1648)) +- [Icons] Update to Fluent UI System Icons 1.1.227 ([#1513](https://github.com/microsoft/fluentui-blazor/pull/1513)) +- [Lists] Small performance update for rendering list items ([#1476](https://github.com/microsoft/fluentui-blazor/pull/1476)) +- [Menu] Add Threshold attributes ([#1644](https://github.com/microsoft/fluentui-blazor/pull/1644)) +- [Menu] Several fixes ([#1574](https://github.com/microsoft/fluentui-blazor/pull/1574)) +- [MenuButton] Changes and additions ([#1602](https://github.com/microsoft/fluentui-blazor/pull/1602)) +- [MessageBar] Allow the ability to hide the dismissal button ([#1495](https://github.com/microsoft/fluentui-blazor/pull/1495)) +- [NavMenu] Fix FluentNavMenu.razor.js for non SSR ([#1560](https://github.com/microsoft/fluentui-blazor/pull/1560)) +- [NavMenu] Render out Id for FluentNavLink + add test ([#1580](https://github.com/microsoft/fluentui-blazor/pull/1580)) +- [NumberField] Fix #1531 by using web components current-value instead of value. ([#1576](https://github.com/microsoft/fluentui-blazor/pull/1576)) +- [Overflow] Better samples and better selector detection ([#1645](https://github.com/microsoft/fluentui-blazor/pull/1645)) +- [Overflow] Misc work ([#1523](https://github.com/microsoft/fluentui-blazor/pull/1523)) +- [Pagination] Fix #1596 (very long title, see description) ([#1606](https://github.com/microsoft/fluentui-blazor/pull/1606)) +- [Paginator] Remove background color ([#1503](https://github.com/microsoft/fluentui-blazor/pull/1503)) +- [Persona] Add support for icons ([#1546](https://github.com/microsoft/fluentui-blazor/pull/1546)) +- [Persona] Fix bug in FluentPersona when the names contains more than one space. ([#1623](https://github.com/microsoft/fluentui-blazor/pull/1623)) +- [Script] Fix #1652 by also checking for OperationCanceledException ([#1653](https://github.com/microsoft/fluentui-blazor/pull/1653)) +- [SortableList] Fix typo/spelling errors for Sortable List Page ([#1600](https://github.com/microsoft/fluentui-blazor/pull/1600)) +- [SplashScreen] Add WaitingMilliseconds and UpdateLabels ([#1570](https://github.com/microsoft/fluentui-blazor/pull/1570)) +- [Splitter] Fix adoptedStyleSheets is frozen in earlier versions by @CV-souryu ([#1557](https://github.com/microsoft/fluentui-blazor/pull/1557)) +- [Splitter] Update SplitPanels.ts ([#1520](https://github.com/microsoft/fluentui-blazor/pull/1520)) +- [Tabs] Add LoadingContent parameter to FluentTab ([#1587](https://github.com/microsoft/fluentui-blazor/pull/1587)) +- [Templates] Makes code created from fluentblazorwasm template neater ([#1501](https://github.com/microsoft/fluentui-blazor/pull/1501)) +- [Templates] Minor clean up ([#1488](https://github.com/microsoft/fluentui-blazor/pull/1488)) +- [Tooltip] Add the HideTooltipOnCursorLeave property ([#1571](https://github.com/microsoft/fluentui-blazor/pull/1571)) +- [ValidationMessage] Adds FieldIdentifier parameter ([#1489](https://github.com/microsoft/fluentui-blazor/pull/1489)) +- [Wizard] Fix ValueChanged never trigerred in FluentWizard ([#1538](https://github.com/microsoft/fluentui-blazor/pull/1538)) ## V4.4.1 - Issue [#1462](https://github.com/microsoft/fluentui-blazor/issues/1462): FluentMessageBar onclick bug and not using Link?.Target diff --git a/CONTRIBUTING.md b/docs/contributing.md similarity index 89% rename from CONTRIBUTING.md rename to docs/contributing.md index 3980718a3e..b8da73aa08 100644 --- a/CONTRIBUTING.md +++ b/docs/contributing.md @@ -4,11 +4,11 @@ ### Machine setup -To begin you'll need Git and .NET setup on your machine. +To begin you'll need Git, .NET, and NodeJS setup on your machine. -The `fluentui-blazor` repo uses Git as its source control system. If you haven't already installed it, you can download it [here](https://git-scm.com/downloads) or if you prefer a GUI-based approach, try [GitHub Desktop](https://desktop.github.com/). +The `fluentui-blazor` repository uses Git as its source control system. If you haven't already installed it, you can download it [here](https://git-scm.com/downloads) or if you prefer a GUI-based approach, try [GitHub Desktop](https://desktop.github.com/). -Once Git is installed, you'll also need .NET. Instructions and downloads for your preferred OS can be found [here](https://dotnet.microsoft.com/download). +Once Git is installed, you'll also need .NET and NodeJS. Instructions and downloads for .NET on your preferred OS can be found [here](https://dotnet.microsoft.com/download). NodeJS can be found [here](https://nodejs.org). :::important The above steps are a one-time setup for your machine and do not need to be repeated after the initial configuration. @@ -16,20 +16,21 @@ The above steps are a one-time setup for your machine and do not need to be repe ### Cloning the repository -Now that your machine is setup, you can clone the `FAST-Blazor` repository. Open a terminal and run this command: +Now that your machine is setup, you can clone the `fluentui-blazor` repository. Open a terminal and run this command: ```shell git clone https://github.com/microsoft/fluentui-blazor.git ``` + Cloning via SSH: ```shell -git clone git@github.com:microsoft/fluent-blazor.git +git clone git@github.com:microsoft/fluentui-blazor.git ``` ### Installing and building -From within the folder where you've cloned the repo, install all package dependencies and build the project with the following command. +From within the folder where you've cloned the repo, build the project with the following command. ```bash dotnet build @@ -43,7 +44,6 @@ If you'd like to contribute by fixing a bug, implementing a feature, or even cor If you are merging a pull request, be sure to use the pull request title as the commit title. The title should follow the [conventional commit guidelines](https://www.conventionalcommits.org/). It is recommended that if you are merging in pull requests regularly that you add a browser extension that will auto-correct the title for you. A few that should do this are [Refined GitHub](https://github.com/sindresorhus/refined-github) and [Squashed Merge Message](https://github.com/zachwhaley/squashed-merge-message). - ## Contribution policy A “Contribution” is work voluntarily submitted to a project. This submitted work can include code, documentation, design, answering questions, or submitting and triaging issues. diff --git a/unit-tests.md b/docs/unit-tests.md similarity index 100% rename from unit-tests.md rename to docs/unit-tests.md diff --git a/eng/pipelines/azure-pipelines.yml b/eng/pipelines/azure-pipelines.yml new file mode 100644 index 0000000000..657b93e3ea --- /dev/null +++ b/eng/pipelines/azure-pipelines.yml @@ -0,0 +1,191 @@ +# Build and test Core project. +name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) + +trigger: + batch: true + branches: + include: + - main + - dev + + paths: + include: + - '*' + exclude: + - .github/* + - .devcontainer/* + - docs/* + - CODE_OF_CONDUCT.md + - README.md + - SECURITY.md + - LICENSE.TXT + - THIRD-PARTY-NOTICES.TXT + +pr: + branches: + include: + - main + - dev + + paths: + include: + - '*' + exclude: + - .github/* + - .devcontainer/* + - docs/* + - CODE_OF_CONDUCT.md + - README.md + - SECURITY.md + - LICENSE.TXT + - THIRD-PARTY-NOTICES.TXT + +variables: + - template: /eng/pipelines/common-variables.yml@self + - template: /eng/pipelines/common/version.yml@self + + - name: _BuildConfig + value: Release + - name: Build.Arcade.ArtifactsPath + value: $(Build.SourcesDirectory)/artifacts/ + - name: Build.Arcade.LogsPath + value: $(Build.Arcade.ArtifactsPath)log/$(_BuildConfig)/ + - name: Build.Arcade.TestResultsPath + value: $(Build.Arcade.ArtifactsPath)TestResults/$(_BuildConfig)/ + + # Produce test-signed build for PR and Public builds + - ${{ if or(eq(variables['_RunAsPublic'], 'true'), eq(variables['Build.Reason'], 'PullRequest')) }}: + # needed for darc (dependency flow) publishing + - name: _PublishArgs + value: '' + - name: _OfficialBuildIdArgs + value: '' + # needed for signing + - name: _SignType + value: test + - name: _SignArgs + value: '' + - name: _Sign + value: false + + # Set up non-PR build from internal project + - ${{ if and(ne(variables['_RunAsPublic'], 'true'), ne(variables['Build.Reason'], 'PullRequest')) }}: + # needed for darc (dependency flow) publishing + - name: _PublishArgs + value: >- + /p:DotNetPublishUsingPipelines=true + - name: _OfficialBuildIdArgs + value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + # needed for signing + - name: _SignType + value: real + - name: _SignArgs + value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName) /p:Sign=$(_Sign) /p:DotNetPublishUsingPipelines=true + - name: _Sign + value: true + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + sdl: + eslint: + enabled: false + justificationForDisabling: 'see https://portal.microsofticm.com/imp/v3/incidents/incident/482258316/summary' + sourceAnalysisPool: + name: NetCore1ESPool-Internal + image: windows.vs2022preview.amd64 + os: windows + + stages: + + # ---------------------------------------------------------------- + # This stage performs build, test, packaging + # ---------------------------------------------------------------- + - stage: build + displayName: Build + jobs: + - template: /eng/common/templates-official/jobs/jobs.yml@self + parameters: + enableMicrobuild: true + # Publish NuGet packages using v3 + # https://github.com/dotnet/arcade/blob/main/Documentation/CorePackages/Publishing.md#basic-onboarding-scenario-for-new-repositories-to-the-current-publishing-version-v3 + enablePublishUsingPipelines: true + enablePublishBuildAssets: true + enableTelemetry: true + enableSourceIndex: false + # Publish build logs + enablePublishBuildArtifacts: true + # Publish test logs + enablePublishTestResults: true + workspace: + clean: all + + jobs: + + - job: Windows + # timeout accounts for wait times for helix agents up to 30mins + timeoutInMinutes: 60 + + pool: + name: NetCore1ESPool-Internal + image: windows.vs2022preview.amd64 + os: windows + + variables: + - name: _buildScript + value: $(Build.SourcesDirectory)/build.cmd -ci + + preSteps: + - checkout: self + fetchDepth: 1 + clean: true + + steps: + - template: /eng/pipelines/templates/BuildAndTest.yml + parameters: + dotnetScript: $(Build.SourcesDirectory)/dotnet.cmd + buildScript: $(_buildScript) + buildConfig: $(_BuildConfig) + repoArtifactsPath: $(Build.Arcade.ArtifactsPath) + repoLogPath: $(Build.Arcade.LogsPath) + repoTestResultsPath: $(Build.Arcade.TestResultsPath) + isWindows: true + + - ${{ if and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/main')) }}: + - template: /eng/common/templates-official/job/onelocbuild.yml@self + parameters: + LclSource: lclFilesfromPackage + LclPackageId: 'LCL-JUNO-PROD-ASPIRE' + MirrorRepo: aspire + MirrorBranch: main + + - template: /eng/common/templates-official/post-build/post-build.yml@self + parameters: + validateDependsOn: + - build + publishingInfraVersion: 3 + enableSymbolValidation: false + enableSigningValidation: false + enableNugetValidation: false + enableSourceLinkValidation: false + # these param values come from the DotNet-Winforms-SDLValidation-Params azdo variable group + SDLValidationParameters: + enable: false + params: ' -SourceToolsList $(_TsaSourceToolsList) + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName $(_TsaRepositoryName) + -TsaCodebaseName $(_TsaCodebaseName) + -TsaOnboard $(_TsaOnboard) + -TsaPublish $(_TsaPublish)' diff --git a/eng/pipelines/build-all-lib.yml b/eng/pipelines/build-all-lib.yml new file mode 100644 index 0000000000..f293419bd1 --- /dev/null +++ b/eng/pipelines/build-all-lib.yml @@ -0,0 +1,285 @@ +# Build all projects (manual). +name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) + +trigger: none # Disable dev and main branches. +pr: none # Disable pull request triggers. + +parameters: + - name: Projects # List of projects to build + default: | + **/Microsoft.FluentUI.AspNetCore.Components.csproj + **/Microsoft.FluentUI.AspNetCore.Components.Icons.csproj + **/Microsoft.FluentUI.AspNetCore.Components.Emoji.csproj + **/Microsoft.FluentUI.AspNetCore.Templates.csproj + **/Microsoft.FluentUI.AspNetCore.Components.DataGrid.EntityFrameworkAdapter.csproj + + - name: Tests # List of Unit-Test projects to run + default: | + **/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj + +variables: + - template: /eng/pipelines/version.yml@self + + - name: SignType + value: real + + - name: TeamName + value: fluentui-blazor + +# The `resources` specify the location and version of the 1ES PT. +resources: + repositories: + #- repository: 1esPipelines + - repository: MicroBuildTemplate + type: git + #name: 1ESPipelineTemplates/1ESPipelineTemplates + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/tags/release + +extends: + # The pipeline extends the 1ES PT which will inject different SDL and compliance tasks. + # For non-production pipelines, use "Unofficial" as defined below. + # For productions pipelines, use "Official". + #template: v1/1ES.Unofficial.PipelineTemplate.yml@1esPipelines + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + parameters: + # Update the pool with your team's 1ES hosted pool. + pool: + name: NetCore1ESPool-Internal + #image: windows.vs2022preview.amd64 + image: 1es-windows-2022 + os: windows + + stages: + + # ---------------------------------------------------------------- + # This stage performs build, test, packaging + # ---------------------------------------------------------------- + - stage: build + displayName: Build + jobs: + - job: BuildTestPackJob + templateContext: + mb: + signing: + enabled: true + signType: $(SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + outputs: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)\SignedPackages' + artifactName: PackageArtifacts + + steps: + # Compute AssemblyVersion and PackageVersion + # -> Update version.yml + - powershell: | + + # Example with FileVersion: "1.2.4" and PackageSuffix: "RC.1" + # Build.BuildNumber = 1.2.4.23296.1 + # = $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) + + # Default values + $branch = "PR" + $package = "" + + # To Test? + $toTest = "true" + + # BranchName = dev, main, archive or PR + if ("$(Build.SourceBranchName)" -eq "main") + { + $branch = "main" + } + elseif ("$(Build.SourceBranchName)" -eq "dev") + { + $branch = "dev" + } + elseif ("$(Build.SourceBranch)" -like "refs/heads/archives/*") + { + $branch = "archive" + } + else + { + $branch = "PR" + } + + # [1, 2, 4, 23296, 1] + $builds = "$(Build.BuildNumber)".Split('.') + + # 1.2.4.23296 + $assembly = "$($builds[0]).$($builds[1]).$($builds[2]).$($builds[3])" + + # Main or Archive without PackageSuffix: 1.2.4 + # Main or Archive with PackageSuffix: 1.2.4-rc.1 + if ("$branch" -eq "main" -or "$branch" -eq "archive") + { + # Main without PackageSuffix + if ("$(PackageSuffix)" -eq "") + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])" + } + + # Main with PackageSuffix + else + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-$(PackageSuffix)" + } + + $toTest = "true" + } + + # Dev: 1.2.4-preview-23296-1 + elseif ("$branch" -eq "dev") + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" + $toTest = "true" + } + + # Other branches: 1.2.4-preview-23296-1 + else + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" + $toTest = "true" + } + + if ("${{ parameters.Tests }}" -eq "") + { + $toTest = "false" + } + + # Set the output variable for use in other tasks. + Write-Host "##vso[task.setvariable variable=AssemblyVersion]${assembly}" + Write-Host "##vso[task.setvariable variable=PackageVersion]${package}" + Write-Host "##vso[task.setvariable variable=ShouldTest]${toTest}" + displayName: Compute AssemblyVersion and PackageVersion + + # Display computed variables + - script: | + echo 🔸 FileVersion = $(FileVersion) + echo 🔸 PackageSuffix = $(PackageSuffix) + echo 🔸 Build.BuildNumber = $(Build.BuildNumber) + echo 🔸 Build.SourceBranch = $(Build.SourceBranch) + echo ----------------------------------------------- + echo 🔸 AssemblyVersion = $(AssemblyVersion) + echo 🔸 PackageVersion = $(PackageVersion) + echo ----------------------------------------------- + echo 🔸 ShouldTest = $(ShouldTest) + displayName: Display computed variables + + # Install NuGet tools + - task: NuGetToolInstaller@1 + displayName: Install NuGet tools + + - ${{ if eq(variables['Build.SourceBranchName'], 'v3') }}: + # Install .NET 6.0 + - task: UseDotNet@2 + displayName: Install .NET 6.0 + inputs: + version: 6.0.x + includePreviewVersions: true + + # Install .NET 7.0 + - task: UseDotNet@2 + displayName: 'Install .NET 7.0' + inputs: + version: 7.0.x + includePreviewVersions: true + + # Install .NET 8.0 + - task: UseDotNet@2 + displayName: 'Install .NET 8.0' + inputs: + version: 8.0.x + includePreviewVersions: true + + # Install nodejs + - task: NodeTool@0 + displayName: 'Install nodejs' + inputs: + versionSpec: '20.x' + + # Set version number (exclude some folders) + - task: PowerShell@2 + displayName: 'Versioning $(Build.BuildNumber)' + inputs: + targetType: 'filePath' + filePath: $(System.DefaultWorkingDirectory)/eng/pipelines/update-assembly-version.ps1 + arguments: > # Use this to avoid newline characters in multiline string + -sourcePath "$(System.DefaultWorkingDirectory)/" + -excludePatterns "**/src/Templates/content/**/*.csproj", "**/tests/TemplateValidation/**/*.csproj" + -assemblyVersion "$(AssemblyVersion)" + -packageVersion "$(PackageVersion)" + + # Install dependencies + - task: DotNetCoreCLI@2 + displayName: Install dependencies + inputs: + command: 'restore' + projects: ${{ parameters.Projects }} + + # Build the projects + - task: DotNetCoreCLI@2 + displayName: 'Build $(Build.BuildNumber)' + inputs: + command: 'build' + projects: ${{ parameters.Projects }} + arguments: '--configuration Release /p:ContinuousIntegrationBuild=true' + + # Test and generate Code Coverage + - task: DotNetCoreCLI@2 + condition: eq(variables['ShouldTest'], 'true') + displayName: 'Test and Code Coverage' + inputs: + command: test + projects: ${{ parameters.Tests }} + arguments: '--configuration Release /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:DebugType=Full' + publishTestResults: true + + # Coverage Generation + - task: reportgenerator@5 + condition: eq(variables['ShouldTest'], 'true') + displayName: Generate reports + inputs: + reports: '**/*.cobertura.xml' + targetdir: 'CoverageFolder' + reporttypes: 'HtmlInline_AzurePipelines' + + # Publish code coverage + - task: PublishCodeCoverageResults@2 + condition: eq(variables['ShouldTest'], 'true') + displayName: 'Publish code coverage' + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: '**/*.cobertura.xml' + reportDirectory: CoverageFolder + + # Since NuGet packages are generated during the build, we need to copy them to the artifacts folder. + - task: CopyFiles@2 + displayName: 'Pack $(Build.BuildNumber)' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: '**/*$(PackageVersion).nupkg' + TargetFolder: '$(Build.ArtifactStagingDirectory)' + CleanTargetFolder: false + OverWrite: true + flattenFolders: true + + # Sign + - task: MSBuild@1 + displayName: 'Sign NuGet Packages' + inputs: + solution: 'Microsoft.FluentUI.signproj' + msbuildArguments: '/p:OutDir=$(Build.ArtifactStagingDirectory)\ /p:IntermediateOutputPath=$(Build.ArtifactStagingDirectory)\sign\' + + + - task: CopyFiles@2 + displayName: 'Copy signed packages to pickup folder' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: '**/*$(PackageVersion).nupkg' + TargetFolder: '$(Build.ArtifactStagingDirectory)\SignedPackages' + CleanTargetFolder: false + OverWrite: true + flattenFolders: true diff --git a/eng/pipelines/build-core-lib.yml b/eng/pipelines/build-core-lib.yml new file mode 100644 index 0000000000..ac18021963 --- /dev/null +++ b/eng/pipelines/build-core-lib.yml @@ -0,0 +1,320 @@ +# Build and test Core project. +name: $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) + +trigger: + batch: true + branches: + include: + - main + - dev + - archives/v3 + + paths: + include: + - '*' + exclude: + - .github/* + - .devcontainer/* + - docs/* + - CODE_OF_CONDUCT.md + - README.md + - SECURITY.md + - LICENSE.TXT + - THIRD-PARTY-NOTICES.TXT + +pr: + branches: + include: + - main + - dev + + paths: + include: + - '*' + exclude: + - .github/* + - .devcontainer/* + - docs/* + - CODE_OF_CONDUCT.md + - README.md + - SECURITY.md + - LICENSE.TXT + - THIRD-PARTY-NOTICES.TXT + +parameters: + - name: Projects # List of projects to build + type: string + default: '**/Microsoft.FluentUI.AspNetCore.Components.csproj' + + - name: Tests # List of Unit-Test projects to run + type: string + default: '**/Microsoft.FluentUI.AspNetCore.Components.Tests.csproj' + +variables: + - template: /eng/pipelines/version.yml@self + + - name: SignType + value: test + + - name: TeamName + value: fluentui-blazor + +# The `resources` specify the location and version of the 1ES PT. +resources: + repositories: + #- repository: 1esPipelines + - repository: MicroBuildTemplate + type: git + #name: 1ESPipelineTemplates/1ESPipelineTemplates + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/tags/release + +extends: + # The pipeline extends the 1ES PT which will inject different SDL and compliance tasks. + # For non-production pipelines, use "Unofficial" as defined below. + # For productions pipelines, use "Official". + #template: v1/1ES.Unofficial.PipelineTemplate.yml@1esPipelines + template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate + parameters: + # Update the pool with your team's 1ES hosted pool. + pool: + name: NetCore1ESPool-Internal + #image: windows.vs2022preview.amd64 + image: 1es-windows-2022 + os: windows + + stages: + + # ---------------------------------------------------------------- + # This stage performs build, test, packaging + # ---------------------------------------------------------------- + - stage: build + displayName: Build + jobs: + - job: BuildTestPackJob + templateContext: + mb: + signing: + enabled: true + signType: $(SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: 'fluentui-blazor' + outputs: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)\SignedPackages' + artifactName: PackageArtifacts + + steps: + # Compute AssemblyVersion and PackageVersion + # -> Update version.yml + - powershell: | + + # Example with FileVersion: "1.2.4" and PackageSuffix: "RC.1" + # Build.BuildNumber = 1.2.4.23296.1 + # = $(FileVersion).$(Year:yy)$(DayOfYear).$(Rev:r) + + # Default values + $branch = "PR" + $package = "" + + # To Test? + $toTest = "true" + + # BranchName = dev, main, archive or PR + if ("$(Build.SourceBranchName)" -eq "main") + { + $branch = "main" + } + elseif ("$(Build.SourceBranchName)" -eq "dev") + { + $branch = "dev" + } + elseif ("$(Build.SourceBranch)" -like "refs/heads/archives/*") + { + $branch = "archive" + } + else + { + $branch = "PR" + } + + # [1, 2, 4, 23296, 1] + $builds = "$(Build.BuildNumber)".Split('.') + + # 1.2.4.23296 + $assembly = "$($builds[0]).$($builds[1]).$($builds[2]).$($builds[3])" + + # Main or Archive without PackageSuffix: 1.2.4 + # Main or Archive with PackageSuffix: 1.2.4-rc.1 + if ("$branch" -eq "main" -or "$branch" -eq "archive") + { + # Main without PackageSuffix + if ("$(PackageSuffix)" -eq "") + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])" + } + + # Main with PackageSuffix + else + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-$(PackageSuffix)" + } + + $toTest = "true" + } + + # Dev: 1.2.4-preview-23296-1 + elseif ("$branch" -eq "dev") + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" + $toTest = "true" + } + + # Other branches: 1.2.4-preview-23296-1 + else + { + $package = "$($builds[0]).$($builds[1]).$($builds[2])-preview.$($builds[3]).$($builds[4])" + $toTest = "true" + } + + if ("${{ parameters.Tests }}" -eq "") + { + $toTest = "false" + } + + # Set the output variable for use in other tasks. + Write-Host "##vso[task.setvariable variable=AssemblyVersion]${assembly}" + Write-Host "##vso[task.setvariable variable=PackageVersion]${package}" + Write-Host "##vso[task.setvariable variable=ShouldTest]${toTest}" + displayName: Compute AssemblyVersion and PackageVersion + + # Display computed variables + - script: | + echo 🔸 FileVersion = $(FileVersion) + echo 🔸 PackageSuffix = $(PackageSuffix) + echo 🔸 Build.BuildNumber = $(Build.BuildNumber) + echo 🔸 Build.SourceBranch = $(Build.SourceBranch) + echo ----------------------------------------------- + echo 🔸 AssemblyVersion = $(AssemblyVersion) + echo 🔸 PackageVersion = $(PackageVersion) + echo ----------------------------------------------- + echo 🔸 ShouldTest = $(ShouldTest) + displayName: Display computed variables + + # Install NuGet tools + - task: NuGetToolInstaller@1 + displayName: Install NuGet tools + + - ${{ if eq(variables['Build.SourceBranchName'], 'v3') }}: + # Install .NET 6.0 + - task: UseDotNet@2 + displayName: Install .NET 6.0 + inputs: + version: 6.0.x + includePreviewVersions: true + + # Install .NET 7.0 + - task: UseDotNet@2 + displayName: 'Install .NET 7.0' + inputs: + version: 7.0.x + includePreviewVersions: true + + # Install .NET 8.0 + - task: UseDotNet@2 + displayName: 'Install .NET 8.0' + inputs: + version: 8.0.x + includePreviewVersions: true + + # Install nodejs + - task: NodeTool@0 + displayName: 'Install nodejs' + inputs: + versionSpec: '20.x' + + # Set version number (exclude some folders) + - task: PowerShell@2 + displayName: 'Versioning $(Build.BuildNumber)' + inputs: + targetType: 'filePath' + filePath: $(System.DefaultWorkingDirectory)/eng/pipelines/update-assembly-version.ps1 + arguments: > # Use this to avoid newline characters in multiline string + -sourcePath "$(System.DefaultWorkingDirectory)/" + -excludePatterns "**/src/Templates/content/**/*.csproj", "**/tests/TemplateValidation/**/*.csproj" + -assemblyVersion "$(AssemblyVersion)" + -packageVersion "$(PackageVersion)" + + # Install dependencies + - task: DotNetCoreCLI@2 + displayName: Install dependencies + inputs: + command: 'restore' + projects: ${{ parameters.Projects }} + + # Build the projects + - task: DotNetCoreCLI@2 + displayName: 'Build $(Build.BuildNumber)' + inputs: + command: 'build' + projects: ${{ parameters.Projects }} + arguments: '--configuration Release /p:ContinuousIntegrationBuild=true' + + # Test and generate Code Coverage + - task: DotNetCoreCLI@2 + condition: eq(variables['ShouldTest'], 'true') + displayName: 'Test and Code Coverage' + inputs: + command: test + projects: ${{ parameters.Tests }} + arguments: '--configuration Release /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:DebugType=Full' + publishTestResults: true + + # Coverage Generation + - task: reportgenerator@5 + condition: eq(variables['ShouldTest'], 'true') + displayName: Generate reports + inputs: + reports: '**/*.cobertura.xml' + targetdir: 'CoverageFolder' + reporttypes: 'HtmlInline_AzurePipelines' + + # Publish code coverage + - task: PublishCodeCoverageResults@2 + condition: eq(variables['ShouldTest'], 'true') + displayName: 'Publish code coverage' + inputs: + codeCoverageTool: Cobertura + summaryFileLocation: '**/*.cobertura.xml' + reportDirectory: CoverageFolder + + # Since NuGet packages are generated during the build, we need to copy them to the artifacts folder. + - task: CopyFiles@2 + displayName: 'Pack $(Build.BuildNumber)' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: '**/*$(PackageVersion).nupkg' + TargetFolder: '$(Build.ArtifactStagingDirectory)' + CleanTargetFolder: false + OverWrite: true + flattenFolders: true + + # Sign + - task: MSBuild@1 + displayName: 'Sign NuGet Packages' + inputs: + solution: 'Microsoft.FluentUI.signproj' + msbuildArguments: '/p:OutDir=$(Build.ArtifactStagingDirectory)\ /p:IntermediateOutputPath=$(Build.ArtifactStagingDirectory)\sign\' + + + - task: CopyFiles@2 + displayName: 'Copy signed packages to pickup folder' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: '**/*$(PackageVersion).nupkg' + TargetFolder: '$(Build.ArtifactStagingDirectory)\SignedPackages' + CleanTargetFolder: false + OverWrite: true + flattenFolders: true diff --git a/eng/pipelines/common-variables.yaml b/eng/pipelines/common-variables.yaml new file mode 100644 index 0000000000..bc468c4003 --- /dev/null +++ b/eng/pipelines/common-variables.yaml @@ -0,0 +1,23 @@ +variables: + - name: _TeamName + value: fluentui-blazor + - name: _RunAsPublic + value: True + - name: _RunAsInternal + value: False + + - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}: + - name: _RunAsPublic + value: False + - name: _RunAsInternal + value: True + - name: _SignType + value: real + - group: SDL_Settings + - name: _InternalBuildArgs + value: /p:DotNetSignType=$(_SignType) + /p:TeamName=$(_TeamName) + /p:DotNetPublishUsingPipelines=true + /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + #- name: PostBuildSign + # value: true diff --git a/eng/pipelines/update-assembly-version.ps1 b/eng/pipelines/update-assembly-version.ps1 new file mode 100644 index 0000000000..68a07d5f69 --- /dev/null +++ b/eng/pipelines/update-assembly-version.ps1 @@ -0,0 +1,157 @@ +<# +.DESCRIPTION + Update all .csproj files, adding these properties, excluding the files from $excludePatterns + - `AssemblyVersion = $assemblyVersion`, + - `FileVersion = $assemblyVersion`, + - `InformationalVersion = $assemblyVersion`, + - `Version = $packageVersion`, + +.PARAMETER sourcePath + Source path to list all .csproj files, by default the current path is used. + +.PARAMETER excludePatterns + List of files to exclude so as not to update the contents of the .csproj file. + +.PARAMETER assemblyVersion + Assembly version. + +.PARAMETER packageVersion + Package version. + +.EXAMPLE + $> .\update-assembly-version -sourcePath "./" -excludePatterns "**/src/Templates/content/**/*.csproj", "**/tests/TemplateValidation/**/*.csproj" -assemblyVersion "1.2.3" -packageVersion "1.2.3" + +.EXAMPLE + # Set version number (exclude some folders) + - task: PowerShell@2 + displayName: 'Versioning $(Build.BuildNumber)' + inputs: + targetType: 'filePath' + filePath: $(System.DefaultWorkingDirectory)/.azure-devops/common/update-assembly-version.ps1 + arguments: > # Use this to avoid newline characters in multiline string + -sourcePath "$(System.DefaultWorkingDirectory)/" + -excludePatterns "**/src/Templates/content/**/*.csproj", "**/tests/TemplateValidation/**/*.csproj" + -assemblyVersion "$(AssemblyVersion)" + -packageVersion "$(PackageVersion)" +#> + +param ( + [string]$sourcePath, + [string[]]$excludePatterns = @(), + [Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()][string]$assemblyVersion, + [string]$packageVersion +) + + +# Define the patterns +$includePattern = "$sourcePath/**/*.csproj" + +if ($assemblyVersion -eq $null) { + $assemblyVersion = "0.0.1" +} + +if ($packageVersion -eq $null) { + $packageVersion = $assemblyVersion +} + +Write-Host "Add or update assemblies versions '$assemblyVersion' and package versions '$packageVersion'." +Write-Host " - include: $includePattern." +Write-Host " - exclude: $excludePatterns." + +# ------------------------------------------ +# Get all files matching the include pattern +# And matching the exclude patterns +# ------------------------------------------ +function Get-FilesFromDirectory { + param ( + [string]$includePattern, + [string[]]$excludePatterns + ) + + # Get all files matching the include pattern + $allFiles = Get-ChildItem -Path $includePattern -Recurse + + + # Get all files matching the exclude pattern => $filteredFiles + $excludedFiles = @() # Empty array + if ($excludePatterns.Length -gt 0) { + foreach ($pattern in $excludePatterns) { + # Create a RegEx: replacing "**" by ".*", "*" by "[^/]*" + $parts = $pattern -split '[\\/]' + foreach ($i in 0..($parts.Length - 1)) { + if ($parts[$i] -eq '**') { + $parts[$i] = '.*' + } + if ($parts[$i] -eq '*') { + $parts[$i] = '[^/]*' + } + } + $excludeRegEx = $parts -join "\/" + + # Check all files to detect the matching one + foreach ($file in $allFiles) { + $match1 = ($file.FullName -replace "\\", "/") -match $excludeRegEx + if ($match1) { + $excludedFiles += $file.FullName + } + } + } + + # Exclude found files + $filteredFiles = $allFiles | Where-Object { $_.FullName -notin $excludedFiles } + } + + return $filteredFiles; +} + +# ------------------------------------------------------------- +# Add or update the PropertyName tag, to set the PropertyValue. +# in the XML file name +# ------------------------------------------------------------- +function Update-PropertyGroup { + param ( + [string]$fileName, + [string]$propertyName, + [string]$propertyValue + ) + + # Load the XML file and find the first "default" PropertyGroup + $xmlDoc = New-Object System.Xml.XmlDocument + $xmlDoc.Load($fileName) + + $propertyGroup = $xmlDoc.SelectSingleNode("//Project//PropertyGroup") + + # Find the VersionNumber element + $propertyTag = $xmlDoc.SelectSingleNode("//Project//PropertyGroup//$propertyName") + + if ($null -eq $propertyTag) { + $propertyTag = $xmlDoc.CreateElement($propertyName) + $propertyGroup.AppendChild($propertyTag) > $null # Suppress the output + } + + # Update the text value of the VersionNumber element + $propertyTag.InnerText = $propertyValue + + # Save the updated XML back to the file + $xmlDoc.Save($fileName) +} + +# ------------------------------------------ +# Main calls +# ------------------------------------------ +$filteredFiles = Get-FilesFromDirectory -includePattern $includePattern -excludePatterns $excludePatterns + +# Update the PropertyGroup items... +# - VersionNumber: '$(assemblyVersion)' +# - FileVersionNumber: '$(assemblyVersion)' +# - InformationalVersion: '$(assemblyVersion)' +# - PackageVersion: '$(packageVersion)' +foreach ($file in $filteredFiles) { + $name = $file.Name + $fileName = $file.FullName + Write-Host " .. Updating $name" + Update-PropertyGroup -fileName $fileName -propertyName "AssemblyVersion" -propertyValue $assemblyVersion + Update-PropertyGroup -fileName $fileName -propertyName "FileVersion" -propertyValue $assemblyVersion + Update-PropertyGroup -fileName $fileName -propertyName "InformationalVersion" -propertyValue $assemblyVersion + Update-PropertyGroup -fileName $fileName -propertyName "Version" -propertyValue $packageVersion +} diff --git a/.azure-devops/common/versioning.yml b/eng/pipelines/version.yml similarity index 80% rename from .azure-devops/common/versioning.yml rename to eng/pipelines/version.yml index 4944f972ab..2958fd10a8 100644 --- a/.azure-devops/common/versioning.yml +++ b/eng/pipelines/version.yml @@ -2,5 +2,5 @@ variables: # File and Package version # dev branch: 1.2.4-Preview-23282-1' (PackageSuffix is always ignored in Dev branch) # main branch: 1.2.4-RC.1' (PackageSuffix is ignored, if empty, in Main branch) - FileVersion: '4.5.0' # Set the next final version here. + FileVersion: '4.6.0' # Set the next final version here. PackageSuffix: '' diff --git a/examples/Demo/Server/Pages/_Layout.cshtml b/examples/Demo/Server/Pages/_Layout.cshtml index 9ac9e9db1a..aaa723d453 100644 --- a/examples/Demo/Server/Pages/_Layout.cshtml +++ b/examples/Demo/Server/Pages/_Layout.cshtml @@ -36,4 +36,4 @@ - \ No newline at end of file + diff --git a/examples/Demo/Shared/Components/MarkdownSection.razor b/examples/Demo/Shared/Components/MarkdownSection.razor index fdb0e40105..fe6403a5b5 100644 --- a/examples/Demo/Shared/Components/MarkdownSection.razor +++ b/examples/Demo/Shared/Components/MarkdownSection.razor @@ -1,8 +1,6 @@ @using Markdig @inherits FluentComponentBase -@HtmlContent - - - - +
+ @HtmlContent +
diff --git a/examples/Demo/Shared/Components/MarkdownSection.razor.cs b/examples/Demo/Shared/Components/MarkdownSection.razor.cs index 9793320c45..35759335c0 100644 --- a/examples/Demo/Shared/Components/MarkdownSection.razor.cs +++ b/examples/Demo/Shared/Components/MarkdownSection.razor.cs @@ -1,15 +1,18 @@ using Markdig; using Microsoft.AspNetCore.Components; - using Microsoft.FluentUI.AspNetCore.Components; +using Microsoft.JSInterop; -// Remember to replace the namespace below with your own project's namespace.. namespace FluentUI.Demo.Shared.Components; public partial class MarkdownSection : FluentComponentBase { private string? _content; private bool _raiseContentConverted; + private IJSObjectReference _jsModule = default!; + + [Inject] + protected IJSRuntime JSRuntime { get; set; } = default!; [Inject] private IStaticAssetService StaticAssetService { get; set; } = default!; @@ -60,10 +63,17 @@ protected override void OnInitialized() protected override async Task OnAfterRenderAsync(bool firstRender) { - - if (firstRender && !string.IsNullOrEmpty(FromAsset)) + if (firstRender) { - InternalContent = await StaticAssetService.GetAsync(FromAsset); + if (!string.IsNullOrEmpty(FromAsset)) + { + InternalContent = await StaticAssetService.GetAsync(FromAsset); + } + // add highlight for any code blocks + _jsModule = await JSRuntime.InvokeAsync("import", + "./_content/FluentUI.Demo.Shared/Components/MarkdownSection.razor.js"); + await _jsModule.InvokeVoidAsync("highlight"); + await _jsModule.InvokeVoidAsync("addCopyButton"); } if (_raiseContentConverted) @@ -81,8 +91,14 @@ private static MarkupString ConvertToMarkupString(string? value) { if (!string.IsNullOrWhiteSpace(value)) { + var builder = new MarkdownPipelineBuilder() + .UseAdvancedExtensions() + .Use(); + + var pipeline = builder.Build(); + // Convert markdown string to HTML - var html = Markdown.ToHtml(value, new MarkdownPipelineBuilder().UseAdvancedExtensions().Build()); + var html = Markdown.ToHtml(value, pipeline); // Return sanitized HTML as a MarkupString that Blazor can render return new MarkupString(html); diff --git a/examples/Demo/Shared/Components/MarkdownSection.razor.css b/examples/Demo/Shared/Components/MarkdownSection.razor.css new file mode 100644 index 0000000000..bfd401443e --- /dev/null +++ b/examples/Demo/Shared/Components/MarkdownSection.razor.css @@ -0,0 +1,62 @@ +::deep th { + padding: 0 5px 0 5px; + border-width: 1px; +} + +::deep td { + padding: 0 5px 0 5px; + border-width: 1px; +} + +.snippet { + margin-bottom: 0.5rem; + border: calc(var(--stroke-width) * 1px) solid var(--neutral-stroke-rest); + border-radius: calc(var(--control-corner-radius) * 1px); + overflow-y: auto; +} + +::deep .hljs { + background-color: var(--neutral-layer-2); + tab-size: 2em; +} + +::deep .hljs-copy-button { + border-color: var(--neutral-fill-strong-rest); + color: var(--accent-fill-rest); + top: 0.4rem; + /*background-color: var(--neutral-layer-2) !important;*/ + /*background-image: url('data:image/svg+xml;utf-8,');*/ +} + + ::deep .hljs-copy-button:hover { + border-color: var(--neutral-fill-strong-hover); + } + + ::deep .hljs-copy-button:active { + border-color: var(--neutral-fill-strong-active); + } + +::deep .hljs-copy { + cursor: pointer; + border-color: var(--neutral-stroke-rest); + border-radius: calc(var(--control-corner-radius) * 1px); + color: var(--accent-fill-rest); + background-color: var(--neutral-layer-2); + top: 0.4rem; +} + +::deep .hljs-copy { + position: absolute; + transform: translateX(calc(100% + 1.125em)); + right: 1em; + transition: background-color 200ms ease, transform 200ms ease-out; +} + +::deep .hljs-copy-wrapper { + position: relative; + overflow: hidden +} + + ::deep .hljs-copy-wrapper:hover .hljs-copy, .hljs-copy:focus { + transform: translateX(0); + } diff --git a/examples/Demo/Shared/Components/MarkdownSection.razor.js b/examples/Demo/Shared/Components/MarkdownSection.razor.js new file mode 100644 index 0000000000..fa6a271cf6 --- /dev/null +++ b/examples/Demo/Shared/Components/MarkdownSection.razor.js @@ -0,0 +1,30 @@ +export function highlight() { + var preTagList = document.getElementsByTagName('pre'); + var numberOfPreTags = preTagList.length; + for (var i = 0; i < numberOfPreTags; i++) { + var codeTag = preTagList[i].getElementsByTagName('code'); + hljs.highlightElement(codeTag[0]); + } +} + +export function addCopyButton() { + var snippets = document.querySelectorAll('.snippet'); + var numberOfSnippets = snippets.length; + for (var i = 0; i < numberOfSnippets; i++) { + let copyButton = snippets[i].getElementsByClassName("hljs-copy") + if (copyButton.length === 0) { + let code = snippets[i].getElementsByTagName('code')[0].innerText; + snippets[i].innerHTML = snippets[i].innerHTML + ''; // append copy button + + copyButton[0].addEventListener("click", function () { + navigator.clipboard.writeText(code); + + this.innerText = 'Copied!'; + let button = this; + setTimeout(function () { + button.innerText = 'Copy'; + }, 1000) + }); + } + } +} diff --git a/examples/Demo/Shared/Components/MarkdownSectionPreCodeExtension.cs b/examples/Demo/Shared/Components/MarkdownSectionPreCodeExtension.cs new file mode 100644 index 0000000000..4eeb51a09b --- /dev/null +++ b/examples/Demo/Shared/Components/MarkdownSectionPreCodeExtension.cs @@ -0,0 +1,34 @@ +using Markdig.Renderers; +using Markdig; +using Markdig.Renderers.Html; + +namespace FluentUI.Demo.Shared.Components; + +internal class MarkdownSectionPreCodeExtension : IMarkdownExtension +{ + public void Setup(MarkdownPipelineBuilder pipeline) + { + } + + public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) + { + var htmlRenderer = renderer as TextRendererBase; + if (htmlRenderer == null) + { + return; + } + + var originalCodeBlockRenderer = htmlRenderer.ObjectRenderers.FindExact(); + if (originalCodeBlockRenderer != null) + { + htmlRenderer.ObjectRenderers.Remove(originalCodeBlockRenderer); + } + + htmlRenderer.ObjectRenderers.AddIfNotAlready(new MarkdownSectionPreCodeRenderer( + new MarkdownSectionPreCodeRendererOptions + { + PreTagAttributes = "{.snippet .hljs-copy-wrapper}", + }) + ); + } +} diff --git a/examples/Demo/Shared/Components/MarkdownSectionPreCodeRenderer.cs b/examples/Demo/Shared/Components/MarkdownSectionPreCodeRenderer.cs new file mode 100644 index 0000000000..85f97c3dd6 --- /dev/null +++ b/examples/Demo/Shared/Components/MarkdownSectionPreCodeRenderer.cs @@ -0,0 +1,137 @@ +using Markdig.Extensions.GenericAttributes; +using Markdig.Helpers; +using Markdig.Parsers; +using Markdig.Renderers; +using Markdig.Renderers.Html; +using Markdig.Syntax; + +namespace FluentUI.Demo.Shared.Components; + +/// +/// Modified version of original markdig CodeBlockRenderer +/// +/// +internal class MarkdownSectionPreCodeRenderer : HtmlObjectRenderer +{ + private HashSet? _blocksAsDiv; + private readonly MarkdownSectionPreCodeRendererOptions? _options; + + public MarkdownSectionPreCodeRenderer(MarkdownSectionPreCodeRendererOptions? options) + { + _options = options; + } + public bool OutputAttributesOnPre { get; set; } + + /// + /// Gets a map of fenced code block infos that should be rendered as div blocks instead of pre/code blocks. + /// + public HashSet BlocksAsDiv => _blocksAsDiv ??= new HashSet(StringComparer.OrdinalIgnoreCase); + + protected override void Write(HtmlRenderer renderer, CodeBlock obj) + { + renderer.EnsureLine(); + + if (_blocksAsDiv is not null && (obj as FencedCodeBlock)?.Info is string info && _blocksAsDiv.Contains(info)) + { + var infoPrefix = (obj.Parser as FencedCodeBlockParser)?.InfoPrefix ?? + FencedCodeBlockParser.DefaultInfoPrefix; + + // We are replacing the HTML attribute `language-mylang` by `mylang` only for a div block + // NOTE that we are allocating a closure here + + if (renderer.EnableHtmlForBlock) + { + renderer.Write(" cls.StartsWith(infoPrefix, StringComparison.Ordinal) ? cls.Substring(infoPrefix.Length) : cls) + .Write('>'); + } + + renderer.WriteLeafRawLines(obj, true, true, true); + + if (renderer.EnableHtmlForBlock) + { + renderer.WriteLine(""); + } + } + else + { + if (renderer.EnableHtmlForBlock) + { + renderer.Write("'); + } + + renderer.WriteLeafRawLines(obj, true, true); + + if (renderer.EnableHtmlForBlock) + { + renderer.WriteLine(""); + } + } + + renderer.EnsureLine(); + } + + private void WritePreAttributes(HtmlRenderer renderer, CodeBlock obj, string? preGenericAttributes) + { + HtmlAttributes? orig = null; + + if (OutputAttributesOnPre) + { + orig = obj.TryGetAttributes(); + } + + WriteElementAttributes(renderer, orig, preGenericAttributes); + } + + private void WriteCodeAttributes(HtmlRenderer renderer, CodeBlock obj, string? codeGenericAttributes) + { + HtmlAttributes? orig = null; + + if (!OutputAttributesOnPre) + { + orig = obj.TryGetAttributes(); + } + + WriteElementAttributes(renderer, orig, codeGenericAttributes); + } + static private void WriteElementAttributes(HtmlRenderer renderer, HtmlAttributes? fromCodeBlock, string? genericAttributes) + { + // origin code block had no attributes + fromCodeBlock ??= new HtmlAttributes(); + + // append if any additional attributes provided + var ss = new StringSlice(genericAttributes); + if (!ss.IsEmpty && GenericAttributesParser.TryParse(ref ss, out var attributes)) + { + if (fromCodeBlock != null) + { + if (attributes.Classes != null) + { + foreach (var a in attributes.Classes) + { + fromCodeBlock.AddClass(a); + } + } + if (attributes.Properties != null) + { + foreach (var pr in attributes.Properties) + { + fromCodeBlock.AddProperty(pr.Key, pr.Value!); + } + } + } + } + + // + renderer.WriteAttributes(fromCodeBlock); + } +} diff --git a/examples/Demo/Shared/Components/MarkdownSectionPreCodeRendererOptions.cs b/examples/Demo/Shared/Components/MarkdownSectionPreCodeRendererOptions.cs new file mode 100644 index 0000000000..28554927a9 --- /dev/null +++ b/examples/Demo/Shared/Components/MarkdownSectionPreCodeRendererOptions.cs @@ -0,0 +1,16 @@ +namespace FluentUI.Demo.Shared.Components; + +/// +/// Options for MarkdownSectionPreCodeRenderer +/// +internal class MarkdownSectionPreCodeRendererOptions +{ + /// + /// html attributes for Tag element in markdig generic attributes format + /// + public string? PreTagAttributes; + /// + /// html attributes for Code element in markdig generic attributes format + /// + public string? CodeTagAttributes; +} diff --git a/examples/Demo/Shared/FluentUI.Demo.Shared.csproj b/examples/Demo/Shared/FluentUI.Demo.Shared.csproj index 214cc44da2..8aa3155b75 100644 --- a/examples/Demo/Shared/FluentUI.Demo.Shared.csproj +++ b/examples/Demo/Shared/FluentUI.Demo.Shared.csproj @@ -30,7 +30,7 @@ - -