Purpose

The purpose of this project is to show how AsciiDoc can be used to generate C4 diagrams from PlantUML, both as html and pdf.

C4 Example

The following example is based on the System Context Diagram example at the C4 Model home page. Consequently, this C4 diagram:

c4 example
Figure 1. C4 Example

is generated from this PlantUML file:

plantuml source
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@startuml
!include <C4/C4_Container>
title System Context diagram for Internet Banking System

Person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts.")
System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")
System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Rel(customer, banking_system, "Uses")
Rel_Back(customer, mail_system, "Sends e-mails to")

Rel_Neighbor(banking_system, mail_system, "Sends e-mails using", "SMTP")
Rel(banking_system, mainframe, "Gets account information from, and makes payments using")
@enduml

Build Local

Prerequisites

  • You need to have Docker installed and running.

  • Download the asciidoctor/docker-asciidoctor image:

    docker pull asciidoctor/docker-asciidoctor

Render html

This project can be rendered as html using this bash command:

generate html
1
2
3
4
5
6
7
docker run --rm \
  --volume "$(pwd)":/documents/ \
  asciidoctor/docker-asciidoctor \
  asciidoctor \
  --require asciidoctor-diagram \
  --destination-dir target \
  docs/index.adoc

Explanation

Line by line explanation of the command above:

  1. docker run starts a Docker container. The --rm option removes the container after the command has completed.

  2. --volume mount a volume to the container, i.e. the current directory (as returned by $(pwd) command) is mounted to the /documents/ directory in the running Docker container. The /documents/ directory is the default working director of the asciidoctor/docker-asciidoctor Docker image.

  3. asciidoctor/docker-asciidoctor the name of the Docker image that is used to create the Docker container.

  4. asciidoctor the AsciiDoctor command to render html.

  5. --require asciidoctor-diagram AsciiDoctor argument that requires the asciidoctor-diagram to be used (necessary for PlantUML rendering).

  6. --destination-dir target asciidoctor argument that defines the destination directory of the output files in the Docker container. In this case the target directory.

  7. docs/index.adoc the name of the AsciiDoc source file to generate the file from. Only the root document needs to be included since the other files are linked from it.

Render pdf

Alternatively, this project can be rendered as a pdf:

generate pdf
1
2
3
4
5
6
7
docker run --rm \
  --volume "$(pwd)":/documents/ \
  asciidoctor/docker-asciidoctor \
  asciidoctor-pdf \
  --require asciidoctor-diagram \
  --destination-dir target \
  docs/index.adoc

Explanation

As can be seen, rendering a pdf is very similar to rendering html. The only difference is the asciidoctor command on line 4 that has been changed to asciidoctor-pdf.

Build GitHub Actions

Build using GitHub Actions and publish to GitHub Pages:

github action
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
name: Build and deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    container:
      image: asciidoctor/docker-asciidoctor:1.54
      volumes:
        # /documents/ is the default working directory of the docker-asciidoctor container
        - ${{ github.workspace }}:/documents/

    env:
      BUILD_PATH: target
      DEPLOY_PATH: _site

    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v4

      - name: Generate html 📝
        run: >
          asciidoctor 
          --require asciidoctor-diagram
          --destination-dir ${{ env.BUILD_PATH }}
          docs/index.adoc 

      - name: Generate pdf 📝
        run: >
          asciidoctor-pdf
          --require asciidoctor-diagram
          --destination-dir ${{ env.BUILD_PATH }}
          docs/index.adoc

      - name: Copy artifacts 📂
        run: |
          apk add rsync tar
          rsync -av --exclude=".*" ${{ env.BUILD_PATH }}/ ${{ env.DEPLOY_PATH }}

      - name: Package and upload 📦
        uses: actions/upload-pages-artifact@v3

  deploy:
    needs: build
    runs-on: ubuntu-latest

    # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
    permissions:
      pages: write      # to deploy to Pages
      id-token: write   # to verify the deployment originates from an appropriate source

    # Deploy to the github-pages environment
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Deploy to GitHub Pages 🚀
        id: deployment
        uses: actions/deploy-pages@v4

Explanation

Lines Purpose

3-6

Trigger the action every time a commit is pushed to the main branch at GitHub.

9

Define the build job

10

Use Ubuntu as the GitHub runner environment.

12-16

Use the asciidoctor/docker-asciidoctor image so that the AsciiDoctor tools are available during the build.

18-20

Define paths used during the build as environment variables.

23-24

The checkout action is used by the GitHub workflow to checkout the source code.

26-31

Use the asciidoctor command to generate the docs as html in the BUILD_PATH directory.

33-38

Use the asciidoctor-pdf command to generate the docs as pdf in the BUILD_PATH directory.

40-43

Install rsync and tar since they are not available in the asciidoctor/docker-asciidoctor image. rsync is used to copy the generated files to the DEPLOY_PATH directory and tar is used by the upload-pages-artifact action.

45-46

Package and upload the files by using upload-pages-artifact. This action packages the files in the format that is required by GitHub Pages and uploads them as an artifact.

48-50

Define the upload job that depends on the build job.

53-55

Grant permissions to the action to make a GitHub Pages deployment.

58-60

Define the github-pages environment and the url to the generated site.

62-65

Use the deploy-pages action to deploy the artifact uploaded in the build job to GitHub Pages.

References