From ddbcda7480bd613046acc54054d508de44fbb5f0 Mon Sep 17 00:00:00 2001 From: mvitale1989 Date: Tue, 30 May 2023 17:34:15 +0200 Subject: [PATCH 01/11] Prepare: run E2E smoketests with GitHub actions (#23301) - Port E2E testing scripts from cypress-ui-automation - Move server to docker-compose, move E2E images to ecrpublic * Integrate General channel renaming, fixes - Add local automation-dashboard - Add readme - Add E2E smoketests - Bump postgres to 12 --------- Co-authored-by: Mattermost Build Co-authored-by: Saturnino Abril Co-authored-by: Antonis Stamatiou --- .github/workflows/e2e-tests-ci.yml | 72 +++++++++++-- e2e-tests/.ci/.e2erc | 75 ++++++++++++++ e2e-tests/.ci/.env.cypress | 1 + e2e-tests/.ci/.env.dashboard | 1 + e2e-tests/.ci/.env.server | 1 + e2e-tests/.ci/.gitignore | 5 + e2e-tests/.ci/dashboard.entrypoint.sh | 21 ++++ e2e-tests/.ci/dashboard.override.yml | 24 +++++ e2e-tests/.ci/dashboard.start.sh | 29 ++++++ e2e-tests/.ci/dashboard.stop.sh | 6 ++ e2e-tests/.ci/server.override.yml | 121 ++++++++++++++++++++++ e2e-tests/.ci/server.prepare.sh | 49 +++++++++ e2e-tests/.ci/server.run_cypress.sh | 46 ++++++++ e2e-tests/.ci/server.start.sh | 45 ++++++++ e2e-tests/.ci/server.stop.sh | 7 ++ e2e-tests/.gitignore | 3 + e2e-tests/Makefile | 28 +++++ e2e-tests/README.md | 33 ++++++ e2e-tests/cypress/package-lock.json | 2 +- e2e-tests/cypress/tests/support/index.js | 3 + server/build/gitlab-dc.common.yml | 57 ++++++++-- server/build/gitlab-dc.mysql.yml | 9 +- server/build/gitlab-dc.postgres.yml | 16 +-- server/build/gitlab-dc.schemamysql.yml | 9 +- server/build/gitlab-dc.schemapostgres.yml | 9 +- 25 files changed, 623 insertions(+), 49 deletions(-) create mode 100644 e2e-tests/.ci/.e2erc create mode 100644 e2e-tests/.ci/.env.cypress create mode 100644 e2e-tests/.ci/.env.dashboard create mode 100644 e2e-tests/.ci/.env.server create mode 100644 e2e-tests/.ci/.gitignore create mode 100755 e2e-tests/.ci/dashboard.entrypoint.sh create mode 100644 e2e-tests/.ci/dashboard.override.yml create mode 100755 e2e-tests/.ci/dashboard.start.sh create mode 100755 e2e-tests/.ci/dashboard.stop.sh create mode 100644 e2e-tests/.ci/server.override.yml create mode 100755 e2e-tests/.ci/server.prepare.sh create mode 100755 e2e-tests/.ci/server.run_cypress.sh create mode 100755 e2e-tests/.ci/server.start.sh create mode 100755 e2e-tests/.ci/server.stop.sh create mode 100644 e2e-tests/Makefile create mode 100644 e2e-tests/README.md diff --git a/.github/workflows/e2e-tests-ci.yml b/.github/workflows/e2e-tests-ci.yml index e526b8a79ca8b..7f7ce780222ed 100644 --- a/.github/workflows/e2e-tests-ci.yml +++ b/.github/workflows/e2e-tests-ci.yml @@ -1,17 +1,35 @@ -name: mattermost-e2e-tests +name: E2E Tests on: - pull_request: - push: - branches: - - master - - mono-repo* + # For PRs, this workflow gets triggered from the Argo Events platform. + # Check the following repo for details: https://github.com/mattermost/delivery-platform + workflow_dispatch: + inputs: + commit_sha: + type: string + required: false defaults: run: shell: bash + jobs: + update-initial-status: + runs-on: ubuntu-22.04 + steps: + - uses: mattermost/actions/delivery/update-commit-status@main + env: + GITHUB_TOKEN: ${{ github.token }} + with: + repository_full_name: ${{ github.repository }} + commit_sha: ${{ inputs.commit_sha || github.sha }} + context: ci/e2e-tests + description: E2E tests for mattermost server app + status: pending + cypress-check: runs-on: ubuntu-22.04 + needs: + - update-initial-status defaults: run: working-directory: e2e-tests/cypress @@ -24,15 +42,18 @@ jobs: with: node-version-file: ".nvmrc" cache: npm - cache-dependency-path: 'e2e-tests/cypress/package-lock.json' + cache-dependency-path: "e2e-tests/cypress/package-lock.json" - name: ci/cypress/npm-install run: | npm ci - name: ci/cypress/npm-check run: | npm run check + playwright-check: runs-on: ubuntu-22.04 + needs: + - update-initial-status defaults: run: working-directory: e2e-tests/playwright @@ -45,7 +66,7 @@ jobs: with: node-version-file: ".nvmrc" cache: npm - cache-dependency-path: 'e2e-tests/playwright/package-lock.json' + cache-dependency-path: "e2e-tests/playwright/package-lock.json" - name: ci/get-webapp-node-modules working-directory: webapp # requires build of client and types @@ -57,3 +78,38 @@ jobs: - name: ci/playwright/npm-check run: | npm run check + + smoketests: + runs-on: ubuntu-22.04 + needs: + - cypress-check + - playwright-check + defaults: + run: + working-directory: e2e-tests + steps: + - name: ci/checkout-repo + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - name: ci/e2e-smoketests + run: | + make + # Assert that the run contained 0 failures + CYPRESS_FAILURES=$(find cypress/results -name '*.json' | xargs -l jq -r '.stats.failures' | jq -s add) + echo "Cypress run completed with $CYPRESS_FAILURES failures" + [ "$CYPRESS_FAILURES" = "0" ] + + update-final-status: + runs-on: ubuntu-22.04 + if: always() + needs: + - smoketests + steps: + - uses: mattermost/actions/delivery/update-commit-status@main + env: + GITHUB_TOKEN: ${{ github.token }} + with: + repository_full_name: ${{ github.repository }} + commit_sha: ${{ inputs.commit_sha || github.sha }} + context: ci/e2e-tests + description: E2E tests for mattermost server app + status: ${{ job.status }} diff --git a/e2e-tests/.ci/.e2erc b/e2e-tests/.ci/.e2erc new file mode 100644 index 0000000000000..e663f0ac08d93 --- /dev/null +++ b/e2e-tests/.ci/.e2erc @@ -0,0 +1,75 @@ +# Utility variables +# NB: these assume you `source` them from the directory this file is in +export MME2E_DC_SERVER="docker-compose -p mmserver -f $(readlink -e ../../server/build/gitlab-dc.postgres.yml) -f $(readlink -e ./server.override.yml)" +export MME2E_DC_DASHBOARD="docker-compose -p mmdashboard -f $(readlink -e ./dashboard/docker/docker-compose.yml) -f $(readlink -e ./dashboard.override.yml)" +export MME2E_UID=$(id -u) + +# Default the optional variables that are used in the docker-compose file +export SERVER_IMAGE_DEFAULT="mattermostdevelopment/mm-ee-test:$(git rev-parse --short=7 HEAD)" +export SERVER_IMAGE=${SERVER_IMAGE:-$SERVER_IMAGE_DEFAULT} + +# Function definitions +mme2e_log () { echo "[$(date -Is)]" "$@"; } +mme2e_get_current_shopt_arg () { + # This function lets you get the current value of shell options, e.g. pipefail or allexport, in the form + # of arguments to pass to the 'set' shell function, in order to restore its value later + SHOPT_ARG=${1:?} + case $(set -o | sed -n -E "s/^${SHOPT_ARG}[[:space:]]+(o..?)$/\1/p") in + on) echo -n "-o ${SHOPT_ARG}";; + off) echo -n "+o ${SHOPT_ARG}";; + *) exit 1;; + esac +} +mme2e_load_env_file () { + # This loads the ./env file. Variables are automatically exported + [ -f ./env ] || return 0 + MME2E_PREVIOUS_ALLEXPORT=$(mme2e_get_current_shopt_arg allexport) + set -o allexport + mme2e_log "Loading env file" + . ./env + set ${MME2E_PREVIOUS_ALLEXPORT} +} +mme2e_generate_envfile_from_var_names () { + # Read var names from stdin, one per line + while read VARIABLE; do + [ -z "${!VARIABLE:-}" ] || echo "${VARIABLE}=${!VARIABLE}"; + done +} +mme2e_wait_command_success () { + COMMAND=${1?} + RETRY_MESSAGE=${2?} + RETRIES_LEFT=${3:-1} + RETRIES_INTERVAL=${4:-10} + MME2E_PREVIOUS_PIPEFAIL=$(mme2e_get_current_shopt_arg pipefail) + set -o pipefail + until bash -c "${COMMAND}"; do + RETRIES_LEFT=$((RETRIES_LEFT - 1)) + [ "$RETRIES_LEFT" -le "0" ] && break + mme2e_log "${RETRY_MESSAGE} ($RETRIES_LEFT retries left, sleeping $RETRIES_INTERVAL seconds)" + sleep $RETRIES_INTERVAL + done + set ${MME2E_PREVIOUS_PIPEFAIL} + if [ "$RETRIES_LEFT" = "0" ]; then + exit 1 + fi +} +mme2e_wait_service_healthy () { + SERVICE_NAME=${1?} + RETRIES_LEFT=${2:-1} + RETRIES_INTERVAL=${3:-10} + mme2e_wait_command_success "${MME2E_DC_SERVER} ps ${SERVICE_NAME} | grep -q '\(healthy\)'" "Waiting for ${SERVICE_NAME} container to be healthy" "$RETRIES_LEFT" "$RETRIES_INTERVAL" +} +mme2e_wait_image () { + IMAGE_NAME=${1?} + RETRIES_LEFT=${2:-1} + RETRIES_INTERVAL=${3:-10} + mme2e_wait_command_success "docker pull $IMAGE_NAME" "Waiting for docker image ${IMAGE_NAME} to be available" "$RETRIES_LEFT" "$RETRIES_INTERVAL" +} + +# Utility alias, for interactive shell usage. Can be reversed with 'unalias docker-compose' in your shell +# NB: this won't work in the script +alias docker-compose-mmserver="${MME2E_DC_SERVER}" +alias docker-compose-mmdashboard="${MME2E_DC_DASHBOARD}" + +# Call prerequisite utility functions +mme2e_load_env_file diff --git a/e2e-tests/.ci/.env.cypress b/e2e-tests/.ci/.env.cypress new file mode 100644 index 0000000000000..64c0275276087 --- /dev/null +++ b/e2e-tests/.ci/.env.cypress @@ -0,0 +1 @@ +# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git diff --git a/e2e-tests/.ci/.env.dashboard b/e2e-tests/.ci/.env.dashboard new file mode 100644 index 0000000000000..64c0275276087 --- /dev/null +++ b/e2e-tests/.ci/.env.dashboard @@ -0,0 +1 @@ +# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git diff --git a/e2e-tests/.ci/.env.server b/e2e-tests/.ci/.env.server new file mode 100644 index 0000000000000..64c0275276087 --- /dev/null +++ b/e2e-tests/.ci/.env.server @@ -0,0 +1 @@ +# NB: this file is just a placeholder required by docker-compose. It's supposed to be modified by the CI pipeline and should remain empty in git diff --git a/e2e-tests/.ci/.gitignore b/e2e-tests/.ci/.gitignore new file mode 100644 index 0000000000000..cc1baff8fddcd --- /dev/null +++ b/e2e-tests/.ci/.gitignore @@ -0,0 +1,5 @@ +dashboard +env +!.env.cypress +!.env.server +!.env.dashboard diff --git a/e2e-tests/.ci/dashboard.entrypoint.sh b/e2e-tests/.ci/dashboard.entrypoint.sh new file mode 100755 index 0000000000000..49ccfe40a9f96 --- /dev/null +++ b/e2e-tests/.ci/dashboard.entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e -u -o pipefail + +npm install + +# Run migrations. This is also a way to wait for the database to be up +MIGRATION_ATTEMPTS_LEFT=10 +MIGRATION_ATTEMPTS_INTERVAL=10 +until npm run migrate:latest; do + MIGRATION_ATTEMPTS_LEFT=$((MIGRATION_ATTEMPTS_LEFT - 1)) + [ "$MIGRATION_ATTEMPTS_LEFT" -gt 0 ] || break + echo "Migration script failed, sleeping $MIGRATION_ATTEMPTS_INTERVAL" + sleep $MIGRATION_ATTEMPTS_INTERVAL +done +[ "$MIGRATION_ATTEMPTS_LEFT" -gt 0 ] || { + echo "Migration script failed, exhausted attempts. Giving up." + exit 1 +} + +# Launch the dashboard +exec npm run dev diff --git a/e2e-tests/.ci/dashboard.override.yml b/e2e-tests/.ci/dashboard.override.yml new file mode 100644 index 0000000000000..a444a7be715bc --- /dev/null +++ b/e2e-tests/.ci/dashboard.override.yml @@ -0,0 +1,24 @@ +--- +version: '3.1' + +services: + dashboard: + image: node:16.17.0 + environment: + PG_URI: postgres://mmuser:mostest@db:5432/automation_dashboard_db + JWT_SECRET: s8gGBA3ujKRohSw1L8HLOY7Jjnu2ZYv8 # Generated with e.g. `dd if=/dev/urandom count=24 bs=1 2>/dev/null | base64 -w0` + JWT_USER: cypress-test + JWT_ROLE: integration + JWT_ALG: HS256 + JWT_EXPIRES_IN: 365d + ALLOWED_USER: cypress-test + ALLOWED_ROLE: integration + user: "${MME2E_UID}" + volumes: + - "../:/app" + - "../../dashboard.entrypoint.sh:/usr/local/bin/dashboard.entrypoint.sh:ro" + - "../../.env.dashboard:/var/local/.env.dashboard:rw" + working_dir: /app + entrypoint: /usr/local/bin/dashboard.entrypoint.sh + ports: + - 4000:4000 diff --git a/e2e-tests/.ci/dashboard.start.sh b/e2e-tests/.ci/dashboard.start.sh new file mode 100755 index 0000000000000..89feb25513e76 --- /dev/null +++ b/e2e-tests/.ci/dashboard.start.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e -u -o pipefail +cd $(dirname $0) +. .e2erc + +MME2E_DASHBOARD_REF_DEFAULT="origin/main" +MME2E_DASHBOARD_REF=${MME2E_DASHBOARD_REF:-$MME2E_DASHBOARD_REF_DEFAULT} + +mme2e_log "Cloning the automation-dashboard project" +[ -d dashboard ] || git clone https://github.com/saturninoabril/automation-dashboard.git dashboard +git -C dashboard fetch +git -C dashboard checkout $MME2E_DASHBOARD_REF + +mme2e_log "Starting the dashboard" +${MME2E_DC_DASHBOARD} up -d db dashboard + +mme2e_log "Generating the dashboard's local URL" +MME2E_DC_DASHBOARD_NETWORK=$(${MME2E_DC_DASHBOARD} ps -q dashboard | xargs -l docker inspect | jq -r '.[0].NetworkSettings.Networks | (keys|.[0])') +MME2E_DC_DASHBOARD_GATEWAY=$(docker network inspect $MME2E_DC_DASHBOARD_NETWORK | jq -r '.[0].IPAM.Config[0].Gateway') +AUTOMATION_DASHBOARD_URL="http://${MME2E_DC_DASHBOARD_GATEWAY}:4000/api" + +mme2e_log "Generating a signed JWT token for accessing the dashboard" +AUTOMATION_DASHBOARD_TOKEN=$(${MME2E_DC_DASHBOARD} exec -T -u $MME2E_UID dashboard node script/sign.js | awk '{ print $2; }') # The token secret is specified in the dashboard.override.yml file + +mme2e_log "Generating the .env.dashboard file, to point Cypress to the dashboard URL" +mme2e_generate_envfile_from_var_names >.env.dashboard </dev/null +${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.9.0/com.mattermost.demo-plugin-0.9.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.9.0.tar.gz >/dev/null +${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null +${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null +${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/keycloak.crt >/dev/null <../../server/build/docker/keycloak/keycloak.crt + +# Generate the test mattermosts-server config, and restart its container +mme2e_log "Prepare Server: patching the mattermost-server config" +${MME2E_DC_SERVER} exec -T -e "OUTPUT_CONFIG=/tmp/config_generated.json" -w /opt/mattermost-server/server -- utils go run scripts/config_generator/main.go +${MME2E_DC_SERVER} exec -T -- utils bash </tmp/config_patched.json +EOF +# TODO double check: could there be race conditions, if the server tries to write back to the file? Afaiu, nobody touching the UI -> no changes to the config file +${MME2E_DC_SERVER} exec -T -- utils cat /tmp/config_patched.json | ${MME2E_DC_SERVER} exec -T -- server tee config/config.json >/dev/null +${MME2E_DC_SERVER} restart server +if ! mme2e_wait_service_healthy server 60 10; then + mme2e_log "Mattermost container not healthy, retry attempts exhausted. Giving up." >&2 + exit 1 +fi +mme2e_log "Mattermost container is running and healthy" + +# Inject test data, prepare for E2E tests +mme2e_log "Prepare Server: injecting E2E test data" +${MME2E_DC_SERVER} exec -T -- server mmctl config set TeamSettings.MaxUsersPerTeam 100 --local +${MME2E_DC_SERVER} exec -T -- server mmctl sampledata -u 60 --local +${MME2E_DC_SERVER} exec -T -- openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest' <../../server/tests/test-data.ldif +${MME2E_DC_SERVER} exec -T -- minio sh -c 'mkdir -p /data/mattermost-test' +mme2e_log "Mattermost is running and ready for E2E testing" +mme2e_log "You can use the test data credentials for logging in (username=sysadmin password=Sys@dmin-sample1)" diff --git a/e2e-tests/.ci/server.run_cypress.sh b/e2e-tests/.ci/server.run_cypress.sh new file mode 100755 index 0000000000000..5ab4eb9c6636e --- /dev/null +++ b/e2e-tests/.ci/server.run_cypress.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e -u -o pipefail +cd $(dirname $0) +. .e2erc + +# Set required variables +TEST_FILTER_DEFAULT='--stage=@prod --group=@smoke' +TEST_FILTER=${TEST_FILTER:-$TEST_FILTER_DEFAULT} + +# Print run information +mme2e_log "Printing Cypress container informations" +${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress node -p 'module.paths' +${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress bash <<"EOF" +cat <' > results/junit/empty.xml +EOF + +# Run cypress test +# No need to collect its exit status: if it's nonzero, this script will terminate since we use '-e' +if ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress bash -c '[ -n "${AUTOMATION_DASHBOARD_URL}" ]'; then + mme2e_log "AUTOMATION_DASHBOARD_URL is set. Using run_test_cycle.js for the cypress run" + ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress node --trace-warnings generate_test_cycle.js ${TEST_FILTER} + ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress node run_test_cycle.js | tee ../cypress/logs/cypress.log +else + mme2e_log "AUTOMATION_DASHBOARD_URL is unset. Using run_tests.js for the cypress run" + ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress node run_tests.js ${TEST_FILTER} | tee ../cypress/logs/cypress.log +fi + +# Collect server logs +${MME2E_DC_SERVER} exec -T -- server cat /mattermost/logs/mattermost.log >../cypress/logs/mattermost.log diff --git a/e2e-tests/.ci/server.start.sh b/e2e-tests/.ci/server.start.sh new file mode 100755 index 0000000000000..4e99ae8df7b4c --- /dev/null +++ b/e2e-tests/.ci/server.start.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -e -u -o pipefail +cd $(dirname $0) +. .e2erc + +export BRANCH_DEFAULT=$(git branch --show-current) +export BRANCH=${BRANCH:-$BRANCH_DEFAULT} +export BUILD_ID_DEFAULT=$(date +%s) +export BUILD_ID=${BUILD_ID:-$BUILD_ID_DEFAULT} +export CI_BASE_URL="${CI_BASE_URL:-localhost}" + +# Cleanup old containers, if any +mme2e_log "Stopping leftover E2E containers, if any are running" +${MME2E_DC_SERVER} down -v + +# Generate .env.server +mme2e_log "Generating .env.server" +mme2e_generate_envfile_from_var_names >.env.server <> .env.server +done + +# Generate .env.cypress +mme2e_log "Generating .env.cypress" +mme2e_generate_envfile_from_var_names >.env.cypress <&2 + exit 1 +fi +mme2e_log "Mattermost container is running and healthy" diff --git a/e2e-tests/.ci/server.stop.sh b/e2e-tests/.ci/server.stop.sh new file mode 100755 index 0000000000000..cd7d7f83e1daa --- /dev/null +++ b/e2e-tests/.ci/server.stop.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e -u -o pipefail +cd $(dirname $0) +. .e2erc + +mme2e_log "Stopping E2E containers" +${MME2E_DC_SERVER} down -v diff --git a/e2e-tests/.gitignore b/e2e-tests/.gitignore index 710358c8d0286..ff56c51f94dda 100644 --- a/e2e-tests/.gitignore +++ b/e2e-tests/.gitignore @@ -6,3 +6,6 @@ # Plugin *.tar.gz + +# node +*.lock diff --git a/e2e-tests/Makefile b/e2e-tests/Makefile new file mode 100644 index 0000000000000..babae1a73b9ee --- /dev/null +++ b/e2e-tests/Makefile @@ -0,0 +1,28 @@ +.PHONY: all run stop +all: run +run: start-server prepare-server run-cypress +stop: stop-server stop-dashboard clean-env-placeholders + +.PHONY: start-server prepare-server run-cypress stop-server restart-server +start-server: + ./.ci/server.start.sh +prepare-server: + ./.ci/server.prepare.sh +run-cypress: + ./.ci/server.run_cypress.sh +stop-server: + ./.ci/server.stop.sh +restart-server: stop-server start-server + +.PHONY: start-dashboard stop-dashboard +start-dashboard: + ./.ci/dashboard.start.sh +stop-dashboard: + ./.ci/dashboard.stop.sh + +.PHONY: print-env-placeholders clean-env-placeholders +print-env-placeholders: + find .ci -maxdepth 1 -name '.env.*' | xargs --verbose -l cat +clean-env-placeholders: + git reset .ci/.env.* + git checkout .ci/.env.* diff --git a/e2e-tests/README.md b/e2e-tests/README.md new file mode 100644 index 0000000000000..dac80d245ea01 --- /dev/null +++ b/e2e-tests/README.md @@ -0,0 +1,33 @@ +# E2E testing for the Mattermost web client + +This directory contains the E2E testing code for the Mattermost web client. + +### How to run locally + +The E2E testing scripts depend on the following tools being installed on your system: `docker`, `docker-compose`, `make`, `git`, `jq`, and some common utilities (`coreutils`, `findutils`, `bash`, `awk`, `sed`, `grep`) + +Instructions, tl;dr: create a local branch with your E2E test changes, then open a PR to the `mattermost-server` repo targeting the `master` branch (so that CI will produce the image that docker-compose needs), then run `make` in this directory. + +Instructions, detailed: +1. Create the `.ci/env` file, and populate the variables you need, keeping in mind that: + * The following variables will be passed over to the server container: `MM_LICENSE` (no enterprise features will be available if this is unset), and the exploded `MM_ENV` (a comma-separated list of env var specifications) + * The following variables will be passed over to the cypress container: `BRANCH`, `BUILD_ID`, `CI_BASE_URL`, `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 + * The `TEST_FILTER` variable can also be set, to customize which tests you want cypress to run + * All variables are optional, and will be set to sane defaults +2. (optional) `make start-dashboard`: start the automation-dashboard in the background + * This also sets the `AUTOMATION_DASHBOARD_URL` and `AUTOMATION_DASHBOARD_TOKEN` variables for the cypress container + * Note that if you run the dashboard locally, but also specify other `AUTOMATION_DASHBOARD_*` variables in your env, the latter variables will take precedence +3. `make`: start and prepare the server, then run the cypress tests + * You can track the progress of the run in the `http://localhost:4000/cycles` dashboard, if you launched it locally +4. `make stop`: tears down the server (and the dashboard, if running), then cleans up the env placeholder files + +Notes: +- Aside from some exceptions (e.g. `TEST_FILTER`), most of the variables in `.ci/env` must be set before the `make start-server` command is run. Modifting that file afterwards has no effect, because the containers' env files are generated in that step. +- If you restart the dashboard at any point, you must also restart the server containers, so that it picks up the new IP of the dashboard from the newly generated `.env.dashboard` file +- If you started the dashboard locally in the past, but want to point to another dasbhoard later, you can run `make clean-env-placeholders` to remove references to the local dasbhoard (you'll likely need to restart the server) +- Dynamically set variables for the server or cypress should be managed within the `.env.*` files, rather than in the docker-compose files, to streamline their management. + +##### How to control which tests to run + +The `TEST_FILTER` variable will control which test files to run Cypress tests against. Please check the `e2e-tests/cypress/run_tests.js` file for details about its format. diff --git a/e2e-tests/cypress/package-lock.json b/e2e-tests/cypress/package-lock.json index 2623f423eb451..29aecb84e0d19 100644 --- a/e2e-tests/cypress/package-lock.json +++ b/e2e-tests/cypress/package-lock.json @@ -1,5 +1,5 @@ { - "name": "cypress", + "name": "app", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/e2e-tests/cypress/tests/support/index.js b/e2e-tests/cypress/tests/support/index.js index 8051dafda0471..3e0d8b27ada51 100644 --- a/e2e-tests/cypress/tests/support/index.js +++ b/e2e-tests/cypress/tests/support/index.js @@ -217,6 +217,9 @@ function sysadminSetup(user) { // # Deactivate test bots if any cy.apiDeactivateTestBots(); + // # Disable welcome tours if any + cy.apiDisableTutorials(user.id); + // # Check if default team is present; create if not found. cy.apiGetTeamsForUser().then(({teams}) => { const defaultTeam = teams && teams.length > 0 && teams.find((team) => team.name === DEFAULT_TEAM.name); diff --git a/server/build/gitlab-dc.common.yml b/server/build/gitlab-dc.common.yml index 935f0d2aa88ca..02cb0a9be05b1 100644 --- a/server/build/gitlab-dc.common.yml +++ b/server/build/gitlab-dc.common.yml @@ -1,29 +1,44 @@ version: '2.4' services: minio: - image: ${CI_REGISTRY}/mattermost/ci/images/minio:RELEASE.2019-10-11T00-38-09Z-1 + image: public.ecr.aws/mattermostqa/minio:RELEASE.2019-10-11T00-38-09Z-1 command: "server /data" environment: MINIO_ACCESS_KEY: minioaccesskey MINIO_SECRET_KEY: miniosecretkey MINIO_SSE_MASTER_KEY: "my-minio-key:6368616e676520746869732070617373776f726420746f206120736563726574" + healthcheck: + test: [ "CMD", "nc", "-z", "-w1", "127.0.0.1", "9000" ] + interval: 10s + timeout: 15s + retries: 12 inbucket: - image: ${CI_REGISTRY}/mattermost/ci/images/inbucket:v3.0.0-rc1-2-gc64e7a6-1 + image: public.ecr.aws/mattermostqa/inbucket:3.0.0 restart: always environment: INBUCKET_WEB_ADDR: "0.0.0.0:9001" INBUCKET_POP3_ADDR: "0.0.0.0:10110" INBUCKET_SMTP_ADDR: "0.0.0.0:10025" + healthcheck: + test: [ "CMD", "nc", "-z", "-w1", "127.0.0.1", "10025" ] + interval: 10s + timeout: 15s + retries: 12 openldap: - image: ${CI_REGISTRY}/mattermost/ci/images/openldap:1.4.0-1 + image: public.ecr.aws/mattermostqa/openldap:1.4.0 restart: always environment: LDAP_TLS_VERIFY_CLIENT: "never" LDAP_ORGANISATION: "Mattermost Test" LDAP_DOMAIN: "mm.test.com" LDAP_ADMIN_PASSWORD: "mostest" + healthcheck: + test: [ "CMD", "bash", "-o", "pipefail", "-c", "ss -ltn 'sport = :636' | grep -qE '^LISTEN'" ] + interval: 10s + timeout: 15s + retries: 12 elasticsearch: - image: ${CI_REGISTRY}/mattermost/ci/images/mattermost-elasticsearch-docker:7.17.3 + image: mattermost/mattermost-elasticsearch-docker:7.17.3 environment: http.host: "0.0.0.0" http.port: 9200 @@ -33,10 +48,20 @@ services: http.cors.allow-credentials: "true" transport.host: "127.0.0.1" ES_JAVA_OPTS: "-Xms512m -Xmx512m" + healthcheck: + test: [ "CMD", "bash", "-o", "pipefail", "-c", "curl --silent localhost:9200/_cat/health | awk '{ print $$4 }' | grep -qE '^green$$'" ] + interval: 10s + timeout: 15s + retries: 12 dejavu: - image: ${CI_REGISTRY}/mattermost/ci/images/dejavu:3.4.2-1 + image: public.ecr.aws/mattermostqa/dejavu:3.4.2 + healthcheck: + test: [ "CMD", "nc", "-z", "-w1", "127.0.0.1", "1358" ] + interval: 10s + timeout: 15s + retries: 12 keycloak: - image: ${CI_REGISTRY}/mattermost/ci/images/keycloak:10.0.2-1 + image: public.ecr.aws/mattermostqa/keycloak:10.0.2 restart: always environment: KEYCLOAK_USER: mmuser @@ -45,13 +70,29 @@ services: KEYCLOAK_IMPORT: /setup/realm.json volumes: - "./docker/keycloak:/setup" + healthcheck: + test: [ "CMD", "bash", "-o", "pipefail", "-c", "curl --silent localhost:9990/health | grep -q '\"status\":\"UP\"'" ] + interval: 10s + timeout: 15s + retries: 12 prometheus: - image: ${CI_REGISTRY}/mattermost/ci/images/prometheus:2.27.1-1 + image: public.ecr.aws/mattermostqa/prometheus:v2.27.1 volumes: - "./docker/prometheus-linux.yml:/etc/prometheus/prometheus.yml" + healthcheck: + test: [ "CMD", "wget", "-q", "-O-", "127.0.0.1:9090/-/ready" ] + interval: 10s + timeout: 15s + retries: 12 + # wget -q -O- localhost:3000/healthz | grep -q Ok grafana: - image: ${CI_REGISTRY}/mattermost/ci/images/grafana:8.0.1-1 + image: public.ecr.aws/mattermostqa/grafana:8.0.1 volumes: - "./docker/grafana/grafana.ini:/etc/grafana/grafana.ini" - "./docker/grafana/provisioning:/etc/grafana/provisioning" - "./docker/grafana/dashboards:/var/lib/grafana/dashboards" + healthcheck: + test: [ "CMD", "bash", "-o", "pipefail", "-c", "wget -q -O- localhost:3000/healthz | grep -q Ok" ] + interval: 10s + timeout: 15s + retries: 12 diff --git a/server/build/gitlab-dc.mysql.yml b/server/build/gitlab-dc.mysql.yml index c64e17bc789d1..49b8aa1dc3c64 100644 --- a/server/build/gitlab-dc.mysql.yml +++ b/server/build/gitlab-dc.mysql.yml @@ -1,7 +1,7 @@ version: '2.4' services: mysql: - image: ${CI_REGISTRY}/mattermost/ci/images/mysql:5.7-1 + image: public.ecr.aws/mattermostqa/mysql:5.7.12 restart: always environment: MYSQL_ROOT_HOST: "%" @@ -83,7 +83,7 @@ services: - grafana start_dependencies: - image: ${CI_REGISTRY}/mattermost/ci/images/mattermost-wait-for-dep:latest-1 + image: mattermost/mattermost-wait-for-dep:latest depends_on: - mysql - minio @@ -95,8 +95,3 @@ services: command: mysql:3306 minio:9000 inbucket:9001 openldap:389 elasticsearch:9200 prometheus:9090 grafana:3000 networks: default: - -networks: - default: - external: - name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.postgres.yml b/server/build/gitlab-dc.postgres.yml index 80d884bcf0550..24f4e67b88398 100644 --- a/server/build/gitlab-dc.postgres.yml +++ b/server/build/gitlab-dc.postgres.yml @@ -1,7 +1,7 @@ version: '2.4' services: postgres: - image: ${CI_REGISTRY}/mattermost/ci/images/postgres:10-1 + image: public.ecr.aws/mattermostqa/postgres:12 restart: always environment: POSTGRES_USER: mmuser @@ -12,9 +12,9 @@ services: - "./docker/postgres.conf:/etc/postgresql/postgresql.conf" healthcheck: test: [ "CMD", "pg_isready", "-h", "localhost" ] - interval: 5s - timeout: 10s - retries: 3 + interval: 10s + timeout: 15s + retries: 12 networks: default: aliases: @@ -81,7 +81,7 @@ services: - grafana start_dependencies: - image: ${CI_REGISTRY}/mattermost/ci/images/mattermost-wait-for-dep:latest-1 + image: mattermost/mattermost-wait-for-dep:latest depends_on: - postgres - minio @@ -93,9 +93,3 @@ services: command: postgres:5432 minio:9000 inbucket:9001 openldap:389 elasticsearch:9200 prometheus:9090 grafana:3000 networks: default: - - -networks: - default: - external: - name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.schemamysql.yml b/server/build/gitlab-dc.schemamysql.yml index 77f2688ad528b..422a1cd7af1dc 100644 --- a/server/build/gitlab-dc.schemamysql.yml +++ b/server/build/gitlab-dc.schemamysql.yml @@ -1,7 +1,7 @@ version: '2.4' services: mysql: - image: ${CI_REGISTRY}/mattermost/ci/images/mysql:5.7-1 + image: public.ecr.aws/mattermostqa/mysql:5.7.12 restart: always environment: MYSQL_ROOT_HOST: "%" @@ -23,14 +23,9 @@ services: - mysql start_dependencies: - image: ${CI_REGISTRY}/mattermost/ci/images/mattermost-wait-for-dep:latest-1 + image: mattermost/mattermost-wait-for-dep:latest depends_on: - mysql command: mysql:3306 networks: default: - -networks: - default: - external: - name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.schemapostgres.yml b/server/build/gitlab-dc.schemapostgres.yml index 458566adc6b3b..b27f41ff85e15 100644 --- a/server/build/gitlab-dc.schemapostgres.yml +++ b/server/build/gitlab-dc.schemapostgres.yml @@ -1,7 +1,7 @@ version: '2.4' services: postgres: - image: ${CI_REGISTRY}/mattermost/ci/images/postgres:10-1 + image: public.ecr.aws/mattermostqa/postgres:12 restart: always environment: POSTGRES_USER: mmuser @@ -21,14 +21,9 @@ services: - postgres start_dependencies: - image: ${CI_REGISTRY}/mattermost/ci/images/mattermost-wait-for-dep:latest-1 + image: mattermost/mattermost-wait-for-dep:latest depends_on: - postgres command: postgres:5432 networks: default: - -networks: - default: - external: - name: ${COMPOSE_PROJECT_NAME} From d5953c6fc7d3e0e7245ffb379061ac54c2996b00 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 2 Jun 2023 09:20:34 +0200 Subject: [PATCH 02/11] Re-add the external network for docker-compose --- e2e-tests/.ci/.e2erc | 7 +++++++ e2e-tests/.ci/dashboard.stop.sh | 2 +- e2e-tests/Makefile | 6 ++++-- server/build/gitlab-dc.mysql.yml | 5 +++++ server/build/gitlab-dc.postgres.yml | 5 +++++ server/build/gitlab-dc.schemamysql.yml | 5 +++++ server/build/gitlab-dc.schemapostgres.yml | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/e2e-tests/.ci/.e2erc b/e2e-tests/.ci/.e2erc index e663f0ac08d93..4f246c4c776c8 100644 --- a/e2e-tests/.ci/.e2erc +++ b/e2e-tests/.ci/.e2erc @@ -65,6 +65,12 @@ mme2e_wait_image () { RETRIES_INTERVAL=${3:-10} mme2e_wait_command_success "docker pull $IMAGE_NAME" "Waiting for docker image ${IMAGE_NAME} to be available" "$RETRIES_LEFT" "$RETRIES_INTERVAL" } +mme2e_legacy_setup () { + # These functions are needed until every pipeline depending on the `server/build/gitlab-dc.*.yml` files is adapted to not use external docker networking anymore + # After that is fixed, this function and the external network in the docker-compose files may be removed + export COMPOSE_PROJECT_NAME=mmserver + docker network inspect ${COMPOSE_PROJECT_NAME} >/dev/null 2>&1 || docker network create ${COMPOSE_PROJECT_NAME} +} # Utility alias, for interactive shell usage. Can be reversed with 'unalias docker-compose' in your shell # NB: this won't work in the script @@ -73,3 +79,4 @@ alias docker-compose-mmdashboard="${MME2E_DC_DASHBOARD}" # Call prerequisite utility functions mme2e_load_env_file +mme2e_legacy_setup # Temporary diff --git a/e2e-tests/.ci/dashboard.stop.sh b/e2e-tests/.ci/dashboard.stop.sh index e528548f3c156..f2e471c424aba 100755 --- a/e2e-tests/.ci/dashboard.stop.sh +++ b/e2e-tests/.ci/dashboard.stop.sh @@ -3,4 +3,4 @@ set -e -u -o pipefail cd $(dirname $0) . .e2erc -${MME2E_DC_DASHBOARD} down +[ ! -d dashboard ] || ${MME2E_DC_DASHBOARD} down diff --git a/e2e-tests/Makefile b/e2e-tests/Makefile index babae1a73b9ee..75a04d77ffa49 100644 --- a/e2e-tests/Makefile +++ b/e2e-tests/Makefile @@ -1,3 +1,5 @@ +SHELL := /bin/bash + .PHONY: all run stop all: run run: start-server prepare-server run-cypress @@ -24,5 +26,5 @@ stop-dashboard: print-env-placeholders: find .ci -maxdepth 1 -name '.env.*' | xargs --verbose -l cat clean-env-placeholders: - git reset .ci/.env.* - git checkout .ci/.env.* + git reset .ci/.env.{cypress,server,dashboard} + git checkout .ci/.env.{cypress,server,dashboard} diff --git a/server/build/gitlab-dc.mysql.yml b/server/build/gitlab-dc.mysql.yml index 49b8aa1dc3c64..f498fb730cdec 100644 --- a/server/build/gitlab-dc.mysql.yml +++ b/server/build/gitlab-dc.mysql.yml @@ -95,3 +95,8 @@ services: command: mysql:3306 minio:9000 inbucket:9001 openldap:389 elasticsearch:9200 prometheus:9090 grafana:3000 networks: default: + +networks: + default: + external: + name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.postgres.yml b/server/build/gitlab-dc.postgres.yml index 24f4e67b88398..b562bec6c9f7f 100644 --- a/server/build/gitlab-dc.postgres.yml +++ b/server/build/gitlab-dc.postgres.yml @@ -93,3 +93,8 @@ services: command: postgres:5432 minio:9000 inbucket:9001 openldap:389 elasticsearch:9200 prometheus:9090 grafana:3000 networks: default: + +networks: + default: + external: + name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.schemamysql.yml b/server/build/gitlab-dc.schemamysql.yml index 422a1cd7af1dc..4d6307dc53a4d 100644 --- a/server/build/gitlab-dc.schemamysql.yml +++ b/server/build/gitlab-dc.schemamysql.yml @@ -29,3 +29,8 @@ services: command: mysql:3306 networks: default: + +networks: + default: + external: + name: ${COMPOSE_PROJECT_NAME} diff --git a/server/build/gitlab-dc.schemapostgres.yml b/server/build/gitlab-dc.schemapostgres.yml index b27f41ff85e15..e9dfa2e80cdb2 100644 --- a/server/build/gitlab-dc.schemapostgres.yml +++ b/server/build/gitlab-dc.schemapostgres.yml @@ -27,3 +27,8 @@ services: command: postgres:5432 networks: default: + +networks: + default: + external: + name: ${COMPOSE_PROJECT_NAME} From 78904c9716120fb6e3987f071814270d52afc8e5 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 2 Jun 2023 10:25:46 +0200 Subject: [PATCH 03/11] [skip ci] Fix dasbhoard first-start issue --- e2e-tests/.ci/.e2erc | 2 +- e2e-tests/.ci/dashboard.start.sh | 6 +++++- e2e-tests/.ci/dashboard.stop.sh | 7 ++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/e2e-tests/.ci/.e2erc b/e2e-tests/.ci/.e2erc index 4f246c4c776c8..34b738891e030 100644 --- a/e2e-tests/.ci/.e2erc +++ b/e2e-tests/.ci/.e2erc @@ -68,7 +68,7 @@ mme2e_wait_image () { mme2e_legacy_setup () { # These functions are needed until every pipeline depending on the `server/build/gitlab-dc.*.yml` files is adapted to not use external docker networking anymore # After that is fixed, this function and the external network in the docker-compose files may be removed - export COMPOSE_PROJECT_NAME=mmserver + export COMPOSE_PROJECT_NAME=mmserver_legacy docker network inspect ${COMPOSE_PROJECT_NAME} >/dev/null 2>&1 || docker network create ${COMPOSE_PROJECT_NAME} } diff --git a/e2e-tests/.ci/dashboard.start.sh b/e2e-tests/.ci/dashboard.start.sh index 89feb25513e76..b17f927280b75 100755 --- a/e2e-tests/.ci/dashboard.start.sh +++ b/e2e-tests/.ci/dashboard.start.sh @@ -7,7 +7,10 @@ MME2E_DASHBOARD_REF_DEFAULT="origin/main" MME2E_DASHBOARD_REF=${MME2E_DASHBOARD_REF:-$MME2E_DASHBOARD_REF_DEFAULT} mme2e_log "Cloning the automation-dashboard project" -[ -d dashboard ] || git clone https://github.com/saturninoabril/automation-dashboard.git dashboard +if [ ! -d dashboard ]; then + git clone https://github.com/saturninoabril/automation-dashboard.git dashboard + . .e2erc # Must reinitialize some variables that depend on the dashboard repo being checked out +fi git -C dashboard fetch git -C dashboard checkout $MME2E_DASHBOARD_REF @@ -20,6 +23,7 @@ MME2E_DC_DASHBOARD_GATEWAY=$(docker network inspect $MME2E_DC_DASHBOARD_NETWORK AUTOMATION_DASHBOARD_URL="http://${MME2E_DC_DASHBOARD_GATEWAY}:4000/api" mme2e_log "Generating a signed JWT token for accessing the dashboard" +${MME2E_DC_DASHBOARD} exec -T -u $MME2E_UID dashboard npm i AUTOMATION_DASHBOARD_TOKEN=$(${MME2E_DC_DASHBOARD} exec -T -u $MME2E_UID dashboard node script/sign.js | awk '{ print $2; }') # The token secret is specified in the dashboard.override.yml file mme2e_log "Generating the .env.dashboard file, to point Cypress to the dashboard URL" diff --git a/e2e-tests/.ci/dashboard.stop.sh b/e2e-tests/.ci/dashboard.stop.sh index f2e471c424aba..97bab72f4c57e 100755 --- a/e2e-tests/.ci/dashboard.stop.sh +++ b/e2e-tests/.ci/dashboard.stop.sh @@ -3,4 +3,9 @@ set -e -u -o pipefail cd $(dirname $0) . .e2erc -[ ! -d dashboard ] || ${MME2E_DC_DASHBOARD} down +if [ -d dashboard ]; then + mme2e_log "Stopping the dashboard containers" + ${MME2E_DC_DASHBOARD} down +else + mme2e_log "Not stopping the dashboard containers: dashboard repo not checked out locally, skipping" +fi From b3a2ce3593dd9999163dbe41863c334c0758c579 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 2 Jun 2023 11:52:07 +0200 Subject: [PATCH 04/11] [skip ci] Add upload script and workflow for mirrored images --- .github/workflows/docker-push-mirrored.yml | 25 ++++++++++++++++ server/scripts/mirror-docker-images.json | 33 +++++++++++++++++++++ server/scripts/mirror-docker-images.sh | 34 ++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 .github/workflows/docker-push-mirrored.yml create mode 100644 server/scripts/mirror-docker-images.json create mode 100755 server/scripts/mirror-docker-images.sh diff --git a/.github/workflows/docker-push-mirrored.yml b/.github/workflows/docker-push-mirrored.yml new file mode 100644 index 0000000000000..49ab07554221b --- /dev/null +++ b/.github/workflows/docker-push-mirrored.yml @@ -0,0 +1,25 @@ +--- +# TODO before merge: do a first manual upload run, and adapt the image references in the docker-compose files +name: Push mirrored docker images +on: + push: + branches: + - master + paths: + - server/scripts/mirror-docker-images.* + +jobs: + build-docker: + name: cd/Push mirrored docker images + runs-on: ubuntu-22.04 + steps: + - name: cd/Login to Docker Hub + uses: docker/login-action@3da7dc6e2b31f99ef2cb9fb4c50fb0971e0d0139 # v2.1.0 + with: + username: ${{ secrets.DOCKERHUB_DEV_USERNAME }} + password: ${{ secrets.DOCKERHUB_DEV_TOKEN }} + - name: cd/Run image upload script + env: + IMAGES_FILE: server/scripts/mirror-docker-images.json + DRY_RUN: no + run: ./server/scripts/mirror-docker-images.sh diff --git a/server/scripts/mirror-docker-images.json b/server/scripts/mirror-docker-images.json new file mode 100644 index 0000000000000..394edc8f29f64 --- /dev/null +++ b/server/scripts/mirror-docker-images.json @@ -0,0 +1,33 @@ +{ + "postgres": { + "10": "postgres:10@sha256:7a484b11fcabd39596b1bf08780cdb61fa9b0d8bfad0844dbdce3a6922df95d1", + "12": "postgres:12@sha256:cc7a021d9aff3aa02788d35c27a5cc32d4790ad92d72232a6be75b76ab7d79db" + }, + "mysql": { + "5.7.12": "mysql/mysql-server:5.7.12@sha256:3f0d90736a3298bb04965db697a3a85f1df1480da49eafd256be1ea2b9b5337e" + }, + "minio": { + "RELEASE.2019-10-11T00-38-09Z-1": "minio/minio:RELEASE.2019-10-11T00-38-09Z@sha256:0d02f16a1662653f9b961211b21ed7de04bf04492f44c2b7594bacbfcc519eb5" + }, + "inbucket": { + "3.0.0": "inbucket/inbucket:3.0.0@sha256:1f10a0efea694592c06799c729aee1d6d71c9a4f72b73031d4a426ef5f26dfc1" + }, + "openldap": { + "1.4.0": "osixia/openldap:1.4.0@sha256:d5b2f2b816b25a1b57033b34f5d48c91cc3161a7d041811a9032604030bad9db" + }, + "keycloak": { + "10.0.2": "jboss/keycloak:10.0.2@sha256:3720b5ace316b5790a58ce838f46e8cd44cedbdb7e35d3866311ddc5a5e71466" + }, + "dejavu": { + "3.4.2": "appbaseio/dejavu:3.4.2@sha256:8f2f4d45565da53c4235495737fff3921d302955daeb2f53a433c7b0e2044951" + }, + "prometheus": { + "v2.27.1": "prom/prometheus:v2.27.1@sha256:5accb68b56ba452e449a5e552411acaeabbbe0f087acf19a1157ce3dd10a8bed" + }, + "grafana": { + "8.0.1": "grafana/grafana:8.0.1@sha256:1c3e2fc7896adf9e33be5d062c08066087cb556f63b0a95f8aefe92bd37a6f38" + }, + "cypress-browsers-public": { + "node16.14.2-slim-chrome100-ff99-edge": "cypress/browsers:node16.14.2-slim-chrome100-ff99-edge@sha256:f8459ee677ce356eff64698095fbdf48eb9ab018fc5eb0d30c07ba23884edace" + } +} diff --git a/server/scripts/mirror-docker-images.sh b/server/scripts/mirror-docker-images.sh new file mode 100755 index 0000000000000..3527810dec297 --- /dev/null +++ b/server/scripts/mirror-docker-images.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -eu -o pipefail + +# Assert that IMAGE_FILE var is given, and that the file exists +: ${IMAGES_FILE} +[ -f ${IMAGES_FILE} ] || { + echo "Error: images spec file $IMAGES_FILE does not exist. Aborting." >&2 + exit 1 +} + +DRY_RUN=${DRY_RUN:-yes} +log () { echo "[$(date -Is)]" $*; } +get_image_specs_per_line () { + jq -c '. as $images | keys[] | . as $image | $images[.] | keys[] | {dst_img_name: $image, dst_img_tag: ., src_img: $images[$image][.]}' <$IMAGES_FILE +} + +log "Pusing images from given spec file: $IMAGES_FILE" +log "Content of the spec file:" +cat $IMAGES_FILE +get_image_specs_per_line | while read IMAGE_SPEC; do + DST_IMG_NAME=$(jq -r '.dst_img_name' <<<$IMAGE_SPEC) + DST_IMG_TAG=$(jq -r '.dst_img_tag' <<<$IMAGE_SPEC) + SOURCE_IMAGE=$(jq -r '.src_img' <<<$IMAGE_SPEC) + DESTINATION_IMAGE=mattermostdevelopment/mirrored-${DST_IMG_NAME}:${DST_IMG_TAG} + if [ "${DRY_RUN,,}" = "no" ]; then + log "Pushing image: $SOURCE_IMAGE ---> $DESTINATION_IMAGE" + docker pull $SOURCE_IMAGE + docker tag $SOURCE_IMAGE $DESTINATION_IMAGE + docker push $DESTINATION_IMAGE + else + log "Pushing image: $SOURCE_IMAGE ---> $DESTINATION_IMAGE (dry run mode, set the DRY_RUN=no env var to disable)" + fi +done +log "All images pushed." From ac69cfeb4ea9dd763e8827ac167e46cd0d210ce1 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 2 Jun 2023 20:27:24 +0200 Subject: [PATCH 05/11] Fully rely on mattermostdevelopment images --- .github/workflows/docker-push-mirrored.yml | 1 - e2e-tests/.ci/server.override.yml | 4 ++-- e2e-tests/.ci/server.prepare.sh | 1 + server/build/gitlab-dc.common.yml | 14 +++++++------- server/build/gitlab-dc.mysql.yml | 2 +- server/build/gitlab-dc.postgres.yml | 2 +- server/build/gitlab-dc.schemamysql.yml | 2 +- server/build/gitlab-dc.schemapostgres.yml | 2 +- server/scripts/mirror-docker-images.json | 3 +++ 9 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/docker-push-mirrored.yml b/.github/workflows/docker-push-mirrored.yml index 49ab07554221b..b1cc2a1eca27c 100644 --- a/.github/workflows/docker-push-mirrored.yml +++ b/.github/workflows/docker-push-mirrored.yml @@ -1,5 +1,4 @@ --- -# TODO before merge: do a first manual upload run, and adapt the image references in the docker-compose files name: Push mirrored docker images on: push: diff --git a/e2e-tests/.ci/server.override.yml b/e2e-tests/.ci/server.override.yml index a0073cbd2e868..b5251414d7cb1 100644 --- a/e2e-tests/.ci/server.override.yml +++ b/e2e-tests/.ci/server.override.yml @@ -68,7 +68,7 @@ services: - webhook-interactions cypress: - image: "public.ecr.aws/mattermostqa/cypress-browsers-public:node16.14.2-slim-chrome100-ff99-edge" + image: "mattermostdevelopment/mirrored-cypress-browsers-public:node16.14.2-slim-chrome100-ff99-edge" entrypoint: [ "/bin/bash", "-c" ] command: [ "until [ -f /var/run/mm_terminate ]; do sleep 5; done" ] env_file: @@ -113,7 +113,7 @@ services: - "../../e2e-tests/cypress/:/app" utils: - image: "public.ecr.aws/mattermostqa/mattermost-build-server:20220415_golang-1.18.1" + image: "mattermostdevelopment/mirrored-golang:1.19.5" entrypoint: [ "/bin/bash", "-c" ] command: [ "until [ -f /var/run/mm_terminate ]; do sleep 5; done" ] working_dir: "/opt/mattermost-server" diff --git a/e2e-tests/.ci/server.prepare.sh b/e2e-tests/.ci/server.prepare.sh index ef0e43f965ef8..e4520f85b6d93 100755 --- a/e2e-tests/.ci/server.prepare.sh +++ b/e2e-tests/.ci/server.prepare.sh @@ -19,6 +19,7 @@ ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/keycloak. # Generate the test mattermosts-server config, and restart its container mme2e_log "Prepare Server: patching the mattermost-server config" +${MME2E_DC_SERVER} exec -T -- utils bash -c "apt update && apt install -y jq" ${MME2E_DC_SERVER} exec -T -e "OUTPUT_CONFIG=/tmp/config_generated.json" -w /opt/mattermost-server/server -- utils go run scripts/config_generator/main.go ${MME2E_DC_SERVER} exec -T -- utils bash < Date: Fri, 2 Jun 2023 21:17:13 +0200 Subject: [PATCH 06/11] Make checked-out commit overridable for smoketests --- .github/workflows/e2e-tests-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/e2e-tests-ci.yml b/.github/workflows/e2e-tests-ci.yml index 7f7ce780222ed..b057e49974719 100644 --- a/.github/workflows/e2e-tests-ci.yml +++ b/.github/workflows/e2e-tests-ci.yml @@ -36,6 +36,8 @@ jobs: steps: - name: ci/checkout-repo uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ inputs.commit_sha || github.sha }} - name: ci/setup-node uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 id: setup_node @@ -60,6 +62,8 @@ jobs: steps: - name: ci/checkout-repo uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ inputs.commit_sha || github.sha }} - name: ci/setup-node uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 id: setup_node @@ -90,6 +94,8 @@ jobs: steps: - name: ci/checkout-repo uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + with: + ref: ${{ inputs.commit_sha || github.sha }} - name: ci/e2e-smoketests run: | make From ba93408e05866de670a25e70d29e6381f76cfb85 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Mon, 5 Jun 2023 20:01:30 +0200 Subject: [PATCH 07/11] Empty commit: trigger pipeline From 2a89079351b7d012de3615350cdcc1271710e08d Mon Sep 17 00:00:00 2001 From: mvitale1989 Date: Thu, 8 Jun 2023 19:45:33 +0200 Subject: [PATCH 08/11] Apply suggestions from code review Fix typos Co-authored-by: Saturnino Abril --- e2e-tests/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e-tests/README.md b/e2e-tests/README.md index dac80d245ea01..fa072c6dc8581 100644 --- a/e2e-tests/README.md +++ b/e2e-tests/README.md @@ -23,9 +23,9 @@ Instructions, detailed: 4. `make stop`: tears down the server (and the dashboard, if running), then cleans up the env placeholder files Notes: -- Aside from some exceptions (e.g. `TEST_FILTER`), most of the variables in `.ci/env` must be set before the `make start-server` command is run. Modifting that file afterwards has no effect, because the containers' env files are generated in that step. +- Aside from some exceptions (e.g. `TEST_FILTER`), most of the variables in `.ci/env` must be set before the `make start-server` command is run. Modifying that file afterwards has no effect, because the containers' env files are generated in that step. - If you restart the dashboard at any point, you must also restart the server containers, so that it picks up the new IP of the dashboard from the newly generated `.env.dashboard` file -- If you started the dashboard locally in the past, but want to point to another dasbhoard later, you can run `make clean-env-placeholders` to remove references to the local dasbhoard (you'll likely need to restart the server) +- If you started the dashboard locally in the past, but want to point to another dashboard later, you can run `make clean-env-placeholders` to remove references to the local dashboard (you'll likely need to restart the server) - Dynamically set variables for the server or cypress should be managed within the `.env.*` files, rather than in the docker-compose files, to streamline their management. ##### How to control which tests to run From ed2c45dcb04fde39564ff96a4fec6331dabb7669 Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 9 Jun 2023 12:40:17 +0200 Subject: [PATCH 09/11] Apply required changes for supporting PR 23443 --- e2e-tests/.ci/server.override.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e-tests/.ci/server.override.yml b/e2e-tests/.ci/server.override.yml index b5251414d7cb1..1a92e50d5622e 100644 --- a/e2e-tests/.ci/server.override.yml +++ b/e2e-tests/.ci/server.override.yml @@ -25,6 +25,7 @@ services: MM_FEATUREFLAGS_USECASEONBOARDING: "false" MM_SERVICESETTINGS_ENABLEONBOARDINGFLOW: "false" MM_FEATUREFLAGS_ONBOARDINGTOURTIPS: "false" + MM_SERVICEENVIRONMENT: "test" ports: - "8065:8065" depends_on: From 530b9b2c018a4db04ac9ff074865014af031048e Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 9 Jun 2023 12:56:54 +0200 Subject: [PATCH 10/11] Move server config generation to server.start.sh --- e2e-tests/.ci/server.override.yml | 6 ++++++ e2e-tests/.ci/server.prepare.sh | 23 ----------------------- e2e-tests/.ci/server.start.sh | 21 ++++++++++++++++++++- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/e2e-tests/.ci/server.override.yml b/e2e-tests/.ci/server.override.yml index 1a92e50d5622e..f962e8798bcb6 100644 --- a/e2e-tests/.ci/server.override.yml +++ b/e2e-tests/.ci/server.override.yml @@ -26,6 +26,8 @@ services: MM_SERVICESETTINGS_ENABLEONBOARDINGFLOW: "false" MM_FEATUREFLAGS_ONBOARDINGTOURTIPS: "false" MM_SERVICEENVIRONMENT: "test" + volumes: + - "server-config:/mattermost/config" ports: - "8065:8065" depends_on: @@ -120,3 +122,7 @@ services: working_dir: "/opt/mattermost-server" volumes: - "../../:/opt/mattermost-server" + - "server-config:/opt/server-config" + +volumes: + server-config: diff --git a/e2e-tests/.ci/server.prepare.sh b/e2e-tests/.ci/server.prepare.sh index e4520f85b6d93..4d24effd865d4 100755 --- a/e2e-tests/.ci/server.prepare.sh +++ b/e2e-tests/.ci/server.prepare.sh @@ -17,29 +17,6 @@ ${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/matterm ${MME2E_DC_SERVER} exec -T -- server curl -L --silent https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz | ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/com.mattermost.demo-plugin-0.8.0.tar.gz >/dev/null ${MME2E_DC_SERVER} exec -T -u $MME2E_UID -- cypress tee tests/fixtures/keycloak.crt >/dev/null <../../server/build/docker/keycloak/keycloak.crt -# Generate the test mattermosts-server config, and restart its container -mme2e_log "Prepare Server: patching the mattermost-server config" -${MME2E_DC_SERVER} exec -T -- utils bash -c "apt update && apt install -y jq" -${MME2E_DC_SERVER} exec -T -e "OUTPUT_CONFIG=/tmp/config_generated.json" -w /opt/mattermost-server/server -- utils go run scripts/config_generator/main.go -${MME2E_DC_SERVER} exec -T -- utils bash </tmp/config_patched.json -EOF -# TODO double check: could there be race conditions, if the server tries to write back to the file? Afaiu, nobody touching the UI -> no changes to the config file -${MME2E_DC_SERVER} exec -T -- utils cat /tmp/config_patched.json | ${MME2E_DC_SERVER} exec -T -- server tee config/config.json >/dev/null -${MME2E_DC_SERVER} restart server -if ! mme2e_wait_service_healthy server 60 10; then - mme2e_log "Mattermost container not healthy, retry attempts exhausted. Giving up." >&2 - exit 1 -fi -mme2e_log "Mattermost container is running and healthy" - # Inject test data, prepare for E2E tests mme2e_log "Prepare Server: injecting E2E test data" ${MME2E_DC_SERVER} exec -T -- server mmctl config set TeamSettings.MaxUsersPerTeam 100 --local diff --git a/e2e-tests/.ci/server.start.sh b/e2e-tests/.ci/server.start.sh index 4e99ae8df7b4c..2dea59932401b 100755 --- a/e2e-tests/.ci/server.start.sh +++ b/e2e-tests/.ci/server.start.sh @@ -33,9 +33,28 @@ AUTOMATION_DASHBOARD_URL AUTOMATION_DASHBOARD_TOKEN EOF -# Launch mattermost-server, and wait for it to be healthy +# Wait for the required server image mme2e_log "Waiting for server image to be available" mme2e_wait_image ${SERVER_IMAGE} 30 60 + +# Create the containers and generate the server config +mme2e_log "Creating E2E containers and generating server config" +${MME2E_DC_SERVER} create +${MME2E_DC_SERVER} up -d -- utils +${MME2E_DC_SERVER} exec -T -- utils bash -c "apt update && apt install -y jq" +${MME2E_DC_SERVER} exec -T -e "OUTPUT_CONFIG=/tmp/config_generated.json" -w /opt/mattermost-server/server -- utils go run scripts/config_generator/main.go +${MME2E_DC_SERVER} exec -T -- utils bash </opt/server-config/config.json +EOF + +# Launch mattermost-server, and wait for it to be healthy mme2e_log "Starting E2E containers" ${MME2E_DC_SERVER} up -d if ! mme2e_wait_service_healthy server 60 10; then From 649155aec23ad43453c99d24b40f4a99f0a7520f Mon Sep 17 00:00:00 2001 From: Mario Vitale Date: Fri, 9 Jun 2023 13:07:19 +0200 Subject: [PATCH 11/11] Unify config generation commands --- e2e-tests/.ci/server.start.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/e2e-tests/.ci/server.start.sh b/e2e-tests/.ci/server.start.sh index 2dea59932401b..3f34838a7dc20 100755 --- a/e2e-tests/.ci/server.start.sh +++ b/e2e-tests/.ci/server.start.sh @@ -41,9 +41,9 @@ mme2e_wait_image ${SERVER_IMAGE} 30 60 mme2e_log "Creating E2E containers and generating server config" ${MME2E_DC_SERVER} create ${MME2E_DC_SERVER} up -d -- utils -${MME2E_DC_SERVER} exec -T -- utils bash -c "apt update && apt install -y jq" -${MME2E_DC_SERVER} exec -T -e "OUTPUT_CONFIG=/tmp/config_generated.json" -w /opt/mattermost-server/server -- utils go run scripts/config_generator/main.go -${MME2E_DC_SERVER} exec -T -- utils bash </opt/server-config/config.json +echo "### Generated server config:" +cat /opt/server-config/config.json EOF # Launch mattermost-server, and wait for it to be healthy