Skip to content

Commit 3c322c3

Browse files
committed
Docker support: import environment variables.
1 parent 09411a2 commit 3c322c3

File tree

9 files changed

+155
-79
lines changed

9 files changed

+155
-79
lines changed

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using PostSharp.Engineering.BuildTools.Build;
55
using System;
66
using System.IO;
7+
using System.Linq;
78

89
namespace PostSharp.Engineering.BuildTools.ContinuousIntegration;
910

@@ -29,26 +30,34 @@ protected override bool ExecuteCore( BuildContext context, CommonCommandSettings
2930
}
3031
}
3132

32-
var dockerBuildScriptPath = Path.Combine( context.RepoDirectory, "DockerBuild.ps1" );
33-
3433
if ( product.UseDocker )
3534
{
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-
35+
ExtractScript( "DockerBuild.ps1", "" );
36+
ExtractScript( "ReadSecrets.ps1", Path.Combine( product.EngineeringDirectory, "docker-context" ) );
37+
}
38+
39+
return true;
40+
41+
void ExtractScript( string fileName, string targetDirectory )
42+
{
43+
var targetPath = Path.Combine( context.RepoDirectory, targetDirectory, fileName );
44+
45+
using var resource = this.GetType().Assembly.GetManifestResourceStream( $"PostSharp.Engineering.BuildTools.Resources.{fileName}" )
46+
?? throw new InvalidOperationException( $"Cannot find the resource {fileName}." );
47+
4048
using var reader = new StreamReader( resource );
4149
var script = reader.ReadToEnd();
42-
script = script.Replace( "<ENG_PATH>", product.EngineeringDirectory, StringComparison.Ordinal );
4350

44-
if ( !File.Exists( dockerBuildScriptPath ) || File.ReadAllText( dockerBuildScriptPath ) != script )
51+
script = script
52+
.Replace( "<ENG_PATH>", product.EngineeringDirectory, StringComparison.Ordinal )
53+
.Replace( "<ENVIRONMENT_VARIABLES>", string.Join( ",", EnvironmentVariableNames.All.OrderBy( x => x ) ), StringComparison.Ordinal );
54+
55+
if ( !File.Exists( targetPath ) || File.ReadAllText( targetPath ) != script )
4556
{
46-
context.Console.WriteMessage( $"Writing '{dockerBuildScriptPath}'." );
57+
context.Console.WriteMessage( $"Writing '{targetPath}'." );
4758

48-
File.WriteAllText( dockerBuildScriptPath, script );
59+
File.WriteAllText( targetPath, script );
4960
}
5061
}
51-
52-
return true;
5362
}
5463
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public string PollRunningBuildStatus( string buildId, out string buildNumber )
241241

242242
public bool IsBuildQueued( ConsoleHelper console, string buildId )
243243
{
244-
if ( !this.TryGet( TeamCityHelper.TeamcityApiBuildQueuePath, console, out var response ) )
244+
if ( !this.TryGet( TeamCityHelper.TeamCityApiBuildQueuePath, console, out var response ) )
245245
{
246246
return false;
247247
}

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

Lines changed: 37 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,22 @@ namespace PostSharp.Engineering.BuildTools.ContinuousIntegration;
2323

2424
public static class TeamCityHelper
2525
{
26-
public const string TeamCityOnPremUrl = "https://tc.postsharp.net";
2726
public const string TeamCityCloudUrl = "https://postsharp.teamcity.com";
2827
public const string TeamCityUsername = "[email protected]";
29-
public const string TeamcityApiBuildQueuePath = $"/app/rest/buildQueue";
28+
public const string TeamCityApiBuildQueuePath = $"/app/rest/buildQueue";
3029
public const string TeamCityApiRunningBuildsPath = "/app/rest/builds?locator=state:running";
3130
public const string TeamCityApiFinishedBuildsPath = "/app/rest/builds?locator=state:finished";
3231

3332
public static bool IsTeamCityBuild( CommonCommandSettings settings )
34-
=> settings.SimulateContinuousIntegration || Environment.GetEnvironmentVariable( EnvironmentVariableNames.IsTeamCityAgent )?.ToLowerInvariant() == "true";
33+
=> settings.SimulateContinuousIntegration
34+
|| Environment.GetEnvironmentVariable( EnvironmentVariableNames.IsTeamCityAgent )?.ToLowerInvariant() == "true";
3535

3636
public static ImmutableDictionary<string, string?> GetSimulatedContinuousIntegrationEnvironmentVariables( CommonCommandSettings settings )
3737
{
3838
if ( settings.SimulateContinuousIntegration )
3939
{
40-
var isIsTeamCityAgentEnvironmentVariableSet = Environment.GetEnvironmentVariable( EnvironmentVariableNames.IsTeamCityAgent )?.ToLowerInvariant() == "true";
40+
var isIsTeamCityAgentEnvironmentVariableSet =
41+
Environment.GetEnvironmentVariable( EnvironmentVariableNames.IsTeamCityAgent )?.ToLowerInvariant() == "true";
4142

4243
if ( !isIsTeamCityAgentEnvironmentVariableSet )
4344
{
@@ -290,7 +291,6 @@ private static bool TryGetBuildTypeId(
290291
public static CiProjectConfiguration CreateConfiguration(
291292
TeamCityProjectId teamCityProjectId,
292293
bool hasVersionBump = true,
293-
bool isCloudInstance = true,
294294
bool pullRequestRequiresStatusCheck = true,
295295
string? pullRequestStatusCheckBuildType = null,
296296
string? vcsRootProjectId = null )
@@ -308,19 +308,9 @@ public static CiProjectConfiguration CreateConfiguration(
308308
}
309309

310310
var deploymentBuildType = $"{teamCityProjectId}_PublicDeployment";
311-
string tokenEnvironmentVariableName;
312-
string baseUrl;
313311

314-
if ( isCloudInstance )
315-
{
316-
tokenEnvironmentVariableName = EnvironmentVariableNames.TeamCityCloudToken;
317-
baseUrl = TeamCityCloudUrl;
318-
}
319-
else
320-
{
321-
tokenEnvironmentVariableName = EnvironmentVariableNames.TeamCityOnPremToken;
322-
baseUrl = TeamCityOnPremUrl;
323-
}
312+
var tokenEnvironmentVariableName = EnvironmentVariableNames.TeamCityToken;
313+
var baseUrl = TeamCityCloudUrl;
324314

325315
return new CiProjectConfiguration(
326316
teamCityProjectId,
@@ -767,8 +757,8 @@ bool TryPopulateBuildConfigurations(
767757
List<TeamCitySnapshotDependency> dependencies = new();
768758
consolidatedBuildConfiguration = null;
769759
nuGetBuildConfiguration = null;
770-
dependenciesByProjectId = new();
771-
nuGetDependencies = new();
760+
dependenciesByProjectId = new Dictionary<string, HashSet<string>>();
761+
nuGetDependencies = new List<TeamCitySnapshotDependency>();
772762
buildArtifactRules = null;
773763

774764
foreach ( var buildConfiguration in buildConfigurationsByKind[consolidatedBuildObjectName] )
@@ -811,16 +801,16 @@ bool TryPopulateBuildConfigurations(
811801
];
812802

813803
var artifactRules = string.Join( "\\n", rules );
814-
804+
815805
nuGetDependencies.Add(
816-
new(
806+
new TeamCitySnapshotDependency(
817807
buildConfiguration.BuildConfigurationId,
818808
true,
819809
artifactRules ) );
820810
}
821811

822812
dependencies.Add(
823-
new(
813+
new TeamCitySnapshotDependency(
824814
buildConfiguration.BuildConfigurationId,
825815
true ) );
826816

@@ -851,7 +841,7 @@ bool TryPopulateBuildConfigurations(
851841

852842
var nuGetBuildCiId = $"{consolidatedProjectIdPrefix}{nuGetBuildObjectName}";
853843

854-
dependencies.Add( new( nuGetBuildCiId, true ) );
844+
dependencies.Add( new TeamCitySnapshotDependency( nuGetBuildCiId, true ) );
855845

856846
var defaultBuildBranch = configuration switch
857847
{
@@ -861,23 +851,25 @@ bool TryPopulateBuildConfigurations(
861851
};
862852

863853
consolidatedBuildConfiguration =
864-
new( consolidatedBuildObjectName, consolidatedBuildConfigurationName, defaultBuildBranch, defaultBranchParameter, vcsRootId )
865-
{
866-
SnapshotDependencies = dependencies.ToArray(), BuildTriggers = consolidatedBuildTriggers
867-
};
854+
new TeamCityBuildConfiguration(
855+
consolidatedBuildObjectName,
856+
consolidatedBuildConfigurationName,
857+
defaultBuildBranch,
858+
defaultBranchParameter,
859+
vcsRootId ) { SnapshotDependencies = dependencies.ToArray(), BuildTriggers = consolidatedBuildTriggers };
868860

869861
DockerSpec? dockerSpec = null;
870862

871863
if ( product.UseDocker )
872864
{
873865
dockerSpec = new DockerSpec( $"{product.ProductNameWithoutDot}-{product.ProductFamily.Version}" );
874866
}
875-
867+
876868
var nuGetBuildSteps =
877869
new TeamCityBuildStep[] { new TeamCityEngineeringBuildBuildStep( configuration, false, dockerSpec ) };
878870

879871
// The default branch is the same as for public build of any other project - see the build configuration of a regular project.
880-
nuGetBuildConfiguration = new(
872+
nuGetBuildConfiguration = new TeamCityBuildConfiguration(
881873
nuGetBuildObjectName,
882874
nuGetBuildConfigurationName,
883875
defaultBranch,
@@ -977,8 +969,7 @@ bool TryPopulateBuildConfigurations(
977969
// The nightly build is done on the develop branch to find issues early and to prepare for the deployment.
978970
// The manually triggered build is done on the release branch to allow for deployment without merge freeze.
979971
// Any successful build of the same commit done on the develop branch is reused by TeamCity when deploying from the release branch.
980-
BranchFilter = $"+:{defaultBranch}",
981-
Parameters = [new TeamCityBuildConfigurationParameter( "DefaultBranch", defaultBranch )]
972+
BranchFilter = $"+:{defaultBranch}", Parameters = [new TeamCityBuildConfigurationParameter( "DefaultBranch", defaultBranch )]
982973
}
983974
],
984975
MarkNuGetObjectId( publicBuildObjectName ),
@@ -1038,10 +1029,7 @@ TeamCitySourceDependency CreateSourceDependencyFromDefinition( DependencyDefinit
10381029
$"Bump{bumpedProjectId.Split( '_' ).Last()}",
10391030
$"Bump version of {bumpedProjectName}",
10401031
"bump",
1041-
areCustomArgumentsAllowed: true )
1042-
{
1043-
WorkingDirectory = $"source-dependencies/{bumpedProjectName}"
1044-
} );
1032+
areCustomArgumentsAllowed: true ) { WorkingDirectory = $"source-dependencies/{bumpedProjectName}" } );
10451033

10461034
consolidatedVersionBumpSourceDependencies.Add( CreateSourceDependencyFromDefinition( dependencyDefinition ) );
10471035

@@ -1123,10 +1111,10 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
11231111
if ( dependencyBranch == null )
11241112
{
11251113
context.Console.WriteError( $"The '{projectDependencyDefinition.Name}' doesn't have the required branch set for {command}ing." );
1126-
1114+
11271115
return false;
11281116
}
1129-
1117+
11301118
parameters.Add(
11311119
new TeamCityTextBuildConfigurationParameterBase(
11321120
projectDependencyDefinition.VcsRepository.DefaultBranchParameter,
@@ -1143,10 +1131,7 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
11431131
$"{commandName} deployment of {project.Name}",
11441132
command,
11451133
"--configuration Public --buildNumber %build.number% --buildType %system.teamcity.buildType.id% --use-local-dependencies",
1146-
areCustomArgumentsAllowed: true )
1147-
{
1148-
WorkingDirectory = $"source-dependencies/{project.Name}"
1149-
} );
1134+
areCustomArgumentsAllowed: true ) { WorkingDirectory = $"source-dependencies/{project.Name}" } );
11501135

11511136
// Dependencies outside of the product family are fetched from the artifacts.
11521137
if ( buildConfigurationsById.TryGetValue( $"{project.Id}_{publicBuildObjectName}", out var publicBuildConfiguration ) )
@@ -1178,7 +1163,7 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
11781163
var artifactRules =
11791164
$"+:{dependencyPrivateArtifactsDirectory}/{dependencyName}.version.props=>source-dependencies/{project.Name}/dependencies/{dependencyName}";
11801165

1181-
snapshotDependencies.Add( new( dependencyConfigurationId, true, artifactRules ) );
1166+
snapshotDependencies.Add( new TeamCitySnapshotDependency( dependencyConfigurationId, true, artifactRules ) );
11821167
}
11831168
}
11841169
}
@@ -1195,13 +1180,13 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
11951180
{
11961181
WorkingDirectory = $"source-dependencies/{consolidatedProjectName}"
11971182
} );
1198-
1183+
11991184
var branch = getBranch( product.DependencyDefinition );
12001185

12011186
if ( branch == null )
12021187
{
12031188
context.Console.WriteError( $"The consolidated project doesn't have the required branch set for {command}ing." );
1204-
1189+
12051190
return false;
12061191
}
12071192

@@ -1250,15 +1235,14 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
12501235
// Here we include all Public builds which will cause download of all artifacts.
12511236
var nuGetPublicDeploymentDependencies =
12521237
nuGetPublicBuildDependencies
1253-
.Select(
1254-
d => new TeamCitySnapshotDependency(
1255-
d.ObjectId.Replace( $"_{publicBuildObjectName}", $"_{publicDeploymentObjectName}", StringComparison.Ordinal ),
1256-
true ) )
1238+
.Select( d => new TeamCitySnapshotDependency(
1239+
d.ObjectId.Replace( $"_{publicBuildObjectName}", $"_{publicDeploymentObjectName}", StringComparison.Ordinal ),
1240+
true ) )
12571241
.Concat( nuGetPublicBuildDependencies )
1258-
.Append( new( publicNuGetBuildCiId, true, nuGetBuildArtifactRules ) );
1242+
.Append( new TeamCitySnapshotDependency( publicNuGetBuildCiId, true, nuGetBuildArtifactRules ) );
12591243

12601244
nuGetConfigurations.Add(
1261-
new(
1245+
new TeamCityBuildConfiguration(
12621246
MarkNuGetObjectId( publicDeploymentObjectName ),
12631247
publicDeploymentName,
12641248
deploymentBranch,
@@ -1286,14 +1270,14 @@ bool TryAddPreOrPostDeploymentBuildConfiguration(
12861270
publicDeploymentBuildConfigurationIds
12871271
.Concat( publicDeploymentDependants )
12881272
.Select( c => new TeamCitySnapshotDependency( c, true ) )
1289-
.Append( new( publicConsolidatedBuildCiId, true ) )
1290-
.Append( new( publicNuGetDeploymentCiId, true ) );
1273+
.Append( new TeamCitySnapshotDependency( publicConsolidatedBuildCiId, true ) )
1274+
.Append( new TeamCitySnapshotDependency( publicNuGetDeploymentCiId, true ) );
12911275

12921276
tcConfigurations.Add(
12931277
new TeamCityBuildConfiguration(
12941278
publicDeploymentObjectName,
12951279
$"4. {publicDeploymentName}",
1296-
1280+
12971281
// We should use deploymentBranch here, but TeamCity doesn't support parameterized branches in snapshot dependencies.
12981282
defaultBranch,
12991283
defaultBranchParameter,

src/PostSharp.Engineering.BuildTools/Dependencies/Definitions/PostSharpDependencies.V2025_0.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public static class V2025_0
1717
private class PostSharpDependencyDefinition : DependencyDefinition
1818
{
1919
private static readonly TeamCityProjectId _teamCityProjectId = new(
20-
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}", "PostSharpGitHub" );
20+
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}",
21+
"PostSharpGitHub" );
2122

2223
private static readonly string _distributionBuildId = $"{_teamCityProjectId}_BuildDistribution";
2324

@@ -33,7 +34,7 @@ public PostSharpDependencyDefinition()
3334
new ConfigurationSpecific<string>( "not-used", _distributionBuildId, "not-used" ),
3435
null,
3536
null,
36-
TeamCityHelper.TeamCityCloudTokenEnvironmentVariableName,
37+
EnvironmentVariableNames.TeamCityToken,
3738
TeamCityHelper.TeamCityCloudUrl ),
3839
false )
3940
{

src/PostSharp.Engineering.BuildTools/Dependencies/Definitions/PostSharpDependencies.V2025_1.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public static class V2025_1
1717
private class PostSharpDependencyDefinition : DependencyDefinition
1818
{
1919
private static readonly TeamCityProjectId _teamCityProjectId = new(
20-
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}", "PostSharpGitHub" );
20+
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}",
21+
"PostSharpGitHub" );
2122

2223
private static readonly string _distributionBuildId = $"{_teamCityProjectId}_BuildDistribution";
2324

@@ -33,7 +34,7 @@ public PostSharpDependencyDefinition()
3334
new ConfigurationSpecific<string>( "not-used", _distributionBuildId, "not-used" ),
3435
null,
3536
null,
36-
TeamCityHelper.TeamCityCloudTokenEnvironmentVariableName,
37+
EnvironmentVariableNames.TeamCityToken,
3738
TeamCityHelper.TeamCityCloudUrl ),
3839
false )
3940
{

src/PostSharp.Engineering.BuildTools/Dependencies/Definitions/PostSharpDependencies.V2026_0.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ public static class V2026_0
1717
private class PostSharpDependencyDefinition : DependencyDefinition
1818
{
1919
private static readonly TeamCityProjectId _teamCityProjectId = new(
20-
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}", "PostSharpGitHub" );
20+
$"PostSharpGitHub_{_projectName}{Family.VersionWithoutDots}",
21+
"PostSharpGitHub" );
2122

2223
private static readonly string _distributionBuildId = $"{_teamCityProjectId}_BuildDistribution";
2324

@@ -33,7 +34,7 @@ public PostSharpDependencyDefinition()
3334
new ConfigurationSpecific<string>( "not-used", _distributionBuildId, "not-used" ),
3435
null,
3536
null,
36-
TeamCityHelper.TeamCityCloudTokenEnvironmentVariableName,
37+
EnvironmentVariableNames.TeamCityToken,
3738
TeamCityHelper.TeamCityCloudUrl ),
3839
false )
3940
{

src/PostSharp.Engineering.BuildTools/EnvironmentVariableNames.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ namespace PostSharp.Engineering.BuildTools;
44

55
public static class EnvironmentVariableNames
66
{
7-
public const string TeamCityOnPremToken = "TEAMCITY_TOKEN";
8-
public const string TeamCityCloudToken = "TEAMCITY_CLOUD_TOKEN";
7+
public const string TeamCityToken = "TEAMCITY_CLOUD_TOKEN";
98
public const string VsMarketplaceAccessToken = "VS_MARKETPLACE_ACCESS_TOKEN";
109
public const string GitHubToken = "GITHUB_TOKEN";
1110
public const string IsPostSharpOwned = "IS_POSTSHARP_OWNED";
@@ -25,8 +24,7 @@ public static class EnvironmentVariableNames
2524

2625
public static readonly string[] All =
2726
[
28-
TeamCityOnPremToken,
29-
TeamCityCloudToken,
27+
TeamCityToken,
3028
VsMarketplaceAccessToken,
3129
GitHubToken,
3230
IsPostSharpOwned,
@@ -44,5 +42,4 @@ public static class EnvironmentVariableNames
4442
TypeSenseApiKey,
4543
AzIdentityUserName
4644
];
47-
4845
}

0 commit comments

Comments
 (0)