Skip to content

Commit

Permalink
Prepare: run E2E smoketests with GitHub actions (#23301)
Browse files Browse the repository at this point in the history
- 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 <build@mattermost.com>
Co-authored-by: Saturnino Abril <saturnino.abril@gmail.com>
Co-authored-by: Antonis Stamatiou <stamatiou.antonis@gmail.com>
  • Loading branch information
4 people committed May 30, 2023
1 parent 6d1a427 commit 68be3a6
Show file tree
Hide file tree
Showing 25 changed files with 623 additions and 49 deletions.
72 changes: 64 additions & 8 deletions .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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 }}
75 changes: 75 additions & 0 deletions 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
1 change: 1 addition & 0 deletions 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
1 change: 1 addition & 0 deletions 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
1 change: 1 addition & 0 deletions 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
5 changes: 5 additions & 0 deletions e2e-tests/.ci/.gitignore
@@ -0,0 +1,5 @@
dashboard
env
!.env.cypress
!.env.server
!.env.dashboard
21 changes: 21 additions & 0 deletions 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
24 changes: 24 additions & 0 deletions 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
29 changes: 29 additions & 0 deletions 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 <<EOF
AUTOMATION_DASHBOARD_URL
AUTOMATION_DASHBOARD_TOKEN
EOF
6 changes: 6 additions & 0 deletions e2e-tests/.ci/dashboard.stop.sh
@@ -0,0 +1,6 @@
#!/bin/bash
set -e -u -o pipefail
cd $(dirname $0)
. .e2erc

${MME2E_DC_DASHBOARD} down

0 comments on commit 68be3a6

Please sign in to comment.