diff --git a/packaging/debian/dotnet-debian_config.json b/packaging/debian/dotnet-debian_config.json index 550508f8c..a3c4873a2 100644 --- a/packaging/debian/dotnet-debian_config.json +++ b/packaging/debian/dotnet-debian_config.json @@ -28,7 +28,7 @@ }, "debian_dependencies":{ - "libssl-dev" : {}, + "libssl1.0.0" : {}, "clang-3.5" : {}, "libcurl3" : {} }, diff --git a/packaging/debian/dotnet-nightly-debian_config.json b/packaging/debian/dotnet-nightly-debian_config.json index 49652c929..cc7d7e9ab 100644 --- a/packaging/debian/dotnet-nightly-debian_config.json +++ b/packaging/debian/dotnet-nightly-debian_config.json @@ -28,7 +28,7 @@ }, "debian_dependencies":{ - "libssl-dev" : {}, + "libssl1.0.0" : {}, "clang-3.5" : {}, "libcurl3" : {} }, diff --git a/packaging/nuget/package.ps1 b/packaging/nuget/package.ps1 index 14b3b3385..b08fd21f3 100644 --- a/packaging/nuget/package.ps1 +++ b/packaging/nuget/package.ps1 @@ -13,8 +13,10 @@ if ($versionSuffix -ne "") { $versionArg = "--version-suffix" } -. "$PSScriptRoot\..\..\scripts\common\_common.ps1" -. "$REPOROOT\scripts\package\projectsToPack.ps1" +$RepoRoot = Convert-Path "$PSScriptRoot\..\.." + +. "$RepoRoot\scripts\common\_common.ps1" +. "$RepoRoot\scripts\package\projectsToPack.ps1" $IntermediatePackagesDir = "$RepoRoot\artifacts\packages\intermediate" $PackagesDir = "$RepoRoot\artifacts\packages" diff --git a/packaging/osx/package-osx.sh b/packaging/osx/package-osx.sh index e2a6a4ede..819a7e1f6 100755 --- a/packaging/osx/package-osx.sh +++ b/packaging/osx/package-osx.sh @@ -12,26 +12,65 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" -source "$DIR/../../scripts/common/_common.sh" +help(){ + echo "Usage: $0 [--version ] [--input ] [--output ] [--help]" + echo "" + echo "Options:" + echo " --version Specify a version for the package. Version format is 4 '.' separated numbers - ..." + echo " --input Package the entire contents of the directory tree." + echo " --output The path to where the package will be written." + exit 1 +} + +while [[ $# > 0 ]]; do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + -v|--version) + DOTNET_CLI_VERSION=$2 + shift + ;; + -o|--output) + OUTPUT_PKG=$2 + shift + ;; + -i|--input) + INPUT_DIR=$2 + shift + ;; + --help) + help + ;; + *) + break + ;; + esac + shift +done if [ -z "$DOTNET_CLI_VERSION" ]; then - echo "Provide a version number (DOTNET_CLI_VERSION) $DOTNET_CLI_VERSION" && exit 1 + echo "Provide a version number. Missing option '--version'" && help fi -STAGE2_DIR=$REPOROOT/artifacts/$RID/stage2 +if [ -z "$OUTPUT_PKG" ]; then + echo "Provide an output pkg. Missing option '--output'" && help +fi -if [ ! -d "$STAGE2_DIR" ]; then - echo "Missing stage2 output in $STAGE2_DIR" 1>&2 +if [ -z "$INPUT_DIR" ]; then + echo "Provide an input directory. Missing option '--input'" && help +fi + +if [ ! -d "$INPUT_DIR" ]; then + echo "'$INPUT_DIR' - is either missing or not a directory" 1>&2 exit 1 fi -PACKAGE_DIR=$REPOROOT/artifacts/packages/pkg +PACKAGE_DIR=$(dirname "${OUTPUT_PKG}") [ -d "$PACKAGE_DIR" ] || mkdir -p $PACKAGE_DIR -PACKAGE_ID=dotnet-osx-x64.${DOTNET_CLI_VERSION}.pkg -PACKAGE_NAME=$PACKAGE_DIR/$PACKAGE_ID -#chmod -R 755 $STAGE2_DIR -pkgbuild --root $STAGE2_DIR \ +PACKAGE_ID=$(basename "${OUTPUT_PKG}") + +#chmod -R 755 $INPUT_DIR +pkgbuild --root $INPUT_DIR \ --version $DOTNET_CLI_VERSION \ --scripts $DIR/scripts \ --identifier com.microsoft.dotnet.cli.pkg.dotnet-osx-x64 \ @@ -40,10 +79,8 @@ pkgbuild --root $STAGE2_DIR \ cat $DIR/Distribution-Template | sed "/{VERSION}/s//$DOTNET_CLI_VERSION/g" > $DIR/Dist -productbuild --version $DOTNET_CLI_VERSION --identifier com.microsoft.dotnet.cli --package-path $DIR --resources $DIR/resources --distribution $DIR/Dist $PACKAGE_NAME +productbuild --version $DOTNET_CLI_VERSION --identifier com.microsoft.dotnet.cli --package-path $DIR --resources $DIR/resources --distribution $DIR/Dist $OUTPUT_PKG #Clean temp files rm $DIR/$PACKAGE_ID rm $DIR/Dist - -$REPOROOT/scripts/publish/publish.sh $PACKAGE_NAME diff --git a/packaging/windows/generatebundle.ps1 b/packaging/windows/generatebundle.ps1 new file mode 100644 index 000000000..e50300363 --- /dev/null +++ b/packaging/windows/generatebundle.ps1 @@ -0,0 +1,108 @@ +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. + +param( + [Parameter(Mandatory=$true)][string]$DotnetMSIFile, + [Parameter(Mandatory=$true)][string]$DotnetBundleOutput, + [Parameter(Mandatory=$true)][string]$WixRoot, + [Parameter(Mandatory=$true)][string]$DotnetMSIVersion, + [Parameter(Mandatory=$true)][string]$DotnetCLIVersion, + [Parameter(Mandatory=$true)][string]$Architecture, + [Parameter(Mandatory=$true)][string]$ReleaseSuffix +) + +. "$PSScriptRoot\..\..\scripts\common\_common.ps1" +$RepoRoot = Convert-Path "$PSScriptRoot\..\.." + +function RunCandleForBundle +{ + $result = $true + pushd "$WixRoot" + + Write-Host Running candle for bundle.. + $AuthWsxRoot = Join-Path $RepoRoot "packaging\windows" + + .\candle.exe -nologo ` + -dDotnetSrc="$inputDir" ` + -dMicrosoftEula="$RepoRoot\packaging\osx\resources\en.lproj\eula.rtf" ` + -dBuildVersion="$DotnetMSIVersion" ` + -dDisplayVersion="$DotnetCLIVersion" ` + -dReleaseSuffix="$ReleaseSuffix" ` + -dMsiSourcePath="$DotnetMSIFile" ` + -arch "$Architecture" ` + -ext WixBalExtension.dll ` + -ext WixUtilExtension.dll ` + -ext WixTagExtension.dll ` + "$AuthWsxRoot\bundle.wxs" | Out-Host + + if($LastExitCode -ne 0) + { + $result = $false + Write-Host "Candle failed with exit code $LastExitCode." + } + + popd + return $result +} + +function RunLightForBundle +{ + $result = $true + pushd "$WixRoot" + + Write-Host Running light for bundle.. + $AuthWsxRoot = Join-Path $RepoRoot "packaging\windows" + + .\light.exe -nologo ` + -cultures:en-us ` + bundle.wixobj ` + -ext WixBalExtension.dll ` + -ext WixUtilExtension.dll ` + -ext WixTagExtension.dll ` + -b "$AuthWsxRoot" ` + -out $DotnetBundleOutput | Out-Host + + if($LastExitCode -ne 0) + { + $result = $false + Write-Host "Light failed with exit code $LastExitCode." + } + + popd + return $result +} + + +if(!(Test-Path $DotnetMSIFile)) +{ + throw "$DotnetMSIFile not found" +} + +Write-Host "Creating dotnet Bundle at $DotnetBundleOutput" + +if([string]::IsNullOrEmpty($WixRoot)) +{ + Exit -1 +} + +if(-Not (RunCandleForBundle)) +{ + Exit -1 +} + +if(-Not (RunLightForBundle)) +{ + Exit -1 +} + +if(!(Test-Path $DotnetBundleOutput)) +{ + throw "Unable to create the dotnet bundle." + Exit -1 +} + +Write-Host -ForegroundColor Green "Successfully created dotnet bundle - $DotnetBundleOutput" + +_ $RepoRoot\test\Installer\testmsi.ps1 @("$DotnetMSIFile") + +exit $LastExitCode diff --git a/packaging/windows/generatemsi.ps1 b/packaging/windows/generatemsi.ps1 index fa6671e9f..54a6a9388 100644 --- a/packaging/windows/generatemsi.ps1 +++ b/packaging/windows/generatemsi.ps1 @@ -2,42 +2,21 @@ # Licensed under the MIT license. See LICENSE file in the project root for full license information. param( - [Parameter(Mandatory=$true)][string]$inputDir + [Parameter(Mandatory=$true)][string]$inputDir, + [Parameter(Mandatory=$true)][string]$DotnetMSIOutput, + [Parameter(Mandatory=$true)][string]$WixRoot, + [Parameter(Mandatory=$true)][string]$DotnetMSIVersion, + [Parameter(Mandatory=$true)][string]$DotnetCLIVersion, + [Parameter(Mandatory=$true)][string]$Architecture, + [Parameter(Mandatory=$true)][string]$ReleaseSuffix ) . "$PSScriptRoot\..\..\scripts\common\_common.ps1" +$RepoRoot = Convert-Path "$PSScriptRoot\..\.." -$DotnetMSIOutput = "" -$DotnetBundleOutput = "" -$WixRoot = "" $InstallFileswsx = "install-files.wxs" $InstallFilesWixobj = "install-files.wixobj" -function AcquireWixTools -{ - $result = Join-Path $OutputDir WiXTools - - if(Test-Path "$result\candle.exe") - { - return $result - } - - Write-Host Downloading Wixtools.. - New-Item $result -type directory -force | Out-Null - # Download Wix version 3.10.2 - https://wix.codeplex.com/releases/view/619491 - Invoke-WebRequest -Uri https://wix.codeplex.com/downloads/get/1540241 -Method Get -OutFile $result\WixTools.zip - - Write-Host Extracting Wixtools.. - [System.IO.Compression.ZipFile]::ExtractToDirectory("$result\WixTools.zip", $result) - - if($LastExitCode -ne 0) - { - throw "Unable to download and extract the WixTools." - } - - return $result -} - function RunHeat { $result = $true @@ -68,10 +47,10 @@ function RunCandle .\candle.exe -nologo ` -dDotnetSrc="$inputDir" ` -dMicrosoftEula="$RepoRoot\packaging\osx\resources\en.lproj\eula.rtf" ` - -dBuildVersion="$env:DOTNET_MSI_VERSION" ` - -dDisplayVersion="$env:DOTNET_CLI_VERSION" ` - -dReleaseSuffix="$env:ReleaseSuffix" ` - -arch "$env:ARCHITECTURE" ` + -dBuildVersion="$DotnetMSIVersion" ` + -dDisplayVersion="$DotnetCLIVersion" ` + -dReleaseSuffix="$ReleaseSuffix" ` + -arch "$Architecture" ` -ext WixDependencyExtension.dll ` "$AuthWsxRoot\dotnet.wxs" ` "$AuthWsxRoot\provider.wxs" ` @@ -121,83 +100,12 @@ function RunLight return $result } -function RunCandleForBundle -{ - $result = $true - pushd "$WixRoot" - - Write-Host Running candle for bundle.. - $AuthWsxRoot = Join-Path $RepoRoot "packaging\windows" - - .\candle.exe -nologo ` - -dDotnetSrc="$inputDir" ` - -dMicrosoftEula="$RepoRoot\packaging\osx\resources\en.lproj\eula.rtf" ` - -dBuildVersion="$env:DOTNET_MSI_VERSION" ` - -dDisplayVersion="$env:DOTNET_CLI_VERSION" ` - -dReleaseSuffix="$env:ReleaseSuffix" ` - -dMsiSourcePath="$DotnetMSIOutput" ` - -arch "$env:ARCHITECTURE" ` - -ext WixBalExtension.dll ` - -ext WixUtilExtension.dll ` - -ext WixTagExtension.dll ` - "$AuthWsxRoot\bundle.wxs" | Out-Host - - if($LastExitCode -ne 0) - { - $result = $false - Write-Host "Candle failed with exit code $LastExitCode." - } - - popd - return $result -} - -function RunLightForBundle -{ - $result = $true - pushd "$WixRoot" - - Write-Host Running light for bundle.. - $AuthWsxRoot = Join-Path $RepoRoot "packaging\windows" - - .\light.exe -nologo ` - -cultures:en-us ` - bundle.wixobj ` - -ext WixBalExtension.dll ` - -ext WixUtilExtension.dll ` - -ext WixTagExtension.dll ` - -b "$AuthWsxRoot" ` - -out $DotnetBundleOutput | Out-Host - - if($LastExitCode -ne 0) - { - $result = $false - Write-Host "Light failed with exit code $LastExitCode." - } - - popd - return $result -} - - if(!(Test-Path $inputDir)) { throw "$inputDir not found" } -if(!(Test-Path $PackageDir)) -{ - mkdir $PackageDir | Out-Null -} - -$DotnetMSIOutput = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$env:DOTNET_CLI_VERSION.msi" -$DotnetBundleOutput = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$env:DOTNET_CLI_VERSION.exe" - Write-Host "Creating dotnet MSI at $DotnetMSIOutput" -Write-Host "Creating dotnet Bundle at $DotnetBundleOutput" - -$WixRoot = AcquireWixTools - if([string]::IsNullOrEmpty($WixRoot)) { @@ -214,39 +122,17 @@ if(-Not (RunCandle)) Exit -1 } -if(-Not (RunCandleForBundle)) -{ - Exit -1 -} - if(-Not (RunLight)) { Exit -1 } -if(-Not (RunLightForBundle)) -{ - Exit -1 -} - if(!(Test-Path $DotnetMSIOutput)) { throw "Unable to create the dotnet msi." Exit -1 } -if(!(Test-Path $DotnetBundleOutput)) -{ - throw "Unable to create the dotnet bundle." - Exit -1 -} - Write-Host -ForegroundColor Green "Successfully created dotnet MSI - $DotnetMSIOutput" -Write-Host -ForegroundColor Green "Successfully created dotnet bundle - $DotnetBundleOutput" - -_ $RepoRoot\test\Installer\testmsi.ps1 @("$DotnetMSIOutput") - -$PublishScript = Join-Path $PSScriptRoot "..\..\scripts\publish\publish.ps1" -& $PublishScript -file $DotnetBundleOutput exit $LastExitCode diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs index 7fd8752ae..c860436e7 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/CurrentPlatform.cs @@ -57,6 +57,45 @@ namespace Microsoft.DotNet.Cli.Build.Framework } } + public static bool IsUnix + { + get + { + return IsLinux || IsOSX; + } + } + + public static bool IsLinux + { + get + { + return IsUbuntu || IsCentOS || IsRHEL; + } + } + + public static bool IsPlatform(BuildPlatform platform) + { + switch (platform) + { + case BuildPlatform.Windows: + return IsWindows; + case BuildPlatform.Ubuntu: + return IsUbuntu; + case BuildPlatform.OSX: + return IsOSX; + case BuildPlatform.CentOS: + return IsCentOS; + case BuildPlatform.RHEL: + return IsRHEL; + case BuildPlatform.Unix: + return IsUnix; + case BuildPlatform.Linux: + return IsLinux; + default: + throw new Exception("Unrecognized Platform."); + } + } + private static BuildPlatform DetermineCurrentPlatform() { if (IsWindows) diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/Enumerations/BuildPlatform.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/Enumerations/BuildPlatform.cs index 715795196..adb2c83d6 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/Enumerations/BuildPlatform.cs +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/Enumerations/BuildPlatform.cs @@ -3,9 +3,11 @@ namespace Microsoft.DotNet.Cli.Build.Framework public enum BuildPlatform { Windows = 1, - OSX = 2, - Ubuntu = 3, - CentOS = 4, - RHEL = 5 + Unix = 2, + Linux = 3, + OSX = 4, + Ubuntu = 5, + CentOS = 6, + RHEL = 7 } } diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs index c22ac967a..975f1fa6f 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs @@ -11,10 +11,11 @@ namespace Microsoft.DotNet.Cli.Build.Framework { return self.UseTargets(new[] { - new BuildTarget("Default", "Standard Goals", new [] { "Prepare", "Compile", "Test", "Publish" }), + new BuildTarget("Default", "Standard Goals", new [] { "Prepare", "Compile", "Test", "Package", "Publish" }), new BuildTarget("Prepare", "Standard Goals"), new BuildTarget("Compile", "Standard Goals"), new BuildTarget("Test", "Standard Goals"), + new BuildTarget("Package", "Standard Goals"), new BuildTarget("Publish", "Standard Goals") }); } diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/BuildPlatformsAttribute.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/BuildPlatformsAttribute.cs index d05655a67..92e8f2441 100644 --- a/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/BuildPlatformsAttribute.cs +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/BuildPlatformsAttribute.cs @@ -20,16 +20,9 @@ namespace Microsoft.DotNet.Cli.Build.Framework public override bool EvaluateCondition() { - var currentPlatform = CurrentPlatform.Current; - - if (currentPlatform == default(BuildPlatform)) - { - throw new Exception("Unrecognized Platform."); - } - foreach (var platform in _buildPlatforms) { - if (platform == currentPlatform) + if (CurrentPlatform.IsPlatform(platform)) { return true; } diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/EnvironmentAttribute.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/EnvironmentAttribute.cs new file mode 100644 index 000000000..2a9aea581 --- /dev/null +++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetConditions/EnvironmentAttribute.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.DotNet.Cli.Build.Framework +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class EnvironmentAttribute : TargetConditionAttribute + { + private string _envVar; + private string[] _expectedVals; + + public EnvironmentAttribute(string envVar, params string[] expectedVals) + { + if (string.IsNullOrEmpty(envVar)) + { + throw new ArgumentNullException("envVar"); + } + + _envVar = envVar; + _expectedVals = expectedVals; + } + + public override bool EvaluateCondition() + { + var actualVal = Environment.GetEnvironmentVariable(_envVar); + + foreach (var expectedVal in _expectedVals) + { + if (string.Equals(actualVal, expectedVal, StringComparison.Ordinal)) + { + return true; + } + } + + return false; + } + } +} diff --git a/scripts/docker/centos/Dockerfile b/scripts/docker/centos/Dockerfile index c44a40a41..70aae5bde 100644 --- a/scripts/docker/centos/Dockerfile +++ b/scripts/docker/centos/Dockerfile @@ -24,12 +24,6 @@ RUN yum -q -y install tar git cmake clang make RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100 RUN update-alternatives --set c++ /usr/bin/clang++ -# Install azure cli. We need this to publish artifacts. -RUN yum -y install nodejs && \ - yum -y install npm && \ - npm install -g azure-cli - - RUN yum -q -y install sudo # Setup User to match Host User, and give superuser permissions diff --git a/scripts/docker/ubuntu/Dockerfile b/scripts/docker/ubuntu/Dockerfile index 852a81720..c57e4e4ca 100644 --- a/scripts/docker/ubuntu/Dockerfile +++ b/scripts/docker/ubuntu/Dockerfile @@ -55,6 +55,7 @@ RUN echo "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | tee libsasl2-2 \ libsqlite3-0 \ libssl1.0.0 \ + libssl-dev \ libtasn1-6 \ libwind0-heimdal @@ -69,11 +70,6 @@ RUN apt-get -qq install -y debhelper build-essential devscripts git cmake RUN update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-3.5 100 RUN update-alternatives --set c++ /usr/bin/clang++-3.5 -# Install azure cli. We need this to publish artifacts. -RUN apt-get -qqy install nodejs-legacy && \ - apt-get -qqy install npm && \ - npm install -g azure-cli - # Setup User to match Host User, and give superuser permissions ARG USER_ID=0 RUN useradd -m code_executor -u ${USER_ID} -g sudo diff --git a/scripts/dotnet-cli-build/InstallerTargets.cs b/scripts/dotnet-cli-build/InstallerTargets.cs new file mode 100644 index 000000000..be1a4836a --- /dev/null +++ b/scripts/dotnet-cli-build/InstallerTargets.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.Extensions.PlatformAbstractions; + +using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers; + +namespace Microsoft.DotNet.Cli.Build +{ + public class InstallerTargets + { + [Target(nameof(MsiTargets.GenerateMsis), + nameof(MsiTargets.GenerateBundle), + nameof(InstallerTargets.GeneratePkg), + nameof(InstallerTargets.GenerateDeb))] + public static BuildTargetResult GenerateInstaller(BuildTargetContext c) + { + return c.Success(); + } + + + + [Target] + [BuildPlatforms(BuildPlatform.OSX)] + public static BuildTargetResult GeneratePkg(BuildTargetContext c) + { + var version = c.BuildContext.Get("BuildVersion").SimpleVersion; + var pkg = c.BuildContext.Get("InstallerFile"); + Cmd(Path.Combine(Dirs.RepoRoot, "packaging", "osx", "package-osx.sh"), + "-v", version, "-i", Dirs.Stage2, "-o", pkg) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Ubuntu)] + public static BuildTargetResult GenerateDeb(BuildTargetContext c) + { + var channel = c.BuildContext.Get("Channel").ToLower(); + var packageName = Monikers.GetDebianPackageName(c); + var version = c.BuildContext.Get("BuildVersion").SimpleVersion; + var debFile = c.BuildContext.Get("InstallerFile"); + var manPagesDir = Path.Combine(Dirs.RepoRoot, "Documentation", "manpages"); + var previousVersionURL = $"https://dotnetcli.blob.core.windows.net/dotnet/{channel}/Installers/Latest/dotnet-ubuntu-x64.latest.deb"; + + Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "package", "package-debian.sh"), + "-v", version, "-i", Dirs.Stage2, "-o", debFile, "-p", packageName, "-m", manPagesDir, "--previous-version-url", previousVersionURL) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + } +} diff --git a/scripts/dotnet-cli-build/MsiTargets.cs b/scripts/dotnet-cli-build/MsiTargets.cs new file mode 100644 index 000000000..6d83a8794 --- /dev/null +++ b/scripts/dotnet-cli-build/MsiTargets.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.Extensions.PlatformAbstractions; + +using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers; + +namespace Microsoft.DotNet.Cli.Build +{ + public class MsiTargets + { + private const string ENGINE = "engine.exe"; + + private static string WixRoot + { + get + { + return Path.Combine(Dirs.Output, "WixTools"); + } + } + + private static string Msi { get; set; } + + private static string Bundle { get; set; } + + private static string Engine { get; set; } + + private static string MsiVersion { get; set; } + + private static string CliVersion { get; set; } + + private static string Arch { get; } = CurrentArchitecture.Current.ToString(); + + private static string Channel { get; set; } + + private static void AcquireWix(BuildTargetContext c) + { + if (File.Exists(Path.Combine(WixRoot, "candle.exe"))) + { + return; + } + + Directory.CreateDirectory(WixRoot); + + c.Info("Downloading WixTools.."); + // Download Wix version 3.10.2 - https://wix.codeplex.com/releases/view/619491 + Cmd("powershell", "-NoProfile", "-NoLogo", + $"Invoke-WebRequest -Uri https://wix.codeplex.com/downloads/get/1540241 -Method Get -OutFile {WixRoot}\\WixTools.zip") + .Execute() + .EnsureSuccessful(); + + c.Info("Extracting WixTools.."); + ZipFile.ExtractToDirectory($"{WixRoot}\\WixTools.zip", WixRoot); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult InitMsi(BuildTargetContext c) + { + Bundle = c.BuildContext.Get("InstallerFile"); + Msi = Path.ChangeExtension(Bundle, "msi"); + Engine = Path.Combine(Path.GetDirectoryName(Bundle), ENGINE); + + var buildVersion = c.BuildContext.Get("BuildVersion"); + MsiVersion = buildVersion.GenerateMsiVersion(); + CliVersion = buildVersion.SimpleVersion; + Channel = c.BuildContext.Get("Channel"); + + AcquireWix(c); + return c.Success(); + } + + [Target(nameof(MsiTargets.InitMsi), + nameof(GenerateDotnetMuxerMsi), + nameof(GenerateDotnetSharedFxMsi), + nameof(GenerateCLISDKMsi))] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateMsis(BuildTargetContext c) + { + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateCLISDKMsi(BuildTargetContext c) + { + Cmd("powershell", "-NoProfile", "-NoLogo", + Path.Combine(Dirs.RepoRoot, "packaging", "windows", "generatemsi.ps1"), + Dirs.Stage2, Msi, WixRoot, MsiVersion, CliVersion, Arch, Channel) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateDotnetMuxerMsi(BuildTargetContext c) + { + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateDotnetSharedFxMsi(BuildTargetContext c) + { + return c.Success(); + } + + + [Target(nameof(MsiTargets.InitMsi))] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateBundle(BuildTargetContext c) + { + Cmd("powershell", "-NoProfile", "-NoLogo", + Path.Combine(Dirs.RepoRoot, "packaging", "windows", "generatebundle.ps1"), + Msi, Bundle, WixRoot, MsiVersion, CliVersion, Arch, Channel) + .EnvironmentVariable("Stage2Dir", Dirs.Stage2) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + [Target(nameof(MsiTargets.InitMsi))] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult ExtractEngineFromBundle(BuildTargetContext c) + { + Cmd($"{WixRoot}\\insignia.exe", "-ib", Bundle, "-o", Engine) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + [Target(nameof(MsiTargets.InitMsi))] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult ReattachEngineToBundle(BuildTargetContext c) + { + Cmd($"{WixRoot}\\insignia.exe", "-ab", Engine, Bundle, "-o", Bundle) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + } +} diff --git a/scripts/dotnet-cli-build/PackageTargets.cs b/scripts/dotnet-cli-build/PackageTargets.cs new file mode 100644 index 000000000..c43b201e1 --- /dev/null +++ b/scripts/dotnet-cli-build/PackageTargets.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.Extensions.PlatformAbstractions; + +using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers; + +namespace Microsoft.DotNet.Cli.Build +{ + public static class PackageTargets + { + [Target] + public static BuildTargetResult InitPackage(BuildTargetContext c) + { + Directory.CreateDirectory(Dirs.Packages); + return c.Success(); + } + + [Target(nameof(PrepareTargets.Init), + nameof(PackageTargets.InitPackage), + nameof(PackageTargets.GenerateVersionBadge), + nameof(PackageTargets.GenerateCompressedFile), + nameof(InstallerTargets.GenerateInstaller), + nameof(PackageTargets.GenerateNugetPackages))] + [Environment("DOTNET_BUILD_SKIP_PACKAGING", null, "0", "false")] + public static BuildTargetResult Package(BuildTargetContext c) + { + return c.Success(); + } + + [Target] + public static BuildTargetResult GenerateVersionBadge(BuildTargetContext c) + { + var buildVersion = c.BuildContext.Get("BuildVersion"); + var versionSvg = Path.Combine(Dirs.RepoRoot, "resources", "images", "version_badge.svg"); + var outputVersionSvg = c.BuildContext.Get("VersionBadge"); + + var versionSvgContent = File.ReadAllText(versionSvg); + versionSvgContent = versionSvgContent.Replace("ver_number", buildVersion.SimpleVersion); + File.WriteAllText(outputVersionSvg, versionSvgContent); + + return c.Success(); + } + + [Target(nameof(PackageTargets.GenerateZip), nameof(PackageTargets.GenerateTarBall))] + public static BuildTargetResult GenerateCompressedFile(BuildTargetContext c) + { + return c.Success(); + } + + [Target(nameof(PackageTargets.InitPackage))] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateZip(BuildTargetContext c) + { + var zipFile = c.BuildContext.Get("CompressedFile"); + + if (File.Exists(zipFile)) + { + File.Delete(zipFile); + } + + ZipFile.CreateFromDirectory(Dirs.Stage2, zipFile, CompressionLevel.Optimal, false); + return c.Success(); + } + + [Target(nameof(PackageTargets.InitPackage))] + [BuildPlatforms(BuildPlatform.Unix)] + public static BuildTargetResult GenerateTarBall(BuildTargetContext c) + { + var tarFile = c.BuildContext.Get("CompressedFile"); + + if (File.Exists(tarFile)) + { + File.Delete(tarFile); + } + + Cmd("tar", "-czf", tarFile, "-C", Dirs.Stage2, ".") + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows)] + public static BuildTargetResult GenerateNugetPackages(BuildTargetContext c) + { + var versionSuffix = c.BuildContext.Get("BuildVersion").VersionSuffix; + var env = GetCommonEnvVars(c); + Cmd("powershell", "-NoProfile", "-NoLogo", + Path.Combine(Dirs.RepoRoot, "packaging", "nuget", "package.ps1"), Path.Combine(Dirs.Stage2, "bin"), versionSuffix) + .Environment(env) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + internal static Dictionary GetCommonEnvVars(BuildTargetContext c) + { + // Set up the environment variables previously defined by common.sh/ps1 + // This is overkill, but I want to cover all the variables used in all OSes (including where some have the same names) + var buildVersion = c.BuildContext.Get("BuildVersion"); + var configuration = c.BuildContext.Get("Configuration"); + var architecture = PlatformServices.Default.Runtime.RuntimeArchitecture; + var env = new Dictionary() + { + { "RID", PlatformServices.Default.Runtime.GetRuntimeIdentifier() }, + { "OSNAME", PlatformServices.Default.Runtime.OperatingSystem }, + { "TFM", "dnxcore50" }, + { "REPOROOT", Dirs.RepoRoot }, + { "OutputDir", Dirs.Output }, + { "Stage1Dir", Dirs.Stage1 }, + { "Stage1CompilationDir", Dirs.Stage1Compilation }, + { "Stage2Dir", Dirs.Stage2 }, + { "STAGE2_DIR", Dirs.Stage2 }, + { "Stage2CompilationDir", Dirs.Stage2Compilation }, + { "HostDir", Dirs.Corehost }, + { "PackageDir", Path.Combine(Dirs.Packages) }, // Legacy name + { "TestBinRoot", Dirs.TestOutput }, + { "TestPackageDir", Dirs.TestPackages }, + { "MajorVersion", buildVersion.Major.ToString() }, + { "MinorVersion", buildVersion.Minor.ToString() }, + { "PatchVersion", buildVersion.Patch.ToString() }, + { "CommitCountVersion", buildVersion.CommitCountString }, + { "COMMIT_COUNT_VERSION", buildVersion.CommitCountString }, + { "DOTNET_CLI_VERSION", buildVersion.SimpleVersion }, + { "DOTNET_MSI_VERSION", buildVersion.GenerateMsiVersion() }, + { "VersionSuffix", buildVersion.VersionSuffix }, + { "CONFIGURATION", configuration }, + { "ARCHITECTURE", architecture } + }; + + return env; + } + } +} diff --git a/scripts/dotnet-cli-build/PrepareTargets.cs b/scripts/dotnet-cli-build/PrepareTargets.cs index bc10066e9..9a11d5b7e 100644 --- a/scripts/dotnet-cli-build/PrepareTargets.cs +++ b/scripts/dotnet-cli-build/PrepareTargets.cs @@ -21,17 +21,17 @@ namespace Microsoft.DotNet.Cli.Build [Target(nameof(CheckPrereqCmakePresent), nameof(CheckPlatformDependencies))] public static BuildTargetResult CheckPrereqs(BuildTargetContext c) => c.Success(); - [Target(nameof(CheckCoreclrPlatformDependencies), nameof(CheckInstallerBuildPlatformDependencies))] + [Target(nameof(CheckCoreclrPlatformDependencies), nameof(CheckInstallerBuildPlatformDependencies))] public static BuildTargetResult CheckPlatformDependencies(BuildTargetContext c) => c.Success(); - [Target(nameof(CheckUbuntuCoreclrAndCoreFxDependencies), nameof(CheckCentOSCoreclrAndCoreFxDependencies))] + [Target(nameof(CheckUbuntuCoreclrAndCoreFxDependencies), nameof(CheckCentOSCoreclrAndCoreFxDependencies))] public static BuildTargetResult CheckCoreclrPlatformDependencies(BuildTargetContext c) => c.Success(); [Target(nameof(CheckUbuntuDebianPackageBuildDependencies))] public static BuildTargetResult CheckInstallerBuildPlatformDependencies(BuildTargetContext c) => c.Success(); // All major targets will depend on this in order to ensure variables are set up right if they are run independently - [Target(nameof(GenerateVersions), nameof(CheckPrereqs), nameof(LocateStage0))] + [Target(nameof(GenerateVersions), nameof(CheckPrereqs), nameof(LocateStage0), nameof(ExpectedBuildArtifacts))] public static BuildTargetResult Init(BuildTargetContext c) { var runtimeInfo = PlatformServices.Default.Runtime; @@ -44,6 +44,7 @@ namespace Microsoft.DotNet.Cli.Build } c.BuildContext["Configuration"] = configEnv; + c.BuildContext["Channel"] = Environment.GetEnvironmentVariable("CHANNEL"); c.Info($"Building {c.BuildContext["Configuration"]} to: {Dirs.Output}"); c.Info("Build Environment:"); @@ -104,6 +105,41 @@ namespace Microsoft.DotNet.Cli.Build return c.Success(); } + [Target] + public static BuildTargetResult ExpectedBuildArtifacts(BuildTargetContext c) + { + var productName = Monikers.GetProductMoniker(c); + var config = Environment.GetEnvironmentVariable("CONFIGURATION"); + var versionBadgeName = $"{CurrentPlatform.Current}_{CurrentArchitecture.Current}_{config}_version_badge.svg"; + c.BuildContext["VersionBadge"] = Path.Combine(Dirs.Output, versionBadgeName); + + var extension = CurrentPlatform.IsWindows ? ".zip" : ".tar.gz"; + c.BuildContext["CompressedFile"] = Path.Combine(Dirs.Packages, productName + extension); + + string installer = ""; + switch (CurrentPlatform.Current) + { + case BuildPlatform.Windows: + installer = productName + ".exe"; + break; + case BuildPlatform.OSX: + installer = productName + ".pkg"; + break; + case BuildPlatform.Ubuntu: + installer = productName + ".deb"; + break; + default: + break; + } + + if (!string.IsNullOrEmpty(installer)) + { + c.BuildContext["InstallerFile"] = Path.Combine(Dirs.Packages, installer); + } + + return c.Success(); + } + [Target] public static BuildTargetResult CheckPackageCache(BuildTargetContext c) { @@ -244,7 +280,7 @@ namespace Microsoft.DotNet.Cli.Build public static BuildTargetResult CheckCentOSCoreclrAndCoreFxDependencies(BuildTargetContext c) { var errorMessageBuilder = new StringBuilder(); - + foreach (var package in PackageDependencies.CentosCoreclrAndCoreFxDependencies) { if (!YumDependencyUtility.PackageIsInstalled(package)) diff --git a/scripts/dotnet-cli-build/PublishTargets.cs b/scripts/dotnet-cli-build/PublishTargets.cs index 2648461b6..6a69fcd89 100644 --- a/scripts/dotnet-cli-build/PublishTargets.cs +++ b/scripts/dotnet-cli-build/PublishTargets.cs @@ -4,6 +4,10 @@ using System.IO; using System.Runtime.InteropServices; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.Extensions.PlatformAbstractions; +using Microsoft.WindowsAzure; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Auth; +using Microsoft.WindowsAzure.Storage.Blob; using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers; @@ -11,71 +15,149 @@ namespace Microsoft.DotNet.Cli.Build { public static class PublishTargets { - [Target(nameof(PrepareTargets.Init))] + private static CloudBlobContainer BlobContainer { get; set; } + + private static string Channel { get; set; } + + private static string Version { get; set; } + + + [Target] + public static BuildTargetResult InitPublish(BuildTargetContext c) + { + CloudStorageAccount storageAccount = CloudStorageAccount.Parse(Environment.GetEnvironmentVariable("CONNECTION_STRING").Trim('"')); + CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); + BlobContainer = blobClient.GetContainerReference("dotnet"); + + Version = c.BuildContext.Get("BuildVersion").SimpleVersion; + Channel = c.BuildContext.Get("Channel"); + return c.Success(); + } + + [Target(nameof(PrepareTargets.Init), + nameof(PublishTargets.InitPublish), + nameof(PublishTargets.PublishArtifacts))] + [Environment("PUBLISH_TO_AZURE_BLOB", "1", "true")] // This is set by CI systems public static BuildTargetResult Publish(BuildTargetContext c) { - if (string.Equals(Environment.GetEnvironmentVariable("DOTNET_BUILD_SKIP_PACKAGING"), "1", StringComparison.Ordinal)) - { - c.Info("Skipping packaging because DOTNET_BUILD_SKIP_PACKAGING is set"); - return c.Success(); - } - - // NOTE(anurse): Currently, this just invokes the remaining build scripts as-is. We should port those to C# as well, but - // I want to get the merged in. - - // Set up the environment variables previously defined by common.sh/ps1 - // This is overkill, but I want to cover all the variables used in all OSes (including where some have the same names) - var buildVersion = c.BuildContext.Get("BuildVersion"); - var configuration = c.BuildContext.Get("Configuration"); - var architecture = PlatformServices.Default.Runtime.RuntimeArchitecture; - var env = new Dictionary() - { - { "RID", PlatformServices.Default.Runtime.GetRuntimeIdentifier() }, - { "OSNAME", PlatformServices.Default.Runtime.OperatingSystem }, - { "TFM", "netstandardapp1.5" }, - { "OutputDir", Dirs.Output }, - { "Stage1Dir", Dirs.Stage1 }, - { "Stage1CompilationDir", Dirs.Stage1Compilation }, - { "Stage2Dir", Dirs.Stage2 }, - { "STAGE2_DIR", Dirs.Stage2 }, - { "Stage2CompilationDir", Dirs.Stage2Compilation }, - { "HostDir", Dirs.Corehost }, - { "PackageDir", Path.Combine(Dirs.Packages, "dnvm") }, // Legacy name - { "TestBinRoot", Dirs.TestOutput }, - { "TestPackageDir", Dirs.TestPackages }, - { "MajorVersion", buildVersion.Major.ToString() }, - { "MinorVersion", buildVersion.Minor.ToString() }, - { "PatchVersion", buildVersion.Patch.ToString() }, - { "CommitCountVersion", buildVersion.CommitCountString }, - { "COMMIT_COUNT_VERSION", buildVersion.CommitCountString }, - { "DOTNET_CLI_VERSION", buildVersion.SimpleVersion }, - { "DOTNET_MSI_VERSION", buildVersion.GenerateMsiVersion() }, - { "VersionSuffix", buildVersion.VersionSuffix }, - { "CONFIGURATION", configuration }, - { "ARCHITECTURE", architecture } - }; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - env["OSNAME"] = "osx"; - } - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Cmd("powershell", "-NoProfile", "-NoLogo", Path.Combine(c.BuildContext.BuildDirectory, "scripts", "package", "package.ps1")) - .Environment(env) - .Execute() - .EnsureSuccessful(); - } - else - { - // Can directly execute scripts on Unix :). Thank you shebangs! - Cmd(Path.Combine(c.BuildContext.BuildDirectory, "scripts", "package", "package.sh")) - .Environment(env) - .Execute() - .EnsureSuccessful(); - } return c.Success(); } + + [Target(nameof(PublishTargets.PublishVersionBadge), + nameof(PublishTargets.PublishCompressedFile), + nameof(PublishTargets.PublishInstallerFile), + nameof(PublishTargets.PublishLatestVersionTextFile))] + public static BuildTargetResult PublishArtifacts(BuildTargetContext c) + { + return c.Success(); + } + + [Target] + public static BuildTargetResult PublishVersionBadge(BuildTargetContext c) + { + var versionBadge = c.BuildContext.Get("VersionBadge"); + var latestVersionBadgeBlob = $"{Channel}/Binaries/Latest/{Path.GetFileName(versionBadge)}"; + var versionBadgeBlob = $"{Channel}/Binaries/{Version}/{Path.GetFileName(versionBadge)}"; + + PublishFileAzure(versionBadgeBlob, versionBadge); + PublishFileAzure(latestVersionBadgeBlob, versionBadge); + return c.Success(); + } + + [Target] + public static BuildTargetResult PublishCompressedFile(BuildTargetContext c) + { + var compressedFile = c.BuildContext.Get("CompressedFile"); + var compressedFileBlob = $"{Channel}/Binaries/{Version}/{Path.GetFileName(compressedFile)}"; + var latestCompressedFile = compressedFile.Replace(Version, "latest"); + var latestCompressedFileBlob = $"{Channel}/Binaries/Latest/{Path.GetFileName(latestCompressedFile)}"; + + PublishFileAzure(compressedFileBlob, compressedFile); + PublishFileAzure(latestCompressedFileBlob, compressedFile); + return c.Success(); + } + + [Target] + [BuildPlatforms(BuildPlatform.Windows, BuildPlatform.OSX, BuildPlatform.Ubuntu)] + public static BuildTargetResult PublishInstallerFile(BuildTargetContext c) + { + var installerFile = c.BuildContext.Get("InstallerFile"); + var installerFileBlob = $"{Channel}/Installers/{Version}/{Path.GetFileName(installerFile)}"; + var latestInstallerFile = installerFile.Replace(Version, "latest"); + var latestInstallerFileBlob = $"{Channel}/Installers/Latest/{Path.GetFileName(latestInstallerFile)}"; + + PublishFileAzure(installerFileBlob, installerFile); + PublishFileAzure(latestInstallerFileBlob, installerFile); + return c.Success(); + } + + [Target] + public static BuildTargetResult PublishLatestVersionTextFile(BuildTargetContext c) + { + var osname = Monikers.GetOSShortName(); + var latestVersionBlob = $"{Channel}/dnvm/latest.{osname}.{CurrentArchitecture.Current}.version"; + var latestVersionFile = Path.Combine(Dirs.Stage2, ".version"); + + PublishFileAzure(latestVersionBlob, latestVersionFile); + return c.Success(); + } + + [Target(nameof(PublishInstallerFile))] + [BuildPlatforms(BuildPlatform.Ubuntu)] + public static BuildTargetResult PublishDebFileToDebianRepo(BuildTargetContext c) + { + var packageName = Monikers.GetDebianPackageName(c); + var installerFile = c.BuildContext.Get("InstallerFile"); + var uploadUrl = $"https://dotnetcli.blob.core.windows.net/dotnet/{Channel}/Installers/{Version}/{Path.GetFileName(installerFile)}"; + var uploadJson = GenerateUploadJsonFile(packageName, Version, uploadUrl); + + Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "publish", "repoapi_client.sh"), "-addpkg", uploadJson) + .Execute() + .EnsureSuccessful(); + + return c.Success(); + } + + private static string GenerateUploadJsonFile(string packageName, string version, string uploadUrl) + { + var repoID = Environment.GetEnvironmentVariable("REPO_ID"); + var uploadJson = Path.Combine(Dirs.Packages, "package_upload.json"); + File.Delete(uploadJson); + + using (var fileStream = File.Create(uploadJson)) + { + using (StreamWriter sw = new StreamWriter(fileStream)) + { + sw.WriteLine("{"); + sw.WriteLine($" \"name\":\"{packageName}\","); + sw.WriteLine($" \"version\":\"{version}\","); + sw.WriteLine($" \"repositoryId\":\"{repoID}\","); + sw.WriteLine($" \"sourceUrl\":\"{uploadUrl}\""); + sw.WriteLine("}"); + } + } + + return uploadJson; + } + + private static BuildTargetResult PublishFile(BuildTargetContext c, string file) + { + var env = PackageTargets.GetCommonEnvVars(c); + Cmd("powershell", "-NoProfile", "-NoLogo", + Path.Combine(Dirs.RepoRoot, "scripts", "publish", "publish.ps1"), file) + .Environment(env) + .Execute() + .EnsureSuccessful(); + return c.Success(); + } + + private static void PublishFileAzure(string blob, string file) + { + CloudBlockBlob blockBlob = BlobContainer.GetBlockBlobReference(blob); + using (var fileStream = File.OpenRead(file)) + { + blockBlob.UploadFromStreamAsync(fileStream).Wait(); + } + } } } diff --git a/scripts/dotnet-cli-build/Utils/Dirs.cs b/scripts/dotnet-cli-build/Utils/Dirs.cs index 98ee39fc1..eea866d9b 100644 --- a/scripts/dotnet-cli-build/Utils/Dirs.cs +++ b/scripts/dotnet-cli-build/Utils/Dirs.cs @@ -7,8 +7,9 @@ namespace Microsoft.DotNet.Cli.Build { public static class Dirs { + public static readonly string RepoRoot = Directory.GetCurrentDirectory(); public static readonly string Output = Path.Combine( - Directory.GetCurrentDirectory(), + RepoRoot, "artifacts", PlatformServices.Default.Runtime.GetRuntimeIdentifier()); public static readonly string Packages = Path.Combine(Output, "packages"); diff --git a/scripts/dotnet-cli-build/Utils/Monikers.cs b/scripts/dotnet-cli-build/Utils/Monikers.cs new file mode 100644 index 000000000..ae8052636 --- /dev/null +++ b/scripts/dotnet-cli-build/Utils/Monikers.cs @@ -0,0 +1,57 @@ +using Microsoft.DotNet.Cli.Build.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Cli.Build +{ + public class Monikers + { + public static string GetProductMoniker(BuildTargetContext c) + { + string osname = GetOSShortName(); + var arch = CurrentArchitecture.Current.ToString(); + var version = c.BuildContext.Get("BuildVersion").SimpleVersion; + return $"dotnet-{osname}-{arch}.{version}"; + } + + public static string GetDebianPackageName(BuildTargetContext c) + { + var channel = c.BuildContext.Get("Channel").ToLower(); + var packageName = ""; + switch (channel) + { + case "dev": + packageName = "dotnet-nightly"; + break; + case "beta": + case "rc1": + case "rc2": + case "rtm": + packageName = "dotnet"; + break; + default: + throw new Exception($"Unknown channel - {channel}"); + } + + return packageName; + } + + public static string GetOSShortName() + { + string osname = ""; + switch (CurrentPlatform.Current) + { + case BuildPlatform.Windows: + osname = "win"; + break; + default: + osname = CurrentPlatform.Current.ToString().ToLower(); + break; + } + + return osname; + } + } +} diff --git a/scripts/dotnet-cli-build/project.json b/scripts/dotnet-cli-build/project.json index 7b6298d22..e76a7a1c3 100755 --- a/scripts/dotnet-cli-build/project.json +++ b/scripts/dotnet-cli-build/project.json @@ -9,12 +9,13 @@ "NETStandard.Library": "1.0.0-rc2-23901", "System.IO.Compression.ZipFile": "4.0.1-rc2-23901", "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537", - "Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*" + "Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*", + "WindowsAzure.Storage" : "6.2.2-preview" }, "frameworks": { "netstandardapp1.5": { - "imports": "dnxcore50" + "imports": ["dnxcore50", "portable-net45+win8"] } } } diff --git a/scripts/package/package-debian.sh b/scripts/package/package-debian.sh index 909f929e7..e06748739 100755 --- a/scripts/package/package-debian.sh +++ b/scripts/package/package-debian.sh @@ -17,46 +17,105 @@ done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" source "$DIR/../common/_common.sh" +REPOROOT="$DIR/../.." -if [ "$OSNAME" != "ubuntu" ]; then - error "Debian Package build only supported on Ubuntu" +help(){ + echo "Usage: $0" + echo "" + echo "Options:" + echo " --version Specify a version for the package." + echo " --input Package the entire contents of the directory tree." + echo " --manpages Directory containing man pages for the package (Optional)." + echo " --output The full path to which the package will be written." + echo " --package-name Package to identify during installation. Example - 'dotnet-nightly', 'dotnet'" + echo " --previous-version-url Url to the previous version of the debian packge against which to run the upgrade tests." exit 1 -fi +} + +parseargs(){ + + while [[ $# > 0 ]]; do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + -m|--manpages) + MANPAGE_DIR=$2 + shift + ;; + -o|--output) + OUTPUT_DEBIAN_FILE=$2 + shift + ;; + -i|--input) + REPO_BINARIES_DIR=$2 + shift + ;; + -p|--package-name) + DOTNET_DEB_PACKAGE_NAME=$2 + shift + ;; + -v|--version) + DOTNET_CLI_VERSION=$2 + shift + ;; + --previous-version-url) + PREVIOUS_VERSION_URL=$2 + shift + ;; + --help) + help + ;; + *) + break + ;; + esac + shift + done + + if [ -z "$DOTNET_CLI_VERSION" ]; then + echo "Provide a version number. Missing option '--version'" && help + fi + + if [ -z "$OUTPUT_DEBIAN_FILE" ]; then + echo "Provide an output deb. Missing option '--output'" && help + fi + + if [ -z "$REPO_BINARIES_DIR" ]; then + echo "Provide an input directory. Missing option '--input'" && help + fi + + if [ -z "$DOTNET_DEB_PACKAGE_NAME" ]; then + echo "Provide an the name for the debian package. Missing option '--package-name'" && help + fi + + if [ -z "$PREVIOUS_VERSION_URL" ]; then + echo "Provide a URL to the previous debian pacakge (Required for running upgrade tests). Missing option '--previous-version-url'" && help + fi + + if [ ! -d "$REPO_BINARIES_DIR" ]; then + echo "'$REPO_BINARIES_DIR' - is either missing or not a directory" 1>&2 + exit 1 + fi + +} + +parseargs $@ PACKAGING_ROOT="$REPOROOT/packaging/debian" PACKAGING_TOOL_DIR="$REPOROOT/tools/DebianPackageTool" -OUTPUT_DIR="$REPOROOT/artifacts" -PACKAGE_LAYOUT_DIR="$OUTPUT_DIR/deb_intermediate" -PACKAGE_OUTPUT_DIR="$OUTPUT_DIR/packages/debian" -TEST_STAGE_DIR="$PACKAGE_OUTPUT_DIR/test" -REPO_BINARIES_DIR="$REPOROOT/artifacts/ubuntu.14.04-x64/stage2" -MANPAGE_DIR="$REPOROOT/Documentation/manpages" +PACKAGE_OUTPUT_DIR=$(dirname "${OUTPUT_DEBIAN_FILE}") +PACKAGE_LAYOUT_DIR="$PACKAGE_OUTPUT_DIR/deb_intermediate" +TEST_STAGE_DIR="$PACKAGE_OUTPUT_DIR/debian_tests" -NIGHTLY_PACKAGE_NAME="dotnet-nightly" -RELEASE_PACKAGE_NAME="dotnet" - -[ -z "$CHANNEL" ] && CHANNEL="dev" +# remove any residual deb files from earlier builds +rm -f "$PACKAGE_OUTPUT_DIR/*.deb" execute_build(){ - determine_package_name create_empty_debian_layout copy_files_to_debian_layout create_debian_package } -determine_package_name(){ - if [[ "$RELEASE_SUFFIX" == "dev" ]]; then - DOTNET_DEB_PACKAGE_NAME=$NIGHTLY_PACKAGE_NAME - elif [[ "beta rc1 rc2 rtm" =~ (^| )"$RELEASE_SUFFIX"($| ) ]]; then - DOTNET_DEB_PACKAGE_NAME=$RELEASE_PACKAGE_NAME - elif [[ "$RELEASE_SUFFIX" == "" ]]; then - DOTNET_DEB_PACKAGE_NAME=$RELEASE_PACKAGE_NAME - else - DOTNET_DEB_PACKAGE_NAME=$NIGHTLY_PACKAGE_NAME - fi -} - execute_test(){ test_debian_package } @@ -120,7 +179,7 @@ remove_debian_package() { run_package_integrity_tests() { # Set LAST_VERSION_URL to enable upgrade tests - export LAST_VERSION_URL="https://dotnetcli.blob.core.windows.net/dotnet/$CHANNEL/Installers/Latest/dotnet-ubuntu-x64.latest.deb" + export LAST_VERSION_URL="$PREVIOUS_VERSION_URL" $TEST_STAGE_DIR/bin/bats $PACKAGE_OUTPUT_DIR/test_package.bats } @@ -142,5 +201,4 @@ DEBIAN_FILE=$(find $PACKAGE_OUTPUT_DIR -iname "*.deb") execute_test -# Publish -$REPOROOT/scripts/publish/publish.sh $DEBIAN_FILE +mv -f "$DEBIAN_FILE" "$OUTPUT_DEBIAN_FILE" diff --git a/scripts/package/package-dnvm.sh b/scripts/package/package-dnvm.sh deleted file mode 100755 index 47d8fe396..000000000 --- a/scripts/package/package-dnvm.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -source "$DIR/../common/_common.sh" - -if [ ! -d "$STAGE2_DIR" ]; then - error "missing stage2 output in $STAGE2_DIR" 1>&2 - exit -fi - -PACKAGE_DIR=$REPOROOT/artifacts/packages/dnvm -[ -d "$PACKAGE_DIR" ] || mkdir -p $PACKAGE_DIR - -PACKAGE_SHORT_NAME=dotnet-${OSNAME}-x64.${DOTNET_CLI_VERSION} -PACKAGE_NAME=$PACKAGE_DIR/${PACKAGE_SHORT_NAME}.tar.gz - -cd $STAGE2_DIR - -header "Packaging $PACKAGE_SHORT_NAME" - -# Tar up the stage2 artifacts -# We need both "*" and ".version" to ensure we pick up that file -tar -czf $PACKAGE_NAME * .version - -info "Packaged stage2 from '$STAGE2_DIR' to '$PACKAGE_NAME'" - -$REPOROOT/scripts/publish/publish.sh $PACKAGE_NAME diff --git a/scripts/package/package-native.sh b/scripts/package/package-native.sh deleted file mode 100755 index f62754e8e..000000000 --- a/scripts/package/package-native.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -set -e - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -source "$DIR/../common/_common.sh" - -if [[ "$OSNAME" == "ubuntu" ]]; then - # Create Debian package - $REPOROOT/scripts/package/package-debian.sh -elif [[ "$OSNAME" == "osx" ]]; then - # Create OSX PKG - $REPOROOT/packaging/osx/package-osx.sh -fi diff --git a/scripts/package/package-zip.ps1 b/scripts/package/package-zip.ps1 deleted file mode 100644 index 8b7000d65..000000000 --- a/scripts/package/package-zip.ps1 +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -. "$PSScriptRoot\..\common\_common.ps1" - -if(!(Test-Path $PackageDir)) { - mkdir $PackageDir | Out-Null -} - -if(![string]::IsNullOrEmpty($env:DOTNET_CLI_VERSION)) { - $PackageVersion = $env:DOTNET_CLI_VERSION -} else { - $Timestamp = [DateTime]::Now.ToString("yyyyMMddHHmmss") - $PackageVersion = "0.0.1-dev-t$Timestamp" -} - -# Stamp the output with the commit metadata and version number -$Commit = git rev-parse HEAD - -$VersionContent = @" -$Commit -$PackageVersion -"@ - -$VersionContent | Out-File -Encoding UTF8 "$Stage2Dir\.version" - -$PackageName = Join-Path $PackageDir "dotnet-win-$env:ARCHITECTURE.$PackageVersion.zip" - -if (Test-Path $PackageName) -{ - del $PackageName -} - -Add-Type -Assembly System.IO.Compression.FileSystem -[System.IO.Compression.ZipFile]::CreateFromDirectory($Stage2Dir, $PackageName, "Optimal", $false) - -Write-Host "Packaged stage2 to $PackageName" - -$PublishScript = Join-Path $PSScriptRoot "..\publish\publish.ps1" -& $PublishScript -file $PackageName - -exit $LastExitCode diff --git a/scripts/package/package.cmd b/scripts/package/package.cmd deleted file mode 100644 index 01f78b1ca..000000000 --- a/scripts/package/package.cmd +++ /dev/null @@ -1,6 +0,0 @@ -@echo off - -REM Copyright (c) .NET Foundation and contributors. All rights reserved. -REM Licensed under the MIT license. See LICENSE file in the project root for full license information. - -powershell -NoProfile -NoLogo -Command "%~dp0package.ps1 %*; exit $LastExitCode;" diff --git a/scripts/package/package.ps1 b/scripts/package/package.ps1 deleted file mode 100644 index cfb3c13d8..000000000 --- a/scripts/package/package.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -. "$PSScriptRoot\..\common\_common.ps1" - -$RepoRoot = Convert-Path "$PSScriptRoot\..\.." - -header "Generating zip package" -_ "$RepoRoot\scripts\package\package-zip.ps1" - -header "Generating dotnet MSI" -_ "$RepoRoot\packaging\windows\generatemsi.ps1" @("$Stage2Dir") - -header "Generating NuGet packages" -_ "$RepoRoot\packaging\nuget\package.ps1" @("$Stage2Dir\bin", "$env:VersionSuffix") - -header "Generating version badge" -$VersionBadge = "$RepoRoot\resources\images\version_badge.svg" -$BadgeDestination = "$RepoRoot\artifacts\version_badge.svg" -(get-content $VersionBadge).replace("ver_number", "$env:DOTNET_CLI_VERSION") | set-content $BadgeDestination - -& "$RepoRoot\scripts\publish\publish.ps1" -file $BadgeDestination diff --git a/scripts/package/package.sh b/scripts/package/package.sh deleted file mode 100755 index 6b8e3c8d6..000000000 --- a/scripts/package/package.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -export REPOROOT="$(cd -P "$DIR/../.." && pwd)" - -set -e - -source "$DIR/../common/_common.sh" - -if [ -z "$DOTNET_CLI_VERSION" ]; then - TIMESTAMP=$(date "+%Y%m%d%H%M%S") - DOTNET_CLI_VERSION=0.0.1-dev-t$TIMESTAMP -fi - -VERSION_BADGE="$REPOROOT/resources/images/version_badge.svg" -BADGE_DESTINATION="$REPOROOT/artifacts/version_badge.svg" - -header "Generating tarball" -$DIR/package-dnvm.sh - -header "Generating Native Installer" -$DIR/package-native.sh - -header "Generating version badge" -sed "s/ver_number/$DOTNET_CLI_VERSION/g" $VERSION_BADGE > $BADGE_DESTINATION - -header "Publishing version badge" -$DIR/../publish/publish.sh $BADGE_DESTINATION - diff --git a/scripts/publish/publish.ps1 b/scripts/publish/publish.ps1 deleted file mode 100644 index 7c106f0bc..000000000 --- a/scripts/publish/publish.ps1 +++ /dev/null @@ -1,186 +0,0 @@ -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -param( - [Parameter(Mandatory=$true)][string]$file -) - -. "$PSScriptRoot\..\common\_common.ps1" - -function CheckRequiredVariables -{ - if([string]::IsNullOrEmpty($env:DOTNET_CLI_VERSION)) - { - return $false - } - - # this variable is set by the CI system - if([string]::IsNullOrEmpty($env:SASTOKEN)) - { - return $false - } - - # this variable is set by the CI system - if([string]::IsNullOrEmpty($env:STORAGE_ACCOUNT)) - { - return $false - } - - # this variable is set by the CI system - if([string]::IsNullOrEmpty($env:STORAGE_CONTAINER)) - { - return $false - } - - # this variable is set by the CI system - if([string]::IsNullOrEmpty($env:CHANNEL)) - { - return $false - } - - # this variable is set by the CI system - if([string]::IsNullOrEmpty($env:CONNECTION_STRING)) - { - return $false - } - - return $true -} - -function UploadFile($Blob, $Uploadfile, $PreventCaching = $false) -{ - Write-Host "Uploading $Uploadfile to dotnet feed." - - if([string]::IsNullOrEmpty($env:HOME)) - { - $env:HOME=Get-Location - } - - $properties = "" - - if($PreventCaching) - { - # use azure cli to upload to blob storage. We cannot use Invoke-WebRequest to do this becuase azure has a max limit of 64mb that can be uploaded using REST - #$statusCode = (Invoke-WebRequest -URI "$Upload_URI" -Method PUT -Headers @{"x-ms-blob-type"="BlockBlob"; "x-ms-date"="2015-10-23";"x-ms-version"="2013-08-15"} -InFile $Uploadfile).StatusCode - azure storage blob upload --quiet --properties cacheControl=no-cache --container $env:STORAGE_CONTAINER --blob $Blob --blobtype block --connection-string "$env:CONNECTION_STRING" --file $Uploadfile | Out-Host - } - else - { - # use azure cli to upload to blob storage. We cannot use Invoke-WebRequest to do this becuase azure has a max limit of 64mb that can be uploaded using REST - #$statusCode = (Invoke-WebRequest -URI "$Upload_URI" -Method PUT -Headers @{"x-ms-blob-type"="BlockBlob"; "x-ms-date"="2015-10-23";"x-ms-version"="2013-08-15"} -InFile $Uploadfile).StatusCode - azure storage blob upload --quiet $properties --container $env:STORAGE_CONTAINER --blob $Blob --blobtype block --connection-string "$env:CONNECTION_STRING" --file $Uploadfile | Out-Host - } - - - if($?) - { - Write-Host "Successfully uploaded $Uploadfile to dotnet feed." - return $true - } - else - { - Write-Host "Failed to upload $Uploadfile to dotnet feed." - return $false - } -} - -function UploadBinaries($zipFile) -{ - $result = -1 - $fileName = [System.IO.Path]::GetFileName($zipFile) - $zipBlob = "$env:CHANNEL/Binaries/$env:DOTNET_CLI_VERSION/$fileName" - - if(-Not (UploadFile $zipBlob $zipFile)) - { - return -1 - } - - Write-Host "Updating the latest dotnet binaries for windows.." - $zipBlobLatest = "$env:CHANNEL/Binaries/Latest/dotnet-win-$env:ARCHITECTURE.latest.zip" - - if(-Not (UploadFile $zipBlobLatest $zipFile $true)) - { - return -1 - } - - # update the version file - $versionFile = Convert-Path $PSScriptRoot\..\..\artifacts\$env:RID\stage2\.version - $versionBlob = "$env:CHANNEL/dnvm/latest.win.$env:ARCHITECTURE.version" - - if(-Not (UploadFile $versionBlob $versionFile $true)) - { - return -1 - } - - return 0 -} - -function UploadInstallers($installerFile) -{ - $fileName = [System.IO.Path]::GetFileName($installerFile) - $installerBlob = "$env:CHANNEL/Installers/$env:DOTNET_CLI_VERSION/$fileName" - - if(-Not (UploadFile $installerBlob $installerFile)) - { - return -1 - } - - Write-Host "Updating the latest dotnet installer for windows.." - $installerBlobLatest = "$env:CHANNEL/Installers/Latest/dotnet-win-$env:ARCHITECTURE.latest.exe" - - if(-Not (UploadFile $installerBlobLatest $installerFile $true)) - { - return -1 - } - - return 0 -} - -function UploadVersionBadge($badgeFile) -{ - $fileName = "windows_$($env:CONFIGURATION)_$([System.IO.Path]::GetFileName($badgeFile))" - - Write-Host "Uploading the version badge to Latest" - if(-Not (UploadFile "$env:CHANNEL/Binaries/Latest/$fileName" $badgeFile $true)) - { - return -1 - } - - Write-Host "Uploading the version badge to $env:DOTNET_CLI_VERSION" - if(-Not (UploadFile "$env:CHANNEL/Binaries/$env:DOTNET_CLI_VERSION/$fileName" $badgeFile)) - { - return -1 - } - - return 0 -} - -if(!(CheckRequiredVariables)) -{ - # fail silently if the required variables are not available for publishing the file - exit 0 -} - -if(![System.IO.File]::Exists($file)) -{ - throw "$file not found" -} - -$result = $false - -if([System.IO.Path]::GetExtension($file).ToLower() -eq ".zip") -{ - $result = UploadBinaries $file -} -elseif([System.IO.Path]::GetExtension($file).ToLower() -eq ".exe") -{ - $result = UploadInstallers $file -} -elseif ([System.IO.Path]::GetExtension($file).ToLower() -eq ".svg") -{ - $result = UploadVersionBadge $file -} - -exit $result diff --git a/scripts/publish/publish.sh b/scripts/publish/publish.sh deleted file mode 100755 index 743815f08..000000000 --- a/scripts/publish/publish.sh +++ /dev/null @@ -1,246 +0,0 @@ -#!/bin/bash -# -# Copyright (c) .NET Foundation and contributors. All rights reserved. -# Licensed under the MIT license. See LICENSE file in the project root for full license information. -# - -# Usage: publish.sh [file to be uploaded] -# -# Environment Dependencies: -# $STORAGE_CONTAINER -# $STORAGE_ACCOUNT -# $SASTOKEN -# $REPO_ID - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -source "$DIR/../common/_common.sh" - -SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -UPLOAD_FILE=$1 -UPLOAD_JSON_FILE="package_upload.json" - -header "Publishing package" - -execute(){ - if ! validate_env_variables; then - # fail silently if the required variables are not available for publishing the file. - exit 0 - fi - - if [[ ! -f "$UPLOAD_FILE" ]]; then - error "\"$UPLOAD_FILE\" file does not exist" - exit 1 - fi - - if [[ $UPLOAD_FILE == *.deb || $UPLOAD_FILE == *.pkg ]]; then - upload_installers_to_blob_storage $UPLOAD_FILE - result=$? - elif [[ $UPLOAD_FILE == *.tar.gz ]]; then - upload_binaries_to_blob_storage $UPLOAD_FILE - result=$? - elif [[ $UPLOAD_FILE == *.svg ]]; then - upload_version_badge $UPLOAD_FILE - result=$? - fi - - exit $result -} - -validate_env_variables(){ - local ret=0 - - if [[ -z "$DOTNET_CLI_VERSION" ]]; then - warning "DOTNET_CLI_VERSION environment variable not set" - ret=1 - fi - - if [[ -z "$SASTOKEN" ]]; then - warning "SASTOKEN environment variable not set" - ret=1 - fi - - if [[ -z "$STORAGE_ACCOUNT" ]]; then - warning "STORAGE_ACCOUNT environment variable not set" - ret=1 - fi - - if [[ -z "$STORAGE_CONTAINER" ]]; then - warning "STORAGE_CONTAINER environment variable not set" - ret=1 - fi - - if [[ -z "$CHANNEL" ]]; then - warning "CHANNEL environment variable not set" - ret=1 - fi - - if [[ -z "$CONNECTION_STRING" ]]; then - warning "CONNECTION_STRING environment variable not set" - ret=1 - fi - - return $ret -} - -upload_file_to_blob_storage_azure_cli(){ - local blob=$1 - local file=$2 - local preventCaching=${3:false} - - header "Uploading $file to blob storage" - - local properties="" - - if $preventCaching ; then - properties="--properties cacheControl=no-cache" - fi - - # use azure cli to upload to blob storage. We cannot use curl to do this becuase azure has a max limit of 64mb that can be uploaded using REST - # statusCode=$(curl -s -w "%{http_code}" -L -H "x-ms-blob-type: BlockBlob" -H "x-ms-date: 2015-10-21" -H "x-ms-version: 2013-08-15" $upload_URL -T $file) - azure storage blob upload --quiet $properties --container $STORAGE_CONTAINER --blob $blob --blobtype block --connection-string "$CONNECTION_STRING" --file $file - result=$? - - if [ "$result" -eq "0" ]; then - info "successfully uploaded $filename to blob storage." - return 0 - else - error "uploading the $filename to blob storage - $statusCode" - return 1 - fi -} - -update_file_in_blob_storage(){ - local update_URL=$1 - local file=$2 - local filecontent=$3 - - header "Updating $file in blob storage" - - statusCode=$(curl -s -w "%{http_code}" -L -H "x-ms-blob-type: BlockBlob" -H "x-ms-date: 2015-10-21" -H "x-ms-version: 2013-08-15" -H "Content-Type: text/plain" $update_URL --data-binary $filecontent --request PUT ) - - if [ "$statusCode" -eq "201" ]; then - info "successfully updated $file in blob storage." - return 0 - else - error "updating the $file in blob storage - $statusCode" - return 1 - fi -} - -upload_binaries_to_blob_storage(){ - local tarfile=$1 - local filename=$(basename $tarfile) - local blob="$CHANNEL/Binaries/$DOTNET_CLI_VERSION/$filename" - - if ! upload_file_to_blob_storage_azure_cli $blob $tarfile; then - return 1 - fi - - # create the latest blob - echo "Updating the latest dotnet binaries.." - local latestblob="$CHANNEL/Binaries/Latest/dotnet-$OSNAME-x64.latest.tar.gz" - - if ! upload_file_to_blob_storage_azure_cli $latestblob $tarfile true; then - return 1 - fi - - # update the index file - local indexContent="Binaries/$DOTNET_CLI_VERSION/$filename" - local indexfile="latest.$OSNAME.index" - local index_URL="https://$STORAGE_ACCOUNT.blob.core.windows.net/$STORAGE_CONTAINER/$CHANNEL/dnvm/$indexfile$SASTOKEN" - update_file_in_blob_storage $index_URL $indexfile $indexContent true - - # update the version file - # the "@" prefix tells curl to upload the content of the file - local versionContent="@$REPOROOT/artifacts/$RID/stage2/.version" - local versionfile="latest.$OSNAME.version" - local version_URL="https://$STORAGE_ACCOUNT.blob.core.windows.net/$STORAGE_CONTAINER/$CHANNEL/dnvm/$versionfile$SASTOKEN" - update_file_in_blob_storage $version_URL $versionfile $versionContent true - - return $? -} - -upload_installers_to_blob_storage(){ - local installfile=$1 - local filename=$(basename $installfile) - local blob="$CHANNEL/Installers/$DOTNET_CLI_VERSION/$filename" - - if ! upload_file_to_blob_storage_azure_cli $blob $installfile; then - return 1 - fi - - # create the latest blob - echo "Updating the latest dotnet installer.." - local extension="${filename##*.}" - local latestblob="$CHANNEL/Installers/Latest/dotnet-$OSNAME-x64.latest.$extension" - - if ! upload_file_to_blob_storage_azure_cli $latestblob $installfile true; then - return 1 - fi - - # debain packages need to be uploaded to the PPA feed too - if [[ $installfile == *.deb ]]; then - DEB_FILE=$installfile - UPLOAD_URL="https://$STORAGE_ACCOUNT.blob.core.windows.net/$STORAGE_CONTAINER/$blob" - generate_repoclient_json - call_repo_client - fi - - return 0 -} - -upload_version_badge(){ - local badgefile=$1 - local filename="${OSNAME}_${CONFIGURATION}_$(basename $badgefile)" - echo "Uploading the version badge to Latest" - upload_file_to_blob_storage_azure_cli "$CHANNEL/Binaries/Latest/$filename" $badgefile true - - echo "Uploading the version badge to $DOTNET_CLI_VERSION" - upload_file_to_blob_storage_azure_cli "$CHANNEL/Binaries/$DOTNET_CLI_VERSION/$filename" $badgefile - - return 0 -} - - -generate_repoclient_json(){ - # Clean any existing json file - rm -f $SCRIPT_DIR/$UPLOAD_JSON_FILE - - echo "{" >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" - echo " \"name\":\"$(_get_package_name)\"," >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" - echo " \"version\":\"$(_get_package_version)\"," >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" - echo " \"repositoryId\":\"$REPO_ID\"," >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" - echo " \"sourceUrl\":\"$UPLOAD_URL\"" >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" - echo "}" >> "$SCRIPT_DIR/$UPLOAD_JSON_FILE" -} - -call_repo_client(){ - $SCRIPT_DIR/repoapi_client.sh -addpkg $SCRIPT_DIR/$UPLOAD_JSON_FILE -} - -# Extract the package name from the .deb filename -_get_package_name(){ - local deb_filename=$(basename $DEB_FILE) - local package_name=${deb_filename%%_*} - - echo $package_name -} - -# Extract the package version from the .deb filename -_get_package_version(){ - local deb_filename=$(basename $DEB_FILE) - local package_version=${deb_filename#*_} - package_version=${package_version%-*} - - echo $package_version -} - -execute diff --git a/scripts/run-build.sh b/scripts/run-build.sh index c2962f0b8..076abfdb2 100755 --- a/scripts/run-build.sh +++ b/scripts/run-build.sh @@ -84,7 +84,8 @@ done < "$DIR/../branchinfo.txt" [ -d $DOTNET_INSTALL_DIR ] || mkdir -p $DOTNET_INSTALL_DIR # Ensure the latest stage0 is installed -$DIR/obtain/install.sh --channel $RELEASE_SUFFIX +export CHANNEL=$RELEASE_SUFFIX +$DIR/obtain/install.sh --channel $CHANNEL # Put stage 0 on the PATH (for this shell only) PATH="$DOTNET_INSTALL_DIR/bin:$PATH" diff --git a/tools/DebianPackageTool/test/integration_tests/test_package.bats b/tools/DebianPackageTool/test/integration_tests/test_package.bats index f0c0c90ef..8f4c75053 100755 --- a/tools/DebianPackageTool/test/integration_tests/test_package.bats +++ b/tools/DebianPackageTool/test/integration_tests/test_package.bats @@ -47,6 +47,14 @@ download_and_install_last_version(){ install_last_version } +delete_last_version(){ + rm -f "$DIR/last_version.deb" +} + +teardown(){ + delete_last_version +} + @test "package install + removal test" { install_package remove_package