diff --git a/build/Publish.targets b/build/Publish.targets new file mode 100644 index 0000000000..4fd0137ab3 --- /dev/null +++ b/build/Publish.targets @@ -0,0 +1,135 @@ + + + + $(RepositoryRoot).deps\assets\ + + aspnetcore_base_runtime.version + $(ArtifactsDir)$(BaseRuntimeVersionFileName) + latest.aspnetcore.version + $(ArtifactsDir)$(LatestRuntimeVersionFileName) + + + + + + + + + + + + + + + + + + + + + + + Runtime/$(PackageVersion)/ + Runtime/$(SharedFxCliBlobChannel)/ + nuGetPackagesArchive-$(PackageVersion).lzma + aspnetcore-runtime-$(PackageVersion) + aspnetcore-runtime-latest + aspnetcore-runtime-symbols-$(PackageVersion) + aspnetcore-runtime-internal-$(PackageVersion) + + + + + + $(BlobBasePath)$(SymbolsArchiveBaseFileName)-%(RuntimeSymbolsArchive.Identity)%(RuntimeSymbolsArchive.FileExt) + + + + + $(BlobBasePath)$(PackageArchiveFileName) + + + + $(BlobBasePath)$(IntermediateInstallerBaseFileName)-%(IntermediateInstaller.Identity)%(IntermediateInstaller.FileExt) + + + + $(BlobBasePath)$(BaseRuntimeVersionFileName) + text/plain + + + + + $(BlobBasePath)$(InstallerBaseFileName)-%(NativeInstaller.Identity)%(NativeInstaller.FileExt) + + + + $(AliasBlobBasePath)$(InstallerAliasBaseFileName)-%(NativeInstaller.Identity)%(NativeInstaller.FileExt) + true + + + + + $(AliasBlobBasePath)%(SharedFxVersionBadge.FileName)%(SharedFxVersionBadge.Extension) + no-cache, no-store, must-revalidate + image/svg+xml + true + + + + $(AliasBlobBasePath)$(LatestRuntimeVersionFileName) + no-cache, no-store, must-revalidate + text/plain + true + + + + + + + + + + <_MissingFiles Include="%(FilesToPublish.Identity)" Condition=" ! Exists(%(FilesToPublish.Identity))" /> + + + + + + + + + + $(AzureBlobRelativePathBase)/ + + + + + + + + + + diff --git a/build/SharedFx.targets b/build/SharedFx.targets index eb0e738b2d..f396901da0 100644 --- a/build/SharedFx.targets +++ b/build/SharedFx.targets @@ -41,7 +41,7 @@ true - + @@ -134,22 +134,6 @@ Overwrite="true" /> - - - - - - diff --git a/build/repo.props b/build/repo.props index e628b52e47..ea5b24a29d 100644 --- a/build/repo.props +++ b/build/repo.props @@ -18,6 +18,37 @@ $(RepositoryRoot).deps\mirror\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -26,6 +57,10 @@ FeedCredential="$(DotNetAssetRootAccessTokenSuffix)" /> + + true + + diff --git a/build/repo.targets b/build/repo.targets index d16b901ae0..05e40b4a16 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -5,6 +5,7 @@ + <_RepositoryBuildTargets Condition="'$(_RepositoryBuildTargets)'=='' AND '$(SkipTests)'=='true'">/t:Package /t:VerifyPackages diff --git a/build/tasks/PublishToAzureBlob.cs b/build/tasks/PublishToAzureBlob.cs new file mode 100644 index 0000000000..94da58dc8a --- /dev/null +++ b/build/tasks/PublishToAzureBlob.cs @@ -0,0 +1,100 @@ +// 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.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Build.Framework; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Blob; + +namespace RepoTasks +{ + /// + /// Publish files to an Azure storage blob + /// + public class PublishToAzureBlob : Microsoft.Build.Utilities.Task, ICancelableTask + { + private CancellationTokenSource _cts = new CancellationTokenSource(); + + /// + /// The files to publish. + /// + [Required] + public ITaskItem[] Files { get; set; } + + /// + /// The Azure blob storage account name. + /// + [Required] + public string AccountName { get; set; } + + /// + /// The SAS token used to write to Azure. + /// + [Required] + public string SharedAccessToken { get; set; } + + /// + /// The Azure blob storage container name + /// + [Required] + public string ContainerName { get; set; } + + public void Cancel() => _cts.Cancel(); + + public override bool Execute() + => ExecuteAsync().Result; + + private async Task ExecuteAsync() + { + var connectionString = $"BlobEndpoint=https://{AccountName}.blob.core.windows.net;SharedAccessSignature={SharedAccessToken}"; + + var account = CloudStorageAccount.Parse(connectionString); + var client = account.CreateCloudBlobClient(); + var container = client.GetContainerReference(ContainerName); + + var ctx = new OperationContext(); + + foreach (var item in Files) + { + // normalize slashes + var dest = item.GetMetadata("RelativeBlobPath") + .Replace('\\', '/') + .Replace("//", "/"); + var contentType = item.GetMetadata("ContentType"); + var cacheControl = item.GetMetadata("CacheControl"); + + if (string.IsNullOrEmpty(dest)) + { + Log.LogError($"Item {item.ItemSpec} is missing required metadata 'RelativeBlobPath'"); + return false; + } + + var blob = container.GetBlockBlobReference(dest); + + if (!string.IsNullOrEmpty(cacheControl)) + { + blob.Properties.CacheControl = cacheControl; + } + + if (!string.IsNullOrEmpty(contentType)) + { + blob.Properties.ContentType = contentType; + } + + Log.LogMessage(MessageImportance.High, $"Publishing {item.ItemSpec} to https://{AccountName}.blob.core.windows.net/{ContainerName}/{dest}"); + + var accessCondition = bool.TryParse(item.GetMetadata("Overwrite"), out var overwrite) && overwrite + ? AccessCondition.GenerateEmptyCondition() + : AccessCondition.GenerateIfNotExistsCondition(); + + await blob.UploadFromFileAsync(item.ItemSpec, accessCondition, new BlobRequestOptions(), ctx, _cts.Token); + } + + return true; + } + } +} diff --git a/build/tasks/RepoTasks.csproj b/build/tasks/RepoTasks.csproj index 2b538f7e0b..4c4e3556e8 100644 --- a/build/tasks/RepoTasks.csproj +++ b/build/tasks/RepoTasks.csproj @@ -8,6 +8,7 @@ + diff --git a/build/tasks/RepoTasks.tasks b/build/tasks/RepoTasks.tasks index 1b8dbe7e76..e1a43cf51f 100644 --- a/build/tasks/RepoTasks.tasks +++ b/build/tasks/RepoTasks.tasks @@ -3,12 +3,19 @@ <_RepoTaskAssembly>$(MSBuildThisFileDirectory)bin\publish\RepoTasks.dll - - - - - - + + + + + + + + + + + + + diff --git a/version.props b/version.props index e5fd0676de..b4422a95c4 100644 --- a/version.props +++ b/version.props @@ -5,5 +5,7 @@ $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final $(VersionSuffix)-$(BuildNumber) + + master