2 Commits

Author SHA1 Message Date
2b2ec21c24 Add debugging to workflow and bump to 0.2.4
All checks were successful
FHIR IG CI/CD Pipeline with Version Persistence / build-ig (push) Successful in 5m59s
FHIR IG CI/CD Pipeline with Version Persistence / deploy (push) Successful in 10s
2026-03-07 00:17:09 +06:00
80c870f8a0 Added ICD11 codesystem
All checks were successful
FHIR IG CI/CD Pipeline with Version Persistence / build-ig (push) Successful in 6m7s
FHIR IG CI/CD Pipeline with Version Persistence / deploy (push) Successful in 10s
2026-03-07 00:00:54 +06:00
7 changed files with 156 additions and 113 deletions

View File

@@ -53,81 +53,6 @@ jobs:
echo "build_type=$BUILD_TYPE" >> $GITHUB_OUTPUT echo "build_type=$BUILD_TYPE" >> $GITHUB_OUTPUT
echo "Build type: $BUILD_TYPE" echo "Build type: $BUILD_TYPE"
# NEW STEP: Update package-list.json BEFORE build so IG Publisher can use it
- name: Pre-build package-list.json update
run: |
VERSION="${{ steps.version.outputs.version }}"
BUILD_TYPE="${{ steps.version.outputs.build_type }}"
DATE=$(date +%Y-%m-%d)
# Only update for release builds
if [ "$BUILD_TYPE" != "release" ]; then
echo " Dev build - skipping package-list.json pre-build update"
exit 0
fi
echo "📋 Updating package-list.json before build..."
# Check if package-list.json exists
if [ ! -f "package-list.json" ]; then
echo "⚠️ package-list.json not found in repo - history.html won't be generated"
echo "Creating minimal package-list.json for this build..."
cat > package-list.json << EOF
{
"package-id": "bd.fhir.core",
"title": "Bangladesh Core FHIR Implementation Guide",
"canonical": "https://fhir.dghs.gov.bd/core",
"introduction": "Core FHIR profiles and extensions for Bangladesh healthcare",
"list": [
{
"version": "current",
"desc": "Continuous Integration Build (latest in version control)",
"path": "https://fhir.dghs.gov.bd/core/",
"status": "ci-build",
"current": true
}
]
}
EOF
fi
# Update package-list.json with new version
python3 << 'PYEOF'
import json
import sys
version = "$VERSION"
date = "$DATE"
with open('package-list.json', 'r') as f:
pkg_list = json.load(f)
# Check if this version already exists
version_exists = any(e['version'] == version for e in pkg_list['list'])
if not version_exists:
new_entry = {
"version": version,
"date": date,
"desc": f"Release {version}",
"path": f"https://fhir.dghs.gov.bd/core/{version}/",
"status": "trial-use",
"sequence": "STU 1"
}
# Insert after 'current' entry
pkg_list['list'].insert(1, new_entry)
with open('package-list.json', 'w') as f:
json.dump(pkg_list, f, indent=2)
print(f"✅ Added version {version} to package-list.json")
else:
print(f" Version {version} already exists in package-list.json")
PYEOF
echo "📋 package-list.json is ready for IG Publisher"
cat package-list.json
- name: Install Docker CLI - name: Install Docker CLI
run: | run: |
apt-get update apt-get update
@@ -169,49 +94,91 @@ jobs:
exit 1 exit 1
fi fi
# Check if history.html was generated
if [ -f "output/history.html" ]; then
echo "✅ history.html generated successfully"
else
echo "⚠️ WARNING: history.html was not generated"
echo "This usually means package-list.json was missing or invalid"
fi
echo "✅ Build successful!" echo "✅ Build successful!"
- name: Update package-feed.xml for releases - name: Update package-list.json and package-feed.xml for releases
if: steps.version.outputs.build_type == 'release' if: steps.version.outputs.build_type == 'release'
run: | run: |
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
DATE=$(date +%Y-%m-%d)
DATETIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) DATETIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
cat > update-feed.py << 'EOF' # Update package-list.json and package-feed.xml
cat > update-registry-files.py << 'EOF'
import json
import sys import sys
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime
version = sys.argv[1] version = sys.argv[1]
datetime_iso = sys.argv[2] date = sys.argv[2]
datetime_iso = sys.argv[3]
# ========== Update package-list.json ==========
with open('package-list.json', 'r') as f:
pkg_list = json.load(f)
# Update current build path
for entry in pkg_list['list']:
if entry['version'] == 'current':
entry['path'] = 'https://fhir.dghs.gov.bd/core/'
break
# Check if this version already exists
version_exists = any(e['version'] == version for e in pkg_list['list'])
if not version_exists:
# Add new version entry
new_entry = {
"version": version,
"date": date,
"desc": f"Release {version}",
"path": f"https://fhir.dghs.gov.bd/core/{version}/",
"status": "trial-use",
"sequence": "STU 1"
}
# Insert after 'current' entry
pkg_list['list'].insert(1, new_entry)
else:
# Update existing entry
for entry in pkg_list['list']:
if entry['version'] == version:
entry['date'] = date
entry['path'] = f"https://fhir.dghs.gov.bd/core/{version}/"
break
with open('output/package-list.json', 'w') as f:
json.dump(pkg_list, f, indent=2)
print(f"✅ Updated package-list.json with version {version}")
# ========== Update package-feed.xml ==========
# Register namespaces
ET.register_namespace('', 'http://www.w3.org/2005/Atom') ET.register_namespace('', 'http://www.w3.org/2005/Atom')
# Parse existing feed
tree = ET.parse('package-feed.xml') tree = ET.parse('package-feed.xml')
root = tree.getroot() root = tree.getroot()
ns = {'atom': 'http://www.w3.org/2005/Atom'} ns = {'atom': 'http://www.w3.org/2005/Atom'}
# Update feed updated timestamp
updated_elem = root.find('atom:updated', ns) updated_elem = root.find('atom:updated', ns)
if updated_elem is not None: if updated_elem is not None:
updated_elem.text = datetime_iso updated_elem.text = datetime_iso
# Check if entry for this version already exists
entry_exists = False entry_exists = False
for entry in root.findall('atom:entry', ns): for entry in root.findall('atom:entry', ns):
title = entry.find('atom:title', ns) title = entry.find('atom:title', ns)
if title is not None and version in title.text: if title is not None and version in title.text:
entry_exists = True entry_exists = True
# Update existing entry timestamp
entry_updated = entry.find('atom:updated', ns) entry_updated = entry.find('atom:updated', ns)
if entry_updated is not None: if entry_updated is not None:
entry_updated.text = datetime_iso entry_updated.text = datetime_iso
break break
# If entry doesn't exist, create new one
if not entry_exists: if not entry_exists:
new_entry = ET.Element('{http://www.w3.org/2005/Atom}entry') new_entry = ET.Element('{http://www.w3.org/2005/Atom}entry')
@@ -231,6 +198,8 @@ jobs:
summary = ET.SubElement(new_entry, '{http://www.w3.org/2005/Atom}summary') summary = ET.SubElement(new_entry, '{http://www.w3.org/2005/Atom}summary')
summary.text = f"Release {version} of Bangladesh Core FHIR Implementation Guide" summary.text = f"Release {version} of Bangladesh Core FHIR Implementation Guide"
# Insert new entry at the beginning (after feed metadata)
# Find the position after the last feed-level element
insert_pos = 0 insert_pos = 0
for i, child in enumerate(root): for i, child in enumerate(root):
if child.tag.endswith('entry'): if child.tag.endswith('entry'):
@@ -240,32 +209,36 @@ jobs:
root.insert(insert_pos, new_entry) root.insert(insert_pos, new_entry)
# Write updated feed
tree.write('output/package-feed.xml', encoding='utf-8', xml_declaration=True) tree.write('output/package-feed.xml', encoding='utf-8', xml_declaration=True)
print(f"✅ Updated package-feed.xml") print(f"✅ Updated package-feed.xml with version {version}")
EOF EOF
python3 update-feed.py "$VERSION" "$DATETIME" python3 update-registry-files.py "$VERSION" "$DATE" "$DATETIME"
# Also copy the updated package-list.json to output # Copy updated files
cp package-list.json output/package-list.json cp output/package-list.json package-list.json
cp output/package-feed.xml package-feed.xml
echo "📋 Updated registry files" echo "📋 Updated registry files (package-list.json and package-feed.xml)"
- name: Prepare deployment artifact - name: Prepare deployment artifact
run: | run: |
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
BUILD_TYPE="${{ steps.version.outputs.build_type }}" BUILD_TYPE="${{ steps.version.outputs.build_type }}"
tar -czf ig-output.tar.gz -C output . # Create a tarball of the output
if [ "$BUILD_TYPE" == "release" ]; then
tar -czf ig-output.tar.gz -C output .
else
tar -czf ig-output.tar.gz -C output .
fi
echo "version=$VERSION" > deployment.env echo "version=$VERSION" > deployment.env
echo "build_type=$BUILD_TYPE" >> deployment.env echo "build_type=$BUILD_TYPE" >> deployment.env
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> deployment.env echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> deployment.env
# List what's in the output
echo "📦 Output contents:"
ls -lh output/ | grep -E "(history\.html|package-list\.json|package-feed\.xml|index\.html)"
ls -lh ig-output.tar.gz ls -lh ig-output.tar.gz
- name: Upload artifact - name: Upload artifact
@@ -342,9 +315,6 @@ jobs:
else else
TARGET_DIR="$VERSIONS_DIR/dev" TARGET_DIR="$VERSIONS_DIR/dev"
echo "🔧 Deploying dev build to: $TARGET_DIR" echo "🔧 Deploying dev build to: $TARGET_DIR"
echo "Cleaning old dev files..."
rm -rf "$TARGET_DIR"/*
fi fi
# Create target directory # Create target directory
@@ -354,13 +324,7 @@ jobs:
echo "Extracting IG output..." echo "Extracting IG output..."
tar -xzf /tmp/fhir-ig-deploy/ig-output.tar.gz -C "$TARGET_DIR" tar -xzf /tmp/fhir-ig-deploy/ig-output.tar.gz -C "$TARGET_DIR"
# Verify history.html was deployed # Copy package-list.json to root
if [ -f "$TARGET_DIR/history.html" ]; then
echo "✅ history.html deployed successfully"
else
echo "⚠️ WARNING: history.html not found in deployment"
fi
cp /tmp/fhir-ig-deploy/package-list.json "$VERSIONS_DIR/package-list.json" cp /tmp/fhir-ig-deploy/package-list.json "$VERSIONS_DIR/package-list.json"
# Copy package-feed.xml to root # Copy package-feed.xml to root
@@ -383,9 +347,9 @@ jobs:
exit 1 exit 1
fi fi
# Force recreate container to ensure new config/mounts are applied # Restart nginx to pick up new content
# This handles "stuck" states better than a simple restart docker compose -f docker-compose.prod.yml restart fhir-ig || \
docker compose -f docker-compose.prod.yml up -d --force-recreate fhir-ig docker compose -f docker-compose.prod.yml up -d
# Cleanup # Cleanup
rm -rf /tmp/fhir-ig-deploy rm -rf /tmp/fhir-ig-deploy
@@ -395,7 +359,6 @@ jobs:
echo "Version $version is now available at:" echo "Version $version is now available at:"
if [ "$build_type" == "release" ]; then if [ "$build_type" == "release" ]; then
echo " - https://fhir.dghs.gov.bd/core/$version/" echo " - https://fhir.dghs.gov.bd/core/$version/"
echo " - https://fhir.dghs.gov.bd/core/$version/history.html"
echo " - https://fhir.dghs.gov.bd/core/ (current)" echo " - https://fhir.dghs.gov.bd/core/ (current)"
else else
echo " - https://fhir.dghs.gov.bd/core/dev/" echo " - https://fhir.dghs.gov.bd/core/dev/"

1
ig.ini
View File

@@ -6,6 +6,7 @@ ig = input/bd.fhir.core.xml
template = #bd-national-template template = #bd-national-template
#template = D:\Git\templates\ig-template-base #template = D:\Git\templates\ig-template-base
#template = #local-template #template = #local-template
historypage = true
########################## ##########################
### ig.ini parameters: ### ### ig.ini parameters: ###

View File

@@ -13,7 +13,7 @@
</extension>--> </extension>-->
<url value="https://fhir.dghs.gov.bd/core/ImplementationGuide/bd.fhir.core"/> <url value="https://fhir.dghs.gov.bd/core/ImplementationGuide/bd.fhir.core"/>
<!-- This version will propagate to all artifacts unless the "propagate-version" extension is overridden --> <!-- This version will propagate to all artifacts unless the "propagate-version" extension is overridden -->
<version value="0.2.2"/> <version value="0.2.4"/>
<name value="BangladeshCoreFHIRIG"/> <name value="BangladeshCoreFHIRIG"/>
<title value="Bangladesh Core FHIR Implementation Guide"/> <title value="Bangladesh Core FHIR Implementation Guide"/>
<status value="active"/> <status value="active"/>

View File

@@ -0,0 +1,47 @@
// ============================================================
// CodeSystem-icd11-mms.fsh
// ICD-11 Mortality and Morbidity Statistics (MMS) — stub only
// Content is hosted externally; canonical authority is WHO.
// Runtime resolution via OCL: https://tr.ocl.dghs.gov.bd
// ============================================================
CodeSystem: ICD11MMSCS
Id: icd11-mms
Title: "ICD-11 Mortality and Morbidity Statistics (MMS)"
Description: """
WHO ICD-11 Mortality and Morbidity Statistics linearization.
Canonical system URI: http://id.who.int/icd/release/11/mms
This CodeSystem is declared as a stub (content = #not-present).
The authoritative content is maintained by the World Health Organization.
In Bangladesh, runtime code validation and lookup are delegated to the
national OCL terminology server at https://tr.ocl.dghs.gov.bd.
Supported operations (use `system=` parameter, not `url=`):
- $validate-code: https://tr.ocl.dghs.gov.bd/api/fhir/CodeSystem/$validate-code?system=http://id.who.int/icd/release/11/mms&code={code}
- $lookup: https://tr.ocl.dghs.gov.bd/api/fhir/CodeSystem/$lookup?system=http://id.who.int/icd/release/11/mms&code={code}
$expand is not supported — known OCL limitation. Expansion must not be
attempted at build time or by IG Publisher.
Preferred code form: short stem codes (e.g. 1A00, NC72.Z).
Linearization URIs are not used as code identifiers in this IG.
Version 2025-01 is imported into OCL with 36,941 concepts across
the following concept classes: Diagnosis, Finding, Substance, Organism,
Device, Anatomy, Misc.
"""
* ^url = "http://id.who.int/icd/release/11/mms"
* ^version = "2025-01"
* ^status = #active
* ^experimental = false
* ^publisher = "World Health Organization (WHO)"
* ^contact.name = "Directorate General of Health Services (DGHS), MoHFW, Bangladesh"
* ^contact.telecom.system = #url
* ^contact.telecom.value = "https://dghs.gov.bd"
* ^jurisdiction = urn:iso:std:iso:3166#BD "Bangladesh"
* ^copyright = "ICD-11 is copyright © World Health Organization. Used under licence."
* ^content = #not-present
* ^count = 36941
* ^caseSensitive = true

View File

@@ -11,6 +11,22 @@
"status": "ci-build", "status": "ci-build",
"current": true "current": true
}, },
{
"version": "0.2.3",
"date": "2025-10-06",
"desc": "Second draft release of the Bangladesh Core FHIR IG",
"path": "https://fhir.dghs.gov.bd/core/0.2.3/",
"status": "trial-use",
"sequence": "STU 1"
},
{
"version": "0.2.2",
"date": "2025-10-06",
"desc": "Second draft release of the Bangladesh Core FHIR IG",
"path": "https://fhir.dghs.gov.bd/core/0.2.2/",
"status": "trial-use",
"sequence": "STU 1"
},
{ {
"version": "0.2.1", "version": "0.2.1",
"date": "2025-10-06", "date": "2025-10-06",

View File

@@ -11,6 +11,22 @@
"status": "ci-build", "status": "ci-build",
"current": true "current": true
}, },
{
"version": "0.2.3",
"date": "2025-10-06",
"desc": "Second draft release of the Bangladesh Core FHIR IG",
"path": "https://fhir.dghs.gov.bd/core/0.2.3/",
"status": "trial-use",
"sequence": "STU 1"
},
{
"version": "0.2.2",
"date": "2025-10-06",
"desc": "Second draft release of the Bangladesh Core FHIR IG",
"path": "https://fhir.dghs.gov.bd/core/0.2.2/",
"status": "trial-use",
"sequence": "STU 1"
},
{ {
"version": "0.2.1", "version": "0.2.1",
"date": "2025-10-06", "date": "2025-10-06",

View File

@@ -6,7 +6,7 @@ description: >
This Implementation Guide defines the Bangladesh Core FHIR profiles, This Implementation Guide defines the Bangladesh Core FHIR profiles,
value sets, code systems, and implementation rules for national digital health systems. value sets, code systems, and implementation rules for national digital health systems.
status: draft status: draft
version: 0.2.2 version: 0.2.4
fhirVersion: 4.0.1 fhirVersion: 4.0.1
copyrightYear: 2025+ copyrightYear: 2025+
releaseLabel: CI Build releaseLabel: CI Build