Skip to content
This repository was archived by the owner on May 18, 2026. It is now read-only.
Merged
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
127 changes: 117 additions & 10 deletions .github/workflows/fhir-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ jobs:
echo "No relevant FHIR JSON/XML changes were detected in tracked spec folders. Validation skipped." >> "$GITHUB_STEP_SUMMARY"

- name: Validate meta.profile presence and prefix
id: precheck
if: steps.collect_files.outputs.has_target_files == 'true'
shell: bash
run: |
Expand All @@ -156,6 +157,8 @@ jobs:
REQUIRED_PREFIX="http://hl7.eu/fhir/"
MISSING_PROFILE=()
MISSING_REQUIRED_PREFIX=()
: > .ci/precheck-missing-profile.txt
: > .ci/precheck-missing-prefix.txt

while IFS= read -r file; do
[[ -z "$file" ]] && continue
Expand Down Expand Up @@ -185,6 +188,7 @@ jobs:

if [[ -z "$PROFILE_LINES" ]]; then
MISSING_PROFILE+=("$file")
echo "$file" >> .ci/precheck-missing-profile.txt
continue
fi

Expand All @@ -199,6 +203,7 @@ jobs:

if [[ "$HAS_REQUIRED_PREFIX" != "true" ]]; then
MISSING_REQUIRED_PREFIX+=("$file")
echo "$file" >> .ci/precheck-missing-prefix.txt
fi
done < .ci/target-files.txt

Expand All @@ -223,21 +228,26 @@ jobs:
echo
fi

exit 1
echo "precheck_exit_code=1" >> "$GITHUB_OUTPUT"
echo "missing_profile_count=${#MISSING_PROFILE[@]}" >> "$GITHUB_OUTPUT"
echo "missing_required_prefix_count=${#MISSING_REQUIRED_PREFIX[@]}" >> "$GITHUB_OUTPUT"
else
echo "meta.profile precheck passed for all candidate resources."
echo "precheck_exit_code=0" >> "$GITHUB_OUTPUT"
echo "missing_profile_count=0" >> "$GITHUB_OUTPUT"
echo "missing_required_prefix_count=0" >> "$GITHUB_OUTPUT"
fi

echo "meta.profile precheck passed for all candidate resources."

- name: Set up Java
if: steps.collect_files.outputs.has_target_files == 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0'
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '21'

- name: Resolve validator download URL
id: validator_meta
if: steps.collect_files.outputs.has_target_files == 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0'
shell: bash
run: |
set -euo pipefail
Expand All @@ -263,7 +273,7 @@ jobs:
echo "cache_key=validator-cli-${CACHE_SUFFIX}" >> "$GITHUB_OUTPUT"

- name: Restore cached validator
if: steps.collect_files.outputs.has_target_files == 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0'
id: validator_cache
uses: actions/cache@v5
with:
Expand All @@ -273,7 +283,7 @@ jobs:
${{ runner.os }}-validator-cli-

- name: Download validator if cache miss
if: steps.collect_files.outputs.has_target_files == 'true' && steps.validator_cache.outputs.cache-hit != 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0' && steps.validator_cache.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
Expand All @@ -283,7 +293,7 @@ jobs:

- name: Run Java FHIR validator
id: run_validator
if: steps.collect_files.outputs.has_target_files == 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0'
shell: bash
run: |
set -euo pipefail
Expand Down Expand Up @@ -323,7 +333,7 @@ jobs:

- name: Render validation summary
id: render_summary
if: steps.collect_files.outputs.has_target_files == 'true'
if: steps.collect_files.outputs.has_target_files == 'true' && steps.precheck.outputs.precheck_exit_code == '0'
continue-on-error: false
uses: patrick-werner/validation-outcome-markdown-renderer@v1
with:
Expand All @@ -341,11 +351,87 @@ jobs:
printf '%s\n' \
'# FHIR Validation Summary' \
'' \
'The markdown summary could not be rendered from `validation.json`.' \
'The markdown summary could not be rendered from `validation.json` or validation was skipped due to precheck issues.' \
'Please check the workflow logs and the uploaded HTML artifact for details.' \
> pr-summary.md
fi

- name: Build precheck summary
if: always() && steps.collect_files.outputs.has_target_files == 'true'
shell: bash
run: |
set -euo pipefail

PRECHECK_EXIT="${{ steps.precheck.outputs.precheck_exit_code }}"
MISSING_PROFILE_COUNT="${{ steps.precheck.outputs.missing_profile_count }}"
MISSING_PREFIX_COUNT="${{ steps.precheck.outputs.missing_required_prefix_count }}"
REQUIRED_PREFIX="http://hl7.eu/fhir/"
MAX_LIST_ITEMS=80

if [[ -z "$PRECHECK_EXIT" ]]; then
PRECHECK_EXIT="0"
fi
if [[ -z "$MISSING_PROFILE_COUNT" ]]; then
MISSING_PROFILE_COUNT="0"
fi
if [[ -z "$MISSING_PREFIX_COUNT" ]]; then
MISSING_PREFIX_COUNT="0"
fi

{
echo "## meta.profile precheck"
echo
if [[ "$PRECHECK_EXIT" == "0" ]]; then
echo "<!-- PRECHECK_STATUS:PASSED -->"
echo
echo "✅ Passed: every checked resource contains \`meta.profile\` and has at least one entry starting with \`${REQUIRED_PREFIX}\`."
else
echo "<!-- PRECHECK_STATUS:FAILED -->"
echo
echo "❌ Failed."
echo
echo "- Missing \`meta.profile\`: ${MISSING_PROFILE_COUNT}"
echo "- No \`meta.profile\` entry with required prefix \`${REQUIRED_PREFIX}\`: ${MISSING_PREFIX_COUNT}"
echo

if [[ -s .ci/precheck-missing-profile.txt ]]; then
echo "### Missing \`meta.profile\`"
count=0
while IFS= read -r file; do
[[ -z "$file" ]] && continue
echo "- \`$file\`"
count=$((count + 1))
if [[ "$count" -ge "$MAX_LIST_ITEMS" ]]; then
break
fi
done < .ci/precheck-missing-profile.txt
total="$(wc -l < .ci/precheck-missing-profile.txt | tr -d ' ')"
if [[ "$total" -gt "$MAX_LIST_ITEMS" ]]; then
echo "- _...truncated (${MAX_LIST_ITEMS} of ${total})_"
fi
echo
fi

if [[ -s .ci/precheck-missing-prefix.txt ]]; then
echo "### No required prefix in \`meta.profile\`"
count=0
while IFS= read -r file; do
[[ -z "$file" ]] && continue
echo "- \`$file\`"
count=$((count + 1))
if [[ "$count" -ge "$MAX_LIST_ITEMS" ]]; then
break
fi
done < .ci/precheck-missing-prefix.txt
total="$(wc -l < .ci/precheck-missing-prefix.txt | tr -d ' ')"
if [[ "$total" -gt "$MAX_LIST_ITEMS" ]]; then
echo "- _...truncated (${MAX_LIST_ITEMS} of ${total})_"
fi
echo
fi
fi
} > precheck-summary.md

- name: Write PR metadata
if: always()
shell: bash
Expand Down Expand Up @@ -376,6 +462,14 @@ jobs:
path: pr-summary.md
if-no-files-found: warn

- name: Upload precheck summary artifact
if: always() && steps.collect_files.outputs.has_target_files == 'true'
uses: actions/upload-artifact@v7
with:
name: fhir-validation-precheck-summary
path: precheck-summary.md
if-no-files-found: warn

- name: Upload validation reports (HTML + JSON)
id: upload_html_report
if: always() && steps.collect_files.outputs.has_target_files == 'true'
Expand All @@ -393,7 +487,20 @@ jobs:
run: |
set -euo pipefail

PRECHECK_EXIT="${{ steps.precheck.outputs.precheck_exit_code }}"
EXIT_CODE="${{ steps.run_validator.outputs.validator_exit_code }}"
if [[ -z "$PRECHECK_EXIT" ]]; then
PRECHECK_EXIT="0"
fi
if [[ -z "$EXIT_CODE" ]]; then
EXIT_CODE="0"
fi

if [[ "$PRECHECK_EXIT" != "0" ]]; then
echo "FHIR validation precheck failed (meta.profile requirements not met)."
exit 1
fi

if [[ "$EXIT_CODE" != "0" ]]; then
echo "FHIR validation finished with errors (exit code: $EXIT_CODE)."
exit 1
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/main-validation-readme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
fetch-depth: 0

Expand Down Expand Up @@ -195,7 +195,7 @@ jobs:

- name: Set up Java
if: steps.collect_files.outputs.has_target_files == 'true'
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
Expand Down Expand Up @@ -230,7 +230,7 @@ jobs:
- name: Restore cached validator
if: steps.collect_files.outputs.has_target_files == 'true'
id: validator_cache
uses: actions/cache@v5
uses: actions/cache@v4
with:
path: .cache/fhir-validator/validator_cli.jar
key: ${{ runner.os }}-${{ steps.validator_meta.outputs.cache_key }}
Expand Down Expand Up @@ -543,7 +543,7 @@ jobs:
steps:
- name: Download main validation artifacts
id: download_artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: main-validation-artifacts
Expand Down Expand Up @@ -605,7 +605,7 @@ jobs:
} > .ci-pages/site/index.html

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
uses: actions/upload-pages-artifact@v3
with:
path: .ci-pages/site

Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/pr-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:

META_ARTIFACT_ID="$(echo "$ARTIFACTS_JSON" | jq -r '.artifacts[] | select(.name == "fhir-validation-pr-meta" and .expired == false) | .id' | head -n 1)"
SUMMARY_ARTIFACT_ID="$(echo "$ARTIFACTS_JSON" | jq -r '.artifacts[] | select(.name == "fhir-validation-pr-summary" and .expired == false) | .id' | head -n 1)"
PRECHECK_ARTIFACT_ID="$(echo "$ARTIFACTS_JSON" | jq -r '.artifacts[] | select(.name == "fhir-validation-precheck-summary" and .expired == false) | .id' | head -n 1)"
HTML_ARTIFACT_ID="$(echo "$ARTIFACTS_JSON" | jq -r '.artifacts[] | select(.name == "fhir-validation-html-report" and .expired == false) | .id' | head -n 1)"

if [[ -z "$META_ARTIFACT_ID" ]]; then
Expand Down Expand Up @@ -133,6 +134,18 @@ jobs:
fi
fi

PRECHECK_SUMMARY_FILE=""
if [[ -n "$PRECHECK_ARTIFACT_ID" ]]; then
mkdir -p .ci-comment/source-precheck
curl -fsSL \
-H "Authorization: Bearer $GH_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/$REPOSITORY/actions/artifacts/$PRECHECK_ARTIFACT_ID/zip" \
-o .ci-comment/precheck-summary.zip
unzip -qo .ci-comment/precheck-summary.zip -d .ci-comment/source-precheck
PRECHECK_SUMMARY_FILE="$(find .ci-comment/source-precheck -type f -name 'precheck-summary.md' | head -n 1 || true)"
fi

# Prefer full renderer summary first.
if [[ -s "$FULL_SUMMARY_FILE" ]]; then
cp "$FULL_SUMMARY_FILE" "$COMMENT_FILE"
Expand Down Expand Up @@ -168,6 +181,7 @@ jobs:
echo "html_artifact_url=$HTML_ARTIFACT_URL" >> "$GITHUB_OUTPUT"
echo "run_url=$RUN_URL" >> "$GITHUB_OUTPUT"
echo "full_summary_file=$FULL_SUMMARY_FILE" >> "$GITHUB_OUTPUT"
echo "precheck_summary_file=$PRECHECK_SUMMARY_FILE" >> "$GITHUB_OUTPUT"

echo "has_pr=true" >> "$GITHUB_OUTPUT"
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
Expand All @@ -190,6 +204,7 @@ jobs:
COMMENT_FILE=".ci-comment/pr-summary.md"
FINAL_FILE=".ci-comment/pr-summary-final.md"
FULL_FILE="${{ steps.build_comment.outputs.full_summary_file }}"
PRECHECK_FILE="${{ steps.build_comment.outputs.precheck_summary_file }}"
FILTERED_RENDERED_FILE=".ci-comment/pr-summary-errors-only-rendered.md"
MAX_COMMENT_BYTES=62000
HTML_ARTIFACT_URL="${{ steps.build_comment.outputs.html_artifact_url }}"
Expand Down Expand Up @@ -226,6 +241,15 @@ jobs:
> "$FINAL_FILE"
fi

if [[ -n "$PRECHECK_FILE" && -s "$PRECHECK_FILE" ]] && grep -q 'PRECHECK_STATUS:FAILED' "$PRECHECK_FILE"; then
{
cat "$PRECHECK_FILE"
printf '\n---\n\n'
cat "$FINAL_FILE"
} > .ci-comment/pr-summary-with-precheck.md
mv .ci-comment/pr-summary-with-precheck.md "$FINAL_FILE"
fi

printf '\n## Artifacts\n\n[Download `fhir-validation-html-report` (includes `validation.html` and `validation.json`)](%s)\n' "$HTML_ARTIFACT_URL" >> "$FINAL_FILE"
printf '\nValidation run: %s\n' "$RUN_URL" >> "$FINAL_FILE"

Expand Down