ci/README.md
This directory houses the configuration for automated tests across multiple version and setup configurations of OpenEMR. It is used by the GitHub Actions workflow in .github/workflows/test.yml to run various tests.
The subdirectories that contain docker-compose.yml files contain different configurations. The name of the directory lets you know the webserver, PHP version, and expected database versions. The naming convention follows this pattern:
{webserver}_{phpversion}[_{dbversion}]
For example, apache_83_116 means:
While the directory names indicate the configuration, the actual docker-compose.yml files determine what's run. If a directory ends with _no-e2e, then the end-to-end (E2E) tests will be skipped for that configuration.
All of the tests use the same source script: ciLibrary.source. That script sets up the environment, optionally including code coverage setup, and then provides shell functions that can be used to run each test suite.
The GitHub Actions workflow dynamically builds a test matrix based on the directories in this folder. For each directory containing a docker-compose.yml file:
docker-compose.yml to determine the exact database image.This allows testing OpenEMR across multiple environments automatically without having to manually update the GitHub workflow file.
The CI runs several different test suites sequentially:
Code coverage reporting is enabled only for the apache_84_114 configuration. When enabled, it:
To add a new test configuration:
webserver_phpversion_dbversion.docker-compose.yml file with the appropriate MySQL/MariaDB and OpenEMR services (see below Adding a New Configuration section).mysql for compatibility with the test scripts._no-e2e suffix to the directory name.The CI process uses several important environment variables:
DOCKER_DIR: The directory containing the Docker Compose configurationENABLE_COVERAGE: Whether to enable code coverage reporting (true/false)OPENEMR_DIR: The directory containing OpenEMR inside the Docker containerCOMPOSE_FILE: The Docker Compose COMPOSE_FILE environment variable is set to store the templates for the multi-file composition. The first file is the template for the web server configuration (Apache or Nginx). The second file is the template for the database configuration (MariaDB or MySQL). The third file is the template for the PHP version and MariaDB/MySQL version.The CI system uses Docker Compose's multi-file composition (otherwise known as compose file merging) to maintain DRY (Don't Repeat Yourself) configuration across multiple test environments. This is implemented through shared base configurations that individual test environments use.
Shared Configuration Files:
compose-shared-selenium/docker-compose.yml: Contains the Selenium Grid configuration for running E2E tests. It is always included.compose-shared-apache.yml: Contains the base configuration for Apache-based setups with database specific items not included.compose-shared-nginx.yml: Contains the base configuration for Nginx-based setups with database specific items not included.compose-shared-mariadb.yml: Contains MariaDB specific items.compose-shared-mysql.yml: Contains MySQL specific items.Individual Test Environment Setup:
Each test directory (e.g., apache_83_116) has its own docker-compose.yml that:
docker-compose.yml Pattern:
# Note these x-includes are not actually seen or used by Docker Compose and are instead utilized by scripting to build the
# multi-file composition command line commands.
x-includes:
selenium-template: "compose-shared-selenium/docker-compose.yml" # Show the Selenium Grid template
webserver-template: "compose-shared-apache.yml" # Show the web server template (Apache or Nginx)
database-template: "compose-shared-mariadb.yml" # Show the database template (MariaDB or MySQL)
services:
mysql:
image: mariadb:11.4 # Specify MariaDB/MySQL version
openemr:
image: openemr/openemr:flex-3.21 # Specify PHP version
To add a new test configuration:
Decide if your new environment needs Apache or Nginx:
compose-shared-apache.ymlcompose-shared-nginx.ymlDecide if your new environment needs MariaDB or MySQL:
compose-shared-mariadb.ymlcompose-shared-mysql.ymlCreate a new directory following the naming convention:
{webserver}_{phpversion}[_{dbversion}][_no-e2e]
Create a docker-compose.yml file in the new directory:
For Apache environments with MariaDB:
# Note these x-includes are not actually seen or used by Docker Compose and are instead utilized by scripting to build the
# multi-file composition command line commands.
x-includes:
selenium-template: "compose-shared-selenium/docker-compose.yml" # Show the Selenium Grid template
webserver-template: "compose-shared-apache.yml" # Show the Apache web server template
database-template: "compose-shared-mariadb.yml" # Show the MariaDB database template
services:
mysql:
image: mariadb:<version> # Specify MariaDB version
openemr:
image: openemr/openemr:<tag> # Specify PHP version
For Apache environments with MySQL:
# Note these x-includes are not actually seen or used by Docker Compose and are instead utilized by scripting to build the
# multi-file composition command line commands.
x-includes:
selenium-template: "compose-shared-selenium/docker-compose.yml" # Show the Selenium Grid template
webserver-template: "compose-shared-apache.yml" # Show the Apache web server template
database-template: "compose-shared-mysql.yml" # Show the MySQL database template
services:
mysql:
image: mysql:<version> # Specify MySQL version
openemr:
image: openemr/openemr:<tag> # Specify PHP version
For Nginx environments with MariaDB:
# Note these x-includes are not actually seen or used by Docker Compose and are instead utilized by scripting to build the
# multi-file composition command line commands.
x-includes:
selenium-template: "compose-shared-selenium/docker-compose.yml" # Show the Selenium Grid template
webserver-template: "compose-shared-nginx.yml" # Show the Nginx web server template
database-template: "compose-shared-mariadb.yml" # Show the MariaDB database template
services:
mysql:
image: mariadb:<version> # Specify MariaDB version
openemr:
image: openemr/dev-php-fpm:<php-version> # Specify PHP version
For Nginx environments with MySQL:
# Note these x-includes are not actually seen or used by Docker Compose and are instead utilized by scripting to build the
# multi-file composition command line commands.
x-includes:
selenium-template: "compose-shared-selenium/docker-compose.yml" # Show the Selenium Grid template
webserver-template: "compose-shared-nginx.yml" # Show the Nginx web server template
database-template: "compose-shared-mysql.yml" # Show the MySQL database template
services:
mysql:
image: mysql:<version> # Specify MySQL version
openemr:
image: openemr/dev-php-fpm:<php-version> # Specify PHP version
Customize any additional settings specific to your configuration as needed.
When updating the shared configuration files:
compose-shared-selenium/docker-compose.yml, ```compose-shared-apache.yml, compose-shared-nginx.yml, compose-shared-mariadb.yml, and compose-shared-mysql.yml` will affect all test environments that use themIf tests are failing in CI but passing locally, check:
-For below commands:
apache_84_114 with the configuration directory you want to test.compose-shared-apache.yml and compose-shared-mariadb.yml with the x-includes values that are included in the main docker-compose.yml file.You can view the fully merged configuration file with the following config command:
docker compose -f "ci/compose-shared-apache.yml" -f "ci/compose-shared-mariadb.yml" -f "ci/compose-shared-selenium/docker-compose.yml" -f "ci/apache_84_114/docker-compose.yml" config
You can also run the same Docker Compose setup locally:
docker compose -f "ci/compose-shared-apache.yml" -f "ci/compose-shared-mariadb.yml" -f "ci/compose-shared-selenium/docker-compose.yml" -f "ci/apache_84_114/docker-compose.yml" up -d
You can go directly into the OpenEMR testing container:
docker compose -f "ci/compose-shared-apache.yml" -f "ci/compose-shared-mariadb.yml" -f "ci/compose-shared-selenium/docker-compose.yml" -f "ci/apache_84_114/docker-compose.yml" exec -it openemr sh
You can shut down the Docker Compose setup:
docker compose -f "ci/compose-shared-apache.yml" -f "ci/compose-shared-mariadb.yml" -f "ci/compose-shared-selenium/docker-compose.yml" -f "ci/apache_84_114/docker-compose.yml" down -v