Skip to content

Commit

Permalink
Build script maintenance
Browse files Browse the repository at this point in the history
  • Loading branch information
GeertvanHorrik committed Sep 13, 2018
1 parent 11c1702 commit fb321c1
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 151 deletions.
2 changes: 1 addition & 1 deletion deployment/cake/apps-uwp-tasks.cake
Expand Up @@ -140,7 +140,7 @@ private void BuildUwpApps()
appxUploadFileName = GetAppxUploadFileName(artifactsDirectory, uwpApp, VersionMajorMinorPatch);
if (appxUploadFileName == null)
{
Error("Couldn't determine the appxupload file using base directory '{0}'", artifactsDirectory);
throw new Exception(string.Format("Couldn't determine the appxupload file using base directory '{0}'", artifactsDirectory));
}

Information("Created appxupload file '{0}'", appxUploadFileName, artifactsDirectory);
Expand Down
29 changes: 2 additions & 27 deletions deployment/cake/apps-web-tasks.cake
@@ -1,35 +1,10 @@
#l "apps-web-variables.cake"
#l "lib-octopusdeploy.cake"

#addin "nuget:?package=MagicChunks&version=2.0.0.119"
#addin "nuget:?package=Newtonsoft.Json&version=11.0.2"
#addin "nuget:?package=WindowsAzure.Storage&version=9.1.1"

#tool "nuget:?package=OctopusTools&version=4.39.1"

//-------------------------------------------------------------

private string GetOctopusRepositoryUrl(string projectName)
{
// Allow per project overrides via "OctopusRepositoryUrlFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "OctopusRepositoryUrlFor", OctopusRepositoryUrl);
}

//-------------------------------------------------------------

private string GetOctopusRepositoryApiKey(string projectName)
{
// Allow per project overrides via "OctopusRepositoryApiKeyFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "OctopusRepositoryApiKeyFor", OctopusRepositoryApiKey);
}

//-------------------------------------------------------------

private string GetOctopusDeploymentTarget(string projectName)
{
// Allow per project overrides via "OctopusDeploymentTargetFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "OctopusDeploymentTargetFor", OctopusDeploymentTarget);
}

//-------------------------------------------------------------

private void ValidateWebAppsInput()
Expand Down Expand Up @@ -188,7 +163,7 @@ private void DeployWebApps()
ReplaceExisting = true,
});

Information("2) Creating release '{0}'", VersionNuGet);
Information("2) Creating release '{0}' in Octopus Deploy", VersionNuGet);

OctoCreateRelease(webApp, new CreateReleaseSettings
{
Expand Down
4 changes: 0 additions & 4 deletions deployment/cake/apps-web-variables.cake
@@ -1,9 +1,5 @@
#l "./buildserver.cake"

var OctopusRepositoryUrl = GetBuildServerVariable("OctopusRepositoryUrl");
var OctopusRepositoryApiKey = GetBuildServerVariable("OctopusRepositoryApiKey");
var OctopusDeploymentTarget = GetBuildServerVariable("OctopusDeploymentTarget", "Staging");

//-------------------------------------------------------------

List<string> _webApps;
Expand Down
5 changes: 2 additions & 3 deletions deployment/cake/apps-wpf-tasks.cake
Expand Up @@ -327,8 +327,7 @@ private void DeployWpfApps()
var azureStorageSyncExe = azureStorageSyncExes.LastOrDefault();
if (azureStorageSyncExe == null)
{
Error("Can't find the AzureStorageSync tool that should have been installed via this script");
return;
throw new Exception("Can't find the AzureStorageSync tool that should have been installed via this script");
}

foreach (var wpfApp in WpfApps)
Expand All @@ -351,7 +350,7 @@ private void DeployWpfApps()

if (exitCode != 0)
{
Error("Received unexpected exit code '{0}' for WPF app '{1}'", exitCode, wpfApp);
throw new Exception(string.Format("Received unexpected exit code '{0}' for WPF app '{1}'", exitCode, wpfApp));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion deployment/cake/buildserver.cake
Expand Up @@ -100,7 +100,7 @@ private string GetBuildServerVariableForCache(string variableName, string defaul
return ((Func<string>)parameter).Invoke();
}

Error("Parameter is defined as '{0}', but that type is not supported yet...", parameter.GetType().Name);
throw new Exception(string.Format("Parameter is defined as '{0}', but that type is not supported yet...", parameter.GetType().Name));
}

Information("Variable '{0}' is not specified, returning default value", variableName);
Expand Down
3 changes: 1 addition & 2 deletions deployment/cake/components-tasks.cake
Expand Up @@ -223,8 +223,7 @@ private void DeployComponents()

if (string.IsNullOrWhiteSpace(nuGetRepositoryUrl))
{
Error("NuGet repository is empty, as a protection mechanism this must *always* be specified to make sure packages aren't accidentally deployed to the default public NuGet feed");
return;
throw new Exception("NuGet repository is empty, as a protection mechanism this must *always* be specified to make sure packages aren't accidentally deployed to the default public NuGet feed");
}

NuGetPush(packageToPush, new NuGetPushSettings
Expand Down
155 changes: 131 additions & 24 deletions deployment/cake/docker-tasks.cake
@@ -1,6 +1,8 @@
#l "docker-variables.cake"
#l "lib-octopusdeploy.cake"

#addin "nuget:?package=Cake.FileHelpers&version=3.0.0"
#addin "nuget:?package=Cake.Docker&version=0.9.6 "

//-------------------------------------------------------------

Expand All @@ -12,10 +14,28 @@ private string GetDockerRegistryUrl(string projectName)

//-------------------------------------------------------------

private string GetDockerRegistryApiKey(string projectName)
private string GetDockerRegistryUserName(string projectName)
{
// Allow per project overrides via "DockerRegistryApiKeyFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "DockerRegistryApiKeyFor", DockerRegistryApiKey);
// Allow per project overrides via "DockerRegistryUserNameFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "DockerRegistryUserNameFor", DockerRegistryUserName);
}

//-------------------------------------------------------------

private string GetDockerRegistryPassword(string projectName)
{
// Allow per project overrides via "DockerRegistryPasswordFor[ProjectName]"
return GetProjectSpecificConfigurationValue(projectName, "DockerRegistryPasswordFor", DockerRegistryPassword);
}

//-------------------------------------------------------------

private string GetDockerImageTag(string projectName, string version)
{
var dockerRegistryUrl = GetDockerRegistryUrl(projectName);

var tag = string.Format("{0}/{1}:v{2}", dockerRegistryUrl, projectName.Replace(".", "-"), version);
return tag.ToLower();
}

//-------------------------------------------------------------
Expand All @@ -41,17 +61,18 @@ private void UpdateInfoForDockerImages()
return;
}

foreach (var dockerImage in DockerImages)
{
Information("Updating version for docker image '{0}'", dockerImage);
// Doesn't seem neccessary yet
// foreach (var dockerImage in DockerImages)
// {
// Information("Updating version for docker image '{0}'", dockerImage);

var projectFileName = GetProjectFileName(dockerImage);
// var projectFileName = GetProjectFileName(dockerImage);

TransformConfig(projectFileName, new TransformationCollection
{
{ "Project/PropertyGroup/PackageVersion", VersionNuGet }
});
}
// TransformConfig(projectFileName, new TransformationCollection
// {
// { "Project/PropertyGroup/PackageVersion", VersionNuGet }
// });
// }
}

//-------------------------------------------------------------
Expand Down Expand Up @@ -85,12 +106,6 @@ private void BuildDockerImages()
msBuildSettings.WithProperty("OverridableOutputPath", outputDirectory);
msBuildSettings.WithProperty("PackageOutputPath", OutputRootDirectory);

// SourceLink specific stuff
msBuildSettings.WithProperty("PublishRepositoryUrl", "true");

// For SourceLink to work, the .csproj should contain something like this:
// <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63127-02 " PrivateAssets="all" />

MSBuild(projectFileName, msBuildSettings);
}
}
Expand All @@ -109,10 +124,50 @@ private void PackageDockerImages()
LogSeparator("Packaging docker image '{0}'", dockerImage);

var projectFileName = string.Format("./src/{0}/{0}.csproj", dockerImage);
var dockerImageSpecificationFileName = string.Format("./deployment/docker/{0}/{0}", dockerImage);

// TODO: How to pack
var outputDirectory = string.Format("{0}/{1}/", OutputRootDirectory, dockerImage);
Information("Output directory: '{0}'", outputDirectory);

Information("1) Using 'dotnet publish' to package '{0}'", dockerImage);

var msBuildSettings = new DotNetCoreMSBuildSettings();

// Note: we need to set OverridableOutputPath because we need to be able to respect
// AppendTargetFrameworkToOutputPath which isn't possible for global properties (which
// are properties passed in using the command line)
msBuildSettings.WithProperty("OverridableOutputPath", outputDirectory);
msBuildSettings.WithProperty("PackageOutputPath", outputDirectory);
msBuildSettings.WithProperty("ConfigurationName", ConfigurationName);
msBuildSettings.WithProperty("PackageVersion", VersionNuGet);

var publishSettings = new DotNetCorePublishSettings
{
MSBuildSettings = msBuildSettings,
OutputDirectory = outputDirectory,
Configuration = ConfigurationName
};

DotNetCorePublish(projectFileName, publishSettings);

Information("2) Using 'docker build' to package '{0}'", dockerImage);

// docker build ..\..\output\Release\platform -f .\Dockerfile

// From the docs (https://docs.microsoft.com/en-us/azure/app-service/containers/tutorial-custom-docker-image#use-a-docker-image-from-any-private-registry-optional),
// we need something like this:
// docker tag <azure-container-registry-name>.azurecr.io/mydockerimage
var dockerRegistryUrl = GetDockerRegistryUrl(dockerImage);

// Note: to prevent all output & source files to be copied to the docker context, we will set the
// output directory as context (to keep the footprint as small as possible)

DockerBuild(new DockerImageBuildSettings
{
File = dockerImageSpecificationFileName,
Tag = new string[] { GetDockerImageTag(dockerImage, VersionNuGet) }
}, outputDirectory);

LogSeparator();
}
}
Expand All @@ -136,17 +191,69 @@ private void DeployDockerImages()

LogSeparator("Deploying docker image '{0}'", dockerImage);

var imageToPush = string.Format("{0}/{1}.{2}.nupkg", OutputRootDirectory, dockerImage, VersionNuGet);
var dockerRegistryUrl = GetDockerRegistryUrl(dockerImage);
var dockerRegistryApiKey = GetDockerRegistryApiKey(dockerImage);
var dockerRegistryUserName = GetDockerRegistryUserName(dockerImage);
var dockerRegistryPassword = GetDockerRegistryPassword(dockerImage);
var dockerImageTag = GetDockerImageTag(dockerImage, VersionNuGet);
var octopusRepositoryUrl = GetOctopusRepositoryUrl(dockerImage);
var octopusRepositoryApiKey = GetOctopusRepositoryApiKey(dockerImage);
var octopusDeploymentTarget = GetOctopusDeploymentTarget(dockerImage);

if (string.IsNullOrWhiteSpace(dockerRegistryUrl))
{
Error("Docker registry url is empty, as a protection mechanism this must *always* be specified to make sure packages aren't accidentally deployed to some default public registry");
return;
throw new Exception("Docker registry url is empty, as a protection mechanism this must *always* be specified to make sure packages aren't accidentally deployed to some default public registry");
}

// TODO: Push to registry
// Note: we are logging in each time because the registry might be different per container
Information("1) Logging in to docker @ '{0}'", dockerRegistryUrl);

DockerLogin(new DockerRegistryLoginSettings
{
Username = dockerRegistryUserName,
Password = dockerRegistryPassword
}, dockerRegistryUrl);

try
{
Information("2) Pushing docker images with tag '{0}' to '{1}'", dockerImageTag, dockerRegistryUrl);

DockerPush(new DockerImagePushSettings
{
}, dockerImageTag);

Information("3) Creating release '{0}' in Octopus Deploy", VersionNuGet);

OctoCreateRelease(dockerImage, new CreateReleaseSettings
{
Server = octopusRepositoryUrl,
ApiKey = octopusRepositoryApiKey,
ReleaseNumber = VersionNuGet,
DefaultPackageVersion = VersionNuGet,
IgnoreExisting = true
});

Information("4) Deploying release '{0}'", VersionNuGet);

OctoDeployRelease(octopusRepositoryUrl, octopusRepositoryApiKey, dockerImage, octopusDeploymentTarget,
VersionNuGet, new OctopusDeployReleaseDeploymentSettings
{
ShowProgress = true,
WaitForDeployment = true,
DeploymentTimeout = TimeSpan.FromMinutes(5),
CancelOnTimeout = true,
GuidedFailure = true,
Force = true,
NoRawLog = true,
});
}
finally
{
Information("5) Logging out of docker @ '{0}'", dockerRegistryUrl);

DockerLogout(new DockerRegistryLogoutSettings
{
}, dockerRegistryUrl);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion deployment/cake/docker-variables.cake
@@ -1,7 +1,8 @@
#l "buildserver.cake"

var DockerRegistryUrl = GetBuildServerVariable("DockerRegistryUrl");
var DockerRegistryApiKey = GetBuildServerVariable("DockerRegistryApiKey");
var DockerRegistryUserName = GetBuildServerVariable("DockerRegistryUserName");
var DockerRegistryPassword = GetBuildServerVariable("DockerRegistryPassword");

//-------------------------------------------------------------

Expand Down

0 comments on commit fb321c1

Please sign in to comment.