Authoring Models in a Source Repo¶
This page describes the producer side of the pipeline: an engineering team that
authors architecture models as code and runs the Linked.Archi converters to emit RDF
on every push. It is distilled from the example-architecture-project template.
If you want the whole picture first, read the Pipeline Overview.
Role¶
A source repo owns models in one or more notations and is responsible for converting
them to RDF (TriG). The converted .trig file is the only interface contract with
the rest of the world — it is published as a CI artifact and later pulled by the
central aggregation graph.
Conversion happens once, here, in the source repo. The aggregation repo never runs a converter.
Repository layout¶
.
├── models/
│ ├── bpmn/ BPMN 2.0 process files
│ │ ├── diagram-index.yaml Index: model IDs + publish status
│ │ └── order-fulfillment.bpmn
│ ├── plantuml/ PlantUML diagrams
│ │ ├── diagram-index.yaml
│ │ ├── inventory-domain.puml
│ │ └── checkout-sequence.puml
│ ├── backstage/ Backstage catalog entities
│ │ ├── catalog-index.yaml
│ │ └── catalog-info.yaml
│ ├── structurizr/ Structurizr workspace (C4)
│ │ └── workspace.json
│ └── archimate/ ArchiMate Exchange XML
│ └── enterprise-model.xml
├── config/
│ └── type-mapping-*.yml Optional domain-ontology overrides
├── out/ Generated RDF (gitignored)
├── convert-*.sh Per-notation convert scripts
├── convert-all.sh Converts everything
├── .gitlab-ci.yml convert → validate → publish
└── README.md
out/ is gitignored
In a fresh checkout out/ is empty. RDF only appears after ./convert-all.sh
runs locally, or after a CI run.
Quick start¶
# Convert all models locally (requires Docker)
./convert-all.sh
# Or run individual converters
./convert-bpmn.sh
./convert-plantuml.sh
./convert-backstage.sh
./convert-structurizr.sh
Each script wraps the converter Docker image. For example, the BPMN conversion runs:
docker run --rm -v "$PWD:/work" -w /work linkedarchi-converters \
bpmn2linkedarchi convert models/bpmn/*.bpmn \
--diagrams-index models/bpmn/diagram-index.yaml \
--base-iri "$BASE_IRI" --format TRIG -o out/bpmn.trig
See Docker & CI and the per-notation pages under Converters for the exact CLI of each tool.
Configuration¶
Base IRI¶
All scripts share a base IRI used to mint stable resource IRIs. Override it via the environment:
Type mapping (optional)¶
Override default notation types with a domain ontology by passing --type-mapping.
See Type Mapping and
Ontology Alignment.
bpmn2linkedarchi convert models/bpmn/*.bpmn \
--type-mapping config/type-mapping-bpmn-lite.yml \
--base-iri "$BASE_IRI" --format TRIG -o out/bpmn.trig
Diagram index files¶
Each notation directory carries a diagram-index.yaml that controls which files are
processed, assigns stable model IDs (used in IRIs, independent of filename), and records
each diagram's lifecycle state, which is
published as adms:status and can be withheld from a build with --exclude-states:
diagrams:
- id: order-fulfillment
file: order-fulfillment.bpmn
status: publish
title: "Order Fulfillment Process"
author: "Platform Team"
See Diagram Index Files for the full schema.
Model IDs and versioning¶
The id (from diagram-index.yaml, or --model-id for Structurizr) is what makes a
model's IRIs stable and deterministic — IRIs are minted from it, never from the
filename. Keep an id fixed across edits so re-conversions produce clean diffs in the
graph rather than duplicate resources.
This matters for versioning. The graph repo overwrites each source in place, so git
history is your version trail (see
Versioning & overwrites). If you ever need
two versions of the same model to coexist in the graph (e.g. during a migration),
they must have distinct IDs — convert them with different id / --model-id values
(e.g. order-v1, order-v2). Two models sharing an id mint identical graph IRIs, and
the second would shadow the first when merged. This is the producer half of the
side-by-side versioning contract.
Output format¶
By default the scripts and CI publish both formats — controlled by the FORMATS
variable (default TRIG TURTLE):
-
out/*.trig— TriG, named-graph aware. Each model yields semantic / model / views / provenance named graphs, withsemanticsplit one graph per input file where a model is built from several: -
out/*.ttl— Turtle, the flat union of those triples (no named graphs).
Publish just one by setting the variable, e.g. FORMATS=TRIG ./convert-all.sh or the
FORMATS CI variable. See the format tradeoff in
Aggregating into a Graph for when to prefer each — TriG preserves
provenance separation and merges cleanly; Turtle is simpler and more portable.
CI pipeline¶
The source repo's .gitlab-ci.yml runs on every push:
- convert — runs the converters, produces
out/*.trig, stored as an artifact (expire_in: neverrecommended onmain) - validate — Tier 1 structural SHACL validation on the output
- publish — optional; the artifact is what the aggregation repo pulls
The convert job runs once; its artifact is reused for the MR check and by the
aggregation repo. See Validation Tiers for
what Tier 1 checks.
Adapting the template¶
- Replace the sample models in
models/with your own - Update each
diagram-index.yamlwith your model IDs - Set
BASE_IRIto your organization's graph root - Point
.gitlab-ci.ymlat your registry (and triplestore, if publishing directly) - Optionally add
config/type-mapping-*.ymlfor domain ontology alignment - Register the repo in the aggregation graph's
sources-index.yaml