Prepare 0.3.0: ICD-11 MMS integration
Some checks failed
FHIR IG CI/CD Pipeline with Version Persistence / build-ig (push) Failing after 46s
FHIR IG CI/CD Pipeline with Version Persistence / deploy (push) Has been skipped

This commit is contained in:
2026-03-08 18:40:08 +06:00
parent 677de56269
commit 65758559cd

View File

@@ -7,61 +7,75 @@ on:
pull_request: pull_request:
branches: [ main ] branches: [ main ]
permissions:
contents: read
concurrency:
group: fhir-ig-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env: env:
REGISTRY: git.dghs.gov.bd REGISTRY: git.dghs.gov.bd
IMAGE_NAME: gitadmin/bd-core-fhir-ig IMAGE_NAME: gitadmin/bd-core-fhir-ig
defaults:
run:
shell: bash
jobs: jobs:
build-ig: build-ig:
runs-on: fhir-runner runs-on: fhir-runner
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Extract version from IG - name: Extract version from IG
id: version id: version
run: | run: |
VERSION=$(grep -oP '<version value="\K[^"]+' input/bd.fhir.core.xml | head -1) set -euo pipefail
if [ -z "$VERSION" ]; then VERSION="$(grep -oP '<version value="\K[^"]+' input/bd.fhir.core.xml | head -1 || true)"
if [[ -z "${VERSION}" ]]; then
echo "ERROR: Could not extract version from ImplementationGuide XML" echo "ERROR: Could not extract version from ImplementationGuide XML"
exit 1 exit 1
fi fi
echo "Extracted version: $VERSION" echo "Extracted version: ${VERSION}"
echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
BUILD_TYPE="release" BUILD_TYPE="release"
TAG_VERSION="${GITHUB_REF#refs/tags/v}" TAG_VERSION="${GITHUB_REF#refs/tags/v}"
if [ "$TAG_VERSION" != "$VERSION" ]; then if [[ "${TAG_VERSION}" != "${VERSION}" ]]; then
echo "ERROR: Git tag version ($TAG_VERSION) doesn't match IG version ($VERSION)" echo "ERROR: Git tag version (${TAG_VERSION}) doesn't match IG version (${VERSION})"
exit 1 exit 1
fi fi
else else
BUILD_TYPE="dev" BUILD_TYPE="dev"
fi fi
echo "build_type=$BUILD_TYPE" >> $GITHUB_OUTPUT echo "build_type=${BUILD_TYPE}" >> "$GITHUB_OUTPUT"
echo "Build type: $BUILD_TYPE" echo "Build type: ${BUILD_TYPE}"
- name: Prepare package-list.json and history.xml for IG Publisher - name: Prepare package-list.json and history.xml
env:
VERSION: ${{ steps.version.outputs.version }}
BUILD_TYPE: ${{ steps.version.outputs.build_type }}
run: | run: |
VERSION="${{ steps.version.outputs.version }}" set -euo pipefail
BUILD_TYPE="${{ steps.version.outputs.build_type }}"
DATE=$(date +%Y-%m-%d)
export VERSION DATE BUILD_TYPE DATE="$(date +%Y-%m-%d)"
export VERSION BUILD_TYPE DATE
echo "📋 Preparing package-list.json and history.xml for IG Publisher..." echo "Preparing package-list.json and history.xml..."
if [ ! -f "package-list.json" ]; then if [[ ! -f package-list.json ]]; then
echo "⚠️ package-list.json not found in repo root" echo "package-list.json not found in repo root. Creating initial file..."
echo "Creating initial package-list.json..."
cat > package-list.json <<'PKGEOF' cat > package-list.json <<'PKGEOF'
{ {
"package-id": "bd.fhir.core", "package-id": "bd.fhir.core",
@@ -85,21 +99,23 @@ jobs:
import json import json
import os import os
import sys import sys
from html import escape
from pathlib import Path
version = os.environ.get('VERSION', '') version = os.environ["VERSION"]
date = os.environ.get('DATE', '') date = os.environ["DATE"]
build_type = os.environ.get('BUILD_TYPE', '') build_type = os.environ["BUILD_TYPE"]
with open('package-list.json', 'r', encoding='utf-8') as f: pkg_path = Path("package-list.json")
with pkg_path.open("r", encoding="utf-8") as f:
pkg_list = json.load(f) pkg_list = json.load(f)
if 'list' not in pkg_list or not isinstance(pkg_list['list'], list): if "list" not in pkg_list or not isinstance(pkg_list["list"], list):
print("ERROR: package-list.json does not contain a valid 'list' array") print("ERROR: package-list.json does not contain a valid 'list' array")
sys.exit(1) sys.exit(1)
current_entries = [e for e in pkg_list['list'] if e.get('version') == 'current'] if not any(e.get("version") == "current" for e in pkg_list["list"]):
if not current_entries: pkg_list["list"].insert(0, {
pkg_list['list'].insert(0, {
"version": "current", "version": "current",
"desc": "Continuous Integration Build (latest in version control)", "desc": "Continuous Integration Build (latest in version control)",
"path": "https://fhir.dghs.gov.bd/core/", "path": "https://fhir.dghs.gov.bd/core/",
@@ -107,13 +123,9 @@ jobs:
"current": True "current": True
}) })
if build_type == 'release': if build_type == "release":
version_entry = None existing = next((e for e in pkg_list["list"] if e.get("version") == version), None)
for e in pkg_list['list']: if existing is None:
if e.get('version') == version:
version_entry = e
break
if version_entry is None:
new_entry = { new_entry = {
"version": version, "version": version,
"date": date, "date": date,
@@ -122,94 +134,70 @@ jobs:
"status": "trial-use", "status": "trial-use",
"sequence": "STU 1" "sequence": "STU 1"
} }
insert_index = 1 insert_index = 1
for i, entry in enumerate(pkg_list['list']): for i, entry in enumerate(pkg_list["list"]):
if entry.get('version') == 'current': if entry.get("version") == "current":
insert_index = i + 1 insert_index = i + 1
break break
pkg_list["list"].insert(insert_index, new_entry)
pkg_list['list'].insert(insert_index, new_entry) print(f"Added version {version} to package-list.json")
print(f"✅ Added version {version} to package-list.json")
else: else:
print(f" Version {version} already exists in package-list.json") print(f"Version {version} already exists in package-list.json")
else: else:
print(" Dev build - using existing package-list.json without release modification") print("Dev build - keeping existing package-list.json structure")
with open('package-list.json', 'w', encoding='utf-8') as f: with pkg_path.open("w", encoding="utf-8") as f:
json.dump(pkg_list, f, indent=2, ensure_ascii=False) json.dump(pkg_list, f, indent=2, ensure_ascii=False)
PYEOF
echo "🔍 Validating package-list.json..." Path("input").mkdir(parents=True, exist_ok=True)
python3 -m json.tool package-list.json > /dev/null && echo "✅ Valid JSON" || (echo "❌ Invalid JSON!" && exit 1) Path("input/package-list.json").write_text(
pkg_path.read_text(encoding="utf-8"),
encoding="utf-8"
)
echo "📂 Ensuring package-list.json is in required locations..." Path("input/pagecontent").mkdir(parents=True, exist_ok=True)
mkdir -p input
cp package-list.json input/package-list.json
echo "📝 Generating static history.xml from package-list.json..." def version_key(v: str):
mkdir -p input/pagecontent
python3 << 'PYEOF'
import json
import os
from html import escape
os.makedirs('input/pagecontent', exist_ok=True)
with open('package-list.json', 'r', encoding='utf-8') as f:
pkg_list = json.load(f)
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<div xmlns="http://www.w3.org/1999/xhtml">
<p>This page provides the version history for the Bangladesh Core FHIR Implementation Guide.</p>
<p>For a machine-readable version history see <a href="package-list.json">package-list.json</a>.</p>
<p><b>Published Versions</b></p>
<table class="grid table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Version</th>
<th>Date</th>
<th>Status</th>
<th>Description</th>
</tr>
</thead>
<tbody>
'''
def version_key(v):
try: try:
return tuple(int(x) for x in v.split('.')) return tuple(int(x) for x in v.split("."))
except: except Exception:
return (0,) return (0,)
published = [ published = [
e for e in pkg_list['list'] e for e in pkg_list["list"]
if e.get('version') and e.get('version') != "current" if e.get("version") and e.get("version") != "current"
]
published.sort(key=lambda e: version_key(e.get("version", "0.0.0")), reverse=True)
xml_parts = [
'<?xml version="1.0" encoding="UTF-8"?>',
'<div xmlns="http://www.w3.org/1999/xhtml">',
'',
'<p>This page provides the version history for the Bangladesh Core FHIR Implementation Guide.</p>',
'',
'<p>For a machine-readable version history see <a href="package-list.json">package-list.json</a>.</p>',
'',
'<p><b>Published Versions</b></p>',
'',
'<table class="grid table table-striped table-bordered table-hover">',
'<thead>',
'<tr>',
'<th>Version</th>',
'<th>Date</th>',
'<th>Status</th>',
'<th>Description</th>',
'</tr>',
'</thead>',
'<tbody>',
] ]
# Sort newest version first if published:
published.sort( for idx, entry in enumerate(published):
key=lambda e: version_key(e.get("version", "0.0.0")), version_escaped = escape(entry.get("version", "Unknown"))
reverse=True date_escaped = escape(entry.get("date", "N/A"))
) desc_escaped = escape(entry.get("desc", ""))
path_escaped = escape(entry.get("path", "#"))
published_found = False status_val = entry.get("status", "unknown")
first_row = True
for entry in published:
published_found = True
version = escape(entry.get('version', 'Unknown'))
date = escape(entry.get('date', 'N/A'))
desc = escape(entry.get('desc', ''))
path = escape(entry.get('path', '#'))
status_val = entry.get('status', 'unknown')
if status_val == "trial-use": if status_val == "trial-use":
status = '<span class="badge bg-info">Trial Use</span>' status = '<span class="badge bg-info">Trial Use</span>'
@@ -218,245 +206,248 @@ jobs:
else: else:
status = f'<span class="badge bg-secondary">{escape(status_val)}</span>' status = f'<span class="badge bg-secondary">{escape(status_val)}</span>'
badge = '<span class="badge bg-success">Latest</span> ' if first_row else '' badge = '<span class="badge bg-success">Latest</span> ' if idx == 0 else ''
xml += f''' xml_parts.extend([
<tr> '<tr>',
<td><a href="{path}">{badge}{version}</a></td> f'<td><a href="{path_escaped}">{badge}{version_escaped}</a></td>',
<td>{date}</td> f'<td>{date_escaped}</td>',
<td>{status}</td> f'<td>{status}</td>',
<td>{desc}</td> f'<td>{desc_escaped}</td>',
</tr> '</tr>',
''' ])
first_row = False
if not published_found:
xml += '''
<tr>
<td colspan="4">No published versions available yet.</td>
</tr>
'''
xml += '''
</tbody>
</table>
<p class="lead"><b>Continuous Integration Build</b></p>
'''
current_entry = None
for entry in pkg_list['list']:
if entry.get('version') == 'current':
current_entry = entry
break
if current_entry:
path = escape(current_entry.get('path', pkg_list.get('canonical', '') + '/'))
xml += f'''
<p>The latest development build is available at:
<a href="{path}">{path}</a></p>
'''
else: else:
xml += ''' xml_parts.extend([
<p><i>No CI build entry found in package-list.json.</i></p> '<tr>',
''' '<td colspan="4">No published versions available yet.</td>',
'</tr>',
])
xml += ''' xml_parts.extend([
</div> '</tbody>',
''' '</table>',
'',
'<p class="lead"><b>Continuous Integration Build</b></p>',
])
with open('input/pagecontent/history.xml', 'w', encoding='utf-8') as f: current_entry = next((e for e in pkg_list["list"] if e.get("version") == "current"), None)
f.write(xml) if current_entry:
path_escaped = escape(current_entry.get("path", pkg_list.get("canonical", "") + "/"))
xml_parts.append(
f'<p>The latest development build is available at: <a href="{path_escaped}">{path_escaped}</a></p>'
)
else:
xml_parts.append('<p><i>No CI build entry found in package-list.json.</i></p>')
print("✅ Generated static history.xml") xml_parts.extend(['', '</div>', ''])
print(f" File location: {os.path.abspath('input/pagecontent/history.xml')}")
print(f" File size: {os.path.getsize('input/pagecontent/history.xml')} bytes") Path("input/pagecontent/history.xml").write_text(
"\n".join(xml_parts),
encoding="utf-8"
)
print("Generated input/pagecontent/history.xml")
PYEOF PYEOF
if [ -f "input/pagecontent/history.xml" ]; then python3 -m json.tool package-list.json > /dev/null
echo "✅ Verified: history.xml exists" test -f input/package-list.json
echo " First 20 lines:" test -f input/pagecontent/history.xml
head -20 input/pagecontent/history.xml
echo "Prepared files:"
echo " - $(pwd)/package-list.json"
echo " - $(pwd)/input/package-list.json"
echo " - $(pwd)/input/pagecontent/history.xml"
- name: Lightweight disk cleanup
run: |
set -euo pipefail
echo "Disk usage before cleanup:"
df -h
AVAIL_GB="$(df -BG "$GITHUB_WORKSPACE" | awk 'NR==2 {gsub(/G/, "", $4); print $4}')"
if [[ "${AVAIL_GB}" -lt 10 ]]; then
echo "Low free disk detected (${AVAIL_GB}G). Running safe cleanup..."
docker system prune -af || true
rm -rf "${GITHUB_WORKSPACE}/output" \
"${GITHUB_WORKSPACE}/temp" \
"${GITHUB_WORKSPACE}/input-cache" \
"${GITHUB_WORKSPACE}/fsh-generated" || true
rm -rf ~/.fhir/packages || true
else else
echo "❌ ERROR: history.xml was not created!" echo "Sufficient disk available (${AVAIL_GB}G). Skipping aggressive cleanup."
exit 1
fi fi
echo "✅ Pre-build preparation complete:" echo "Disk usage after cleanup:"
echo " - Root: $(pwd)/package-list.json"
echo " - Input: $(pwd)/input/package-list.json"
echo " - History: $(pwd)/input/pagecontent/history.xml"
echo "==============================="
echo "PACKAGE LIST USED FOR BUILD:"
cat package-list.json
echo "-------------------------------"
echo "INPUT COPY:"
cat input/package-list.json
echo "==============================="
- name: Emergency Disk Cleanup
run: |
echo "Disk usage before:"
df -h df -h
echo "Clearing tool cache..." - name: Ensure Docker is available
rm -rf /opt/hostedtoolcache/* || true
rm -rf /usr/share/dotnet || true
rm -rf /usr/local/lib/android || true
rm -rf /opt/ghc || true
rm -rf ~/.fhir/packages || true
echo "Disk usage after:"
df -h
- name: Install Docker CLI
run: | run: |
apt-get update set -euo pipefail
apt-get install -y docker.io
if command -v docker >/dev/null 2>&1; then
echo "Docker already installed: $(docker --version)"
exit 0
fi
echo "Docker not found. Installing..."
sudo apt-get update
sudo apt-get install -y docker.io
docker --version docker --version
- name: Preload previous IG package for comparison - name: Preload previous IG package for comparison
env:
VERSION: ${{ steps.version.outputs.version }}
run: | run: |
set -euo pipefail
echo "Detecting previous version..." echo "Detecting previous version..."
export VERSION="${{ steps.version.outputs.version }}"
PREV_VERSION=$(python3 <<'PY' PREV_VERSION="$(
python3 <<'PY'
import json import json
import os import os
current_build = os.environ.get("VERSION") current_build = os.environ.get("VERSION", "")
with open("package-list.json") as f: with open("package-list.json", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
def parse(v): def parse(v):
try: try:
return tuple(int(x) for x in v.split(".")) return tuple(int(x) for x in v.split("."))
except: except Exception:
return (0,) return (0,)
versions = [ versions = [
v["version"] entry["version"]
for v in data["list"] for entry in data.get("list", [])
if v.get("version") not in ("current", current_build) if entry.get("version") not in ("current", current_build)
] ]
versions.sort(key=parse, reverse=True) versions.sort(key=parse, reverse=True)
print(versions[0] if versions else "") print(versions[0] if versions else "")
PY PY
) )"
if [ -z "$PREV_VERSION" ]; then rm -rf previous-packages
mkdir -p previous-packages
if [[ -z "${PREV_VERSION}" ]]; then
echo "No previous version found. Skipping preload." echo "No previous version found. Skipping preload."
exit 0 exit 0
fi fi
echo "Previous version detected: $PREV_VERSION" echo "Previous version detected: ${PREV_VERSION}"
mkdir -p previous-packages TMPDIR="$(mktemp -d)"
TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT
URL="https://fhir.dghs.gov.bd/core/$PREV_VERSION/package.tgz" URL="https://fhir.dghs.gov.bd/core/${PREV_VERSION}/package.tgz"
echo "Downloading ${URL}"
curl -fL "${URL}" -o "${TMPDIR}/package.tgz"
echo "Downloading $URL" mkdir -p "previous-packages/bd.fhir.core#${PREV_VERSION}"
curl -fL "$URL" -o "$TMPDIR/package.tgz" tar -xzf "${TMPDIR}/package.tgz" -C "previous-packages/bd.fhir.core#${PREV_VERSION}"
mkdir -p "previous-packages/bd.fhir.core#$PREV_VERSION"
tar -xzf "$TMPDIR/package.tgz" -C "previous-packages/bd.fhir.core#$PREV_VERSION"
echo "Previous package cached:" echo "Previous package cached:"
ls previous-packages ls -lah previous-packages
- name: Build FHIR IG - name: Build FHIR IG
env:
VERSION: ${{ steps.version.outputs.version }}
run: | run: |
echo "Building FHIR IG version ${{ steps.version.outputs.version }}..." set -euo pipefail
CONTAINER_ID=$(docker create \ echo "Building FHIR IG version ${VERSION}..."
-v $(pwd)/previous-packages:/previous-packages \
CONTAINER_ID="$(
docker create \
-v "$(pwd)/previous-packages:/previous-packages" \
hl7fhir/ig-publisher-base:latest \ hl7fhir/ig-publisher-base:latest \
/bin/bash -c " /bin/bash -lc '
set -euo pipefail
mkdir -p /tmp/build mkdir -p /tmp/build
cp -r /home/publisher/ig /tmp/build/ig cp -r /home/publisher/ig /tmp/build/ig
cd /tmp/build/ig cd /tmp/build/ig
rm -f package-list.json rm -f package-list.json
_updatePublisher.sh -y _updatePublisher.sh -y
_genonce.sh _genonce.sh
") '
)"
echo "Container ID: $CONTAINER_ID" echo "Container ID: ${CONTAINER_ID}"
docker cp "$(pwd)/." "$CONTAINER_ID:/home/publisher/ig/" cleanup() {
echo "Mounted FHIR packages:" docker rm -f "${CONTAINER_ID}" >/dev/null 2>&1 || true
}
trap cleanup EXIT
docker cp "$(pwd)/." "${CONTAINER_ID}:/home/publisher/ig/"
echo "Mounted previous packages:"
ls -R previous-packages || echo "No previous packages directory" ls -R previous-packages || echo "No previous packages directory"
docker start -a "$CONTAINER_ID"
docker start -a "${CONTAINER_ID}"
EXIT_CODE=$? EXIT_CODE=$?
echo "Copying outputs from container..." echo "Copying outputs from container..."
docker cp "$CONTAINER_ID:/tmp/build/ig/output" ./output || echo "Warning: No output directory" docker cp "${CONTAINER_ID}:/tmp/build/ig/output" ./output || echo "Warning: No output directory"
docker cp "$CONTAINER_ID:/tmp/build/ig/fsh-generated" ./fsh-generated || echo "No FSH generated" docker cp "${CONTAINER_ID}:/tmp/build/ig/fsh-generated" ./fsh-generated || echo "No FSH generated"
docker cp "$CONTAINER_ID:/tmp/build/ig/input-cache" ./input-cache || echo "No input-cache" docker cp "${CONTAINER_ID}:/tmp/build/ig/input-cache" ./input-cache || echo "No input-cache"
docker cp "$CONTAINER_ID:/tmp/build/ig/temp" ./temp || echo "No temp directory" docker cp "${CONTAINER_ID}:/tmp/build/ig/temp" ./temp || echo "No temp directory"
if [ $EXIT_CODE -ne 0 ]; then if [[ ${EXIT_CODE} -ne 0 ]]; then
echo "Build failed, showing logs:" echo "Build failed."
docker logs "$CONTAINER_ID" exit "${EXIT_CODE}"
docker rm "$CONTAINER_ID" fi
if [[ ! -f output/index.html ]]; then
echo "ERROR: Build failed - output/index.html not found"
exit 1 exit 1
fi fi
docker rm "$CONTAINER_ID" echo "Checking for history.html..."
if [[ -f output/history.html ]]; then
if [ ! -f "output/index.html" ]; then echo "history.html generated successfully"
echo "ERROR: Build failed - no index.html" ls -lh output/history.html
exit 1
fi
echo ""
echo "🔍 Checking for history.html..."
if [ -f "output/history.html" ]; then
echo "✅ history.html generated successfully!"
echo "📄 history.html size: $(ls -lh output/history.html | awk '{print $5}')"
else else
echo "⚠️ WARNING: history.html was NOT generated" echo "WARNING: history.html was not generated"
echo "This might indicate an issue with the template or history.xml/package-list.json"
fi fi
echo "================================"
echo "IG Publisher comparison log:" echo "IG Publisher comparison log:"
cat output/qa.compare.txt || echo "qa.compare.txt not found" cat output/qa.compare.txt || echo "qa.compare.txt not found"
echo "================================"
echo "Build successful!" echo "Build successful"
- name: Update package-feed.xml for releases - name: Update package-feed.xml for releases
if: steps.version.outputs.build_type == 'release' if: steps.version.outputs.build_type == 'release'
env:
VERSION: ${{ steps.version.outputs.version }}
run: | run: |
VERSION="${{ steps.version.outputs.version }}" set -euo pipefail
DATETIME=$(date -u +%Y-%m-%dT%H:%M:%SZ)
if [ ! -f "package-feed.xml" ]; then DATETIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "⚠️ package-feed.xml not found, creating initial feed..." export DATETIME
if [[ ! -f package-feed.xml ]]; then
echo "package-feed.xml not found, creating initial feed..."
cat > package-feed.xml <<EOF cat > package-feed.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> <feed xmlns="http://www.w3.org/2005/Atom">
<title>bd.fhir.core</title> <title>bd.fhir.core</title>
<id>https://fhir.dghs.gov.bd/core/package-feed.xml</id> <id>https://fhir.dghs.gov.bd/core/package-feed.xml</id>
<updated>$DATETIME</updated> <updated>${DATETIME}</updated>
</feed> </feed>
EOF EOF
fi fi
cat > update-feed.py << 'EOF' python3 <<'PYEOF'
import sys import os
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
version = sys.argv[1] version = os.environ["VERSION"]
datetime_iso = sys.argv[2] datetime_iso = os.environ["DATETIME"]
ET.register_namespace('', 'http://www.w3.org/2005/Atom') ET.register_namespace('', 'http://www.w3.org/2005/Atom')
@@ -507,33 +498,35 @@ jobs:
root.insert(insert_pos, new_entry) root.insert(insert_pos, new_entry)
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("Updated package-feed.xml") print("Updated package-feed.xml")
EOF PYEOF
python3 update-feed.py "$VERSION" "$DATETIME"
cp package-list.json output/package-list.json cp package-list.json output/package-list.json
echo "Updated registry files"
echo "📋 Updated registry files"
- name: Prepare deployment artifact - name: Prepare deployment artifact
run: | run: |
set -euo pipefail
VERSION="${{ steps.version.outputs.version }}" VERSION="${{ steps.version.outputs.version }}"
BUILD_TYPE="${{ steps.version.outputs.build_type }}" BUILD_TYPE="${{ steps.version.outputs.build_type }}"
BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
tar -czf ig-output.tar.gz -C output . tar -czf ig-output.tar.gz -C output .
echo "version=$VERSION" > deployment.env {
echo "build_type=$BUILD_TYPE" >> deployment.env echo "version=${VERSION}"
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> deployment.env echo "build_type=${BUILD_TYPE}"
echo "build_date=${BUILD_DATE}"
} > deployment.env
echo "📦 Output contents:" echo "Output contents:"
ls -lh output/ | grep -E "(history\.html|package-list\.json|package-feed\.xml|index\.html)" || echo "Some files may be missing" ls -lh output/ | grep -E "(history\.html|package-list\.json|package-feed\.xml|index\.html)" || echo "Some files may be missing"
ls -lh ig-output.tar.gz ls -lh ig-output.tar.gz
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ig-output name: ig-output
path: | path: |
@@ -541,6 +534,7 @@ jobs:
deployment.env deployment.env
package-list.json package-list.json
package-feed.xml package-feed.xml
if-no-files-found: warn
retention-days: 30 retention-days: 30
deploy: deploy:
@@ -550,22 +544,25 @@ jobs:
steps: steps:
- name: Download artifact - name: Download artifact
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ig-output name: ig-output
- name: Load deployment env - name: Load deployment env
id: deploy_info id: deploy_info
run: | run: |
set -euo pipefail
source deployment.env source deployment.env
echo "version=$version" >> $GITHUB_OUTPUT
echo "build_type=$build_type" >> $GITHUB_OUTPUT
echo "build_date=$build_date" >> $GITHUB_OUTPUT
echo "Deploying version: $version" echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "Build type: $build_type" echo "build_type=${build_type}" >> "$GITHUB_OUTPUT"
echo "build_date=${build_date}" >> "$GITHUB_OUTPUT"
- name: Deploy to server echo "Deploying version: ${version}"
echo "Build type: ${build_type}"
- name: Deploy files to server
uses: appleboy/scp-action@v0.1.7 uses: appleboy/scp-action@v0.1.7
with: with:
host: ${{ secrets.DEPLOY_HOST }} host: ${{ secrets.DEPLOY_HOST }}
@@ -583,7 +580,7 @@ jobs:
password: ${{ secrets.DEPLOY_PASSWORD }} password: ${{ secrets.DEPLOY_PASSWORD }}
port: ${{ secrets.DEPLOY_PORT || 22 }} port: ${{ secrets.DEPLOY_PORT || 22 }}
script: | script: |
set -e set -euo pipefail
source /tmp/fhir-ig-deploy/deployment.env source /tmp/fhir-ig-deploy/deployment.env
@@ -597,12 +594,12 @@ jobs:
VERSIONS_DIR="/opt/fhir-ig/versions" VERSIONS_DIR="/opt/fhir-ig/versions"
mkdir -p "$VERSIONS_DIR" mkdir -p "$VERSIONS_DIR"
if [ "$build_type" = "release" ]; then if [[ "$build_type" == "release" ]]; then
TARGET_DIR="$VERSIONS_DIR/$version" TARGET_DIR="$VERSIONS_DIR/$version"
echo "📦 Deploying release version to: $TARGET_DIR" echo "Deploying release version to: $TARGET_DIR"
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"
mkdir -p "$TARGET_DIR" mkdir -p "$TARGET_DIR"
echo "Cleaning old dev files..." echo "Cleaning old dev files..."
rm -rf "$TARGET_DIR"/* rm -rf "$TARGET_DIR"/*
@@ -613,29 +610,37 @@ 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"
if [ -f "$TARGET_DIR/history.html" ]; then if [[ -f "$TARGET_DIR/history.html" ]]; then
echo "history.html deployed successfully" echo "history.html deployed successfully"
else else
echo "⚠️ WARNING: history.html not found in deployment" echo "WARNING: history.html not found in deployment"
fi fi
if [[ -f "$TARGET_DIR/package-list.json" ]]; then
cp "$TARGET_DIR/package-list.json" "$VERSIONS_DIR/package-list.json" cp "$TARGET_DIR/package-list.json" "$VERSIONS_DIR/package-list.json"
cp "$TARGET_DIR/package-feed.xml" "$VERSIONS_DIR/package-feed.xml"
cp "$TARGET_DIR/package-list.json" "/opt/fhir-ig/package-list.json" cp "$TARGET_DIR/package-list.json" "/opt/fhir-ig/package-list.json"
cp "$TARGET_DIR/package-feed.xml" "/opt/fhir-ig/package-feed.xml" elif [[ -f /tmp/fhir-ig-deploy/package-list.json ]]; then
cp /tmp/fhir-ig-deploy/package-list.json "$VERSIONS_DIR/package-list.json"
cp /tmp/fhir-ig-deploy/package-list.json "/opt/fhir-ig/package-list.json"
fi
if [ "$build_type" = "release" ]; then if [[ -f "$TARGET_DIR/package-feed.xml" ]]; then
echo "Updating 'current' symlink to point to $version" cp "$TARGET_DIR/package-feed.xml" "$VERSIONS_DIR/package-feed.xml"
rm -f "$VERSIONS_DIR/current" cp "$TARGET_DIR/package-feed.xml" "/opt/fhir-ig/package-feed.xml"
ln -sf "$version" "$VERSIONS_DIR/current" elif [[ -f /tmp/fhir-ig-deploy/package-feed.xml ]]; then
cp /tmp/fhir-ig-deploy/package-feed.xml "$VERSIONS_DIR/package-feed.xml"
cp /tmp/fhir-ig-deploy/package-feed.xml "/opt/fhir-ig/package-feed.xml"
fi
if [[ "$build_type" == "release" ]]; then
echo "Updating current symlink to point to $version"
ln -sfn "$version" "$VERSIONS_DIR/current"
fi fi
cd /opt/fhir-ig cd /opt/fhir-ig
if [ ! -f "docker-compose.prod.yml" ]; then if [[ ! -f docker-compose.prod.yml ]]; then
echo "ERROR: docker-compose.prod.yml not found!" echo "ERROR: docker-compose.prod.yml not found!"
echo "Please deploy the updated docker-compose.prod.yml and nginx.conf first"
exit 1 exit 1
fi fi
@@ -644,9 +649,8 @@ jobs:
rm -rf /tmp/fhir-ig-deploy rm -rf /tmp/fhir-ig-deploy
echo "==========================================" echo "=========================================="
echo "Deployment completed successfully!" echo "Deployment completed successfully"
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/$version/history.html"
echo " - https://fhir.dghs.gov.bd/core/ (current)" echo " - https://fhir.dghs.gov.bd/core/ (current)"
@@ -656,4 +660,4 @@ jobs:
echo "==========================================" echo "=========================================="
echo "Available versions:" echo "Available versions:"
ls -lh "$VERSIONS_DIR" | grep -v total ls -lh "$VERSIONS_DIR" | grep -v total || true