mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* Add weekly recurring scheduled posts. Extend scheduled posts so users can schedule weekly repeats and keep the series healthy across sends, reschedules, and UI updates instead of falling back to one-shot behavior. Made-with: Cursor * Add Playwright coverage for recurring scheduled posts. Cover weekly recurring scheduled messages in the scheduled-messages spec so the recurring UI and reschedule flow stay protected without adding a separate test surface. Made-with: Cursor * Fix recurring scheduled post CI failures. Resolve the initial lint and formatting issues and renumber the new scheduled-post migration so it no longer collides with master during Postgres-backed test setup. Made-with: Cursor * Sync recurring scheduled post translation files. Regenerate the affected English translation catalogs so the recurring scheduled post strings match the source extraction order expected by CI. Made-with: Cursor * Fix recurring scheduled post review follow-ups. Preserve overdue cleanup behavior during weekly catch-up, defer delete websocket events until deletion succeeds, and address the remaining migration and UI review nits. Made-with: Cursor * Address recurring scheduled post review feedback Made-with: Cursor * Fix recurring scheduled post CI checks Made-with: Cursor * Make pending scheduled post keyset cursor index-scannable EXPLAIN ANALYZE on a 5M-row ScheduledPosts table showed the pure OR-form cursor forced Postgres to scan idx_scheduledposts_pending_scheduled_at_id from the top on every page (~383ms/page, ~2M rows filtered). Keeping the ScheduledAt <= beforeTime bound outside the tie-break restores the index boundary (~0.12ms/page). Adds storetest coverage for cursor pagination. Co-authored-by: nick.misasi <[email protected]> * Address code quality review findings for recurring scheduled posts Server: - Replace silent-fallback AdvanceWeeklyScheduledNextOccurrence with error-returning ScheduledPost.ComputeNextScheduledAt; a recurring post whose timezone fails to load is now routed through the failed-post path instead of being reposted every job run or silently deleted - Add ScheduledPost.IsRecurring and partition batches in processScheduledPostBatch; advance/delete now run independently so a store failure in one path can't cause reposts in the other - Drop dead generality in UpdateRecurringScheduledPosts (only ScheduledAt varies per row; ErrorCode/ProcessedAt are constants) - Simplify redundant repeat-type condition in GetPendingScheduledPosts Webapp: - Add shared isRecurringScheduledPost helper, replacing six scattered repeat_type === 'weekly' literals - Recurrence timezone is now simply the scheduler's current timezone; removes initialRepeatTimezone/effectiveTimezone plumbing and the modal-label/picker timezone mismatch - Single enforcement point for hiding send-now on recurring posts - Use canonical getTeamIdByChannelId at both SCHEDULED_POST_UPDATED dispatch sites; rewrite errorsByTeamId update case as remove-then-add and add reducer tests Co-authored-by: nick.misasi <[email protected]> * Simplify recurring scheduled post code per review - End a recurring series when its channel no longer exists instead of advancing it forever (matches the one-shot channel-not-found handling) - Collapse the errorsByTeamId SCHEDULED_POST_UPDATED case into the identical SINGLE_SCHEDULED_POST_RECEIVED case (a scheduled post's team can't change) and combine duplicate byId cases; preserves state references on no-op updates - Drop no-op timezone conversions in ComputeNextScheduledAt - Remove redundant checkbox aria-label (label htmlFor already names it) - Schedule new job tests in the past instead of sleeping a real second - Remove redundant test assignment and e2e positional boolean Co-authored-by: nick.misasi <[email protected]> * Remove slop from recurring scheduled post changes - Drop the business-rule CHECK constraint from the recurrence migration; no other migration enforces model-layer validation in the database, and BaseIsValid plus the job's failure handling already own it - Fold the standalone repeat-validation test file into the existing TestScheduledPostBaseIsValid, matching its conventions - Revert unrelated benchmark modernization in utils_test.go - Drop an unneeded cast, unused fixture fields, and naming/assertion inconsistencies in tests Co-authored-by: nick.misasi <[email protected]> * Regenerate ScheduledPostStore mock with mockery ordering Co-authored-by: nick.misasi <[email protected]> * Address CodeRabbit review feedback - Reject the host-dependent 'Local' value for RepeatTimezone; recurring schedules need a fixed zone (UTC or IANA name) - Hide reschedule for deactivated DMs, matching send-now eligibility Co-authored-by: nick.misasi <[email protected]> * Resolve scheduled post team bucket from existing state when channel is unloaded An admin can reschedule before fetchMissingChannels resolves, in which case deriving the team from the channel returns undefined and the update was misfiled under directChannels. getScheduledPostTeamId falls back to the byTeamId bucket that already holds the post. Co-authored-by: nick.misasi <[email protected]> * Retrigger CI after transient enterprise npm network failure Co-authored-by: nick.misasi <[email protected]> * Clear hover/focus before asserting scheduled post header details in e2e The drafts panel hides its timestamp/tag info section while hovered or focus-within; after the reschedule modal closes, focus returns to the row and the 'Repeats weekly' tag assertion saw a hidden element. Co-authored-by: nick.misasi <[email protected]> * Move recurrence columns into baseColumns and dispatch ComputeNextScheduledAt on repeat type Co-authored-by: nick.misasi <[email protected]> * Preserve recurrence when scheduled post updates omit repeat fields Co-authored-by: nick.misasi <[email protected]> * Disallow file attachments on recurring scheduled posts Co-authored-by: nick.misasi <[email protected]> * Stop pinning the channel indicator for recurring-only scheduled posts Co-authored-by: nick.misasi <[email protected]> * Re-home nullable-Type comment onto baseColumns Co-authored-by: nick.misasi <[email protected]> * Gate recurring scheduled posts behind a default-off feature flag Co-authored-by: nick.misasi <[email protected]> * Move presence-preservation rationale to the copy site Co-authored-by: nick.misasi <[email protected]> * Extract draftHasAttachments helper and require allowRecurring at single-caller layers Co-authored-by: nick.misasi <[email protected]> * Return null from the indicator selector when nothing should show Co-authored-by: nick.misasi <[email protected]> * Gate only recurrence transitions and preserve existing series in the modal Co-authored-by: nick.misasi <[email protected]> * Avoid err shadowing in scheduled post update handler Co-authored-by: nick.misasi <[email protected]> * Disable the repeat weekly checkbox with a tooltip when the message has attachments Co-authored-by: nick.misasi <[email protected]> * Return an explicit disposition from postScheduledPost The batch loop inferred 'channel permanently gone' from the one return path with a nil error and an error code set - an invariant a future change could silently break, deleting recurring series by accident. postScheduledPost now returns posted/failed/unsendable explicitly, the switch refuses to delete on an unhandled disposition, and a test pins that both recurring and one-shot posts in a nonexistent channel are permanently deleted. Co-authored-by: nick.misasi <[email protected]> * Fix Repeat weekly attachments tooltip centering on the modal row (#37927) Shrink-wrap the repeat checkbox row so WithTooltip anchors to the control/label instead of the full modal body width. --------- Co-authored-by: Hanzo Dev <[email protected]>
478 lines
16 KiB
Bash
Executable File
478 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
# SC2034: <variable> appears unused.
|
|
# https://www.shellcheck.net/wiki/SC2034
|
|
# shellcheck disable=SC2034
|
|
# Note: Variables are dynamically used depending on usage input (ENABLED_DOCKER_SERVICES)
|
|
|
|
set -e -u -o pipefail
|
|
cd "$(dirname "$0")"
|
|
. .e2erc
|
|
|
|
enable_docker_service() {
|
|
local SERVICE_TO_ENABLE="$1"
|
|
if ! mme2e_is_token_in_list "$SERVICE_TO_ENABLE" "$ENABLED_DOCKER_SERVICES"; then
|
|
ENABLED_DOCKER_SERVICES="$ENABLED_DOCKER_SERVICES $SERVICE_TO_ENABLE"
|
|
fi
|
|
}
|
|
|
|
assert_docker_services_validity() {
|
|
local SERVICES_TO_CHECK="$*"
|
|
local SERVICES_VALID="postgres minio inbucket openldap elasticsearch opensearch redis keycloak cypress webhook-interactions playwright"
|
|
local SERVICES_REQUIRED="postgres inbucket"
|
|
for SERVICE_NAME in $SERVICES_TO_CHECK; do
|
|
if ! mme2e_is_token_in_list "$SERVICE_NAME" "$SERVICES_VALID"; then
|
|
mme2e_log "Error, requested invalid service: $SERVICE_NAME" >&2
|
|
mme2e_log "Valid services are: $SERVICES_VALID" >&2
|
|
mme2e_log "Aborting" >&2
|
|
exit 1
|
|
fi
|
|
SERVICES_REQUIRED="${SERVICES_REQUIRED/$SERVICE_NAME/}"
|
|
done
|
|
if [ -n "${SERVICES_REQUIRED/ /}" ]; then
|
|
mme2e_log "Missing required services: $SERVICES_REQUIRED" >&2
|
|
mme2e_log "Aborting" >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
generate_docker_compose_file() {
|
|
# Generating the server docker-compose file
|
|
local DC_FILE="server.yml"
|
|
mme2e_log "Generating docker-compose file in: $DC_FILE"
|
|
|
|
# Generate the docker compose override file
|
|
cat <<EOL >"$DC_FILE"
|
|
# Image hashes in this file are for amd64 systems
|
|
# NB: May include paths relative to the "server/build" directory, which contains the original compose file that this yaml is overriding
|
|
|
|
services:
|
|
server:
|
|
image: \${SERVER_IMAGE}
|
|
platform: linux/amd64
|
|
restart: always
|
|
env_file:
|
|
- "./.env.server"
|
|
environment:
|
|
MM_SERVICESETTINGS_ALLOWCORSFROM: "*"
|
|
MM_SERVICESETTINGS_ENABLELOCALMODE: "true"
|
|
MM_SERVICESETTINGS_ENABLESECURITYFIXALERT: "false"
|
|
MM_CONNECTEDWORKSPACESSETTINGS_ENABLEREMOTECLUSTERSERVICE: "true"
|
|
MM_CONNECTEDWORKSPACESSETTINGS_ENABLESHAREDWORKSPACES: "true"
|
|
MM_FEATUREFLAGS_ENABLEREMOTECLUSTERSERVICE: "true"
|
|
MM_SQLSETTINGS_DATASOURCE: "postgres://mmuser:mostest@localhost:5432/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes"
|
|
MM_SQLSETTINGS_DRIVERNAME: "postgres"
|
|
MM_EMAILSETTINGS_SMTPSERVER: "localhost"
|
|
MM_CLUSTERSETTINGS_READONLYCONFIG: "false"
|
|
MM_SERVICEENVIRONMENT: "test"
|
|
MM_FEATUREFLAGS_MOVETHREADSENABLED: "true"
|
|
MM_FEATUREFLAGS_CUSTOMPROFILEATTRIBUTES: "true"
|
|
MM_FEATUREFLAGS_PERMISSIONPOLICIES: "true"
|
|
MM_FEATUREFLAGS_TEAMMEMBERSHIPACCESSCONTROL: "true"
|
|
MM_FEATUREFLAGS_CLASSIFICATIONMARKINGS: "true"
|
|
MM_FEATUREFLAGS_INTEGRATEDBOARDS: "true"
|
|
MM_FEATUREFLAGS_PROPERTYFIELDRANK: "true"
|
|
MM_FEATUREFLAGS_ATTRIBUTEVALUEMASKING: "true"
|
|
MM_FEATUREFLAGS_WYSIWYGEDITOR: "true"
|
|
MM_FEATUREFLAGS_RECURRINGSCHEDULEDPOSTS: "true"
|
|
MM_LOGSETTINGS_ENABLEDIAGNOSTICS: "false"
|
|
MM_LOGSETTINGS_CONSOLELEVEL: "DEBUG"
|
|
network_mode: host
|
|
ports:
|
|
- "8065:8065"
|
|
depends_on:
|
|
$(for service in $ENABLED_DOCKER_SERVICES; do
|
|
# The server container will start only if all other dependent services are healthy
|
|
# Skip creating the dependency for containers that don't need a healthcheck
|
|
if grep -qE "^(cypress|webhook-interactions|playwright)" <<<"$service"; then
|
|
continue
|
|
fi
|
|
echo " $service:"
|
|
echo " condition: service_healthy"
|
|
done)
|
|
|
|
$(if mme2e_is_token_in_list "postgres" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
postgres:
|
|
image: mattermostdevelopment/mirrored-postgres:14
|
|
restart: "no"
|
|
network_mode: host
|
|
networks: !reset []
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: postgres'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "inbucket" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
inbucket:
|
|
network_mode: host
|
|
networks: !reset []
|
|
restart: "no"
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: inbucket
|
|
healthcheck:
|
|
test: [ "CMD", "nc", "-z", "-w1", "127.0.0.1", "10025" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "minio" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
minio:
|
|
network_mode: host
|
|
networks: !reset []
|
|
restart: "no"
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: minio
|
|
healthcheck:
|
|
test: [ "CMD", "curl", "-f", "127.0.0.1:9000/minio/health/live" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "openldap" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
openldap:
|
|
network_mode: host
|
|
networks: !reset []
|
|
restart: "no"
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: openldap
|
|
healthcheck:
|
|
test: [ "CMD", "bash", "-o", "pipefail", "-c", "ss -ltn \"sport = :636\" | grep -qE \"^LISTEN\"" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "elasticsearch" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
elasticsearch:
|
|
restart: "no"
|
|
network_mode: host
|
|
networks: !reset []
|
|
environment:
|
|
xpack.security.enabled: "false"
|
|
action.destructive_requires_name: "false"
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: elasticsearch
|
|
healthcheck:
|
|
test: [ "CMD", "curl", "-fsS", "localhost:9200/_cluster/health?wait_for_status=green&timeout=5s" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
if [ "$MME2E_ARCHTYPE" = "arm64" ]; then
|
|
echo '
|
|
image: mattermostdevelopment/mattermost-elasticsearch:8.9.0
|
|
platform: linux/arm64/v8'
|
|
fi
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "opensearch" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
opensearch:
|
|
restart: "no"
|
|
network_mode: host
|
|
networks: !reset []
|
|
environment:
|
|
http.port: 9200
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: opensearch
|
|
healthcheck:
|
|
test: [ "CMD", "curl", "-fsS", "localhost:9200/_cluster/health?wait_for_status=green&timeout=5s" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "redis" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
redis:
|
|
restart: "no"
|
|
network_mode: host
|
|
networks: !reset []
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: redis
|
|
healthcheck:
|
|
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "keycloak" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
keycloak:
|
|
restart: "no"
|
|
network_mode: host
|
|
networks: !reset []
|
|
environment:
|
|
JAVA_OPTS: "-Xms64m -Xmx2G -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true"
|
|
volumes:
|
|
- "../../server/build/docker/keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json"
|
|
- "../../server/build/docker/keycloak/kc-healthcheck.sh:/usr/local/bin/kc-healthcheck.sh"
|
|
extends:
|
|
file: ../../server/build/docker-compose.common.yml
|
|
service: keycloak
|
|
healthcheck:
|
|
# We cannot use a simple curl --silent localhost:9990/health | grep -q \"status\":\"UP\" because theres no curl in the image: https://www.keycloak.org/server/health#_using_the_health_checks
|
|
test: [ "CMD", "/usr/local/bin/kc-healthcheck.sh" ]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "cypress" "$ENABLED_DOCKER_SERVICES"; then
|
|
echo '
|
|
cypress:
|
|
image: "cypress/browsers:node-24.14.0-chrome-145.0.7632.116-1-ff-148.0-edge-145.0.3800.70-1"
|
|
platform: linux/amd64
|
|
entrypoint: ["/bin/bash", "-c"]
|
|
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
|
|
env_file:
|
|
- "../../e2e-tests/.ci/.env.cypress"
|
|
environment:
|
|
CYPRESS_baseUrl: "http://localhost:8065"
|
|
CYPRESS_dbConnection: "postgres://mmuser:mostest@localhost:5432/mattermost_test?sslmode=disable&connect_timeout=10"
|
|
CYPRESS_smtpUrl: "http://localhost:9001"
|
|
CYPRESS_webhookBaseUrl: "http://localhost:3000"
|
|
CYPRESS_chromeWebSecurity: "false"
|
|
CYPRESS_firstTest: "true"
|
|
CYPRESS_resetBeforeTest: "true"
|
|
CYPRESS_allowedUntrustedInternalConnections: "localhost webhook-interactions"
|
|
TM4J_ENABLE: "false"
|
|
# disable shared memory X11 affecting Cypress v4 and Chrome
|
|
# https://github.com/cypress-io/cypress-docker-images/issues/270
|
|
QT_X11_NO_MITSHM: "1"
|
|
_X11_NO_MITSHM: "1"
|
|
_MITSHM: "0"
|
|
# avoid too many progress messages
|
|
# https://github.com/cypress-io/cypress/issues/1243
|
|
CI: "1"
|
|
# Use /tmp for Cypress cache and config so any UID can write without permission issues
|
|
CYPRESS_CACHE_FOLDER: /tmp/cypress-cache
|
|
XDG_CONFIG_HOME: /tmp/xdg-config
|
|
# Ensure we are independent from the global node environment
|
|
PATH: /e2e-tests/cypress/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
ulimits:
|
|
nofile:
|
|
soft: 8096
|
|
hard: 1048576
|
|
working_dir: /e2e-tests/cypress
|
|
network_mode: host
|
|
volumes:
|
|
- "../../e2e-tests/cypress/:/e2e-tests/cypress"
|
|
- "../../webapp/platform/eslint-plugin/:/webapp/platform/eslint-plugin"'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; then
|
|
# shellcheck disable=SC2016
|
|
echo '
|
|
webhook-interactions:
|
|
image: node:${NODE_VERSION_REQUIRED}
|
|
command: sh -c "npm init -y > /dev/null && npm install [email protected] [email protected] client-oauth2@github:larkox/js-client-oauth2#e24e2eb5dfcbbbb3a59d095e831dbe0012b0ac49 && exec node webhook_serve.js"
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
|
|
interval: 10s
|
|
timeout: 15s
|
|
retries: 12
|
|
working_dir: /webhook
|
|
network_mode: host
|
|
restart: on-failure
|
|
volumes:
|
|
- "../../e2e-tests/cypress/webhook_serve.js:/webhook/webhook_serve.js:ro"
|
|
- "../../e2e-tests/cypress/utils/:/webhook/utils:ro"
|
|
- "../../e2e-tests/cypress/tests/plugins/post_message_as.js:/webhook/tests/plugins/post_message_as.js:ro"'
|
|
fi)
|
|
|
|
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
|
|
# shellcheck disable=SC2016
|
|
echo '
|
|
playwright:
|
|
image: mcr.microsoft.com/playwright:v1.61.0-noble
|
|
entrypoint: ["/bin/bash", "-c"]
|
|
command:
|
|
- |
|
|
# Install Node.js based on .nvmrc
|
|
NODE_VERSION=$$(cat /mattermost/.nvmrc)
|
|
echo "Installing Node.js $${NODE_VERSION}..."
|
|
curl -fsSL https://deb.nodesource.com/setup_$${NODE_VERSION%%.*}.x | bash -
|
|
apt-get install -y nodejs
|
|
echo "Node.js version: $$(node --version)"
|
|
# Wait for termination signal
|
|
until [ -f /var/run/mm_terminate ]; do sleep 5; done
|
|
env_file:
|
|
- "./.env.playwright"
|
|
environment:
|
|
CI: "true"
|
|
PLAYWRIGHT_SKIP_BROWSER_GC: 1
|
|
PW_BASE_URL: http://localhost:8065
|
|
PW_ADMIN_USERNAME: sysadmin
|
|
PW_ADMIN_PASSWORD: Sys@dmin-sample1
|
|
PW_ADMIN_EMAIL: [email protected]
|
|
PW_ENSURE_PLUGINS_INSTALLED: ""
|
|
MM_TEST_DB_URL: "postgres://mmuser:mostest@localhost:5432/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes"
|
|
PW_HA_CLUSTER_ENABLED: "false"
|
|
PW_RESET_BEFORE_TEST: "false"
|
|
PW_HEADLESS: "true"
|
|
PW_SLOWMO: 0
|
|
PW_WORKERS: 1
|
|
PW_SNAPSHOT_ENABLE: "false"
|
|
PW_PERCY_ENABLE: "false"
|
|
PW_WEBHOOK_BASE_URL: http://localhost:3000
|
|
ulimits:
|
|
nofile:
|
|
soft: 8096
|
|
hard: 1048576
|
|
working_dir: /mattermost
|
|
network_mode: host
|
|
volumes:
|
|
- "../../:/mattermost"'
|
|
fi)
|
|
EOL
|
|
|
|
mme2e_log "docker-compose file generated."
|
|
}
|
|
|
|
generate_env_files() {
|
|
# Generate .env.server
|
|
mme2e_log "Generating .env.server"
|
|
truncate -s 0 .env.server
|
|
|
|
# Setting SERVER-specific variables
|
|
case "$SERVER" in
|
|
cloud)
|
|
echo "MM_NOTIFY_ADMIN_COOL_OFF_DAYS=0.00000001" >>.env.server
|
|
echo 'MM_FEATUREFLAGS_ANNUALSUBSCRIPTION="true"' >>.env.server
|
|
# Load .env.cloud into .env.server
|
|
# We assume the file exist at this point. The actual check for that should be done before calling this function
|
|
cat >>.env.server <.env.cloud
|
|
;;
|
|
esac
|
|
|
|
# Setting MM_ENV-injected variables
|
|
# shellcheck disable=SC2086
|
|
envarr=$(echo ${MM_ENV:-} | tr "," "\n")
|
|
for env in $envarr; do
|
|
echo "$env" >>.env.server
|
|
done
|
|
|
|
# Generating service-specific env vars
|
|
for SERVICE in $ENABLED_DOCKER_SERVICES; do
|
|
case $SERVICE in
|
|
opensearch)
|
|
echo "MM_ELASTICSEARCHSETTINGS_BACKEND=opensearch" >>.env.server
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Generating TEST-specific env files
|
|
# Some are defaulted in .e2erc due to being needed to other scripts as well
|
|
export REPO=mattermost # Static, but declared here for making generate_test_cycle.js easier to run
|
|
export HEADLESS=true # Static, but declared here for making generate_test_cycle.js easier to run
|
|
case "$TEST" in
|
|
cypress)
|
|
mme2e_log "Cypress: Generating .env.cypress"
|
|
truncate -s 0 .env.cypress
|
|
|
|
mme2e_generate_envfile_from_var_names >.env.cypress <<-EOF
|
|
BRANCH
|
|
BUILD_ID
|
|
CI_BASE_URL
|
|
BROWSER
|
|
HEADLESS
|
|
REPO
|
|
CYPRESS_pushNotificationServer
|
|
EOF
|
|
# Adding service-specific cypress variables
|
|
for SERVICE in $ENABLED_DOCKER_SERVICES; do
|
|
case $SERVICE in
|
|
openldap)
|
|
echo "CYPRESS_ldapServer=localhost" >>.env.cypress
|
|
echo "CYPRESS_runLDAPSync=true" >>.env.cypress
|
|
;;
|
|
minio)
|
|
echo "CYPRESS_minioS3Endpoint=localhost:9000" >>.env.cypress
|
|
;;
|
|
keycloak)
|
|
echo "CYPRESS_keycloakBaseUrl=http://localhost:8484" >>.env.cypress
|
|
;;
|
|
elasticsearch | opensearch)
|
|
echo "CYPRESS_elasticsearchConnectionURL=http://localhost:9200" >>.env.cypress
|
|
;;
|
|
esac
|
|
done
|
|
# Adding SERVER-specific cypress variables
|
|
case "$SERVER" in
|
|
cloud)
|
|
echo "CYPRESS_serverEdition=Cloud" >>.env.cypress
|
|
echo "CYPRESS_cwsURL=${CWS_URL}" >>.env.cypress
|
|
echo "CYPRESS_cwsAPIURL=${CWS_URL}" >>.env.cypress
|
|
;;
|
|
*)
|
|
echo "CYPRESS_serverEdition=E20" >>.env.cypress
|
|
;;
|
|
esac
|
|
# Add Automation Dashboard related variables to cypress container
|
|
if [ -n "${AUTOMATION_DASHBOARD_URL:-}" ]; then
|
|
mme2e_log "Automation dashboard URL is set: loading related variables into the Cypress container"
|
|
mme2e_generate_envfile_from_var_names >>.env.cypress <<-EOF
|
|
AUTOMATION_DASHBOARD_URL
|
|
AUTOMATION_DASHBOARD_TOKEN
|
|
EOF
|
|
elif DC_COMMAND="$MME2E_DC_DASHBOARD" mme2e_wait_service_healthy dashboard 1; then
|
|
mme2e_log "Detected a running automation dashboard: loading its access variables into the Cypress container"
|
|
cat >>.env.cypress <.env.dashboard
|
|
fi
|
|
;;
|
|
playwright)
|
|
mme2e_log "Playwright: Generating .env.playwright"
|
|
mme2e_generate_envfile_from_var_names >.env.playwright <<-EOF
|
|
BRANCH
|
|
BUILD_ID
|
|
EOF
|
|
;;
|
|
none)
|
|
mme2e_log "Requested TEST=$TEST. Skipping generation of test-specific env files."
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Perform SERVER-specific checks/customizations
|
|
case "$SERVER" in
|
|
cloud)
|
|
if ! [ -f .env.cloud ]; then
|
|
mme2e_log "Error: when using SERVER=$SERVER, the .env.cloud file is expected to exist, before generating the docker-compose file. Aborting." >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# Perform TEST-specific checks/customizations
|
|
case $TEST in
|
|
cypress)
|
|
enable_docker_service cypress
|
|
enable_docker_service webhook-interactions
|
|
;;
|
|
playwright)
|
|
enable_docker_service playwright
|
|
enable_docker_service webhook-interactions
|
|
;;
|
|
esac
|
|
|
|
mme2e_log "Generating docker-compose file using the following parameters..."
|
|
mme2e_log "TEST: ${TEST}"
|
|
mme2e_log "SERVER: ${SERVER}"
|
|
mme2e_log "ENABLED_DOCKER_SERVICES: ${ENABLED_DOCKER_SERVICES}"
|
|
assert_docker_services_validity "$ENABLED_DOCKER_SERVICES"
|
|
generate_docker_compose_file
|
|
generate_env_files
|