diff --git a/.env b/.env index 94f660c3..054f82c2 100644 --- a/.env +++ b/.env @@ -13,18 +13,14 @@ DRUPAL_HOSTNAME=helfi-elo.docker.so OC_PROJECT_NAME=hki-kanslia-tyo-yrittaminen-test # Stage file proxy origin domain -STAGE_FILE_PROXY_ORIGIN=https://tyoyrittaminen.blob.core.windows.net - +STAGE_FILE_PROXY_ORIGIN= # Stage file proxy path STAGE_FILE_PROXY_ORIGIN_DIR= -# Docker image -DRUPAL_IMAGE=ghcr.io/city-of-helsinki/drupal-web:8.1 +COMPOSE_PROFILES=queue -# Default source @alias where to sync database and files from -DRUPAL_SYNC_SOURCE=main +# Docker image +DRUPAL_IMAGE=ghcr.io/city-of-helsinki/drupal-web:8.2 # Public webroot DRUPAL_WEBROOT=public - -DRUPAL_SYNC_FILES=no diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 975c3a4e..31a819c6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,11 +5,13 @@ on: name: CI env: SYMFONY_DEPRECATIONS_HELPER: disabled + SIMPLETEST_BASE_URL: http://app:8888 jobs: tests: runs-on: ubuntu-latest container: image: ghcr.io/city-of-helsinki/drupal-php-docker:8.2-alpine + options: --hostname app services: db: @@ -31,7 +33,7 @@ jobs: run: composer install --no-interaction - name: Scan security updates - run: drush pm:security + run: composer audit - name: Check that subtheme is not built with dev mode run: if grep -q 'sourceMappingURL=' -R public/themes/custom/hdbt_subtheme/dist/css; then exit 1; fi @@ -53,11 +55,7 @@ jobs: - name: Start services run: | - drush runserver $SIMPLETEST_BASE_URL > /dev/null 2>&1 & - chromedriver --port=4444 > /dev/null 2>&1 & - # Chromium browser is required to run 'functional-javascript' and - # 'existing-site-javascript' tests. - chromium-browser --headless --disable-gpu --no-sandbox --remote-debugging-port=9222 & + drush runserver $SIMPLETEST_BASE_URL --dns > /dev/null 2>&1 & # Wait for drush server to start. for i in {1..5}; do RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$SIMPLETEST_BASE_URL" || true); if [ "$RESPONSE_CODE" -gt "301" ] || [ "$RESPONSE_CODE" -lt "200" ]; then sleep 2; fi; done @@ -65,4 +63,5 @@ jobs: - name: Run PHPUnit tests run: | composer test-php public/modules/custom - [ -d "tests/" ] && composer test-php tests/ || echo "No DTT tests found. Ignoring..." + if [ -d "tests/" ]; then composer test-php tests/; else echo "No DTT tests found. Ignoring..."; fi + diff --git a/composer.json b/composer.json index 475a8f6c..b520b8b7 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,8 @@ "drupal/coder": "^8.3", "drupal/core-dev": "^9.1", "phpspec/prophecy-phpunit": "^2", - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^9.6", + "weitzman/drupal-test-traits": "^2.1" }, "conflict": { "drupal/drupal": "*" @@ -44,6 +45,9 @@ "cweagans/composer-patches": true, "drupal/core-composer-scaffold": true, "php-http/discovery": false + }, + "audit": { + "abandoned": "report" } }, "extra": { diff --git a/composer.lock b/composer.lock index 9f7ccf4d..17891860 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c281162f7165d8fee78fe49765383619", + "content-hash": "df243a00a2b5fe53d9a160f323d198f1", "packages": [ { "name": "asm89/stack-cors", @@ -14221,16 +14221,16 @@ }, { "name": "composer/composer", - "version": "2.2.21", + "version": "2.2.22", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "978198befc71de0b18fc1fc5a472c03b184b504a" + "reference": "fedc76ee3f3e3d57d20993b9f4c5fcfb2f8596aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/978198befc71de0b18fc1fc5a472c03b184b504a", - "reference": "978198befc71de0b18fc1fc5a472c03b184b504a", + "url": "https://api.github.com/repos/composer/composer/zipball/fedc76ee3f3e3d57d20993b9f4c5fcfb2f8596aa", + "reference": "fedc76ee3f3e3d57d20993b9f4c5fcfb2f8596aa", "shasum": "" }, "require": { @@ -14300,7 +14300,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.2.21" + "source": "https://github.com/composer/composer/tree/2.2.22" }, "funding": [ { @@ -14316,7 +14316,7 @@ "type": "tidelift" } ], - "time": "2023-02-15T12:07:40+00:00" + "time": "2023-09-29T08:53:46+00:00" }, { "name": "composer/metadata-minifier", @@ -17775,6 +17775,59 @@ } ], "time": "2021-07-28T10:34:58+00:00" + }, + { + "name": "weitzman/drupal-test-traits", + "version": "2.1.0", + "source": { + "type": "git", + "url": "git@gitlab.com:weitzman/drupal-test-traits.git", + "reference": "e40ee4e8e41f229d297c5e714fd63c4a00c633a2" + }, + "dist": { + "type": "zip", + "url": "https://gitlab.com/api/v4/projects/weitzman%2Fdrupal-test-traits/repository/archive.zip?sha=e40ee4e8e41f229d297c5e714fd63c4a00c633a2", + "reference": "e40ee4e8e41f229d297c5e714fd63c4a00c633a2", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "installer-paths": { + "web/core": [ + "type:drupal-core" + ] + }, + "drupal-scaffold": { + "locations": { + "web-root": "web/" + }, + "file-mapping": { + "[project-root]/.editorconfig": false, + "[project-root]/.gitattributes": false, + "[project-root]/.gitignore": false + } + } + }, + "autoload": { + "psr-4": { + "weitzman\\DrupalTestTraits\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "Traits for testing Drupal sites that have user content (versus unpopulated sites).", + "time": "2023-04-23T03:17:53+00:00" } ], "aliases": [], @@ -17786,5 +17839,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/docker-compose.yml b/docker-compose.yml index c9be64c7..c7dc6ba8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,7 @@ services: STAGE_FILE_PROXY_ORIGIN: "${STAGE_FILE_PROXY_ORIGIN}" STAGE_FILE_PROXY_ORIGIN_DIR: "${STAGE_FILE_PROXY_ORIGIN_DIR}" APP_ENV: "${APP_ENV:-local}" + ELASTIC_PROXY_URL: ${ELASTIC_PROXY_URL:-""} DRUPAL_ROUTES: "https://varnish-${DRUPAL_HOSTNAME},https://helfi-proxy.docker.so,http://${COMPOSE_PROJECT_NAME}-varnish" DRUPAL_REVERSE_PROXY_ADDRESS: helfi-proxy.docker.so DRUSH_OPTIONS_URI: "https://${DRUPAL_HOSTNAME}" @@ -21,9 +22,9 @@ services: # xdebug by default (like /etc/environments, ~/.bashrc, or ~/.zshrc). XDEBUG_ENABLE: "${XDEBUG_ENABLE:-false}" # DOCKERHOST: host.docker.internal - # Use drush server to run functional tests so we don't have to care about - # permission issues. - SIMPLETEST_BASE_URL: "http://127.0.0.1:8888" + # Use drush server to run functional tests, so we don't have to care about + # permission or SSL issues. + SIMPLETEST_BASE_URL: "http://app:8888" SIMPLETEST_DB: "mysql://drupal:drupal@db:3306/drupal" BROWSERTEST_OUTPUT_BASE_URL: "https://${DRUPAL_HOSTNAME}" DRUPAL_VARNISH_HOST: "${COMPOSE_PROJECT_NAME}-varnish" @@ -82,6 +83,59 @@ services: - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-varnish.tls=true" - "traefik.http.services.${COMPOSE_PROJECT_NAME}-varnish.loadbalancer.server.port=6081" - "traefik.docker.network=stonehenge-network" + elastic: + image: docker.elastic.co/elasticsearch/elasticsearch:8.4.0 + container_name: "${COMPOSE_PROJECT_NAME}-elastic" + environment: + - node.name="${COMPOSE_PROJECT_NAME}-elastic" + - discovery.seed_hosts=elastic + - cluster.name=es-docker-cluster + - cluster.initial_master_nodes="${COMPOSE_PROJECT_NAME}-elastic" + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - "http.cors.allow-origin=\"*\"" + - "http.cors.enabled=true" + - "http.cors.allow-headers=X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization" + - "http.cors.allow-credentials=true" + - xpack.security.enabled=false + ulimits: + memlock: + soft: -1 + hard: -1 + ports: + - 9200-9220:9200 + networks: + - internal + - stonehenge-network + labels: + - "traefik.enable=true" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-elastic.entrypoints=https" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-elastic.rule=Host(`elastic-${DRUPAL_HOSTNAME}`)" + - "traefik.http.routers.${COMPOSE_PROJECT_NAME}-elastic.tls=true" + - "traefik.http.services.${COMPOSE_PROJECT_NAME}-elastic.loadbalancer.server.port=9200" + - "traefik.docker.network=stonehenge-network" + - "traefik.port=9200" + profiles: + - search + artemis: + container_name: "${COMPOSE_PROJECT_NAME}-artemis" + image: quay.io/artemiscloud/activemq-artemis-broker + environment: + AMQ_EXTRA_ARGS: "--nio --user admin --password admin" + depends_on: + - app + networks: + - internal + profiles: + - queue + chromium: + # @todo Update this to newer version once minkphp supports Selenium 4. + # @see https://github.com/minkphp/MinkSelenium2Driver/pull/372 + image: selenium/standalone-chrome:106.0 + networks: + - internal + profiles: + - testing networks: internal: external: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0ae082a9..b4434b3c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,14 @@ @@ -12,11 +16,11 @@ - - + + - - + + diff --git a/public/sites/default/settings.php b/public/sites/default/settings.php index fb6e9839..e402d926 100755 --- a/public/sites/default/settings.php +++ b/public/sites/default/settings.php @@ -12,6 +12,31 @@ ini_set('zend.enable_gc', 'Off'); } + +if (!function_exists('drupal_get_env')) { + /** + * Gets the value of given environment variable. + * + * @param string|array $variables + * The variables to scan. + * + * @return mixed + * The value. + */ + function drupal_get_env(string|array $variables) : mixed { + if (!is_array($variables)) { + $variables = [$variables]; + } + + foreach ($variables as $var) { + if ($value = getenv($var)) { + return $value; + } + } + return NULL; + } +} + if ($simpletest_db = getenv('SIMPLETEST_DB')) { $parts = parse_url($simpletest_db); putenv(sprintf('DRUPAL_DB_NAME=%s', substr($parts['path'], 1))); @@ -69,6 +94,10 @@ } $routes[] = 'http://127.0.0.1'; +if ($simpletest_base_url = getenv('SIMPLETEST_BASE_URL')) { + $routes[] = $simpletest_base_url; +} + if ($drush_options_uri = getenv('DRUSH_OPTIONS_URI')) { $routes[] = $drush_options_uri; } @@ -102,8 +131,14 @@ 'driver' => 'helfi_azure', 'config' => [ 'name' => $blob_storage_name, - 'key' => getenv('AZURE_BLOB_STORAGE_KEY'), - 'token' => getenv('AZURE_BLOB_STORAGE_SAS_TOKEN'), + 'key' => drupal_get_env([ + 'AZURE_BLOB_STORAGE_KEY', + 'BLOBSTORAGE_ACCOUNT_KEY', + ]), + 'token' => drupal_get_env([ + 'AZURE_BLOB_STORAGE_SAS_TOKEN', + 'BLOBSTORAGE_SAS_TOKEN', + ]), 'container' => getenv('AZURE_BLOB_STORAGE_CONTAINER'), 'endpointSuffix' => 'core.windows.net', 'protocol' => 'https', @@ -205,6 +240,32 @@ $config['helfi_proxy.settings']['robots_header_enabled'] = (bool) $robots_header_enabled; } +$artemis_destination = drupal_get_env([ + 'ARTEMIS_DESTINATION', + 'PROJECT_NAME', +]); + +if ($artemis_brokers = getenv('ARTEMIS_BROKERS') && $artemis_destination) { + $settings['stomp']['default'] = [ + 'clientId' => getenv('ARTEMIS_CLIENT_ID') ?: 'artemis', + 'login' => getenv('ARTEMIS_LOGIN'), + 'passcode' => getenv('ARTEMIS_PASSCODE'), + 'destination' => sprintf('/queue/%s', $artemis_destination), + 'brokers' => $artemis_brokers, + 'timeout' => ['read' => 15000], + 'heartbeat' => [ + 'send' => 12000, + 'receive' => 0, + 'observers' => [ + [ + 'class' => '\Stomp\Network\Observer\HeartbeatEmitter', + ], + ], + ], + ]; + $settings['queue_default'] = 'queue.stomp.default'; +} + $config['filelog.settings']['rotation']['schedule'] = 'never'; if ( diff --git a/tools/make/project/robo.mk b/tools/make/project/robo.mk deleted file mode 100644 index 8780af09..00000000 --- a/tools/make/project/robo.mk +++ /dev/null @@ -1,86 +0,0 @@ -STONEHENGE_PATH ?= ${HOME}/stonehenge -PROJECT_DIR ?= ${GITHUB_WORKSPACE} -SITE_PREFIX ?= / - -SETUP_ROBO_TARGETS := -CI_POST_INSTALL_TARGETS := - -ifeq ($(CI),true) - SETUP_ROBO_TARGETS += install-stonehenge start-stonehenge set-permissions - CI_POST_INSTALL_TARGETS += fix-files-permission -endif - -SETUP_ROBO_TARGETS += up composer-install $(CI_POST_INSTALL_TARGETS) update-automation - -ifeq ($(DRUPAL_BUILD_FROM_SCRATCH),true) - SETUP_ROBO_TARGETS += install-drupal post-install-tasks -else - SETUP_ROBO_TARGETS += install-drupal-from-dump post-install-tasks -endif - -install-stonehenge: $(STONEHENGE_PATH)/.git - -$(STONEHENGE_PATH)/.git: - git clone -b 3.x https://github.com/druidfi/stonehenge.git $(STONEHENGE_PATH) - -PHONY += start-stonehenge -start-stonehenge: - cd $(STONEHENGE_PATH) && COMPOSE_FILE=docker-compose.yml make up - -$(PROJECT_DIR)/helfi-test-automation-python/.git: - git clone https://github.com/City-of-Helsinki/helfi-test-automation-python.git $(PROJECT_DIR)/helfi-test-automation-python - -PHONY += update-automation -update-automation: $(PROJECT_DIR)/helfi-test-automation-python/.git - git pull - -PHONY += install-drupal -install-drupal: - $(call docker_run_ci,app,drush si minimal -y) - $(call docker_run_ci,app,drush cr) - $(call docker_run_ci,app,drush si minimal --existing-config -y) - $(call docker_run_ci,app,drush deploy) - -PHONY += install-drupal-from-dump -install-drupal-from-dump: - $(call docker_run_ci,app,drush sql-drop -y) - $(call docker_run_ci,app,mysql --user=drupal --password=drupal --database=drupal --host=db --port=3306 -A < latest.sql) - $(call docker_run_ci,app,drush deploy) - -PHONY += post-install-tasks -post-install-tasks: - $(call docker_run_ci,app,drush upwd helfi-admin Test_Automation) - $(call docker_run_ci,app,drush en helfi_example_content syslog -y) - $(call docker_run_ci,app,drush helfi:migrate-fixture tpr_unit --publish) - $(call docker_run_ci,app,drush helfi:migrate-fixture tpr_service --publish) - $(call docker_run_ci,app,drush helfi:migrate-fixture tpr_errand_service --publish) - $(call docker_run_ci,app,drush helfi:migrate-fixture tpr_service_channel --publish) - $(call docker_run_ci,app,drush pmu editoria11y -y) - -PHONY += save-dump -save-dump: - $(call docker_run_ci,app,drush sql-dump --result-file=/app/latest.sql) - -PHONY += robo-shell -robo-shell: - @docker compose $(DOCKER_COMPOSE_FILES) exec robo sh - -PHONY += set-permissions -set-permissions: - chmod 777 /home/runner/.cache/composer -R - chmod 777 -R $(PROJECT_DIR) - -PHONY += fix-files-permission -fix-files-permission: - mkdir $(PROJECT_DIR)public/sites/default/files -p && chmod 777 -R $(PROJECT_DIR)public/sites/default/files - -define docker_run_ci - docker compose exec -T $(1) sh -c "$(2)" -endef - -PHONY += setup-robo -setup-robo: $(SETUP_ROBO_TARGETS) - -PHONY += run-robo-tests -run-robo-tests: - $(call docker_run_ci,robo,cd /app/helfi-test-automation-python && chmod +x run_all_tests.sh && PREFIX=$(SITE_PREFIX) BASE_URL=$(DRUPAL_HOSTNAME) ./run_all_tests.sh)