diff --git a/.teamcity/README b/.teamcity/README deleted file mode 100644 index 056eb30c07c7e1..00000000000000 --- a/.teamcity/README +++ /dev/null @@ -1,7 +0,0 @@ -The archive contains settings for a TeamCity project. - -To edit the settings in IntelliJ Idea, open the pom.xml and -select the 'Open as a project' option. - -If you want to move this dsl to version control, save it in the -.teamcity directory. \ No newline at end of file diff --git a/.teamcity/_self/bashNodeScript.kt b/.teamcity/_self/bashNodeScript.kt deleted file mode 100644 index ec218702cac969..00000000000000 --- a/.teamcity/_self/bashNodeScript.kt +++ /dev/null @@ -1,40 +0,0 @@ -package _self - -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildSteps -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep - -/** - * A default version of the "script" step with node, bash, and docker configured as expected. - * - * To use, add `import _self.bashNodeScript`, and then reference exactly like a script step: - * ``` - * steps { - * bashNodeScript { - * name = "Hello world!" - * scriptContent = """ - * echo "Hello world!" - * """ - * } - * } - * ``` - */ -fun BuildSteps.bashNodeScript(init: ScriptBuildStep.() -> Unit): ScriptBuildStep { - val result = ScriptBuildStep(init) - result.scriptContent = """ - #!/bin/bash - # Set bash options. - set -o errexit - set -o nounset - set -o pipefail - - # Existing script content set by caller: - ${result.scriptContent} - """.trimIndent() - - result.dockerImagePlatform = ScriptBuildStep.ImagePlatform.Linux - result.dockerPull = true - result.dockerImage = result.dockerImage ?: "%docker_image%" - result.dockerRunParameters = result.dockerRunParameters ?: "-u %env.UID%" - step(result) - return result -} diff --git a/.teamcity/_self/lib/customBuildType/E2EBuildType.kt b/.teamcity/_self/lib/customBuildType/E2EBuildType.kt deleted file mode 100644 index 59364a291bf296..00000000000000 --- a/.teamcity/_self/lib/customBuildType/E2EBuildType.kt +++ /dev/null @@ -1,230 +0,0 @@ -package _self.lib.customBuildType - -import Settings -import _self.bashNodeScript -import _self.lib.utils.mergeTrunk -import jetbrains.buildServer.configs.kotlin.v2019_2.AbsoluteId -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildSteps -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType -import jetbrains.buildServer.configs.kotlin.v2019_2.ParametrizedWithType -import jetbrains.buildServer.configs.kotlin.v2019_2.Project -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildFeatures -import jetbrains.buildServer.configs.kotlin.v2019_2.Triggers -import jetbrains.buildServer.configs.kotlin.v2019_2.Dependencies -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.PullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.notifications -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.dockerCommand -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs - -/** - * This class provides a template to easily create end-to-end build configurations. - * - * To use, import then invoke the `E2EBuildType` class instance with the parameters - * required, as outlined in the class definition. - * - * @param buildId Human-readable value, single string. - * @param buildUuid UUID value generated by TeamCity and obtainable via the web UI. - * Refer to https://fieldguide.automattic.com/quality-engineering-in-calypso/running-tests/. - * @param buildName Human-readable display name. Primarily used in the GUI. - * @param buidDescription Human-readable description. Primarily used in the GUI. - * @param concurrentBuilds Set the number of simultaneous builds. Defaults to 0 (infinite). - * @param getCalypsoLiveURL String containing the commands to be run in order to obtain the live URL. Only used for Calypso E2E. - * @param testGroup String corresponding to an existing group defined for Jest Runner Group. - * @param buildParams Environment variables and other parameters to set for the build. - * @param buildFeatures Features to enable on top of the default feature set (perfmon). - * @param enableCommitStatusPublisher Boolean toggle to enable the commit status publisher in Build Features. - * @param buildTriggers Rules to trigger the build. By default, no triggers are defined. - * @param buildDepedencies If the build configuration depends on another existing build configuration, define it here. - */ -open class E2EBuildType( - var buildId: String, - var buildUuid: String, - var buildName: String, - var buildDescription: String, - var concurrentBuilds: Int = 0, - var getCalypsoLiveURL: String = "", - var testGroup: String, - var buildParams: ParametrizedWithType.() -> Unit = {}, - var buildFeatures: BuildFeatures.() -> Unit, - var enableCommitStatusPublisher: Boolean = false, - var buildTriggers: Triggers.() -> Unit = {}, - var buildDependencies: Dependencies.() -> Unit = {}, - var addWpcomVcsRoot: Boolean = false, - var buildSteps: BuildSteps.() -> Unit = {} - -): BuildType() { - init { - val concurrentBuilds = concurrentBuilds - val getCalypsoLiveURL = getCalypsoLiveURL - val testGroup = testGroup - val buildParams = buildParams - val buildFeatures = buildFeatures - val enableCommitStatusPublisher = enableCommitStatusPublisher - val buildTriggers = buildTriggers - val buildDependencies = buildDependencies - val params = params - val buildSteps = buildSteps - - id( buildId ) - uuid = buildUuid - name = buildName - description = buildDescription - maxRunningBuilds = concurrentBuilds - - artifactRules = """ - logs => logs.tgz - screenshots => screenshots - trace => trace - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - param("env.NODE_CONFIG_ENV", "test") - param("env.PLAYWRIGHT_BROWSERS_PATH", "0") - param("env.HEADLESS", "true") - param("env.LOCALE", "en") - param("env.DEBUG", "") - buildParams() - } - - steps { - // IMPORTANT! This step MUST match what the docker image does. If trunk - // is merged when building the docker image, it must also be merged - // to run the tests, or they may not be compatible. See the "mergeTrunk" - // step in BuildDockerImage in WebApp.kt. - mergeTrunk( skipIfConflict = true ) - - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Install deps - yarn workspaces focus wp-e2e-tests @automattic/calypso-e2e - - # Decrypt secrets - # Must do before build so the secrets are in the dist output - E2E_SECRETS_KEY="%E2E_SECRETS_ENCRYPTION_KEY_CURRENT%" yarn workspace @automattic/calypso-e2e decrypt-secrets - - # Build packages - yarn workspace @automattic/calypso-e2e build - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Run tests" - scriptContent = """ - # Configure bash shell. - shopt -s globstar - set -x - - # For Calypso E2E build configurations, the URL environment variable - # is computed and exported by a script that must be executed at runtime. - # Unset variables throw an error, so we initialize CALYPSO_LIVE_URL as empty first. - export CALYPSO_LIVE_URL='' - - # This script, if provided, will ultimately sets the CALYPSO_LIVE_URL environment variable. - $getCalypsoLiveURL - - # We only want to override the Calypso URL if we have a live one to use! - if [[ -n ${'$'}CALYPSO_LIVE_URL ]]; then - export CALYPSO_BASE_URL=${'$'}CALYPSO_LIVE_URL - fi - - # Enter testing directory. - cd test/e2e - mkdir temp - - # Disable exit on error to support retries. - set +o errexit - - # Run suite. - xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=$testGroup - - # Restore exit on error. - set -o errexit - - # Retry failed tests only. - RETRY_COUNT=1 xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=$testGroup --onlyFailures - """ - dockerImage = "%docker_image_e2e%" - dockerRunParameters = "-u %env.UID% --shm-size=4g" - } - - bashNodeScript { - name = "Collect results" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - set -x - - mkdir -p screenshots - find test/e2e/results -type f \( -iname \*.webm -o -iname \*.png \) -print0 | xargs -r -0 mv -t screenshots - - mkdir -p logs - find test/e2e/results -name '*.log' -print0 | xargs -r -0 mv -t logs - - mkdir -p trace - find test/e2e/results -name '*.zip' -print0 | xargs -r -0 mv -t trace - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - buildSteps() - } - - features { - perfmon { - } - - if (enableCommitStatusPublisher) { - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } - - buildFeatures() - } - - // By default, no triggers are defined for this template class. - triggers {buildTriggers()} - - dependencies.buildDependencies() - - failureConditions { - executionTimeoutMin = 20 - // Don't fail if the runner exists with a non zero code. This allows a build to pass if the failed tests have been muted previously. - nonZeroExitCode = false - - // Support retries using the --onlyFailures flag in Jest. - supportTestRetry = true - - // Fail if the number of passing tests is 50% or less than the last build. This will catch the case where the test runner crashes and no tests are run. - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.PASSED_TEST_COUNT - threshold = 50 - units = BuildFailureOnMetric.MetricUnit.PERCENTS - comparison = BuildFailureOnMetric.MetricComparison.LESS - compareTo = build { - buildRule = lastSuccessful() - } - } - } - } -} diff --git a/.teamcity/_self/lib/utils/E2EBuildLibrary.kt b/.teamcity/_self/lib/utils/E2EBuildLibrary.kt deleted file mode 100644 index 5f8f1cff9f8294..00000000000000 --- a/.teamcity/_self/lib/utils/E2EBuildLibrary.kt +++ /dev/null @@ -1,129 +0,0 @@ -package _self.lib.utils - -import _self.bashNodeScript -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildSteps -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.ParametrizedWithType -import jetbrains.buildServer.configs.kotlin.v2019_2.FailureConditions -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange - - -fun BuildSteps.prepareE2eEnvironment(): ScriptBuildStep { - return bashNodeScript { - name = "Prepare e2e environment" - scriptContent = """ - # Install deps - yarn workspaces focus wp-e2e-tests @automattic/calypso-e2e - - # Decrypt secrets - # Must do before build so the secrets are in the dist output - E2E_SECRETS_KEY="%E2E_SECRETS_ENCRYPTION_KEY_CURRENT%" yarn workspace @automattic/calypso-e2e decrypt-secrets - - # Build packages - yarn workspace @automattic/calypso-e2e build - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } -} - -fun BuildSteps.collectE2eResults(): ScriptBuildStep { - return bashNodeScript { - name = "Collect results" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - set -x - - mkdir -p screenshots - find test/e2e/results -type f \( -iname \*.webm -o -iname \*.png \) -print0 | xargs -r -0 mv -t screenshots - - mkdir -p logs - find test/e2e/results -name '*.log' -print0 | xargs -r -0 mv -t logs - - mkdir -p trace - find test/e2e/results -name '*.zip' -print0 | xargs -r -0 mv -t trace - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } -} - -fun ParametrizedWithType.defaultE2eParams() { - param("env.NODE_CONFIG_ENV", "test") - param("env.PLAYWRIGHT_BROWSERS_PATH", "0") - param("env.HEADLESS", "true") - param("env.LOCALE", "en") - param("env.DEBUG", "") -} - -fun ParametrizedWithType.calypsoBaseUrlParam( defaultUrl: String = "https://wordpress.com" ) { - text( - name = "env.CALYPSO_BASE_URL", - value = defaultUrl, - label = "Test URL", - description = "URL to test against", - allowEmpty = false - ) -} - -fun FailureConditions.defaultE2eFailureConditions() { - executionTimeoutMin = 20 - // Don't fail if the runner exists with a non zero code. This allows a build to pass if the failed tests have been muted previously. - nonZeroExitCode = false - - // Support retries using the --onlyFailures flag in Jest. - supportTestRetry = true - - // Fail if the number of passing tests is 50% or less than the last build. This will catch the case where the test runner crashes and no tests are run. - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.PASSED_TEST_COUNT - threshold = 50 - units = BuildFailureOnMetric.MetricUnit.PERCENTS - comparison = BuildFailureOnMetric.MetricComparison.LESS - compareTo = build { - buildRule = lastSuccessful() - } - } -} - -fun defaultE2eArtifactRules(): String = """ - logs => logs.tgz - screenshots => screenshots - trace => trace -""".trimIndent() - -fun BuildSteps.runE2eTestsWithRetry( - testGroup: String, - additionalEnvVars: Map = mapOf(), - stepName: String = "Run tests" -): ScriptBuildStep { - val envVarExport = additionalEnvVars.map { ( key, value ) -> "export $key='$value'" }.joinToString( separator = "\n" ) - - return bashNodeScript { - name = stepName - scriptContent = """ - # Configure bash shell. - set -x - - # Export additional environment variables. - $envVarExport - - # Enter testing directory. - cd test/e2e - mkdir -p temp - - # Disable exit on error to support retries. - set +o errexit - - # Run suite. - xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=$testGroup - - # Restore exit on error. - set -o errexit - - # Retry failed tests only. - RETRY_COUNT=1 xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=$testGroup --onlyFailures - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } -} diff --git a/.teamcity/_self/lib/utils/MergeTrunk.kt b/.teamcity/_self/lib/utils/MergeTrunk.kt deleted file mode 100644 index b6b053a0ec0e3a..00000000000000 --- a/.teamcity/_self/lib/utils/MergeTrunk.kt +++ /dev/null @@ -1,40 +0,0 @@ -package _self.lib.utils - -import _self.bashNodeScript -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildSteps -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep - -// Merge the trunk branch as a build step. -// - For WPCOM plugins, our builds and tests include the latest merged version of the plugin being built. -// Otherwise, we can get into a situation where the current plugin build appears "different", but that's -// just because it's older. -// - For metric tracking: (for example, tracking TypeScript errors). Merging trunk ensures any potential fix -// in trunk is included. Otherwise, we can get into a situation where trunk includes a fix for TypeScript -// and this branch adds a new error, resulting in a net total increase when it is merged. -fun BuildSteps.mergeTrunk(skipIfConflict: Boolean = false): ScriptBuildStep { - return bashNodeScript { - name = "Merge trunk" - conditions { - doesNotEqual("teamcity.build.branch.is_default", "true") - } - scriptContent = """ - set -x - # git operations will fail if no user is set. - git config --local user.email "tcbuildagent@example.com" - git config --local user.name "TeamCity Build Agent" - - # Note that `trunk` is already up-to-date from the `teamcity.git.fetchAllHeads` - # parameter in the project settings. - if ! git merge trunk ; then - if [ "$skipIfConflict" = false ] ; then - echo "##teamcity[buildProblem description='There is a merge conflict with trunk. Rebase on trunk to resolve this problem.' identity='merge_conflict']]" - exit - fi - # If do want to skip if there's a conflict, reset the merge. - git reset --merge - fi - # See if the trunk commit shows up: - git --no-pager log --oneline -n 5 - """ - } -} diff --git a/.teamcity/_self/projects/MarTech.kt b/.teamcity/_self/projects/MarTech.kt deleted file mode 100644 index ad97f9e3acde40..00000000000000 --- a/.teamcity/_self/projects/MarTech.kt +++ /dev/null @@ -1,148 +0,0 @@ -package _self.projects - -import Settings -import _self.bashNodeScript -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType -import jetbrains.buildServer.configs.kotlin.v2019_2.Project -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.notifications -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule - -object MarTech : Project({ - id("MarTech") - name = "MarTech" - description = "Tasks run by MarTech." - - params { - param("docker_image", "%docker_image_e2e%") - } - - buildType(ToSAcceptanceTracking) -}) - -object ToSAcceptanceTracking: BuildType ({ - name = "ToS Acceptance Tracking" - description = "Captures screenshots of locations where Terms of Service are shown." - - - artifactRules = """ - tos_screenshots => tos_screenshots - logs.tgz => logs.tgz - recording => recording - trace => trace - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - param("env.NODE_CONFIG_ENV", "test") - param("env.PLAYWRIGHT_BROWSERS_PATH", "0") - param("env.HEADLESS", "true") - param("env.LOCALE", "en") - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Install deps - yarn workspaces focus wp-e2e-tests @automattic/calypso-e2e - - # Decrypt secrets - # Must do before build so the secrets are in the dist output - E2E_SECRETS_KEY="%E2E_SECRETS_ENCRYPTION_KEY_CURRENT%" yarn workspace @automattic/calypso-e2e decrypt-secrets - - # Build packages - yarn workspace @automattic/calypso-e2e build - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Capture screenshots" - scriptContent = """ - # Configure bash shell. - shopt -s globstar - set -x - - # Enter testing directory. - cd test/e2e - mkdir temp - - # Run suite. - xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=legal - """ - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Collect results" - scriptContent = """ - set -x - - mkdir -p tos_screenshots - find test/e2e -type f -path '*tos*.png' -print0 | xargs -r -0 mv -t tos_screenshots - - mkdir -p recording - find test/e2e/results -type f \( -iname \*.webm \) -print0 | xargs -r -0 mv -t recording - - mkdir -p logs - find test/e2e/ -name '*.log' -print0 | xargs -r -0 tar cvfz logs.tgz - - mkdir -p trace - find test/e2e/results -name '*.zip' -print0 | xargs -r -0 mv -t trace - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - } - - features { - perfmon { - } - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#martech-tos-alerts" - messageFormat = simpleMessageFormat() - } - buildFailedToStart = true - buildFailed = true - buildProbablyHanging = true - } - } - - triggers { - schedule { - schedulingPolicy = cron { - hours = "*/3" - } - branchFilter = """ - +:trunk - """.trimIndent() - triggerBuild = always() - withPendingChangesOnly = false - } - } - - failureConditions { - executionTimeoutMin = 20 - // Don't fail if the runner exists with a non zero code. This allows a build to pass if the failed tests have been muted previously. - nonZeroExitCode = false - - // Fail if the number of passing tests is 50% or less than the last build. This will catch the case where the test runner crashes and no tests are run. - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.PASSED_TEST_COUNT - threshold = 50 - units = BuildFailureOnMetric.MetricUnit.PERCENTS - comparison = BuildFailureOnMetric.MetricComparison.LESS - compareTo = build { - buildRule = lastSuccessful() - } - } - } -}) diff --git a/.teamcity/_self/projects/WPComPlugins.kt b/.teamcity/_self/projects/WPComPlugins.kt deleted file mode 100644 index d8ab6fd61ca7c4..00000000000000 --- a/.teamcity/_self/projects/WPComPlugins.kt +++ /dev/null @@ -1,284 +0,0 @@ -package _self.projects - -import _self.bashNodeScript -import _self.lib.utils.mergeTrunk -import jetbrains.buildServer.configs.kotlin.v2019_2.Project -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildSteps -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.PullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs - -object WPComPlugins : Project({ - id("WPComPlugins") - name = "WPCom Plugins" - description = "Builds for WordPress.com plugins developed in calypso and deployed to wp-admin." - - // Default params for WPcom Plugins. - params { - param("docker_image", "registry.a8c.com/calypso/ci-wpcom:latest") - } - - buildType(CalypsoApps) - buildType(GutenbergUploadSourceMapsToSentry); - - cleanup { - keepRule { - id = "keepReleaseBuilds" - keepAtLeast = allBuilds() - applyToBuilds { - inBranches { - branchFilter = patterns("+:") - } - withStatus = successful() - withTags = anyOf( - "notifications-release-build", - "odyssey-stats-release-build", - "blaze-dashboard-release-build", - "editing-toolkit-release-build", - "wpcom-block-editor-release-build", - "o2-blocks-release-build", - "happy-blocks-release-build", - "command-palette-wp-admin-release-build", - ) - } - dataToKeep = everything() - applyPerEachBranch = true - preserveArtifactsDependencies = true - } - } -}) - -object CalypsoApps: BuildType({ - id("calypso_WPComPlugins_Build_Plugins") - uuid = "8453b8fe-226f-4e91-b5cc-8bdad15e0814" - name = "Build Calypso Apps" - description = "Builds all Calypso apps and saves release artifacts for each. This replaces the separate build configurations for each app." - - buildNumberPattern = "%build.prefix%.%build.counter%" - params { - // Incremented to 4 to make sure ETK updates continue to work: - param("build.prefix", "4") - checkbox( - name = "skip_release_diff", - value = "false", - label = "Skip release diff", - description = "Skips the diff against the previous successful build, uploading the artifact as the latest successful build.", - checked = "true", - unchecked = "false" - ) - } - - features { - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } - - triggers { - vcs { - branchFilter = """ - +:* - -:pull* - """.trimIndent() - triggerRules = """ - -:test/e2e/** - -:docs/**.md - -:comment=stress test:** - -:packages/calypso-e2e/** - """.trimIndent() - } - } - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - artifactRules = """ - apps/notifications/dist => notifications.zip - apps/wpcom-block-editor/dist => wpcom-block-editor.zip - apps/notifications/dist => notifications.zip - apps/odyssey-stats/dist => odyssey-stats.zip - apps/blaze-dashboard/dist => blaze-dashboard.zip - apps/o2-blocks/release-files => o2-blocks.zip - apps/happy-blocks/release-files => happy-blocks.zip - apps/editing-toolkit/editing-toolkit-plugin => editing-toolkit.zip - apps/command-palette-wp-admin/dist => command-palette-wp-admin.zip - """.trimIndent() - - steps { - mergeTrunk() - bashNodeScript { - name = "Install dependencies" - scriptContent = """ - composer install - yarn install - """ - } - - // Automatically generate a list of apps to build by scanning the directories, - // then build every app in parallel using yarn workspaces. - bashNodeScript { - name = "Build artifacts" - scriptContent = """ - set -x - export IS_CI=true - apps="" - for dir in ./apps/*/; do - # Only include apps which define the "teamcity:build-app" script. - if [ "$(cat ${'$'}dir/package.json | jq -r '.scripts["teamcity:build-app"]')" = "null" ] ; then - continue - fi - apps+="${'$'}(cat ${'$'}dir/package.json | jq -r '.name')," - done - - # These env vars are used by the build process. (See calypso app builder.) - export build_number="%build.number%" - export commit_sha="%build.vcs.number%" - - yarn workspaces foreach --all --verbose --parallel --include "{${'$'}apps}" run teamcity:build-app - """ - } - - // After the artifacts are built, we process them. This includes comparing - // with each previous release (to determine if a new release is needed), - // and then sending Slack/GitHub notifications as needed. - bashNodeScript { - name = "Process artifact" - scriptContent = """ - export tc_auth="%system.teamcity.auth.userId%:%system.teamcity.auth.password%" - export tc_sever_url="%teamcity.serverUrl%" - export mc_auth_secret="%mc_auth_secret%" - export mc_post_root="%mc_post_root%" - export GH_TOKEN="%matticbot_oauth_token%" - - export commit_sha="%build.vcs.number%" - export git_branch="%teamcity.build.branch%" - export build_id="%teamcity.build.id%" - export is_default_branch="%teamcity.build.branch.is_default%" - export skip_build_diff="%skip_release_diff%" - - node ./bin/process-calypso-app-artifacts.mjs - """ - } - } -}) - -private object GutenbergUploadSourceMapsToSentry: BuildType() { - init { - name = "Upload Source Maps"; - description = "Uploads sourcemaps for various WordPress.com plugins to Sentry. Often triggered per-commit by a WPCOM post-deploy job."; - - id("WPComPlugins_GutenbergUploadSourceMapsToSentry"); - - // Only needed so that we can test the job in different branches. - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - text( - name = "GUTENBERG_VERSION", - value = "", - label = "Gutenberg version", - description = "The Gutenberg version to upload source maps for (include the whole string, including the `v` prefix)", - allowEmpty = false - ) - } - - params { - text( - name = "SENTRY_RELEASE_NAME", - value = "", - label = "Sentry release name", - description = "The WPCOM Sentry release to upload the source-maps to", - allowEmpty = false - ) - } - - steps { - bashNodeScript { - name = "Upload Gutenberg source maps to Sentry" - scriptContent = """ - rm -rf gutenberg gutenberg.zip - - wget https://github.com/WordPress/gutenberg/releases/download/%GUTENBERG_VERSION%/gutenberg.zip - unzip gutenberg.zip -d gutenberg - cd gutenberg - - # Upload the .js and .js.map files to Sentry for the given release. - sentry-cli releases files %SENTRY_RELEASE_NAME% upload-sourcemaps . \ - --auth-token %SENTRY_AUTH_TOKEN% \ - --org a8c \ - --project wpcom-gutenberg-wp-admin \ - --url-prefix "~/wp-content/plugins/gutenberg-core/%GUTENBERG_VERSION%/" - """ - } - - uploadPluginSourceMaps( - slug = "editing-toolkit", - wpcomURL = "~/wp-content/plugins/editing-toolkit-plugin/prod/" - ) - - uploadPluginSourceMaps( - slug = "wpcom-block-editor", - wpcomURL = "~/wpcom-block-editor" - ) - - uploadPluginSourceMaps( - slug = "notifications", - wpcomURL = "~/notifications" - ) - } - } -} - -// Given the plugin information, get the source code and upload any sourcemaps -// to Sentry. -fun BuildSteps.uploadPluginSourceMaps( - slug: String, - wpcomURL: String, - buildTag: String = "$slug-release-build", -): ScriptBuildStep { - return bashNodeScript { - name = "Upload $slug source maps to Sentry" - scriptContent = """ - rm -rf code code.zip - - # Downloads the latest release build for the plugin. - wget "%teamcity.serverUrl%/repository/download/calypso_calypso_WPComPlugins_Build_Plugins/$buildTag.tcbuildtag/$slug.zip?guest=1&branch=trunk" -O ./code.zip - - unzip -q ./code.zip -d ./code - cd code - - # Upload the .js and .js.map files to Sentry for the given release. - sentry-cli releases files %SENTRY_RELEASE_NAME% upload-sourcemaps . \ - --auth-token %SENTRY_AUTH_TOKEN% \ - --org a8c \ - --project wpcom-gutenberg-wp-admin \ - --url-prefix "$wpcomURL" - """ - } -} diff --git a/.teamcity/_self/projects/WPComTests.kt b/.teamcity/_self/projects/WPComTests.kt deleted file mode 100644 index 95361ba31085f6..00000000000000 --- a/.teamcity/_self/projects/WPComTests.kt +++ /dev/null @@ -1,593 +0,0 @@ -package _self.projects - -import Settings -import _self.bashNodeScript -import _self.lib.customBuildType.E2EBuildType -import _self.lib.utils.* -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType -import jetbrains.buildServer.configs.kotlin.v2019_2.Project -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.notifications -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange -import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.buildReportTab -import jetbrains.buildServer.configs.kotlin.v2019_2.Triggers -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.finishBuildTrigger -import jetbrains.buildServer.configs.kotlin.v2019_2.ParameterDisplay -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.exec -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.ScriptBuildStep - -object WPComTests : Project({ - id("WPComTests") - name = "WPCom Tests" - description = "Builds which test WordPress.com functionality, such as the Gutenberg plugin." - - params { - param("docker_image", "%docker_image_e2e%") - param("build.prefix", "1") - } - - features { - buildReportTab { - title = "VR Report" - startPage= "vr-report.zip!vr-report.zip!/test/visual/backstop_data/html_report/index.html" - } - } - - // Gutenberg Simple - buildType(gutenbergPlaywrightBuildType("desktop", "fab2e82e-d27b-4ba2-bbd7-232df944e75c", atomic=false, edge=false)); - buildType(gutenbergPlaywrightBuildType("mobile", "77a5a0f1-9644-4c04-9d27-0066cd2d4ada", atomic=false, edge=false)); - // Gutenberg Simple Edge - buildType(gutenbergPlaywrightBuildType("desktop", "e8817ab4-ec4e-4d58-a215-d1f87b2227b6", atomic=false, edge=true)); - buildType(gutenbergPlaywrightBuildType("mobile", "a655d304-4dcf-4864-8d82-8b22dba29feb", atomic=false, edge=true)); - // Gutenberg Atomic - buildType(gutenbergPlaywrightBuildType("desktop", "c341e9b9-1118-48e9-a569-325100f5fd9" , atomic=true, edge=false)); - buildType(gutenbergPlaywrightBuildType("mobile", "e0f7e412-ae6c-41d3-9eec-c57c94dd8385", atomic=true, edge=false)); - // Gutenberg Atomic Edge - buildType(gutenbergPlaywrightBuildType("desktop", "4c66d90d-99c6-4ecb-9507-18bc2f44b551" , atomic=true, edge=true)); - buildType(gutenbergPlaywrightBuildType("mobile", "ba0f925b-497b-4156-977e-5bfbe94f5744", atomic=true, edge=true)); - // Gutenberg Atomic Nightly - buildType(gutenbergPlaywrightBuildType("desktop", "a3f58555-56bb-42c6-8543-ab27213d3085" , atomic=true, nightly=true)); - buildType(gutenbergPlaywrightBuildType("mobile", "8191e677-0682-4709-9201-66a7788980f0", atomic=true, nightly=true)); - // Gutenberg Core - buildType(gutenbergCoreE2eBuildType()); - - // E2E Tests for Jetpack Simple Deployment - buildType(jetpackSimpleDeploymentE2eBuildType("desktop", "3007d7a1-5642-4dbf-9935-d93f3cdb4dcc")); - buildType(jetpackSimpleDeploymentE2eBuildType("mobile", "ccfe7d2c-8f04-406b-8b83-3db6c8475661")); - - // E2E Tests for Jetpack Atomic Deployment - // Just desktop to start - buildType(jetpackAtomicDeploymentE2eBuildType("desktop", "81015cf6-27e7-40bd-a52d-df6bd19ffb01")); - - // E2E Tests for smoke testing each new Jetpack build on Atomic - // Also just desktop to start - buildType(jetpackAtomicBuildSmokeE2eBuildType("desktop", "f39587ab-f526-42aa-a88b-814702135af3")); - - buildType(I18NTests); - buildType(P2E2ETests) -}) - -fun gutenbergCoreE2eBuildType(): BuildType { - return BuildType ({ - id("WPComTests_gutenberg_core_e2e") - name = "Gutenberg Core E2E Tests" - description = "Runs Gutenberg core E2E tests against a Dotcom environment." - - artifactRules = """ - gutenberg/artifacts => artifacts - logs/*.log => logs - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - // WP.com URL of the site to test against. - password("WP_BASE_URL", "credentialsJSON:5cc9ce44-c31a-4591-9f02-cda749351bff"); - // WP.com username and password to use for logging in. - password("WP_USERNAME", "credentialsJSON:ab140672-6955-4206-9ae4-df940896992d"); - password("WP_PASSWORD", "credentialsJSON:1b787674-1c6f-41c5-9b39-41768fa1aa0c"); - // Calypso client ID and secret for remote logging in. - password("WP_CLIENT_ID", "credentialsJSON:7bcd18c5-7ebe-42ab-9f85-45abcea3f21b"); - password("WP_CLIENT_SECRET", "credentialsJSON:87a99f9c-2bf6-43c2-bd43-903f28bec4fb"); - // Application password for authenticating REST API requests. - password("WP_APP_PASSWORD", "credentialsJSON:2f191dbd-7341-4ff9-acab-f5dd0111e364"); - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Set up the logs directory and define log file path - logs_dir="%system.teamcity.build.checkoutDir%/logs" - mkdir -p "${'$'}logs_dir" - exec &> "${'$'}logs_dir/prepare-environment.log" - set -x # Enable debugging - - echo "Starting environment preparation" - mkdir -p gutenberg - cd gutenberg - git init - git remote add origin https://github.com/WordPress/gutenberg.git - git fetch --depth=1 origin try/run-e2e-tests-against-wpcom - git checkout try/run-e2e-tests-against-wpcom - - echo "Installing dependencies" - npm ci - - echo "Building packages" - npm run build:packages - - echo "Environment preparation complete" - """.trimIndent() - dockerImage = "%docker_image_ci_e2e_gb_core_on_dotcom%" - dockerRunParameters = "-u %env.UID% --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3" - } - - bashNodeScript { - name = "Run Playwright E2E tests" - scriptContent = """ - cd gutenberg - - # Export env vars - export WP_BASE_URL="%WP_BASE_URL%" - export WP_USERNAME="%WP_USERNAME%" - export WP_PASSWORD="%WP_PASSWORD%" - export WP_APP_PASSWORD="%WP_APP_PASSWORD%" - export WP_CLIENT_ID="%WP_CLIENT_ID%" - export WP_CLIENT_SECRET="%WP_CLIENT_SECRET%" - - # Run suite. - npm run test:e2e:playwright - """.trimIndent() - dockerImage = "%docker_image_ci_e2e_gb_core_on_dotcom%" - dockerRunParameters = "-u %env.UID% --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3" - } - - step(ScriptBuildStep { - name = "Copy Docker Container Logs and Capture Script Output" - scriptContent = """ - #!/bin/bash - # Ensure the logs directory exists - logs_dir="%system.teamcity.build.checkoutDir%/logs" - mkdir -p "${'$'}logs_dir" - echo "Logs directory prepared at ${'$'}logs_dir" - - # Redirect all output to script-run.log - exec &> "${'$'}logs_dir/script-run.log" - set -x # Enable debugging - - echo "Attempting to copy logs for all known containers, regardless of state:" - docker ps -a --no-trunc | awk '{print ${'$'}1}' | tail -n +2 > container_ids.txt - - if [ ! -s container_ids.txt ]; then - echo "No Docker containers found. No logs to copy." - else - while read id; do - echo "Checking logs for container ${'$'}id" - src_log_file="/var/lib/docker/containers/${'$'}id/${'$'}id-json.log" - dest_log_file="${'$'}logs_dir/${'$'}id-json.log" - - if [ -f "${'$'}src_log_file" ]; then - cp "${'$'}src_log_file" "${'$'}dest_log_file" - echo "Logs copied from ${'$'}src_log_file to ${'$'}dest_log_file" - else - echo "Log file ${'$'}src_log_file does not exist" - fi - done < container_ids.txt - fi - - echo "Appending 'foobar' to a log file to ensure file system is writable." - echo "foobar" >> "${'$'}logs_dir/test-foobar-log.log" - echo "End of Script" - """.trimIndent() - executionMode = BuildStep.ExecutionMode.ALWAYS - }) - } - }) -} - -fun gutenbergPlaywrightBuildType( targetDevice: String, buildUuid: String, atomic: Boolean = false, edge: Boolean = false, nightly: Boolean = false): E2EBuildType { - var siteType = if (atomic) "atomic" else "simple"; - var releaseType = when { - nightly -> "nightly" - edge -> "edge" - else -> "production" - } - - val buildName = "Gutenberg $siteType E2E tests $releaseType ($targetDevice)" - - return E2EBuildType ( - buildId = "WPComTests_gutenberg_${siteType}_${releaseType}_$targetDevice", - buildUuid = buildUuid, - buildName = buildName, - buildDescription = "Runs Gutenberg $siteType E2E tests on $targetDevice size", - testGroup = "gutenberg", - buildParams = { - text( - name = "env.CALYPSO_BASE_URL", - value = "https://wordpress.com", - label = "Test URL", - description = "URL to test against", - allowEmpty = false - ) - checkbox( - name = "env.COBLOCKS_EDGE", - value = "false", - label = "Use coblocks-edge", - description = "Use a blog with coblocks-edge sticker", - checked = "true", - unchecked = "false" - ) - param("env.AUTHENTICATE_ACCOUNTS", "gutenbergSimpleSiteEdgeUser,gutenbergSimpleSiteUser,coBlocksSimpleSiteEdgeUser,simpleSitePersonalPlanUser,gutenbergAtomicSiteUser,gutenbergAtomicSiteEdgeUser,gutenbergAtomicSiteEdgeNightliesUser") - param("env.VIEWPORT_NAME", "$targetDevice") - if (atomic) { - param("env.TEST_ON_ATOMIC", "true") - // Overrides the inherited max workers settings and sets it to not run any tests in parallel. - // The reason for this is an inconsistent issue breaking the login in AT test sites when - // more than one test runs in parallel. Remove or set it to 16 after the issue is solved. - param("JEST_E2E_WORKERS", "1") - - } - - if (nightly) { - param("env.GUTENBERG_NIGHTLY", "true"); - } - - if (edge) { - param("env.GUTENBERG_EDGE", "true") - } - - password("GB_E2E_ANNOUNCEMENT_SLACK_API_TOKEN", "credentialsJSON:8196e9b8-cf0a-4ab5-9547-95145134f04a", display = ParameterDisplay.HIDDEN); - // Uncomment the following to route it to the test channel, don't forget to change the reference in the exec() calls below, too. - // Ask someone from the Team Calypso Platform to know what these channels are. They are also available in the source for `announce.sh` (par of Gutenbot). - // password("GB_E2E_ANNOUNCEMENT_SLACK_CHANNEL_ID_TEST", "credentialsJSON:180d1bb6-a28e-4985-bf9a-8acba63bb90c", display = ParameterDisplay.HIDDEN); - password("GB_E2E_ANNOUNCEMENT_SLACK_CHANNEL_ID", "credentialsJSON:b8ca97ea-322f-499f-aa21-ecdb8b373527", display = ParameterDisplay.HIDDEN); - text("GB_E2E_ANNOUNCEMENT_THREAD_TS", value = "", allowEmpty = true, display = ParameterDisplay.HIDDEN); - }, - buildSteps = { - exec { - name = "Post Successful Message to Slack" - executionMode = BuildStep.ExecutionMode.RUN_ON_SUCCESS - path = "./bin/post-threaded-slack-message.sh" - arguments = "%GB_E2E_ANNOUNCEMENT_SLACK_CHANNEL_ID% %GB_E2E_ANNOUNCEMENT_THREAD_TS% \"The $buildName passed successfully! <%teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%|View build>\" %GB_E2E_ANNOUNCEMENT_SLACK_API_TOKEN%" - } - - exec { - name = "Post Failure Message to Slack" - executionMode = BuildStep.ExecutionMode.RUN_ONLY_ON_FAILURE - path = "./bin/post-threaded-slack-message.sh" - arguments = "%GB_E2E_ANNOUNCEMENT_SLACK_CHANNEL_ID% %GB_E2E_ANNOUNCEMENT_THREAD_TS% \"The $buildName failed! Could you have a look?! <%teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%|View build>\" %GB_E2E_ANNOUNCEMENT_SLACK_API_TOKEN%" - } - }, - buildFeatures = { - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#gutenberg-e2e" - messageFormat = verboseMessageFormat { - addBranch = true - addStatusText = true - maximumNumberOfChanges = 10 - } - } - branchFilter = "+:" - buildFailed = true - buildFinishedSuccessfully = true - } - }, - buildTriggers = { - schedule { - schedulingPolicy = daily { - hour = 4 - } - branchFilter = """ - +:trunk - """.trimIndent() - triggerBuild = always() - withPendingChangesOnly = false - } - } - ) -} - -fun jetpackSimpleDeploymentE2eBuildType( targetDevice: String, buildUuid: String ): BuildType { - return BuildType({ - id("WPComTests_jetpack_simple_deployment_e2e_$targetDevice") - uuid = buildUuid - name = "Jetpack Simple Deployment E2E Tests ($targetDevice)" - description = "Runs E2E tests validating the deployment of Jetpack on Simple sites on $targetDevice viewport" - - artifactRules = defaultE2eArtifactRules(); - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - defaultE2eParams() - calypsoBaseUrlParam() - param("env.VIEWPORT_NAME", "$targetDevice") - param("env.JETPACK_TARGET", "wpcom-deployment") - } - - triggers { - finishBuildTrigger { - buildType = "JetpackStaging_JetpackSunMoonUpdated" - } - } - - steps { - prepareE2eEnvironment() - - runE2eTestsWithRetry(testGroup = "jetpack-wpcom-integration") - - collectE2eResults() - } - - features { - perfmon {} - - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#jetpack-alerts" - messageFormat = verboseMessageFormat { - addStatusText = true - } - } - branchFilter = "+:" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - } - - failureConditions { - defaultE2eFailureConditions() - } - }); -} - -fun jetpackAtomicDeploymentE2eBuildType( targetDevice: String, buildUuid: String ): BuildType { - val atomicVariations = listOf("default", "php-old", "php-new", "wp-beta", "wp-previous", "private", "ecomm-plan") - - return BuildType({ - id("WPComTests_jetpack_atomic_deployment_e2e_$targetDevice") - uuid = buildUuid - name = "Jetpack Atomic Deployment E2E Tests ($targetDevice)" - description = "Runs E2E tests validating a Jetpack release candidate for full WPCOM Atomic deployment. Runs all tests on all Atomic environment variations." - - artifactRules = defaultE2eArtifactRules(); - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - defaultE2eParams() - calypsoBaseUrlParam() - param("env.VIEWPORT_NAME", "$targetDevice") - param("env.JETPACK_TARGET", "wpcom-deployment") - param("env.TEST_ON_ATOMIC", "true") - // We run all the tests on all variations, and go through each variation sequentially. - // We can easily overwhlem the target Atomic site under test if we have too much parallelization. - // This number of works plays nicely with the expected load handling on these Atomic sites. - // See: pMz3w-ix0-p2 - param("JEST_E2E_WORKERS", "5") - } - - steps { - prepareE2eEnvironment() - - atomicVariations.forEach { variation -> - runE2eTestsWithRetry( - testGroup = "jetpack-wpcom-integration", - additionalEnvVars = mapOf( - "ATOMIC_VARIATION" to variation, - "RUN_ID" to "Atomic: $variation" - ), - stepName = "Run Atomic Jetpack E2E Tests: $variation", - ) - } - - collectE2eResults() - } - - features { - perfmon {} - - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#jetpack-alerts" - messageFormat = verboseMessageFormat { - addStatusText = true - } - } - branchFilter = "+:" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - } - - failureConditions { - defaultE2eFailureConditions() - // These are long-running tests, and we have to scale back the parallelization too. - // Let's give them some more breathing room. - // This number is arbitrary, but tests in mid-2024 tend to run longer than 25 minutes. - executionTimeoutMin = 31 - } - }); -} - -fun jetpackAtomicBuildSmokeE2eBuildType( targetDevice: String, buildUuid: String ): BuildType { - return BuildType({ - id("WPComTests_jetpack_atomic_build_smoke_e2e_$targetDevice") - uuid = buildUuid - name = "Jetpack Atomic Build Smoke E2E Tests ($targetDevice)" - description = "Runs E2E tests to smoke test the most recent Jetpack build on Atomic staging sites. It uses a randomized mix of Atomic environment variations." - - artifactRules = defaultE2eArtifactRules(); - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - defaultE2eParams() - calypsoBaseUrlParam() - param("env.VIEWPORT_NAME", "$targetDevice") - param("env.JETPACK_TARGET", "wpcom-deployment") - param("env.TEST_ON_ATOMIC", "true") - param("env.ATOMIC_VARIATION", "mixed") - // We need to be careful of overwhelming the Atomic sites under test. - // The mixing of Atomic variations happens per-worker. - // There are currently 7 variations. So let's do 2 workers per variation for 14 workers total. - param("JEST_E2E_WORKERS", "14") - } - - steps { - prepareE2eEnvironment() - - runE2eTestsWithRetry(testGroup = "jetpack-wpcom-integration") - - collectE2eResults() - } - - features { - perfmon {} - - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#jetpack-alerts" - messageFormat = verboseMessageFormat { - addStatusText = true - } - } - branchFilter = "+:" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - } - - failureConditions { - defaultE2eFailureConditions() - } - }); -} - - -private object I18NTests : E2EBuildType( - buildId = "WPComTests_i18n", - buildUuid = "2698576f-6ae4-4f05-ae9a-55ce07c9b42f", - buildName = "I18N Tests", - buildDescription = "Runs tests related to i18n", - testGroup = "i18n", - buildParams = { - text( - name = "env.CALYPSO_BASE_URL", - value = "https://wordpress.com", - label = "Test URL", - description = "URL to test against", - allowEmpty = false - ) - text( - name = "env.LOCALES", - value = "en,es,pt-br,de,fr,he,ja,it,nl,ru,tr,id,zh-cn,zh-tw,ko,ar,sv", - label = "Locales to use", - description = "Locales to use, separated by comma", - allowEmpty = false - ) - param("env.VIEWPORT_NAME", "desktop") - }, - buildFeatures = { - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#i18n-devs" - messageFormat = simpleMessageFormat() - } - branchFilter = "trunk" - buildFailed = true - buildFinishedSuccessfully = true - buildFailedToStart = true - firstSuccessAfterFailure = true - buildProbablyHanging = true - } - }, - buildTriggers = { - schedule { - schedulingPolicy = daily { - hour = 3 - } - branchFilter = """ - +:trunk - """.trimIndent() - triggerBuild = always() - withPendingChangesOnly = false - } - } -) - -object P2E2ETests : E2EBuildType( - buildId = "WPComTests_p2", - buildUuid = "086ed775-eee4-4cc0-abc4-bb497979ef48", - buildName = "P2 E2E Tests", - buildDescription = "Runs end-to-end tests against P2.", - testGroup = "p2", - buildParams = { - param("env.VIEWPORT_NAME", "desktop") - param("env.CALYPSO_BASE_URL", "https://wpcalypso.wordpress.com") - }, - buildFeatures = { - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#e2eflowtesting-p2" - messageFormat = simpleMessageFormat() - } - branchFilter = "trunk" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#happytools-alerts" - messageFormat = simpleMessageFormat() - } - branchFilter = "trunk" - buildFailed = true - } - }, - buildTriggers = { - schedule { - schedulingPolicy = cron { - hours = "*/3" - dayOfWeek = "*" - } - branchFilter = "+:trunk" - triggerBuild = always() - withPendingChangesOnly = false - } - } -) diff --git a/.teamcity/_self/projects/WebApp.kt b/.teamcity/_self/projects/WebApp.kt deleted file mode 100644 index 88f0538ef5ed0c..00000000000000 --- a/.teamcity/_self/projects/WebApp.kt +++ /dev/null @@ -1,1061 +0,0 @@ -package _self.projects - -import Settings -import _self.bashNodeScript -import _self.lib.customBuildType.E2EBuildType -import _self.lib.utils.mergeTrunk - -import jetbrains.buildServer.configs.kotlin.* -import jetbrains.buildServer.configs.kotlin.v2019_2.* -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.* -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.* -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.* -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.* - -object WebApp : Project({ - id("WebApp") - name = "Web app" - - buildType(RunAllUnitTests) - buildType(CheckCodeStyleBranch) - buildType(Translate) - buildType(BuildDockerImage) - buildType(playwrightPrBuildType("desktop", "23cc069f-59e5-4a63-a131-539fb55264e7")) - buildType(playwrightPrBuildType("mobile", "90fbd6b7-fddb-4668-9ed0-b32598143616")) - buildType(PreReleaseE2ETests) - buildType(AuthenticationE2ETests) - buildType(QuarantinedE2ETests) -}) - -object BuildDockerImage : BuildType({ - uuid = "89fff49e-c79b-4e68-a012-a7ba405359b6" - name = "Docker image" - description = "Build the primary Docker image for Calypso which will be deployed to calypso.live (for PRs) or to production (on trunk)." - - params { - text("base_image", "registry.a8c.com/calypso/base:latest", label = "Base docker image", description = "Base docker image", allowEmpty = false) - text("base_image_publish_tag", "latest", label = "Tag to use for the published base image", description = "Base docker image tag", allowEmpty = false) - checkbox( - name = "MANUAL_SENTRY_RELEASE", - value = "false", - label = "Create a sentry release.", - description = "Generate and upload sourcemaps to Sentry as a new release for this commit.", - checked = "true", - unchecked = "false" - ) - checkbox( - name = "UPDATE_BASE_IMAGE_CACHE", - value = "false", - label = "Update the base image from the cache.", - description = "Updates the base image by copying .cache files from the current build. Runs on trunk by default if the cache invalidates during the build.", - checked = "true", - unchecked = "false" - ) - param("env.WEBPACK_CACHE_INVALIDATED", "false") - } - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - // Normally, this build can be triggered via snapshot dependencies, such as - // the e2e tests. If those builds don't run (e.g. if they're disabled for certain - // directories), then we still want the docker image to be triggered for the - // deploy system. This build chain sends requests to missioncontrol which start - // different aspects of the deploy system. So the entire deploy system depends - // on this build getting triggered either here or via snapshot dependencies. - triggers { - vcs { - branchFilter = """ - +:* - -:pull* - """.trimIndent() - } - } - - steps { - script { - name = "Webhook Start" - conditions { - equals("teamcity.build.branch.is_default", "true") - } - scriptContent = """ - #!/usr/bin/env bash - - payload=${'$'}(jq -n \ - --arg action "start" \ - --arg commit "${Settings.WpCalypso.paramRefs.buildVcsNumber}" \ - --arg branch "%teamcity.build.branch%" \ - '{action: ${'$'}action, commit: ${'$'}commit, branch: ${'$'}branch}' \ - ) - signature=`echo -n "%teamcity.build.id%" | openssl sha256 -hmac "%mc_auth_secret%" | sed 's/^.* //'` - - curl -s -X POST -d "${'$'}payload" -H "TEAMCITY-SIGNATURE: ${'$'}signature" "%mc_teamcity_webhook%calypso/?build_id=%teamcity.build.id%" - """ - } - - script { - name = "Post PR comment" - conditions { - doesNotEqual("teamcity.build.branch.is_default", "true") - } - scriptContent = """ - #!/usr/bin/env bash - - export GH_TOKEN="%matticbot_oauth_token%" - chmod +x ./bin/add-pr-comment.sh - ./bin/add-pr-comment.sh "%teamcity.build.branch%" "calypso-live" <<- EOF || true - Link to live branch is being generated... - Please wait a few minutes and refresh this page. - EOF - """ - } - - // We want calypso.live and Calypso e2e tests to run even if there's a merge conflict, - // just to keep things going. However, if we can merge, the webpack cache - // can be better utilized, since it's kept up-to-date for trunk commits. - // Note that this only happens on non-trunk - mergeTrunk( skipIfConflict = true ) - - script { - name = "Restore git mtime" - scriptContent = """ - #!/usr/bin/env bash - sudo apt-get install -y git-restore-mtime - /usr/lib/git-core/git-restore-mtime --force --commit-time --skip-missing - """ - dockerImage = "%docker_image_e2e%" - dockerRunParameters = "-u %env.UID%" - dockerPull = true - dockerImagePlatform = ScriptBuildStep.ImagePlatform.Linux - } - - val commonArgs = """ - --label com.a8c.image-builder=teamcity - --label com.a8c.build-id=%teamcity.build.id% - --build-arg workers=32 - --build-arg node_memory=16384 - --build-arg use_cache=true - --build-arg base_image=%base_image% - --build-arg commit_sha=${Settings.WpCalypso.paramRefs.buildVcsNumber} - --build-arg manual_sentry_release=%MANUAL_SENTRY_RELEASE% - --build-arg is_default_branch=%teamcity.build.branch.is_default% - --build-arg sentry_auth_token=%SENTRY_AUTH_TOKEN% - --build-arg generate_cache_image=%UPDATE_BASE_IMAGE_CACHE% - """.trimIndent().replace("\n"," ") - - dockerCommand { - name = "Build docker image" - commandType = build { - source = file { - path = "Dockerfile" - } - namesAndTags = """ - registry.a8c.com/calypso/app:build-%build.number% - registry.a8c.com/calypso/app:commit-${Settings.WpCalypso.paramRefs.buildVcsNumber} - registry.a8c.com/calypso/app:latest - """.trimIndent() - commandArgs = "--pull --label com.a8c.target=calypso-live $commonArgs" - } - param("dockerImage.platform", "linux") - } - - dockerCommand { - commandType = push { - namesAndTags = """ - registry.a8c.com/calypso/app:build-%build.number% - registry.a8c.com/calypso/app:commit-${Settings.WpCalypso.paramRefs.buildVcsNumber} - """.trimIndent() - } - } - - script { - name = "Webhook fail OR webhook done and push trunk tag for deploy" - executionMode = BuildStep.ExecutionMode.ALWAYS - conditions { - equals("teamcity.build.branch.is_default", "true") - } - scriptContent = """ - #!/usr/bin/env bash - - ACTION="fail" - SUCCESS=$(curl --silent -X GET -H "Content-Type: text/plain" https://teamcity.a8c.com/guestAuth/app/rest/builds/?locator=id:%teamcity.build.id% | grep -c 'status="SUCCESS"') - if [ ${'$'}SUCCESS -eq 1 ]; then - docker push "registry.a8c.com/calypso/app:latest" - ACTION="done" - fi - - payload=${'$'}(jq -n \ - --arg action "${'$'}ACTION" \ - --arg commit "${Settings.WpCalypso.paramRefs.buildVcsNumber}" \ - --arg branch "%teamcity.build.branch%" \ - '{action: ${'$'}action, commit: ${'$'}commit, branch: ${'$'}branch}' \ - ) - signature=`echo -n "%teamcity.build.id%" | openssl sha256 -hmac "%mc_auth_secret%" | sed 's/^.* //'` - - curl -s -X POST -d "${'$'}payload" -H "TEAMCITY-SIGNATURE: ${'$'}signature" "%mc_teamcity_webhook%calypso/?build_id=%teamcity.build.id%" - """ - } - - script { - name = "Post PR comment with link" - conditions { - doesNotEqual("teamcity.build.branch.is_default", "true") - } - scriptContent = """ - #!/usr/bin/env bash - - export GH_TOKEN="%matticbot_oauth_token%" - chmod +x ./bin/add-pr-comment.sh - ./bin/add-pr-comment.sh "%teamcity.build.branch%" "calypso-live" <<- EOF || true -
- Calypso Live (direct link) - - - - - -
- - - https://calypso.live?image=registry.a8c.com/calypso/app:build-%build.number% -
-
-
- Jetpack Cloud live (direct link) - - - - - -
- - - https://calypso.live?image=registry.a8c.com/calypso/app:build-%build.number%&env=jetpack -
-
-
- Automattic for Agencies live (direct link) - - - - - -
- - - https://calypso.live?image=registry.a8c.com/calypso/app:build-%build.number%&env=a8c-for-agencies -
-
- EOF - """ - } - - // TODO: Cache rebuilding is currently disabled. It takes a long time and - // causes timeouts on trunk. It needs to run more quickly to be worth it. - // For now, the cache will be rebuilt a couple times a day by the dedicated - // cache build. - - // Conditions don't seem to support and/or, so we do this in a separate step. - // Essentially, UPDATE_BASE_IMAGE_CACHE will remain false by default, but - // if we're on trunk and get WEBPACK_CACHE_INVALIDATED set by the docker build, - // then we can flip it to true to trigger the cache rebuild. - // script { - // name = "Set cache update" - // conditions { - // equals("env.WEBPACK_CACHE_INVALIDATED", "true") - // equals("teamcity.build.branch.is_default", "true") - // } - // scriptContent = """ - // echo "##teamcity[setParameter name='UPDATE_BASE_IMAGE_CACHE' value='true']" - // """ - // } - - // This updates the base docker image when the webpack cache invalidates. - // It does so by re-using the layers already generated above, and simply - // copying the .cache directory as a new layer into the base image. On - // trunk, this will update the latest base image for future builds. - // - // Runs after everything else to avoid blocking the deploy system or calypso.live. - dockerCommand { - name = "Rebuild cache image" - conditions { - equals("UPDATE_BASE_IMAGE_CACHE", "true") - } - commandType = build { - source = file { - path = "Dockerfile" - } - namesAndTags = "registry.a8c.com/calypso/base:%base_image_publish_tag%" - commandArgs = """ - --target update-base-cache - --cache-from=registry.a8c.com/calypso/app:commit-${Settings.WpCalypso.paramRefs.buildVcsNumber},%base_image% - $commonArgs - """.trimIndent().replace("\n"," ") - } - param("dockerImage.platform", "linux") - } - - dockerCommand { - name = "Push cache image" - conditions { - equals("UPDATE_BASE_IMAGE_CACHE", "true") - } - commandType = push { - namesAndTags = "registry.a8c.com/calypso/base:%base_image_publish_tag%" - } - } - } - - failureConditions { - executionTimeoutMin = 20 - } - - features { - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#calypso" - messageFormat = verboseMessageFormat { - addChanges = true - addStatusText = true - addBranch = true - } - } - branchFilter = """ - +:trunk - """.trimIndent() - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = true - firstSuccessAfterFailure = true - buildProbablyHanging = true - } - } -}) - -object RunAllUnitTests : BuildType({ - id("calypso_WebApp_Run_All_Unit_Tests") - uuid = "beb75760-2786-472b-8909-ec33457bdece" - name = "Unit tests" - description = "Run unit tests (client + server + packages)" - - artifactRules = """ - test_results => test_results - artifacts => artifacts - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - steps { - mergeTrunk() - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - export NODE_ENV="test" - echo -n "Node version: " && node --version - echo -n "Yarn version: " && yarn --version - echo -n "NPM version: " && npm --version - - # Install modules - ${_self.yarn_install_cmd} - - # The "name" property refers to the code of the message (like YN0002). - - # Generate a JSON array of the errors we care about: - # 1. Select warning YN0002 (Missing peer dependencies.) - # 2. Select warning ZN0060 (Invalid peer dependency.) - # 3. Select warning YN0068 (A yarnrc.yml entry needs to be removed.) - # 4. Select any errors which aren't code 0. (Which shows the error summary, not individual problems.) - yarn_errors=${'$'}(cat "${'$'}yarn_out" | jq '[ .[] | select(.name == 2 or .name == 60 or .name == 68 or (.type == "error" and .name != 0)) ]') - - num_errors=${'$'}(jq length <<< "${'$'}yarn_errors") - if [ "${'$'}num_errors" -gt 0 ] ; then - # Construct warning strings from the JSON array of yarn problems. - err_string=${'$'}(jq '.[] | "Yarn error \(.displayName): \(.data)"' <<< "${'$'}yarn_errors") - - # Remove quotes which had to be added in the jq expression: - err_string=${'$'}(sed 's/^"//g;s/"${'$'}//g' <<< "${'$'}err_string") - - # Escape values as needed for TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Escaped+values - # Specifically, add | before every [, ], |, and '. - err_string=${'$'}(sed "s/\([][|']\)/|\1/g" <<< "${'$'}err_string") - - # Output each yarn problem as a TeamCity service message for easier debugging. - while read -r err ; do - echo "##teamcity[message text='${'$'}err' status='ERROR']" - done <<< "${'$'}err_string" - - # Quick plural handling because why not. - if [ "${'$'}num_errors" -gt 1 ]; then s='s'; else s=''; fi - - echo "##teamcity[buildProblem description='${'$'}num_errors error${'$'}s occurred during yarn install.' identity='yarn_problem']" - exit 1 - fi - """ - } - bashNodeScript { - name = "Check for yarn.lock changes and duplicated packages" - scriptContent = """ - function prevent_uncommitted_changes { - DIRTY_FILES=${'$'}(git status --porcelain 2>/dev/null) - if [ ! -z "${'$'}DIRTY_FILES" ]; then - echo "Repository contains uncommitted changes: " - echo "${'$'}DIRTY_FILES" - echo "You need to checkout the branch, run 'yarn' and commit those files." - return 1 - fi - } - - function prevent_duplicated_packages { - if ! DUPLICATED_PACKAGES=${'$'}( - set +e - yarn dedupe --check - ); then - echo "Repository contains duplicated packages: " - echo "" - echo "${'$'}DUPLICATED_PACKAGES" - echo "" - echo "To fix them, you need to checkout the branch, run 'yarn dedupe'," - echo "verify that the new packages work and commit the changes in 'yarn.lock'." - return 1 - else - echo "No duplicated packages found." - fi - } - - prevent_uncommitted_changes & prevent_duplicated_packages - wait - """.trimIndent() - } - bashNodeScript { - name = "Run parallelized tests" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = "./bin/unit-test-suite.mjs" - } - bashNodeScript { - name = "Tag build" - executionMode = BuildStep.ExecutionMode.RUN_ON_SUCCESS - scriptContent = """ - set -x - - if [[ "%teamcity.build.branch.is_default%" == "true" ]] ; then - curl -s -X POST -H "Content-Type: text/plain" --data "release-candidate" -u "%system.teamcity.auth.userId%:%system.teamcity.auth.password%" "%teamcity.serverUrl%/httpAuth/app/rest/builds/id:%teamcity.build.id%/tags/" - fi - """.trimIndent() - } - } - - triggers { - vcs { - branchFilter = """ - +:* - -:pull* - """.trimIndent() - } - } - - failureConditions { - executionTimeoutMin = 10 - } - features { - feature { - type = "xml-report-plugin" - param("xmlReportParsing.verboseOutput", "true") - } - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#team-calypso-bot" - messageFormat = simpleMessageFormat() - } - branchFilter = """ - +:trunk - """.trimIndent() - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = true - firstSuccessAfterFailure = true - buildProbablyHanging = true - } - } -}) - -object CheckCodeStyleBranch : BuildType({ - id("calypso_WebApp_Check_Code_Style_Branch") - uuid = "dfee7987-6bbc-4250-bb10-ef9dd7322bd2" - name = "Code style" - description = "Check code style" - - params { - checkbox( - name = "run_full_eslint", - value = "false", - label = "Run full eslint", - description = "Run ESLint for all files in the repo, not only for changed files", - checked = "true", - unchecked = "false" - ) - } - - cleanup { - artifacts(days = 14) - } - - artifactRules = """ - checkstyle_results => checkstyle_results - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - export NODE_ENV="test" - - # Install modules - ${_self.yarn_install_cmd} - """ - } - bashNodeScript { - name = "Run eslint" - scriptContent = """ - set -x - export NODE_ENV="test" - - # Find files to lint - TOTAL_FILES_TO_LINT=$(git diff --name-only --diff-filter=d refs/remotes/origin/trunk...HEAD | grep -cE '\.[jt]sx?' || true) - - # Avoid running more than 16 parallel eslint tasks as it could OOM - if [ "%run_full_eslint%" = "true" ] || [ "${'$'}TOTAL_FILES_TO_LINT" -gt 16 ] || [ "${'$'}TOTAL_FILES_TO_LINT" == "0" ]; then - echo "Linting all files" - yarn run eslint --format checkstyle --output-file "./checkstyle_results/eslint/results.xml" . - else - # To avoid `ENAMETOOLONG` errors linting files, we have to lint them one by one, - # instead of passing the full list of files to eslint directly. - for file in ${'$'}(git diff --name-only --diff-filter=d refs/remotes/origin/trunk...HEAD | grep -E '(\.[jt]sx?)${'$'}' || true); do - ( echo "Linting ${'$'}file" - yarn run eslint --format checkstyle --output-file "./checkstyle_results/eslint/${'$'}{file//\//_}.xml" "${'$'}file" ) & - done - wait - fi - """ - } - - bashNodeScript { - name = "Run stylelint" - scriptContent = """ - # In the future, we may add the stylelint cache here. - yarn run lint:css - """ - } - } - - triggers { - vcs { - branchFilter = """ - +:* - -:trunk - -:pull* - """.trimIndent() - } - } - - failureConditions { - executionTimeoutMin = 20 - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.INSPECTION_ERROR_COUNT - threshold = 0 - units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT - comparison = BuildFailureOnMetric.MetricComparison.MORE - compareTo = value() - } - } - - features { - feature { - type = "xml-report-plugin" - param("xmlReportParsing.reportType", "checkstyle") - param("xmlReportParsing.reportDirs", "checkstyle_results/**/*.xml") - param("xmlReportParsing.verboseOutput", "true") - } - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } -}) - -object Translate : BuildType({ - id("calypso_WebApp_Translate") - name = "Translate" - description = "Extract translatable strings from the source code and build POT file" - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Install modules - ${_self.yarn_install_cmd} - """ - dockerImage = "%docker_image_e2e%" - } - bashNodeScript { - name = "Extract strings" - scriptContent = """ - # Run script to extract strings from source code - yarn run translate - - # Move `calypso-strings.pot` to artifacts directory - mkdir -p ./translate - mv public/calypso-strings.pot ./translate/ - - # Publish calypso-string.pot artifact - echo "##teamcity[publishArtifacts './translate/calypso-strings.pot']" - """ - dockerImage = "%docker_image_e2e%" - } - bashNodeScript { - name = "Build New Strings .pot" - scriptContent = """ - # Export LocalCI Client Authentication Variables - export LOCALCI_APP_SECRET="%TRANSLATE_GH_APP_SECRET%" - export LOCALCI_APP_ID="%TRANSLATE_GH_APP_ID%" - - # Clone GP LocalCI Client - git clone --single-branch --depth=1 https://github.com/Automattic/gp-localci-client.git - - # Build `localci-new-strings.pot` - DEFAULT_BRANCH=trunk bash gp-localci-client/generate-new-strings-pot.sh "%teamcity.build.branch%" "${Settings.WpCalypso.paramRefs.buildVcsNumber}" "./translate" - - # Remove GP LocalCI Client - rm -rf gp-localci-client - - # Publish localci-new-strings.pot artifact - echo "##teamcity[publishArtifacts './translate/localci-new-strings.pot']" - """ - dockerImage = "%docker_image_e2e%" - } - bashNodeScript { - name = "Notify GlotPress Translate build is ready" - scriptContent = """ - if [[ "%teamcity.build.branch.is_default%" == "true" ]]; then - exit 0 - fi - - curl -X POST https://translate.wordpress.com/api/localci/-relay-new-strings-to-gh \ - -H 'Cache-Control: no-cache' \ - -H 'Content-Type: application/json' \ - -d '{ - "payload": { - "username": "Automattic", - "reponame": "wp-calypso", - "branch": "%teamcity.build.branch%", - "vcs_revision": "${Settings.WpCalypso.paramRefs.buildVcsNumber}", - "build_num": "%teamcity.build.id%" - } - }' - """ - } - } - - triggers { - vcs { - branchFilter = """ - +:* - -:pull* - """.trimIndent() - } - } - - features { - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } -}) - -fun playwrightPrBuildType( targetDevice: String, buildUuid: String ): E2EBuildType { - return E2EBuildType( - buildId = "calypso_WebApp_Calypso_E2E_Playwright_$targetDevice", - buildUuid = buildUuid, - buildName = "E2E Tests ($targetDevice)", - buildDescription = "Runs Calypso e2e tests on $targetDevice size", - getCalypsoLiveURL = """ - chmod +x ./bin/get-calypso-live-url.sh - CALYPSO_LIVE_URL=${'$'}(./bin/get-calypso-live-url.sh ${BuildDockerImage.depParamRefs.buildNumber}) - if [[ ${'$'}? -ne 0 ]]; then - // Command failed. CALYPSO_LIVE_URL contains stderr - echo ${'$'}CALYPSO_LIVE_URL - exit 1 - fi - """.trimIndent(), - testGroup = "calypso-pr", - buildParams = { - param("env.AUTHENTICATE_ACCOUNTS", "simpleSitePersonalPlanUser,gutenbergSimpleSiteUser,defaultUser") - param("env.LIVEBRANCHES", "true") - param("env.VIEWPORT_NAME", "$targetDevice") - }, - buildFeatures = { - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - }, - enableCommitStatusPublisher = true, - buildTriggers = { - vcs { - branchFilter = """ - +:* - -:pull* - -:trunk - """.trimIndent() - triggerRules = """ - -:**.md - """.trimIndent() - } - }, - buildDependencies = { - snapshot(BuildDockerImage) { - onDependencyFailure = FailureAction.FAIL_TO_START - } - } - ) -} - -object PreReleaseE2ETests : BuildType({ - id("calypso_WebApp_Calypso_E2E_Pre_Release") - uuid = "9c2f634f-6582-4245-bb77-fb97d9f16533" - name = "Pre-Release E2E Tests" - description = "Runs a pre-release suite of E2E tests against trunk on staging, intended to be run after PR merge, but before deployment to production." - artifactRules = """ - logs => logs.tgz - screenshots => screenshots - trace => trace - allure-results => allure-results.tgz - """.trimIndent() - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - params { - param("env.NODE_CONFIG_ENV", "test") - param("env.PLAYWRIGHT_BROWSERS_PATH", "0") - param("env.HEADLESS", "true") - param("env.LOCALE", "en") - param("env.VIEWPORT_NAME", "desktop") - param("env.CALYPSO_BASE_URL", "https://wpcalypso.wordpress.com") - param("env.ALLURE_RESULTS_PATH", "allure-results") - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Install deps - yarn workspaces focus wp-e2e-tests @automattic/calypso-e2e - - # Decrypt secrets - # Must do before build so the secrets are in the dist output - E2E_SECRETS_KEY="%E2E_SECRETS_ENCRYPTION_KEY_CURRENT%" yarn workspace @automattic/calypso-e2e decrypt-secrets - - # Build packages - yarn workspace @automattic/calypso-e2e build - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Run tests" - scriptContent = """ - # Configure bash shell. - shopt -s globstar - set -x - - # Enter testing directory. - cd test/e2e - mkdir temp - - # Disable exit on error to support retries. - set +o errexit - - # Run suite. - xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=calypso-release - - # Restore exit on error. - set -o errexit - - # Retry failed tests only. - RETRY_COUNT=1 xvfb-run yarn jest --reporters=jest-teamcity --reporters=default --maxWorkers=%JEST_E2E_WORKERS% --workerIdleMemoryLimit=1GB --group=calypso-release --onlyFailures --json --outputFile=pre-release-test-results.json - """ - dockerImage = "%docker_image_e2e%" - } - - - bashNodeScript { - name = "Collect results" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - set -x - - mkdir -p screenshots - find test/e2e/results -type f \( -iname \*.webm -o -iname \*.png \) -print0 | xargs -r -0 mv -t screenshots - - mkdir -p logs - find test/e2e/results -name '*.log' -print0 | xargs -r -0 mv -t logs - - mkdir -p trace - find test/e2e/results -name '*.zip' -print0 | xargs -r -0 mv -t trace - - mkdir -p allure-results - find test/e2e/allure-results -name '*.json' -print0 | xargs -r -0 mv -t allure-results - """.trimIndent() - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Upload Allure results to S3" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - aws configure set aws_access_key_id %CALYPSO_E2E_DASHBOARD_AWS_S3_ACCESS_KEY_ID% - aws configure set aws_secret_access_key %CALYPSO_E2E_DASHBOARD_AWS_S3_SECRET_ACCESS_KEY% - - # Need to use -C to avoid creation of an unnecessary top level directory. - tar cvfz %build.counter%-%build.vcs.number%.tgz -C allure-results . - - aws s3 cp %build.counter%-%build.vcs.number%.tgz %CALYPSO_E2E_DASHBOARD_AWS_S3_ROOT% - """.trimIndent() - conditions { - exists("env.ALLURE_RESULTS_PATH") - equals("teamcity.build.branch", "trunk") - } - dockerImage = "%docker_image_e2e%" - } - - bashNodeScript { - name = "Send webhook to GitHub Actions" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - # Issue call as matticbot. - # The GitHub Action workflow expects the filename of the most recent Allure report - # as param. - curl https://api.github.com/repos/Automattic/wp-calypso-test-results/actions/workflows/generate-report.yml/dispatches -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer %MATTICBOT_GITHUB_BEARER_TOKEN%" -d '{"ref":"trunk","inputs":{"allure_result_filename": "%build.counter%-%build.vcs.number%.tgz"}}' - """.trimIndent() - conditions { - exists("env.ALLURE_RESULTS_PATH") - equals("teamcity.build.branch", "trunk") - } - dockerImage = "%docker_image_e2e%" - } - } - - features { - perfmon { - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#e2eflowtesting-notif" - messageFormat = verboseMessageFormat { - addStatusText = true - } - } - branchFilter = "+:" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - } - - failureConditions { - executionTimeoutMin = 20 - // Don't fail if the runner exists with a non zero code. This allows a build to pass if the failed tests have been muted previously. - nonZeroExitCode = false - - // Support retries using the --onlyFailures flag in Jest. - supportTestRetry = true - - // Fail if the number of passing tests is 50% or less than the last build. This will catch the case where the test runner crashes and no tests are run. - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.PASSED_TEST_COUNT - threshold = 50 - units = BuildFailureOnMetric.MetricUnit.PERCENTS - comparison = BuildFailureOnMetric.MetricComparison.LESS - compareTo = build { - buildRule = lastSuccessful() - } - } - } -}) - -object AuthenticationE2ETests : E2EBuildType( - buildId = "calypso_WebApp_Calypso_E2E_Authentication", - buildUuid = "f5036e29-f400-49ea-b5c5-4aba9307c5e8", - buildName = "Authentication E2E Tests", - buildDescription = "Runs a suite of Authentication E2E tests.", - concurrentBuilds = 1, - testGroup = "authentication", - buildParams = { - param("env.VIEWPORT_NAME", "desktop") - }, - buildFeatures = { - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#e2eflowtesting-notif" - messageFormat = verboseMessageFormat { - addStatusText = true - } - } - branchFilter = "+:" - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - }, - buildTriggers = { - schedule { - schedulingPolicy = cron { - hours = "*/6" - } - branchFilter = "+:" - triggerBuild = always() - withPendingChangesOnly = true - } - } -) - -object QuarantinedE2ETests: E2EBuildType( - buildId = "calypso_WebApp_Quarantined_E2E_Tests", - buildUuid = "14083675-b6de-419f-b2f6-ec89c06d3a8c", - buildName = "Quarantined E2E Tests", - buildDescription = "E2E tests quarantined due to intermittent failures.", - concurrentBuilds = 1, - testGroup = "quarantined", - buildParams = { - param("env.VIEWPORT_NAME", "desktop") - param("env.CALYPSO_BASE_URL", "https://wpcalypso.wordpress.com") - }, - buildFeatures = { - notifications { - notifierSettings = slackNotifier { - connection = "PROJECT_EXT_11" - sendTo = "#e2eflowtesting-notif" - messageFormat = simpleMessageFormat() - } - buildFailedToStart = true - buildFailed = true - buildFinishedSuccessfully = false - buildProbablyHanging = true - } - }, - buildTriggers = { - } -) - diff --git a/.teamcity/_self/yarnInstall.kt b/.teamcity/_self/yarnInstall.kt deleted file mode 100644 index c14590b5a0254d..00000000000000 --- a/.teamcity/_self/yarnInstall.kt +++ /dev/null @@ -1,18 +0,0 @@ -package _self - -/** - * Use variable in scripts to take advantage of node_module caching. - */ -val yarn_install_cmd = """ - # Do not type-check packages on postinstall, we already have a unit test for that - export SKIP_TSC=true - - # Install modules. We save to the file while also outputting it for visibility. - yarn_out="/tmp/yarn-json-output.json" - yarn --json | tee -a "${'$'}yarn_out" - - # Yarn --json saves as newline-delimited JSON. To make the JSON file valid, - # we add brackets at the beginning and end and commas on each entry in between. - # Inspired by https://stackoverflow.com/a/35021663. - sed -i -e '1s/^/[/' -e '${'$'}!s/$/,/' -e '${'$'}s/$/]/' "${'$'}yarn_out" -""".trimIndent() diff --git a/.teamcity/docker-seccomp.json b/.teamcity/docker-seccomp.json deleted file mode 100644 index 4802ec27f917cc..00000000000000 --- a/.teamcity/docker-seccomp.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "defaultAction": "SCMP_ACT_ALLOW" -} diff --git a/.teamcity/pom.xml b/.teamcity/pom.xml deleted file mode 100644 index 503d2a58b21bb6..00000000000000 --- a/.teamcity/pom.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - 4.0.0 - calypso Config DSL Script - calypso - calypso_dsl - 1.0-SNAPSHOT - - - org.jetbrains.teamcity - configs-dsl-kotlin-parent - 1.0-SNAPSHOT - - - - - jetbrains-all - https://download.jetbrains.com/teamcity-repository - - true - - - - teamcity-server - https://teamcity.a8c.com/app/dsl-plugins-repository - - true - - - - - - - JetBrains - https://download.jetbrains.com/teamcity-repository - - - - - ${basedir} - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - - - compile - process-sources - - compile - - - - test-compile - process-test-sources - - test-compile - - - - - - org.jetbrains.teamcity - teamcity-configs-maven-plugin - ${teamcity.dsl.version} - - kotlin - target/generated-configs - - - - - - - - org.jetbrains.teamcity - configs-dsl-kotlin - ${teamcity.dsl.version} - compile - - - org.jetbrains.teamcity - configs-dsl-kotlin-plugins - 1.0-SNAPSHOT - pom - compile - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - compile - - - org.jetbrains.kotlin - kotlin-script-runtime - ${kotlin.version} - compile - - - \ No newline at end of file diff --git a/.teamcity/settings.kts b/.teamcity/settings.kts deleted file mode 100644 index 3303565e112ece..00000000000000 --- a/.teamcity/settings.kts +++ /dev/null @@ -1,396 +0,0 @@ - -import _self.bashNodeScript -import _self.yarn_install_cmd -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildStep -import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType -import jetbrains.buildServer.configs.kotlin.v2019_2.ParameterDisplay -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.PullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.dockerSupport -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.perfmon -import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.pullRequests -import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.dockerCommand -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric -import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange -import jetbrains.buildServer.configs.kotlin.v2019_2.project -import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.dockerRegistry -import jetbrains.buildServer.configs.kotlin.v2019_2.projectFeatures.githubConnection -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule -import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs -import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot -import jetbrains.buildServer.configs.kotlin.v2019_2.version - -/* -The settings script is an entry point for defining a TeamCity -project hierarchy. The script should contain a single call to the -project() function with a Project instance or an init function as -an argument. - -VcsRoots, BuildTypes, Templates, and subprojects can be -registered inside the project using the vcsRoot(), buildType(), -template(), and subProject() methods respectively. - -To debug settings scripts in command-line, run the - - mvnDebug org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate - -command and attach your debugger to the port 8000. - -To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View --> Tool Windows -> Maven Projects), find the generate task node -(Plugins -> teamcity-configs -> teamcity-configs:generate), the -'Debug' option is available in the context menu for the task. -*/ - -version = "2023.05" - -project { - - vcsRoot(WpCalypso) - subProject(_self.projects.WPComPlugins) - subProject(_self.projects.WPComTests) - subProject(_self.projects.WebApp) - subProject(_self.projects.MarTech) - buildType(YarnInstall) - buildType(BuildBaseImages) - buildType(CheckCodeStyle) - buildType(SmartBuildLauncher) - - params { - // Force color support in chalk. For some reason it doesn't detect TeamCity - // as supported (even though both TeamCity and chalk support that.) - param("env.FORCE_COLOR", "1") - param("env.NODE_OPTIONS", "--max-old-space-size=16384") - text("JEST_E2E_WORKERS", "100%", label = "Jest max workers", description = "Number or percent of cores to use when running E2E tests.", allowEmpty = true) - password("matticbot_oauth_token", "credentialsJSON:34cb38a5-9124-41c4-8497-74ed6289d751", display = ParameterDisplay.HIDDEN) - text("env.CHILD_CONCURRENCY", "15", label = "Yarn child concurrency", description = "How many packages yarn builds in parallel", allowEmpty = true) - text("docker_image", "registry.a8c.com/calypso/base:latest", label = "Docker image", description = "Default Docker image used to run builds", allowEmpty = true) - text("docker_image_e2e", "registry.a8c.com/calypso/ci-e2e:latest", label = "Docker e2e image", description = "Docker image used to run e2e tests", allowEmpty = true) - text("docker_image_ci_e2e_gb_core_on_dotcom", "registry.a8c.com/calypso/ci-e2e-gb-core-on-dotcom:latest", label = "Docker GB core on dotcom image", description = "Docker image used to run GB core E2E tests on dotcom", allowEmpty = true) - text("env.DOCKER_BUILDKIT", "1", label = "Enable Docker BuildKit", description = "Enables BuildKit (faster image generation). Values 0 or 1", allowEmpty = true) - password("mc_post_root", "credentialsJSON:2f764583-d399-4d5f-8ee1-06f68ef2e2a6", display = ParameterDisplay.HIDDEN ) - password("mc_auth_secret", "credentialsJSON:5b1903f9-4b03-43ff-bba8-4a7509d07088", display = ParameterDisplay.HIDDEN) - password("mc_teamcity_webhook", "credentialsJSON:7a711930-afd4-4058-b33f-39af8a0b7f91", display = ParameterDisplay.HIDDEN) - password("TRANSLATE_GH_APP_SECRET", "credentialsJSON:083cc9f7-4e9a-461f-b213-bc306baaeb28", display = ParameterDisplay.HIDDEN) - password("TRANSLATE_GH_APP_ID", "credentialsJSON:c03b1958-5ec3-4f4c-ab1c-ca1bf0e629f5", display = ParameterDisplay.HIDDEN) - password("SENTRY_AUTH_TOKEN", "credentialsJSON:e266a488-d639-4baa-b681-0e11be59ebc1", display = ParameterDisplay.HIDDEN) - - // Fetch all heads. This is used for builds that merge trunk before running tests - param("teamcity.git.fetchAllHeads", "true") - - // e2e config decryption key references. See PCYsg-vnR-p2 for more info. - password("E2E_SECRETS_ENCRYPTION_KEY_AUG_29_23", "credentialsJSON:f29ecb29-687d-4411-8769-cc7b44edc0c5", display = ParameterDisplay.HIDDEN) - password("E2E_SECRETS_ENCRYPTION_KEY_DEC_1_23" , "credentialsJSON:1d6bc37e-2243-4fcb-b202-f7cc35e748da", display = ParameterDisplay.HIDDEN) - // Define the currently used encryption key here. This allows easy swapping between previously used keys. - password("E2E_SECRETS_ENCRYPTION_KEY_CURRENT", "%E2E_SECRETS_ENCRYPTION_KEY_DEC_1_23%", display = ParameterDisplay.HIDDEN) - - // Calypso dashboard AWS secrets for S3 bucket. - password("CALYPSO_E2E_DASHBOARD_AWS_S3_ACCESS_KEY_ID", "credentialsJSON:1f324549-3795-43e5-a8c2-fb81d6e7c15d", display = ParameterDisplay.HIDDEN) - password("CALYPSO_E2E_DASHBOARD_AWS_S3_SECRET_ACCESS_KEY", "credentialsJSON:782b4bde-b73d-4326-9970-5a79251bdf07", display = ParameterDisplay.HIDDEN) - password("MATTICBOT_GITHUB_BEARER_TOKEN", "credentialsJSON:34cb38a5-9124-41c4-8497-74ed6289d751", display = ParameterDisplay.HIDDEN, label = "Matticbot GitHub Bearer Token") - text("CALYPSO_E2E_DASHBOARD_AWS_S3_ROOT", "s3://a8c-calypso-e2e-reports", label = "Calypso E2E Dashboard S3 bucket root") - - // TeamCity Rich Notificaion App. - password("TEAMCITY_SLACK_RICH_NOTIFICATION_APP_OAUTH_TOKEN", "credentialsJSON:1ade13b3-4f88-4b2a-a71a-9c6f95698d00", display=ParameterDisplay.HIDDEN) - - // Values related to the WPCOM VCS - password("WPCOM_JETPACK_PLUGIN_PATH", "credentialsJSON:db955a02-2a79-4167-a823-ac4840fd71d7", display = ParameterDisplay.HIDDEN) - password("WPCOM_JETPACK_MU_WPCOM_PLUGIN_PATH", "credentialsJSON:81683f57-784e-4535-9af0-26212c9e599b", display = ParameterDisplay.HIDDEN) - } - - features { - dockerRegistry { - id = "PROJECT_EXT_15" - name = "Docker Registry" - url = "registry.a8c.com" - } - githubConnection { - id = "PROJECT_EXT_8" - displayName = "GitHub.com" - clientId = "abfe9b6b38deb65e68e5" - clientSecret = "credentialsJSON:52797023-03f8-430a-b66f-2ac50fcc9608" - } - } -} - -// This build should mostly be triggered by other builds. -object YarnInstall : BuildType({ - name = "Install Dependencies" - description = "Installs dependencies, e.g. yarn install" - vcs { - root(WpCalypso) - cleanCheckout = true - } - steps { - bashNodeScript { - name = "Yarn Install" - scriptContent = """ - # Install modules - ${_self.yarn_install_cmd} - """.trimIndent() - } - } - features { - perfmon { - } - } -}) - -object BuildBaseImages : BuildType({ - name = "Build base images" - description = "Build base docker images" - - buildNumberPattern = "%build.prefix%.%build.counter%" - - params { - param("build.prefix", "1.0") - param("image_tag", "latest") - } - - vcs { - root(WpCalypso) - cleanCheckout = true - } - - steps { - dockerCommand { - name = "Build base image" - commandType = build { - source = file { - path = "Dockerfile.base" - } - namesAndTags = """ - registry.a8c.com/calypso/base:%image_tag% - registry.a8c.com/calypso/base:%build.number% - """.trimIndent() - commandArgs = "--no-cache --target base --build-arg commit_sha=${Settings.WpCalypso.paramRefs.buildVcsNumber}" - } - param("dockerImage.platform", "linux") - } - dockerCommand { - name = "Build CI e2e image" - commandType = build { - source = file { - path = "Dockerfile.base" - } - namesAndTags = """ - registry.a8c.com/calypso/ci-e2e:%image_tag% - registry.a8c.com/calypso/ci-e2e:%build.number% - """.trimIndent() - commandArgs = "--target ci-e2e" - } - param("dockerImage.platform", "linux") - } - dockerCommand { - name = "Build CI wpcom image" - commandType = build { - source = file { - path = "Dockerfile.base" - } - namesAndTags = """ - registry.a8c.com/calypso/ci-wpcom:%image_tag% - registry.a8c.com/calypso/ci-wpcom:%build.number% - """.trimIndent() - commandArgs = "--target ci-wpcom" - } - param("dockerImage.platform", "linux") - } - dockerCommand { - name = "Push images" - commandType = push { - namesAndTags = """ - registry.a8c.com/calypso/base:%image_tag% - registry.a8c.com/calypso/base:%build.number% - registry.a8c.com/calypso/ci-e2e:%image_tag% - registry.a8c.com/calypso/ci-e2e:%build.number% - registry.a8c.com/calypso/ci-wpcom:%image_tag% - registry.a8c.com/calypso/ci-wpcom:%build.number% - """.trimIndent() - } - } - } - - triggers { - schedule { - schedulingPolicy = cron { - hours = "*/12" - } - branchFilter = """ - +:trunk - """.trimIndent() - triggerBuild = always() - withPendingChangesOnly = false - } - } - - failureConditions { - executionTimeoutMin = 30 - } - - features { - perfmon { - } - dockerSupport { - cleanupPushedImages = true - } - } -}) - -object CheckCodeStyle : BuildType({ - name = "Check code style" - description = "Check code style" - - artifactRules = """ - checkstyle_results => checkstyle_results - """.trimIndent() - - params { - param("env.NODE_ENV", "test") - param("env.TIMING", "1") - } - - vcs { - root(WpCalypso) - cleanCheckout = true - } - - steps { - bashNodeScript { - name = "Prepare environment" - scriptContent = """ - # Install modules - ${_self.yarn_install_cmd} - """ - } - bashNodeScript { - name = "Run linters" - executionMode = BuildStep.ExecutionMode.RUN_ON_FAILURE - scriptContent = """ - # Lint files - yarn run eslint --format checkstyle --output-file "./checkstyle_results/eslint/results.xml" . - """ - } - } - - triggers { - schedule { - schedulingPolicy = daily { - hour = 5 - } - branchFilter = """ - +:trunk - """.trimIndent() - triggerBuild = always() - withPendingChangesOnly = false - } - vcs { - branchFilter = """ - +:renovate/eslint-packages - +:renovate/major-linters - +:renovate/linters - """.trimIndent() - } - } - - failureConditions { - executionTimeoutMin = 20 - nonZeroExitCode = false - failOnMetricChange { - metric = BuildFailureOnMetric.MetricType.INSPECTION_ERROR_COUNT - units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT - comparison = BuildFailureOnMetric.MetricComparison.MORE - compareTo = build { - buildRule = lastSuccessful() - } - } - } - - features { - feature { - type = "xml-report-plugin" - param("xmlReportParsing.reportType", "checkstyle") - param("xmlReportParsing.reportDirs", "checkstyle_results/**/*.xml") - param("xmlReportParsing.verboseOutput", "true") - } - perfmon { - } - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } -}) - -object SmartBuildLauncher : BuildType({ - name = "Smart Build Launcher" - description = "Launches TeamCity builds based on which files were modified in VCS." - - vcs { - root(Settings.WpCalypso) - cleanCheckout = true - } - - features { - pullRequests { - vcsRootExtId = "${Settings.WpCalypso.id}" - provider = github { - authType = token { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - filterAuthorRole = PullRequests.GitHubRoleFilter.EVERYBODY - } - } - - commitStatusPublisher { - vcsRootExtId = "${Settings.WpCalypso.id}" - publisher = github { - githubUrl = "https://api.github.com" - authType = personalToken { - token = "credentialsJSON:57e22787-e451-48ed-9fea-b9bf30775b36" - } - } - } - } - - steps { - bashNodeScript { - name = "Install and build dependencies" - scriptContent = """ - $yarn_install_cmd - yarn workspace @automattic/dependency-finder build - """ - } - bashNodeScript { - name = "Launch relevant builds" - scriptContent = """ - node ./packages/dependency-finder/dist/esm/index.js - """ - } - } -}) - -object WpCalypso : GitVcsRoot({ - name = "wp-calypso" - url = "git@github.com:Automattic/wp-calypso.git" - pushUrl = "git@github.com:Automattic/wp-calypso.git" - branch = "refs/heads/trunk" - branchSpec = "+:refs/heads/*" - useTagsAsBranches = true - authMethod = uploadedKey { - uploadedKey = "matticbot" - } -}) diff --git a/client/my-sites/earn/memberships/section.tsx b/client/my-sites/earn/memberships/section.tsx index 9c01b9a6fadb48..4eb1045254f87c 100644 --- a/client/my-sites/earn/memberships/section.tsx +++ b/client/my-sites/earn/memberships/section.tsx @@ -94,7 +94,14 @@ function MembershipsSection( { query }: MembershipsSectionProps ) {
{ isMembershipsSandboxed === 'sandbox' && ( - { translate( 'Memberships Sandbox Active' ) } + + { translate( 'Memberships Sandbox Active' ) } + ) } { ! hasConnectedAccount && (