Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# OpenEMR Docker Testing

## Workflow: Production Docker Test (test-prod.yml)

The `test-prod.yml` workflow verifies that the production OpenEMR Docker images can be built correctly and function with a database connection. These images have the OpenEMR code embedded within them and are identified by version numbers (e.g., 7.0.4).

The workflow performs the following steps:

1. Builds OpenEMR Docker images defined in docker/openemr for numbered versions (e.g., 6.1.0, 7.0.4)
2. Sets up a test environment using Docker Compose with:
- MariaDB 11.4 database
- OpenEMR container connected to the database
3. Verifies that the web server is responding correctly
4. Runs the OpenEMR installation process
5. Executes multiple test suites including unit, fixtures, services, validators, and controllers tests

### Triggers for Production Tests

The workflow runs automatically when:
- Files in the `docker/openemr/[0-9]*.[0-9]*.[0-9]/**` directory are changed on the main branch
- A pull request targeting the main branch changes files in the numbered version directories

## Workflow: Flex Docker Test (test-flex.yml)

The `test-flex.yml` workflow tests the development-oriented "flex" Docker images. Unlike production images, flex builds don't embed the OpenEMR code within the image - they're designed for development purposes where the code is mounted separately.

The workflow performs the following steps:

1. Checks out both the openemr-devops repository and the OpenEMR code repository
2. Builds the flex Docker images defined in docker/openemr
3. Sets up a test environment using Docker Compose with:
- MariaDB database
- OpenEMR container with mounted code
4. Verifies that the web server is responding correctly

### Triggers for Flex Tests

The workflow runs automatically when:
- Files in the `docker/openemr/**` directory are changed on the main branch
- A pull request targeting the main branch changes files in the docker/openemr directory
22 changes: 12 additions & 10 deletions .github/workflows/shellcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ on:
branches:
- master
# GitHub Actions do not support YAML anchors
# There are four places in here we must keep
# the paths in sync.
# There are five places in here we must keep
# the paths in sync and the exclusion logic.
paths:
- '**.sh'
# Include all shell scripts except those in docker/openemr/obsolete/
- '{!docker/openemr/obsolete/,}**.sh'
- '.github/workflows/shellcheck.yml'
- 'docker/openemr/flex-*/utilities/devtools'
- 'kubernetes/kub-down'
Expand All @@ -22,7 +23,8 @@ on:
branches:
- master
paths:
- '**.sh'
# Include all shell scripts except those in docker/openemr/obsolete/
- '{!docker/openemr/obsolete/,}**.sh'
- '.github/workflows/shellcheck.yml'
- 'docker/openemr/flex-*/utilities/devtools'
- 'kubernetes/kub-down'
Expand Down Expand Up @@ -57,6 +59,7 @@ jobs:
# See https://github.com/tj-actions/changed-files/blob/v46/README.md#inputs-%EF%B8%8F
# for tj-actions/changed-files specific syntax
files: |
!docker/openemr/obsolete/**
**.sh
docker/openemr/flex-*/utilities/devtools
kubernetes/kub-down
Expand Down Expand Up @@ -108,6 +111,8 @@ jobs:
# Process each changed file
for file in "${files_to_check[@]}"; do
[[ -f "$file" ]] || continue
# Skip files in the obsolete directory
[[ "$file" = docker/openemr/obsolete/* ]] && continue
# Get hash of file content
hash=$(sha256sum "$file" | cut -d ' ' -f 1)
# Check if we've seen this hash before
Expand All @@ -120,19 +125,16 @@ jobs:
# This relies on one space between each path name.
echo "files=${unique_files[*]}" >> "$GITHUB_OUTPUT"
- name: Run shellcheck on unique files
if: ${{ steps.unique-files.outputs.files != '' }}
run: |
if [[ -z "${{ steps.unique-files.outputs.files }}" ]]; then
echo "No shell files to check."
exit 0
fi
shellcheck --check-sourced --external-sources --format=checkstyle ${{ steps.unique-files.outputs.files }} | tee checkstyle-shellcheck.xml
- uses: staabm/annotate-pull-request-from-checkstyle-action@v1
if: always()
if: ${{ failure() && hashFiles('checkstyle-shellcheck.xml') != '' }}
with:
files: checkstyle-shellcheck.xml
notices-as-warnings: true
- name: Upload shellcheck results
if: always()
if: ${{ failure() && hashFiles('checkstyle-shellcheck.xml') != '' }}
uses: actions/upload-artifact@v4
with:
name: shellcheck-results
Expand Down
147 changes: 147 additions & 0 deletions .github/workflows/test-flex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
name: OpenEMR Docker Flex Build Test

on:
push:
branches:
- master
paths:
- '.github/workflows/test-flex.yml'
- 'docker/openemr/flex-[0-9]*.[0-9]*/**'
pull_request:
branches:
- master
paths:
- '.github/workflows/test-flex.yml'
- 'docker/openemr/flex-[0-9]*.[0-9]*/**'

env:
COMPOSE_BAKE: "1"
COMPOSE_PROFILES: flex
DOCKER_BUILDKIT: "1"
OPENEMR_SERVICE_NAME: openemr-flex

jobs:
build-and-test:
name: Test OpenEMR Image
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker-dir:
- container: flex-3.15-8
branch: rel-701
# - container: flex-3.17
# branch: rel-702
# - container: flex-3.18
# branch: rel-702
# - container: flex-3.20
# branch: rel-703
# - container: flex-3.21
# branch: rel-703
# - container: flex-edge
# branch: master
defaults:
run:
working-directory: openemr-devops/docker/openemr
env:
DOCKER_CONTEXT_PATH: "${{matrix.docker-dir.container}}"

steps:
- name: Checkout
uses: actions/checkout@v3
with:
path: openemr-devops
ref: "${{ matrix.docker-dir.openemr.branch }}"

- name: Checkout OpenEMR
uses: actions/checkout@v3
with:
repository: openemr/openemr
path: openemr

- name: Verify Docker Compose Configuration
run: docker compose config

- name: Build the Docker image
run: docker compose build

- name: Run the containers
# some of the containers take a while to start
run: docker compose up --detach --wait --wait-timeout 600

- name: Check container status
if: always()
run: |
docker compose ps
docker compose logs "${OPENEMR_SERVICE_NAME}"

- name: Get PHP Configuration
if: always()
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -i

- name: Test web connectivity
run: |
# Test that OpenEMR web server is responding
HTTP_CODE=$(curl -f -s -o /dev/null -w "%{http_code}" http://localhost:8080/)
echo "OpenEMR HTTP status code: $HTTP_CODE"
if (( HTTP_CODE == 200 || HTTP_CODE == 302 )); then
echo "OpenEMR web server is responding correctly!"
exit 0
fi
echo "OpenEMR web server is not responding correctly!"
exit 1

- name: Install and configure
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr/contrib/util/installScripts \
"${OPENEMR_SERVICE_NAME}" sh -c 'sed -e "s@^exit;@ @" InstallerAuto.php |
php -- rootpass=root server=mysql loginhost=%'
docker compose exec "${OPENEMR_SERVICE_NAME}" mysql -u openemr --password="openemr" -h mysql -e '
INSERT INTO product_registration (opt_out) VALUES (1);
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_api";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_fhir_api";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_portal_api";
UPDATE globals SET gl_value = 3 WHERE gl_name = "oauth_password_grant";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_system_scopes_api";
' openemr
# delete the platform check and then disable it so composer does not recreate it; otherwise
# PHP Fatal error: Uncaught Error: Undefined constant "STDERR" in /var/www/localhost/htdocs/openemr/vendor/composer/platform_check.php:21
rm ../../openemr/vendor/composer/platform_check.php
docker compose exec --workdir /var/www/localhost/htdocs/openemr \
"${OPENEMR_SERVICE_NAME}" composer install --dev --no-interaction --optimize-autoloader --ignore-platform-reqs

- name: Debug platform check
if: always()
uses: actions/upload-artifact@v4
with:
name: platform-check-php
path: ./platform_check.php

- name: Unit Test
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite unit

- name: Fixtures testing
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite fixtures

- name: Services testing
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite services

- name: Validators testing
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite validators

- name: Controllers testing
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite controllers

- name: Common testing
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite common

- name: Cleanup
if: always()
run: docker compose down --remove-orphans --volumes
120 changes: 120 additions & 0 deletions .github/workflows/test-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: OpenEMR Docker Prod Build Test

on:
push:
branches:
- master
paths:
- '.github/workflows/test-prod.yml'
- 'docker/openemr/[0-9]*.[0-9]*.[0-9]/**'
pull_request:
branches:
- master
paths:
- '.github/workflows/test-prod.yml'
- 'docker/openemr/[0-9]*.[0-9]*.[0-9]/**'

env:
COMPOSE_BAKE: "1"
COMPOSE_PROFILES: prod
DOCKER_BUILDKIT: "1"
OPENEMR_SERVICE_NAME: openemr

jobs:
build-and-test:
name: Test OpenEMR Image
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
docker-dir: []
# - 6.1.0
# - 7.0.0
# - 7.0.1
# - 7.0.2
# - 7.0.3
# - 7.0.4
defaults:
run:
working-directory: docker/openemr
env:
DOCKER_CONTEXT_PATH: "${{matrix.docker-dir}}"

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Verify Docker Compose Configuration
run: docker compose config

- name: Build the Docker image
run: docker compose build

- name: Run the containers
run: docker compose up --detach --wait --wait-timeout 180

- name: Check container status
if: always()
run: |
docker compose ps
docker compose logs "${OPENEMR_SERVICE_NAME}"

- name: Get PHP Configuration
if: always()
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr "${OPENEMR_SERVICE_NAME}" php -i

- name: Test web connectivity
run: |
# Test that OpenEMR web server is responding
HTTP_CODE=$(curl -f -s -o /dev/null -w "%{http_code}" http://localhost:8080/)
echo "OpenEMR HTTP status code: $HTTP_CODE"
if (( HTTP_CODE == 200 || HTTP_CODE == 302 )); then
echo "OpenEMR web server is responding correctly!"
exit 0
fi
echo "OpenEMR web server is not responding correctly!"
exit 1

- name: Install and configure
run: |
docker compose exec --workdir /var/www/localhost/htdocs/openemr/contrib/util/installScripts \
"${OPENEMR_SERVICE_NAME}" sh -c 'sed -e "s@^exit;@ @" InstallerAuto.php |
php -- rootpass=root server=mysql loginhost=%'
docker compose exec "${OPENEMR_SERVICE_NAME}" mysql -u openemr --password="openemr" -h mysql -e '
INSERT INTO product_registration (opt_out) VALUES (1);
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_api";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_fhir_api";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_portal_api";
UPDATE globals SET gl_value = 3 WHERE gl_name = "oauth_password_grant";
UPDATE globals SET gl_value = 1 WHERE gl_name = "rest_system_scopes_api";
' openemr
docker compose exec "${OPENEMR_SERVICE_NAME}" composer install --dev --no-interaction --optimize-autoloader

- name: Unit Test
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite unit

- name: Fixtures testing
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite fixtures

- name: Services testing
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite services

- name: Validators testing
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite validators

- name: Controllers testing
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite controllers

- name: Common testing
run: |
docker compose exec "${OPENEMR_SERVICE_NAME}" php -d memory_limit=8G ./vendor/bin/phpunit --colors=always --testdox --stop-on-failure --testsuite common

- name: Cleanup
if: always()
run: docker compose down --remove-orphans --volumes
Loading
Loading