Skip to content

Commit cf4ea86

Browse files
committed
Move git safe.directory config from Dockerfile to Init.g.ps1
1 parent 1b7df3d commit cf4ea86

File tree

3 files changed

+61
-20
lines changed

3 files changed

+61
-20
lines changed

src/PostSharp.Engineering.BuildTools/Build/Publishing/PublishCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ private static bool Execute( BuildContext context, PublishSettings settings )
6060
var product = context.Product;
6161
context.Console.WriteHeading( "Publishing files" );
6262

63-
if ( !context.Product.IsPublishingNonReleaseBranchesAllowed && !settings.IsStandalone )
63+
if ( !context.Product.IsPublishingNonReleaseBranchesAllowed && !settings.IsStandalone && !settings.Force )
6464
{
6565
var publishingBranch = context.Product.DependencyDefinition.PublishingBranch;
6666

6767
if ( context.Branch != publishingBranch )
6868
{
69-
context.Console.WriteError( $"Publishing can only be executed on the '{publishingBranch}' branch. The current branch is '{context.Branch}'." );
69+
context.Console.WriteError( $"Publishing can only be executed on the '{publishingBranch}' branch. The current branch is '{context.Branch}'. Use --force to override." );
7070

7171
return false;
7272
}

src/PostSharp.Engineering.BuildTools/Docker/EpilogueComponent.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,7 @@ ARG MOUNTPOINTS
4242
# Configure .NET SDK
4343
ENV DOTNET_NOLOGO=1
4444
45-
# Configure git
46-
ARG GITDIRS
47-
RUN if ($env:GITDIRS) { `
48-
$gitdirs = $env:GITDIRS -split ';'; `
49-
foreach ($dir in $gitdirs) { `
50-
if ($dir) { `
51-
git config --global --add safe.directory $dir/; `
52-
} `
53-
} `
54-
}
45+
# Configure git (safe.directory is configured in Init.g.ps1)
5546
RUN if ( $env:GIT_USER_NAME ) { git config --global user.name $env:GIT_USER_NAME } `
5647
if ( $env:GIT_USER_EMAIL ) { git config --global user.email $env:GIT_USER_EMAIL }
5748
""" );

src/PostSharp.Engineering.BuildTools/Resources/DockerBuild.ps1

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ function New-ClaudeEnvJson
119119
$claudeEnv["IS_TEAMCITY_AGENT"] = $env:IS_TEAMCITY_AGENT
120120
}
121121

122+
# Git identity - read from host git config if not set in environment
123+
$gitUserName = $env:GIT_USER_NAME
124+
$gitUserEmail = $env:GIT_USER_EMAIL
125+
if (-not $gitUserName)
126+
{
127+
$gitUserName = git config --global user.name
128+
}
129+
if (-not $gitUserEmail)
130+
{
131+
$gitUserEmail = git config --global user.email
132+
}
133+
if ($gitUserName)
134+
{
135+
$claudeEnv["GIT_USER_NAME"] = $gitUserName
136+
}
137+
if ($gitUserEmail)
138+
{
139+
$claudeEnv["GIT_USER_EMAIL"] = $gitUserEmail
140+
}
141+
122142
# Convert to JSON and save
123143
$jsonPath = Join-Path $dockerContextDirectory "env.g.json"
124144

@@ -367,6 +387,22 @@ $MountPoints = $MountPoints | ForEach-Object { Get-ContainerPath $_ }
367387
$GitDirectories = $GitDirectories | ForEach-Object { Get-ContainerPath $_ }
368388
$ContainerSourceDir = Get-ContainerPath $SourceDirName
369389

390+
# Add both the unmapped (C:\X\...) and mapped (X:\...) paths to GitDirectories for safe.directory
391+
# Git may resolve paths differently depending on how it's invoked
392+
$expandedGitDirectories = @()
393+
foreach ($dir in $GitDirectories)
394+
{
395+
$expandedGitDirectories += $dir
396+
# If path is C:\<letter>\... (unmapped subst path), also add <letter>:\... (mapped path)
397+
if ($dir -match '^C:\\([A-Za-z])\\(.*)$')
398+
{
399+
$letter = $Matches[1].ToUpper()
400+
$rest = $Matches[2]
401+
$expandedGitDirectories += "${letter}:\$rest"
402+
}
403+
}
404+
$GitDirectories = $expandedGitDirectories
405+
370406
# Build subst commands string for inline execution in docker run
371407
$substCommandsInline = ""
372408
foreach ($letter in $driveLetters.Keys | Sort-Object)
@@ -378,9 +414,23 @@ if ($driveLetters.Count -gt 0)
378414
Write-Host "Drive letter mappings for container: $($driveLetters.Keys -join ', ')" -ForegroundColor Cyan
379415
}
380416

381-
# Create empty Init.g.ps1 for Dockerfile COPY (required by Dockerfile but not used for drive mapping)
417+
# Create Init.g.ps1 with git safe.directory configuration
382418
$initScript = Join-Path $dockerContextDirectory "Init.g.ps1"
383-
"# Drive mappings are handled inline in docker run command" | Set-Content -Path $initScript -Encoding UTF8
419+
$initScriptContent = @"
420+
# Auto-generated initialization script for container startup
421+
# Configure git safe.directory for all mounted directories
422+
`$gitDirectories = @(
423+
$(($GitDirectories | ForEach-Object { " '$_'" }) -join ",`n")
424+
)
425+
426+
foreach (`$dir in `$gitDirectories) {
427+
if (`$dir) {
428+
`$normalizedDir = (`$dir -replace '\\\\', '/').TrimEnd('/') + '/'
429+
git config --global --add safe.directory `$normalizedDir
430+
}
431+
}
432+
"@
433+
$initScriptContent | Set-Content -Path $initScript -Encoding UTF8
384434

385435
$mountPointsAsString = $MountPoints -Join ";"
386436
$gitDirectoriesAsString = $GitDirectories -Join ";"
@@ -410,7 +460,7 @@ if (-not $NoBuildImage)
410460
exit 1
411461
}
412462

413-
Get-Content -Raw Dockerfile.claude | docker build -t $ImageTag --build-arg GITDIRS="$gitDirectoriesAsString" --build-arg MOUNTPOINTS="$mountPointsAsString" -f - $dockerContextDirectory
463+
Get-Content -Raw Dockerfile.claude | docker build -t $ImageTag --build-arg MOUNTPOINTS="$mountPointsAsString" -f - $dockerContextDirectory
414464
if ($LASTEXITCODE -ne 0)
415465
{
416466
Write-Host "Docker build (Claude) failed with exit code $LASTEXITCODE" -ForegroundColor Red
@@ -421,7 +471,7 @@ if (-not $NoBuildImage)
421471
{
422472
# Build base image
423473
Write-Host "Building the base image with tag: $ImageTag" -ForegroundColor Green
424-
Get-Content -Raw Dockerfile | docker build -t $ImageTag --build-arg GITDIRS="$gitDirectoriesAsString" --build-arg MOUNTPOINTS="$mountPointsAsString" -f - $dockerContextDirectory
474+
Get-Content -Raw Dockerfile | docker build -t $ImageTag --build-arg MOUNTPOINTS="$mountPointsAsString" -f - $dockerContextDirectory
425475
if ($LASTEXITCODE -ne 0)
426476
{
427477
Write-Host "Docker build failed with exit code $LASTEXITCODE" -ForegroundColor Red
@@ -498,13 +548,13 @@ if (-not $BuildImage)
498548
{
499549
# Non-interactive mode with prompt - no -it flags
500550
$dockerArgs = @()
501-
$inlineScript = "${substCommandsInline}${copyClaudeJsonScript}cd '$SourceDirName'; & .\eng\RunClaude.g.ps1 -Prompt `"$ClaudePrompt`""
551+
$inlineScript = "${substCommandsInline}& c:\Init.g.ps1; ${copyClaudeJsonScript}cd '$SourceDirName'; & .\eng\RunClaude.g.ps1 -Prompt `"$ClaudePrompt`""
502552
}
503553
else
504554
{
505555
# Interactive mode - requires TTY
506556
$dockerArgs = @("-it")
507-
$inlineScript = "${substCommandsInline}${copyClaudeJsonScript}cd '$SourceDirName'; & .\eng\RunClaude.g.ps1"
557+
$inlineScript = "${substCommandsInline}& c:\Init.g.ps1; ${copyClaudeJsonScript}cd '$SourceDirName'; & .\eng\RunClaude.g.ps1"
508558
}
509559

510560
$dockerArgsAsString = $dockerArgs -join " "
@@ -552,8 +602,8 @@ if (-not $BuildImage)
552602
$VolumeMappingsAsString = $VolumeMappings -join " "
553603
$dockerArgsAsString = $dockerArgs -join " "
554604

555-
# Build inline script: subst drives, cd to source, run build
556-
$inlineScript = "${substCommandsInline}cd '$SourceDirName'; & .\$Script $buildArgsString; $pwshExitCommand"
605+
# Build inline script: subst drives, run init, cd to source, run build
606+
$inlineScript = "${substCommandsInline}& c:\Init.g.ps1; cd '$SourceDirName'; & .\$Script $buildArgsString; $pwshExitCommand"
557607

558608
$pwshPath = 'C:\Program Files\PowerShell\7\pwsh.exe'
559609
Write-Host "Executing: ``docker run --rm --memory=12g $dockerArgsAsString $VolumeMappingsAsString -w $ContainerSourceDir $ImageTag `"$pwshPath`" $pwshArgs -Command `"$inlineScript`"" -ForegroundColor Cyan

0 commit comments

Comments
 (0)