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 (#8685) (#15613)

* 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

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored Aug 24, 2023
1 parent f35c1bb commit 87a908f
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 7 deletions.
3 changes: 3 additions & 0 deletions .changelog/8685.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:none

```
1 change: 1 addition & 0 deletions .teamcity/components/build_config_package.kt
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
23 changes: 23 additions & 0 deletions .teamcity/components/generated/build_components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,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
5 changes: 3 additions & 2 deletions .teamcity/components/generated/project.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const val providerName = "google"
// Google 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(environment: String, manualVcsRoot: AbsoluteId, branchRef: String, configuration: ClientConfiguration) : Project {
fun Google(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 @@ -28,9 +28,10 @@ fun Google(environment: String, manualVcsRoot: AbsoluteId, branchRef: String, co
postSweeperConfig.addTrigger(triggerConfig)
}


return Project{

description = projDescription

// Register build configs in the project
buildType(preSweeperConfig)
packageConfigs.forEach { buildConfiguration ->
Expand Down
1 change: 1 addition & 0 deletions .teamcity/components/sweepers.kt
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
3 changes: 2 additions & 1 deletion .teamcity/settings.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,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(environment, manualVcsRoot, branchRef, clientConfig))
project(Google(environment, projDescription, manualVcsRoot, branchRef, clientConfig))
6 changes: 3 additions & 3 deletions .teamcity/tests/generated/configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import useTeamCityGoTest
class ConfigurationTests {
@Test
fun buildShouldFailOnError() {
val project = Google("default", testVcsRootId(), "refs/heads/main", testConfiguration())
val project = Google("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("default", testVcsRootId(), "refs/heads/main",testConfiguration())
val project = Google("default", "description", testVcsRootId(), "refs/heads/main", testConfiguration())
project.buildTypes.forEach{ bt ->
var exists = false
bt.features.items.forEach { f ->
Expand All @@ -42,7 +42,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
2 changes: 1 addition & 1 deletion .teamcity/tests/generated/vcs_roots.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.junit.Test
class VcsTests {
@Test
fun buildsHaveCleanCheckOut() {
val project = Google("default", testVcsRootId(), "refs/heads/main", testConfiguration())
val project = Google("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 87a908f

Please sign in to comment.