in tool/TeamCity.Docker/TeamCityKotlinSettingsGenerator.cs [370:492]
private IEnumerable<string> CreateImageValidationConfig(string buildTypeId, IEnumerable<Image> allImages, string imagePostfix) {
yield return $"object {buildTypeId}: BuildType(" + "{";
yield return "\t name = \"Validation of Size Regression - Staging Docker Images (Windows / Linux)\"";
yield return $"\t {_buildNumberPattern}";
// VCS Root Is needed in order to launch automation framework
yield return String.Join('\n',
"\t vcs {",
"\t\t root(TeamCityDockerImagesRepo)",
"\t }"
);
// Trigger is needed to execute the image once they've been published into Dockerhub
yield return String.Join('\n',
"\n\t triggers {",
"\t\t // Execute the build once the images are available within %deployRepository%",
"\t\t finishBuildTrigger {",
"\t\t\t buildType = \"${PublishHubVersion.publish_hub_version.id}\"",
"\t\t\t // if filter won't be specified, only <default> branch would be included",
"\t\t\t branchFilter = \"\"\"",
"\t\t\t\t +:development/*",
"\t\t\t\t +:release/*",
"\t\t\t \"\"\".trimIndent()",
"\t\t }",
"\t }"
);
// Parameters are needed in order to prevent unnecessarry dependency from an inherited parameter
yield return String.Join('\n',
"\n\t params {",
"\t\t // -- inherited parameter, removed in debug purposes",
"\t\t param(\"dockerImage.teamcity.buildNumber\", \"-\")",
"\t }"
);
// -- Declare a set of images that we'd need to iterate over
// -- containing elements for Kotlin hashmap declaration: ...
// -- ... <Image Static Name> - <Image Name with Parameter References>
List<string> validationHashmapEntries = new List<string>();
foreach (var image in allImages) {
var newRepo = $"{DeployRepositoryName}{image.File.ImageId}{imagePostfix}";
var newRepoTag = $"{newRepo}:{image.File.Tags.First()}";
// Add as as Kotlin DSL list element
// -- hashmap: <name>, <parameter reference domain name>
validationHashmapEntries.Add($"\"{image.File.ImageId}-{image.File.Tags.First()}\" to \"{newRepoTag}\"");
}
// -- Create declaration of HashMap within DSL which will be used for generation of step "{ ... }" blocks
yield return String.Join('\n',
"\n\t val targetImages: HashMap<String, String> = hashMapOf(",
// concatenate previously created hashmap entries for the declaration within DSL
String.Join(", \n\t\t", validationHashmapEntries),
"\t )"
);
// Generate steps in order to validate the images within the list above
yield return String.Join('\n',
"\n\t steps {",
"\t\t targetImages.forEach { (imageVerificationStepId, imageDomainName) ->",
"\t\t // Generate validation for each image fully-qualified domain name (FQDN)",
"\t\t gradle {",
"\t\t\t name = \"Image Verification - $imageVerificationStepId\"",
// "%docker.buildRepository.login% %docker.stagingRepository.token%" are defined within TeamCity server
"\t\t\t tasks = \"clean build run --args=\\\"validate $imageDomainName %docker.stagingRepository.login% %docker.stagingRepository.token%\\\"\"",
"\t\t\t workingDir = \"tool/automation/framework\"",
"\t\t\t buildFile = \"build.gradle\"",
"\t\t\t jdkHome = \"%env.JDK_11_x64%\"",
"\t\t\t executionMode = BuildStep.ExecutionMode.ALWAYS",
"\t\t\t }",
"\t\t }",
"\t }"
);
// Generate failure conditions
yield return String.Join('\n',
"\n\t failureConditions {",
"\t\t // Failed in case the validation via framework didn't succeed",
"\t\t failOnText {",
"\t\t\t conditionType = BuildFailureOnText.ConditionType.CONTAINS",
"\t\t\t pattern = \"DockerImageValidationException\"",
"\t\t\t failureMessage = \"Docker Image validation have failed\"",
"\t\t\t // allows the steps to continue running even in case of one problem",
"\t\t\t reportOnlyFirstMatch = false",
"\t\t }",
"\t }"
);
// Generate requirements
yield return String.Join('\n',
"\n\t requirements {",
"\t\t exists(\"env.JDK_11\")",
"\t\t // Images are validated mostly via DockerHub REST API. In case ...",
"\t\t // ... Docker agent will be used, platform-compatibility must be addressed, ...",
"\t\t // ... especially in case of Windows images.",
"\t\t contains(\"teamcity.agent.jvm.os.name\", \"Linux\")",
"\t }"
);
// Generate build features
yield return String.Join('\n',
"\n\t features {",
"\t\t dockerSupport {",
"\t\t\t cleanupPushedImages = true",
"\t\t\t loginToRegistry = on {",
"\t\t\t dockerRegistryId = \"PROJECT_EXT_774,PROJECT_EXT_315\"",
"\t\t\t }",
"\t\t }",
"\t }"
);
// Generation of build configuration is deprecated, thus no dependencies are set.
yield return String.Join('\n',
"\n\t dependencies {",
"\t}"
);
yield return "})";
yield return string.Empty;
}