diff --git a/.azure/pipelines/site-extensions.yml b/.azure/pipelines/site-extensions.yml new file mode 100644 index 0000000000..69924ca3c1 --- /dev/null +++ b/.azure/pipelines/site-extensions.yml @@ -0,0 +1,38 @@ +trigger: + branches: + include: + - release/2.2 + +phases: +- phase: SiteExtensions + variables: + CI: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + + # This variable is required by MicroBuildSigningPlugin to determine permissions for codesigning. + TeamName: AspNetCore + + # SignType = { test, real } + # This is prefixed underscore because variables automatically become environment variables (and therefore MSBuild properties), + # and this one was causing issues in MSBuild projects which use the $(SignType) MSbuild prop. + _SignType: real + + steps: + - task: MicroBuildSigningPlugin@1 + displayName: Install MicroBuild plugin + condition: and(succeeded(), in(variables['_SignType'], 'test', 'real')) + inputs: + signType: $(_SignType) + zipSources: false + - script: src/SiteExtensions/build.cmd -ci + displayName: Run src/SiteExtensions/build.cmd + - task: PublishBuildArtifacts@1 + displayName: Upload artifacts + condition: eq(variables['system.pullrequest.isfork'], false) + inputs: + pathtoPublish: ./src/SiteExtensions/artifacts/ + artifactName: artifacts-Windows-Release + artifactType: Container + - task: MicroBuildCleanup@1 + displayName: Cleanup MicroBuild tasks + condition: always() diff --git a/src/SiteExtensions/Directory.Build.props b/src/SiteExtensions/Directory.Build.props new file mode 100644 index 0000000000..e0780dd926 --- /dev/null +++ b/src/SiteExtensions/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/SiteExtensions/SiteExtensions.sln b/src/SiteExtensions/SiteExtensions.sln new file mode 100644 index 0000000000..8fe1d6c64c --- /dev/null +++ b/src/SiteExtensions/SiteExtensions.sln @@ -0,0 +1,54 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0ED05384-4F64-44BA-A4AA-47519DA26E8C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.AzureAppServices.SiteExtension", "src\Microsoft.AspNetCore.AzureAppServices.SiteExtension\Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj", "{69E22952-302D-4C56-B2BE-7C086EB05C79}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Web.Xdt.Extensions", "src\Microsoft.Web.Xdt.Extensions\Microsoft.Web.Xdt.Extensions.csproj", "{637E1D65-7F1C-476B-AD0A-30B295DF5414}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|x64.ActiveCfg = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|x64.Build.0 = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|x86.ActiveCfg = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Debug|x86.Build.0 = Debug|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|Any CPU.Build.0 = Release|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|x64.ActiveCfg = Release|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|x64.Build.0 = Release|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|x86.ActiveCfg = Release|Any CPU + {69E22952-302D-4C56-B2BE-7C086EB05C79}.Release|x86.Build.0 = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|Any CPU.Build.0 = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|x64.ActiveCfg = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|x64.Build.0 = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|x86.ActiveCfg = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Debug|x86.Build.0 = Debug|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|Any CPU.ActiveCfg = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|Any CPU.Build.0 = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|x64.ActiveCfg = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|x64.Build.0 = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|x86.ActiveCfg = Release|Any CPU + {637E1D65-7F1C-476B-AD0A-30B295DF5414}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {69E22952-302D-4C56-B2BE-7C086EB05C79} = {0ED05384-4F64-44BA-A4AA-47519DA26E8C} + {637E1D65-7F1C-476B-AD0A-30B295DF5414} = {0ED05384-4F64-44BA-A4AA-47519DA26E8C} + EndGlobalSection +EndGlobal diff --git a/src/SiteExtensions/build.cmd b/src/SiteExtensions/build.cmd new file mode 100644 index 0000000000..f4169ea5e4 --- /dev/null +++ b/src/SiteExtensions/build.cmd @@ -0,0 +1,3 @@ +@ECHO OFF +SET RepoRoot="%~dp0..\.." +%RepoRoot%\build.cmd -LockFile %RepoRoot%\korebuild-lock.txt -Path %~dp0 %* diff --git a/src/SiteExtensions/build.sh b/src/SiteExtensions/build.sh new file mode 100644 index 0000000000..d5bb0cf631 --- /dev/null +++ b/src/SiteExtensions/build.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +repo_root="$DIR/../.." +"$repo_root/build.sh" --path "$DIR" --lockfile "$repo_root/korebuild-lock.txt" "$@" diff --git a/src/SiteExtensions/build/dependencies.props b/src/SiteExtensions/build/dependencies.props new file mode 100644 index 0000000000..4a707b5182 --- /dev/null +++ b/src/SiteExtensions/build/dependencies.props @@ -0,0 +1,13 @@ + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + + + 2.2.0-preview2-20181004.6 + 2.1.1-rtm-31076 + 2.2.0-rtm-35515 + 1.4.0 + + + diff --git a/src/SiteExtensions/build/repo.props b/src/SiteExtensions/build/repo.props new file mode 100644 index 0000000000..25129c9001 --- /dev/null +++ b/src/SiteExtensions/build/repo.props @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/SiteExtensions/build/sources.props b/src/SiteExtensions/build/sources.props new file mode 100644 index 0000000000..43ce6137a6 --- /dev/null +++ b/src/SiteExtensions/build/sources.props @@ -0,0 +1,11 @@ + + + + + $(RestoreSources); + https://api.nuget.org/v3/index.json; + https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json; + + + + \ No newline at end of file diff --git a/src/SiteExtensions/global.json b/src/SiteExtensions/global.json new file mode 100644 index 0000000000..336b8c5dba --- /dev/null +++ b/src/SiteExtensions/global.json @@ -0,0 +1,8 @@ +{ + "sdk": { + "version": "2.2.100-preview2-009404" + }, + "msbuild-sdks": { + "Internal.AspNetCore.Sdk": "2.2.0-preview2-20181011.10" + } +} diff --git a/src/SiteExtensions/src/Directory.Build.props b/src/SiteExtensions/src/Directory.Build.props new file mode 100644 index 0000000000..4b89a431e7 --- /dev/null +++ b/src/SiteExtensions/src/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj new file mode 100644 index 0000000000..4b8b8f0762 --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/Microsoft.AspNetCore.AzureAppServices.SiteExtension.csproj @@ -0,0 +1,50 @@ + + + + ASP.NET Core Logging Extensions + This extension enables additional functionality for ASP.NET Core on Azure WebSites, such as enabling Azure logging. + net461 + false + aspnet;logging;aspnetcore;AzureSiteExtension;keyvault;configuration;dataprotection + false + AzureSiteExtension + true + false + false + false + content + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/applicationHost.xdt b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/applicationHost.xdt new file mode 100644 index 0000000000..7078c4f254 --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/applicationHost.xdt @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/scmApplicationHost.xdt b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/scmApplicationHost.xdt new file mode 100644 index 0000000000..a8dd367f9f --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.AspNetCore.AzureAppServices.SiteExtension/scmApplicationHost.xdt @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/InsertOrAppendAttribute.cs b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/InsertOrAppendAttribute.cs new file mode 100644 index 0000000000..c2e711cb93 --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/InsertOrAppendAttribute.cs @@ -0,0 +1,144 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Xml; +using Microsoft.Web.XmlTransform; + +namespace Microsoft.Web.Xdt.Extensions +{ + /// + /// Insert or append to the given attribute + /// + public class InsertOrAppendAttribute : Transform + { + /// + /// + /// + public InsertOrAppendAttribute() + : base(TransformFlags.UseParentAsTargetNode, MissingTargetMessage.Error) + { + } + + private string _attributeName; + + /// + /// + /// + protected string AttributeName + { + get + { + if (_attributeName == null) + { + _attributeName = GetArgumentValue("Attribute"); + } + return _attributeName; + } + } + + /// + /// Extracts a value from the arguments provided + /// + /// + /// + protected string GetArgumentValue(string name) + { + if (string.IsNullOrEmpty(name)) + { + throw new ArgumentNullException(nameof(name)); + } + + string result = null; + if (Arguments != null && Arguments.Count > 0) + { + foreach (var arg in Arguments) + { + if (!string.IsNullOrEmpty(arg)) + { + var trimmedArg = arg.Trim(); + if (trimmedArg.StartsWith(name, StringComparison.OrdinalIgnoreCase)) + { + var start = arg.IndexOf('\''); + var last = arg.LastIndexOf('\''); + if (start <= 0 || last <= 0 || last <= start) + { + throw new ArgumentException("Expected two ['] characters"); + } + + var value = trimmedArg.Substring(start, last - start); + + // remove any leading or trailing ' + value = value.Trim().TrimStart('\'').TrimStart('\''); + result = value; + } + } + } + } + return result; + } + + /// + /// + /// + protected override void Apply() + { + if (TargetChildNodes == null || TargetChildNodes.Count == 0) + { + TargetNode.AppendChild(TransformNode); + } + else + { + XmlAttribute transformAtt = null; + + foreach (XmlAttribute att in TransformNode.Attributes) + { + if (string.Equals(att.Name, AttributeName, StringComparison.OrdinalIgnoreCase)) + { + transformAtt = att; + break; + } + } + + if (transformAtt == null) + { + throw new InvalidOperationException("No target attribute to append"); + } + + foreach (XmlNode targetNode in TargetChildNodes) + { + var foundAttribute = false; + foreach (XmlAttribute att in targetNode.Attributes) + { + if (string.Equals(att.Name, AttributeName, StringComparison.OrdinalIgnoreCase)) + { + foundAttribute = true; + if (string.IsNullOrEmpty(att.Value)) + { + att.Value = transformAtt.Value; + } + else + { + // TODO: This doesn't compose well with insertOrAppend being applied on the TargetNode. + // The target node is created with the children it has in the transform, which means we would + // duplicate the value here. + if (att.Value == transformAtt.Value) + { + return; + } + att.Value = $"{att.Value};{transformAtt.Value}"; + } + } + } + + if (!foundAttribute) + { + var attribute = targetNode.OwnerDocument.CreateAttribute(AttributeName); + attribute.Value = transformAtt.Value; + targetNode.Attributes.Append(attribute); + } + } + } + } + } +} \ No newline at end of file diff --git a/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/Microsoft.Web.Xdt.Extensions.csproj b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/Microsoft.Web.Xdt.Extensions.csproj new file mode 100644 index 0000000000..4222ec4e2d --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/Microsoft.Web.Xdt.Extensions.csproj @@ -0,0 +1,14 @@ + + + + Additional functionality for Xdt transforms. + net461 + true + xdt + + + + + + + \ No newline at end of file diff --git a/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/baseline.netframework.json b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/baseline.netframework.json new file mode 100644 index 0000000000..202b401f50 --- /dev/null +++ b/src/SiteExtensions/src/Microsoft.Web.Xdt.Extensions/baseline.netframework.json @@ -0,0 +1,53 @@ +{ + "AssemblyIdentity": "Microsoft.Web.Xdt.Extensions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", + "Types": [ + { + "Name": "Microsoft.Web.Xdt.Extensions.InsertOrAppendAttribute", + "Visibility": "Public", + "Kind": "Class", + "BaseType": "Microsoft.Web.XmlTransform.Transform", + "ImplementedInterfaces": [], + "Members": [ + { + "Kind": "Method", + "Name": "get_AttributeName", + "Parameters": [], + "ReturnType": "System.String", + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "GetArgumentValue", + "Parameters": [ + { + "Name": "name", + "Type": "System.String" + } + ], + "ReturnType": "System.String", + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Method", + "Name": "Apply", + "Parameters": [], + "ReturnType": "System.Void", + "Virtual": true, + "Override": true, + "Visibility": "Protected", + "GenericParameter": [] + }, + { + "Kind": "Constructor", + "Name": ".ctor", + "Parameters": [], + "Visibility": "Public", + "GenericParameter": [] + } + ], + "GenericParameters": [] + } + ] +} \ No newline at end of file diff --git a/src/SiteExtensions/version.props b/src/SiteExtensions/version.props new file mode 100644 index 0000000000..4889a26987 --- /dev/null +++ b/src/SiteExtensions/version.props @@ -0,0 +1,12 @@ + + + 2.2.0 + rtm + $(VersionPrefix) + $(VersionPrefix)-$(VersionSuffix)-final + t000 + a- + $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) + $(VersionSuffix)-$(BuildNumber) + +