Skip to content

Gefyra/capabilityStatement-expander

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

85 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FHIR CapabilityStatement Expander Action πŸš€

A **GitHub### Advanced Configuration

- name: Expand FHIR CapabilityStatement  
  id: expand
  uses: Gefyra/capabilityStatement-expander@v0  # or @v0.0.2 for specific version
  with:
    input_directory: './implementation-guide/input'
    output_directory: './build/expanded'
    capability_statement_url: 'https://example.org/fhir/CapabilityStatement/MyCapability'
    verbose: 'true'  # Enable detailed logging for debugging
    python_version: '3.10'
    
- name: Show Results
  run: |
    echo "Expanded files: ${{ steps.expand.outputs.expanded_files_count }}"
    echo "CapabilityStatement: ${{ steps.expand.outputs.expanded_capability_statement }}"

πŸ” Verbose Logging

Enable detailed logging to troubleshoot expansion issues:

- name: Debug Expansion Process
  uses: Gefyra/capabilityStatement-expander@v0
  with:
    input_directory: './resources'
    output_directory: './output'
    capability_statement_url: 'https://example.org/fhir/CapabilityStatement/MyCS'
    verbose: 'true'  # Shows detailed processing steps

With verbose: 'true' you get:

  • πŸ“‹ Detailed file processing information
  • πŸ” Step-by-step import resolution
  • πŸ“Š Resource collection statistics
  • 🧩 Profile and example discovery details
  • ⚠️ Warning messages for missing resources

πŸ€– Auto-Enable Verbose with GitHub Debug Mode

Bonus Feature: Verbose logging is automatically enabled when you activate GitHub Actions debug logging!

# No need to set verbose: 'true' when using GitHub debug mode
- name: Expand CapabilityStatement (with auto-verbose)
  uses: Gefyra/capabilityStatement-expander@v0
  with:
    input_directory: './resources'
    output_directory: './output'
    capability_statement_url: 'https://example.org/fhir/CapabilityStatement/MyCS'
    # verbose automatically enabled when ACTIONS_STEP_DEBUG=true

To activate both debug modes:

  1. πŸ”§ Repository Settings β†’ Actions β†’ General β†’ "Enable debug logging"
  2. πŸš€ Run workflow β†’ Both GitHub Actions debug + FHIR verbose logging active automatically!ursively expands FHIR CapabilityStatements by resolving all imports and collecting all referenced resources. Perfect for FHIR Implementation Guide development and distribution.

GitHub Release License FHIR R4

✨ Features

  • πŸ”„ Recursive Import Resolution: Automatically resolves all imports and instantiates references
  • 🏷️ Canonical URL Support: Uses FHIR-compliant canonical URLs for resource identification
  • 🧩 Complete Resource Extraction: Automatically collects:
    • βœ… StructureDefinitions (profiles)
    • βœ… ValueSets and CodeSystems (including from StructureDefinition bindings)
    • βœ… SearchParameters and OperationDefinitions
    • βœ… Examples and other referenced resources
  • πŸ“‹ Smart Example Detection: Finds examples via meta.profile references to collected profiles
  • 🧹 Import Cleanup: Removes imports/_imports from the final expanded CapabilityStatement
  • ⚑ GitHub Action Ready: Directly usable as a reusable action
  • πŸ” Iterative Analysis: Multi-layered analysis for nested dependencies
  • πŸ“Š Detailed Logging: Complete traceability of the expansion process

πŸš€ Usage as GitHub Action

Simple Usage (Single CapabilityStatement)

name: Expand FHIR CapabilityStatement

on:
  workflow_dispatch:
    inputs:
      capability_statement_url:
        description: 'Canonical URL of the CapabilityStatement'
        required: true

jobs:
  expand:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Expand CapabilityStatement
      uses: Gefyra/capabilityStatement-expander@v0  # or @v0.0.2 for specific version
      with:
        input_directory: './fhir-resources'
        output_directory: './expanded-resources'  
        capability_statement_url: ${{ github.event.inputs.capability_statement_url }}
        
    - name: Upload Results
      uses: actions/upload-artifact@v4
      with:
        name: expanded-fhir-resources
        path: './expanded-resources'

Expanding Multiple CapabilityStatements

name: Expand Multiple FHIR CapabilityStatements

on:
  push:
    branches: [ main ]

jobs:
  expand:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Expand Multiple CapabilityStatements
      uses: Gefyra/capabilityStatement-expander@v0
      with:
        input_directory: './fhir-resources'
        output_directory: './expanded-resources'
        # Use toJSON() to convert YAML list to JSON array
        capability_statement_url: ${{ toJSON(fromJSON('[
          "https://example.org/fhir/CapabilityStatement/ServerCapability",
          "https://example.org/fhir/CapabilityStatement/ClientCapability"
        ]')) }}
        
    - name: Upload Results
      uses: actions/upload-artifact@v4
      with:
        name: expanded-fhir-resources
        path: './expanded-resources'

Using Matrix Strategy for Multiple CapabilityStatements

name: Expand CapabilityStatements with Matrix

on:
  push:
    branches: [ main ]

jobs:
  expand:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        capability_statement_urls:
          - https://gematik.de/fhir/isik/CapabilityStatement/ISiKCapabilityStatementBasis
          - https://gematik.de/fhir/isik/CapabilityStatement/ISiKCapabilityStatementSubscription
    steps:
    - uses: actions/checkout@v4
    
    - name: Expand CapabilityStatement
      uses: Gefyra/capabilityStatement-expander@v0
      with:
        input_directory: './Resources/fsh-generated/resources'
        output_directory: './publisher-input/resources'
        # Convert YAML list to JSON array
        capability_statement_url: ${{ toJSON(matrix.capability_statement_urls) }}

Advanced Configuration

- name: Expand FHIR CapabilityStatement  
  id: expand
  uses: Gefyra/capabilityStatement-expander@v0  # or @v0.0.2 for specific version
  with:
    input_directory: './implementation-guide/input'
    output_directory: './build/expanded'
    capability_statement_url: 'https://example.org/fhir/CapabilityStatement/MyCapability'
    verbose: 'true'
    python_version: '3.11'
    
- name: Show Results
  run: |
    echo "Expanded files: ${{ steps.expand.outputs.expanded_files_count }}"
    echo "CapabilityStatement: ${{ steps.expand.outputs.expanded_capability_statement }}"

🏷️ Version Tags

This action supports semantic versioning with automatic major version tags:

# Latest within major version (recommended for most use cases)
uses: Gefyra/capabilityStatement-expander@v0

# Specific version (recommended for production)
uses: Gefyra/capabilityStatement-expander@v0.0.2

# Latest release (not recommended)
uses: Gefyra/capabilityStatement-expander@main

πŸ“‹ Version Strategy:

  • @v0 - Always points to the latest v0.x.x release (automatic updates)
  • @v0.0.2 - Fixed to specific version (no automatic updates)
  • @main - Development branch (may be unstable)

πŸ“₯ Action Inputs

| Input | Description | Required | Default | |-------|-------------|----------|---------|| | input_directory | Directory with FHIR JSON files | βœ… | ./input | | output_directory | Target directory for expanded resources | βœ… | ./output | | capability_statement_url | Canonical URL(s) of the CapabilityStatement(s) to expand.
Can be:
β€’ Single URL: "https://example.org/CS"
β€’ JSON array: ["url1", "url2"]
β€’ YAML list (use toJSON()): ${{ toJSON(matrix.urls) }} | βœ… | - | | verbose | Enable verbose logging | ❌ | false | | no_clean | Do not clean output directory before expansion (by default, directory is cleaned) | ❌ | false | | expectation_filter | Filter imports by minimum expectation level.
SHALL = only SHALL
SHOULD = SHALL + SHOULD
MAY = SHALL + SHOULD + MAY
Default: import all expectations
Note: SHOULD-NOT is never imported | ❌ | - | | python_version | Python version for execution | ❌ | 3.11 |

πŸ“€ Action Outputs

Output Description
expanded_files_count Number of created files
output_directory Path to output directory
expanded_capability_statement Filename of the expanded CapabilityStatement

πŸ’» Local Execution (for Development)

You can also run the script locally:

python capability_statement_expander.py <input_dir> <output_dir> <capability_statement_url>

Parameters:

  • input_dir: Directory with JSON files (CapabilityStatements, profiles, etc.)
  • output_dir: Target directory for expanded resources
  • capability_statement_url: Canonical URL(s) of the CapabilityStatement(s) to expand
    • Single URL: "https://example.org/CS"
    • JSON array: '["url1", "url2"]' (note the quotes!)

Options:

  • --verbose or -v: Enables detailed logging
  • --no-clean: Do not clean output directory before expansion (by default, the output directory is cleaned to avoid stale files)
  • --expectation-filter {SHALL|SHOULD|MAY}: Filter imports by minimum expectation level. SHALL imports only SHALL, SHOULD imports SHALL+SHOULD, MAY imports SHALL+SHOULD+MAY. Default: import all expectations. Note: SHOULD-NOT is never imported regardless of filter.

Local Examples

Single CapabilityStatement:

python capability_statement_expander.py ./fhir-resources ./output "http://example.org/CapabilityStatement/MyCapabilityStatement" --verbose

Multiple CapabilityStatements:

python capability_statement_expander.py ./fhir-resources ./output '["http://example.org/CapabilityStatement/CS1", "http://example.org/CapabilityStatement/CS2"]' --verbose

πŸ§ͺ Tests

The project includes automated tests:

# Run tests
python test_expander.py

# For ISiK tests (if ISiK resources are available)  
python capability_statement_expander.py ./isik_resources ./output_isik "https://gematik.de/fhir/isik/CapabilityStatement/ISiKCapabilityStatementSubscriptionServerAkteur"

πŸ“ Directory Structure

Input Directory

input/
β”œβ”€β”€ CapabilityStatement-MyCS.json
β”œβ”€β”€ CapabilityStatement-ImportedCS.json
β”œβ”€β”€ profiles/
β”‚   β”œβ”€β”€ Patient-Profile.json
β”‚   └── Observation-Profile.json
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ Patient-Example.json
β”‚   └── Observation-Example.json
└── terminology/
    β”œβ”€β”€ ValueSet-Codes.json
    └── CodeSystem-MySystem.json

Output Directory (after expansion)

output/
β”œβ”€β”€ CapabilityStatement-example-base-capability-expanded.json  # ✨ Expanded CapabilityStatement  
β”œβ”€β”€ StructureDefinition-PatientProfile.json                    # πŸ—οΈ Patient profile
β”œβ”€β”€ StructureDefinition-ObservationProfile.json                # πŸ—οΈ Observation profile  
β”œβ”€β”€ ValueSet-PatientStatus.json                                # πŸ“‹ Patient status values
β”œβ”€β”€ SearchParameter-Patient-identifier.json                    # πŸ” Patient identifier search
β”œβ”€β”€ CapabilityStatement-example-base-capability.json           # πŸ“„ Original CapabilityStatement
β”œβ”€β”€ CapabilityStatement-imported-capability.json               # πŸ“₯ Imported CapabilityStatement
β”œβ”€β”€ Patient-example-1.json                                     # πŸ‘€ Example detected via meta.profile
└── Observation-example-1.json                                 # πŸ“Š Example detected via meta.profile

πŸ“ Note: The expanded CapabilityStatement has:

  • File name: Original ID + -expanded suffix (e.g., CapabilityStatement-MyCS-expanded.json)
  • Resource ID: Original ID + -expanded suffix (e.g., "id": "MyCS-expanded")
  • Canonical URL: Original URL + -expanded suffix (e.g., "url": "https://example.org/CS-expanded")
  • Name & Title: Original + Expanded suffix (e.g., "name": "MyCSExpanded")
  • No imports: All imports and _imports fields are removed after expansion

πŸ”§ How It Works

The expander performs the following steps:

  1. Initial Analysis: Loads the base CapabilityStatement and analyzes its structure
  2. Import Resolution: Recursively resolves all imports and instantiates references
    • Supports multi-level imports (CS1 β†’ CS2 β†’ CS3, CS4)
    • Respects expectation filters (SHALL/SHOULD/MAY)
  3. Profile Collection: Extracts all StructureDefinition references from supportedProfile fields
  4. Binding Analysis: Analyzes StructureDefinitions for ValueSet and CodeSystem bindings
  5. Dependency Resolution: Follows references in SearchParameters and OperationDefinitions
  6. Example Detection: Searches for Examples via meta.profile references to collected profiles
  7. Iterative Processing: Repeats analysis until no new resources are found
  8. Final Assembly: Creates expanded CapabilityStatement with modified metadata:
    • Canonical URL: {original-url}-expanded (e.g., https://example.org/CS-expanded)
    • Resource ID: {original-id}-expanded
    • Name/Title: {original}Expanded / {original} (Expanded)
    • Removes all imports and _imports fields
  9. Resource Copy: Copies all referenced resources (profiles, ValueSets, examples, etc.)

🎯 Smart Example Detection

The expander includes intelligent example detection that:

  • Scans all resources in the directory structure
  • Identifies resources with meta.profile references
  • Matches these references against collected supportedProfile URLs
  • Automatically includes matching examples in the expanded output

For example, if your CapabilityStatement references:

"supportedProfile": [
  "http://example.org/StructureDefinition/PatientProfile"
]

And you have an example like:

{
  "resourceType": "Patient",
  "meta": {
    "profile": ["http://example.org/StructureDefinition/PatientProfile"]
  },
  // ... rest of example
}

The example will be automatically detected and included in the expanded package.

πŸ”§ FHIR CapabilityStatement Import Mechanism

The script supports the following import mechanisms from the FHIR standard:

imports

{
  "resourceType": "CapabilityStatement",
  "imports": [
    "http://example.org/CapabilityStatement/BaseCapability",
    "CapabilityStatement/AnotherCapability"
  ]
}

instantiates

{
  "resourceType": "CapabilityStatement", 
  "instantiates": [
    "http://hl7.org/fhir/CapabilityStatement/base"
  ]
}

🎯 Use Cases

  • πŸ₯ Implementation Guide Development: Automatically collect all dependencies
  • πŸ“¦ FHIR Package Creation: Complete resource collections for distribution
  • βœ… Validation: Verify completeness of CapabilityStatements
  • πŸ”„ CI/CD: Automated processing in GitHub Actions workflows

πŸ§‘β€πŸ’» Development

# Clone repository
git clone https://github.com/patrickwerner/CapabilityStatementExpander.git
cd CapabilityStatementExpander

# Run tests
python test_expander.py

# Test local development
python capability_statement_expander.py ./examples ./output_test "http://example.org/CapabilityStatement/example-base-capability" --verbose

πŸ“„ License

MIT License - see LICENSE for details.

🀝 Contributing

Contributions are welcome! Please create an issue or submit a pull request.


Created for the FHIR Community πŸ₯✨

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages