2016-02-15 10:07:39 -08:00
using System ;
2016-04-25 13:17:46 -07:00
using System.Collections.Generic ;
2016-02-12 10:11:30 -08:00
using System.IO ;
2016-04-25 13:17:46 -07:00
using System.Linq ;
2016-03-16 14:39:02 -07:00
using System.Net.Http ;
using System.Text ;
2016-04-08 08:57:24 -07:00
using System.Text.RegularExpressions ;
2016-02-15 10:07:39 -08:00
using Microsoft.DotNet.Cli.Build.Framework ;
2016-03-07 12:20:50 -08:00
using Microsoft.WindowsAzure.Storage ;
using Microsoft.WindowsAzure.Storage.Blob ;
2016-02-12 10:11:30 -08:00
using static Microsoft . DotNet . Cli . Build . Framework . BuildHelpers ;
namespace Microsoft.DotNet.Cli.Build
{
public static class PublishTargets
{
2016-03-23 16:37:59 -07:00
private static AzurePublisher AzurePublisherTool { get ; set ; }
private static DebRepoPublisher DebRepoPublisherTool { get ; set ; }
2016-03-07 12:20:50 -08:00
2016-03-07 14:52:41 -08:00
private static string Channel { get ; set ; }
2016-03-07 12:20:50 -08:00
2016-03-23 16:37:59 -07:00
private static string CliVersion { get ; set ; }
2016-03-07 12:20:50 -08:00
2016-03-23 16:37:59 -07:00
private static string CliNuGetVersion { get ; set ; }
2016-03-17 22:22:22 -07:00
2016-03-23 16:37:59 -07:00
private static string SharedFrameworkNugetVersion { get ; set ; }
2016-03-07 12:20:50 -08:00
[Target]
public static BuildTargetResult InitPublish ( BuildTargetContext c )
{
2016-03-23 16:37:59 -07:00
AzurePublisherTool = new AzurePublisher ( ) ;
DebRepoPublisherTool = new DebRepoPublisher ( Dirs . Packages ) ;
2016-03-07 12:20:50 -08:00
2016-03-23 17:13:58 -07:00
CliVersion = c . BuildContext . Get < BuildVersion > ( "BuildVersion" ) . SimpleVersion ;
CliNuGetVersion = c . BuildContext . Get < BuildVersion > ( "BuildVersion" ) . NuGetVersion ;
2016-05-27 13:24:39 -07:00
SharedFrameworkNugetVersion = CliDependencyVersions . SharedFrameworkVersion ;
2016-03-07 14:52:41 -08:00
Channel = c . BuildContext . Get < string > ( "Channel" ) ;
2016-03-23 16:37:59 -07:00
2016-03-07 12:20:50 -08:00
return c . Success ( ) ;
}
[ Target ( nameof ( PrepareTargets . Init ) ,
nameof ( PublishTargets . InitPublish ) ,
2016-03-24 10:50:29 -07:00
nameof ( PublishTargets . PublishArtifacts ) ,
2016-04-25 13:17:46 -07:00
nameof ( PublishTargets . TriggerDockerHubBuilds ) ,
nameof ( PublishTargets . FinalizeBuild ) ) ]
2016-03-07 14:52:41 -08:00
[Environment("PUBLISH_TO_AZURE_BLOB", "1", "true")] // This is set by CI systems
2016-02-12 10:11:30 -08:00
public static BuildTargetResult Publish ( BuildTargetContext c )
{
2016-03-07 12:20:50 -08:00
return c . Success ( ) ;
}
2016-02-16 11:39:17 -08:00
2016-04-25 13:17:46 -07:00
[Target]
public static BuildTargetResult FinalizeBuild ( BuildTargetContext c )
{
if ( CheckIfAllBuildsHavePublished ( ) )
{
string targetContainer = $"{Channel}/Binaries/Latest/" ;
string targetVersionFile = $"{targetContainer}{CliNuGetVersion}" ;
2016-04-29 14:05:41 -07:00
string semaphoreBlob = $"{Channel}/Binaries/publishSemaphore" ;
AzurePublisherTool . CreateBlobIfNotExists ( semaphoreBlob ) ;
string leaseId = AzurePublisherTool . AcquireLeaseOnBlob ( semaphoreBlob ) ;
2016-04-25 13:17:46 -07:00
// Prevent race conditions by dropping a version hint of what version this is. If we see this file
// and it is the same as our version then we know that a race happened where two+ builds finished
// at the same time and someone already took care of publishing and we have no work to do.
if ( AzurePublisherTool . IsLatestSpecifiedVersion ( targetVersionFile ) )
{
2016-05-02 01:03:31 -07:00
AzurePublisherTool . ReleaseLeaseOnBlob ( semaphoreBlob , leaseId ) ;
2016-04-25 13:17:46 -07:00
return c . Success ( ) ;
}
else
{
2016-05-26 10:20:14 -07:00
Regex versionFileRegex = new Regex ( @"(?<version>\d\.\d\.\d)-(?<release>.*)?" ) ;
// Delete old version files
2016-05-02 01:03:31 -07:00
AzurePublisherTool . ListBlobs ( $"{targetContainer}" )
. Select ( s = > s . Replace ( "/dotnet/" , "" ) )
2016-05-26 10:20:14 -07:00
. Where ( s = > versionFileRegex . IsMatch ( s ) )
2016-05-02 01:03:31 -07:00
. ToList ( )
. ForEach ( f = > AzurePublisherTool . TryDeleteBlob ( f ) ) ;
2016-04-25 13:17:46 -07:00
// Drop the version file signaling such for any race-condition builds (see above comment).
AzurePublisherTool . DropLatestSpecifiedVersion ( targetVersionFile ) ;
}
try
{
2016-05-02 10:32:28 -07:00
// Copy the latest CLI bits
CopyBlobs ( $"{Channel}/Binaries/{CliNuGetVersion}/" , targetContainer ) ;
2016-05-04 12:25:26 -07:00
2016-05-02 10:32:28 -07:00
// Copy the latest installer files
CopyBlobs ( $"{Channel}/Installers/{CliNuGetVersion}/" , $"{Channel}/Installers/Latest/" ) ;
2016-05-26 12:48:16 -07:00
// Generate the CLI and SDK Version text files
List < string > versionFiles = new List < string > ( )
{
"win.x86.version" ,
"win.x64.version" ,
"ubuntu.x64.version" ,
"ubuntu.16.04.x64.version" ,
"rhel.x64.version" ,
"osx.x64.version" ,
"debian.x64.version" ,
2016-05-26 23:16:18 -07:00
"centos.x64.version" ,
2016-05-31 13:54:35 -07:00
"fedora.23.x64.version" ,
"opensuse.13.2.x64.version"
2016-05-26 12:48:16 -07:00
} ;
2016-04-25 13:17:46 -07:00
string cliVersion = Utils . GetCliVersionFileContent ( c ) ;
foreach ( string version in versionFiles )
{
AzurePublisherTool . PublishStringToBlob ( $"{Channel}/dnvm/latest.{version}" , cliVersion ) ;
}
}
finally
{
2016-05-02 09:54:10 -07:00
AzurePublisherTool . ReleaseLeaseOnBlob ( semaphoreBlob , leaseId ) ;
2016-04-25 13:17:46 -07:00
}
}
return c . Success ( ) ;
}
2016-05-02 10:32:28 -07:00
private static void CopyBlobs ( string sourceFolder , string destinationFolder )
{
foreach ( string blob in AzurePublisherTool . ListBlobs ( sourceFolder ) )
{
string source = blob . Replace ( "/dotnet/" , "" ) ;
string targetName = Path . GetFileName ( blob )
2016-05-16 15:30:53 -07:00
. Replace ( CliNuGetVersion , "latest" ) ;
2016-05-02 10:32:28 -07:00
string target = $"{destinationFolder}{targetName}" ;
AzurePublisherTool . CopyBlob ( source , target ) ;
}
}
2016-04-25 13:17:46 -07:00
private static bool CheckIfAllBuildsHavePublished ( )
{
2016-05-04 12:25:26 -07:00
Dictionary < string , bool > badges = new Dictionary < string , bool > ( )
2016-04-25 13:17:46 -07:00
{
{ "Windows_x86" , false } ,
{ "Windows_x64" , false } ,
{ "Ubuntu_x64" , false } ,
2016-05-26 12:48:16 -07:00
{ "Ubuntu_16_04_x64" , false } ,
2016-04-25 13:17:46 -07:00
{ "RHEL_x64" , false } ,
{ "OSX_x64" , false } ,
{ "Debian_x64" , false } ,
2016-05-26 23:33:37 -07:00
{ "CentOS_x64" , false } ,
2016-05-31 13:54:35 -07:00
{ "Fedora_23_x64" , false } ,
{ "openSUSE_13_2_x64" , false }
2016-04-25 13:17:46 -07:00
} ;
2016-05-02 10:32:28 -07:00
List < string > blobs = new List < string > ( AzurePublisherTool . ListBlobs ( $"{Channel}/Binaries/{CliNuGetVersion}/" ) ) ;
2016-04-25 13:17:46 -07:00
2016-05-31 13:54:35 -07:00
var versionBadgeName = $"{Monikers.GetBadgeMoniker()}" ;
2016-04-25 13:17:46 -07:00
if ( badges . ContainsKey ( versionBadgeName ) = = false )
{
throw new ArgumentException ( "A new OS build was added without adding the moniker to the {nameof(badges)} lookup" ) ;
}
2016-05-02 10:32:28 -07:00
foreach ( string file in blobs )
2016-04-25 13:17:46 -07:00
{
string name = Path . GetFileName ( file ) ;
string key = string . Empty ;
foreach ( string img in badges . Keys )
{
if ( ( name . StartsWith ( $"{img}" ) ) & & ( name . EndsWith ( ".svg" ) ) )
{
key = img ;
break ;
}
}
if ( string . IsNullOrEmpty ( key ) = = false )
{
badges [ key ] = true ;
}
}
return badges . Keys . All ( key = > badges [ key ] ) ;
}
2016-03-18 02:23:24 -07:00
[ Target (
2016-03-23 16:37:59 -07:00
nameof ( PublishTargets . PublishInstallerFilesToAzure ) ,
nameof ( PublishTargets . PublishArchivesToAzure ) ,
2016-05-10 13:22:58 -07:00
/*nameof(PublishTargets.PublishDebFilesToDebianRepo),*/ //https://github.com/dotnet/cli/issues/2973
2016-03-23 16:37:59 -07:00
nameof ( PublishTargets . PublishCliVersionBadge ) ) ]
public static BuildTargetResult PublishArtifacts ( BuildTargetContext c ) = > c . Success ( ) ;
[ Target (
nameof ( PublishTargets . PublishSdkInstallerFileToAzure ) ,
2016-05-16 15:30:53 -07:00
nameof ( PublishTargets . PublishCombinedFrameworkSDKHostInstallerFileToAzure ) ) ]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishInstallerFilesToAzure ( BuildTargetContext c ) = > c . Success ( ) ;
[ Target (
2016-04-04 20:13:13 -07:00
nameof ( PublishTargets . PublishCombinedHostFrameworkSdkArchiveToAzure ) ,
2016-04-24 13:01:52 -07:00
nameof ( PublishTargets . PublishCombinedFrameworkSDKArchiveToAzure ) ,
2016-04-04 20:13:13 -07:00
nameof ( PublishTargets . PublishSDKSymbolsArchiveToAzure ) ) ]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishArchivesToAzure ( BuildTargetContext c ) = > c . Success ( ) ;
[ Target (
2016-05-16 15:30:53 -07:00
nameof ( PublishSdkDebToDebianRepo ) ) ]
2016-05-29 22:38:45 -07:00
[BuildPlatforms(BuildPlatform.Ubuntu, "14.04")]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishDebFilesToDebianRepo ( BuildTargetContext c )
2016-03-07 12:20:50 -08:00
{
return c . Success ( ) ;
}
2016-02-12 10:11:30 -08:00
2016-03-07 12:20:50 -08:00
[Target]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishCliVersionBadge ( BuildTargetContext c )
2016-03-07 12:20:50 -08:00
{
2016-03-23 17:13:58 -07:00
var versionBadge = c . BuildContext . Get < string > ( "VersionBadge" ) ;
var versionBadgeBlob = $"{Channel}/Binaries/{CliNuGetVersion}/{Path.GetFileName(versionBadge)}" ;
AzurePublisherTool . PublishFile ( versionBadgeBlob , versionBadge ) ;
2016-03-23 16:37:59 -07:00
return c . Success ( ) ;
}
2016-05-16 15:30:53 -07:00
2016-03-23 16:37:59 -07:00
[Target]
2016-05-29 22:38:45 -07:00
[BuildPlatforms(BuildPlatform.Ubuntu, "14.04")]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishSdkInstallerFileToAzure ( BuildTargetContext c )
{
var version = CliNuGetVersion ;
2016-03-23 17:13:58 -07:00
var installerFile = c . BuildContext . Get < string > ( "SdkInstallerFile" ) ;
2016-03-23 16:37:59 -07:00
2016-04-25 13:17:46 -07:00
AzurePublisherTool . PublishInstallerFile ( installerFile , Channel , version ) ;
2016-03-23 16:37:59 -07:00
return c . Success ( ) ;
}
2016-03-07 12:20:50 -08:00
[Target]
2016-03-22 18:31:16 -07:00
[BuildPlatforms(BuildPlatform.Windows, BuildPlatform.OSX)]
2016-03-23 16:37:59 -07:00
public static BuildTargetResult PublishCombinedFrameworkSDKHostInstallerFileToAzure ( BuildTargetContext c )
2016-03-07 12:20:50 -08:00
{
2016-03-23 16:37:59 -07:00
var version = CliNuGetVersion ;
2016-03-16 18:16:51 -07:00
var installerFile = c . BuildContext . Get < string > ( "CombinedFrameworkSDKHostInstallerFile" ) ;
2016-03-07 12:20:50 -08:00
2016-04-25 13:17:46 -07:00
AzurePublisherTool . PublishInstallerFile ( installerFile , Channel , version ) ;
2016-03-23 16:37:59 -07:00
return c . Success ( ) ;
}
2016-04-24 13:01:52 -07:00
[Target]
2016-04-26 14:33:40 -07:00
[BuildPlatforms(BuildPlatform.Windows)]
2016-04-24 13:01:52 -07:00
public static BuildTargetResult PublishCombinedFrameworkSDKArchiveToAzure ( BuildTargetContext c )
{
var version = CliNuGetVersion ;
var archiveFile = c . BuildContext . Get < string > ( "CombinedFrameworkSDKCompressedFile" ) ;
2016-04-25 13:17:46 -07:00
AzurePublisherTool . PublishArchive ( archiveFile , Channel , version ) ;
2016-04-24 13:01:52 -07:00
return c . Success ( ) ;
}
2016-03-23 16:37:59 -07:00
[Target]
public static BuildTargetResult PublishCombinedHostFrameworkSdkArchiveToAzure ( BuildTargetContext c )
{
var version = CliNuGetVersion ;
var archiveFile = c . BuildContext . Get < string > ( "CombinedFrameworkSDKHostCompressedFile" ) ;
2016-04-25 13:17:46 -07:00
AzurePublisherTool . PublishArchive ( archiveFile , Channel , version ) ;
2016-03-23 16:37:59 -07:00
2016-03-07 12:20:50 -08:00
return c . Success ( ) ;
}
2016-04-04 20:13:13 -07:00
[Target]
public static BuildTargetResult PublishSDKSymbolsArchiveToAzure ( BuildTargetContext c )
{
var version = CliNuGetVersion ;
var archiveFile = c . BuildContext . Get < string > ( "SdkSymbolsCompressedFile" ) ;
2016-04-25 13:17:46 -07:00
AzurePublisherTool . PublishArchive ( archiveFile , Channel , version ) ;
2016-04-04 20:13:13 -07:00
return c . Success ( ) ;
}
2016-03-22 14:14:54 -07:00
[Target]
2016-05-29 22:38:45 -07:00
[BuildPlatforms(BuildPlatform.Ubuntu, "14.04")]
2016-03-22 14:14:54 -07:00
public static BuildTargetResult PublishSdkDebToDebianRepo ( BuildTargetContext c )
{
2016-03-23 16:37:59 -07:00
var version = CliNuGetVersion ;
2016-03-22 14:14:54 -07:00
var packageName = Monikers . GetSdkDebianPackageName ( c ) ;
2016-03-08 13:39:41 -08:00
var installerFile = c . BuildContext . Get < string > ( "SdkInstallerFile" ) ;
2016-03-23 16:37:59 -07:00
var uploadUrl = AzurePublisherTool . CalculateInstallerUploadUrl ( installerFile , Channel , version ) ;
2016-03-08 23:33:18 +00:00
2016-03-23 16:37:59 -07:00
DebRepoPublisherTool . PublishDebFileToDebianRepo (
2016-04-06 15:28:12 -07:00
packageName ,
version ,
2016-03-23 16:37:59 -07:00
uploadUrl ) ;
2016-03-08 23:33:18 +00:00
return c . Success ( ) ;
}
2016-03-16 14:39:02 -07:00
[Target]
[Environment("DOCKER_HUB_REPO")]
[Environment("DOCKER_HUB_TRIGGER_TOKEN")]
public static BuildTargetResult TriggerDockerHubBuilds ( BuildTargetContext c )
{
string dockerHubRepo = Environment . GetEnvironmentVariable ( "DOCKER_HUB_REPO" ) ;
string dockerHubTriggerToken = Environment . GetEnvironmentVariable ( "DOCKER_HUB_TRIGGER_TOKEN" ) ;
Uri baseDockerHubUri = new Uri ( "https://registry.hub.docker.com/u/" ) ;
Uri dockerHubTriggerUri ;
if ( ! Uri . TryCreate ( baseDockerHubUri , $"{dockerHubRepo}/trigger/{dockerHubTriggerToken}/" , out dockerHubTriggerUri ) )
{
return c . Failed ( "Invalid DOCKER_HUB_REPO and/or DOCKER_HUB_TRIGGER_TOKEN" ) ;
}
c . Info ( $"Triggering automated DockerHub builds for {dockerHubRepo}" ) ;
using ( HttpClient client = new HttpClient ( ) )
{
StringContent requestContent = new StringContent ( "{\"build\": true}" , Encoding . UTF8 , "application/json" ) ;
try
{
HttpResponseMessage response = client . PostAsync ( dockerHubTriggerUri , requestContent ) . Result ;
if ( ! response . IsSuccessStatusCode )
{
StringBuilder sb = new StringBuilder ( ) ;
sb . AppendLine ( $"HTTP request to {dockerHubTriggerUri.ToString()} was unsuccessful." ) ;
sb . AppendLine ( $"Response status code: {response.StatusCode}. Reason phrase: {response.ReasonPhrase}." ) ;
sb . Append ( $"Respone content: {response.Content.ReadAsStringAsync().Result}" ) ;
return c . Failed ( sb . ToString ( ) ) ;
}
}
catch ( AggregateException e )
{
return c . Failed ( $"HTTP request to {dockerHubTriggerUri.ToString()} failed. {e.ToString()}" ) ;
}
}
return c . Success ( ) ;
}
2016-04-07 17:25:37 -07:00
2016-05-17 18:16:48 -05:00
[Target(nameof(PrepareTargets.Init))]
public static BuildTargetResult UpdateVersionsRepo ( BuildTargetContext c )
{
2016-05-18 14:14:50 -05:00
string githubAuthToken = EnvVars . EnsureVariable ( "GITHUB_PASSWORD" ) ;
string nupkgFilePath = EnvVars . EnsureVariable ( "NUPKG_FILE_PATH" ) ;
string versionsRepoPath = EnvVars . EnsureVariable ( "VERSIONS_REPO_PATH" ) ;
2016-05-17 18:16:48 -05:00
2016-05-18 14:14:50 -05:00
VersionRepoUpdater repoUpdater = new VersionRepoUpdater ( githubAuthToken ) ;
2016-05-17 18:16:48 -05:00
repoUpdater . UpdatePublishedVersions ( nupkgFilePath , versionsRepoPath ) . Wait ( ) ;
return c . Success ( ) ;
}
2016-02-12 10:11:30 -08:00
}
}
2016-05-11 17:20:40 -07:00