in tool/TeamCity.Docker/TeamCityKotlinSettingsGenerator.cs [58:200]
public void Generate(IGraph<IArtifact, Dependency> graph)
{
if (graph == null) throw new ArgumentNullException(nameof(graph));
if (string.IsNullOrWhiteSpace(_options.TeamCityDslPath))
{
return;
}
if (string.IsNullOrWhiteSpace(_options.TeamCityBuildConfigurationId))
{
return;
}
var buildGraphResult = _buildGraphsFactory.Create(graph);
if (buildGraphResult.State == Result.Error)
{
return;
}
var names = new Dictionary<string, int>();
var buildGraphs = (
from buildGraph in buildGraphResult.Value
let weight = buildGraph.Nodes.Select(i => i.Value.Weight.Value).Sum()
let nodesDescription = _nodesDescriptionsFactory.Create(buildGraph.Nodes)
orderby nodesDescription.State != Result.Error ? nodesDescription.Value.Name : string.Empty
select new { graph = buildGraph, weight })
.ToList();
var localBuildTypes = new List<string>();
var hubBuildTypes = new List<string>();
var allImages = buildGraphs
.SelectMany(i => i.graph.Nodes.Select(j => j.Value).OfType<Image>())
.Where(i => i.File.Repositories.Any())
// ARM-based Docker Images Are not currently supported by TeamCity.
.Where(i => IsArmBasedImageBuildEnabled || i.File.Tags.First().IndexOf("arm", StringComparison.OrdinalIgnoreCase) < 0)
.ToList();
// Build and push on local registry
var buildAndPushLocalBuildTypes = new List<string>();
foreach (var buildGraph in buildGraphs)
{
var path = _buildPathProvider.GetPath(buildGraph.graph).ToList();
var description = _nodesDescriptionsFactory.Create(path);
var name = description.State != Result.Error
? description.Value.Name
: string.Join("", path.Select(i => i.Value).OfType<Image>().Select(i => i.File.Platform).Distinct().OrderBy(i => i));
if (names.TryGetValue(name, out var counter))
{
name = $"{name} {++counter}";
}
else
{
names[name] = 1;
}
var buildTypeId = $"push_local_{NormalizeName(name)}";
var onPause = !path.Select(i => i.Value).OfType<Image>().Any(i => i.File.Repositories.Any());
localBuildTypes.Add(buildTypeId);
if (!onPause)
{
buildAndPushLocalBuildTypes.Add(buildTypeId);
}
graph.TryAddNode(AddFile(buildTypeId, GenerateBuildAndPushType(buildTypeId, name, path, buildGraph.weight, onPause)), out _);
}
// Publish on staging registry
var localPublishGroups =
from image in allImages
from tag in image.File.Tags.Skip(1)
group image by tag;
var publishLocalId = "publish_local";
localBuildTypes.Add(publishLocalId);
graph.TryAddNode(AddFile(publishLocalId, CreateManifestBuildConfiguration(publishLocalId, BuildRepositoryName, "Publish", localPublishGroups.ToList(), BuildImagePostfix, true, buildAndPushLocalBuildTypes.ToArray())), out _);
// Push on docker hub
var pushOnHubBuildTypes = new List<string>();
var platforms = allImages.Select(i => i.File.Platform).Distinct();
foreach (var platform in platforms)
{
var buildTypeId = $"push_hub_{NormalizeName(platform)}";
pushOnHubBuildTypes.Add(buildTypeId);
graph.TryAddNode(AddFile(buildTypeId, CreatePushBuildConfiguration(buildTypeId, platform, allImages, publishLocalId)), out _);
}
hubBuildTypes.AddRange(pushOnHubBuildTypes);
// Publish on docker hub
var publishOnHubBuildTypes = new List<string>();
var publishOnHubGroups =
from grp in
from image in allImages
from tag in image.File.Tags.Skip(1)
group image by tag
group grp by grp.Key.ToLowerInvariant() == "latest" ? "latest" : "version";
foreach (var group in publishOnHubGroups)
{
string publishToDockerhubBuildId = $"publish_hub_{NormalizeName(group.Key)}";
publishOnHubBuildTypes.Add(publishToDockerhubBuildId);
graph.TryAddNode(AddFile(publishToDockerhubBuildId,CreateManifestBuildConfiguration(publishToDockerhubBuildId,
DeployRepositoryName, $"Publish as {group.Key}",
group.ToList(), string.Empty, false,
pushOnHubBuildTypes.ToArray())), out _);
}
hubBuildTypes.AddRange(publishOnHubBuildTypes);
// Validation of Docker Image Size
const string validationBuildTypeId = "image_validation";
graph.TryAddNode(AddFile(validationBuildTypeId, CreateImageValidationConfig(validationBuildTypeId, allImages, BuildImagePostfix)), out _);
localBuildTypes.Add(validationBuildTypeId);
// Local project
// ReSharper disable once UseObjectOrCollectionInitializer
var lines = new List<string>();
lines.Add("object LocalProject : Project({");
lines.Add("\t name = \"Staging registry\"");
foreach (var buildType in localBuildTypes.Distinct())
{
lines.Add($"\t buildType({NormalizeFileName(buildType)}.{buildType})");
}
lines.Add("})");
graph.TryAddNode(AddFile("LocalProject", lines), out _);
lines.Clear();
// Hub project
lines.Add("object HubProject : Project({");
lines.Add("\t name = \"Docker hub\"");
foreach (var buildType in hubBuildTypes.Distinct())
{
lines.Add($"\t buildType({NormalizeFileName(buildType)}.{buildType})");
}
lines.Add("})");
graph.TryAddNode(AddFile("HubProject", lines), out _);
lines.Clear();
}