diff --git a/.ahoy.yml b/.ahoy.yml index 489c12314..6aae8a633 100644 --- a/.ahoy.yml +++ b/.ahoy.yml @@ -197,7 +197,7 @@ commands: usage: Lint front-end code. cmd: | ahoy cli vendor/bin/twig-cs-fixer lint - ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" + ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" #;> DRUPAL_THEME lint-tests: @@ -220,7 +220,7 @@ commands: usage: Fix lint issues of front-end code. cmd: | ahoy cli vendor/bin/twig-cs-fixer lint --fix - ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" + ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" #;> DRUPAL_THEME test: @@ -283,7 +283,7 @@ commands: fi hide: true -# Override entrypoint to alter default behaviour of Ahoy. +# Override entrypoint to alter default behavior of Ahoy. entrypoint: - bash - -c diff --git a/.circleci/config.yml b/.circleci/config.yml index ec1b2f1de..8724f3bd1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,7 +48,7 @@ aliases: environment: # Set runner timezone to ensure that executed operations use correct timestamps. # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ: "Australia/Melbourne" + TZ: "UTC" # Set runner terminal capabilities. TERM: xterm-256color # Disable strict host key checking for SSH connections. @@ -69,10 +69,8 @@ aliases: VORTEX_CI_TEST_RESULTS: &test_results /tmp/tests # Directory to store test artifacts. VORTEX_CI_ARTIFACTS: &artifacts /tmp/artifacts - # Directory to store code exported between jobs. - VORTEX_EXPORT_CODE_DIR: &vortex_build_export_dir /tmp/workspace/code # Directory to use for artifact deployments. - VORTEX_DEPLOY_ARTIFACT_SRC: *vortex_build_export_dir + VORTEX_DEPLOY_ARTIFACT_SRC: /tmp/workspace/code # Source code location for artifact deployments. VORTEX_DEPLOY_ARTIFACT_ROOT: *working_directory # Report file location for artifact deployments. @@ -255,8 +253,9 @@ jobs: - run: name: Export built codebase command: | - mkdir -p "${VORTEX_EXPORT_CODE_DIR}" - docker compose cp -L cli:"/app/." "${VORTEX_EXPORT_CODE_DIR}" + mkdir -p "/tmp/workspace/code" + docker compose cp -L cli:"/app/." "/tmp/workspace/code" + du -sh "/tmp/workspace/code" - run: name: Install development dependencies diff --git a/.env b/.env index 50c982549..c8a69de8e 100644 --- a/.env +++ b/.env @@ -1,18 +1,19 @@ ## # Project environment variables. # -# This is a single location where defined variables control how the stack -# operates and should be the primary place for modifications. Avoid overriding +# This is a single location where variables control how the project stack +# operates. It should be the primary place for modifications. Avoid overriding # values in scripts or configuration files to simplify future updates and # centralize changes. # -# Values must be scalar and cannot reference another variable. -# Do not enclose values in double quotes unless they include spaces. +# A value must be scalar and cannot reference another variable. +# Do not enclose a value in double quotes unless it includes spaces. # # To apply any changes made to this file, run `docker-compose up cli -d` or # `ahoy up cli`. # -# To customize variables locally, copy `.env.local.example` to `.env.local`. +# To customize variables locally, copy `.env.local.example` to `.env.local`, +# and add your custom values there. # # @see https://vortex.drevops.com/workflows/variables @@ -30,14 +31,14 @@ VORTEX_PROJECT=your_site # Name of the web root directory containing a Drupal codebase. WEBROOT=web -# The timezone used in the containers. -TZ="Australia/Melbourne" +# The timezone used within the containers. +TZ=UTC ################################################################################ # DRUPAL # ################################################################################ -# Drupal profile name (used only when installing from profile). +# Drupal profile name. DRUPAL_PROFILE=standard #;< DRUPAL_THEME @@ -82,7 +83,7 @@ DRUPAL_CLAMAV_MODE=daemon # or fresh install from profile), running updates, appying configuration # changes, clearing caches and performing other tasks that prepare the site for # use. -# @see https://vortex.drevops.com/workflows/provision +# @see https://vortex.drevops.com/drupal/provision # Set to 'profile' to install a site from profile instead of the database dump. VORTEX_PROVISION_TYPE=database @@ -98,12 +99,13 @@ VORTEX_PROVISION_OVERRIDE_DB=0 # # Database sanitization is enabled by default in all non-production # environments and is always skipped in the production environment. +# @see https://vortex.drevops.com/drupal/provision#database-sanitization VORTEX_PROVISION_SANITIZE_DB_SKIP=0 # Sanitization email pattern. # # Applied if database sanitization is enabled. -# @see https://vortex.drevops.com/workflows/build#sanitization +# @see https://vortex.drevops.com/drupal/provision#database-sanitization VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@your-site-domain.example" # Put the site into a maintenance mode during site provisioning. @@ -129,22 +131,26 @@ VORTEX_ACQUIA_APP_NAME= #;> HOSTING ################################################################################ -# DATABASE # +# DATABASE SOURCE # ################################################################################ # Database service runs a single database within a container. -# See settings.php for database credentials defaults or run -# `ahoy drush sql:connect`. +# See settings.php for database credentials or run # `ahoy drush sql:connect`. # Database can be imported from a *file dump* into an empty database started -# from the database default image or can *exist* in a pre-built container image. +# from the database default container image or can *exist* in a pre-built +# container image. # Defaults to importing from a file. # @see https://vortex.drevops.com/workflows/database # Database dump directory. +# +# The directory is used to store the database dump files for import and export. VORTEX_DB_DIR=./.data # Database dump file name. +# +# The file is used to import the database into an empty database container. VORTEX_DB_FILE=db.sql #;< !PROVISION_TYPE_PROFILE @@ -152,13 +158,13 @@ VORTEX_DB_FILE=db.sql VORTEX_DB_DOWNLOAD_SOURCE=url #;< DB_DOWNLOAD_SOURCE_CONTAINER_REGISTRY -# Name of the pre-built container image. +# Name of the pre-built database container image. # @see https://github.com/drevops/mariadb-drupal-data to seed your DB image. # VORTEX_DB_IMAGE=your_org/your_site:latest #;> DB_DOWNLOAD_SOURCE_CONTAINER_REGISTRY #;< DB_DOWNLOAD_SOURCE_URL -# Database dump file sourced from CURL. +# Database dump file sourced from a URL. # # HTTP Basic Authentication credentials should be embedded into the value. VORTEX_DB_DOWNLOAD_URL= @@ -211,18 +217,22 @@ VORTEX_DEPLOY_TYPES=artifact # The channels of the notifications. # -# Can be a combination of comma-separated values: email,newrelic,github,jira +# A combination of comma-separated values: email,newrelic,github,jira VORTEX_NOTIFY_CHANNELS=email -# Email to send notifications from. -VORTEX_NOTIFY_EMAIL_FROM="webmaster@your-site-domain.example" +# An email address to send notifications from. +# +# Applies to email notifications. +VORTEX_NOTIFY_EMAIL_FROM=webmaster@your-site-domain.example # Email address(es) to send notifications to. # +# Applies to email notifications. +# # Multiple names can be specified as a comma-separated list of email addresses # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" -VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@your-site-domain.example" +VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@your-site-domain.example #;> NOTIFICATIONS #;< DEMO diff --git a/.github/workflows/build-test-deploy.yml b/.github/workflows/build-test-deploy.yml index 94b98fb4e..3217e9d0a 100644 --- a/.github/workflows/build-test-deploy.yml +++ b/.github/workflows/build-test-deploy.yml @@ -59,7 +59,7 @@ jobs: image: drevops/ci-runner:25.5.0 env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" VORTEX_SSH_REMOVE_ALL_KEYS: "1" @@ -168,7 +168,7 @@ jobs: image: drevops/ci-runner:25.5.0 env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color # Disable strict host key checking for SSH connections. VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" @@ -366,7 +366,7 @@ jobs: container: image: drevops/ci-runner:25.5.0 env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} diff --git a/.vortex/docs/.utils/variables/extra/.env.local.example.variables.sh b/.vortex/docs/.utils/variables/extra/.env.local.example.variables.sh index ac921af6f..1b08ad9b7 100755 --- a/.vortex/docs/.utils/variables/extra/.env.local.example.variables.sh +++ b/.vortex/docs/.utils/variables/extra/.env.local.example.variables.sh @@ -5,8 +5,12 @@ # shellcheck disable=SC2034 # Local development URL. +# +# Based on the `$COMPOSE_PROJECT_NAME` environment variable, which is set by +# Docker Compose to the name of the project directory. +# # Override only if you need to use a different URL than the default. -VORTEX_LOCALDEV_URL=".docker.amazee.io" +VORTEX_LOCALDEV_URL="${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io" # Set to `1` to override existing downloaded DB dump without asking. VORTEX_DB_DOWNLOAD_FORCE= diff --git a/.vortex/docs/.utils/variables/extra/.env.variables.sh b/.vortex/docs/.utils/variables/extra/.env.variables.sh index d6323e0db..886e83488 100755 --- a/.vortex/docs/.utils/variables/extra/.env.variables.sh +++ b/.vortex/docs/.utils/variables/extra/.env.variables.sh @@ -18,7 +18,7 @@ VORTEX_DB_IMAGE_BASE= # Drupal admin email. May need to be reset if database was sanitized. DRUPAL_ADMIN_EMAIL="webmaster@your-site-domain.example" -# Password replacement used for sanitised database. +# Password replacement used for sanitized database. VORTEX_PROVISION_SANITIZE_DB_PASSWORD="" # Container registry name. diff --git a/.vortex/docs/.utils/variables/extra/ci.variables.sh b/.vortex/docs/.utils/variables/extra/ci.variables.sh index 590def73f..9adc31faf 100755 --- a/.vortex/docs/.utils/variables/extra/ci.variables.sh +++ b/.vortex/docs/.utils/variables/extra/ci.variables.sh @@ -9,9 +9,6 @@ VORTEX_DEPLOY_SKIP= # Proceed with container image deployment after it was exported. VORTEX_EXPORT_DB_CONTAINER_REGISTRY_DEPLOY_PROCEED= -# Directory to store exported code. -VORTEX_EXPORT_CODE_DIR= - # Ignore Hadolint failures. VORTEX_CI_HADOLINT_IGNORE_FAILURE=0 @@ -69,3 +66,7 @@ RENOVATE_DRY_RUN=false # Commit author for self-hosted Renovate bot. RENOVATE_GIT_AUTHOR='Renovate Self Hosted ' + +# Renovate repositories to manage. +# Set as "organization/repository". +RENOVATE_REPOSITORIES= diff --git a/.vortex/docs/content/README.mdx b/.vortex/docs/content/README.mdx index 9b0dabf53..aaee0d7a4 100644 --- a/.vortex/docs/content/README.mdx +++ b/.vortex/docs/content/README.mdx @@ -14,15 +14,24 @@ sidebar_position: 1 +**Vortex** is a Drupal project template designed to streamline onboarding, +accelerate development, and support long-term maintainability. -Welcome to Vortex — a project template for Drupal designed to simplify onboarding and website maintenance. +It provides a complete foundation for building and deploying Drupal sites β€” +including containerized local environments, automated testing and code quality +tools, CI/CD pipeline configurations, and integrations with popular hosting +platforms. Everything is pre-configured and ready to use, so teams can focus on +building features instead of setting up infrastructure. -At [DrevOps®](https://www.drevops.com/), we carefully maintain this -template, keeping it aligned with the latest tools and validating it through -automated tests to ensure everything works together seamlessly. +By standardizing project structure and tooling, **Vortex** ensures a consistent +developer experience across every project that uses it. Whether you’re starting +fresh or joining an existing Vortex-based site, you can get up to speed quickly +and start contributing right away. -Our goal is to provide a consistent developer experience across projects, making -it easier to switch between them and get up to speed quickly. +The template is actively maintained and kept in sync with the latest tools. +Every change is verified through automated tests to ensure updates remain stable +and reliable β€” reducing the risk of regressions and making it easier to maintain +projects over time. ## Main features diff --git a/.vortex/docs/content/ci/README.mdx b/.vortex/docs/content/ci/README.mdx index 1dcf5514c..1e637355d 100644 --- a/.vortex/docs/content/ci/README.mdx +++ b/.vortex/docs/content/ci/README.mdx @@ -58,5 +58,5 @@ The CI pipeline is triggered by: Database is downloaded overnight and cached so that the next CI run on the same day uses the cached database dump. -By default, the database is cached per-branch for 24 hours. Of cache is not +By default, the database is cached per-branch for 24 hours. If cache is not available, the fallback default branch is used. diff --git a/.vortex/docs/content/contributing/maintenance/scripts.mdx b/.vortex/docs/content/contributing/maintenance/scripts.mdx index 3c9363cda..246a56ab2 100644 --- a/.vortex/docs/content/contributing/maintenance/scripts.mdx +++ b/.vortex/docs/content/contributing/maintenance/scripts.mdx @@ -82,7 +82,7 @@ Follow these guidelines when creating or updating **Vortex** variables. 1. Local variables MUST be in lowercase, and global variables MUST be in uppercase. -2. All **Vortex** variables MUST start with `VORTEX_` to separate Vortex from +2. All **Vortex** variables MUST start with `VORTEX_` to separate **Vortex** from third-party variables. 3. Global variables MAY be re-used as-is across scripts. For instance, the diff --git a/.vortex/docs/content/contributing/roadmap.mdx b/.vortex/docs/content/contributing/roadmap.mdx index 499e20054..dd71178f1 100644 --- a/.vortex/docs/content/contributing/roadmap.mdx +++ b/.vortex/docs/content/contributing/roadmap.mdx @@ -25,4 +25,4 @@ bug fixes required. 1. Adding integration with Platform.sh. 2. Adding support for Cypress and Drupal Test Traits. 2. Adding support for Visual Regression and Accessibility tools. -3. Introduction of the Vortex Dashboard as a single place for managing projects. +3. Introduction of the **Vortex** Dashboard as a single place for managing projects. diff --git a/.vortex/docs/content/drupal/README.mdx b/.vortex/docs/content/drupal/README.mdx index 500d8dc3b..28f19aee4 100644 --- a/.vortex/docs/content/drupal/README.mdx +++ b/.vortex/docs/content/drupal/README.mdx @@ -6,10 +6,11 @@ sidebar_position: 1 # Drupal When it comes to Drupal code, **Vortex** offers several key components: + 1. [Composer configuration](composer) 2. [Settings management](settings) 3. [Provision script](provision) -4. [Module scaffold with tests scaffold](module-scaffold) +4. [Module scaffold](module-scaffold) 5. [Theme scaffold](theme-scaffold) ## Included modules @@ -18,21 +19,20 @@ Please note that **Vortex** is not a Drupal distribution, and it does not aim to provide a full Drupal installation profile or a set of recipes. Instead, it provides you with a minimal set of modules and dependencies to get you started. -You would add more modules and themes once you finish the initial setup. - +You would need to add more modules and themes once you finish the initial setup. -| Module Name | Description | -|----------------------------------------------|-----------------------------------------------------------| -| [`admin_toolbar`](https://www.drupal.org/project/admin_toolbar) | Extends the Drupal Toolbar with drop-down menus for easier access to admin pages. | -| [`clamav`](https://www.drupal.org/project/clamav) | Integrates ClamAV antivirus for file scanning in Drupal. | -| [`coffee`](https://www.drupal.org/project/coffee) | Provides quick access to admin pages through a search bar. | -| [`config_split`](https://www.drupal.org/project/config_split) | Allows exporting and importing different configurations. | -| [`config_update`](https://www.drupal.org/project/config_update) | Tracks and updates configuration changes on your site. | -| [`environment_indicator`](https://www.drupal.org/project/environment_indicator) | Adds a visual indicator for the current environment (e.g., Dev, Prod). | -| [`pathauto`](https://www.drupal.org/project/pathauto) | Automatically generates URL/path aliases for content. | -| [`redirect`](https://www.drupal.org/project/redirect) | Provides URL redirection management. | -| [`redis`](https://www.drupal.org/project/redis) | Integrates Valkey caching backend with Drupal. | -| [`search_api`](https://www.drupal.org/project/search_api) | Provides a flexible framework for creating search pages. | -| [`search_api_solr`](https://www.drupal.org/project/search_api_solr) | Integrates Apache Solr with Search API. | -| [`shield`](https://www.drupal.org/project/shield) | Protects your site with HTTP authentication. | -| [`stage_file_proxy`](https://www.drupal.org/project/stage_file_proxy) | Serves production files for non-production environments. | +| Module Name | Description | +|---------------------------------------------------------------------------------|-----------------------------------------------------------------------------------| +| [`admin_toolbar`](https://www.drupal.org/project/admin_toolbar) | Extends the Drupal Toolbar with drop-down menus for easier access to admin pages. | +| [`clamav`](https://www.drupal.org/project/clamav) | Integrates ClamAV antivirus for file scanning. | +| [`coffee`](https://www.drupal.org/project/coffee) | Provides quick access to admin pages through a search bar. | +| [`config_split`](https://www.drupal.org/project/config_split) | Allows exporting and importing different configurations based on the environment. | +| [`config_update`](https://www.drupal.org/project/config_update) | Tracks and updates configuration changes on your site. | +| [`environment_indicator`](https://www.drupal.org/project/environment_indicator) | Adds a visual indicator for the current environment (e.g., Dev, Stage, Prod). | +| [`pathauto`](https://www.drupal.org/project/pathauto) | Automatically generates URL/path aliases for content. | +| [`redirect`](https://www.drupal.org/project/redirect) | Provides URL redirection management. | +| [`redis`](https://www.drupal.org/project/redis) | Integrates Valkey caching backend. | +| [`search_api`](https://www.drupal.org/project/search_api) | Provides a flexible framework for creating search pages. | +| [`search_api_solr`](https://www.drupal.org/project/search_api_solr) | Integrates Apache Solr with Search API. | +| [`shield`](https://www.drupal.org/project/shield) | Restricts access to your site by requiring a username and password. | +| [`stage_file_proxy`](https://www.drupal.org/project/stage_file_proxy) | Serves production asset files when accessing non-production environments. | diff --git a/.vortex/docs/content/drupal/composer.mdx b/.vortex/docs/content/drupal/composer.mdx index c736f763b..2e2965fb2 100644 --- a/.vortex/docs/content/drupal/composer.mdx +++ b/.vortex/docs/content/drupal/composer.mdx @@ -40,12 +40,12 @@ explaining its role and how it contributes to your project's setup and management. import CodeBlock from '@theme/CodeBlock'; -import MyComponentSource from '!!raw-loader!./../../../../composer.json'; +import ComposerJsonSource from '!!raw-loader!./../../../../composer.json';
Click here to see the contents of the `composer.json` file - {MyComponentSource} + {ComposerJsonSource}
diff --git a/.vortex/docs/content/drupal/module-scaffold.mdx b/.vortex/docs/content/drupal/module-scaffold.mdx index 43a9422bb..bea69e783 100644 --- a/.vortex/docs/content/drupal/module-scaffold.mdx +++ b/.vortex/docs/content/drupal/module-scaffold.mdx @@ -7,17 +7,18 @@ sidebar_position: 4 [Module scaffold](https://github.com/drevops/vortex/tree/develop/web/modules/custom/ys_base) is an example of a Drupal module. -We recommend creating a custom `ys_base` module for your project to place -custom functionality that is not specific to a feature that can be placed in -a dedicated self-contained module. +We recommend creating a custom `ys_base` module for your project to hold +general-purpose functionality that doesn’t belong in a dedicated, +feature-specific module. The `ys` prefix is abbreviated from your project name (`your_site` in this case). -We recommend using this technique to prefix all modules, and use the site full -name for a theme name (`yoursite` in this case). +We recommend using this technique to prefix all modules, and use the site +machine name for a theme name. ## Deploy file -The `ys_base.deploy` file is an example of a Drush deploy file that can be used +The [`ys_base.deploy.php`](https://github.com/drevops/vortex/blob/develop/web/modules/custom/ys_base/ys_base.deploy.php) +file is an example of a Drush deploy file that can be used to run deployment commands during the site [provisioning](provision) process. ## Tests scaffold @@ -26,4 +27,9 @@ The `tests` directory contains working examples of tests that can be used as a starting point in your project. It also has a set of helper `Traits` that you may find useful when writing your -tests. Or simply remove them if you do not find them useful. +tests. Simply remove them if you do not find them useful. + +--- + +See [Development](/workflows/development) for more details on how to work with +the custom modules. diff --git a/.vortex/docs/content/drupal/provision-example.sh b/.vortex/docs/content/drupal/provision-example.sh new file mode 100755 index 000000000..810481fe7 --- /dev/null +++ b/.vortex/docs/content/drupal/provision-example.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +## +# Example of the custom per-project command that will run after website is installed. +# +# Clone this file and modify it to your needs or simply remove it. +# +# For ordering multiple commands, use a two-digit suffix for clarity and consistency. +# This approach ensures a clear sequence and avoids potential ordering issues. +# +# Example: +# - provision-10-example.sh +# - provision-20-example.sh +# - provision-30-example.sh +# +# shellcheck disable=SC2086 + +set -eu +[ "${VORTEX_DEBUG-}" = "1" ] && set -x + +# ------------------------------------------------------------------------------ + +info() { printf " ==> %s\n" "${1}"; } +task() { printf " > %s\n" "${1}"; } +note() { printf " %s\n" "${1}"; } + +drush() { ./vendor/bin/drush -y "$@"; } + +info "Started example operations." + +# πŸ‘‡ Get the current environment from Drupal settings. +environment="$(drush php:eval "print \Drupal\core\Site\Settings::get('environment');")" +note "Environment: ${environment}" + +# πŸ‘‡ Perform operations based on the current environment. +if echo "${environment}" | grep -q -e dev -e stage -e ci -e local; then + note "Running example operations in non-production environment." + + # πŸ‘‡ Enable custom site modules and run its deployment hooks. + task "Installing custom site modules." + drush pm:install ys_base ys_search + + # πŸ‘‡ Conditionally perform an action if this is a "fresh" database. + if [ "${VORTEX_PROVISION_OVERRIDE_DB:-0}" = "1" ]; then + note "Fresh database detected. Performing additional example operations." + else + note "Existing database detected. Performing additional example operations." + fi +else + note "Skipping example operations in production environment." +fi + +info "Finished example operations." diff --git a/.vortex/docs/content/drupal/provision.mdx b/.vortex/docs/content/drupal/provision.mdx index a98e5e4f9..7ee919bbd 100644 --- a/.vortex/docs/content/drupal/provision.mdx +++ b/.vortex/docs/content/drupal/provision.mdx @@ -7,77 +7,54 @@ sidebar_position: 3 The provisioning process, handled by the [`provision.sh`](https://github.com/drevops/vortex/blob/develop/scripts/vortex/provision.sh) script, sets up a -Drupal site by either restoring an existing database or installing a fresh -instance using a profile, followed by running the necessary configuration -import and database updates. +Drupal site on already assembled codebase by either importing an existing +database from the dump or installing a fresh instance of Drupal using a profile, +followed by running the necessary configuration import and database updates. The main purpose of the script is to automate the setup of a Drupal site in every environment, ensuring consistency and eliminating manual steps. +## Rationale + +While `drush deploy` is a powerful tool for executing standard Drupal deployment +steps (such as configuration import and database updates), it assumes that the +site is already in a bootstrapped, stable state. In practice, especially during +initial setup or provisioning in dynamic environments (like CI pipelines, +container rebuilds, or multisite setups), additional orchestration is needed. + +The `provision.sh` script addresses these gaps by: +- **Bootstrapping the environment:** It can import a database dump or install a fresh Drupal instance from a +profile. +- **Handling conditional logic:** It accounts for different runtime scenarios, such as skipping provisioning, +enforcing fresh database imports, or using maintenance mode. +- **Enforcing consistency:** The same provisioning logic runs across local, CI, staging, and production +environments, eliminating β€œit works on my machine” issues. +- **Supporting extensibility:** It allows for custom post-provisioning scripts, making it easy to layer in +project-specific logic like enabling test modules or running migrations. + +In short, `provision.sh` wraps `drush deploy` in a consistent, repeatable, and +configurable process β€” turning a manual setup step into a reliable automation +layer. + ## Provisioning flow -```mermaid -graph TD; - START((πŸš€ Start)) --> B; - - B{πŸ’‘ Skip provision? 1} - B -- No --> C; - B -- Yes --> B1(((🏁 End))); - - C{πŸ’‘ Can bootstrap?}; - C -- Yes --> C1; - C1{πŸ’‘ Override DB? 2} - C1 --> | No
Preserve existing DB | D; - C1 -- Yes --> C11; - C11[πŸ—‘οΈ Drop DB]; - C11 --> C12 - C12{πŸ’‘ Use DB dump
or profile? 3} - C12 -- DB dump --> C121[πŸ›’οΈ Import from DB dump]; - C121 --> D - C12 -- Profile --> C122[πŸ“¦ Install from profile]; - C122 --> D - C -- No --> C11 - - D@{ shape: braces, label: "Site is bootstrappable" } - D --> E - - E{πŸ’‘ Skip other operations? 4} - E -- No --> F; - E -- Yes --> E1(((🏁 End))); - - F[🚧 Enable maintenance mode 5]; - F --> G - - subgraph SG3 ["Standard operations"] - direction BT - G[⬇️ Import configuration]; - G --> H[πŸ”„ Run DB updates]; - H --> I[🧹 Rebuild caches]; - I --> J[πŸ”„ Run deployment updates] - end - - J --> K["😷 Run DB sanitization 6"] - K --> L["βš™οΈ Run custom scripts"]; - L --> M["🚧 Disable maintenance mode 5"]; - - M-->END - END(((🏁 End))); -``` + + Provision flow + Provision flow + ### Customizing flow You can control the provisioning flow using the following environment variables: -| Variable | Description | -|-------------------------------------------|--------------------------------------------------------------------------------------------------------------------| -| `VORTEX_PROVISION_SKIP=1` | Kill-switch to skip provisioning entirely. Useful in emergencies when any kind of automation needs to be disabled. | -| `VORTEX_PROVISION_TYPE=profile` | Install from a Drupal `profile` instead of importing from a `database` dump. | -| `VORTEX_PROVISION_OVERRIDE_DB=1` | Drop an existing database before importing from dump/installing from profile. | -| `VORTEX_PROVISION_POST_OPERATIONS_SKIP=1` | Skip configuration imports, database updates, and other post-provisioning steps. | -| `VORTEX_PROVISION_USE_MAINTENANCE_MODE=1` | Enable maintenance mode right after the site is bootstrappable and disable it at the end. | -| `VORTEX_PROVISION_SANITIZE_DB_SKIP=1` | Disable database sanitization. | +1. `VORTEX_PROVISION_SKIP=1`
Kill-switch to completely skip provisioning. The script will exit immediately after start. Useful in emergencies when any kind of automation needs to be disabled.

+2. `VORTEX_PROVISION_OVERRIDE_DB=1`
Drop an existing database before importing from dump/installing from profile. This is useful when an already provisioned environment requires a fresh database to be imported.

+3. `VORTEX_PROVISION_TYPE=profile`
Install from a Drupal `profile` instead of importing from a `database` dump. Useful for building sites without the persistent DB and/or test profile configuration installation.

+4. `VORTEX_PROVISION_POST_OPERATIONS_SKIP=1`
Skip configuration imports, database updates, and other post-provisioning steps. Essentially, this is `drush sql:drop` and `drush sql:cli < .data/db.sql` commands. This is useful when you want to provision a site without running any additional operations.

+5. `VORTEX_PROVISION_USE_MAINTENANCE_MODE=1`
Enable maintenance mode right after the site is bootstrappable and disable it at the end. Useful when you want to prevent users from accessing the site while it is being provisioned.

+6. `VORTEX_PROVISION_SANITIZE_DB_SKIP=1`
Disable database sanitization. -## Maintenance mode +### Maintenance mode During the provisioning process, you may want to enable maintenance mode to prevent users from accessing the site while it is being updated. @@ -86,72 +63,71 @@ To enable maintenance mode, set the `VORTEX_PROVISION_USE_MAINTENANCE_MODE=1` environment variable in your `.env` file to apply it globally or set it in your hosting provider's specific environment. -## Database sanitization +### Database sanitization The `provision.sh` script includes a step to sanitize the database after -provisioning. This step is essential for ensuring that sensitive data is not -present in non-production environments. +provisioning. This helps ensure that sensitive data β€” like real email addresses, +passwords, and user information β€” is replaced with safe, generic values in +non-production environments. It prevents issues like accidentally sending emails +to real users or exposing private data during testing, making shared +environments safer to work with. :::warning - This step does not prevent developers from accessing sensitive data in - the database dump directly. If your database has highly sensitive data, - consider sanitizing the database dump before it can be downloaded. + Sanitization takes place only after the database is **imported**, so anyone + with access to the dump file can still see sensitive data. + + If your database has highly sensitive data, consider sanitizing the database + dump before it can be downloaded (sanitize on export). There are tools + available for this purpose, such as [Drush GDPR Dumper](https://github.com/robiningelbrecht/drush-gdpr-dumper) + or [MTK](https://github.com/skpr/mtk). ::: -To disable database sanitization, set the `VORTEX_PROVISION_SANITIZE_DB_SKIP=1` -in the `.env` file or in your hosting provider's specific environment. +The database sanitization step is enabled by default on all environments except +production. To disable database sanitization, set the +`VORTEX_PROVISION_SANITIZE_DB_SKIP=1` in the `.env` file or in your hosting +provider's specific environment. -### Customizing database sanitization +#### Customizing database sanitization -Use the following environment variables to customize the database sanitization: +Place these variables in the `.env` file or in your hosting provider's specific +environment to further customize the database sanitization: -| Variable | Default value | Description | -|------------------------------------------------------------|--------------------------------------|----------------------------------------------------| -| `VORTEX_PROVISION_SANITIZE_DB_EMAIL` | `user_%uid@your-site-domain.example` | Database sanitized account email replacement. | -| `VORTEX_PROVISION_SANITIZE_DB_PASSWORD` | Random | Database sanitized account password replacement. | -| `VORTEX_PROVISION_SANITIZE_DB_REPLACE_USERNAME_WITH_EMAIL` | `0` (disabled) | Replace username with mail. | -| `VORTEX_PROVISION_SANITIZE_DB_ADDITIONAL_FILE` | `./scripts/sanitize.sql` | Path to file with custom sanitization SQL queries. | +1. `VORTEX_PROVISION_SANITIZE_DB_EMAIL=user_%uid@your-site-domain.example`
Replace all emails with a tokenized email string.

+2. `VORTEX_PROVISION_SANITIZE_DB_PASSWORD=`
Replace passwords with a random or exact value.

+3. `VORTEX_PROVISION_SANITIZE_DB_REPLACE_USERNAME_WITH_EMAIL=0`
Replace username with email. Useful to also sanitize user names.

+4. `VORTEX_PROVISION_SANITIZE_DB_ADDITIONAL_FILE=./scripts/sanitize.sql`
Path to a file with custom sanitization SQL queries.

## Running custom scripts -The `provision.sh` script can execute custom scripts or commands after the -standard provisioning steps. This feature allows you to automate additional -tasks specific to your project (migrations, conditionally enabling modules etc). +The `provision.sh` script can execute custom scripts after all provisioning +steps. This feature allows you to automate additional tasks specific to your +project, such as conditionally enabling modules or running migrations in a +specific order. To run custom scripts, create a new file in the `scripts/custom` directory -with the `provision-` prefix and the `.sh` extension. The script will be -automatically sourced and executed after the standard provisioning steps. -Make sure the script is executable: -`chmod +x scripts/custom/provision-10-example.sh`. +with the `provision-` prefix and the `.sh` extension, and make it executable +with `chmod +x scripts/custom/provision-10-example.sh`. The script will be +automatically discovered and executed. It is recommended to use a 2-digit suffix to control the order of execution: e.g., `provision-10-example.sh`, `provision-20-another-example.sh`. -Expand below to see an example script [ -`scripts/custom/provision-10-example.sh`](https://github.com/drevops/vortex/blob/develop/scripts/custom/provision-10-example.sh) -script: - -import CodeBlock from '@theme/CodeBlock'; -import ProvisionScriptExample from '!!raw-loader!./../../../../scripts/custom/provision-10-example.sh'; - -
- Example of a custom script - -{ProvisionScriptExample} - -
- ### Conditional execution You may choose to only perform an action based on a specific environment (the value of `$settings['environment']` is populated by -the [Drupal settings file](settings#1-environment-type-constants-definitions)): +the [Drupal settings file](settings#environment-type-detection)): ```bash -if drush php:eval "print \Drupal\core\Site\Settings::get('environment');" | grep -q -e dev -e ci -e local; then - echo "==> Executing example operations in DEV, CI or Local environment." +environment="$(drush php:eval "print \Drupal\core\Site\Settings::get('environment');")" + +if echo "${environment}" | grep -q -e dev -e stage -e ci -e local; then + echo "> Running custom script for dev, stage, ci, or local environment." + # Place your commands here. +else + echo "> Skipping custom script for ${environment} environment." fi ``` @@ -160,8 +136,21 @@ freshly imported or not: ```bash if [ "${VORTEX_PROVISION_OVERRIDE_DB:-0}" = "1" ]; then - echo " > Fresh database detected." + echo "> Fresh database detected." else - echo " > Existing database detected." + echo "> Existing database detected." fi ``` + +Expand below to see a provision scaffold script that you can use as a +starting point for your custom scripts: + +import CodeBlock from '@theme/CodeBlock'; +import ProvisionScriptExample from '!!raw-loader!./provision-example.sh'; + +
+ Example of a custom provision script + +{ProvisionScriptExample} + +
diff --git a/.vortex/docs/content/drupal/settings.mdx b/.vortex/docs/content/drupal/settings.mdx index 32e8304a0..aab0e09c1 100644 --- a/.vortex/docs/content/drupal/settings.mdx +++ b/.vortex/docs/content/drupal/settings.mdx @@ -4,32 +4,105 @@ sidebar_position: 2 # Settings -The `settings.php` file provides the primary configuration for a Drupal site, -including its database connection, file paths, and various other settings. +Drupal site configuration β€” including database connections, file paths, and +environment-specific behavior β€” is controlled through the `settings.php` and +`services.yml` files. This section explains how **Vortex** structures and +extends these files to support consistent setup across environments. -**Vortex** ships with own streamlined version of +**Vortex** ships with its own streamlined version of the [`settings.php`](https://github.com/drevops/vortex/blob/develop/web/sites/default/settings.php) and [`services.yml`](https://github.com/drevops/vortex/blob/develop/web/sites/default/services.yml) files. -It also provides [Settings unit tests](#testing-settings-with-unit-tests) to ensure that -the settings apply correctly when a site runs in a specific environment. These -tests are intended to be maintained within your project, ensuring that the -settings activated within a specific _environment type_ and with specific -_environment variables_ applied correctly. +It provides logic to detect the current environment (such as local, CI, or +production) and apply settings conditionally. You can also define configuration +overrides for individual modules if needed. The default **Drupal Scaffold**'s [`default.settings.php`](https://github.com/drevops/vortex/blob/develop/web/sites/default/default.settings.php) and [`default.services.yml`](https://github.com/drevops/vortex/blob/develop/web/sites/default/default.services.yml) files are also provided if you choose to use them instead. -The [`settings.php`](https://github.com/drevops/vortex/blob/develop/web/sites/default/settings.php) file is divided -into several sections: +## Approach + +Managing Drupal settings across multiple environments β€” such as local, CI, +development, staging, and production β€” often requires conditional configuration. +Different environments may need to enable or disable modules, change performance +settings, use different APIs, or point to different services. + +The challenge is that Drupal doesn’t offer a standard way to manage these +environment-specific differences. Its configuration system is not designed to +handle conditional logic, such as applying different settings based on runtime +environment, or retrieving values from environment variables. + +Modules like `config_split` can help by allowing you to maintain separate +configuration sets per environment, but they are limited: they don’t support +environment-based conditions inside the configuration YAML files, cannot access +environment variables directly, and are not suitable when you need dynamic logic +(e.g. setting values based on external service URLs). + +**Vortex** does support `config_split` as part of its standard tooling, and it’s +ideal for use cases where declarative configuration is sufficient β€” for example, +enabling a module in staging but not production. However, when settings require +conditional logic or need to pull values from the environment, `config_split` +does not suffice. In addition, it is not possible to automatically test which +settings are applied in a specific environment. + +**Vortex** addresses this problem with a clear and maintainable approach: +- The _environment type_ is [detected](#environment-type-detection) based on the + environment where the site is running. This detection step is isolated and + does not apply any configuration overrides. +- Configuration overrides are defined in [per-module override files](#per-module-overrides), + with conditions applied based on the detected _environment type_. + +This structure offers several benefits: +- It keeps environment detection separate from configuration logic. +- It makes it easy to see how a module behaves in a specific environment β€” all +in one place. +- If a module is no longer needed, its override file can be safely removed +without modifying the `settings.php` file. +- It prevents environment-specific settings from leaking into unrelated parts of +the configuration. + +## Guidelines + +When working with settings, follow these guidelines to ensure clarity, consistency, and maintainability: +- **Do not modify `settings.php` directly.
** + Use environment variables for [general](#general) settings or [per-module override files](#per-module-overrides) + for any custom or environment-aware configuration. + +- **Keep all overrides isolated by module.**
+ Each file should encapsulate logic for a single module only. If a module is + removed, its override file should be removable without affecting unrelated + settings. + +- **Use environment variables for configuration that changes by environment.**
+ Prefix all such variables with `DRUPAL_` (e.g. `DRUPAL_MY_SETTING`) to easily + distinguish them from other environment variables.
+ Always define a default hardcoded value for each environment variable. + +- **Use conditions based on _environment type_ within per-module override files.**
+ This allows for environment-specific configuration without cluttering the main + `settings.php` file.
+ Use the `$settings['environment']` variable to check the current _environment type_. + +import EnvironmentIndicatorModuleSettingsExample from '!!raw-loader!./../../../../web/sites/default/includes/modules/settings.environment_indicator.php'; -1. [Environment type constants definitions](#1-environment-type-constants-definitions) -2. [Site-specific settings](#2-site-specific-settings) -3. [Environment detection](#3-environment-type-detection) -4. [Per-environment overrides](#4-per-environment-overrides) -5. [Inclusion of generated Settings](#5-inclusion-of-per-module-settings) -6. [Inclusion of local settings](#6-inclusion-of-local-settings) +
+ Example of the `Environment indicator` module settings file + +{EnvironmentIndicatorModuleSettingsExample} + +
+ +## Settings file structure + +The [`settings.php`](https://github.com/drevops/vortex/blob/develop/web/sites/default/settings.php) +file is organized into the following sections: + +- [Database](#database) +- [General](#general) +- [Environment type detection](#environment-type-detection) +- [Per-module overrides](#per-module-overrides) +- [Local overrides](#local-overrides) import CodeBlock from '@theme/CodeBlock'; import SettingsExample from '!!raw-loader!./../../../../web/sites/default/settings.php'; @@ -41,122 +114,143 @@ import SettingsExample from '!!raw-loader!./../../../../web/sites/default/settin -### 1. Environment type constants definitions +### Database -Constants for various _environment types_ are defined here. These can be used to -alter site behavior based on the active _environment type_. +Database configuration is managed through environment variables with sensible +defaults, offering flexibility across hosting environments while keeping the +setup consistent. -Available _environment type_ constants are: +To support a variety of hosting providers and container platforms, multiple +environment variable names are accepted for each setting: -- `ENVIRONMENT_LOCAL` -- `ENVIRONMENT_CI` -- `ENVIRONMENT_PROD` -- `ENVIRONMENT_STAGE` -- `ENVIRONMENT_DEV` +| Variable | Alternative Variables | Default | Purpose | +|----------------------|-----------------------------------------|----------------------|-------------------| +| `DATABASE_NAME` | `DATABASE_DATABASE`, `MARIADB_DATABASE` | `drupal` | Database name | +| `DATABASE_USERNAME` | `MARIADB_USERNAME` | `drupal` | Database username | +| `DATABASE_PASSWORD` | `MARIADB_PASSWORD` | `drupal` | Database password | +| `DATABASE_HOST` | `MARIADB_HOST` | `localhost` | Database host | +| `DATABASE_PORT` | `MARIADB_PORT` | `3306` | Database port | +| `DATABASE_CHARSET` | `MARIADB_CHARSET`, `MYSQL_CHARSET` | `utf8mb4` | Character set | +| `DATABASE_COLLATION` | `MARIADB_COLLATION`, `MYSQL_COLLATION` | `utf8mb4_general_ci` | Collation | -These are later used to set `$settings['environment']`, which can be -used in the modules and shell scripts to target code execution to specific -_environments types_. +These variables normally should not be modified unless you are using a +custom database setup or a different hosting provider that requires specific +configuration. The defaults are designed to work with most common setups, +including local development environments and popular hosting providers. -:::info[EXAMPLE] +### General - ```shell - if drush php:eval "print \Drupal\core\Site\Settings::get('environment');" | grep -q -e ci -e local; then - # Do something only in CI or local environments. - fi - ``` +This section configures generic site settings such as file paths, security +patterns, performance optimizations, and essential directories. These settings +are identical across all _environment types_. -::: +The following environment variables can be used to customize general settings: -### 2. Site-specific settings +| Variable | Alternative Variables | Default | Purpose | +|-----------------------------|-----------------------|--------------------------------|------------------------------------------| +| `DRUPAL_CONFIG_PATH` | | `../config/default` | Location of configuration sync directory | +| `DRUPAL_PUBLIC_FILES` | | `sites/default/files` | Public files directory path | +| `DRUPAL_PRIVATE_FILES` | | `sites/default/files/private` | Private files directory path | +| `DRUPAL_TEMPORARY_FILES` | | `/tmp` | Temporary files directory path | +| `DRUPAL_HASH_SALT` | | _Generated from database host_ | Cryptographic salt for security | +| `DRUPAL_TIMEZONE` | `TZ` | `UTC` | Site timezone | +| `DRUPAL_MAINTENANCE_THEME` | `DRUPAL_THEME` | `claro` | Theme used during maintenance mode | +| `DRUPAL_CACHE_PAGE_MAX_AGE` | | `900` | Page cache expiration time (seconds) | -This section is used for configuring core site settings such as defining paths, -ensuring security with trusted host patterns, setting performance optimizations -like aggregating CSS and JS files, and specifying essential directories for -Drupal's functionality. +### Environment type detection -These settings are identical for all _environment types_ . +**Vortex** defines an _environment type_ to represent the context in which the +Drupal site is running β€” such as local, CI, development, staging, or production. +This concept allows the system to conditionally adjust settings and behaviors +depending on the runtime environment. -Use per-module settings files in the [`web/site/default/includes/modules`](https://github.com/drevops/vortex/tree/develop/web/sites/default/includes/modules) -directory to override per-module settings. +The _environment type_ is detected automatically based on known hosting provider +indicators or predefined environment variables. Detection logic is intentionally +isolated from configuration logic β€” it identifies the context but does not apply +any overrides directly. -### 3. Environment type detection +Once detected, the environment type is stored in the `$settings['environment']` +value, which can be used by modules, settings overrides, and shell scripts to +drive environment-specific behavior. -This section uses known hosting providers mechanisms to determine the -_environment type_ where the site currently runs. +#### Environment type constants -Settings for the supported hosting providers are stored in the -[`web/site/default/includes/providers`](https://github.com/drevops/vortex/tree/develop/web/sites/default/includes/providers) -directory. You can add your own custom provider _environment type_ detection logic -by creating a new file `settings.[provider].php` in this directory. +**Vortex** defines the following constants to represent supported environments: +- `ENVIRONMENT_LOCAL` +- `ENVIRONMENT_CI` +- `ENVIRONMENT_DEV` +- `ENVIRONMENT_STAGE` +- `ENVIRONMENT_PROD` -Once a hosting provider is detected, the _environment type_ -`$settings['environment']` is set to -`ENVIRONMENT_DEV` for all environments as a default. +These constants are used consistently across settings files and scripts to +determine conditional behavior. -Higher-level environments types (`PROD`, `STAGE` etc.) are then set based on -the **additional** detected provider-specific settings. +#### Detection mechanism -When the hosting provider is not detected, the default value is set to -`ENVIRONMENT_LOCAL`. +The detection process uses indicators provided by known hosting platforms. Logic +for supported providers is stored in the `includes/providers` directory. -:::note +To add support for a custom platform, simply create a `settings.[provider].php` +file in that directory with the relevant detection logic. - Environment type detection settings are only used for _environment type_ - detection and not for environment-specific settings. Those are defined in - the [Per-environment overrides](#4-per-environment-overrides) section. - This approach allows for a more flexible and maintainable configuration - independent of a specific hosting provider. +- If a provider is detected, the default environment type is set to `ENVIRONMENT_DEV`. +- Additional provider-specific conditions can elevate this to `ENVIRONMENT_STAGE` or `ENVIRONMENT_PROD`. +- If no provider is detected, the environment type defaults to `ENVIRONMENT_LOCAL`. -::: +It is important to note that this detection logic is only responsible for +identifying the environment type. It does not apply any configuration changes. +Those are handled separately in per-module override files, making the setup +modular and independent of hosting platform. #### Overriding environment type -It is also possible to force specific _environment type_ by setting -`DRUPAL_ENVIRONMENT` _environment variable_. +You can override the detected environment type by setting the +`DRUPAL_ENVIRONMENT` environment variable. -This is useful in cases where a certain behavior is required for a specific -environment, but the _environment type_ detection logic does not provide it. +This is useful when: +- Testing environment-specific behavior locally. +- Working around gaps in the detection logic. +- Forcing a known environment type for debugging. -It is also useful when debugging _environment type_-specific issues locally. -For example, you can set `DRUPAL_ENVIRONMENT=ci` in your `.env.local` file and -run the site locally with the CI environment settings. +For example, add `DRUPAL_ENVIRONMENT=ci` to your `.env.local` file to simulate +the CI environment locally. -### 4. Per-environment overrides +### Per-module overrides -Configurations in this section alter the site's behavior based on the detected -_environment type_ (see [Environment type detection](#3-environment-type-detection) -above). Out-of-the-box, **Vortex** provides overrides for CI and Local -environments. +This section automatically includes module-specific settings from files in the +`includes/modules` directory. Each file follows the naming pattern +`settings.[module].php` and contains configuration overrides for a specific +Drupal module. -You can add additional overrides for other _environment types_ as needed. +**Vortex** ships with pre-configured settings for several popular contributed +modules, each isolated in its own file for easy maintenance and removal. -### 5. Inclusion of per-module settings +#### Creating custom module settings -This section includes any additional module-specific settings from the -[`web/site/default/includes/modules`](https://github.com/drevops/vortex/tree/develop/web/sites/default/includes/modules) directory. +To add settings for a new module, create a file following the naming pattern: -**Vortex** ships with settings overrides for several popular contributed -modules. +``` +web/sites/default/includes/modules/settings.[module_name].php +``` -The per _environment type_ overrides for each module should be placed into the -module-specific settings file. - -import ModuleSettingsExample from '!!raw-loader!./../../../../web/sites/default/includes/modules/settings.environment_indicator.php'; +Each settings file should: +- Use environment type constants (`ENVIRONMENT_LOCAL`, `ENVIRONMENT_PROD`, etc.) for conditional logic +- Leverage environment variables for configuration values +- Provide sensible defaults when environment variables are not set +- Be self-contained and removable without affecting other modules
Example of the `Environment indicator` module settings file - {ModuleSettingsExample} +{EnvironmentIndicatorModuleSettingsExample}
- -### 6. Inclusion of local settings +### Local overrides At the end of the `settings.php`, there is an option to include additional local -settings. This allows developers to override some settings for their local -environment without affecting the main configuration. Developers can +settings. This allows you to override some settings for the local +environment without affecting the main configuration. You can copy `default.settings.local.php` and `default.services.local.yml` to `settings.local.php` and `services.local.yml`, respectively, to utilize this functionality. @@ -180,15 +274,20 @@ import LocalServicesExample from '!!raw-loader!./../../../../web/sites/default/d - ## Testing settings with unit tests -**Vortex** provides a [set of unit tests](https://github.com/drevops/vortex/blob/develop/tests/phpunit/Drupal) that -ensure that the settings apply correctly per environment type. These tests are -expected to be maintained within your project, ensuring that settings activated -by a specific _environment type_ and _environment variables_ are applied correctly. +**Vortex** includes a [set of unit tests](https://github.com/drevops/vortex/blob/develop/tests/phpunit/Drupal) +to verify that settings are applied correctly for each detected environment +type. + +These tests are intended to be maintained within your project, helping you +ensure that environment-driven configuration β€” including both environment types +and environment variables β€” behaves as expected. + +To run unit tests for settings: -After installing **Vortex**, run `vendor/bin/phpunit --group=drupal_settings` to -run the tests for the settings provided by **Vortex**. +```bash +vendor/bin/phpunit --group=drupal_settings +``` You may simply remove these tests if you do not want to maintain them. diff --git a/.vortex/docs/content/drupal/theme-scaffold.mdx b/.vortex/docs/content/drupal/theme-scaffold.mdx index 588984217..0afd66720 100644 --- a/.vortex/docs/content/drupal/theme-scaffold.mdx +++ b/.vortex/docs/content/drupal/theme-scaffold.mdx @@ -4,8 +4,135 @@ sidebar_position: 5 # Theme scaffold -:::note "Work in progress" +[Theme scaffold](https://github.com/drevops/vortex/tree/develop/web/themes/custom/your_site_theme) +is an example of a Drupal theme. - The documentation section is still a work in progress. +We recommend creating a custom `your_site_theme` theme for your project to place +custom styling and front-end functionality specific to your site. + +The theme uses the site machine name convention (`your_site_theme` in this case), +while modules use the abbreviated prefix (`ys_` for `your_site`). + +:::note + + We understand that front-end theming is often highly project-specific and + subject to team preferences. The provided `your_site_theme` scaffold is not + intended to dictate how your theme should be built β€” it simply demonstrates how + custom themes can integrate with the **Vortex** tooling and workflows. + + Feel free to adapt or replace it with your preferred theme. ::: + +## Build system + +The theme includes a complete Node.js-based build system using Grunt: + +- **SCSS compilation** with Sass globbing support +- **JavaScript concatenation and minification** +- **CSS auto-prefixing** for browser compatibility +- **Linting** for both CSS (Stylelint) and JavaScript (ESLint) +- **Watch mode** for development workflow + +### Build commands + +```bash +cd web/themes/custom/your_site_theme + +# Install dependencies +yarn install + +# Build production assets +yarn run build + +# Build development assets (unminified) +yarn run build-dev + +# Run linting +yarn run lint + +# Auto-fix linting issues +yarn run lint-fix + +# Watch for changes during development +yarn run watch +``` + +Ahoy commands are configured to call the appropriate Yarn scripts from the +theme directory: + +```bash +# Install front-end dependencies +ahoy fei + +# Build production assets +ahoy fe + +# Build development assets (unminified) +ahoy fed + +# Watch for changes during development +ahoy few + +# Lint front-end code +ahoy lint-fe +``` + +These commands run within the container to use the Node.js environment +and tools installed there, ensuring consistency across development environments. + +:::note + + When adding your own theme with a custom build system, it’s a good idea to + follow the same command structure and naming conventions. This keeps things + consistent across projects and makes it easier for other developers to work with + the build system without learning a new workflow. + +::: + + +## File structure + +``` +your_site_theme/ +β”œβ”€β”€ scss/ # Sass source files +β”‚ β”œβ”€β”€ _variables.scss # Theme variables +β”‚ β”œβ”€β”€ _mixins.scss # Sass mixins +β”‚ β”œβ”€β”€ _fonts.scss # Font definitions +β”‚ β”œβ”€β”€ _rem.scss # REM unit utilities +β”‚ β”œβ”€β”€ styles.scss # Main stylesheet +β”‚ └── components/ # Component-specific styles +β”‚ └── _header.scss # Header component styles +β”œβ”€β”€ js/ # JavaScript source files +β”‚ └── your_site_theme.js # Main theme JavaScript +β”œβ”€β”€ tests/ # Theme tests +β”‚ └── src/ +β”‚ β”œβ”€β”€ Unit/ # Unit tests +β”‚ β”œβ”€β”€ Kernel/ # Kernel tests +β”‚ └── Functional/ # Functional tests +β”œβ”€β”€ your_site_theme.info.yml # Theme definition +β”œβ”€β”€ your_site_theme.libraries.yml # Asset libraries +β”œβ”€β”€ your_site_theme.theme # Theme functions +β”œβ”€β”€ package.json # Node.js dependencies +β”œβ”€β”€ Gruntfile.js # Build configuration +└── logo.svg # Theme logo +``` + +## Libraries + +The theme defines asset libraries in `your_site_theme.libraries.yml` for +organized CSS and JavaScript loading with proper dependencies and browser +compatibility. + +## Tests scaffold + +The `tests` directory contains working examples of tests that can be used as a +starting point in your project. + +It also has a set of helper `Traits` that you may find useful when writing your +tests. Simply remove them if you do not find them useful. + +--- + +See [Development](/workflows/development) for more details on how to work with +the theme. diff --git a/.vortex/docs/content/getting-started/architecture.mdx b/.vortex/docs/content/getting-started/architecture.mdx index becbd3588..b01b66faa 100644 --- a/.vortex/docs/content/getting-started/architecture.mdx +++ b/.vortex/docs/content/getting-started/architecture.mdx @@ -2,15 +2,22 @@ hide: - toc --- + # Architecture **Vortex** offers a pre-configured project template that is reliable, tested and ready-to-use. Its main goal is to streamline onboarding, making it as quick and efficient as possible. +This page describes the architecture of **Vortex** and how it is structured to +provide a consistent developer experience across all projects that use it. +Specifics of every feature are described in the corresponding sections of this +documentation. + ## Zen of **Vortex** -Similar to [Zen of Python](https://www.python.org/dev/peps/pep-0020/), **Vortex** +Similar to [Zen of Python](https://www.python.org/dev/peps/pep-0020/), **Vortex +** is built on its own set of principles: * Simple is better than complex. @@ -19,6 +26,13 @@ is built on its own set of principles: * Readability counts. * Explicit logging helps. +## System components + + +System components +System components + + ## Repository structure The repository file structure follows the structure defined in @@ -45,7 +59,7 @@ with addition of several configuration files and directories. β”‚ β”œβ”€β”€ default # Default configuration. β”‚ β”œβ”€β”€ dev # Config split configuration for DEV environment. β”‚ β”œβ”€β”€ local # Config split configuration for local environment. -β”‚ └── test # Config split configuration for test environment. +β”‚ └── stage # Config split configuration for stage environment. β”œβ”€β”€ docs # Your project documentation. β”œβ”€β”€ drush # Drush configuration files. β”œβ”€β”€ hooks # Acquia hooks. Removed if not using Acquia hosting. @@ -53,6 +67,7 @@ with addition of several configuration files and directories. β”‚ β”œβ”€β”€ library # Library of hook implementations. β”‚ └── prod # Hook implementations that run in prod environment. β”œβ”€β”€ patches # Patches for packages. +β”œβ”€β”€ recipes # Custom recipes directory. β”œβ”€β”€ scripts # Composer, Vortex and custom project scripts. β”‚ β”œβ”€β”€ composer # Composer scripts. β”‚ β”œβ”€β”€ custom # Custom project scripts. @@ -76,23 +91,27 @@ with addition of several configuration files and directories. β”œβ”€β”€ .env # Environment variables to control project workflow using variables. β”œβ”€β”€ .env.local.example # Environment variables local overrides. β”œβ”€β”€ .gitignore # Intentionally untracked files to ignore in Git. -β”œβ”€β”€ .gitignore.artifact # Intentionally untracked files to ignore in artifact deployment. +β”œβ”€β”€ .gitignore.artifact # Intentionally untracked files to ignore in artifact deployment. β”œβ”€β”€ .lagoon.yml # Lagoon configuration file. Removed if not using Lagoon hosting. β”œβ”€β”€ .twig-cs-fixer.php # Twig CS Fixer configuration file. β”œβ”€β”€ behat.yml # Behat configuration file. +β”œβ”€β”€ CLAUDE.md # Claude Code development guide. β”œβ”€β”€ composer.json # Composer configuration file. β”œβ”€β”€ docker-compose.yml # Docker Compose configuration file. +β”œβ”€β”€ gherkinlint.json # Gherkin Lint configuration file. β”œβ”€β”€ phpcs.xml # PHP CodeSniffer configuration file. β”œβ”€β”€ phpmd.xml # PHP Mess Detector configuration file. β”œβ”€β”€ phpstan.neon # PHPStan configuration file. β”œβ”€β”€ phpunit.xml # PHPUnit configuration file. β”œβ”€β”€ README.md # Project main readme file. +β”œβ”€β”€ rector.php # Rector configuration file. └── renovate.json # Renovate configuration file. ``` ## Scripts -**Vortex** provides a set of [POSIX](https://en.wikipedia.org/wiki/POSIX)-compliant +**Vortex** provides a set of [POSIX](https://en.wikipedia.org/wiki/POSIX) +-compliant shell scripts designed to orchestrate workflows. During installation, the scripts are added to your project repository into @@ -104,17 +123,18 @@ compile sources, or waiting for someone upstream to update the code. :::note - We are [looking into providing](https://github.com/drevops/vortex/issues/1198) `pre-` and `post-` hooks for scripts so - that you can extend the functionality without modifying the original source - code. + We are [looking into providing](https://github.com/drevops/vortex/issues/1198) + `pre-` and `post-` hooks for scripts so that you can extend the + functionality without modifying the original source code. - This will also alow us to extract the scripts into a separate repository + This will also allow us to extract the scripts into a separate repository that can be included in your project as a Composer package. + ::: ### Centralised workflows -> A workflow is a sequence of steps or tasks to accomplish a specific goal. +> _A workflow is a sequence of steps or tasks to accomplish a specific goal._ **Vortex** comes with as set of pre-defined workflow scripts used to standardise the development process. @@ -128,7 +148,8 @@ provision a website in a consistent way, allowing to alter the flow using scripts. The scripts aim to centralize workflows instead of adjusting them for every -environment (local, CI, dev, prod, etc.), reducing multiple points of failure. +environment (local, CI, dev, prod, etc.), reducing **multiple points of failure +**. This means that a developer updating a workflow for local environment, for example, will not accidentally forget to update it for the CI environment, and so on. @@ -147,21 +168,20 @@ In the diagram below, the `download-db.sh` and `provision.sh` scripts are subgraph Scripts direction TB D["download-db.sh"] -.-> E["provision.sh"] + E["provision.sh"] -.-> F["deploy.sh"] + F["deploy.sh"] -.-> G["notify.sh"] end A --> Scripts - A --> Scripts - B --> Scripts B --> Scripts C --> Scripts - C --> Scripts ``` See [Workflows](../../workflows) section for more details. ### Router scripts -The script from the example above is a _router_ script that invokes other, +The scripts from the example above are _router_ script that invokes other, more specific scripts (by sourcing them) based on the project configuration. This design **keeps the entry point consistent** while allowing implementation updates as needed without modifying the entry point in multiple places. @@ -181,7 +201,8 @@ In this example, changing the database download source from `lagoon` to `s3` would not require changes to any local, CI, or hosting scripts. In addition, a developer would not need to learn how to use `s3` to -download a database or even know how that download process was setup. +download a database or even know how that download process was configured +— they would continue using the same command wrapper command as before. If a new database download method is introduced, the router script `download-db.sh` can be easily extended to accommodate it, @@ -209,7 +230,38 @@ The workflow within scripts is controlled via environment variables. To alter the workflow for a specific environment, the variables would need to be set within that environment via the `.env` configuration file or other means -supported by the environment (e.g. CI and Hosting providers support injecting +supported by the environment (e.g. CI and Hosting providers support adding variables via UI). See [Variables](../workflows/variables.mdx) section for more details. + +## Template placeholders and tokens + +**Vortex** uses a system of placeholders and conditional tokens to generate +customized projects while keeping the template structure transparent. This +approach allows you to see exactly what your final project will look like - the +repository structure shown above is precisely what you get after installation, +with no files copied from hidden locations or magic transformations. + +### Naming placeholders + +Throughout the template, placeholder names are used consistently and replaced +during installation. Examples include `your_site`, `YOURSITE`, and `ys_`, among +many others. These placeholders ensure consistent naming patterns across all +generated files and maintain best practices for Drupal naming conventions. + +### Conditional tokens + +Conditional tokens allow the template to include or exclude entire sections of +code based on the features selected during installation. This keeps the +generated project lean and relevant to your specific needs. + +The tokens use different syntax depending on the file type: + +- **Shell scripts and YAML files:** `#;< TOKEN_NAME` ... `#;> TOKEN_NAME` +- **Markdown documentation:** `[//]: # (#;< TOKEN_NAME)` ... + `[//]: # (#;> TOKEN_NAME)` + +During installation, content wrapped in these tokens is either kept or removed +based on your feature selections, ensuring your project contains only the +components you actually need. diff --git a/.vortex/docs/content/getting-started/features.mdx b/.vortex/docs/content/getting-started/features.mdx index 95e2fe9de..d5cb32b47 100644 --- a/.vortex/docs/content/getting-started/features.mdx +++ b/.vortex/docs/content/getting-started/features.mdx @@ -34,8 +34,8 @@ The following list includes βœ… completed and 🚧 upcoming features. * 🚧 [Platform.sh](https://platform.sh/) * πŸ’» Local development * βœ… [Docker Compose](https://docs.docker.com/compose/) + [Ahoy](https://github.com/ahoy-cli/ahoy) - * 🚧 [Lando](https://lando.dev/) * 🚧 [DDEV](https://ddev.readthedocs.io/) + * 🚧 [Lando](https://lando.dev/) * πŸ—οΈ CI/CD * βœ… [Circle CI](https://circleci.com/) * βœ… [GitHub Actions](https://github.com/features/actions) @@ -44,6 +44,7 @@ The following list includes βœ… completed and 🚧 upcoming features. * πŸ› οΈ Tooling * βœ… [Behat](https://docs.behat.org/en/latest/) + [Drupal extension](https://github.com/jhedstrom/drupalextension) + [Behat Screenshot](https://github.com/drevops/behat-screenshot) + [Behat steps](https://github.com/drevops/behat-steps) * βœ… [ESLint](https://eslint.org/) + * βœ… [Gherkin Lint](https://github.com/dantleech/gherkin-lint-php) * βœ… [PHP Parallel Lint](https://github.com/php-parallel-lint/PHP-Parallel-Lint) * βœ… [PHPCS](https://github.com/squizlabs/PHP_CodeSniffer) * βœ… [PHPMD](https://phpmd.org/) @@ -54,13 +55,13 @@ The following list includes βœ… completed and 🚧 upcoming features. * βœ… [Twig CS Fixer](https://github.com/VincentLanglet/Twig-CS-Fixer) * 🚧 [Pa11y](https://pa11y.org/) * βš™οΈ Workflow - * βœ… Database from CURL, FTP, container image, hosting provider + * βœ… Database sourcing from CURL, FTP, container image, hosting provider + * βœ… Deployment notification to email, GitHub, Jira, New Relic + * βœ… Automated dependencies updates ([Renovate](https://www.mend.io/renovate/)) * βœ… [Pull request template](https://github.com/drevops/vortex/blob/develop/.github/PULL_REQUEST_TEMPLATE.md) * βœ… [Release drafter](https://github.com/release-drafter/release-drafter) * βœ… [PR auto-assign](https://github.com/toshimaru/auto-author-assign) * βœ… [PR auto-label](https://github.com/eps1lon/actions-label-merge-conflict) - * βœ… Deployment notification to email, GitHub, Jira, New Relic - * βœ… Automated dependencies updates ([Renovate](https://www.mend.io/renovate/)) * πŸ“– Documentation * βœ… Your project [README.md](https://github.com/drevops/vortex/blob/develop/README.dist.md) * βœ… Your [project documentation](https://github.com/drevops/vortex/blob/develop/docs) diff --git a/.vortex/docs/content/getting-started/installation.mdx b/.vortex/docs/content/getting-started/installation.mdx index 388da2ec5..c2b174fc9 100644 --- a/.vortex/docs/content/getting-started/installation.mdx +++ b/.vortex/docs/content/getting-started/installation.mdx @@ -4,12 +4,13 @@ sidebar_position: 1 # Installation -The installation process consists of installing the **Vortex** template -followed by setting up the integrations with the required services. +The installation process consists of installing the **Vortex** template into +your project's codebase, and then setting up the integrations with the required +services. We automated the first part by providing an in interactive installer. The second part is a manual process that requires you to follow the instructions provided -for each service. +for each service (see relevant sections in the documentation). ## Installing Vortex into a new project @@ -75,7 +76,7 @@ the changes between the **Vortex** files and your files. ## Setting up integrations Depending on the services you are using, you will need to set up the -integrations with CI, Docker Hub, your hosting and other services. +integrations with CI, your hosting and other services. Please refer to the following guides for more information: diff --git a/.vortex/docs/content/tools/docker.mdx b/.vortex/docs/content/tools/docker.mdx index 3a327a07f..0c6e3e850 100644 --- a/.vortex/docs/content/tools/docker.mdx +++ b/.vortex/docs/content/tools/docker.mdx @@ -6,7 +6,7 @@ https://github.com/docker/compose > Docker is a platform for developing, shipping, and running applications in > containers. -Vortex provides a configuration for Docker and Docker Compose to run the +**Vortex** provides a configuration for Docker and Docker Compose to run the project in all environments using containers. Special thanks to Lagoon for providing @@ -74,7 +74,7 @@ configuration and services. ## Using Docker -Vortex uses Docker to run the project in a containerized environment locally +**Vortex** uses Docker to run the project in a containerized environment locally and in CI. Some of the commands are wrapped in the Ahoy script as a shorthand. But all @@ -90,7 +90,7 @@ Docker Compose reads the configuration from the `docker-compose.yml` and YAML, which [support anchors and references](http://blog.daemonl.com/2016/02/yaml.html) that help to reduce duplication. -The file provided by Vortex contains the following sections: +The file provided by **Vortex** contains the following sections: - [Volumes definitions](#volumes-definitions) - [Default user](#default-user) @@ -147,7 +147,7 @@ Changes this value if your user ID is different. ### Environment variables By default, the Docker Composer reads environment variables from the `.env` -file. Vortex provides an additional capability to read files from `.env.local` +file. **Vortex** provides an additional capability to read files from `.env.local` file as well. This allows to override the environment variables locally without modifying the `.env` file. @@ -166,7 +166,7 @@ Any other variables should be defined in the `.env` file. Consider the example: ``` - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Local development URL. VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io # Local development route used in Lagoon images and Pygmy to route requests. @@ -175,8 +175,8 @@ Consider the example: where -- `TZ: ${TZ:-Australia/Melbourne}` - defines a variable `TZ` with a - default value of `Australia/Melbourne`, but only if `TZ` variable is +- `TZ: ${TZ:-UTC}` - defines a variable `TZ` with a + default value of `UTC`, but only if `TZ` variable is not defined. - `VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io` - defines a variable `VORTEX_LOCALDEV_URL` with a default value of diff --git a/.vortex/docs/content/tools/drush.mdx b/.vortex/docs/content/tools/drush.mdx index 6daac0d5f..b111b2652 100644 --- a/.vortex/docs/content/tools/drush.mdx +++ b/.vortex/docs/content/tools/drush.mdx @@ -7,12 +7,12 @@ https://www.drush.org/ > update.php, executes SQL queries, runs content migrations, and misc utilities > like cron or cache rebuild. Drush can be extended by 3rd party commandfiles. -Drush is used throughout Vortex to interact with Drupal from the workflow +Drush is used throughout **Vortex** to interact with Drupal from the workflow scripts and Behat tests. It also allows a developer to interact with the site via CLI during development. -While all the standard Drush commands supported, Vortex also provides some +While all the standard Drush commands supported, **Vortex** also provides some shorthand commands to abstract some of the common tasks: - downloading the database dump from the remote environment diff --git a/.vortex/docs/content/tools/rector.mdx b/.vortex/docs/content/tools/rector.mdx index a37fa1b74..d79caabfa 100644 --- a/.vortex/docs/content/tools/rector.mdx +++ b/.vortex/docs/content/tools/rector.mdx @@ -50,7 +50,7 @@ Targets include custom modules and themes, settings and tests. Rector provides [config sets](https://getrector.com/documentation/set-lists) functionality that allows to enable/disable rules in bulk. -Vortex provides the config sets for Drupal 8 and Drupal 9 deprecated code and +**Vortex** provides the config sets for Drupal 8 and Drupal 9 deprecated code and code style fixes. The config sets are meant to be adjusted per-project as needed. diff --git a/.vortex/docs/content/tools/renovate.mdx b/.vortex/docs/content/tools/renovate.mdx index 89c19e7c9..640483575 100644 --- a/.vortex/docs/content/tools/renovate.mdx +++ b/.vortex/docs/content/tools/renovate.mdx @@ -4,7 +4,7 @@ sidebar_label: Renovate # Renovate - Automated updates -Vortex uses [Renovate](https://renovatebot.com) for automated dependency updates. +**Vortex** uses [Renovate](https://renovatebot.com) for automated dependency updates. The configuration is stored in [`renovate.json`](https://github.com/drevops/vortex/blob/develop/renovate.json). It is based on [Renovate configuration for automated Drupal dependency updates](https://github.com/drevops/renovate-drupal) diff --git a/.vortex/docs/content/workflows/notifications.mdx b/.vortex/docs/content/workflows/notifications.mdx new file mode 100644 index 000000000..59a5715c0 --- /dev/null +++ b/.vortex/docs/content/workflows/notifications.mdx @@ -0,0 +1,8 @@ +--- +sidebar_label: Notifications +sidebar_position: 4 +--- + +# Notifications + +The documentation section is still a work in progress. diff --git a/.vortex/docs/content/workflows/variables.mdx b/.vortex/docs/content/workflows/variables.mdx index 1fb832812..d623c3ba4 100644 --- a/.vortex/docs/content/workflows/variables.mdx +++ b/.vortex/docs/content/workflows/variables.mdx @@ -184,7 +184,7 @@ Defined in: `docker-compose.yml` ### `DRUPAL_PROFILE` -Drupal profile name (used only when installing from profile). +Drupal profile name. Default value: `standard` @@ -324,6 +324,14 @@ Default value: `'Renovate Self Hosted '` Defined in: `CI config` +### `RENOVATE_REPOSITORIES` + +Renovate repositories to manage.
Set as "organization/repository". + +Default value: `UNDEFINED` + +Defined in: `CI config` + ### `RENOVATE_TOKEN` Self-hosted Renovate bot token.
Create a GitHub token with a permission to write to a repository. @@ -342,9 +350,9 @@ Defined in: `scripts/vortex/task-purge-cache-acquia.sh` ### `TZ` -The timezone used in the containers. +The timezone used within the containers. -Default value: `Australia/Melbourne` +Default value: `UTC` Defined in: `.env` @@ -522,6 +530,8 @@ Defined in: `.env.local.example`, `scripts/vortex/login-container-registry.sh` Database dump directory. +The directory is used to store the database dump files for import and export. + Default value: `./.data` Defined in: `.env`, `scripts/vortex/download-db-acquia.sh`, `scripts/vortex/download-db-container-registry.sh`, `scripts/vortex/download-db-ftp.sh`, `scripts/vortex/download-db-lagoon.sh`, `scripts/vortex/download-db-url.sh`, `scripts/vortex/download-db.sh`, `scripts/vortex/provision.sh` @@ -684,7 +694,7 @@ Defined in: `scripts/vortex/download-db-lagoon.sh` ### `VORTEX_DB_DOWNLOAD_URL` -Database dump file sourced from CURL. +Database dump file sourced from a URL. HTTP Basic Authentication credentials should be embedded into the value. @@ -744,6 +754,8 @@ Defined in: `scripts/vortex/export-db-image.sh` Database dump file name. +The file is used to import the database into an empty database container. + Default value: `db.sql` Defined in: `.env`, `scripts/vortex/download-db-acquia.sh`, `scripts/vortex/download-db-ftp.sh`, `scripts/vortex/download-db-lagoon.sh`, `scripts/vortex/download-db-url.sh`, `scripts/vortex/provision.sh` @@ -1101,14 +1113,6 @@ Default value: `${VORTEX_CONTAINER_REGISTRY_USER}` Defined in: `scripts/vortex/download-db-container-registry.sh` -### `VORTEX_EXPORT_CODE_DIR` - -Directory to store exported code. - -Default value: `UNDEFINED` - -Defined in: `CI config` - ### `VORTEX_EXPORT_DB_CONTAINER_REGISTRY_DEPLOY_PROCEED` Proceed with container image deployment after it was exported. @@ -1169,9 +1173,13 @@ Defined in: `.env` ### `VORTEX_LOCALDEV_URL` -Local development URL.
Override only if you need to use a different URL than the default. +Local development URL. -Default value: `.docker.amazee.io` +Based on the [`$COMPOSE_PROJECT_NAME`](#compose_project_name) environment variable, which is set by
Docker Compose to the name of the project directory. + +Override only if you need to use a different URL than the default. + +Default value: `example-site.docker.amazee.io` Defined in: `.env.local.example`, `scripts/vortex/info.sh` @@ -1187,7 +1195,7 @@ Defined in: `scripts/vortex/notify-github.sh`, `scripts/vortex/notify-jira.sh` The channels of the notifications. -Can be a combination of comma-separated values: email,newrelic,github,jira +A combination of comma-separated values: email,newrelic,github,jira Default value: `email` @@ -1203,7 +1211,9 @@ Defined in: `scripts/vortex/notify-email.sh` ### `VORTEX_NOTIFY_EMAIL_FROM` -Email to send notifications from. +An email address to send notifications from. + +Applies to email notifications. Default value: `webmaster@your-site-domain.example` @@ -1229,6 +1239,8 @@ Defined in: `scripts/vortex/notify-email.sh` Email address(es) to send notifications to. +Applies to email notifications. + Multiple names can be specified as a comma-separated list of email addresses
with optional names in the format "email|name".
Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" Default value: `webmaster@your-site-domain.example` @@ -1551,7 +1563,7 @@ Defined in: `scripts/vortex/provision-sanitize-db.sh` Sanitization email pattern. -Applied if database sanitization is enabled.
@see https://vortex.drevops.com/workflows/build#sanitization +Applied if database sanitization is enabled.
@see https://vortex.drevops.com/drupal/provision#database-sanitization Default value: `user_%uid@your-site-domain.example` @@ -1559,7 +1571,7 @@ Defined in: `.env`, `scripts/vortex/provision-sanitize-db.sh` ### `VORTEX_PROVISION_SANITIZE_DB_PASSWORD` -Password replacement used for sanitised database. +Password replacement used for sanitized database. Default value: `` @@ -1577,7 +1589,7 @@ Defined in: `.env`, `scripts/vortex/provision-sanitize-db.sh` Skip database sanitization. -Database sanitization is enabled by default in all non-production
environments and is always skipped in the production environment. +Database sanitization is enabled by default in all non-production
environments and is always skipped in the production environment.
@see https://vortex.drevops.com/drupal/provision#database-sanitization Default value: `UNDEFINED` diff --git a/.vortex/docs/cspell.json b/.vortex/docs/cspell.json index 959a46309..eb4e1f46c 100644 --- a/.vortex/docs/cspell.json +++ b/.vortex/docs/cspell.json @@ -37,6 +37,7 @@ "localdev", "mglaman", "minimised", + "multisite", "novnc", "oomphinc", "optimise", @@ -51,7 +52,6 @@ "pyrech", "renovatebot", "ruleset", - "sanitised", "shellvar", "standardise", "utilising", diff --git a/.vortex/docs/static/img/diagram-dark.png b/.vortex/docs/static/img/diagram-dark.png index 64424a07a..2ba176165 100644 Binary files a/.vortex/docs/static/img/diagram-dark.png and b/.vortex/docs/static/img/diagram-dark.png differ diff --git a/.vortex/docs/static/img/diagram-light.png b/.vortex/docs/static/img/diagram-light.png index 0d40be6c1..0bb9c37a2 100644 Binary files a/.vortex/docs/static/img/diagram-light.png and b/.vortex/docs/static/img/diagram-light.png differ diff --git a/.vortex/docs/static/img/diagram-provision-dark.svg b/.vortex/docs/static/img/diagram-provision-dark.svg new file mode 100644 index 000000000..209ef3cda --- /dev/null +++ b/.vortex/docs/static/img/diagram-provision-dark.svg @@ -0,0 +1,4 @@ + + + +
Β  Β Standard operations
Β  Β Standard operations
πŸš€ Start
πŸš€ Start
πŸ’‘ Skip provision?Β 
πŸ’‘ Skip provision?Β 
πŸ’‘ Can bootstrap?
πŸ’‘ Can bootstrap?
🏁 End
🏁 End
πŸ’‘ Override DB?Β Β 
πŸ’‘ Override DB?Β Β 
Site is bootstrappable
πŸ—‘οΈ Drop DB
πŸ—‘οΈ Drop DB
πŸ’‘ Use DB dump
or profile?
πŸ’‘ Use DB dump...
πŸ›’οΈ Import from DB dump
πŸ›’οΈ Import from DB dump
πŸ“¦ Install from profile
πŸ“¦ Install from profile
πŸ’‘ Skip other operations?Β 
πŸ’‘ Skip other operations?Β 
🚧 Enable maintenance mode 
🚧 Enable maintenance mode 
🏁 End
🏁 End
⬇️ Import configuration
⬇️ Import configuration
πŸ”„ Run DB updates
πŸ”„ Run DB updates
🧹 Rebuild caches
🧹 Rebuild caches
πŸ”„ Run deployment operations
πŸ”„ Run deployment operations
😷 Run DB sanitization 
😷 Run DB sanitization 
βš™οΈ Run custom scripts
βš™οΈ Run custom scripts
🚧 Disable maintenance mode
🚧 Disable maintenance mode
🏁 End
🏁 End
NoYesYesNoPreserve existing DBYesDB dumpProfileNoNoYes
1
1
2
2
3
3
4
4
5
5
6
6
Text is not SVG - cannot display
\ No newline at end of file diff --git a/.vortex/docs/static/img/diagram-provision-light.svg b/.vortex/docs/static/img/diagram-provision-light.svg new file mode 100644 index 000000000..209ef3cda --- /dev/null +++ b/.vortex/docs/static/img/diagram-provision-light.svg @@ -0,0 +1,4 @@ + + + +
Β  Β Standard operations
Β  Β Standard operations
πŸš€ Start
πŸš€ Start
πŸ’‘ Skip provision?Β 
πŸ’‘ Skip provision?Β 
πŸ’‘ Can bootstrap?
πŸ’‘ Can bootstrap?
🏁 End
🏁 End
πŸ’‘ Override DB?Β Β 
πŸ’‘ Override DB?Β Β 
Site is bootstrappable
πŸ—‘οΈ Drop DB
πŸ—‘οΈ Drop DB
πŸ’‘ Use DB dump
or profile?
πŸ’‘ Use DB dump...
πŸ›’οΈ Import from DB dump
πŸ›’οΈ Import from DB dump
πŸ“¦ Install from profile
πŸ“¦ Install from profile
πŸ’‘ Skip other operations?Β 
πŸ’‘ Skip other operations?Β 
🚧 Enable maintenance mode 
🚧 Enable maintenance mode 
🏁 End
🏁 End
⬇️ Import configuration
⬇️ Import configuration
πŸ”„ Run DB updates
πŸ”„ Run DB updates
🧹 Rebuild caches
🧹 Rebuild caches
πŸ”„ Run deployment operations
πŸ”„ Run deployment operations
😷 Run DB sanitization 
😷 Run DB sanitization 
βš™οΈ Run custom scripts
βš™οΈ Run custom scripts
🚧 Disable maintenance mode
🚧 Disable maintenance mode
🏁 End
🏁 End
NoYesYesNoPreserve existing DBYesDB dumpProfileNoNoYes
1
1
2
2
3
3
4
4
5
5
6
6
Text is not SVG - cannot display
\ No newline at end of file diff --git a/.vortex/docs/static/img/installer.png b/.vortex/docs/static/img/installer.png index 3b7c065bd..f81280416 100644 Binary files a/.vortex/docs/static/img/installer.png and b/.vortex/docs/static/img/installer.png differ diff --git a/.vortex/installer/src/Prompts/Handlers/CiProvider.php b/.vortex/installer/src/Prompts/Handlers/CiProvider.php index a2954870d..a3618367e 100644 --- a/.vortex/installer/src/Prompts/Handlers/CiProvider.php +++ b/.vortex/installer/src/Prompts/Handlers/CiProvider.php @@ -58,13 +58,17 @@ public function process(): void { if ($remove_gha) { @unlink($this->tmpDir . '/.github/workflows/build-test-deploy.yml'); + @unlink($this->tmpDir . '/' . $this->webroot . '/sites/default/includes/providers/settings.gha.php'); File::removeTokenAsync('CI_PROVIDER_GHA'); + File::removeTokenAsync('SETTINGS_PROVIDER_GHA'); } if ($remove_circleci) { File::rmdir($this->tmpDir . '/.circleci'); + @unlink($this->tmpDir . '/' . $this->webroot . '/sites/default/includes/providers/settings.circleci.php'); @unlink($this->tmpDir . '/tests/phpunit/CircleCiConfigTest.php'); File::removeTokenAsync('CI_PROVIDER_CIRCLECI'); + File::removeTokenAsync('SETTINGS_PROVIDER_CIRCLECI'); } if ($remove_gha && $remove_circleci) { diff --git a/.vortex/installer/src/Prompts/Handlers/HostingProvider.php b/.vortex/installer/src/Prompts/Handlers/HostingProvider.php index 7e5eafe0f..8f8132603 100644 --- a/.vortex/installer/src/Prompts/Handlers/HostingProvider.php +++ b/.vortex/installer/src/Prompts/Handlers/HostingProvider.php @@ -40,10 +40,12 @@ public function process(): void { if ($v === static::ACQUIA) { File::removeTokenAsync('!HOSTING_ACQUIA'); + File::removeTokenAsync('!SETTINGS_PROVIDER_ACQUIA'); $this->removeLagoon(); } elseif ($v === static::LAGOON) { File::removeTokenAsync('!HOSTING_LAGOON'); + File::removeTokenAsync('!SETTINGS_PROVIDER_LAGOON'); $this->removeAcquia(); } else { @@ -58,6 +60,7 @@ protected function removeAcquia(): void { @unlink(sprintf('%s/%s/sites/default/includes/providers/settings.acquia.php', $this->tmpDir, $this->webroot)); File::removeTokenAsync('HOSTING_ACQUIA'); + File::removeTokenAsync('SETTINGS_PROVIDER_ACQUIA'); } protected function removeLagoon(): void { @@ -67,6 +70,7 @@ protected function removeLagoon(): void { @unlink(sprintf('%s/%s/sites/default/includes/providers/settings.lagoon.php', $this->tmpDir, $this->webroot)); File::removeTokenAsync('HOSTING_LAGOON'); + File::removeTokenAsync('SETTINGS_PROVIDER_LAGOON'); } } diff --git a/.vortex/installer/src/Prompts/Handlers/ModulePrefix.php b/.vortex/installer/src/Prompts/Handlers/ModulePrefix.php index 08b2e2753..459329e36 100644 --- a/.vortex/installer/src/Prompts/Handlers/ModulePrefix.php +++ b/.vortex/installer/src/Prompts/Handlers/ModulePrefix.php @@ -47,6 +47,7 @@ public function process(): void { File::renameInDir($t . sprintf('/%s/modules/custom', $w), 'ys_base', $v . '_base'); File::renameInDir($t . sprintf('/%s/modules/custom', $w), 'ys_search', $v . '_search'); File::renameInDir($t . sprintf('/%s/modules/custom', $w), 'YsBase', Converter::pascal($v) . 'Base'); + File::renameInDir($t . sprintf('/%s/sites/default/includes', $w), 'ys_base', $v . '_base'); } } diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/.ahoy.yml b/.vortex/installer/tests/Fixtures/install/_baseline/.ahoy.yml index 2e0f21154..06c45090a 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/.ahoy.yml +++ b/.vortex/installer/tests/Fixtures/install/_baseline/.ahoy.yml @@ -187,7 +187,7 @@ commands: usage: Lint front-end code. cmd: | ahoy cli vendor/bin/twig-cs-fixer lint - ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" + ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" lint-tests: usage: Lint tests code. @@ -208,7 +208,7 @@ commands: usage: Fix lint issues of front-end code. cmd: | ahoy cli vendor/bin/twig-cs-fixer lint --fix - ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" + ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" test: usage: Run all tests. @@ -270,7 +270,7 @@ commands: fi hide: true -# Override entrypoint to alter default behaviour of Ahoy. +# Override entrypoint to alter default behavior of Ahoy. entrypoint: - bash - -c diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/.env b/.vortex/installer/tests/Fixtures/install/_baseline/.env index 309c8ce10..a5f289721 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/.env +++ b/.vortex/installer/tests/Fixtures/install/_baseline/.env @@ -1,18 +1,19 @@ ## # Project environment variables. # -# This is a single location where defined variables control how the stack -# operates and should be the primary place for modifications. Avoid overriding +# This is a single location where variables control how the project stack +# operates. It should be the primary place for modifications. Avoid overriding # values in scripts or configuration files to simplify future updates and # centralize changes. # -# Values must be scalar and cannot reference another variable. -# Do not enclose values in double quotes unless they include spaces. +# A value must be scalar and cannot reference another variable. +# Do not enclose a value in double quotes unless it includes spaces. # # To apply any changes made to this file, run `docker-compose up cli -d` or # `ahoy up cli`. # -# To customize variables locally, copy `.env.local.example` to `.env.local`. +# To customize variables locally, copy `.env.local.example` to `.env.local`, +# and add your custom values there. # # @see https://vortex.drevops.com/workflows/variables @@ -30,14 +31,14 @@ VORTEX_PROJECT=star_wars # Name of the web root directory containing a Drupal codebase. WEBROOT=web -# The timezone used in the containers. -TZ="Australia/Melbourne" +# The timezone used within the containers. +TZ=UTC ################################################################################ # DRUPAL # ################################################################################ -# Drupal profile name (used only when installing from profile). +# Drupal profile name. DRUPAL_PROFILE=standard # Drupal theme name. @@ -76,7 +77,7 @@ DRUPAL_CLAMAV_MODE=daemon # or fresh install from profile), running updates, appying configuration # changes, clearing caches and performing other tasks that prepare the site for # use. -# @see https://vortex.drevops.com/workflows/provision +# @see https://vortex.drevops.com/drupal/provision # Set to 'profile' to install a site from profile instead of the database dump. VORTEX_PROVISION_TYPE=database @@ -92,40 +93,45 @@ VORTEX_PROVISION_OVERRIDE_DB=0 # # Database sanitization is enabled by default in all non-production # environments and is always skipped in the production environment. +# @see https://vortex.drevops.com/drupal/provision#database-sanitization VORTEX_PROVISION_SANITIZE_DB_SKIP=0 # Sanitization email pattern. # # Applied if database sanitization is enabled. -# @see https://vortex.drevops.com/workflows/build#sanitization +# @see https://vortex.drevops.com/drupal/provision#database-sanitization VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@star-wars.com" # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ -# DATABASE # +# DATABASE SOURCE # ################################################################################ # Database service runs a single database within a container. -# See settings.php for database credentials defaults or run -# `ahoy drush sql:connect`. +# See settings.php for database credentials or run # `ahoy drush sql:connect`. # Database can be imported from a *file dump* into an empty database started -# from the database default image or can *exist* in a pre-built container image. +# from the database default container image or can *exist* in a pre-built +# container image. # Defaults to importing from a file. # @see https://vortex.drevops.com/workflows/database # Database dump directory. +# +# The directory is used to store the database dump files for import and export. VORTEX_DB_DIR=./.data # Database dump file name. +# +# The file is used to import the database into an empty database container. VORTEX_DB_FILE=db.sql # Database download source. VORTEX_DB_DOWNLOAD_SOURCE=url -# Database dump file sourced from CURL. +# Database dump file sourced from a URL. # # HTTP Basic Authentication credentials should be embedded into the value. VORTEX_DB_DOWNLOAD_URL= @@ -154,18 +160,22 @@ VORTEX_DEPLOY_TYPES=webhook # The channels of the notifications. # -# Can be a combination of comma-separated values: email,newrelic,github,jira +# A combination of comma-separated values: email,newrelic,github,jira VORTEX_NOTIFY_CHANNELS=email -# Email to send notifications from. -VORTEX_NOTIFY_EMAIL_FROM="webmaster@star-wars.com" +# An email address to send notifications from. +# +# Applies to email notifications. +VORTEX_NOTIFY_EMAIL_FROM=webmaster@star-wars.com # Email address(es) to send notifications to. # +# Applies to email notifications. +# # Multiple names can be specified as a comma-separated list of email addresses # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" -VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com" +VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@star-wars.com ################################################################################ # DEMO # diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/install/_baseline/.github/workflows/build-test-deploy.yml index 3faa11faf..aa8cf1065 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/install/_baseline/.github/workflows/build-test-deploy.yml @@ -53,7 +53,7 @@ jobs: image: drevops/ci-runner:__VERSION__ env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" VORTEX_SSH_REMOVE_ALL_KEYS: "1" @@ -159,7 +159,7 @@ jobs: image: drevops/ci-runner:__VERSION__ env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color # Disable strict host key checking for SSH connections. VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" @@ -348,7 +348,7 @@ jobs: container: image: drevops/ci-runner:__VERSION__ env: - TZ: Australia/Melbourne + TZ: UTC TERM: xterm-256color VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" VORTEX_DEBUG: ${{ vars.VORTEX_DEBUG }} diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/docker-compose.yml b/.vortex/installer/tests/Fixtures/install/_baseline/docker-compose.yml index 5543d978d..85ba3aa5d 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/docker-compose.yml +++ b/.vortex/installer/tests/Fixtures/install/_baseline/docker-compose.yml @@ -33,7 +33,7 @@ x-user: &default-user # Environment variables set in all containers during build and runtime. x-environment: &default-environment - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Pass-through 'CI' variable used to identify the CI environment. CI: ${CI:-} # Pass-through 'XDEBUG_ENABLE' to enable XDebug with "ahoy debug" or "XDEBUG_ENABLE=true docker compose up -d". diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/renovate.json b/.vortex/installer/tests/Fixtures/install/_baseline/renovate.json index 3cc6f1c52..b22d5ce60 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/renovate.json +++ b/.vortex/installer/tests/Fixtures/install/_baseline/renovate.json @@ -11,7 +11,7 @@ ":prHourlyLimit2" ], "rangeStrategy": "update-lockfile", - "timezone": "Australia/Melbourne", + "timezone": "UTC", "configMigration": true, "enabledManagers": [ "composer", diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/DatabaseSettingsTest.php b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/DatabaseSettingsTest.php index 7cef68873..afd22bff6 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/DatabaseSettingsTest.php +++ b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/DatabaseSettingsTest.php @@ -40,7 +40,7 @@ public static function dataProviderDatabases(): array { 'username' => 'drupal', 'password' => 'drupal', 'host' => 'localhost', - 'port' => '', + 'port' => '3306', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_general_ci', 'driver' => 'mysql', diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 29f1e5275..3fb2818d8 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -22,11 +22,11 @@ class EnvironmentSettingsTest extends SettingsTestCase { /** - * Test the resulting environment based on the provider's configuration. + * Test the detection of the resulting environment type. * - * @dataProvider dataProviderEnvironmentTypeResolution + * @dataProvider dataProviderEnvironmentTypeDetection */ - public function testEnvironmentTypeResolution(array $vars, string $expected_env): void { + public function testEnvironmentTypeDetection(array $vars, string $expected_env): void { $this->setEnvVars($vars); $this->requireSettingsFile(); @@ -35,9 +35,9 @@ public function testEnvironmentTypeResolution(array $vars, string $expected_env) } /** - * Data provider for testing of the resulting environment. + * Data provider for testing environment type detection. */ - public static function dataProviderEnvironmentTypeResolution(): array { + public static function dataProviderEnvironmentTypeDetection(): array { return [ // By default, the default environment type is local. [[], static::ENVIRONMENT_LOCAL], @@ -50,13 +50,21 @@ public static function dataProviderEnvironmentTypeResolution(): array { static::ENVIRONMENT_CI, ], + // Container. + [ + [ + 'VORTEX_LOCALDEV_URL' => 'https://example-site.docker.amazee.io', + ], + static::ENVIRONMENT_LOCAL, + ], + ]; } /** - * Test generic settings without any environment overrides. + * Test settings without any environment overrides. */ - public function testEnvironmentGeneric(): void { + public function testEnvironmentNoOverrides(): void { $this->setEnvVars([ 'DRUPAL_ENVIRONMENT' => static::ENVIRONMENT_SUT, ]); @@ -70,8 +78,6 @@ public function testEnvironmentGeneric(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -79,22 +85,101 @@ public function testEnvironmentGeneric(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', - '^nginx$', + '^localhost$', + ]; + $this->assertSettings($settings); + } + + /** + * Test environment variable overrides. + */ + public function testEnvironmentOverrides(): void { + $this->setEnvVars([ + 'DRUPAL_ENVIRONMENT' => static::ENVIRONMENT_SUT, + // Database configuration. + 'DATABASE_NAME' => 'custom_db', + 'DATABASE_USERNAME' => 'custom_user', + 'DATABASE_PASSWORD' => 'custom_pass', + 'DATABASE_HOST' => 'custom_host', + 'DATABASE_PORT' => '5432', + 'DATABASE_CHARSET' => 'utf8', + 'DATABASE_COLLATION' => 'utf8_general_ci', + // General Drupal settings. + 'DRUPAL_CONFIG_PATH' => 'custom_config', + 'DRUPAL_PUBLIC_FILES' => 'custom_public', + 'DRUPAL_PRIVATE_FILES' => 'custom_private', + 'DRUPAL_TEMPORARY_FILES' => 'custom_temp', + 'DRUPAL_HASH_SALT' => 'custom_hash_salt', + 'DRUPAL_TIMEZONE' => 'Australia/Melbourne', + 'DRUPAL_MAINTENANCE_THEME' => 'custom_theme', + // Performance settings. + 'DRUPAL_CACHE_PAGE_MAX_AGE' => '1800', + ]); + + $this->requireSettingsFile(); + + // Verify database settings. + $databases['default']['default']['database'] = 'custom_db'; + $databases['default']['default']['username'] = 'custom_user'; + $databases['default']['default']['password'] = 'custom_pass'; + $databases['default']['default']['host'] = 'custom_host'; + $databases['default']['default']['port'] = '5432'; + $databases['default']['default']['charset'] = 'utf8'; + $databases['default']['default']['collation'] = 'utf8_general_ci'; + $databases['default']['default']['driver'] = 'mysql'; + $databases['default']['default']['prefix'] = ''; + $this->assertEquals($databases, $this->databases); + + // Verify key config overrides. + $config['environment_indicator.indicator']['bg_color'] = '#006600'; + $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; + $config['environment_indicator.indicator']['name'] = static::ENVIRONMENT_SUT; + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 1800; + $this->assertConfig($config); + + // Verify settings overrides. + $settings['config_sync_directory'] = 'custom_config'; + $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = 'custom_public'; + $settings['file_private_path'] = 'custom_private'; + $settings['file_temp_path'] = 'custom_temp'; + + $settings['config_exclude_modules'] = []; + $settings['config_sync_directory'] = static::CONFIG_PATH_TESTING; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; + $settings['hash_salt'] = 'custom_hash_salt'; + $settings['maintenance_theme'] = 'custom_theme'; + $settings['trusted_host_patterns'] = [ + '^localhost$', ]; + $this->assertSettings($settings); } /** - * Test per-environment settings for LOCAL environment. + * Test per-environment settings for Local environment. */ public function testEnvironmentLocal(): void { $this->setEnvVars([ @@ -113,8 +198,6 @@ public function testEnvironmentLocal(): void { $config['shield.settings']['shield_enable'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $this->assertConfig($config); @@ -124,25 +207,73 @@ public function testEnvironmentLocal(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_LOCAL; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; + $settings['skip_permissions_hardening'] = TRUE; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; + $this->assertSettings($settings); + } + + /** + * Test per-environment settings for Local with container provider. + */ + public function testEnvironmentLocalContainer(): void { + $this->setEnvVars([ + 'VORTEX_LOCALDEV_URL' => 'https://example-site.docker.amazee.io', + ]); + + $this->requireSettingsFile(); + + $config['automated_cron.settings']['interval'] = 0; + $config['config_split.config_split.local']['status'] = TRUE; + $config['environment_indicator.indicator']['bg_color'] = '#006600'; + $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; + $config['environment_indicator.indicator']['name'] = static::ENVIRONMENT_LOCAL; + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = FALSE; + $config['system.logging']['error_level'] = 'all'; + $config['system.performance']['cache']['page']['max_age'] = 900; + $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; + $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; + $settings['config_sync_directory'] = static::CONFIG_PATH_TESTING; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_LOCAL; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', + '^localhost$', + '^example-site\.docker\.amazee\.io$', '^nginx$', ]; $this->assertSettings($settings); } /** - * Test per-environment settings for CI environment. + * Test per-environment settings for GitHub Actions. */ - public function testEnvironmentCi(): void { + public function testEnvironmentGha(): void { $this->setEnvVars([ 'CI' => TRUE, ]); @@ -158,8 +289,6 @@ public function testEnvironmentCi(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = FALSE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $this->assertConfig($config); @@ -169,18 +298,19 @@ public function testEnvironmentCi(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_CI; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['suspend_mail_send'] = TRUE; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', - '^nginx$', + '^localhost$', ]; $this->assertSettings($settings); } diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SettingsTestCase.php index 97e35bc75..fa577ea9a 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SettingsTestCase.php @@ -34,11 +34,6 @@ abstract class SettingsTestCase extends TestCase { */ final const ENVIRONMENT_CI = 'ci'; - /** - * Defines a constant for the name of the 'prod' environment. - */ - final const ENVIRONMENT_PROD = 'prod'; - /** * Defines a constant for the name of the 'stage' environment. */ @@ -50,20 +45,52 @@ abstract class SettingsTestCase extends TestCase { final const ENVIRONMENT_DEV = 'dev'; /** - * Defines a constant for the temp path used in testing. + * Defines a constant for the name of the 'prod' environment. */ - final const TMP_PATH_TESTING = '/tmp-test'; + final const ENVIRONMENT_PROD = 'prod'; + + /** + * Defines a constant for the public path used in testing. + */ + final const PUBLIC_PATH_TESTING = '/public-test'; /** * Defines a constant for the private path used in testing. */ final const PRIVATE_PATH_TESTING = '/private-test'; + /** + * Defines a constant for the temp path used in testing. + */ + final const TMP_PATH_TESTING = '/tmp-test'; + /** * Defines a constant for the config directory used in testing. */ final const CONFIG_PATH_TESTING = '/config-test'; + /** + * Defines a constant for the allowed environment variables. + * + * These variables are used to filter the environment variables that are set + * during the test setup. This is to ensure that only relevant variables are + * set and to avoid conflicts with other environment variables. + * + * Consumer sites should update this list if they need to add additional + * environment variables that are not part of the default set. + */ + const ALLOWED_ENV_VARS = [ + // Service variables. + 'DATABASE_', + 'VALKEY_', + 'COMPOSE_', + 'GITHUB_', + 'DOCKER_', + // Vortex and Drupal variables. + 'VORTEX_', + 'DRUPAL_', + ]; + /** * Application root. * @@ -133,21 +160,12 @@ protected function setEnvVars(array $vars): void { } $vars['DRUPAL_CONFIG_PATH'] = static::CONFIG_PATH_TESTING; - $vars['DRUPAL_TEMPORARY_FILES'] = static::TMP_PATH_TESTING; + $vars['DRUPAL_PUBLIC_FILES'] = static::PUBLIC_PATH_TESTING; $vars['DRUPAL_PRIVATE_FILES'] = static::PRIVATE_PATH_TESTING; + $vars['DRUPAL_TEMPORARY_FILES'] = static::TMP_PATH_TESTING; // Filtered real vars without a value to unset them in the lines below. - $vars_real = self::getRealEnvVarsFilteredNoValues([ - // Service variables. - 'DATABASE_', - 'VALKEY_', - 'COMPOSE_', - 'GITHUB_', - 'DOCKER_', - // Vortex and Drupal variables. - 'VORTEX_', - 'DRUPAL_', - ]); + $vars_real = self::getRealEnvVarsFilteredNoValues(static::ALLOWED_ENV_VARS); // Passed vars + existing vars + filtered real vars. $this->envVars = $vars + $this->envVars + $vars_real; diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php index f67272e13..e35e02c46 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/.vortex/installer/tests/Fixtures/install/_baseline/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -178,7 +178,7 @@ public function testEnvironmentIndicator(string $env, array $expected_present, a } /** - * Data provider for testEntityPrint(). + * Data provider for testEnvironmentIndicator(). */ public static function dataProviderEnvironmentIndicator(): array { return [ @@ -636,64 +636,4 @@ public static function dataProviderStageFileProxy(): array { ]; } - /** - * Test maintenance theme configuration. - * - * @dataProvider dataProviderMaintenanceTheme - */ - public function testMaintenanceTheme(array $vars, array $expected_present, array $expected_absent = []): void { - $this->setEnvVars($vars); - - $this->requireSettingsFile(); - - $this->assertConfigContains($expected_present); - $this->assertConfigNotContains($expected_absent); - } - - /** - * Data provider for testMaintenanceTheme(). - */ - public static function dataProviderMaintenanceTheme(): array { - return [ - // DRUPAL_MAINTENANCE_THEME set - should use it. - [ - [ - 'DRUPAL_MAINTENANCE_THEME' => 'custom_maintenance_theme', - ], - [ - 'maintenance_theme' => 'custom_maintenance_theme', - ], - ], - // DRUPAL_MAINTENANCE_THEME not set, DRUPAL_THEME set - should fall - // back to DRUPAL_THEME. - [ - [ - 'DRUPAL_THEME' => 'default_theme', - ], - [ - 'maintenance_theme' => 'default_theme', - ], - ], - // Both DRUPAL_MAINTENANCE_THEME and DRUPAL_THEME set - should prefer - // DRUPAL_MAINTENANCE_THEME. - [ - [ - 'DRUPAL_MAINTENANCE_THEME' => 'custom_maintenance_theme', - 'DRUPAL_THEME' => 'default_theme', - ], - [ - 'maintenance_theme' => 'custom_maintenance_theme', - ], - ], - // Neither set - no maintenance_theme config should be present. - [ - [], - [], - [ - 'maintenance_theme' => NULL, - ], - ], - ]; - } - } diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/web/sites/default/includes/modules/settings.automated_cron.php b/.vortex/installer/tests/Fixtures/install/_baseline/web/sites/default/includes/modules/settings.automated_cron.php new file mode 100644 index 000000000..ef3fdd5ae --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/_baseline/web/sites/default/includes/modules/settings.automated_cron.php @@ -0,0 +1,13 @@ + + [ + 'default' => + [ + 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', + 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', + 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', + 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', + 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '3306', + 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', + 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', + 'prefix' => '', + 'driver' => 'mysql', + ], + ], +]; //////////////////////////////////////////////////////////////////////////////// -/// SITE-SPECIFIC SETTINGS /// +/// GENERAL /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#general $app_root = $app_root ?? DRUPAL_ROOT; $site_path = $site_path ?? 'sites/default'; @@ -61,21 +60,39 @@ // Location of the site configuration files. $settings['config_sync_directory'] = getenv('DRUPAL_CONFIG_PATH') ?: '../config/default'; +// Location of the public files directory. +$settings['file_public_path'] = getenv('DRUPAL_PUBLIC_FILES') ?: 'sites/default/files'; + // Private directory. $settings['file_private_path'] = getenv('DRUPAL_PRIVATE_FILES') ?: 'sites/default/files/private'; // Temporary directory. $settings['file_temp_path'] = getenv('DRUPAL_TEMPORARY_FILES') ?: '/tmp'; -// Base salt on the DB host name. -$settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); +// Salt is taken from DRUPAL_HASH_SALT or the database host name. +$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT') ?: hash('sha256', $databases['default']['default']['host']); + +// Timezone settings. +ini_set('date.timezone', getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); +date_default_timezone_set(getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); + +// Maintenance theme. +$settings['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME') ?: getenv('DRUPAL_THEME') ?: 'claro'; -// Expiration of cached pages. -$config['system.performance']['cache']['page']['max_age'] = 900; +// Trusted Host Patterns. +// See https://www.drupal.org/node/2410395 for more information on how to +// populate this array. +// Settings for specific environments (including a local container-based +// environment) are populated within provider-specific +// `includes/providers/settings..php` files. +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides +$settings['trusted_host_patterns'] = [ + '^localhost$', +]; -// Aggregate CSS and JS files. -$config['system.performance']['css']['preprocess'] = TRUE; -$config['system.performance']['js']['preprocess'] = TRUE; +// Modules excluded from config export. +// Populate this array in the `includes/modules/settings..php` file. +$settings['config_exclude_modules'] = []; // The default list of directories that will be ignored by Drupal's file API. $settings['file_scan_ignore_directories'] = [ @@ -86,56 +103,35 @@ // The default number of entities to update in a batch process. $settings['entity_update_batch_size'] = 50; -// Trusted Host Patterns. -// Settings for other environments are included below. -// If your site runs on multiple domains, you need to add these domains here. -// escape dots, remove schema, use commas as regex separator. -// See https://www.drupal.org/node/2410395 for more information. -$settings['trusted_host_patterns'] = [ - // Local URL. - '^.+\.docker\.amazee\.io$', - // URL when accessed from Behat tests. - '^nginx$', -]; - -// Modules excluded from config export. -$settings['config_exclude_modules'] = []; - -ini_set('date.timezone', 'Australia/Melbourne'); -date_default_timezone_set('Australia/Melbourne'); +//////////////////////////////////////////////////////////////////////////////// +/// ENVIRONMENT TYPE DETECTION /// +//////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#environment-type-detection -// Maintenance theme. -if (getenv('DRUPAL_MAINTENANCE_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME'); +// Use these constants anywhere in code to alter behavior for a specific +// environment. +// @codeCoverageIgnoreStart +if (!defined('ENVIRONMENT_LOCAL')) { + define('ENVIRONMENT_LOCAL', 'local'); } -elseif (getenv('DRUPAL_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_THEME'); +if (!defined('ENVIRONMENT_CI')) { + define('ENVIRONMENT_CI', 'ci'); } +if (!defined('ENVIRONMENT_DEV')) { + define('ENVIRONMENT_DEV', 'dev'); +} +if (!defined('ENVIRONMENT_STAGE')) { + define('ENVIRONMENT_STAGE', 'stage'); +} +if (!defined('ENVIRONMENT_PROD')) { + define('ENVIRONMENT_PROD', 'prod'); +} +// @codeCoverageIgnoreEnd -// Default database configuration. -$databases = [ - 'default' => - [ - 'default' => - [ - 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', - 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', - 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', - 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', - 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '', - 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', - 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', - 'prefix' => '', - 'driver' => 'mysql', - ], - ], -]; - -//////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT TYPE DETECTION /// -//////////////////////////////////////////////////////////////////////////////// +// Default environment type is 'local'. +$settings['environment'] = ENVIRONMENT_LOCAL; -// Load provider-specific settings. +// Load provider-specific environment detection settings. if (file_exists($app_root . '/' . $site_path . '/includes/providers')) { $files = glob($app_root . '/' . $site_path . '/includes/providers/settings.*.php'); if ($files) { @@ -145,40 +141,15 @@ } } -// Allow overriding of an environment type. +// Allow to override an environment type using the DRUPAL_ENVIRONMENT variable. if (!empty(getenv('DRUPAL_ENVIRONMENT'))) { $settings['environment'] = getenv('DRUPAL_ENVIRONMENT'); } //////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT-SPECIFIC SETTINGS /// -//////////////////////////////////////////////////////////////////////////////// - -if ($settings['environment'] == ENVIRONMENT_CI) { - // Never harden permissions on sites/default/files. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Disable mail send out. - $settings['suspend_mail_send'] = TRUE; -} - -if ($settings['environment'] == ENVIRONMENT_LOCAL) { - // Never harden permissions on sites/default/files during local development. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Show all error messages on the site. - $config['system.logging']['error_level'] = 'all'; -} - -//////////////////////////////////////////////////////////////////////////////// -/// PER-MODULE SETTINGS /// +/// PER-MODULE OVERRIDES /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides if (file_exists($app_root . '/' . $site_path . '/includes/modules')) { $files = glob($app_root . '/' . $site_path . '/includes/modules/settings.*.php'); @@ -190,14 +161,17 @@ } //////////////////////////////////////////////////////////////////////////////// -/// LOCAL SETTINGS /// +/// LOCAL OVERRIDE /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#local-overrides -// Load local development override configuration, if available. +// Load local override configuration, if available. +// +// Copy `default.settings.local.php` and `default.services.local.yml` to +// `settings.local.php` and `services.local.yml` respectively to enable local +// overrides. // -// Copy default.settings.local.php and default.services.local.yml to -// settings.local.php and services.local.yml respectively. -// services.local.yml is loaded in in settings.local.php. +// `services.local.yml` is loaded from within `settings.local.php`. // // Keep this code block at the end of this file to take full effect. // @codeCoverageIgnoreStart diff --git a/.vortex/installer/tests/Fixtures/install/_baseline/web/themes/custom/star_wars/js/star_wars.js b/.vortex/installer/tests/Fixtures/install/_baseline/web/themes/custom/star_wars/js/star_wars.js index ce74ee472..6064078cb 100644 --- a/.vortex/installer/tests/Fixtures/install/_baseline/web/themes/custom/star_wars/js/star_wars.js +++ b/.vortex/installer/tests/Fixtures/install/_baseline/web/themes/custom/star_wars/js/star_wars.js @@ -1,6 +1,6 @@ /** * @file - * Global theme behaviours. + * Global theme behaviors. */ (function ($, Drupal) { diff --git a/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/.circleci/config.yml b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/.circleci/config.yml index e46af4f7f..4edf3913d 100644 --- a/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/.circleci/config.yml +++ b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/.circleci/config.yml @@ -39,7 +39,7 @@ aliases: environment: # Set runner timezone to ensure that executed operations use correct timestamps. # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ: "Australia/Melbourne" + TZ: "UTC" # Set runner terminal capabilities. TERM: xterm-256color # Disable strict host key checking for SSH connections. @@ -58,10 +58,8 @@ aliases: VORTEX_CI_TEST_RESULTS: &test_results /tmp/tests # Directory to store test artifacts. VORTEX_CI_ARTIFACTS: &artifacts /tmp/artifacts - # Directory to store code exported between jobs. - VORTEX_EXPORT_CODE_DIR: &vortex_build_export_dir /tmp/workspace/code # Directory to use for artifact deployments. - VORTEX_DEPLOY_ARTIFACT_SRC: *vortex_build_export_dir + VORTEX_DEPLOY_ARTIFACT_SRC: /tmp/workspace/code # Source code location for artifact deployments. VORTEX_DEPLOY_ARTIFACT_ROOT: *working_directory # Report file location for artifact deployments. @@ -239,8 +237,9 @@ jobs: - run: name: Export built codebase command: | - mkdir -p "${VORTEX_EXPORT_CODE_DIR}" - docker compose cp -L cli:"/app/." "${VORTEX_EXPORT_CODE_DIR}" + mkdir -p "/tmp/workspace/code" + docker compose cp -L cli:"/app/." "/tmp/workspace/code" + du -sh "/tmp/workspace/code" - run: name: Install development dependencies diff --git a/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php new file mode 100644 index 000000000..c5bcd4c8b --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -0,0 +1,12 @@ +@@ -271,9 +271,9 @@ + } + + /** +- * Test per-environment settings for GitHub Actions. ++ * Test per-environment settings for CircleCI. + */ +- public function testEnvironmentGha(): void { ++ public function testEnvironmentCircleCi(): void { + $this->setEnvVars([ + 'CI' => TRUE, + ]); diff --git a/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/web/sites/default/includes/providers/-settings.gha.php b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/web/sites/default/includes/providers/-settings.gha.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/web/sites/default/includes/providers/settings.circleci.php b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/web/sites/default/includes/providers/settings.circleci.php new file mode 100644 index 000000000..7cad35cf8 --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/ciprovider_circleci/web/sites/default/includes/providers/settings.circleci.php @@ -0,0 +1,17 @@ +setEnvVars([ + 'CI' => TRUE, + ]); diff --git a/.vortex/installer/tests/Fixtures/install/deploy_type_all_circleci/web/sites/default/includes/providers/-settings.gha.php b/.vortex/installer/tests/Fixtures/install/deploy_type_all_circleci/web/sites/default/includes/providers/-settings.gha.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/deploy_type_all_circleci/web/sites/default/includes/providers/settings.circleci.php b/.vortex/installer/tests/Fixtures/install/deploy_type_all_circleci/web/sites/default/includes/providers/settings.circleci.php new file mode 100644 index 000000000..7cad35cf8 --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/deploy_type_all_circleci/web/sites/default/includes/providers/settings.circleci.php @@ -0,0 +1,17 @@ +setEnvVars([ + 'CI' => TRUE, + ]); diff --git a/.vortex/installer/tests/Fixtures/install/deploy_type_none_circleci/web/sites/default/includes/providers/-settings.gha.php b/.vortex/installer/tests/Fixtures/install/deploy_type_none_circleci/web/sites/default/includes/providers/-settings.gha.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/deploy_type_none_circleci/web/sites/default/includes/providers/settings.circleci.php b/.vortex/installer/tests/Fixtures/install/deploy_type_none_circleci/web/sites/default/includes/providers/settings.circleci.php new file mode 100644 index 000000000..7cad35cf8 --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/deploy_type_none_circleci/web/sites/default/includes/providers/settings.circleci.php @@ -0,0 +1,17 @@ +setEnvVars([ + 'CI' => TRUE, + ]); diff --git a/.vortex/installer/tests/Fixtures/install/deps_updates_provider_ci_circleci/web/sites/default/includes/providers/-settings.gha.php b/.vortex/installer/tests/Fixtures/install/deps_updates_provider_ci_circleci/web/sites/default/includes/providers/-settings.gha.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/deps_updates_provider_ci_circleci/web/sites/default/includes/providers/settings.circleci.php b/.vortex/installer/tests/Fixtures/install/deps_updates_provider_ci_circleci/web/sites/default/includes/providers/settings.circleci.php new file mode 100644 index 000000000..7cad35cf8 --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/deps_updates_provider_ci_circleci/web/sites/default/includes/providers/settings.circleci.php @@ -0,0 +1,17 @@ + + [ + 'default' => + [ + 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', + 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', + 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', + 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', + 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '3306', + 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', + 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', + 'prefix' => '', + 'driver' => 'mysql', + ], + ], +]; //////////////////////////////////////////////////////////////////////////////// -/// SITE-SPECIFIC SETTINGS /// +/// GENERAL /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#general $app_root = $app_root ?? DRUPAL_ROOT; $site_path = $site_path ?? 'sites/default'; @@ -61,21 +60,39 @@ // Location of the site configuration files. $settings['config_sync_directory'] = getenv('DRUPAL_CONFIG_PATH') ?: '../config/default'; +// Location of the public files directory. +$settings['file_public_path'] = getenv('DRUPAL_PUBLIC_FILES') ?: 'sites/default/files'; + // Private directory. $settings['file_private_path'] = getenv('DRUPAL_PRIVATE_FILES') ?: 'sites/default/files/private'; // Temporary directory. $settings['file_temp_path'] = getenv('DRUPAL_TEMPORARY_FILES') ?: '/tmp'; -// Base salt on the DB host name. -$settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); +// Salt is taken from DRUPAL_HASH_SALT or the database host name. +$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT') ?: hash('sha256', $databases['default']['default']['host']); + +// Timezone settings. +ini_set('date.timezone', getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); +date_default_timezone_set(getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); + +// Maintenance theme. +$settings['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME') ?: getenv('DRUPAL_THEME') ?: 'claro'; -// Expiration of cached pages. -$config['system.performance']['cache']['page']['max_age'] = 900; +// Trusted Host Patterns. +// See https://www.drupal.org/node/2410395 for more information on how to +// populate this array. +// Settings for specific environments (including a local container-based +// environment) are populated within provider-specific +// `includes/providers/settings..php` files. +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides +$settings['trusted_host_patterns'] = [ + '^localhost$', +]; -// Aggregate CSS and JS files. -$config['system.performance']['css']['preprocess'] = TRUE; -$config['system.performance']['js']['preprocess'] = TRUE; +// Modules excluded from config export. +// Populate this array in the `includes/modules/settings..php` file. +$settings['config_exclude_modules'] = []; // The default list of directories that will be ignored by Drupal's file API. $settings['file_scan_ignore_directories'] = [ @@ -86,56 +103,35 @@ // The default number of entities to update in a batch process. $settings['entity_update_batch_size'] = 50; -// Trusted Host Patterns. -// Settings for other environments are included below. -// If your site runs on multiple domains, you need to add these domains here. -// escape dots, remove schema, use commas as regex separator. -// See https://www.drupal.org/node/2410395 for more information. -$settings['trusted_host_patterns'] = [ - // Local URL. - '^.+\.docker\.amazee\.io$', - // URL when accessed from Behat tests. - '^nginx$', -]; - -// Modules excluded from config export. -$settings['config_exclude_modules'] = []; - -ini_set('date.timezone', 'Australia/Melbourne'); -date_default_timezone_set('Australia/Melbourne'); +//////////////////////////////////////////////////////////////////////////////// +/// ENVIRONMENT TYPE DETECTION /// +//////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#environment-type-detection -// Maintenance theme. -if (getenv('DRUPAL_MAINTENANCE_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME'); +// Use these constants anywhere in code to alter behavior for a specific +// environment. +// @codeCoverageIgnoreStart +if (!defined('ENVIRONMENT_LOCAL')) { + define('ENVIRONMENT_LOCAL', 'local'); } -elseif (getenv('DRUPAL_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_THEME'); +if (!defined('ENVIRONMENT_CI')) { + define('ENVIRONMENT_CI', 'ci'); } +if (!defined('ENVIRONMENT_DEV')) { + define('ENVIRONMENT_DEV', 'dev'); +} +if (!defined('ENVIRONMENT_STAGE')) { + define('ENVIRONMENT_STAGE', 'stage'); +} +if (!defined('ENVIRONMENT_PROD')) { + define('ENVIRONMENT_PROD', 'prod'); +} +// @codeCoverageIgnoreEnd -// Default database configuration. -$databases = [ - 'default' => - [ - 'default' => - [ - 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', - 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', - 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', - 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', - 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '', - 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', - 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', - 'prefix' => '', - 'driver' => 'mysql', - ], - ], -]; - -//////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT TYPE DETECTION /// -//////////////////////////////////////////////////////////////////////////////// +// Default environment type is 'local'. +$settings['environment'] = ENVIRONMENT_LOCAL; -// Load provider-specific settings. +// Load provider-specific environment detection settings. if (file_exists($app_root . '/' . $site_path . '/includes/providers')) { $files = glob($app_root . '/' . $site_path . '/includes/providers/settings.*.php'); if ($files) { @@ -145,40 +141,15 @@ } } -// Allow overriding of an environment type. +// Allow to override an environment type using the DRUPAL_ENVIRONMENT variable. if (!empty(getenv('DRUPAL_ENVIRONMENT'))) { $settings['environment'] = getenv('DRUPAL_ENVIRONMENT'); } //////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT-SPECIFIC SETTINGS /// -//////////////////////////////////////////////////////////////////////////////// - -if ($settings['environment'] == ENVIRONMENT_CI) { - // Never harden permissions on sites/default/files. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Disable mail send out. - $settings['suspend_mail_send'] = TRUE; -} - -if ($settings['environment'] == ENVIRONMENT_LOCAL) { - // Never harden permissions on sites/default/files during local development. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Show all error messages on the site. - $config['system.logging']['error_level'] = 'all'; -} - -//////////////////////////////////////////////////////////////////////////////// -/// PER-MODULE SETTINGS /// +/// PER-MODULE OVERRIDES /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides if (file_exists($app_root . '/' . $site_path . '/includes/modules')) { $files = glob($app_root . '/' . $site_path . '/includes/modules/settings.*.php'); @@ -190,14 +161,17 @@ } //////////////////////////////////////////////////////////////////////////////// -/// LOCAL SETTINGS /// +/// LOCAL OVERRIDE /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#local-overrides -// Load local development override configuration, if available. +// Load local override configuration, if available. +// +// Copy `default.settings.local.php` and `default.services.local.yml` to +// `settings.local.php` and `services.local.yml` respectively to enable local +// overrides. // -// Copy default.settings.local.php and default.services.local.yml to -// settings.local.php and services.local.yml respectively. -// services.local.yml is loaded in in settings.local.php. +// `services.local.yml` is loaded from within `settings.local.php`. // // Keep this code block at the end of this file to take full effect. // @codeCoverageIgnoreStart diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/docroot/themes/custom/star_wars/js/star_wars.js b/.vortex/installer/tests/Fixtures/install/hosting_acquia/docroot/themes/custom/star_wars/js/star_wars.js index ce74ee472..6064078cb 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_acquia/docroot/themes/custom/star_wars/js/star_wars.js +++ b/.vortex/installer/tests/Fixtures/install/hosting_acquia/docroot/themes/custom/star_wars/js/star_wars.js @@ -1,6 +1,6 @@ /** * @file - * Global theme behaviours. + * Global theme behaviors. */ (function ($, Drupal) { diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 43b5e6d4f..fb008481a 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,5 +1,5 @@ -@@ -50,6 +50,49 @@ - static::ENVIRONMENT_CI, +@@ -58,6 +58,50 @@ + static::ENVIRONMENT_LOCAL, ], + // Acquia. @@ -45,13 +45,17 @@ + ], + static::ENVIRONMENT_DEV, + ], ++ ]; } -@@ -182,6 +225,164 @@ - '^.+\.docker\.amazee\.io$', - '^nginx$', - ]; +@@ -309,6 +353,170 @@ + $settings['maintenance_theme'] = 'claro'; + $settings['skip_permissions_hardening'] = TRUE; + $settings['suspend_mail_send'] = TRUE; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ ]; + $this->assertSettings($settings); + } + @@ -74,8 +78,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; @@ -83,15 +85,18 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; ++ $settings['maintenance_theme'] = 'claro'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ ]; + $this->assertSettings($settings); + } + @@ -114,8 +119,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; @@ -123,15 +126,18 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; ++ $settings['maintenance_theme'] = 'claro'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ ]; + $this->assertSettings($settings); + } + @@ -154,8 +160,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; @@ -163,15 +167,18 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_STAGE; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; ++ $settings['maintenance_theme'] = 'claro'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ ]; + $this->assertSettings($settings); + } + @@ -192,8 +199,8 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; ++ $config['system.performance']['css']['preprocess'] = TRUE; ++ $config['system.performance']['js']['preprocess'] = TRUE; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; @@ -201,15 +208,15 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_PROD; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; - $this->assertSettings($settings); - } - ++ $settings['maintenance_theme'] = 'claro'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php index 4d161780a..5fd164183 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php +++ b/.vortex/installer/tests/Fixtures/install/hosting_acquia/tests/phpunit/Drupal/SettingsTestCase.php @@ -1,4 +1,4 @@ -@@ -201,7 +201,7 @@ +@@ -219,7 +219,7 @@ * Require settings file. */ protected function requireSettingsFile(): void { diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.automated_cron.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.automated_cron.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.sw_base.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.sw_base.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.system.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/modules/-settings.system.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/providers/-settings.container.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/providers/-settings.container.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/providers/-settings.gha.php b/.vortex/installer/tests/Fixtures/install/hosting_acquia/web/sites/default/includes/providers/-settings.gha.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/.env b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/.env index 07728e493..25937b841 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/.env +++ b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/.env @@ -1,4 +1,4 @@ -@@ -104,6 +104,16 @@ +@@ -106,6 +106,16 @@ VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 ################################################################################ @@ -12,17 +12,17 @@ +VORTEX_LAGOON_PRODUCTION_BRANCH=main + +################################################################################ - # DATABASE # + # DATABASE SOURCE # ################################################################################ -@@ -123,13 +133,8 @@ +@@ -129,13 +139,8 @@ VORTEX_DB_FILE=db.sql # Database download source. -VORTEX_DB_DOWNLOAD_SOURCE=url +VORTEX_DB_DOWNLOAD_SOURCE=lagoon --# Database dump file sourced from CURL. +-# Database dump file sourced from a URL. -# -# HTTP Basic Authentication credentials should be embedded into the value. -VORTEX_DB_DOWNLOAD_URL= @@ -30,7 +30,7 @@ # Environment to download the database from. # # Applies to hosting environments. -@@ -143,7 +148,7 @@ +@@ -149,7 +154,7 @@ # Deployment occurs when tests pass in the CI environment. # @see https://vortex.drevops.com/workflows/deployment @@ -39,10 +39,10 @@ ################################################################################ # NOTIFICATIONS # -@@ -166,17 +171,3 @@ +@@ -176,17 +181,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" - VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com" + VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@star-wars.com - -################################################################################ -# DEMO # diff --git a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/docker-compose.yml b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/docker-compose.yml index ad30bab80..0b828e819 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/docker-compose.yml +++ b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/docker-compose.yml @@ -4,7 +4,7 @@ # Environment variables set in all containers during build and runtime. +# Note that these variables are not read from here in Lagoon environment. x-environment: &default-environment - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Pass-through 'CI' variable used to identify the CI environment. @@ -90,6 +91,10 @@ # Mount volumes from the ssh-agent running in Pygmy to inject host SSH key into container. See https://pygmy.readthedocs.io/en/master/ssh_agent/ diff --git a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 88f107c8c..80f47d135 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -1,5 +1,5 @@ -@@ -50,6 +50,186 @@ - static::ENVIRONMENT_CI, +@@ -58,6 +58,186 @@ + static::ENVIRONMENT_LOCAL, ], + // Lagoon. @@ -185,17 +185,18 @@ ]; } -@@ -182,6 +362,205 @@ - '^.+\.docker\.amazee\.io$', - '^nginx$', - ]; +@@ -311,6 +491,211 @@ + $settings['suspend_mail_send'] = TRUE; + $settings['trusted_host_patterns'] = [ + '^localhost$', ++ ]; + $this->assertSettings($settings); + } + + /** -+ * Test per-environment settings for dynamic environment. ++ * Test per-environment settings for preview environment. + */ -+ public function testEnvironmentLagoonDynamic(): void { ++ public function testEnvironmentLagoonPreview(): void { + $this->setEnvVars([ + 'LAGOON_KUBERNETES' => 1, + 'LAGOON_ENVIRONMENT_TYPE' => 'development', @@ -215,8 +216,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_test_branch'; @@ -225,20 +224,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -265,8 +267,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_develop'; @@ -275,20 +275,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -315,8 +318,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_master'; @@ -325,20 +326,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_STAGE; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -364,8 +368,8 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; ++ $config['system.performance']['css']['preprocess'] = TRUE; ++ $config['system.performance']['js']['preprocess'] = TRUE; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_production'; @@ -374,20 +378,22 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_PROD; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } - diff --git a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/web/sites/default/includes/providers/settings.lagoon.php b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/web/sites/default/includes/providers/settings.lagoon.php index 087e20452..6de5991a5 100644 --- a/.vortex/installer/tests/Fixtures/install/hosting_lagoon/web/sites/default/includes/providers/settings.lagoon.php +++ b/.vortex/installer/tests/Fixtures/install/hosting_lagoon/web/sites/default/includes/providers/settings.lagoon.php @@ -5,8 +5,8 @@ * Lagoon hosting provider settings. * * Do not place any custom settings in this file. - * It is used to explicitly map Lagoon environments to $settings['environment'] - * and set platform-specific settings only. + * It is used to explicitly map provider environments to + * $settings['environment'] and set platform-specific settings only. * Instead, use per-module settings files. */ diff --git a/.vortex/installer/tests/Fixtures/install/names/.env b/.vortex/installer/tests/Fixtures/install/names/.env index 9c1ba4577..9974a4263 100644 --- a/.vortex/installer/tests/Fixtures/install/names/.env +++ b/.vortex/installer/tests/Fixtures/install/names/.env @@ -1,4 +1,4 @@ -@@ -25,7 +25,7 @@ +@@ -26,7 +26,7 @@ # Drives internal naming within the codebase. # Does not affect the names of containers and development URL - those depend on # the project directory and can be overridden with $COMPOSE_PROJECT_NAME. @@ -7,7 +7,7 @@ # Name of the web root directory containing a Drupal codebase. WEBROOT=web -@@ -41,16 +41,16 @@ +@@ -42,16 +42,16 @@ DRUPAL_PROFILE=standard # Drupal theme name. @@ -27,30 +27,30 @@ # Shield message. DRUPAL_SHIELD_PRINT="Restricted access." -@@ -98,7 +98,7 @@ +@@ -100,7 +100,7 @@ # # Applied if database sanitization is enabled. - # @see https://vortex.drevops.com/workflows/build#sanitization + # @see https://vortex.drevops.com/drupal/provision#database-sanitization -VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@star-wars.com" +VORTEX_PROVISION_SANITIZE_DB_EMAIL="user_%uid@deathstar.com" # Put the site into a maintenance mode during site provisioning. VORTEX_PROVISION_USE_MAINTENANCE_MODE=1 -@@ -158,7 +158,7 @@ - VORTEX_NOTIFY_CHANNELS=email - - # Email to send notifications from. --VORTEX_NOTIFY_EMAIL_FROM="webmaster@star-wars.com" -+VORTEX_NOTIFY_EMAIL_FROM="webmaster@deathstar.com" +@@ -166,7 +166,7 @@ + # An email address to send notifications from. + # + # Applies to email notifications. +-VORTEX_NOTIFY_EMAIL_FROM=webmaster@star-wars.com ++VORTEX_NOTIFY_EMAIL_FROM=webmaster@deathstar.com # Email address(es) to send notifications to. # -@@ -165,7 +165,7 @@ +@@ -175,7 +175,7 @@ # Multiple names can be specified as a comma-separated list of email addresses # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" --VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com" -+VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@deathstar.com" +-VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@star-wars.com ++VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@deathstar.com ################################################################################ # DEMO # diff --git a/.vortex/installer/tests/Fixtures/install/names/web/sites/default/includes/modules/-settings.sw_base.php b/.vortex/installer/tests/Fixtures/install/names/web/sites/default/includes/modules/-settings.sw_base.php new file mode 100644 index 000000000..e69de29bb diff --git a/.vortex/installer/tests/Fixtures/install/names/web/sites/default/includes/modules/settings.the_force_base.php b/.vortex/installer/tests/Fixtures/install/names/web/sites/default/includes/modules/settings.the_force_base.php new file mode 100644 index 000000000..35cb1f118 --- /dev/null +++ b/.vortex/installer/tests/Fixtures/install/names/web/sites/default/includes/modules/settings.the_force_base.php @@ -0,0 +1,13 @@ +assertSettings($settings); + } + + /** -+ * Test per-environment settings for dynamic environment. ++ * Test per-environment settings for preview environment. + */ -+ public function testEnvironmentLagoonDynamic(): void { ++ public function testEnvironmentLagoonPreview(): void { + $this->setEnvVars([ + 'LAGOON_KUBERNETES' => 1, + 'LAGOON_ENVIRONMENT_TYPE' => 'development', @@ -215,8 +216,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_test_branch'; @@ -225,20 +224,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -265,8 +267,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_develop'; @@ -275,20 +275,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_DEV; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -315,8 +318,6 @@ + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_master'; @@ -325,20 +326,23 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_STAGE; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', ++ ]; + $this->assertSettings($settings); + } + @@ -364,8 +368,8 @@ + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['system.performance']['cache']['page']['max_age'] = 900; -+ $config['system.performance']['css']['preprocess'] = 1; -+ $config['system.performance']['js']['preprocess'] = 1; ++ $config['system.performance']['css']['preprocess'] = TRUE; ++ $config['system.performance']['js']['preprocess'] = TRUE; + $this->assertConfig($config); + + $settings['cache_prefix']['default'] = 'test_project_production'; @@ -374,20 +378,22 @@ + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_PROD; ++ $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; ++ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; -+ $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); ++ $settings['maintenance_theme'] = 'claro'; + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; -+ $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^nginx$'; -+ $settings['trusted_host_patterns'][] = '^nginx\-php$'; -+ $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; -+ $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; ++ $settings['trusted_host_patterns'] = [ ++ '^localhost$', ++ '^nginx\-php$', ++ '^.+\.au\.amazee\.io$', ++ '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } - diff --git a/.vortex/installer/tests/Fixtures/install/provision_database_lagoon/web/sites/default/includes/providers/settings.lagoon.php b/.vortex/installer/tests/Fixtures/install/provision_database_lagoon/web/sites/default/includes/providers/settings.lagoon.php index 087e20452..6de5991a5 100644 --- a/.vortex/installer/tests/Fixtures/install/provision_database_lagoon/web/sites/default/includes/providers/settings.lagoon.php +++ b/.vortex/installer/tests/Fixtures/install/provision_database_lagoon/web/sites/default/includes/providers/settings.lagoon.php @@ -5,8 +5,8 @@ * Lagoon hosting provider settings. * * Do not place any custom settings in this file. - * It is used to explicitly map Lagoon environments to $settings['environment'] - * and set platform-specific settings only. + * It is used to explicitly map provider environments to + * $settings['environment'] and set platform-specific settings only. * Instead, use per-module settings files. */ diff --git a/.vortex/installer/tests/Fixtures/install/provision_profile/.env b/.vortex/installer/tests/Fixtures/install/provision_profile/.env index 647d75589..3574fe1bd 100644 --- a/.vortex/installer/tests/Fixtures/install/provision_profile/.env +++ b/.vortex/installer/tests/Fixtures/install/provision_profile/.env @@ -1,5 +1,5 @@ -@@ -79,7 +79,7 @@ - # @see https://vortex.drevops.com/workflows/provision +@@ -80,7 +80,7 @@ + # @see https://vortex.drevops.com/drupal/provision # Set to 'profile' to install a site from profile instead of the database dump. -VORTEX_PROVISION_TYPE=database @@ -7,14 +7,14 @@ # Overwrite a database if it exists. # -@@ -122,21 +122,6 @@ - # Database dump file name. +@@ -128,21 +128,6 @@ + # The file is used to import the database into an empty database container. VORTEX_DB_FILE=db.sql -# Database download source. -VORTEX_DB_DOWNLOAD_SOURCE=url - --# Database dump file sourced from CURL. +-# Database dump file sourced from a URL. -# -# HTTP Basic Authentication credentials should be embedded into the value. -VORTEX_DB_DOWNLOAD_URL= @@ -29,10 +29,10 @@ ################################################################################ # DEPLOYMENT # ################################################################################ -@@ -166,17 +151,3 @@ +@@ -176,17 +161,3 @@ # with optional names in the format "email|name". # Example: "to1@example.com|Jane Doe, to2@example.com|John Doe" - VORTEX_NOTIFY_EMAIL_RECIPIENTS="webmaster@star-wars.com" + VORTEX_NOTIFY_EMAIL_RECIPIENTS=webmaster@star-wars.com - -################################################################################ -# DEMO # diff --git a/.vortex/installer/tests/Fixtures/install/provision_profile/.github/workflows/build-test-deploy.yml b/.vortex/installer/tests/Fixtures/install/provision_profile/.github/workflows/build-test-deploy.yml index 835076aa2..efbbdb72e 100644 --- a/.vortex/installer/tests/Fixtures/install/provision_profile/.github/workflows/build-test-deploy.yml +++ b/.vortex/installer/tests/Fixtures/install/provision_profile/.github/workflows/build-test-deploy.yml @@ -18,7 +18,7 @@ - image: drevops/ci-runner:__VERSION__ - - env: -- TZ: Australia/Melbourne +- TZ: UTC - TERM: xterm-256color - VORTEX_SSH_DISABLE_STRICT_HOST_KEY_CHECKING: "1" - VORTEX_SSH_REMOVE_ALL_KEYS: "1" diff --git a/.vortex/installer/tests/Fixtures/install/services_no_clamav/.env b/.vortex/installer/tests/Fixtures/install/services_no_clamav/.env index 356468c2b..3d9e1548e 100644 --- a/.vortex/installer/tests/Fixtures/install/services_no_clamav/.env +++ b/.vortex/installer/tests/Fixtures/install/services_no_clamav/.env @@ -1,4 +1,4 @@ -@@ -59,15 +59,6 @@ +@@ -60,15 +60,6 @@ # See settings.redis.php for details. DRUPAL_VALKEY_ENABLED=0 diff --git a/.vortex/installer/tests/Fixtures/install/services_no_valkey/.env b/.vortex/installer/tests/Fixtures/install/services_no_valkey/.env index cf1cc1bec..254f5334a 100644 --- a/.vortex/installer/tests/Fixtures/install/services_no_valkey/.env +++ b/.vortex/installer/tests/Fixtures/install/services_no_valkey/.env @@ -1,4 +1,4 @@ -@@ -55,10 +55,6 @@ +@@ -56,10 +56,6 @@ # Shield message. DRUPAL_SHIELD_PRINT="Restricted access." diff --git a/.vortex/installer/tests/Fixtures/install/services_none/.env b/.vortex/installer/tests/Fixtures/install/services_none/.env index 2265d2bf4..a1d1f1f1e 100644 --- a/.vortex/installer/tests/Fixtures/install/services_none/.env +++ b/.vortex/installer/tests/Fixtures/install/services_none/.env @@ -1,4 +1,4 @@ -@@ -55,19 +55,6 @@ +@@ -56,19 +56,6 @@ # Shield message. DRUPAL_SHIELD_PRINT="Restricted access." diff --git a/.vortex/installer/tests/Fixtures/install/theme_absent/.ahoy.yml b/.vortex/installer/tests/Fixtures/install/theme_absent/.ahoy.yml index ab46bf97d..fdc6254e8 100644 --- a/.vortex/installer/tests/Fixtures/install/theme_absent/.ahoy.yml +++ b/.vortex/installer/tests/Fixtures/install/theme_absent/.ahoy.yml @@ -35,7 +35,7 @@ - usage: Lint front-end code. - cmd: | - ahoy cli vendor/bin/twig-cs-fixer lint -- ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" +- ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint" - lint-tests: usage: Lint tests code. @@ -58,7 +58,7 @@ - usage: Fix lint issues of front-end code. - cmd: | - ahoy cli vendor/bin/twig-cs-fixer lint --fix -- ahoy cli "npm run --prefix \${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" +- ahoy cli "yarn run --cwd=\${WEBROOT}/themes/custom/\${DRUPAL_THEME} lint-fix" test: usage: Run all tests. diff --git a/.vortex/installer/tests/Fixtures/install/theme_absent/.env b/.vortex/installer/tests/Fixtures/install/theme_absent/.env index 5ec4f2b96..f5534e032 100644 --- a/.vortex/installer/tests/Fixtures/install/theme_absent/.env +++ b/.vortex/installer/tests/Fixtures/install/theme_absent/.env @@ -1,5 +1,5 @@ -@@ -40,11 +40,8 @@ - # Drupal profile name (used only when installing from profile). +@@ -41,11 +41,8 @@ + # Drupal profile name. DRUPAL_PROFILE=standard -# Drupal theme name. diff --git a/.vortex/installer/tests/Fixtures/install/theme_custom/.env b/.vortex/installer/tests/Fixtures/install/theme_custom/.env index 3c58eb4fc..9d9967624 100644 --- a/.vortex/installer/tests/Fixtures/install/theme_custom/.env +++ b/.vortex/installer/tests/Fixtures/install/theme_custom/.env @@ -1,4 +1,4 @@ -@@ -41,10 +41,10 @@ +@@ -42,10 +42,10 @@ DRUPAL_PROFILE=standard # Drupal theme name. diff --git a/.vortex/installer/tests/Fixtures/install/theme_custom/web/themes/custom/light_saber/js/light_saber.js b/.vortex/installer/tests/Fixtures/install/theme_custom/web/themes/custom/light_saber/js/light_saber.js index e4d3a54d3..b7592043c 100644 --- a/.vortex/installer/tests/Fixtures/install/theme_custom/web/themes/custom/light_saber/js/light_saber.js +++ b/.vortex/installer/tests/Fixtures/install/theme_custom/web/themes/custom/light_saber/js/light_saber.js @@ -1,6 +1,6 @@ /** * @file - * Global theme behaviours. + * Global theme behaviors. */ (function ($, Drupal) { diff --git a/.vortex/installer/tests/Fixtures/version_replacement/baseline/docker-compose.yml b/.vortex/installer/tests/Fixtures/version_replacement/baseline/docker-compose.yml index 286d73369..6e4a808b8 100644 --- a/.vortex/installer/tests/Fixtures/version_replacement/baseline/docker-compose.yml +++ b/.vortex/installer/tests/Fixtures/version_replacement/baseline/docker-compose.yml @@ -41,7 +41,7 @@ x-user: &default-user # Note that these variables are not read from here in Lagoon environment. #;> HOSTING_LAGOON x-environment: &default-environment - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Local development URL. VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io # Local development route used in Lagoon images and Pygmy to route requests. diff --git a/.vortex/installer/tests/Fixtures/version_replacement/expected/docker-compose.yml b/.vortex/installer/tests/Fixtures/version_replacement/expected/docker-compose.yml index 03c328e2c..06a6a8e7e 100644 --- a/.vortex/installer/tests/Fixtures/version_replacement/expected/docker-compose.yml +++ b/.vortex/installer/tests/Fixtures/version_replacement/expected/docker-compose.yml @@ -41,7 +41,7 @@ x-user: &default-user # Note that these variables are not read from here in Lagoon environment. #;> HOSTING_LAGOON x-environment: &default-environment - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Local development URL. VORTEX_LOCALDEV_URL: &default-url ${COMPOSE_PROJECT_NAME:-example-site}.docker.amazee.io # Local development route used in Lagoon images and Pygmy to route requests. diff --git a/.vortex/tests/bats/_helper.bash b/.vortex/tests/bats/_helper.bash index 7ac489136..73e367d67 100644 --- a/.vortex/tests/bats/_helper.bash +++ b/.vortex/tests/bats/_helper.bash @@ -1351,7 +1351,7 @@ sync_to_container() { # Special treatment for cases where volumes are not mounted from the host. fix_host_dependencies() { - # Replicate behaviour of .vortex/installer/install script to extract destination directory + # Replicate behavior of .vortex/installer/install script to extract destination directory # passed as an argument. # shellcheck disable=SC2235 ([ "${1:-}" = "--quiet" ] || [ "${1:-}" = "-q" ]) && shift diff --git a/.vortex/tests/bats/_helper.workflow.bash b/.vortex/tests/bats/_helper.workflow.bash index d5c887821..b5a473932 100644 --- a/.vortex/tests/bats/_helper.workflow.bash +++ b/.vortex/tests/bats/_helper.workflow.bash @@ -211,7 +211,7 @@ assert_env_changes() { assert_output_contains "my_custom_var_value" assert_success - # Restore file, apply changes and assert that original behaviour has been restored. + # Restore file, apply changes and assert that original behavior has been restored. restore_file ".env" ahoy up cli sync_to_container @@ -229,16 +229,15 @@ assert_timezone() { step "Check that timezone can be applied" # Assert that .env contains a default value. - # Note that AEDT changes to AEST during winter. - assert_file_contains ".env" 'TZ="Australia/Melbourne"' + assert_file_contains ".env" 'TZ=UTC' run docker compose exec cli date - assert_output_contains "AE" + assert_output_contains "UTC" run docker compose exec php date - assert_output_contains "AE" + assert_output_contains "UTC" run docker compose exec nginx date - assert_output_contains "AE" + assert_output_contains "UTC" run docker compose exec database date - assert_output_contains "AE" + assert_output_contains "UTC" # Add variable to the .env file and apply the change to container. add_var_to_file .env "TZ" '"Australia/Perth"' @@ -254,7 +253,7 @@ assert_timezone() { run docker compose exec database date assert_output_contains "AWST" - # Restore file, apply changes and assert that original behaviour has been restored. + # Restore file, apply changes and assert that original behavior has been restored. restore_file ".env" sync_to_container run ahoy up diff --git a/.vortex/tests/bats/fixtures/docker-compose.env.json b/.vortex/tests/bats/fixtures/docker-compose.env.json index b40883d35..f2af9a916 100644 --- a/.vortex/tests/bats/fixtures/docker-compose.env.json +++ b/.vortex/tests/bats/fixtures/docker-compose.env.json @@ -34,7 +34,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -93,7 +93,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -143,7 +143,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -200,7 +200,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -258,7 +258,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -321,7 +321,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -384,7 +384,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, diff --git a/.vortex/tests/bats/fixtures/docker-compose.env_local.json b/.vortex/tests/bats/fixtures/docker-compose.env_local.json index b40883d35..f2af9a916 100644 --- a/.vortex/tests/bats/fixtures/docker-compose.env_local.json +++ b/.vortex/tests/bats/fixtures/docker-compose.env_local.json @@ -34,7 +34,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -93,7 +93,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -143,7 +143,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -200,7 +200,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -258,7 +258,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -321,7 +321,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -384,7 +384,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "0", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, diff --git a/.vortex/tests/bats/fixtures/docker-compose.env_mod.json b/.vortex/tests/bats/fixtures/docker-compose.env_mod.json index 10435556e..0107627d9 100644 --- a/.vortex/tests/bats/fixtures/docker-compose.env_mod.json +++ b/.vortex/tests/bats/fixtures/docker-compose.env_mod.json @@ -34,7 +34,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -93,7 +93,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -143,7 +143,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -200,7 +200,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -258,7 +258,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -321,7 +321,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, @@ -384,7 +384,7 @@ "DRUPAL_THEME": "your_site_theme", "DRUPAL_VALKEY_ENABLED": "1", "LAGOON_ROUTE": "the_matrix.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "the_matrix.docker.amazee.io", "XDEBUG_ENABLE": "1" }, diff --git a/.vortex/tests/bats/fixtures/docker-compose.noenv.json b/.vortex/tests/bats/fixtures/docker-compose.noenv.json index 135bf8263..5b9601212 100644 --- a/.vortex/tests/bats/fixtures/docker-compose.noenv.json +++ b/.vortex/tests/bats/fixtures/docker-compose.noenv.json @@ -34,7 +34,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -93,7 +93,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -143,7 +143,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -200,7 +200,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -258,7 +258,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -321,7 +321,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, @@ -384,7 +384,7 @@ "DRUPAL_THEME": "", "DRUPAL_VALKEY_ENABLED": "", "LAGOON_ROUTE": "star_wars.docker.amazee.io", - "TZ": "Australia/Melbourne", + "TZ": "UTC", "VORTEX_LOCALDEV_URL": "star_wars.docker.amazee.io", "XDEBUG_ENABLE": "" }, diff --git a/README.md b/README.md index 0f09e717f..24247a776 100644 --- a/README.md +++ b/README.md @@ -20,23 +20,32 @@ -Welcome to Vortex — a project template for Drupal designed to simplify onboarding and website maintenance. +**Vortex** is a Drupal project template designed to streamline onboarding, +accelerate development, and support long-term maintainability. -At [DrevOps®](https://www.drevops.com/), we carefully maintain this -template, keeping it aligned with the latest tools and validating it through -automated tests to ensure everything works together seamlessly. +It provides a complete foundation for building and deploying Drupal sites β€” +including containerized local environments, automated testing and code quality +tools, CI/CD pipeline configurations, and integrations with popular hosting +platforms. Everything is pre-configured and ready to use, so teams can focus on +building features instead of setting up infrastructure. -Our goal is to provide a consistent developer experience across projects, making -it easier to switch between them and get up to speed quickly. +By standardizing project structure and tooling, Vortex ensures a consistent +developer experience across every project that uses it. Whether you’re starting +fresh or joining an existing Vortex-based site, you can get up to speed quickly +and start contributing right away. -Track our current progress and view planned updates on [the GitHub project board](https://github.com/orgs/drevops/projects/2/views/1). +The template is actively maintained and kept in sync with the latest tools. +Every change is verified through automated tests to ensure updates remain stable +and reliable β€” reducing the risk of regressions and making it easier to maintain +projects over time. -> [!IMPORTANT] -> Vortex 2.0 is coming soon! Planned changes are captured in [this issue](https://github.com/drevops/vortex/issues/698). +Track our current progress and view planned updates on [the GitHub project board](https://github.com/orgs/drevops/projects/2/views/1). ## Installation -Our installer simplifies setup, letting you choose only the features you need. It will integrate the latest Vortex release into your codebase and you will choose which changes to commit. +Our installer simplifies setup, letting you choose only the features you need. +It will integrate the latest Vortex release into your codebase, and you will +choose which changes to commit. ```bash curl -SsL https://vortex.drevops.com/install > install.php && php install.php diff --git a/docker-compose.yml b/docker-compose.yml index 85bddb0c9..5a1a9d921 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ x-user: &default-user # Note that these variables are not read from here in Lagoon environment. #;> HOSTING_LAGOON x-environment: &default-environment - TZ: ${TZ:-Australia/Melbourne} + TZ: ${TZ:-UTC} # Pass-through 'CI' variable used to identify the CI environment. CI: ${CI:-} # Pass-through 'XDEBUG_ENABLE' to enable XDebug with "ahoy debug" or "XDEBUG_ENABLE=true docker compose up -d". diff --git a/renovate.json b/renovate.json index 3cc6f1c52..b22d5ce60 100644 --- a/renovate.json +++ b/renovate.json @@ -11,7 +11,7 @@ ":prHourlyLimit2" ], "rangeStrategy": "update-lockfile", - "timezone": "Australia/Melbourne", + "timezone": "UTC", "configMigration": true, "enabledManagers": [ "composer", diff --git a/scripts/vortex/login.sh b/scripts/vortex/login.sh index 6a3fd5a71..6728a2de8 100755 --- a/scripts/vortex/login.sh +++ b/scripts/vortex/login.sh @@ -9,7 +9,7 @@ t=$(mktemp) && export -p >"${t}" && set -a && . ./.env && if [ -f ./.env.local ] set -eu [ "${VORTEX_DEBUG-}" = "1" ] && set -x -# Flag to block or unblock admin. +# Flag to unblock admin. DRUPAL_UNBLOCK_ADMIN="${DRUPAL_UNBLOCK_ADMIN:-1}" # ------------------------------------------------------------------------------ diff --git a/tests/phpunit/Drupal/DatabaseSettingsTest.php b/tests/phpunit/Drupal/DatabaseSettingsTest.php index 7cef68873..afd22bff6 100644 --- a/tests/phpunit/Drupal/DatabaseSettingsTest.php +++ b/tests/phpunit/Drupal/DatabaseSettingsTest.php @@ -40,7 +40,7 @@ public static function dataProviderDatabases(): array { 'username' => 'drupal', 'password' => 'drupal', 'host' => 'localhost', - 'port' => '', + 'port' => '3306', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_general_ci', 'driver' => 'mysql', diff --git a/tests/phpunit/Drupal/EnvironmentSettingsTest.php b/tests/phpunit/Drupal/EnvironmentSettingsTest.php index 9d3736dbd..4e7f5356b 100644 --- a/tests/phpunit/Drupal/EnvironmentSettingsTest.php +++ b/tests/phpunit/Drupal/EnvironmentSettingsTest.php @@ -22,11 +22,11 @@ class EnvironmentSettingsTest extends SettingsTestCase { /** - * Test the resulting environment based on the provider's configuration. + * Test the detection of the resulting environment type. * - * @dataProvider dataProviderEnvironmentTypeResolution + * @dataProvider dataProviderEnvironmentTypeDetection */ - public function testEnvironmentTypeResolution(array $vars, string $expected_env): void { + public function testEnvironmentTypeDetection(array $vars, string $expected_env): void { $this->setEnvVars($vars); $this->requireSettingsFile(); @@ -35,9 +35,9 @@ public function testEnvironmentTypeResolution(array $vars, string $expected_env) } /** - * Data provider for testing of the resulting environment. + * Data provider for testing environment type detection. */ - public static function dataProviderEnvironmentTypeResolution(): array { + public static function dataProviderEnvironmentTypeDetection(): array { return [ // By default, the default environment type is local. [[], static::ENVIRONMENT_LOCAL], @@ -50,7 +50,15 @@ public static function dataProviderEnvironmentTypeResolution(): array { static::ENVIRONMENT_CI, ], - // #;< HOSTING_ACQUIA + // Container. + [ + [ + 'VORTEX_LOCALDEV_URL' => 'https://example-site.docker.amazee.io', + ], + static::ENVIRONMENT_LOCAL, + ], + + // #;< SETTINGS_PROVIDER_ACQUIA // Acquia. [ [ @@ -94,8 +102,9 @@ public static function dataProviderEnvironmentTypeResolution(): array { ], static::ENVIRONMENT_DEV, ], - // phpcs:ignore #;> HOSTING_ACQUIA - // phpcs:ignore #;< HOSTING_LAGOON + // phpcs:ignore #;> SETTINGS_PROVIDER_ACQUIA + + // phpcs:ignore #;< SETTINGS_PROVIDER_LAGOON // Lagoon. [ [ @@ -276,14 +285,14 @@ public static function dataProviderEnvironmentTypeResolution(): array { ], static::ENVIRONMENT_DEV, ], - // phpcs:ignore #;> HOSTING_LAGOON + // phpcs:ignore #;> SETTINGS_PROVIDER_LAGOON ]; } /** - * Test generic settings without any environment overrides. + * Test settings without any environment overrides. */ - public function testEnvironmentGeneric(): void { + public function testEnvironmentNoOverrides(): void { $this->setEnvVars([ 'DRUPAL_ENVIRONMENT' => static::ENVIRONMENT_SUT, ]); @@ -297,8 +306,6 @@ public function testEnvironmentGeneric(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -306,22 +313,101 @@ public function testEnvironmentGeneric(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', - '^nginx$', + '^localhost$', ]; $this->assertSettings($settings); } /** - * Test per-environment settings for LOCAL environment. + * Test environment variable overrides. + */ + public function testEnvironmentOverrides(): void { + $this->setEnvVars([ + 'DRUPAL_ENVIRONMENT' => static::ENVIRONMENT_SUT, + // Database configuration. + 'DATABASE_NAME' => 'custom_db', + 'DATABASE_USERNAME' => 'custom_user', + 'DATABASE_PASSWORD' => 'custom_pass', + 'DATABASE_HOST' => 'custom_host', + 'DATABASE_PORT' => '5432', + 'DATABASE_CHARSET' => 'utf8', + 'DATABASE_COLLATION' => 'utf8_general_ci', + // General Drupal settings. + 'DRUPAL_CONFIG_PATH' => 'custom_config', + 'DRUPAL_PUBLIC_FILES' => 'custom_public', + 'DRUPAL_PRIVATE_FILES' => 'custom_private', + 'DRUPAL_TEMPORARY_FILES' => 'custom_temp', + 'DRUPAL_HASH_SALT' => 'custom_hash_salt', + 'DRUPAL_TIMEZONE' => 'Australia/Melbourne', + 'DRUPAL_MAINTENANCE_THEME' => 'custom_theme', + // Performance settings. + 'DRUPAL_CACHE_PAGE_MAX_AGE' => '1800', + ]); + + $this->requireSettingsFile(); + + // Verify database settings. + $databases['default']['default']['database'] = 'custom_db'; + $databases['default']['default']['username'] = 'custom_user'; + $databases['default']['default']['password'] = 'custom_pass'; + $databases['default']['default']['host'] = 'custom_host'; + $databases['default']['default']['port'] = '5432'; + $databases['default']['default']['charset'] = 'utf8'; + $databases['default']['default']['collation'] = 'utf8_general_ci'; + $databases['default']['default']['driver'] = 'mysql'; + $databases['default']['default']['prefix'] = ''; + $this->assertEquals($databases, $this->databases); + + // Verify key config overrides. + $config['environment_indicator.indicator']['bg_color'] = '#006600'; + $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; + $config['environment_indicator.indicator']['name'] = static::ENVIRONMENT_SUT; + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = TRUE; + $config['system.performance']['cache']['page']['max_age'] = 1800; + $this->assertConfig($config); + + // Verify settings overrides. + $settings['config_sync_directory'] = 'custom_config'; + $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = 'custom_public'; + $settings['file_private_path'] = 'custom_private'; + $settings['file_temp_path'] = 'custom_temp'; + + $settings['config_exclude_modules'] = []; + $settings['config_sync_directory'] = static::CONFIG_PATH_TESTING; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_SUT; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; + $settings['hash_salt'] = 'custom_hash_salt'; + $settings['maintenance_theme'] = 'custom_theme'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; + + $this->assertSettings($settings); + } + + /** + * Test per-environment settings for Local environment. */ public function testEnvironmentLocal(): void { $this->setEnvVars([ @@ -340,8 +426,6 @@ public function testEnvironmentLocal(): void { $config['shield.settings']['shield_enable'] = FALSE; $config['system.logging']['error_level'] = 'all'; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $this->assertConfig($config); @@ -351,25 +435,76 @@ public function testEnvironmentLocal(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_LOCAL; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; + $settings['skip_permissions_hardening'] = TRUE; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; + $this->assertSettings($settings); + } + + // phpcs:ignore #;< SETTINGS_PROVIDER_CONTAINER + /** + * Test per-environment settings for Local with container provider. + */ + public function testEnvironmentLocalContainer(): void { + $this->setEnvVars([ + 'VORTEX_LOCALDEV_URL' => 'https://example-site.docker.amazee.io', + ]); + + $this->requireSettingsFile(); + + $config['automated_cron.settings']['interval'] = 0; + $config['config_split.config_split.local']['status'] = TRUE; + $config['environment_indicator.indicator']['bg_color'] = '#006600'; + $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; + $config['environment_indicator.indicator']['name'] = static::ENVIRONMENT_LOCAL; + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = FALSE; + $config['system.logging']['error_level'] = 'all'; + $config['system.performance']['cache']['page']['max_age'] = 900; + $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; + $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; + $settings['config_sync_directory'] = static::CONFIG_PATH_TESTING; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_LOCAL; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', + '^localhost$', + '^example-site\.docker\.amazee\.io$', '^nginx$', ]; $this->assertSettings($settings); } + // phpcs:ignore #;> SETTINGS_PROVIDER_CONTAINER + // phpcs:ignore #;< SETTINGS_PROVIDER_CIRCLECI /** - * Test per-environment settings for CI environment. + * Test per-environment settings for CircleCI. */ - public function testEnvironmentCi(): void { + public function testEnvironmentCircleCi(): void { $this->setEnvVars([ 'CI' => TRUE, ]); @@ -385,8 +520,6 @@ public function testEnvironmentCi(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = FALSE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; $this->assertConfig($config); @@ -396,23 +529,72 @@ public function testEnvironmentCi(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_CI; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; + $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; + $settings['skip_permissions_hardening'] = TRUE; + $settings['suspend_mail_send'] = TRUE; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; + $this->assertSettings($settings); + } + // phpcs:ignore #;> SETTINGS_PROVIDER_CIRCLECI + + // phpcs:ignore #;< SETTINGS_PROVIDER_GHA + /** + * Test per-environment settings for GitHub Actions. + */ + public function testEnvironmentGha(): void { + $this->setEnvVars([ + 'CI' => TRUE, + ]); + + $this->requireSettingsFile(); + + $config['automated_cron.settings']['interval'] = 0; + $config['config_split.config_split.ci']['status'] = TRUE; + $config['environment_indicator.indicator']['bg_color'] = '#006600'; + $config['environment_indicator.indicator']['fg_color'] = '#ffffff'; + $config['environment_indicator.indicator']['name'] = static::ENVIRONMENT_CI; + $config['environment_indicator.settings']['favicon'] = TRUE; + $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; + $config['shield.settings']['shield_enable'] = FALSE; + $config['system.performance']['cache']['page']['max_age'] = 900; + $config['seckit.settings']['seckit_xss']['csp']['checkbox'] = FALSE; + $config['seckit.settings']['seckit_xss']['csp']['upgrade-req'] = FALSE; + $this->assertConfig($config); + + $settings['config_exclude_modules'] = []; + $settings['config_sync_directory'] = static::CONFIG_PATH_TESTING; + $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; + $settings['entity_update_batch_size'] = 50; + $settings['environment'] = static::ENVIRONMENT_CI; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; + $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; $settings['file_temp_path'] = static::TMP_PATH_TESTING; + $settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', + ]; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['skip_permissions_hardening'] = TRUE; $settings['suspend_mail_send'] = TRUE; $settings['trusted_host_patterns'] = [ - '^.+\.docker\.amazee\.io$', - '^nginx$', + '^localhost$', ]; $this->assertSettings($settings); } + // phpcs:ignore #;> SETTINGS_PROVIDER_GHA - // phpcs:ignore #;< HOSTING_ACQUIA + // phpcs:ignore #;< SETTINGS_PROVIDER_ACQUIA /** * Test per-environment settings for dynamic environment. */ @@ -432,8 +614,6 @@ public function testEnvironmentAcquiaDynamic(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -441,15 +621,18 @@ public function testEnvironmentAcquiaDynamic(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_DEV; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; + $settings['maintenance_theme'] = 'claro'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; $this->assertSettings($settings); } @@ -472,8 +655,6 @@ public function testEnvironmentAcquiaDev(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -481,15 +662,18 @@ public function testEnvironmentAcquiaDev(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_DEV; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; + $settings['maintenance_theme'] = 'claro'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; $this->assertSettings($settings); } @@ -512,8 +696,6 @@ public function testEnvironmentAcquiaStage(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -521,15 +703,18 @@ public function testEnvironmentAcquiaStage(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_STAGE; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; + $settings['maintenance_theme'] = 'claro'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; $this->assertSettings($settings); } @@ -550,8 +735,8 @@ public function testEnvironmentAcquiaProd(): void { $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; + $config['system.performance']['css']['preprocess'] = TRUE; + $config['system.performance']['js']['preprocess'] = TRUE; $this->assertConfig($config); $settings['config_exclude_modules'] = []; @@ -559,23 +744,26 @@ public function testEnvironmentAcquiaProd(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_PROD; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; + $settings['maintenance_theme'] = 'claro'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + ]; $this->assertSettings($settings); } - // phpcs:ignore #;> HOSTING_ACQUIA - // phpcs:ignore #;< HOSTING_LAGOON + // phpcs:ignore #;> SETTINGS_PROVIDER_ACQUIA + // phpcs:ignore #;< SETTINGS_PROVIDER_LAGOON /** - * Test per-environment settings for dynamic environment. + * Test per-environment settings for preview environment. */ - public function testEnvironmentLagoonDynamic(): void { + public function testEnvironmentLagoonPreview(): void { $this->setEnvVars([ 'LAGOON_KUBERNETES' => 1, 'LAGOON_ENVIRONMENT_TYPE' => 'development', @@ -595,8 +783,6 @@ public function testEnvironmentLagoonDynamic(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['cache_prefix']['default'] = 'test_project_test_branch'; @@ -605,20 +791,23 @@ public function testEnvironmentLagoonDynamic(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_DEV; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; - $settings['trusted_host_patterns'][] = '^nginx\-php$'; - $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + '^nginx\-php$', + '^.+\.au\.amazee\.io$', + '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } @@ -645,8 +834,6 @@ public function testEnvironmentLagoonDev(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['cache_prefix']['default'] = 'test_project_develop'; @@ -655,20 +842,23 @@ public function testEnvironmentLagoonDev(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_DEV; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; - $settings['trusted_host_patterns'][] = '^nginx\-php$'; - $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + '^nginx\-php$', + '^.+\.au\.amazee\.io$', + '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } @@ -695,8 +885,6 @@ public function testEnvironmentLagoonTest(): void { $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['shield.settings']['shield_enable'] = TRUE; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; $this->assertConfig($config); $settings['cache_prefix']['default'] = 'test_project_master'; @@ -705,20 +893,23 @@ public function testEnvironmentLagoonTest(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_STAGE; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; - $settings['trusted_host_patterns'][] = '^nginx\-php$'; - $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + '^nginx\-php$', + '^.+\.au\.amazee\.io$', + '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } @@ -744,8 +935,8 @@ public function testEnvironmentLagoonProd(): void { $config['environment_indicator.settings']['favicon'] = TRUE; $config['environment_indicator.settings']['toolbar_integration'] = [TRUE]; $config['system.performance']['cache']['page']['max_age'] = 900; - $config['system.performance']['css']['preprocess'] = 1; - $config['system.performance']['js']['preprocess'] = 1; + $config['system.performance']['css']['preprocess'] = TRUE; + $config['system.performance']['js']['preprocess'] = TRUE; $this->assertConfig($config); $settings['cache_prefix']['default'] = 'test_project_production'; @@ -754,22 +945,25 @@ public function testEnvironmentLagoonProd(): void { $settings['container_yamls'][0] = $this->app_root . '/' . $this->site_path . '/services.yml'; $settings['entity_update_batch_size'] = 50; $settings['environment'] = static::ENVIRONMENT_PROD; + $settings['file_public_path'] = static::PUBLIC_PATH_TESTING; $settings['file_private_path'] = static::PRIVATE_PATH_TESTING; + $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['file_scan_ignore_directories'] = [ 'node_modules', 'bower_components', ]; - $settings['file_temp_path'] = static::TMP_PATH_TESTING; $settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); + $settings['maintenance_theme'] = 'claro'; $settings['reverse_proxy'] = TRUE; $settings['reverse_proxy_header'] = 'HTTP_TRUE_CLIENT_IP'; - $settings['trusted_host_patterns'][] = '^.+\.docker\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^nginx$'; - $settings['trusted_host_patterns'][] = '^nginx\-php$'; - $settings['trusted_host_patterns'][] = '^.+\.au\.amazee\.io$'; - $settings['trusted_host_patterns'][] = '^example1\.com|example2/com$'; + $settings['trusted_host_patterns'] = [ + '^localhost$', + '^nginx\-php$', + '^.+\.au\.amazee\.io$', + '^example1\.com|example2/com$', + ]; $this->assertSettings($settings); } - // phpcs:ignore #;> HOSTING_LAGOON + // phpcs:ignore #;> SETTINGS_PROVIDER_LAGOON } diff --git a/tests/phpunit/Drupal/SettingsTestCase.php b/tests/phpunit/Drupal/SettingsTestCase.php index 97e35bc75..fa577ea9a 100644 --- a/tests/phpunit/Drupal/SettingsTestCase.php +++ b/tests/phpunit/Drupal/SettingsTestCase.php @@ -34,11 +34,6 @@ abstract class SettingsTestCase extends TestCase { */ final const ENVIRONMENT_CI = 'ci'; - /** - * Defines a constant for the name of the 'prod' environment. - */ - final const ENVIRONMENT_PROD = 'prod'; - /** * Defines a constant for the name of the 'stage' environment. */ @@ -50,20 +45,52 @@ abstract class SettingsTestCase extends TestCase { final const ENVIRONMENT_DEV = 'dev'; /** - * Defines a constant for the temp path used in testing. + * Defines a constant for the name of the 'prod' environment. */ - final const TMP_PATH_TESTING = '/tmp-test'; + final const ENVIRONMENT_PROD = 'prod'; + + /** + * Defines a constant for the public path used in testing. + */ + final const PUBLIC_PATH_TESTING = '/public-test'; /** * Defines a constant for the private path used in testing. */ final const PRIVATE_PATH_TESTING = '/private-test'; + /** + * Defines a constant for the temp path used in testing. + */ + final const TMP_PATH_TESTING = '/tmp-test'; + /** * Defines a constant for the config directory used in testing. */ final const CONFIG_PATH_TESTING = '/config-test'; + /** + * Defines a constant for the allowed environment variables. + * + * These variables are used to filter the environment variables that are set + * during the test setup. This is to ensure that only relevant variables are + * set and to avoid conflicts with other environment variables. + * + * Consumer sites should update this list if they need to add additional + * environment variables that are not part of the default set. + */ + const ALLOWED_ENV_VARS = [ + // Service variables. + 'DATABASE_', + 'VALKEY_', + 'COMPOSE_', + 'GITHUB_', + 'DOCKER_', + // Vortex and Drupal variables. + 'VORTEX_', + 'DRUPAL_', + ]; + /** * Application root. * @@ -133,21 +160,12 @@ protected function setEnvVars(array $vars): void { } $vars['DRUPAL_CONFIG_PATH'] = static::CONFIG_PATH_TESTING; - $vars['DRUPAL_TEMPORARY_FILES'] = static::TMP_PATH_TESTING; + $vars['DRUPAL_PUBLIC_FILES'] = static::PUBLIC_PATH_TESTING; $vars['DRUPAL_PRIVATE_FILES'] = static::PRIVATE_PATH_TESTING; + $vars['DRUPAL_TEMPORARY_FILES'] = static::TMP_PATH_TESTING; // Filtered real vars without a value to unset them in the lines below. - $vars_real = self::getRealEnvVarsFilteredNoValues([ - // Service variables. - 'DATABASE_', - 'VALKEY_', - 'COMPOSE_', - 'GITHUB_', - 'DOCKER_', - // Vortex and Drupal variables. - 'VORTEX_', - 'DRUPAL_', - ]); + $vars_real = self::getRealEnvVarsFilteredNoValues(static::ALLOWED_ENV_VARS); // Passed vars + existing vars + filtered real vars. $this->envVars = $vars + $this->envVars + $vars_real; diff --git a/tests/phpunit/Drupal/SwitchableSettingsTest.php b/tests/phpunit/Drupal/SwitchableSettingsTest.php index 461446a0b..91a998a14 100644 --- a/tests/phpunit/Drupal/SwitchableSettingsTest.php +++ b/tests/phpunit/Drupal/SwitchableSettingsTest.php @@ -182,7 +182,7 @@ public function testEnvironmentIndicator(string $env, array $expected_present, a } /** - * Data provider for testEntityPrint(). + * Data provider for testEnvironmentIndicator(). */ public static function dataProviderEnvironmentIndicator(): array { return [ @@ -644,64 +644,4 @@ public static function dataProviderStageFileProxy(): array { ]; } - /** - * Test maintenance theme configuration. - * - * @dataProvider dataProviderMaintenanceTheme - */ - public function testMaintenanceTheme(array $vars, array $expected_present, array $expected_absent = []): void { - $this->setEnvVars($vars); - - $this->requireSettingsFile(); - - $this->assertConfigContains($expected_present); - $this->assertConfigNotContains($expected_absent); - } - - /** - * Data provider for testMaintenanceTheme(). - */ - public static function dataProviderMaintenanceTheme(): array { - return [ - // DRUPAL_MAINTENANCE_THEME set - should use it. - [ - [ - 'DRUPAL_MAINTENANCE_THEME' => 'custom_maintenance_theme', - ], - [ - 'maintenance_theme' => 'custom_maintenance_theme', - ], - ], - // DRUPAL_MAINTENANCE_THEME not set, DRUPAL_THEME set - should fall - // back to DRUPAL_THEME. - [ - [ - 'DRUPAL_THEME' => 'default_theme', - ], - [ - 'maintenance_theme' => 'default_theme', - ], - ], - // Both DRUPAL_MAINTENANCE_THEME and DRUPAL_THEME set - should prefer - // DRUPAL_MAINTENANCE_THEME. - [ - [ - 'DRUPAL_MAINTENANCE_THEME' => 'custom_maintenance_theme', - 'DRUPAL_THEME' => 'default_theme', - ], - [ - 'maintenance_theme' => 'custom_maintenance_theme', - ], - ], - // Neither set - no maintenance_theme config should be present. - [ - [], - [], - [ - 'maintenance_theme' => NULL, - ], - ], - ]; - } - } diff --git a/web/sites/default/includes/modules/settings.automated_cron.php b/web/sites/default/includes/modules/settings.automated_cron.php new file mode 100644 index 000000000..ef3fdd5ae --- /dev/null +++ b/web/sites/default/includes/modules/settings.automated_cron.php @@ -0,0 +1,13 @@ + + [ + 'default' => + [ + 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', + 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', + 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', + 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', + 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '3306', + 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', + 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', + 'prefix' => '', + 'driver' => 'mysql', + ], + ], +]; //////////////////////////////////////////////////////////////////////////////// -/// SITE-SPECIFIC SETTINGS /// +/// GENERAL /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#general $app_root = $app_root ?? DRUPAL_ROOT; $site_path = $site_path ?? 'sites/default'; @@ -61,21 +60,39 @@ // Location of the site configuration files. $settings['config_sync_directory'] = getenv('DRUPAL_CONFIG_PATH') ?: '../config/default'; +// Location of the public files directory. +$settings['file_public_path'] = getenv('DRUPAL_PUBLIC_FILES') ?: 'sites/default/files'; + // Private directory. $settings['file_private_path'] = getenv('DRUPAL_PRIVATE_FILES') ?: 'sites/default/files/private'; // Temporary directory. $settings['file_temp_path'] = getenv('DRUPAL_TEMPORARY_FILES') ?: '/tmp'; -// Base salt on the DB host name. -$settings['hash_salt'] = hash('sha256', getenv('DATABASE_HOST') ?: 'localhost'); +// Salt is taken from DRUPAL_HASH_SALT or the database host name. +$settings['hash_salt'] = getenv('DRUPAL_HASH_SALT') ?: hash('sha256', $databases['default']['default']['host']); + +// Timezone settings. +ini_set('date.timezone', getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); +date_default_timezone_set(getenv('DRUPAL_TIMEZONE') ?: getenv('TZ') ?: 'UTC'); + +// Maintenance theme. +$settings['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME') ?: getenv('DRUPAL_THEME') ?: 'claro'; -// Expiration of cached pages. -$config['system.performance']['cache']['page']['max_age'] = 900; +// Trusted Host Patterns. +// See https://www.drupal.org/node/2410395 for more information on how to +// populate this array. +// Settings for specific environments (including a local container-based +// environment) are populated within provider-specific +// `includes/providers/settings..php` files. +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides +$settings['trusted_host_patterns'] = [ + '^localhost$', +]; -// Aggregate CSS and JS files. -$config['system.performance']['css']['preprocess'] = TRUE; -$config['system.performance']['js']['preprocess'] = TRUE; +// Modules excluded from config export. +// Populate this array in the `includes/modules/settings..php` file. +$settings['config_exclude_modules'] = []; // The default list of directories that will be ignored by Drupal's file API. $settings['file_scan_ignore_directories'] = [ @@ -86,56 +103,35 @@ // The default number of entities to update in a batch process. $settings['entity_update_batch_size'] = 50; -// Trusted Host Patterns. -// Settings for other environments are included below. -// If your site runs on multiple domains, you need to add these domains here. -// escape dots, remove schema, use commas as regex separator. -// See https://www.drupal.org/node/2410395 for more information. -$settings['trusted_host_patterns'] = [ - // Local URL. - '^.+\.docker\.amazee\.io$', - // URL when accessed from Behat tests. - '^nginx$', -]; - -// Modules excluded from config export. -$settings['config_exclude_modules'] = []; - -ini_set('date.timezone', 'Australia/Melbourne'); -date_default_timezone_set('Australia/Melbourne'); +//////////////////////////////////////////////////////////////////////////////// +/// ENVIRONMENT TYPE DETECTION /// +//////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#environment-type-detection -// Maintenance theme. -if (getenv('DRUPAL_MAINTENANCE_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_MAINTENANCE_THEME'); +// Use these constants anywhere in code to alter behavior for a specific +// environment. +// @codeCoverageIgnoreStart +if (!defined('ENVIRONMENT_LOCAL')) { + define('ENVIRONMENT_LOCAL', 'local'); } -elseif (getenv('DRUPAL_THEME')) { - $config['maintenance_theme'] = getenv('DRUPAL_THEME'); +if (!defined('ENVIRONMENT_CI')) { + define('ENVIRONMENT_CI', 'ci'); } +if (!defined('ENVIRONMENT_DEV')) { + define('ENVIRONMENT_DEV', 'dev'); +} +if (!defined('ENVIRONMENT_STAGE')) { + define('ENVIRONMENT_STAGE', 'stage'); +} +if (!defined('ENVIRONMENT_PROD')) { + define('ENVIRONMENT_PROD', 'prod'); +} +// @codeCoverageIgnoreEnd -// Default database configuration. -$databases = [ - 'default' => - [ - 'default' => - [ - 'database' => getenv('DATABASE_NAME') ?: getenv('DATABASE_DATABASE') ?: getenv('MARIADB_DATABASE') ?: 'drupal', - 'username' => getenv('DATABASE_USERNAME') ?: getenv('MARIADB_USERNAME') ?: 'drupal', - 'password' => getenv('DATABASE_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: 'drupal', - 'host' => getenv('DATABASE_HOST') ?: getenv('MARIADB_HOST') ?: 'localhost', - 'port' => getenv('DATABASE_PORT') ?: getenv('MARIADB_PORT') ?: '', - 'charset' => getenv('DATABASE_CHARSET') ?: getenv('MARIADB_CHARSET') ?: getenv('MYSQL_CHARSET') ?: 'utf8mb4', - 'collation' => getenv('DATABASE_COLLATION') ?: getenv('MARIADB_COLLATION') ?: getenv('MYSQL_COLLATION') ?: 'utf8mb4_general_ci', - 'prefix' => '', - 'driver' => 'mysql', - ], - ], -]; - -//////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT TYPE DETECTION /// -//////////////////////////////////////////////////////////////////////////////// +// Default environment type is 'local'. +$settings['environment'] = ENVIRONMENT_LOCAL; -// Load provider-specific settings. +// Load provider-specific environment detection settings. if (file_exists($app_root . '/' . $site_path . '/includes/providers')) { $files = glob($app_root . '/' . $site_path . '/includes/providers/settings.*.php'); if ($files) { @@ -145,40 +141,15 @@ } } -// Allow overriding of an environment type. +// Allow to override an environment type using the DRUPAL_ENVIRONMENT variable. if (!empty(getenv('DRUPAL_ENVIRONMENT'))) { $settings['environment'] = getenv('DRUPAL_ENVIRONMENT'); } //////////////////////////////////////////////////////////////////////////////// -/// ENVIRONMENT-SPECIFIC SETTINGS /// -//////////////////////////////////////////////////////////////////////////////// - -if ($settings['environment'] == ENVIRONMENT_CI) { - // Never harden permissions on sites/default/files. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Disable mail send out. - $settings['suspend_mail_send'] = TRUE; -} - -if ($settings['environment'] == ENVIRONMENT_LOCAL) { - // Never harden permissions on sites/default/files during local development. - $settings['skip_permissions_hardening'] = TRUE; - - // Disable built-in cron trigger. - $config['automated_cron.settings']['interval'] = 0; - - // Show all error messages on the site. - $config['system.logging']['error_level'] = 'all'; -} - -//////////////////////////////////////////////////////////////////////////////// -/// PER-MODULE SETTINGS /// +/// PER-MODULE OVERRIDES /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#per-module-overrides if (file_exists($app_root . '/' . $site_path . '/includes/modules')) { $files = glob($app_root . '/' . $site_path . '/includes/modules/settings.*.php'); @@ -190,14 +161,17 @@ } //////////////////////////////////////////////////////////////////////////////// -/// LOCAL SETTINGS /// +/// LOCAL OVERRIDE /// //////////////////////////////////////////////////////////////////////////////// +// @see https://vortex.drevops.com/drupal/settings#local-overrides -// Load local development override configuration, if available. +// Load local override configuration, if available. +// +// Copy `default.settings.local.php` and `default.services.local.yml` to +// `settings.local.php` and `services.local.yml` respectively to enable local +// overrides. // -// Copy default.settings.local.php and default.services.local.yml to -// settings.local.php and services.local.yml respectively. -// services.local.yml is loaded in in settings.local.php. +// `services.local.yml` is loaded from within `settings.local.php`. // // Keep this code block at the end of this file to take full effect. // @codeCoverageIgnoreStart diff --git a/web/themes/custom/your_site_theme/js/your_site_theme.js b/web/themes/custom/your_site_theme/js/your_site_theme.js index 8ac6e4b1c..ed5a779da 100644 --- a/web/themes/custom/your_site_theme/js/your_site_theme.js +++ b/web/themes/custom/your_site_theme/js/your_site_theme.js @@ -1,6 +1,6 @@ /** * @file - * Global theme behaviours. + * Global theme behaviors. */ (function ($, Drupal) {