feat: add c4-diagramming skill (#16)

* feat: add c4-diagramming skill

Signed-off-by: Magnus Hedemark <magnus919@pm.me>

* fix: remove host-specific port assumptions

Signed-off-by: Magnus Hedemark <magnus919@pm.me>

---------

Signed-off-by: Magnus Hedemark <magnus919@pm.me>
This commit is contained in:
Magnus Hedemark
2026-07-12 14:45:28 -04:00
committed by GitHub
parent b5ba3a7793
commit 8786ad1fd1
8 changed files with 831 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
# C4 Diagramming
Make system boundaries, responsibilities, and relationships legible at the architectural level appropriate to the reader.
## Why Install This Skill
Make system boundaries, responsibilities, and relationships legible at the architectural level appropriate to the reader. It preserves a practical method, local reference material, and reusable templates so an agent can do more than produce a generic answer.
Use it when the work needs a repeatable process and an inspectable result. It is portable across Agent Skills-compatible clients and does not require a profile system or a particular task orchestrator.
## What You Get
| Path | What it provides |
|---|---|
| `SKILL.md` | Trigger conditions, workflow, and guidance for loading deeper resources. |
| `references/` | Reference material: `architecture-as-code-ecosystem.md`, `c4-to-pyramid-mapping.md`, `ci-pipeline-templates.md` |
## Quick Start
Choose the C4 level and authoring format in `SKILL.md`, then load the matching reference before drawing.
Install or expose this directory using your agent's standard Agent Skills loading mechanism, then ask for work that matches the triggers below.
## Triggers
- Create C4 software-architecture diagrams using Mermaid or Structurizr. Use when teams need clear system context, container, component, or code-level views.
- Requests involving the method, deliverables, or review process described in `SKILL.md`.
- Work where a reusable template or reference from this skill would reduce avoidable mistakes.
## Requirements
Mermaid or Structurizr tooling is optional and only needed to render or validate diagrams.
## Source and maintenance
This skill was extracted from [`magnus919/hermes-profiles`](https://github.com/magnus919/hermes-profiles) at commit [`867a555`](https://github.com/magnus919/hermes-profiles/commit/867a555). The portable methodology was retained; Hermes-specific profile, orchestration, and memory assumptions were removed.
+102
View File
@@ -0,0 +1,102 @@
---
name: c4-diagramming
description: Create C4 software-architecture diagrams using Mermaid or Structurizr. Use when teams need clear system context, container, component, or code-level views.
license: MIT
compatibility: Mermaid or Structurizr tooling is optional and only needed to render or validate diagrams.
metadata:
source_repo: https://github.com/magnus919/hermes-profiles
source_commit: 867a555
---
# C4 Diagramming
C4 Model for structural architecture visualization. Produces diagrams at four zoom levels, mapped into the artifact pyramid.
## C4-to-Pyramid Mapping
| C4 Level | Pyramid Layer | Path |
|----------|--------------|------|
| Level 1: System Context | L1 (Summary) | 01-summary/system-context.md |
| Level 2: Container | L2 (Analysis) | 02-analysis/structural-views/container.md |
| Level 3: Component | L2 (Analysis) | 02-analysis/structural-views/components.md |
| Level 4: Code | L3 (Dossiers) | 03-dossiers/code-level-detail.md |
C4 is the cleanest structural fit — its four-level hierarchy maps to the three pyramid layers with almost no translation, and Levels 2-3 both resolve to separate L2 analysis files.
## Authoring Formats
### Mermaid (Default for Quick Diagrams)
Use when you need a single diagram embedded in markdown. See the GitHub Rendering Constraint section below for C4-in-Mermaid compatibility notes.
### Structurizr DSL (Recommended for Long-Lived Projects)
Structurizr DSL is the C4 model's reference "models as code" implementation, created by Simon Brown. Define the entire architecture model in a single DSL file; all 4 C4 levels are generated from it. This ensures structural consistency across diagrams that hand-written Mermaid cannot guarantee.
```
workspace {
model {
user = person "Customer"
system = softwareSystem "Your System" {
webapp = container "Web Application" "TypeScript, React"
api = container "API" "Go"
db = container "Database" "PostgreSQL"
user -> webapp "Uses"
webapp -> api "Makes API calls"
api -> db "Reads/writes"
}
}
views {
systemContext system { include * autolayout lr }
container system { include * autolayout lr }
component api { include * autolayout lr }
theme default
}
}
```
**Key capabilities:**
- `!adrs docs/adr` — imports Architecture Decision Records (adr-tools, MADR, log4brains) into the workspace, rendered alongside C4 diagrams
- `!docs docs/arc42` — imports arc42 documentation as Markdown/AsciiDoc
- Structurizr Lite (Docker) — local preview at http://localhost:8081
- CI commands: `validate`, `inspect`, `export` (PlantUML, Mermaid, static site)
Full reference in `references/architecture-as-code-ecosystem.md` — tool comparison, DSL cookbook, C4-PlantUML alternative, and the converged repo convention.
## Contents
- `references/c4-to-pyramid-mapping.md` — context→L1, container/component→L2, code→L3 (Mermaid + Structurizr DSL paths)
- `references/c4-to-flowchart.md` — (in `mermaid-diagrams` skill) C4 → standard flowchart conversion patterns for GitHub compatibility
- `references/architecture-as-code-ecosystem.md` — Structurizr DSL, C4-PlantUML, docToolChain, converged repo convention, tool comparison table
- `references/ci-pipeline-templates.md` — GitHub Actions, GitLab CI, ForgeJo (Gitea Actions, Woodpecker) pipeline templates for Structurizr validation, export, deploy
## GitHub Rendering Constraint
GitHub's built-in Mermaid renderer does **not** bundle the C4 plugin (`@mermaid-js/mermaid`). Any ````mermaid` block using `C4Context`, `C4Container`, or `C4Component` syntax renders as raw code rather than a diagram on GitHub. This affects issues, PR descriptions, discussion comments, and markdown files.
**Workaround:** Convert C4 diagrams to standard `flowchart` syntax before embedding in GitHub markdown:
- `Person()``[rect]` node with label
- `System()` / `System_Ext()``[rect]` inside or outside subgraphs
- `Container()``[rect` with tech stack label]`
- `Db()``[(cylinder shape)]`
- `System_Boundary{}` / `Container_Boundary{}``subgraph ... end`
- `Rel()``-- label -->` or `-.->`
- Drop `UpdateLayoutConfig()` — use `flowchart LR` or `TB` directive instead
For the full conversion table with worked examples, load `references/c4-to-flowchart.md` from the companion `mermaid-diagrams` skill when it is available.
**.mmd files in a DIAGRAMS/ directory** must also use standard flowchart syntax if they need to render via `mmdc` or on GitHub. Files using C4-plugin syntax can only render in tools that bundle the plugin (e.g., Mermaid Live Editor, mmdc with C4 extension config). If you commit `.mmd` files with C4 syntax to a repo, GitHub's file preview will show them as raw text — convert them to standard syntax or render them to PNG first.
## Feature Request Filed
A GitHub Community feature request to bundle the C4 mermaid plugin was filed at https://github.com/orgs/community/discussions/197898 (closed — requires submission through the web UI with the Apps, API and Webhooks discussion template). If this gets implemented, the flowchart conversions below would no longer be necessary for GitHub rendering.
## Canonical Reference
- Simon Brown, "The C4 Model" — https://c4model.com/
- GroktoPlan C4 Diagrams (worked examples) — https://github.com/groktopus/groktoplan/blob/main/TECHNICAL_ARCHITECTURE.md
## Portability
This skill is intentionally host-neutral. Use your agent's normal mechanisms to load the references, templates, and scripts listed here. Do not assume a particular profile system, task orchestrator, memory service, or response-handoff format.
@@ -0,0 +1,300 @@
# Architecture as Code (AaC) Ecosystem
Tools, conventions, and patterns for managing C4 model diagrams, arc42 documentation, and Architecture Decision Records (ADRs) together in a git repository.
## 1. Structurizr — C4 Reference Implementation
Structurizr is the official "models as code" tool for the C4 model, created by Simon Brown (the C4 model's author). You write a text-based DSL that defines your entire software architecture model; all diagrams are generated from that single model.
**Key website:** https://structurizr.com/ — **Docs:** https://docs.structurizr.com/
### Core Concepts
- **Workspace** — the top-level container. Holds a model + views + documentation + decisions.
- **Model** — defines elements (persons, software systems, containers, components) and their relationships.
- **Views** — selects subsets of the model for diagram rendering (system context, container, component, dynamic, deployment).
- **DSL** — text-based domain-specific language. Single source of truth. Git-friendly.
### Minimal Example (All Four C4 Levels)
```
workspace {
model {
user = person "Customer"
system = softwareSystem "Internet Banking System" {
webapp = container "Web Application" "TypeScript, React" {
user -> this "Uses"
}
api = container "API" "Go" {
webapp -> this "Makes API calls"
}
db = container "Database" "PostgreSQL" {
api -> this "Reads/writes"
}
}
}
views {
systemContext system {
include *
autolayout lr
}
container system {
include *
autolayout lr
}
component api {
include *
autolayout lr
}
theme default
}
}
```
### The `!adrs` Keyword — Native ADR Integration
Structurizr can import Architecture Decision Records directly into the workspace:
```
workspace {
!adrs docs/adr
model { ... }
views { ... }
}
```
This imports all Markdown files from `docs/adr/` using the adr-tools format by default. Supported formats:
- `adrtools` (default) — expects files matching adr-tools naming convention
- `madr` — for MADR-format ADRs
- `log4brains` — for log4brains-format ADRs
The ADRs are rendered in the Structurizr UI alongside the C4 diagrams. This is the tightest integration available between C4 and ADRs.
### The `!docs` Keyword — arc42 Documentation Import
```
workspace {
!docs docs/arc42
model { ... }
views { ... }
}
```
Imports Markdown or AsciiDoc documentation (structured as arc42 sections) and renders them in the UI alongside diagrams and ADRs. Supports section-based navigation.
### Structurizr Lite — Local Preview
Docker container for rendering the full workspace in a browser:
```yaml
# docker-compose.yml
services:
structurizr-lite:
image: structurizr/lite
ports:
- "8081:8080"
volumes:
- ./docs/arch:/usr/local/structurizr
```
Access at `http://localhost:8081`. Shows C4 diagrams, arc42 documentation, and ADRs in a unified web UI with navigation.
### CI/CD Commands
```bash
# Validate DSL syntax and model consistency
structurizr-cli validate -w docs/arch/model/system.dsl
# Inspect for architectural drift
structurizr-cli inspect -w docs/arch/model/system.dsl
# Export diagrams to PlantUML
structurizr-cli export -w docs/arch/model/system.dsl -format plantuml
# Export diagrams to Mermaid
structurizr-cli export -w docs/arch/model/system.dsl -format mermaid
# Export to static HTML site
structurizr-cli export -w docs/arch/model/system.dsl -format site
```
### DSL Cookbook
Full tutorial guide: https://docs.structurizr.com/dsl/cookbook/
Topics covered: workspace structure, model elements, relationships, views, styling, themes, animations, deployment nodes, dynamic diagrams, filtering, properties, perspectives.
---
## 2. C4-PlantUML — Lighter Alternative
**Repo:** https://github.com/plantuml-stdlib/C4-PlantUML
PlantUML include files that add C4 semantics to standard PlantUML. No single-model consistency (each diagram is a separate file), but much lower learning curve than Structurizr.
### Function Reference
| Function | C4 Level | Purpose |
|---|---|---|
| `Person(alias, label, description)` | Any | External user or actor |
| `Person_Ext(alias, label, description)` | Context | External user (outside system boundary) |
| `System(alias, label, description)` | Context | Software system |
| `System_Ext(alias, label, description)` | Context | External software system |
| `Container(alias, label, tech, description)` | Container | Application container (web app, API, DB) |
| `Container_Boundary(alias, label)` | Container | Groups related containers |
| `Component(alias, label, tech, description)` | Component | Module within a container |
| `System_Boundary(alias, label)` | Context | Groups related systems |
| `Rel(from, to, label, tech)` | Any | Relationship between elements |
| `Rel_D(from, to, label, tech)` | Any | Relationship (dashed) |
| `Rel_Neighbor(from, to, label, tech)` | Any | Relationship rendering optimization |
| `UpdateLayoutConfig(c4ShapeInRow, c4BoundaryInRow)` | Any | Layout tuning |
| `LAYOUT_WITH_LEGEND()` | Any | Renders with automatic legend |
### Example
```plantuml
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
Person(customer, "Customer")
System(system, "Your System", "Core platform")
System_Ext(external, "External Service", "Payment processor")
Rel(customer, system, "Uses")
Rel(system, external, "Charges via")
@enduml
```
### When to Choose Over Structurizr
| Situation | Choice |
|---|---|
| Team already uses PlantUML for other diagrams | C4-PlantUML (consistent toolchain) |
| Need a quick C4 diagram for an ad-hoc document | C4-PlantUML (no DSL learning curve) |
| Need consistent multi-diagram model across 4 C4 levels | Structurizr (single source of truth) |
| Want ADR integration in the diagram viewer | Structurizr (native `!adrs` support) |
| CI pipeline already has PlantUML | Either — Structurizr exports to PlantUML |
---
## 3. docToolChain — arc42 Build Pipeline
**Repo:** https://github.com/docToolchain/docToolchain
A Gradle-based docs-as-code toolchain purpose-built for arc42 documentation. Handles the full pipeline: AsciiDoc compilation, PlantUML diagram generation, PDF/HTML export, Confluence publishing.
### Key Capabilities
- **arc42 template management** — generates skeleton arc42 documentation with all 12 sections
- **AsciiDoc compilation** — converts `.adoc` source files to HTML, PDF, DocBook
- **PlantUML integration** — renders C4 diagrams (via C4-PlantUML includes) as part of the build
- **Confluence export** — publishes rendered docs to Confluence spaces via asciidoc2confluence
- **Gradle task hierarchy** — `generateHTML`, `generatePDF`, `exportConfluence` as standard tasks
### Directory Structure Convention
```
docs/
├── src/
│ ├── arc42/
│ │ ├── 01_introduction_and_goals.adoc
│ │ ├── ...
│ │ └── 12_glossary.adoc
│ └── images/
├── build/ ← Generated output
├── build.gradle ← docToolChain configuration
└── gradle.properties
```
### When to Use
docToolChain is for organizations that want a **standardized, build-pipeline-driven** approach to arc42 documentation. It adds ceremony (Gradle build, strict directory structure) in exchange for consistent output formats and Confluence integration. For teams that just want C4 diagrams with ADRs, Structurizr is lighter.
---
## 4. Converged Repo Convention
The AaC community has converged on a standard directory structure for combining C4, arc42, and ADRs in a single git repository. Multiple reference implementations use the same pattern:
### Directory Structure
```
docs/arch/
├── model/
│ ├── system.dsl ← Structurizr DSL (the architecture model)
│ └── deployment/ ← Deployment-specific views (dev, staging, prod)
│ ├── dev.dsl
│ └── live.dsl
├── src/ ← arc42 12-section template
│ ├── 01_introduction_and_goals.adoc
│ ├── 02_constraints.adoc
│ ├── 03_system_scope_and_context.adoc
│ ├── 04_solution_strategy.adoc
│ ├── 05_building_block_view.adoc
│ ├── 06_runtime_view.adoc
│ ├── 07_deployment_view.adoc
│ ├── 08_crosscutting_concepts.adoc
│ ├── 09_architecture_decisions.adoc
│ ├── 10_quality_requirements.adoc
│ ├── 11_technical_risks.adoc
│ └── 12_glossary.adoc
├── adr/ ← Architecture Decision Records
│ ├── 0001-record-architecture-decisions.md
│ ├── 0002-use-postgresql.md
│ ├── 0003-adopt-event-sourcing.md
│ └── README.md ← ADR index with status table
├── images/ ← Embedded screenshots, diagrams
├── README.md ← Project overview
└── docker-compose.yml ← Structurizr Lite
```
### How the Three Methodologies Relate
| Component | Purpose | Created By | Consumed By |
|---|---|---|---|
| `model/system.dsl` | C4 model (all levels) | Technical architect | Structurizr renders 4 diagrams |
| `src/09_architecture_decisions.adoc` | arc42 decision section | Technical architect | Humans reading arc42 docs |
| `adr/0002-use-postgresql.md` | Full ADR content | Technical architect | Structurizr imports via `!adrs` |
| `docker-compose.yml` | Local preview | Team | `docker compose up` → browser |
### Reference Implementations
- **dzimchuk/architecture-as-code** — Structurizr DSL + arc42 AsciiDoc + ADRs + Docker Compose. The cleanest minimal example. https://github.com/dzimchuk/architecture-as-code
- **milanm/architecture-docs** — Same approach but with PlantUML diagram export and GitHub Pages CI. https://github.com/milanm/architecture-docs
- **bitsmuggler/arc42-c4-example** — arc42 template filled out for an Internet Banking System. https://bitsmuggler.github.io/arc42-c4-software-architecture-documentation-example/
---
## 5. Tool Comparison
| Criteria | Structurizr | C4-PlantUML | Mermaid |
|---|---|---|---|
| **Model consistency** | Single model → all 4 diagrams | Per-file includes | Per-file manual |
| **Learning curve** | Medium (DSL syntax) | Low (PlantUML) | Low |
| **ADR integration** | Native (`!adrs` keyword) | None | None |
| **arc42 integration** | Native (`!docs` keyword) | None | None |
| **CI readiness** | CLI + Docker image | PlantUML CLI | `mmdc` CLI |
| **GitHub rendering** | No (needs Structurizr viewer) | Via PlantUML GitHub Action | Native (if flowchart syntax) |
| **Local preview** | Structurizr Lite (Docker) | PlantUML server | VS Code plugins |
| **Layout** | Auto + manual (drag to arrange) | Auto only | Auto via `---` direction |
## 6. Further Reading
- Structurizr DSL cookbook: https://docs.structurizr.com/dsl/cookbook/
- Structurizr DSL language reference: https://docs.structurizr.com/dsl/language
- Structurizr ADR integration: https://docs.structurizr.com/dsl/adrs
- Structurizr "as code" philosophy: https://docs.structurizr.com/as-code
- C4-PlantUML: https://github.com/plantuml-stdlib/C4-PlantUML
- docToolChain: https://github.com/docToolchain/docToolchain
- dzimchuk AaC example: https://github.com/dzimchuk/architecture-as-code
- milanm AaC example: https://github.com/milanm/architecture-docs
- CI pipeline templates (GitHub Actions, GitLab CI, ForgeJo): `references/ci-pipeline-templates.md`
@@ -0,0 +1,20 @@
# C4-to-Pyramid Mapping
## Mapping Table
| C4 Level | Pyramid Layer | Mermaid Path | Structurizr DSL Path | Consumer |
|----------|--------------|--------------|----------------------|----------|
| Level 1: System Context | **L1** (01-summary/) | 01-summary/system-context.md | `docs/arch/model/system.dsl` (systemContext view) | Any stakeholder needing the big picture |
| Level 2: Container | **L2** (02-analysis/) | 02-analysis/structural-views/container.md | `docs/arch/model/system.dsl` (container view) | Developers, integrators |
| Level 3: Component | **L2** (02-analysis/) | 02-analysis/structural-views/components.md | `docs/arch/model/system.dsl` (component view) | Component developers |
| Level 4: Code | **L3** (03-dossiers/) | 03-dossiers/code-level-detail.md | `docs/arch/model/system.dsl` (code view) | Implementers, code reviewers |
**Note on Structurizr DSL paths:** All four C4 levels are defined in a single `system.dsl` file. The `system.dsl` path is the same for all levels because Structurizr generates all diagrams from one model. The difference is which **view** is rendered: `systemContext` for L1, `container` for L2, `component` for L3, `code` for L4. See `references/architecture-as-code-ecosystem.md` for the full Structurizr reference.
## Why C4 Maps Cleanly
C4 is the only architecture methodology with a built-in depth hierarchy. Its four zoom levels correspond naturally to the three pyramid layers (with Levels 2-3 both resolved as separate L2 analysis files). No other methodology maps this cleanly.
## Key Principle
C4 is fundamentally a visual notation. It communicates structure to someone who already understands the domain. It does NOT communicate rationale (that's ADRs) or constraints (that's arc42). The three methodologies are complementary, not competitive.
@@ -0,0 +1,362 @@
# CI Pipeline Templates for Architecture Documentation
Platform-specific CI/CD pipeline templates for automating Structurizr-based architecture documentation — validation, diagram export, static site generation, and deployment.
All templates use the **Docker image** `structurizr/cli:latest` to avoid Java runtime dependencies on CI runners.
## Pipeline Stages (Common Across Platforms)
Every pipeline follows the same logical sequence:
```
1. validate → structurizr-cli validate -w docs/arch/model/system.dsl
2. inspect → structurizr-cli inspect -w docs/arch/model/system.dsl
3. export → structurizr-cli export -w docs/arch/model/system.dsl -format mermaid -output site/diagrams
4. site → structurizr-cli export -w docs/arch/model/system.dsl -format static -output site
5. deploy → Platform-specific Pages or artifact publishing
```
Not all stages run on every trigger. PRs typically run only stages 1-2 (validation). Merges to main run the full pipeline.
---
## 1. GitHub Actions
### Pipeline A: PR Validation (Stages 1-2 Only)
Path: `.github/workflows/validate-architecture.yml`
```yaml
name: Validate Architecture Docs
on:
pull_request:
paths:
- 'docs/arch/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Structurizr DSL
uses: docker://structurizr/cli:latest
with:
args: validate -w docs/arch/model/system.dsl
- name: Inspect for architectural drift
uses: docker://structurizr/cli:latest
with:
args: inspect -w docs/arch/model/system.dsl
```
### Pipeline B: Full Deploy to GitHub Pages (Stages 1-5)
Path: `.github/workflows/deploy-architecture-site.yml`
```yaml
name: Deploy Architecture Documentation
on:
push:
branches: [main]
paths:
- 'docs/arch/**'
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Structurizr DSL
uses: docker://structurizr/cli:latest
with:
args: validate -w docs/arch/model/system.dsl
- name: Inspect for architectural drift
uses: docker://structurizr/cli:latest
with:
args: inspect -w docs/arch/model/system.dsl
- name: Export Mermaid diagrams
uses: docker://structurizr/cli:latest
with:
args: export -w docs/arch/model/system.dsl -format mermaid -output site/diagrams
- name: Export static site
uses: docker://structurizr/cli:latest
with:
args: export -w docs/arch/model/system.dsl -format static -output site
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: site
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
### Alternative: Marketplace Action
A community action `structurizr/structurizr-cli-action` wraps the CLI as a dedicated action step:
```yaml
- name: Validate with marketplace action
uses: structurizr/structurizr-cli-action@v1
with:
args: validate -w docs/arch/model/system.dsl
```
The Docker-based approach above is more portable and works identically on ForgeJo.
---
## 2. GitLab CI
Path: `.gitlab-ci.yml`
```yaml
stages:
- validate
- export
- pages
validate-architecture:
stage: validate
image:
name: structurizr/cli:latest
entrypoint: [""]
script:
- /usr/local/structurizr-cli/structurizr.sh validate -w docs/arch/model/system.dsl
- /usr/local/structurizr-cli/structurizr.sh inspect -w docs/arch/model/system.dsl
only:
changes:
- docs/arch/**/*
except:
- main
export-diagrams:
stage: export
image:
name: structurizr/cli:latest
entrypoint: [""]
script:
- /usr/local/structurizr-cli/structurizr.sh export -w docs/arch/model/system.dsl -format mermaid -output public/diagrams
- /usr/local/structurizr-cli/structurizr.sh export -w docs/arch/model/system.dsl -format static -output public
artifacts:
paths:
- public
only:
- main
pages:
stage: pages
script:
- echo "Publishing architecture documentation to GitLab Pages"
artifacts:
paths:
- public
only:
- main
environment: production
```
**Notes:**
- The `entrypoint: [""]` override is required to use the Structurizr CLI as a command rather than a long-running process
- GitLab Pages serves from the `public/` directory — the export step targets `public/` directly
- The `except: main` on validate ensures it runs on feature branches but not on the main branch (redundant with `only: changes` but explicit)
---
## 3. ForgeJo (Gitea Actions)
ForgeJo is a fork of Gitea. Gitea 1.19+ ships **Gitea Actions** as a built-in CI/CD solution — a GitHub Actions compatible runner using `act`. Workflows go in `.gitea/workflows/` and use the same syntax as GitHub Actions.
### Pipeline A: PR Validation
Path: `.gitea/workflows/validate-architecture.yml`
```yaml
name: Validate Architecture Docs
on:
pull_request:
paths:
- 'docs/arch/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Structurizr DSL
uses: docker://structurizr/cli:latest
with:
args: validate -w docs/arch/model/system.dsl
- name: Inspect for architectural drift
uses: docker://structurizr/cli:latest
with:
args: inspect -w docs/arch/model/system.dsl
```
### Pipeline B: Full Deploy (Artifact-based)
Path: `.gitea/workflows/deploy-architecture.yml`
```yaml
name: Build Architecture Documentation
on:
push:
branches: [main]
paths:
- 'docs/arch/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Structurizr DSL
uses: docker://structurizr/cli:latest
with:
args: validate -w docs/arch/model/system.dsl
- name: Export Mermaid diagrams
uses: docker://structurizr/cli:latest
with:
args: export -w docs/arch/model/system.dsl -format mermaid -output site/diagrams
- name: Export static site
uses: docker://structurizr/cli:latest
with:
args: export -w docs/arch/model/system.dsl -format static -output site
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: architecture-docs
path: site
```
**Deploy note:** Gitea/ForgeJo does not have a built-in Pages deployment in all versions (unlike GitHub Pages or GitLab Pages). Options for hosting the generated static site:
1. **Download artifact manually** — developers download from the Actions run page
2. **External hosting** — add a step to rsync/scp to a web server:
```yaml
- name: Deploy to web server
run: |
rsync -avz --delete site/ user@server:/var/www/architecture/
```
3. **Woodpecker CI** — if your ForgeJo instance uses Woodpecker instead of Gitea Actions, see the note below
### Woodpecker CI Alternative
If the ForgeJo instance uses Woodpecker CI (not Gitea Actions), the schema is different:
```yaml
# .woodpecker.yml
pipeline:
validate:
image: structurizr/cli:latest
commands:
- /usr/local/structurizr-cli/structurizr.sh validate -w docs/arch/model/system.dsl
- /usr/local/structurizr-cli/structurizr.sh inspect -w docs/arch/model/system.dsl
when:
path:
include: [docs/arch/**]
export:
image: structurizr/cli:latest
commands:
- /usr/local/structurizr-cli/structurizr.sh export -w docs/arch/model/system.dsl -format mermaid -output site/diagrams
- /usr/local/structurizr-cli/structurizr.sh export -w docs/arch/model/system.dsl -format static -output site
when:
branch: main
deploy:
image: alpine:latest
commands:
- echo "Site generated in ./site — deploy via rsync, S3, or artifact download"
when:
branch: main
```
---
## 4. Pipeline Selection Guide
| Situation | Trigger | Stages | Pipeline |
|---|---|---|---|
| PR changes architecture docs | `pull_request` | 1-2 (validate + inspect) | Short validation |
| Merge to main | `push main` | 1-5 (full pipeline) | Full deploy |
| Ad-hoc manual run | `workflow_dispatch` | 1-5 (full pipeline) | Full deploy |
---
## 5. Customization Notes
### Path Scoping
All templates use `docs/arch/**` as the path filter. Adjust to match your actual architecture directory:
| Directory Convention | Path Pattern |
|---|---|
| AaC standard (`docs/arch/`) | `docs/arch/**` |
| ADR + docs (`docs/adr/`, `docs/`) | Add multiple paths: `['docs/adr/**', 'docs/model/**']` |
| Root-level (`model.dsl` at project root) | `*.dsl` |
| Monorepo with multiple systems | `services/*/docs/arch/**` |
### PNG/SVG Export Limitation
The Structurizr CLI can only export Mermaid, PlantUML, DOT, and static HTML. For PNG/SVG rendering, you need headless Chrome + Puppeteer. Scripts are available at:
https://github.com/structurizr/puppeteer
This adds significant CI complexity (Chrome installation, rendering time). For most CI pipelines, the static HTML site with interactive diagrams (Mermaid) is sufficient.
### vNext Migration
The Structurizr CLI is deprecated in favor of new vNext commands. When vNext stabilizes:
- The binary name may change (`structurizr.sh` → `structurizr`)
- Flag syntax may change (`-workspace` → `--workspace`)
- The pipeline structure (validate → export → deploy) and Docker image (`structurizr/cli`) will remain the same
Monitor https://docs.structurizr.com/commands for updates.
### Trigger on Specific File Types
To only run when the DSL or ADR files change (not images or unrelated docs):
```yaml
paths:
- 'docs/arch/model/**/*.dsl'
- 'docs/arch/adr/**/*.md'
- 'docs/arch/src/**/*.adoc'
```
---
## 6. Further Reading
- Structurizr CLI installation: https://docs.structurizr.com/cli/installation
- Structurizr CLI export: https://docs.structurizr.com/cli/export
- Structurizr static site: https://docs.structurizr.com/static
- GitHub Actions marketplace (Structurizr): https://github.com/marketplace/actions/structurizr-cli-action
- Gitea Actions overview: https://docs.gitea.com/usage/actions/overview
- Woodpecker CI: https://woodpecker-ci.org/
@@ -0,0 +1,6 @@
# Source index
- **Source repository:** https://github.com/magnus919/hermes-profiles
- **Inspected commit:** `867a555`
- **Imported source directory:** `architecture/c4-diagramming`
- **Porting boundary:** Retained portable methodology, templates, scripts, and references. Removed or generalized Hermes profile, task-orchestration, memory, and rigid response-handoff assumptions.