Skip to content

Commit 968ec7d

Browse files
committed
Adding DockerBuild.ps1.
1 parent a9ef47a commit 968ec7d

File tree

5 files changed

+182
-5
lines changed

5 files changed

+182
-5
lines changed

src/PostSharp.Engineering.BuildTools/ContinuousIntegration/GenerateCiScriptsCommand.cs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,53 @@
22

33
using JetBrains.Annotations;
44
using PostSharp.Engineering.BuildTools.Build;
5+
using System;
6+
using System.IO;
57

68
namespace PostSharp.Engineering.BuildTools.ContinuousIntegration;
79

810
[UsedImplicitly]
911
public class GenerateCiScriptsCommand : BaseCommand<CommonCommandSettings>
1012
{
1113
protected override bool ExecuteCore( BuildContext context, CommonCommandSettings settings )
12-
=> context.Product.IsBundle
13-
? TeamCityHelper.TryGenerateConsolidatedTeamcityConfiguration( context )
14-
: context.Product.GenerateTeamcityConfiguration( context, settings );
14+
{
15+
var product = context.Product;
16+
17+
if ( product.IsBundle )
18+
{
19+
if ( !TeamCityHelper.TryGenerateConsolidatedTeamcityConfiguration( context ) )
20+
{
21+
return false;
22+
}
23+
}
24+
else
25+
{
26+
if ( !product.GenerateTeamcityConfiguration( context, settings ) )
27+
{
28+
return false;
29+
}
30+
}
31+
32+
var dockerBuildScriptPath = Path.Combine( context.RepoDirectory, "DockerBuild.ps1" );
33+
34+
if ( product.UseDocker )
35+
{
36+
// Extract DockerBuild.ps1.
37+
using var resource = this.GetType().Assembly.GetManifestResourceStream( "PostSharp.Engineering.BuildTools.Resources.DockerBuild.ps1" )
38+
?? throw new InvalidOperationException( "Cannot find the resource DockerBuild.ps1." );
39+
40+
using var reader = new StreamReader( resource );
41+
var script = reader.ReadToEnd();
42+
script = script.Replace( "<ENG_PATH>", product.EngineeringDirectory, StringComparison.Ordinal );
43+
44+
if ( !File.Exists( dockerBuildScriptPath ) || File.ReadAllText( dockerBuildScriptPath ) != script )
45+
{
46+
context.Console.WriteMessage( $"Writing '{dockerBuildScriptPath}'." );
47+
48+
File.WriteAllText( dockerBuildScriptPath, script );
49+
}
50+
}
51+
52+
return true;
53+
}
1554
}

src/PostSharp.Engineering.BuildTools/PostSharp.Engineering.BuildTools.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
</ItemGroup>
4747

4848
<ItemGroup>
49-
<EmbeddedResource Include="ToolsResources\*.*" />
49+
<EmbeddedResource Include="Resources\**\*" />
5050
</ItemGroup>
5151

5252
</Project>
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# The original of this file is in the PostSharp.Engineering repo.
2+
# You can generate this file using `./Build.ps1 generate-scripts`.
3+
[CmdletBinding(PositionalBinding = $false)]
4+
param(
5+
[switch]$Interactive,
6+
[switch]$BuildImage,
7+
[switch]$NoBuildImage,
8+
[switch]$NoClean,
9+
[string]$ImageName,
10+
[string]$BuildAgentPath = 'C:\BuildAgent',
11+
[Parameter(ValueFromRemainingArguments)]
12+
[string[]]$BuildArgs
13+
)
14+
15+
# This setting is replaced by the generate-scripts command.
16+
$EngPath = '<ENG_PATH>'
17+
18+
# Generate ImageName from script directory if not provided
19+
if ( [string]::IsNullOrEmpty($ImageName))
20+
{
21+
# Get full path without drive name (e.g., "C:\src\Metalama.Compiler" becomes "src\Metalama.Compiler")
22+
$fullPath = $PSScriptRoot -replace '^[A-Za-z]:\\', ''
23+
# Sanitize path to valid Docker image name (lowercase alphanumeric and hyphens only)
24+
$ImageName = $fullPath.ToLower() -replace '[^a-z0-9\-]', '-' -replace '-+', '-' -replace '^-|-$', ''
25+
# Ensure it doesn't start with a hyphen and has at least one character
26+
if ([string]::IsNullOrEmpty($ImageName) -or $ImageName -match '^-')
27+
{
28+
$ImageName = "docker-build-image"
29+
}
30+
Write-Host "Generated image name from directory: $ImageName" -ForegroundColor Cyan
31+
}
32+
33+
# When building locally (as opposed as on the build agent), we must do a complete cleanup because
34+
# obj files may point to the host filesystem.
35+
if (-not $env:IS_TEAMCITY_AGENT -and -not $NoClean)
36+
{
37+
Write-Host "Cleaning up." -ForegroundColor Green
38+
if (Test-Path "artifacts")
39+
{
40+
Remove-Item artifacts -Force -Recurse -ProgressAction SilentlyContinue
41+
}
42+
Get-ChildItem @("bin", "obj") -Recurse | Remove-Item -Force -Recurse -ProgressAction SilentlyContinue
43+
}
44+
45+
# Get the source directory name from $PSScriptRoot
46+
$SourceDirName = $PSScriptRoot
47+
48+
# Start timing the entire process except cleaning
49+
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
50+
51+
$dockerContextDirectory = "$EngPath/docker-context"
52+
53+
# Ensure docker context directory exists and contains at least one file
54+
if (-not (Test-Path $dockerContextDirectory))
55+
{
56+
Write-Error "Docker context directory '$dockerContextDirectory' does not exist."
57+
exit 1
58+
}
59+
60+
# Create local NuGet cache directory if it doesn't exist
61+
$nugetCacheDir = Join-Path $env:USERPROFILE ".nuget\packages"
62+
Write-Host "NuGet cache directory: $nugetCacheDir" -ForegroundColor Cyan
63+
if (-not (Test-Path $nugetCacheDir))
64+
{
65+
Write-Host "Creating NuGet cache directory on host: $nugetCacheDir"
66+
New-Item -ItemType Directory -Force -Path $nugetCacheDir | Out-Null
67+
}
68+
# Define static Git system directory for mapping
69+
$gitSystemDir = "$BuildAgentPath\system\git"
70+
71+
if (-not $NoBuildImage)
72+
{
73+
Write-Host "Building the image." -ForegroundColor Green
74+
Get-Content -Raw Dockerfile | docker build -t $ImageName -f - $dockerContextDirectory
75+
if ($LASTEXITCODE -ne 0)
76+
{
77+
Write-Host "Docker build failed with exit code $LASTEXITCODE" -ForegroundColor Red
78+
exit $LASTEXITCODE
79+
}
80+
}
81+
else
82+
{
83+
Write-Host "Skipping image build (-NoBuildImage specified)." -ForegroundColor Yellow
84+
}
85+
86+
# Prepare volume mappings
87+
$volumeMappings = @("-v", "${SourceDirName}:${SourceDirName}", "-v", "${nugetCacheDir}:c:\packages")
88+
Get-Content -Raw Dockerfile | docker build -t $ImageName --build-arg SRC_DIR="$SourceDirName" -f - $dockerContextDirectory
89+
90+
# Create Git system directory on host if it doesn't exist and add volume mapping
91+
if (Test-Path $gitSystemDir)
92+
{
93+
$volumeMappings += @("-v", "${gitSystemDir}:${gitSystemDir}:ro")
94+
}
95+
96+
Write-Host "Volume mappings: " @volumeMappings -ForegroundColor Gray
97+
98+
99+
if (-not $BuildImage)
100+
{
101+
if ($Interactive)
102+
{
103+
docker run --rm -it --memory=12g @volumeMappings -w $SourceDirName $ImageName pwsh
104+
if ($LASTEXITCODE -ne 0)
105+
{
106+
Write-Host "Docker run (interactive) failed with exit code $LASTEXITCODE" -ForegroundColor Red
107+
exit $LASTEXITCODE
108+
}
109+
}
110+
else
111+
{
112+
# Delete now and not in the container because it's much faster and lock error messages are more relevant.
113+
Write-Host "Building the product in the container." -ForegroundColor Green
114+
115+
# Prepare Build.ps1 arguments
116+
$buildCommand = "$SourceDirName\Build.ps1"
117+
$buildArgsString = $BuildArgs -join " "
118+
$buildCommand += " $buildArgsString"
119+
Write-Host "Passing arguments to Build.ps1: `"$buildArgsString`"." -ForegroundColor Cyan
120+
121+
docker run --rm --memory=12g @volumeMappings -w $SourceDirName $ImageName pwsh -NonInteractive -Command $buildCommand
122+
if ($LASTEXITCODE -ne 0)
123+
{
124+
Write-Host "Docker run (build) failed with exit code $LASTEXITCODE" -ForegroundColor Red
125+
exit $LASTEXITCODE
126+
}
127+
}
128+
}
129+
else
130+
{
131+
Write-Host "Skipping container run (BuildImage specified)." -ForegroundColor Yellow
132+
}
133+
134+
# Stop timing and display results
135+
$elapsed = $stopwatch.Elapsed
136+
Write-Host ""
137+
Write-Host "Total build time: $($elapsed.ToString('hh\:mm\:ss\.fff') )" -ForegroundColor Cyan
138+
Write-Host "Build completed at: $( Get-Date -Format 'yyyy-MM-dd HH:mm:ss' )" -ForegroundColor Cyan

src/PostSharp.Engineering.BuildTools/ToolsResources/signclient-appsettings.json renamed to src/PostSharp.Engineering.BuildTools/Resources/Tools/signclient-appsettings.json

File renamed without changes.

src/PostSharp.Engineering.BuildTools/Utilities/DotNetTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public bool Install( BuildContext context )
108108

109109
foreach ( var resourceName in assembly.GetManifestResourceNames() )
110110
{
111-
const string prefix = "PostSharp.Engineering.BuildTools.ToolsResources.";
111+
const string prefix = "PostSharp.Engineering.BuildTools.Resources.Tools.";
112112

113113
if ( resourceName.StartsWith( prefix, StringComparison.Ordinal ) )
114114
{

0 commit comments

Comments
 (0)