Skip to content

Latest commit

 

History

History
374 lines (286 loc) · 18.8 KB

README.md

File metadata and controls

374 lines (286 loc) · 18.8 KB

Structurizr Site Generatr

A static site generator for C4 architecture models created with Structrizr DSL. See Background for the story behind this tool.

Click here to see an example of a generated site based on the Big Bank plc example from https://structurizr.com. This site is generated from the example workspace in this repository.

Features

  • Generate a static HTML site, based on a Structurizr DSL workspace.
  • Generates diagrams in SVG, PNG and PlantUML format, which can be viewed and downloaded from the generated site.
  • Easy browsing through the site by clicking on software system and container elements in the diagrams.
  • Start a development server which generates a site, serves it and updates the site automatically whenever a file that's part of the Structurizr workspace changes.
  • Include documentation (in Markdown format) in the generated site. Both workspace level documentation and software system level documentation are included in the site.
  • Include ADR's in the generated site. Again, both workspace level ADR's and software system level ADR's are included in the site.
  • Include static assets in the generated site, which can be used in ADR's and documentation.
  • Generate a site from a Structurizr DSL model in a Git repository. Supports multiple branches, which makes it possible to for example maintain an actual state in master and one or more future states in feature branches. The generated site includes diagrams for all valid configured or detected branches.
  • Include a version number in the generated site.

Getting Started

To get started with the Structurizr Site Generatr, you can either:

  • Install it to your local machine (recommended for the best experience), or
  • Execute it on your local machine via a container (requires Docker)

Please note: The intended use of the Docker image is to generate a site from a CI pipeline. Using it for model development is possible, but not a usage scenario that's actively supported.

Installation using Homebrew - Recommended

As this approach relies on Homebrew, ensure this is already installed. For Windows and other operating systems not supported by Homebrew, please use the Docker approach instead.

To install Structurizr Site Generatr execute the following commands in your terminal:

brew tap avisi-cloud/tools
brew install structurizr-site-generatr

structurizr-site-generatr --help

Periodically, you would have to update your local installation to take advantage of any new Structurizr Site Generatr releases.

Manual installation

If using Homebrew is not an option for you, it's also possible to install Structurizr Site Generatr manually. This can be done as follows:

  • Consult the Structurizr Site Generatr releases and choose the version you wish to use
  • Download the .tar.gz or .zip distribution
  • Extract the archive using your favourite tool
  • For ease of use, it's recommended to add Structurizr Site Generatr's bin directory to your PATH

Docker

Though local installation is recommended for development where possible, Structurizr Site Generatr is also a packaged as a Docker image. Therefore, to use this approach, ensure Docker is already installed. Additionally, for Windows 10+ users, you may want to take advantage of WSL2 (Windows Subsystem for Linux). Both Docker and WSL2 are topics too vast to repeat here, so you are invited to study these as prerequisite learning for this approach.

Then to download our packaged image, consider the Structurizr Site Generatr releases and choose the version you wish to use. Then, in your terminal, execute the following:

docker pull ghcr.io/avisi-cloud/structurizr-site-generatr

Once downloaded, you can execute Structurizr Site Generatr via a temporary Docker container by executing the following in your terminal:

docker run -it --rm ghcr.io/avisi-cloud/structurizr-site-generatr --help

[Optional] Verify the Structurizr Site Generatr image with CoSign

cat cosign.pub
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzezKl0vAWSHosQ0JLEsDzNBd2nGm
08KqX+imYqq2avlbH+ehprJFMqKK0/I/bY0q5W9hQC8SLzTRJ9Q5dB9UiQ==
-----END PUBLIC KEY-----
cosign verify --key cosign.pub ghcr.io/avisi-cloud/structurizr-site-generatr

Or by using the Github repo url:

 cosign verify --key https://github.com/avisi-cloud/structurizr-site-generatr ghcr.io/avisi-cloud/structurizr-site-generatr

Usage

These examples use the example workspace in this repository.

Once installed, Structurizr Site Generatr is operated via your terminal by issuing commands. Each command is explained here:

Help

To learn about available commands, or parameters for individual commands, call Structurizr Site Generatr with the --help argument.

installed> structurizr-site-generatr --help

   docker> docker run -it --rm ghcr.io/avisi-cloud/structurizr-site-generatr --help

Usage: structurizr-site-generatr options_list
Subcommands:
    serve - Start a development server
    generate-site - Generate a site for the selected workspace.
    version - Print version information

Options:
    --help, -h -> Usage info

Version

To query the version of Structurizr Site Generatr installed / used.

installed> structurizr-site-generatr version

   docker> docker run -it --rm ghcr.io/avisi-cloud/structurizr-site-generatr version

Structurizr Site Generatr v1.1.3

Generate a website

This is the primary use case of Structurizr Site Generatr -- to generate a website from a C4 Workspace.

installed> structurizr-site-generatr generate-site -w workspace.dsl

   docker> docker run -it --rm -v c:/projects/c4:/var/model ghcr.io/avisi-cloud/structurizr-site-generatr generate-site -w workspace.dsl

Here, the --workspace-file or -w parameter specifies the input C4 Workspace DSL file to the generate-site command. Additional parameters that affect website generation can be reviewed using the --help operator.

By default, the generated website will be placed in ./build, which is overwritten if it already exisits.

For those taking the Docker approach

When using the Docker approach, the local file system must be made available to the temporary Structurizr Site Generatr container via a Docker file system volume mount. This is achieved by specifying the -v parameter with a linux-like absolute path to the folder containing the .dsl file specified via -w. See how C:\Projects\C4 has become -v c:/projects/c4:/var/model in the above example?

Generate a website from a Git repository

Instead of relying on local .dsl files only, the generate-site command can also retrieve input files from a Git repository as follows. This is particularly advantageous for demos, documentation, or CI/CD pipelines.

To explicitly name the branches that you want to build sites from you can use the --branches option.

structurizr-site-generatr generate-site
    --git-url https://github.com/avisi-cloud/structurizr-site-generatr.git
    --workspace-file docs/example/workspace.dsl
    --branches main,future,old
    --default-branch main

or you can choose to build all branches that are found in the repository and exclude specific ones by using the --all-branches and --exclude-branches options.

structurizr-site-generatr generate-site
    --git-url https://github.com/avisi-cloud/structurizr-site-generatr.git
    --workspace-file docs/example/workspace.dsl
    --all-branches
    --exclude-branches gh-pages
    --default-branch main

Both the --branches and --exclude-branches options are comma separated lists and can contain multiple branch names.

Start a development web server around the generated website

To aid composition of C4 Workspace DSL files, the serve command will generate a website from the input .dsl specified with -w and start a web server to view it. Default port for the web server is 8080. A different port for the web server can be specified with -p PORT. Additional parameters that affect website generation and the development web server can be reviewed using the --help operator.

installed> structurizr-site-generatr serve -w workspace.dsl

   docker> docker run -it --rm -v c:/projects/c4:/var/model -p 8080:8080 ghcr.io/avisi-cloud/structurizr-site-generatr serve -w workspace.dsl

By default, a development web server will be started and accessible at http://localhost:8080/ (if available).

For those taking the Docker approach

However, when using the Docker approach, this development web server is within the temporary Structurizr Site Generatr container. So Docker port mapping is needed to expose the container's port 8080 to the host (web browser). In the example above, the -p 8080:8080 argument tells Docker to bind the local machine / host's port 8080 to the container's port 8080.

Customizing the generated website

The site generator use the C4PlantUmlExporter to generate the diagrams. All properties available for the C4PlantUMLExporter, e.g. c4plantuml.tags, can be applied and affect the diagrams in the generate site. See also Diagram notation for an overview of supported features and limitations for this exporter.

The look and feel of the generated site can be customized with several additional view properties in the C4 architecture model:

Property name Description Default Example
generatr.style.colors.primary Primary site color, used for header bar background and active menu background. #333333 #485fc7
generatr.style.colors.secondary Secondary site color, used for font color in header bar and for active menu. #cccccc #ffffff
generatr.style.faviconPath Site logo location relative to the configured assets folder. When configured, the logo image will be place on the left side in the header bar. This requires the --assets-dir switch when generating the site and the corresponding file to be available in the assets folder. site/favicon.ico
generatr.style.logoPath Site favicon location relative to the configured assets folder. When configured, the favicon will be set for all generated pages. This requires the --assets-dir switch when generating the site and the corresponding file to be available in the assets folder. site/logo.png
generatr.search.language Indexing/stemming language for the search index. See Lunr language support en nl
generatr.markdown.flexmark.extensions Additional extensions to the markdown generator to add new markdown capabilities. More Details Tables Tables,Admonition
generatr.svglink.target Specifies the link target for element links in the exported svg _top _self

See the included example for usage of some those properties in the C4 architecture model example.

Running as a github action

To generate the site, for a set of branches you can use the builtin action.yml directly from your own worflow:

jobs:
  ...
  steps:
    - name: Build docs
      uses: avisi-cloud/structurizr-site-generatr@action
      with:
        repository: https://github.com/MY_ORG/MY_REPO.git
        default-branch: develop
        branches: main,develop
        workspace-file: path/to/workspace.dsl
        token: ${{ secrets.GH_ACCESS_TOKEN }}

The action will use the github workspace, rather than /var/model. Additionally, you will need to generate a personal acess token with, at least, read access to your repository.

Here's a complete example of publishing main, deveop and PR docs to github pages (the token also will need read for PRs and write for pages):

# Simple workflow for deploying static content to GitHub Pages
name: Build & Deploy Docs to Pages

on:
  # Runs on pushes targeting the design folder...
  push:
    paths:
      - 'docs/**'
  # ... and in pull requests when they are introduced or removed
  pull_request:
    types: [opened, reopened, closed]
  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: true

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Get PR head refs
        id: prs
        run: (echo -n 'LIST='; gh pr list --json headRefName |jq -r '[.[] | .headRefName] | join(",")') >> "$GITHUB_OUTPUT"
        env:
          GH_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
          GH_REPO: ${{ github.repository }}
      - name: Build
        uses: avisi-cloud/structurizr-site-generatr@action
        with:
          repository: https://github.com/MY_ORG/MY_REPO.git
          default-branch: develop
          branches: main,develop,${{ steps.prs.outputs.LIST }}
          workspace-file: docs/workspace.dsl
          token: ${{ secrets.GH_ACCESS_TOKEN }}
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v2
        with:
          path: "build/site"
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2

Contributing

We welcome contributions! Please refer to CONTRIBUTING.md for more information on how you can help.

Background

At Avisi, we're big fans of the C4 model. We use it in many projects, big and small, to document the architecture of the systems and system landscapes we're working on.

We started out by using PlantUML, combined with the C4 extension. This works well for small systems. However, for larger application landscapes, maintained by multiple development teams, this lead to duplication and inconsistency across diagrams.

To solve this problem, we needed a model based approach. Rather than maintaining separate diagrams and trying to keep them consistent, we needed to have a single model, from which diagrams could be generated. This is why we started using the Structurizr for Java library. About a year later, we migrated our models to Structurizr DSL.

We created custom tooling to generate diagrams and check them in to our Git repository. All diagrams could be seen by navigating to our GitLab repository. This is less than ideal, because we like to make these diagrams easily accessible to everyone, including our customers. This is why we decided that we needed a way of publishing our models to an easily accessible website.

This tool is the result. It's still a work in progress, but it has already proven to be very useful to us.