diff --git a/.github/workflows/e2e-fulltests-ci.yml b/.github/workflows/e2e-fulltests-ci.yml index 907654739d..f167d0ae67 100644 --- a/.github/workflows/e2e-fulltests-ci.yml +++ b/.github/workflows/e2e-fulltests-ci.yml @@ -58,6 +58,7 @@ jobs: curl -fsSL -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" -H "Authorization: Bearer ${{ github.token }}" "${{ github.api_url }}/repos/${{ github.repository }}/pulls/${PR_NUMBER}" -o pr.json echo "commit_sha=$(jq -r .head.sha > $GITHUB_OUTPUT echo "BRANCH=server-pr-${PR_NUMBER}" >> $GITHUB_OUTPUT + # For reference, the real branch name may be retrievable as follows: #echo "BRANCH=$(jq -r .head.ref > $GITHUB_OUTPUT else echo "commit_sha=$(git rev-parse --verify HEAD)" >> $GITHUB_OUTPUT @@ -77,18 +78,32 @@ jobs: outputs: status_check_context: "${{ steps.generate.outputs.status_check_context }}" workers_number: "${{ steps.generate.outputs.workers_number }}" + server_uppercase: "${{ steps.generate.outputs.server_uppercase }}" # Required for license selection + SERVER: "${{ steps.generate.outputs.SERVER }}" ENABLED_DOCKER_SERVICES: "${{ steps.generate.outputs.ENABLED_DOCKER_SERVICES }}" TEST_FILTER: "${{ steps.generate.outputs.TEST_FILTER }}" BUILD_ID: "${{ steps.generate.outputs.BUILD_ID }}" + TM4J_ENABLE: "${{ steps.generate.outputs.TM4J_ENABLE }}" env: GH_TOKEN: "${{ github.token }}" PR_NUMBER: "${{ inputs.PR_NUMBER || '' }}" + REPORT_TYPE: "${{ inputs.REPORT_TYPE }}" # We could exclude the @smoke group for PRs, but then we wouldn't have it in the report TEST_FILTER_PR: >- --stage="@prod" --excludeGroup="@te_only,@cloud_only,@high_availability" --sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap" --sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa,@license_removal" + TEST_FILTER_DAILY_ONPREM: >- + --stage="@prod" + --excludeGroup="@te_only,@cloud_only,@high_availability" + --sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap,@playbooks" + --sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa,@license_removal" + TEST_FILTER_DAILY_CLOUD: >- + --stage="@prod" + --excludeGroup="@not_cloud,@cloud_trial,@e20_only,@te_only,@high_availability,@license_removal" + --sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap,@playbooks" + --sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa" MM_ENV: "${{ inputs.MM_ENV || '' }}" steps: - name: ci/generate-test-variables @@ -99,19 +114,35 @@ jobs: # Reference on BUILD_ID parsing: https://github.com/saturninoabril/automation-dashboard/blob/175891781bf1072c162c58c6ec0abfc5bcb3520e/lib/common_utils.ts#L3-L23 BUILD_ID_PREFIX="${{ github.run_id }}_${{ github.run_attempt }}-${COMMIT_SHA::7}" MM_ENV_HASH=$(md5sum -z <<<"$MM_ENV" | cut -c-8) - case "${{ inputs.REPORT_TYPE }}" in + SERVER=onprem + case "$REPORT_TYPE" in NONE | PR) echo "status_check_context=E2E Tests/test${MM_ENV:+/$MM_ENV_HASH}" >> $GITHUB_OUTPUT echo "workers_number=20" >> $GITHUB_OUTPUT - echo "ENABLED_DOCKER_SERVICES=postgres inbucket minio openldap elasticsearch keycloak" >> $GITHUB_OUTPUT echo "TEST_FILTER=$TEST_FILTER_PR" >> $GITHUB_OUTPUT - echo "BUILD_ID=${BUILD_ID_PREFIX}-pr-onprem-ent" >> $GITHUB_OUTPUT + echo "BUILD_ID=${BUILD_ID_PREFIX}-${REPORT_TYPE@L}-${SERVER}-ent" >> $GITHUB_OUTPUT + ;; + MASTER | MASTER_UNSTABLE | CLOUD | CLOUD_UNSTABLE) + IS_TEST_UNSTABLE=$(sed -n -E 's/^.*(UNSTABLE).*$/\1/p' <<< "$REPORT_TYPE") # Variable is UNSTABLE if report type is for unstable tests + if grep -q CLOUD <<<$REPORT_TYPE; then + SERVER=cloud + fi + TEST_FILTER_VARIABLE="TEST_FILTER_DAILY_${SERVER@U}" + BUILD_ID_SUFFIX="${IS_TEST_UNSTABLE:+unstable-}daily-${SERVER}-ent" + echo "status_check_context=E2E Tests/test-${BUILD_ID_SUFFIX}${MM_ENV:+/$MM_ENV_HASH}" >> $GITHUB_OUTPUT + echo "workers_number=10" >> $GITHUB_OUTPUT # Daily tests are not time critical, and it's more efficient to run on fewer workers + echo "TEST_FILTER=${!TEST_FILTER_VARIABLE} ${IS_TEST_UNSTABLE:+--invert}" >> $GITHUB_OUTPUT + echo "BUILD_ID=${BUILD_ID_PREFIX}-${BUILD_ID_SUFFIX}" >> $GITHUB_OUTPUT + echo "TM4J_ENABLE=true" >> $GITHUB_OUTPUT ;; *) - # TODO implement other test types, in the future + # TODO implement release testing, in the future echo "Fatal: unimplemented test type. Aborting." exit 1 esac + echo "SERVER=${SERVER}" >> $GITHUB_OUTPUT + echo "server_uppercase=${SERVER@U}" >> $GITHUB_OUTPUT + echo "ENABLED_DOCKER_SERVICES=postgres inbucket minio openldap elasticsearch keycloak" >> $GITHUB_OUTPUT - name: ci/notify-user run: | if [ -n "$PR_NUMBER" ]; then @@ -142,6 +173,7 @@ jobs: testcase_failure_fatal: false run_preflight_checks: false enable_reporting: true + SERVER: "${{ needs.generate-test-variables.outputs.SERVER }}" ENABLED_DOCKER_SERVICES: "${{ needs.generate-test-variables.outputs.ENABLED_DOCKER_SERVICES }}" TEST_FILTER: "${{ needs.generate-test-variables.outputs.TEST_FILTER }}" MM_ENV: "${{ inputs.MM_ENV || '' }}" @@ -149,11 +181,12 @@ jobs: BUILD_ID: "${{ needs.generate-test-variables.outputs.BUILD_ID }}" REPORT_TYPE: "${{ inputs.REPORT_TYPE }}" secrets: - MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}" + MM_LICENSE: "${{ secrets[format('MM_E2E_TEST_LICENSE_{0}_ENT', needs.generate-test-variables.outputs.server_uppercase)] }}" AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}" AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}" PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}" REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}" - ### These are disabled until release tests are implemented - #REPORT_TM4J_API_KEY: "${{ secrets.MM_E2E_TM4J_API_KEY }}" - #REPORT_TEST_CYCLE_LINK_PREFIX: "${{ secrets.MM_E2E_TEST_CYCLE_LINK_PREFIX }}" + REPORT_TM4J_API_KEY: "${{ needs.generate-test-variables.outputs.TM4J_ENABLE == 'true' && secrets.MM_E2E_TM4J_API_KEY || '' }}" + REPORT_TM4J_TEST_CYCLE_LINK_PREFIX: "${{ secrets.MM_E2E_TEST_CYCLE_LINK_PREFIX }}" + CWS_URL: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_URL || '' }}" + CWS_EXTRA_HTTP_HEADERS: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS || '' }}" diff --git a/.github/workflows/e2e-tests-ci-template.yml b/.github/workflows/e2e-tests-ci-template.yml index 8d9bf5a2f1..f969cd839e 100644 --- a/.github/workflows/e2e-tests-ci-template.yml +++ b/.github/workflows/e2e-tests-ci-template.yml @@ -30,6 +30,10 @@ on: type: boolean required: false default: false + SERVER: + type: string # Valid values are: onprem, cloud + required: false + default: onprem ENABLED_DOCKER_SERVICES: type: string required: false @@ -63,6 +67,10 @@ on: required: false REPORT_TM4J_TEST_CYCLE_LINK_PREFIX: required: false + CWS_URL: + required: false + CWS_EXTRA_HTTP_HEADERS: + required: false jobs: update-initial-status: @@ -150,21 +158,31 @@ jobs: runs-on: ubuntu-22.04 needs: - update-initial-status + defaults: + run: + shell: bash outputs: - workers: "${{ steps.workers.outputs.workers }}" + workers: "${{ steps.generate.outputs.workers }}" + SERVER_IMAGE: "${{ steps.generate.outputs.SERVER_IMAGE }}" steps: - name: ci/checkout-repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: ref: ${{ inputs.commit_sha }} fetch-depth: 0 - - name: ci/generate-workers - id: workers + - name: ci/generate-build-variables + id: generate env: WORKERS: ${{ inputs.workers_number }} + REPORT_TYPE: ${{ inputs.REPORT_TYPE }} run: | [ "$WORKERS" -gt "0" ] # Assert that the workers number is an integer greater than 0 echo "workers="$(jq --slurp --compact-output '[range('"$WORKERS"')] | map(tostring)' /dev/null) >> $GITHUB_OUTPUT + if grep -qE '^((MASTER|CLOUD)(_UNSTABLE)?)$' <<<"$REPORT_TYPE"; then + # For MASTER, MASTER_UNSTABLE, CLOUD and CLOUD_UNSTABLE runs, always use the latest master image + # The commit_sha is still used for reporting the test result, and for the testing scripts and test cases + echo "SERVER_IMAGE=mattermostdevelopment/mattermost-enterprise-edition:master" >> $GITHUB_OUTPUT + fi generate-test-cycle: runs-on: ubuntu-22.04 @@ -237,6 +255,8 @@ jobs: env: AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}" AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}" + SERVER: "${{ inputs.SERVER }}" + SERVER_IMAGE: "${{ needs.generate-build-variables.outputs.SERVER_IMAGE }}" MM_LICENSE: "${{ secrets.MM_LICENSE }}" ENABLED_DOCKER_SERVICES: "${{ inputs.ENABLED_DOCKER_SERVICES }}" TEST_FILTER: "${{ inputs.TEST_FILTER }}" @@ -245,6 +265,8 @@ jobs: BUILD_ID: "${{ inputs.BUILD_ID }}" CI_BASE_URL: "http://localhost:8065/?worker_index=${{ matrix.worker_index }}" CYPRESS_pushNotificationServer: "${{ secrets.PUSH_NOTIFICATION_SERVER }}" + CWS_URL: "${{ secrets.CWS_URL }}" + CWS_EXTRA_HTTP_HEADERS: "${{ secrets.CWS_EXTRA_HTTP_HEADERS }}" steps: - name: ci/checkout-repo uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -282,6 +304,7 @@ jobs: runs-on: ubuntu-22.04 needs: - test + - generate-build-variables defaults: run: shell: bash @@ -322,6 +345,8 @@ jobs: if: "${{ inputs.enable_reporting }}" env: TYPE: "${{ inputs.REPORT_TYPE }}" + SERVER: "${{ inputs.SERVER }}" + SERVER_IMAGE: "${{ needs.generate-build-variables.outputs.SERVER_IMAGE }}" WEBHOOK_URL: "${{ secrets.REPORT_WEBHOOK_URL }}" BRANCH: "${{ inputs.BRANCH }}" BUILD_ID: "${{ inputs.BUILD_ID }}" diff --git a/e2e-tests/.ci/.e2erc b/e2e-tests/.ci/.e2erc index 0ebb1b67e0..01f1d3bbfc 100644 --- a/e2e-tests/.ci/.e2erc +++ b/e2e-tests/.ci/.e2erc @@ -87,7 +87,7 @@ alias docker-compose-mmdashboard='${MME2E_DC_DASHBOARD}' # Default values for optional variables export SERVER_IMAGE_DEFAULT="mattermostdevelopment/mattermost-enterprise-edition:$(git rev-parse --short=7 HEAD)" export BROWSER_DEFAULT="chrome" -export SERVER_DEFAULT="self-hosted" +export SERVER_DEFAULT="onprem" export TEST_DEFAULT="cypress" export ENABLED_DOCKER_SERVICES_DEFAULT="postgres inbucket" export TEST_FILTER_DEFAULT='--stage=@prod --group=@smoke' diff --git a/e2e-tests/.ci/report.publish.sh b/e2e-tests/.ci/report.publish.sh index 2c10061955..9d946e9b89 100755 --- a/e2e-tests/.ci/report.publish.sh +++ b/e2e-tests/.ci/report.publish.sh @@ -8,15 +8,26 @@ set -e -u -o pipefail cd "$(dirname "$0")" . .e2erc -# Default required variables, assert that they are set, and document optional variables +# Default or assert variables required by the save_report.js script, and document optional variables : ${FULL_REPORT:=false} # Valid values: true, false -: ${TYPE:=NONE} # Valid values: PR, RELEASE, MASTER, MASTER_UNSTABLE, CLOUD, CLOUD_UNSTABLE, NONE (which is the same as omitting it) +: ${TYPE:=NONE} # Valid values: PR, RELEASE, MASTER, MASTER_UNSTABLE, CLOUD, CLOUD_UNSTABLE, NONE (which is the same as omitting it); also known as REPORT_TYPE : ${WEBHOOK_URL:-} # Optional. Mattermost webhook to post the report back to : ${RELEASE_DATE:-} # Optional. If set, its value will be included in the report as the release date of the tested artifact +if [ "$TYPE" = "PR" ]; then + # In this case, we expect the PR number to be present in the BRANCH variable + BRANCH_REGEX='^server-pr-[0-9]+$' + if ! grep -qE "${BRANCH_REGEX}"<<<"$BRANCH"; then + mme2e_log "Error: when using TYPE=PR, the BRANCH variable should respect regex '$BRANCH_REGEX'. Aborting." >&2 + exit 1 + fi + export PULL_REQUEST="https://github.com/mattermost/mattermost/pull/${BRANCH##*-}" +fi # Env vars used during the test. Their values will be included in the report -: ${BRANCH:?} +: ${TEST:?} # See E2E tests' readme; usually set to 'cypress' +: ${BRANCH:?} # May be either a ref, a commit hash, or 'server-pr-PR_NUMBER' (if TYPE=PR) : ${BUILD_ID:?} +: ${SERVER:?} # May be either 'onprem' or 'cloud' : ${MM_ENV:-} # Populate intermediate variables @@ -24,26 +35,45 @@ export BUILD_TAG="${SERVER_IMAGE##*/}" export MM_DOCKER_IMAGE="${BUILD_TAG%%:*}" # NB: the 'mattermostdevelopment/' prefix is assumed export MM_DOCKER_TAG="${BUILD_TAG##*:}" export SERVER_TYPE="${SERVER}" -# NB: assume that BRANCH follows the convention 'server-pr-${PR_NUMBER}'. If multiple PRs match, the last one is used to generate the link -# Only needed if TYPE=PR -export PULL_REQUEST="https://github.com/mattermost/mattermost/pull/${BRANCH##*-}" if [ -n "${TM4J_API_KEY:-}" ]; then + # Set additional variables required for Zephyr reporting + if grep -q 'UNSTABLE' <<<"$TYPE"; then + export TEST_SUITE=prod + else + export TEST_SUITE=unstable + fi + if [ "$TYPE" = "RELEASE" ]; then + export SERVER_ARTIFACT_TYPE=release + else + export SERVER_ARTIFACT_TYPE=master + export TEST_IS_DAILY=yes + fi export TM4J_ENABLE=true export JIRA_PROJECT_KEY=MM - export TM4J_ENVIRONMENT_NAME="${TEST}/${BROWSER}/${SERVER}" - case "${SERVER}" in - cloud) - export TM4J_FOLDER_ID="2014474" - ;; + export TM4J_ENVIRONMENT_NAME="${TEST@u}/${BROWSER@u}/${SERVER_ARTIFACT_TYPE}-${SERVER_TYPE}-ent${TEST_IS_DAILY:+-${TEST_SUITE}}" + # Assert that the test type is among the ones supported by Zephyr, and select the corresponding folderId + case "${SERVER}-${TYPE}" in + onprem-RELEASE) + export TM4J_FOLDER_ID="2014475" ;; + onprem-MASTER) + export TM4J_FOLDER_ID="2014476" ;; + onprem-MASTER_UNSTABLE) + export TM4J_FOLDER_ID="2014478" ;; + cloud-RELEASE) + export TM4J_FOLDER_ID="2014474" ;; + cloud-CLOUD) + export TM4J_FOLDER_ID="2014479" ;; + cloud-CLOUD_UNSTABLE) + export TM4J_FOLDER_ID="2014481" ;; *) - export TM4J_FOLDER_ID="2014475" - ;; + mme2e_log "Error: unsupported Zephyr environment for the requested report (SERVER=${SERVER}, TYPE=${TYPE}). Aborting." >&2 + exit 1 esac : ${TEST_CYCLE_LINK_PREFIX:?} - : ${TM4J_CYCLE_KEY:-} - : ${TM4J_CYCLE_NAME:-} - mme2e_log "TMJ4 integration enabled." + : ${TM4J_CYCLE_KEY:-} # Optional. Populated automatically by the reporting script + : ${TM4J_CYCLE_NAME:-} # Optional. Populated automatically by the reporting script + mme2e_log "TMJ4 integration enabled. Environment: $TM4J_ENVIRONMENT_NAME" fi if [ -n "${DIAGNOSTIC_WEBHOOK_URL:-}" ]; then diff --git a/e2e-tests/.ci/server.cloud_init.sh b/e2e-tests/.ci/server.cloud_init.sh index 23d797fe5f..a5072306bf 100755 --- a/e2e-tests/.ci/server.cloud_init.sh +++ b/e2e-tests/.ci/server.cloud_init.sh @@ -15,7 +15,7 @@ MME2E_ENVCHECK_MSG="variable required for initializing cloud tests, but is empty : "${CWS_URL:?$MME2E_ENVCHECK_MSG}" : "${MM_LICENSE:?$MME2E_ENVCHECK_MSG}" -response=$(curl -X POST "${CWS_URL}/api/v1/internal/tests/create-customer?sku=cloud-enterprise&is_paid=true") +response=$(curl -fsSL -X POST -H @- "${CWS_URL}/api/v1/tests/create-customer?sku=cloud-enterprise&is_paid=true" <<<"${CWS_EXTRA_HTTP_HEADERS:-}") MM_CUSTOMER_ID=$(echo "$response" | jq -r .customer_id) MM_CLOUD_API_KEY=$(echo "$response" | jq -r .api_key) MM_CLOUD_INSTALLATION_ID=$(echo "$response" | jq -r .installation_id) diff --git a/e2e-tests/.ci/server.cloud_teardown.sh b/e2e-tests/.ci/server.cloud_teardown.sh index 70359efa20..84666fd98b 100755 --- a/e2e-tests/.ci/server.cloud_teardown.sh +++ b/e2e-tests/.ci/server.cloud_teardown.sh @@ -19,6 +19,6 @@ MME2E_ENVCHECK_MSG="variable required for tearing down cloud tests, but is empty : "${MM_CUSTOMER_ID:?$MME2E_ENVCHECK_MSG}" mme2e_log "Deleting customer $MM_CUSTOMER_ID." -curl -X DELETE "${CWS_URL}/api/v1/internal/tests/customers/$MM_CUSTOMER_ID/payment-customer" +curl -fsSL -X DELETE -H @- "${CWS_URL}/api/v1/tests/customers/$MM_CUSTOMER_ID/payment-customer" <<<"${CWS_EXTRA_HTTP_HEADERS:-}" mme2e_log "Test cloud customer deleted, MM_CUSTOMER_ID: $MM_CUSTOMER_ID." diff --git a/e2e-tests/README.md b/e2e-tests/README.md index 0a5787c643..50f23281b0 100644 --- a/e2e-tests/README.md +++ b/e2e-tests/README.md @@ -16,7 +16,7 @@ Instructions, tl;dr: create a local branch with your E2E test changes, then open Instructions, detailed: 1. (optional, undefined variables are set to sane defaults) Create the `.ci/env` file, and populate it with the variables you need out of the following list: - * `SERVER`: either `self-hosted` (default) or `cloud`. + * `SERVER`: either `onprem` (default) or `cloud`. * `CWS_URL` (mandatory when `SERVER=cloud`, only used in such case): when spinning up a cloud-like test server that communicates with a test instance of a customer web server. * `TEST`: either `cypress` (default), `playwright`, or `none` (to avoid creating the cypress/playwright sidecar containers, e.g. if you only want to launch a server instance) * `ENABLED_DOCKER_SERVICES`: a space-separated list of services to start alongside the server. Default to `postgres inbucket`, for smoke test purposes and for lightweight and faster start-up time. Depending on the test requirement being worked on, you may want to override as needed, as such: @@ -27,6 +27,7 @@ Instructions, detailed: * The following variables, which will be passed over to the cypress container: `BRANCH`, `BUILD_ID`, `CI_BASE_URL`, `BROWSER`, `AUTOMATION_DASHBOARD_URL` and `AUTOMATION_DASHBOARD_TOKEN` * The `SERVER_IMAGE` variable can also be set if you want to select a custom mattermost-server image. If not specified, the value of the `SERVER_IMAGE_DEFAULT` variable defined in file `.ci/.e2erc` is used. * The `TEST_FILTER` variable can also be set, to customize which tests you want Cypress to run. If not specified, only the smoke tests will run. Please check the `e2e-tests/cypress/run_tests.js` file for details about its format. + * More variables may be required to configure reporting and cloud interactions. Check the content of the `.ci/report.publish.sh` and `.ci/server.cloud_*.sh` scripts for reference. 2. (optional) `make start-dashboard && make generate-test-cycle`: start the automation dashboard in the background, and initiate a test cycle on it, for the given `BUILD_ID` * NB: the `BUILD_ID` value should stay the same across the `make generate-test-cycle` command, and the subsequent `make` (see next step). If you need to initiate a new test cycle on the same dashboard, you'll need to change the `BUILD_ID` value and rerun both `make generate-test-cycle` and `make`. * Note that part of the dashboard functionality assumes the `BUILD_ID` to have a certain format (see [here](https://github.com/saturninoabril/automation-dashboard/blob/175891781bf1072c162c58c6ec0abfc5bcb3520e/lib/common_utils.ts#L3-L23) for details). This is not relevant for local running, but it's important to note in the testing pipelines. diff --git a/e2e-tests/cypress/save_report.js b/e2e-tests/cypress/save_report.js index 7f1abc069e..8fd2cd6330 100644 --- a/e2e-tests/cypress/save_report.js +++ b/e2e-tests/cypress/save_report.js @@ -24,7 +24,9 @@ * For sending hooks to Mattermost channels * - FULL_REPORT, WEBHOOK_URL and DIAGNOSTIC_WEBHOOK_URL * Test type - * - TYPE=[type], e.g. "MASTER", "PR", "RELEASE", "CLOUD" + * - TYPE=[type]; valid values: "PR", "RELEASE", "MASTER", "MASTER_UNSTABLE", "CLOUD", "CLOUD_UNSTABLE", "NONE" + * Server type + * - SERVER_TYPE=[type]; used for the 'Test Server' field in the webhook. Any string representing the server type is valid, common values are "onprem" and "cloud" */ const {merge} = require('mochawesome-merge');