[pull] develop from ehrbase:develop #86
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "Build & Test" | |
# we have multiple workflows - this helps to distinguish for them | |
run-name: "${{ github.event.pull_request.title && github.event.pull_request.title || github.ref_name }} - Build & Test" | |
on: | |
push: | |
branches: [ master, develop, release/* ] | |
pull_request: | |
branches: [ develop ] | |
workflow_dispatch: | |
env: | |
JAVA_VERSION: 21 | |
JAVA_DISTRIBUTION: 'temurin' | |
jobs: | |
# | |
# Performs maven build and check as well as junit test result collection. Finally, creates the ehrbase docker image | |
# and saves it, as an archive, for later usage. | |
# | |
build-maven: | |
name: Build-Maven | |
runs-on: ubuntu-latest | |
outputs: | |
# Map the step outputs to job outputs | |
ehrbase-version: ${{ steps.get_version.outputs.ehrbase-version }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Setup - Java 21 | |
uses: actions/setup-java@v4 | |
with: | |
java-version: ${{ env.JAVA_VERSION }} | |
distribution: ${{ env.JAVA_DISTRIBUTION }} | |
cache: 'maven' | |
- name: Setup - Dependency Cache | |
uses: actions/cache@v4 | |
with: | |
path: ~/.m2/repository | |
key: deps-${{ runner.os }}-m2-${{ github.head_ref }}-${{ hashFiles('**/pom.xml') }} | |
restore-keys: | | |
deps-${{ runner.os }}-m2-${{ github.head_ref }}- | |
deps-${{ runner.os }}-m2- | |
deps-${{ runner.os }}- | |
deps- | |
- name: Maven - Verify and Package | |
run: mvn --batch-mode --update-snapshots --activate-profiles full -Dmaven.test.failure.ignore=true verify package | |
- name: Maven - Get Version | |
id: "get_version" | |
run: | | |
# evaluate project version | |
version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) | |
echo "EHRbase version [$version]" | |
echo "ehrbase-version=${version}" >> $GITHUB_OUTPUT | |
- name: Upload - Jar | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ehrbase-jar | |
path: ./application/target/ehrbase.jar | |
if-no-files-found: error | |
retention-days: 1 | |
# Upload created class files that are needed for the merged jacoco coverage in a later step | |
- name: Upload - Class Files | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: java-class-files | |
path: "**/target/classes/**/*.class" | |
if-no-files-found: error | |
- name: Upload - Jacoco Coverage | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: jacoco-coverage-partial-build-maven | |
path: "**/target/jacoco*.exec" | |
if-no-files-found: error | |
- name: Upload - Junit reports | |
uses: actions/upload-artifact@v4 # upload test results | |
if: success() || failure() # run this step even if previous step failed | |
with: | |
name: junit-test-results | |
path: '**/target/surefire-reports/*.xml' | |
# | |
# Performs docker test image builds. | |
# | |
docker-test-image: | |
name: Docker Test-Image | |
runs-on: ubuntu-latest | |
needs: [ | |
build-maven | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Download - Jar | |
uses: actions/download-artifact@v4 | |
with: | |
name: ehrbase-jar | |
path: ./application/target/ | |
- name: Docker - Build Base Image | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: Dockerfile | |
load: true | |
tags: ehrbase/ehrbase:build | |
- name: Docker - Build Test Image | |
run: | | |
docker build \ | |
--tag ehrbase/ehrbase:test \ | |
--build-arg EHRBASE_IMAGE=ehrbase/ehrbase:build \ | |
--file tests/DockerfileTest . | |
- name: Docker - Save Test Image | |
run: docker save --output ${{ runner.temp }}/ehrbase-test.tar ehrbase/ehrbase:test | |
- name: Upload - Test Image | |
uses: actions/upload-artifact@v4 | |
with: | |
name: ehrbase-image-test | |
path: ${{ runner.temp }}/ehrbase-test.tar | |
if-no-files-found: error | |
retention-days: 1 | |
# | |
# Uses the ehrbase docker image from [build] to run the robot integrations against it. | |
# | |
integration-test-run: | |
runs-on: ubuntu-latest | |
needs: [ | |
docker-test-image | |
] | |
strategy: | |
fail-fast: false # ensure all tests run | |
matrix: | |
test-suite: [ | |
# Swagger EHRBase API endpoints checks | |
{ path: 'SWAGGER_TESTS', name: 'SWAGGER_TESTS', tags: 'SWAGGER_EHRBASE', env: { 'AUTH_TYPE': 'NONE' } }, | |
# Basic and OUATH authorization type checks | |
{ path: 'AUTH_TYPE_TESTS', name: 'BASIC_AUTH_TYPE_TESTS', tags: 'AUTH_TYPE_TESTS_BASIC', env: { 'AUTH_TYPE': 'BASIC' } }, | |
{ path: 'AUTH_TYPE_TESTS', name: 'OAUTH_AUTH_TYPE_TESTS', tags: 'AUTH_TYPE_TESTS_OAUTH', env: { 'AUTH_TYPE': 'OAUTH' } }, | |
# sanity checks | |
{ path: 'SANITY_TESTS', name: 'SANITY', tags: 'Sanity', env: { 'AUTH_TYPE': 'NONE' } }, | |
# rest/openehr/v1/definition | |
{ path: 'TEMPLATE_TESTS', name: 'TEMPLATE', tags: 'Template', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'STORED_QUERY_TESTS', name: 'STORED_QUERY', tags: 'stored_query', suite: 'TEST', env: { 'AUTH_TYPE': 'NONE' } }, | |
## rest/openehr/v1/ehr | |
{ path: 'EHR_SERVICE_TESTS', name: 'EHR_SERVICE', tags: 'EHR_SERVICE', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'EHR_STATUS_TESTS', name: 'EHR_STATUS', tags: 'EHR_STATUS', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'DIRECTORY_TESTS', name: 'DIRECTORY', tags: 'directory', env: { 'AUTH_TYPE': 'NONE' } }, | |
## rest/openehr/v1/ehr/{ehr_id}/contribution | |
{ path: 'CONTRIBUTION_TESTS', name: 'CONTRIBUTION', tags: 'CONTRIBUTION', env: { 'AUTH_TYPE': 'NONE' } }, | |
## rest/openehr/v1/ehr/{ehr_id}/composition | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_CREATE_1', tags: 'compositionANDcomposition_create_1', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_CREATE_2', tags: 'compositionANDcomposition_create_2', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_CREATE_3', tags: 'compositionANDcomposition_create_3', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_CREATE_4', tags: 'compositionANDcomposition_create_4', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_CREATE_5', tags: 'compositionANDcomposition_create_5', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_GET', tags: 'compositionANDcomposition_get', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_UPDATE', tags: 'compositionANDcomposition_update', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_DELETE', tags: 'compositionANDcomposition_delete', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_GET_VERSIONED', tags: 'compositionANDcomposition_get_versioned', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_VALIDATION', tags: 'COMPOSITION_validation', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_HEADERS_CHECKS', tags: 'HeadersChecks', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_ISM_TRANSITIONS', tags: 'compositionANDcomposition_ism_transitions', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'COMPOSITION_TESTS', name: 'COMPOSITION_WITH_DIFFERENT_TIME_ZONES', tags: 'COMPOSITION_dtz', env: { 'AUTH_TYPE': 'NONE' } }, | |
## rest/openehr/v1/query/aql - could be split into individual sub-suite | |
{ path: 'AQL_TESTS', name: 'AQL', tags: 'AQL_TESTS_PACKAGE', env: { 'AUTH_TYPE': 'NONE' } }, | |
## rest/rest/ecis | |
{ path: 'EHRSCAPE_TESTS', name: 'EHRSCAPE', tags: 'EhrScapeTag', env: { 'AUTH_TYPE': 'NONE' } }, | |
{ path: 'ADMIN_TESTS', name: 'ADMIN', tags: 'ADMIN', env: { 'AUTH_TYPE': 'NONE' } }, | |
# TODO Still missing | |
# FHIR_TERMINOLOGY | |
# SECURITY_TESTS | |
] | |
name: Robot (${{ matrix.test-suite.name }}) | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
sparse-checkout: | | |
tests | |
.env.ehrbase | |
docker-compose.yml | |
- name: Download - Test Image | |
uses: actions/download-artifact@v4 | |
with: | |
name: ehrbase-image-test | |
path: ${{ runner.temp }} | |
- name: Docker - Load Image | |
run: docker load --input ${{ runner.temp }}/ehrbase-test.tar | |
# image used by the docker-compose-int-test.yml | |
- name: Docker Compose - Setup env | |
run: | | |
echo "EHRBASE_IMAGE=ehrbase/ehrbase:test" >> $GITHUB_ENV | |
echo "JACOCO_RESULT_PATH=/app/coverage/jacoco-${{ matrix.test-suite.path }}-${{ matrix.test-suite.name }}.exec" >> $GITHUB_ENV | |
- name: Modify .env.ehrbase file | |
run: | | |
echo "SECURITY_AUTHTYPE=${{ matrix.test-suite.env['AUTH_TYPE'] }}" >> .env.ehrbase | |
if [ "${{ matrix.test-suite.env['AUTH_TYPE'] }}" == "OAUTH" ]; then | |
echo "SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUERURI=http://keycloak:8080/auth/realms/ehrbase" >> .env.ehrbase | |
fi | |
cat .env.ehrbase | |
- name: Docker Compose - Starting | |
run: | | |
docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml up -d | |
- name: Wait for Keycloak to be ready | |
run: | | |
if [ "${{ matrix.test-suite.env['AUTH_TYPE'] }}" == "OAUTH" ]; then | |
until curl -s http://localhost:8081/auth/realms/ehrbase; do | |
echo "Waiting for Keycloak..." | |
sleep 30 | |
done | |
#curl -s http://localhost:8081/auth/realms/ehrbase/.well-known/openid-configuration | |
fi | |
docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml ps | |
- name: Run - Robot Test-Suite | |
run: | | |
docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml run --remove-orphans --rm ehrbase-integration-tests runRobotTest \ | |
--name ${{ matrix.test-suite.name }} \ | |
--path ${{ matrix.test-suite.path }} \ | |
--tags ${{ matrix.test-suite.tags }} \ | |
--env ${{ matrix.test-suite.env['AUTH_TYPE'] }} | |
- name: Docker Compose - Logs ehrbase | |
if: always() | |
run: docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml logs ehrbase | |
- name: Docker Compose - Logs keycloak | |
if: always() | |
run: docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml logs keycloak | |
- name: Docker Compose - Stopping | |
if: always() | |
run: | | |
docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml down --remove-orphans | |
docker compose -f docker-compose.yml -f tests/docker-compose-int-test.yml rm --force --volumes | |
- name: Upload - Jacoco Coverage | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: jacoco-coverage-partial-robot-${{ matrix.test-suite.path }}-${{ matrix.test-suite.name }} | |
path: ./tests/coverage/jacoco*.exec | |
if-no-files-found: error | |
- name: Upload - Robot results | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: robot-result-${{ matrix.test-suite.name }} | |
path: ./tests/results/${{ matrix.test-suite.name }}/output.xml | |
if-no-files-found: error | |
# | |
# Collect all Robot result from [integration-test-run] and generated the final report. | |
# | |
integration-test-collect: | |
name: Robot-Collect | |
if: ${{ always() }} | |
needs: [ | |
integration-test-run | |
] | |
runs-on: ubuntu-latest | |
# allow to write comments to the issue | |
permissions: | |
issues: write | |
pull-requests: write | |
steps: | |
- name: Download - Robot results | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: robot-result-* | |
path: ./tests/results/ | |
- name: Generate - Robot Tests-Report | |
run: | | |
docker run \ | |
-v ./tests/results:/integration-tests/results \ | |
-v ./tests/report:/integration-tests/report \ | |
ehrbase/integration-tests:latest collectRebotResults | |
- name: Archive - Robot Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: robot-report-final | |
path: ./tests/report | |
- name: Cleanup - Test Folder | |
if: always() | |
run: | | |
rm -rf ./tests/result | true | |
rm -rf ./tests/report | true | |
# | |
# Collect all Robot result from [integration-test-run] and generated the final report. | |
# | |
coverage-collect: | |
name: Jacoco-Collect | |
if: ${{ always() }} | |
needs: [ | |
integration-test-run | |
] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Download - Class files | |
uses: actions/download-artifact@v4 | |
with: | |
name: java-class-files | |
path: ./ | |
- name: Download - Robot results | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: jacoco-coverage-partial-* | |
path: ./tests/coverage | |
- name: Docker - Build Jacoco-CLI | |
uses: docker/build-push-action@v6 | |
env: | |
DOCKER_BUILD_NO_SUMMARY: true | |
with: | |
context: . | |
file: tests/DockerfileJacocoCLI | |
load: true | |
tags: jacoco-cli:local | |
# create merged.exec | |
- name: Jacoco - Merge | |
run: | | |
cd ./tests/coverage | |
docker run --rm -v ./:/workspace -w /workspace --pull never jacoco-cli:local merge $(find . -type f -name '*.exec' | tr '\n' ' ') --destfile jacoco-merged.exec | |
# it is easier to copy over .java and .class and pass them later as a bundle to the jacoco report generation | |
- name: Collect - Sources & Classes | |
run: | | |
mkdir -p ./tests/coverage/ehrbase | |
mkdir -p ./tests/coverage/ehrbase/src | |
find . -type d -path '*/src/main/java' | xargs -0 sh -c 'cp -prnv $0 ./tests/coverage/ehrbase/src' | true | |
find . -type d -path '*/generated-sources' | xargs -0 sh -c 'cp -prnv $0 ./tests/coverage/ehrbase/src' | true | |
find . -type d -path '*/target/classes' | xargs -0 sh -c 'cp -prnv $0 ./tests/coverage/ehrbase' | true | |
# create final jacoco report | |
- name: Jacoco - Report | |
run: | | |
cd ./tests/coverage | |
mkdir -p jacoco-report-final | |
docker run --rm -v $(pwd)/:/workspace -w /workspace --pull never jacoco-cli:local report jacoco-merged.exec --classfiles ehrbase/classes/ --sourcefiles ehrbase/src/java --sourcefiles ehrbase/src/generated-sources --encoding utf-8 --name Merged --html ./jacoco-report-final --xml ./jacoco-report-final/jacoco.xml | |
- name: Archive - Jacoco Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: jacoco-report-final | |
path: ./tests/coverage/jacoco-report-final | |
# | |
# Build and push docker image | |
# | |
docker-build-push: | |
name: Docker | |
uses: ./.github/workflows/job-docker-build-push.yml | |
secrets: inherit | |
# ignore dependabot here. | |
if: ${{ github.actor != 'dependabot[bot]' }} | |
needs: [ | |
build-maven, # needed to obtain ehrbase-version from | |
integration-test-run | |
] | |
with: | |
ehrbase-version: ${{ needs.build-maven.outputs.ehrbase-version }} | |
ehrbase-jar-artifact: ehrbase-jar | |
# | |
# Maven publish | |
# | |
maven-publish: | |
name: Maven | |
uses: ./.github/workflows/job-maven-publish.yml | |
secrets: inherit | |
# ignore dependabot here. | |
if: ${{ github.actor != 'dependabot[bot]' }} | |
needs: [ | |
build-maven, # only to have them in the same UI group as docker-build-push | |
integration-test-run | |
] | |
# | |
# Cleanup serialized oci image as well as intermediate robot results | |
# | |
cleanup: | |
name: Cleanup | |
if: ${{ always() }} | |
needs: [ | |
coverage-collect, | |
integration-test-collect, | |
docker-build-push, | |
maven-publish | |
] | |
runs-on: ubuntu-latest | |
steps: | |
- name: Delete - Temp Artifacts | |
uses: geekyeggo/delete-artifact@v5 | |
with: | |
name: | | |
java-class-files | |
ehrbase-jar | |
ehrbase-image-test | |
robot-result-* | |
jacoco-coverage-* | |
failOnError: false |