diff --git a/.github/workflows/combine-schema.v3.2.yml b/.github/workflows/combine-schema.v3.2.yml new file mode 100644 index 0000000..1932190 --- /dev/null +++ b/.github/workflows/combine-schema.v3.2.yml @@ -0,0 +1,71 @@ +# +# GitHub Actions Workflow: Combine XSD Schema v3.2 +# +# This workflow runs on every push to the 'main' branch. +# It combines modular XSD files into a single file, formats the result +# using xmlstarlet, uploads it as an artifact, and commits it to the repository. +# + +name: Combine XSD Schema v3.2 + +on: + push: + branches: [main] + +jobs: + combine-schema: + runs-on: ubuntu-latest + permissions: + contents: write + env: + INPUT_FILE: 3.2/itop_design.xsd + OUTPUT_FILE: dist/3.2/itop_design.xsd + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Python dependencies + run: pip install -r scripts/requirements.txt + + - name: Install xmlstarlet + run: sudo apt-get update && sudo apt-get install -y xmlstarlet + + - name: Combine XSD schema into single file + run: python scripts/combine_schema.py $INPUT_FILE $OUTPUT_FILE + + - name: Beautify and normalize XSD with xmlstarlet + run: | + xmlstarlet fo --omit-decl $OUTPUT_FILE > tmp.xml && mv tmp.xml $OUTPUT_FILE + xmlstarlet ed -P -L -u "//xs:documentation/text()" -x "normalize-space(.)" $OUTPUT_FILE + + - name: Set artifact path + id: vars + run: echo "path=$OUTPUT_FILE" >> $GITHUB_OUTPUT + + - name: Upload merged XSD as artifact + uses: actions/upload-artifact@v4 + with: + name: combined-xsd + path: ${{ steps.vars.outputs.path }} + + - name: Commit combined schema to repository + run: | + git config --global user.name "GitHub Action" + git config --global user.email "action@github.com" + git add $OUTPUT_FILE || echo "No changes to add" + git status + if ! git diff --cached --quiet; then + git commit -m "Auto-update combined schema" + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} + git push + else + echo "No changes to commit." + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.vscode/settings.json b/.vscode/settings.json index a845341..3dd5224 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "fileref", "finalclass", "functionalci", + "github", "Hipska", "ITSM", "jointype", @@ -31,6 +32,7 @@ "stylesheet", "teemip", "timespent", + "xmlstarlet", "Zlist" ], "xml.codeLens.enabled": true, diff --git a/README.md b/README.md index 04b5488..61f3adc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # iTop DataModel XSD -[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/rudnerbjoern/iTop-schema/issues) +[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?logo=git&style=flat)](https://github.com/rudnerbjoern/iTop-schema/issues) [![Validate XSD Schema v3.2](https://github.com/rudnerbjoern/iTop-schema/actions/workflows/validate-xml.v3.2.yml/badge.svg)](https://github.com/rudnerbjoern/iTop-schema/actions/workflows/validate-xml.v3.2.yml) [![Combine XSD Schema v3.2](https://github.com/rudnerbjoern/iTop-schema/actions/workflows/combine-schema.v3.2.yml/badge.svg)](https://github.com/rudnerbjoern/iTop-schema/actions/workflows/combine-schema.v3.2.yml) This project provides an **XSD schema** to validate `datamodel.xxx.xml` files used in the [iTop CMDB software](https://www.combodo.com/itop). diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..485b135 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,21 @@ +# Combined XSD Schemas for iTop + +This directory contains **automatically generated** XSD files for the [iTop CMDB system](https://www.combodo.com/itop). + +## ⚠️ Do not edit manually + +All files in this folder are **generated by an automated workflow**. +Manual changes will be overwritten on every commit to the `main` branch. + +## 📦 Purpose + +These files are intended for **external use**: + +- You can download and include them in your own iTop-related projects +- Each file is self-contained – all referenced definitions via `xs:include` are already merged +- They are validated and formatted as part of the CI pipeline + +## ℹ️ Learn more + +For details, visit the project homepage: +👉 [https://rudnerbjoern.github.io/iTop-schema/](https://rudnerbjoern.github.io/iTop-schema/) diff --git a/scripts/combine_schema.py b/scripts/combine_schema.py new file mode 100644 index 0000000..fa4ad46 --- /dev/null +++ b/scripts/combine_schema.py @@ -0,0 +1,67 @@ +from lxml import etree +import os +import sys + +XSD_NS = "http://www.w3.org/2001/XMLSchema" +NSMAP = {"xs": XSD_NS} +INCLUDE_TAG = f"{{{XSD_NS}}}include" + +if len(sys.argv) != 3: + print("Usage: python combine_schema.py ") + sys.exit(1) + +MASTER_FILE = sys.argv[1] +OUTPUT_FILE = sys.argv[2] + +included_files = set() + +def resolve_includes(tree, base_path): + root = tree.getroot() + includes = root.findall(INCLUDE_TAG) + for include in includes: + href = include.attrib.get("schemaLocation") + if not href: + continue + included_path = os.path.normpath(os.path.join(base_path, href)) + if included_path in included_files: + root.remove(include) + continue + print(f"Including: {included_path}") + included_tree = etree.parse(included_path, etree.XMLParser(remove_blank_text=True)) + resolve_includes(included_tree, os.path.dirname(included_path)) + included_root = included_tree.getroot() + for child in included_root: + root.append(child) + root.remove(include) + included_files.add(included_path) + +os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True) + +parser = etree.XMLParser(remove_blank_text=True) +master_tree = etree.parse(MASTER_FILE, parser) +resolve_includes(master_tree, os.path.dirname(MASTER_FILE)) + +# Add project comment before root +root = master_tree.getroot() +comment = etree.Comment( + """ + This schema file was automatically generated from modular XSD components. + Provided by the iTop-schema project by Björn Rudner. + + Project website: https://rudnerbjoern.github.io/iTop-schema/ + GitHub repository: https://github.com/rudnerbjoern/iTop-schema + + Use this file to validate your iTop datamodels with confidence and consistency. + """ +) +root.addprevious(comment) + +# Write formatted output +etree.ElementTree(root).write( + OUTPUT_FILE, + pretty_print=True, + xml_declaration=True, + encoding="UTF-8" +) + +print(f"✅ Combined schema written to: {OUTPUT_FILE}")