Skip to content

Commit

Permalink
feat: add implementation guide from astacus main repository
Browse files Browse the repository at this point in the history
  • Loading branch information
pl-buiquang committed Oct 17, 2023
1 parent 853b342 commit 745f697
Show file tree
Hide file tree
Showing 52 changed files with 2,162 additions and 2 deletions.
101 changes: 101 additions & 0 deletions .github/workflows/deploy-ig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy implementation-guide to GitHub pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main", "deploy_ig_pages"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

# Set up languages framework and libraries
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'

- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install -g fsh-sushi
- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2

- name: Install Jekyll
run: |
gem install jekyll bundler
- uses: actions/setup-dotnet@v3
with:
dotnet-version: '6.0.x'

- run: dotnet tool install --tool-path ./fhir-cli firely.terminal

# Build IG
- run: gradle buildIG
continue-on-error: true

# Build Fix
# TODO remove this and properly fix the build...
- run: ./fhir-cli/fhir install hl7.fhir.fr.core 1.1.0
continue-on-error: true

- run: rm package.json package-lock.json

- run: gradle buildIG
# End Of Build Fix
# Build IG

# Upload IG artifact
- name: Setup Pages
uses: actions/configure-pages@v3

- name: Fix permissions
run: cp -r ./output _site

- name: Fix permissions
run: |
chmod -c -R +rX "_site/" | while read line; do
echo "::warning title=Invalid file permissions automatically fixed::$line"
done
- name: Upload artifact
uses: actions/upload-pages-artifact@v2

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.DS_Store
.idea
.gradle
/gradle
gradlew
gradlew.bat
Thumbs.db
/fsh-generated
/_input-cache
input-cache
/output
/temp
/template
/build
/node_modules
package.json
package-lock.json
Empty file added LICENSE
Empty file.
71 changes: 69 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,69 @@
# astacus-ig
Guide d'implémentation FHIR du projet Astacus
# Astacus IG



## Building the IG

"Building" the IG means generating a web-based, human-readable representation of the structured information and accompanying documentation defined within this repository. This is done via the [FHIR Implementation Guide Publisher](https://confluence.hl7.org/display/FHIR/IG+Publisher+Documentation) ("IG Publisher"), a Java program provided by the FHIR team for building IGs into a standardized presentation.

If you would like to generate this locally, open command prompt window and navigate to the directory where this repository has been cloned. Then run this command:

- Linux/macOS: `./gradlew buildIG`
- Windows: `.\gradlew.bat buildIG`

Astacus IG is developed in [FHIR Shorthand (FSH)](http://build.fhir.org/ig/HL7/fhir-shorthand/), a domain-specific language (DSL) for defining the content of FHIR IGs. SUSHI complies FHS files into the JSON files expected by the IG Publisher.

You will need an active internet connection to build the IG. It makes take up to 30 minutes to build for the first time; subsequent builds should be faster (5-7 minutes) on a modern laptop.

When the build finishes, you can open `output/index.html` in your browser to see the locally built IG.

### Dependencies for building the IG

1. You will need to [install java](https://adoptium.net/)
2. You will need to [install jekyll](https://jekyllrb.com/docs/installation/)

### Running SUSHI independently of the IG Publisher

If you want to run SUSHI without building the entire IG, you can run a gradle task `runSushi`.

### Getting a clean build

While not normally necessary, you can delete the following folders to get a clean build:

- `fsh-generated/` (SUSHI output)
- `output/` (IG Publisher output)
- `input-cache/` (IG Publisher local cache; note that deleting this will dramatically increase the length of the next build)

## Key folders & files in the IG

- The FHIR Shorthand (`.fsh`) files defining the resources in this IG are found in `input/fsh/`.
- There is an [FSH syntax highlighting extension](https://marketplace.visualstudio.com/items?itemName=kmahalingam.vscode-language-fsh) for [VSCode](https://code.visualstudio.com). The mCODE team generally uses this set of tools for working on FSH files.
- The FSH files are prefixed based on what is contained inside.

| Prefix | Description |
|--------|----------------------|
| `AL` | Aliases |
| `DEF` | Other Definitions |
| `EX` | Examples |
| `SD` | StructureDefinitions |
| `VS` | ValueSets |

- The main pages in the built IG are generated from [Markdown](https://daringfireball.net/projects/markdown/) found in `input/pagecontent/`. These pages must also be included in `sushi-config.yaml` to be compiled to HTML by the IG Publisher.
- There are a number of other important configuration options in `sushi-config.yaml` including the menu contents of the built IG and the groupings on the [Artifacts Summary page](https://aphp.fr/ig/fhir-astacus-ig/artifacts.html).
- The source for the UML diagrams in the IG are found in `input/images-source/` and MUST have a `.plantuml` extension. These are automatically converted to SVG by the IG Publisher, and are inserted inline into Markdown files using `{%include some-diagram.svg%}` (which corresponds to `input/images-source/some-diagram.plantuml`).

## Troubleshooting

### Structure Definition is Missing Snapshot Error

Some non-HL7 FHIR packages are distributed without snapshot elements in their profiles. If your IG uses one of these profiles, SUSHI will report an error like the following:

Structure Definition http://interopsante.org/fhir/StructureDefinition/FrPatient is missing snapshot. Snapshot is required for import.

Since SUSHI does not implement its own snapshot generator, you must update the package in your FHIR cache so that its profiles include snapshot elements. Fortunately, the [Firely Terminal](https://fire.ly/products/firely-terminal/) provides a way to do this.

First, you must install [Firely Terminal](https://docs.fire.ly/projects/Firely-Terminal/InstallingFirelyTerminal.html). Then use Firely Terminal to populate the snapshot elements in the dependency package.

1. Run the command: fhir install <package> (<version>), substituting the dependency package ID for <package>.
E.g., fhir install hl7.fhir.fr.core 1.1.0
2. Run SUSHI again. The error about missing snapshots should no longer be displayed.
151 changes: 151 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import com.github.gradle.node.npm.task.NpmTask
import com.github.gradle.node.npm.task.NpxTask
import java.nio.file.Files
import java.io.FileOutputStream
import java.net.URI
import java.nio.channels.Channels
import java.nio.file.Paths

plugins {
id("java")
id("com.github.node-gradle.node") version "3.5.1"
}

val rootDir = Paths.get(
projectDir.absolutePath
)
.toUri()
.path
.substringAfter("/")
.substringBeforeLast("/")

val currentOperatingSystem = DefaultNativePlatform.getCurrentOperatingSystem()!!
project.ext.set(
"os",
when {
currentOperatingSystem.isWindows -> "win"
currentOperatingSystem.isLinux -> "linux"
currentOperatingSystem.isMacOsX -> "darwin"
currentOperatingSystem.isSolaris -> ""
currentOperatingSystem.isFreeBSD -> ""
else -> ""
}
)

val currentArchitecture = DefaultNativePlatform.getCurrentArchitecture()!!
project.ext.set(
"arch",
when {
currentArchitecture.isAmd64 -> "x64"
currentArchitecture.isArm -> "arm64"
currentArchitecture.isI386 -> ""
currentArchitecture.isIa64 -> ""
else -> ""
}
)

group = "fr.aphp"
version = "0.0.1-SNAPSHOT"

node {
download.set(true)
version.set(properties["nodeVersion"] as? String)
}

defaultTasks("cleanIG", "buildIG")

val sushiInstall = tasks.register<NpmTask>("sushiInstall") {
args.set(
listOf(
"install",
"fsh-sushi@${properties["sushiVersion"]}"
)
)
dependsOn(
tasks.nodeSetup,
tasks.npmSetup,
tasks.npmInstall
)
}

val sushiBuild = tasks.register<NpxTask>("sushiBuild") {
command.set("sushi")
args.set(
listOf(
"build",
"."
)
)
dependsOn(
sushiInstall
)
}

val igPublisherInstall = tasks.register<Task>("igPublisherInstall") {
group = "build setup"
doLast {
val inputCacheDir = file("input-cache").toPath()
val publisherJar = file("input-cache/publisher.jar").toPath()

if (!Files.exists(inputCacheDir)) {
Files.createDirectory(inputCacheDir)
}

if (!Files.exists(publisherJar)) {
URI.create("https://github.com/HL7/fhir-ig-publisher/releases/download/${properties["publisherVersion"]}/publisher.jar")
.toURL().openStream().use {
Channels.newChannel(it).use { rbc ->
FileOutputStream("input-cache/publisher.jar").use { fos ->
fos.channel.transferFrom(rbc, 0, Long.MAX_VALUE)
}
}
}
}
}
}

val buildIG = tasks.register<JavaExec>("buildIG") {
group = "build"

environment(
"PATH",
listOf(
System.getenv("PATH"),
"$rootDir/.gradle/nodejs/node-v${properties["nodeVersion"]}-${project.ext.get("os")}-${project.ext.get("arch")}",
"$rootDir/node_modules/.bin"
).joinToString(
System.getProperties().getProperty("path.separator")
)
)
jvmArgs(
"-Xmx6144m",
"-Dfile.encoding=UTF-8"
)
classpath("input-cache/publisher.jar")
args = listOf(
"-no-sushi",
"-ig",
"."
)
dependsOn(
tasks.nodeSetup,
tasks.npmSetup,
tasks.npmInstall,
sushiBuild,
igPublisherInstall
)
}

val cleanIG = tasks.register<Delete>("cleanIG") {
group = "build"
delete(
"fsh-generated",
"output",
"temp",
"template",
"input-cache/schemas",
"input-cache/txcache",
"input-cache/publisher.jar"
)
}
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeVersion = 18.18.2
sushiVersion = 3.3.3
publisherVersion = 1.4.6
3 changes: 3 additions & 0 deletions ig.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[IG]
ig = fsh-generated/resources/ImplementationGuide-aphp.fhir.fr.astacus.json
template = fhir.base.template#current
Loading

0 comments on commit 745f697

Please sign in to comment.