Skip to content

Commit

Permalink
TeamCity: Usability improvements : tag builds to distinguish nightly …
Browse files Browse the repository at this point in the history
…builds vs ad hoc builds, add project descriptions (GoogleCloudPlatform#8685)

* Add ability to tag TeamCity builds based on whether they're automated or ad-hoc. Nightly builds tagged with the date.

* Add ability to set project descriptions using a context parameter

* Refactor how date is formatted, to avoid problem where TeamCity interprets `%Y-%` as interpolating a `Y-` parameter

* Remove use of `TRIGGERED_BY`; value in build didn't match UI and isn't useful

* Update tag for nightly test builds to be static/consistent
  • Loading branch information
SarahFrench authored and joelkattapuram committed Sep 20, 2023
1 parent 256098b commit 854d1d1
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class packageDetails(packageName: String, displayName: String, providerName: Str

steps {
SetGitCommitBuildId()
TagBuildToIndicatePurpose()
ConfigureGoEnv()
DownloadTerraformBinary()
RunAcceptanceTests()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ fun BuildSteps.SetGitCommitBuildId() {
})
}

fun BuildSteps.TagBuildToIndicatePurpose() {
step(ScriptBuildStep {
name = "Set build tag to indicate if build is run automatically or manually triggered"
scriptContent = """
#!/bin/bash
TRIGGERED_BY_USERNAME=%teamcity.build.triggeredBy.username%

if [[ "${'$'}TRIGGERED_BY_USERNAME" = "n/a" ]] ; then
echo "Build was triggered as part of automated testing. We know this because the `triggeredBy.username` value was `n/a`, value: ${'$'}{TRIGGERED_BY_USERNAME}"
TAG="nightly-test"
echo "##teamcity[addBuildTag '${'$'}{TAG}']"
else
echo "Build wasn't triggered as part of automated testing. We know this because the `triggeredBy.username` value was not `n/a`, value: ${'$'}{TRIGGERED_BY_USERNAME}"
TAG="one-off-build"
echo "##teamcity[addBuildTag '${'$'}{TAG}']"
fi
""".trimIndent()
// ${'$'} is required to allow creating a script in TeamCity that contains
// parts like ${GIT_HASH_SHORT} without having Kotlin syntax issues. For more info see:
// https://youtrack.jetbrains.com/issue/KT-2425/Provide-a-way-for-escaping-the-dollar-sign-symbol-in-multiline-strings-and-string-templates
})
}

fun BuildSteps.DownloadTerraformBinary() {
// https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip
var terraformUrl = "https://releases.hashicorp.com/terraform/%env.TERRAFORM_CORE_VERSION%/terraform_%env.TERRAFORM_CORE_VERSION%_linux_amd64.zip"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const val providerName = "google<%= "-" + version unless version == 'ga' -%>"
// Google<%= version.capitalize unless version == 'ga' -%> returns an instance of Project,
// which has multiple build configurations defined within it.
// See https://teamcity.jetbrains.com/app/dsl-documentation/root/project/index.html
fun Google<%= version.capitalize unless version == 'ga' -%>(environment: String, manualVcsRoot: AbsoluteId, branchRef: String, configuration: ClientConfiguration) : Project {
fun Google<%= version.capitalize unless version == 'ga' -%>(environment: String, projDescription: String, manualVcsRoot: AbsoluteId, branchRef: String, configuration: ClientConfiguration) : Project {

// Create build configs for each package defined in packages.kt and services.kt files
val allPackages = packages + services
Expand All @@ -29,9 +29,10 @@ fun Google<%= version.capitalize unless version == 'ga' -%>(environment: String,
postSweeperConfig.addTrigger(triggerConfig)
}


return Project{

description = projDescription

// Register build configs in the project
buildType(preSweeperConfig)
packageConfigs.forEach { buildConfiguration ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class sweeperDetails() {

steps {
SetGitCommitBuildId()
TagBuildToIndicatePurpose()
ConfigureGoEnv()
DownloadTerraformBinary()
RunSweepers(sweeperName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ var manualVcsRoot = DslContext.settingsRootId
// Values of these context parameters change configuration code behaviour.
var environment = DslContext.getParameter("environment", "default")
var branchRef = DslContext.getParameter("branch", "refs/heads/main")
var projDescription = DslContext.getParameter("description", "")

var clientConfig = ClientConfiguration(custId, org, org2, billingAccount, billingAccount2, masterBillingAccount, credentials, project, orgDomain, projectNumber, region, serviceAccount, zone, firestoreProject, identityUser)

// This is the entry point of the code in .teamcity/
// See https://teamcity.jetbrains.com/app/dsl-documentation/root/project.html
project(Google<%= version.capitalize unless version == 'ga' -%>(environment, manualVcsRoot, branchRef, clientConfig))
project(Google<%= version.capitalize unless version == 'ga' -%>(environment, projDescription, manualVcsRoot, branchRef, clientConfig))
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import useTeamCityGoTest
class ConfigurationTests {
@Test
fun buildShouldFailOnError() {
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", testVcsRootId(), "refs/heads/main", testConfiguration())
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", "description", testVcsRootId(), "refs/heads/main", testConfiguration())
project.buildTypes.forEach { bt ->
assertTrue("Build '${bt.id}' should fail on errors!", bt.failureConditions.errorMessage)
}
}

@Test
fun buildShouldHaveGoTestFeature() {
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", testVcsRootId(), "refs/heads/main",testConfiguration())
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", "description", testVcsRootId(), "refs/heads/main", testConfiguration())
project.buildTypes.forEach{ bt ->
var exists = false
bt.features.items.forEach { f ->
Expand All @@ -44,7 +44,7 @@ class ConfigurationTests {
// Once I have the ability to run tests I'll address this - writing new tests for the new config
// @Test
// fun buildShouldHaveTrigger() {
// val project = Google("default", testVcsRootId(), "refs/heads/main", testConfiguration())
// val project = Google("default", "description", testVcsRootId(), "refs/heads/main", testConfiguration())
// var exists = false
// project.buildTypes.forEach{ bt ->
// bt.triggers.items.forEach { t ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.junit.Test
class VcsTests {
@Test
fun buildsHaveCleanCheckOut() {
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", testVcsRootId(), "refs/heads/main", testConfiguration())
val project = Google<%= version.capitalize unless version == 'ga' -%>("default", "description", testVcsRootId(), "refs/heads/main", testConfiguration())
project.buildTypes.forEach { bt ->
assertTrue("Build '${bt.id}' doesn't use clean checkout", bt.vcs.cleanCheckout)
}
Expand Down

0 comments on commit 854d1d1

Please sign in to comment.