if correct site ID is missing die #19
This file contains hidden or 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: Inferno Certification Test | |
| on: | |
| push: | |
| branches: | |
| - master | |
| - rel-* | |
| pull_request: | |
| branches: | |
| - master | |
| - rel-* | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'pull_request' && github.event.number || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| check_secret: | |
| runs-on: ubuntu-24.04 | |
| name: Check Required Secret | |
| outputs: | |
| has_inferno_pat: ${{ steps.check.outputs.has_inferno_pat }} | |
| has_codecov_token: ${{ steps.check.outputs.has_codecov_token }} | |
| steps: | |
| - name: Check if INFERNO_PAT is available | |
| id: check | |
| run: | | |
| if [[ -n '${{ secrets.INFERNO_PAT }}' ]]; then | |
| echo 'INFERNO_PAT secret is available. Proceeding with tests.' | |
| echo 'has_inferno_pat=true' >> "$GITHUB_OUTPUT" | |
| else | |
| echo '::warning::INFERNO_PAT secret is not set. Inferno certification tests will be skipped.' | |
| echo 'To run these tests, please set the INFERNO_PAT secret in your repository settings.' | |
| echo 'has_inferno_pat=false' >> "$GITHUB_OUTPUT" | |
| fi | |
| # Check for Codecov token (optional - coverage will still work without it) | |
| if [[ -n '${{ secrets.CODECOV_TOKEN }}' ]]; then | |
| echo 'CODECOV_TOKEN is available. Coverage will be uploaded.' | |
| echo 'has_codecov_token=true' >> "$GITHUB_OUTPUT" | |
| else | |
| echo '::warning::CODECOV_TOKEN not set. Coverage reports will not be uploaded to Codecov.' | |
| echo 'has_codecov_token=false' >> "$GITHUB_OUTPUT" | |
| fi | |
| inferno_certification_test: | |
| needs: check_secret | |
| runs-on: ubuntu-24.04 | |
| name: Inferno Certification Test | |
| timeout-minutes: 180 # 3 hours timeout due to potential terminology downloads | |
| if: needs.check_secret.outputs.has_inferno_pat == 'true' | |
| strategy: | |
| matrix: | |
| # Single-element matrix provides named variable and job title | |
| php-version: ['8.4'] | |
| node-version: ['22'] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: 'recursive' | |
| token: ${{ secrets.INFERNO_PAT }} | |
| - name: Fix permissions for Docker uid/gid differences | |
| run: | | |
| # HACK Docker runs with a different uid/gid than the host. | |
| # See openemr/openemr#9233 | |
| sudo chmod -R 0777 . | |
| - name: Install PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: ${{ matrix.php-version }} | |
| - name: Get composer cache directory | |
| id: composer-cache | |
| run: | | |
| { | |
| printf 'dir=' | |
| composer config cache-files-dir | |
| } >> "$GITHUB_OUTPUT" | |
| ## | |
| # Collect cache keys upfront for reusability | |
| - name: Collect cache keys | |
| id: cache-keys | |
| run: | | |
| { | |
| echo 'vendor=${{ runner.os }}-vendor-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}' | |
| echo 'composer=${{ runner.os }}-composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}' | |
| } >> "$GITHUB_OUTPUT" | |
| ## | |
| # Restore vendor artifacts (entire vendor/ directory) | |
| # If we get a hit, we can skip composer install entirely | |
| - name: Restore vendor artifacts | |
| id: vendor-cache-restore | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: ${{ steps.cache-keys.outputs.vendor }} | |
| path: vendor/ | |
| restore-keys: | | |
| ${{ runner.os }}-vendor-${{ matrix.php-version }}- | |
| ${{ runner.os }}-vendor- | |
| ## | |
| # Manual cache-hit check (actions/cache/restore returns false when restore-keys match) | |
| - name: Check vendor artifacts cache | |
| id: vendor-cache-check | |
| run: | | |
| key='${{ steps.cache-keys.outputs.vendor }}' | |
| matched='${{ steps.vendor-cache-restore.outputs.cache-matched-key }}' | |
| if [[ $key = $matched ]]; then | |
| echo hit=true | |
| else | |
| echo hit=false | |
| fi >> "$GITHUB_OUTPUT" | |
| ## | |
| # Restore composer's download cache (fallback if vendor cache misses) | |
| - name: Restore composer downloads | |
| id: composer-cache-restore | |
| if: ${{ steps.vendor-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: ${{ steps.cache-keys.outputs.composer }} | |
| path: ${{ steps.composer-cache.outputs.dir }} | |
| restore-keys: | | |
| ${{ runner.os }}-composer-${{ matrix.php-version }}- | |
| ${{ runner.os }}-composer- | |
| - name: Check composer cache | |
| id: composer-cache-check | |
| run: | | |
| key='${{ steps.cache-keys.outputs.composer }}' | |
| matched='${{ steps.composer-cache-restore.outputs.cache-matched-key }}' | |
| if [[ $key = $matched ]]; then | |
| echo hit=true | |
| else | |
| echo hit=false | |
| fi >> "$GITHUB_OUTPUT" | |
| - name: Composer Install | |
| if: ${{ steps.vendor-cache-check.outputs.hit != 'true' }} | |
| run: composer install --prefer-dist --no-progress | |
| ## | |
| # Save caches only if they weren't exact hits | |
| - name: Save composer cache | |
| if: ${{ steps.vendor-cache-check.outputs.hit != 'true' && steps.composer-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: ${{ steps.composer-cache.outputs.dir }} | |
| key: ${{ steps.cache-keys.outputs.composer }} | |
| - name: Save vendor artifacts | |
| if: ${{ steps.vendor-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.cache-keys.outputs.vendor }} | |
| path: vendor/ | |
| - name: Install npm package | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| - name: Get NPM Cache Directory | |
| id: npm-cache-dir | |
| run: | | |
| { | |
| printf 'dir=' | |
| npm config get cache | |
| } >> "$GITHUB_OUTPUT" | |
| ## | |
| # Update cache keys to include npm build artifacts | |
| - name: Add npm cache keys | |
| id: npm-cache-keys | |
| run: | | |
| { | |
| echo 'npm-build=${{ runner.os }}-npm-build-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}' | |
| echo 'ccda-build=${{ runner.os }}-ccda-build-${{ matrix.node-version }}-${{ hashFiles('**/ccdaservice/package-lock.json') }}' | |
| echo 'npm=${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}' | |
| } >> "$GITHUB_OUTPUT" | |
| ## | |
| # Restore npm build artifacts (node_modules/, public/assets/, public/themes/) | |
| - name: Restore npm build artifacts | |
| id: npm-build-cache-restore | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: ${{ steps.npm-cache-keys.outputs.npm-build }} | |
| path: | | |
| node_modules/ | |
| public/assets/ | |
| public/themes/ | |
| restore-keys: | | |
| ${{ runner.os }}-npm-build-${{ matrix.node-version }}- | |
| ${{ runner.os }}-npm-build- | |
| - name: Check npm build cache | |
| id: npm-build-cache-check | |
| run: | | |
| key='${{ steps.npm-cache-keys.outputs.npm-build }}' | |
| matched='${{ steps.npm-build-cache-restore.outputs.cache-matched-key }}' | |
| if [[ $key = $matched ]]; then | |
| echo hit=true | |
| else | |
| echo hit=false | |
| fi >> "$GITHUB_OUTPUT" | |
| ## | |
| # Restore CCDA build artifacts | |
| - name: Restore CCDA build artifacts | |
| id: ccda-build-cache-restore | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: | | |
| ccdaservice/node_modules/ | |
| ccdaservice/packages/oe-cqm-service/node_modules/ | |
| key: ${{ steps.npm-cache-keys.outputs.ccda-build }} | |
| restore-keys: | | |
| ${{ runner.os }}-ccda-build-${{ matrix.node-version }}- | |
| ${{ runner.os }}-ccda-build- | |
| - name: Check ccda build cache | |
| id: ccda-build-cache-check | |
| run: | | |
| key='${{ steps.npm-cache-keys.outputs.ccda-build }}' | |
| matched='${{ steps.ccda-build-cache-restore.outputs.cache-matched-key }}' | |
| if [[ $key = $matched ]]; then | |
| echo hit=true | |
| else | |
| echo hit=false | |
| fi >> "$GITHUB_OUTPUT" | |
| ## | |
| # Restore npm download cache (fallback if build caches miss) | |
| - name: Restore npm cache | |
| if: ${{ steps.npm-build-cache-check.outputs.hit != 'true' || steps.ccda-build-cache-check.outputs.hit != 'true' }} | |
| id: npm-cache-restore | |
| uses: actions/cache/restore@v5 | |
| with: | |
| key: ${{ steps.npm-cache-keys.outputs.npm }} | |
| path: ${{ steps.npm-cache-dir.outputs.dir }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ matrix.node-version }}- | |
| ${{ runner.os }}-node- | |
| - name: Check npm cache | |
| id: npm-cache-check | |
| run: | | |
| key='${{ steps.npm-cache-keys.outputs.npm }}' | |
| matched='${{ steps.npm-cache-restore.outputs.cache-matched-key }}' | |
| if [[ $key = $matched ]]; then | |
| echo hit=true | |
| else | |
| echo hit=false | |
| fi >> "$GITHUB_OUTPUT" | |
| - name: NPM CI | |
| if: ${{ steps.npm-build-cache-check.outputs.hit != 'true' }} | |
| run: npm ci | |
| ## | |
| # Save caches (base caches before derived caches) | |
| - name: Save npm cache | |
| if: ${{ (steps.npm-build-cache-check.outputs.hit != 'true' || steps.ccda-build-cache-check.outputs.hit != 'true') && steps.npm-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.npm-cache-keys.outputs.npm }} | |
| path: ${{ steps.npm-cache-dir.outputs.dir }} | |
| - name: Save CCDA build artifacts | |
| if: ${{ steps.ccda-build-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.npm-cache-keys.outputs.ccda-build }} | |
| path: | | |
| ccdaservice/node_modules/ | |
| ccdaservice/packages/oe-cqm-service/node_modules/ | |
| - name: Save npm build artifacts | |
| if: ${{ steps.npm-build-cache-check.outputs.hit != 'true' }} | |
| uses: actions/cache/save@v5 | |
| with: | |
| key: ${{ steps.npm-cache-keys.outputs.npm-build }} | |
| path: | | |
| node_modules/ | |
| public/assets/ | |
| public/themes/ | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log Docker info | |
| run: | | |
| docker --version | |
| docker compose version | |
| - name: Install OpenEMR-cmd | |
| run: | | |
| mkdir -p "$HOME/bin" | |
| curl -sSfL https://raw.githubusercontent.com/openemr/openemr-devops/master/utilities/openemr-cmd/openemr-cmd > "$HOME/bin/openemr-cmd" | |
| chmod +x "$HOME/bin/openemr-cmd" | |
| # add the command to default path so will be found and run.sh can still be used locally | |
| - name: Run Inferno Certification Tests | |
| working-directory: ci/inferno | |
| shell: bash | |
| env: | |
| ENABLE_COVERAGE: 'true' | |
| INFERNO_TEST: 'true' | |
| XDEBUG_ON: '1' | |
| XDEBUG_MODE: 'coverage' | |
| run: | | |
| echo 'Starting Inferno certification test suite with coverage…' | |
| ./run.sh | |
| echo 'Inferno certification tests completed successfully' | |
| - name: Upload Inferno test results to Codecov | |
| if: ${{ !cancelled() && needs.check_secret.outputs.has_codecov_token == 'true' && hashFiles('junit-inferno.xml') != '' }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: junit-inferno.xml | |
| flags: inferno,certification,php${{ matrix.php-version }} | |
| report_type: test_results | |
| - name: Hide Inferno test results from subsequent uploads | |
| if: ${{ !cancelled() && hashFiles('junit-inferno.xml') != '' }} | |
| run: mv junit-inferno.xml junit-inferno.saved-test-data | |
| - name: Upload PHPUnit coverage to Codecov | |
| if: ${{ !cancelled() && needs.check_secret.outputs.has_codecov_token == 'true' && hashFiles('coverage.inferno-phpunit.clover.xml') != '' }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage.inferno-phpunit.clover.xml | |
| flags: inferno,phpunit,php${{ matrix.php-version }} | |
| - name: Hide PHPUnit coverage from subsequent uploads | |
| if: ${{ !cancelled() && hashFiles('coverage.inferno-phpunit.clover.xml') != '' }} | |
| run: mv coverage.inferno-phpunit.clover.xml inferno-phpunit.saved-cov-data | |
| - name: Upload HTTP coverage to Codecov | |
| if: ${{ !cancelled() && needs.check_secret.outputs.has_codecov_token == 'true' && hashFiles('coverage.inferno-http.clover.xml') != '' }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage.inferno-http.clover.xml | |
| flags: inferno,http,php${{ matrix.php-version }} | |
| - name: Hide HTTP coverage from subsequent uploads | |
| if: ${{ !cancelled() && hashFiles('coverage.inferno-http.clover.xml') != '' }} | |
| run: mv coverage.inferno-http.clover.xml inferno-http.saved-cov-data | |
| - name: Upload combined coverage to Codecov | |
| if: ${{ !cancelled() && needs.check_secret.outputs.has_codecov_token == 'true' && hashFiles('coverage.clover.xml') != '' }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: coverage.clover.xml | |
| flags: inferno,combined,php${{ matrix.php-version }} | |
| # Unhide files before uploading to GitHub | |
| - name: Unhide test results and coverage for GitHub upload | |
| if: ${{ !cancelled() }} | |
| run: | | |
| shopt -s nullglob | |
| # Unhide junit files | |
| [ -f junit-inferno.saved-test-data ] && mv junit-inferno.saved-test-data junit-inferno.xml || true | |
| # Unhide coverage files | |
| [ -f inferno-phpunit.saved-cov-data ] && mv inferno-phpunit.saved-cov-data coverage.inferno-phpunit.clover.xml || true | |
| [ -f inferno-http.saved-cov-data ] && mv inferno-http.saved-cov-data coverage.inferno-http.clover.xml || true | |
| - name: Upload JUnit test results to GitHub | |
| if: ${{ !cancelled() && hashFiles('junit-inferno.xml') != '' }} | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: junit-inferno-test-results | |
| path: junit-inferno.xml | |
| - name: Upload coverage artifacts to GitHub | |
| if: ${{ !cancelled() && hashFiles('coverage.clover.xml') != '' }} | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: inferno-coverage-reports | |
| path: | | |
| coverage.clover.xml | |
| coverage.inferno-phpunit.clover.xml | |
| coverage.inferno-http.clover.xml | |
| htmlcov/ | |
| - name: Cleanup Docker resources | |
| if: always() | |
| run: | | |
| docker compose -f ci/inferno/compose.yml down --volumes --remove-orphans || true | |
| docker system prune -f || true |