mermaid cliで外部アイコンを使ったアーキテクチャ図を出力させてみた


最終更新日:

mermaidはwebベースで動くシステム図やグラフが描けるツール。github上でもレンダリングされるなど、使い勝手がいい。2024/9月あたりにmermaidでアーキテクチャ図をかけるようになった。まだベータ版のようではあるがアーキテクチャ図をコード管理してみたい

サーバやデータベースなどの図形はデフォルトで使用できるが、AWSの各種サービスのカスタムアイコンを使いたいときなどはiconifyにあるアイコンを追加することで利用可能になっている

7/13 追記: actionsをつくった

出力先は入力ファイル直下のgeneratedフォルダを作るようにした いままでのと比べるとスクリプトがなくなってスッキリした

name: Generate Mermaid Diagrams
 
on:
  workflow_dispatch:
  pull_request:
    paths:
      - '**.mmd'
      - '**.md'
      - '.github/workflows/gen-svg.yml'
 
jobs:
  generate-diagrams:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    env:
      ICON_PACKAGES: '@iconify-json/logos @iconify-json/mdi'
 
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
 
    - name: Get changed files
      id: changed-files
      uses: tj-actions/changed-files@v45
      with:
        files: |
          **/*.mmd
          **/*.md
 
    - name: Generate mermaid diagrams to svg
      if: steps.changed-files.outputs.any_changed == 'true'
      uses: uni-3/render-mermaid-svg@v2
      with:
        input-files: ${{ steps.changed-files.outputs.all_changed_files }}
        icon-packages: ${{ env.ICON_PACKAGES }}
 
    - name: Auto commit
      uses: stefanzweifel/git-auto-commit-action@v5
      with:
        commit_message: Generate Mermaid diagrams for changed files
        file_pattern: '**/*.svg'

Generate mermaid diagrams to svgのログ

Generating diagrams with minlag/mermaid-cli:latest
Input files: docs/test.md
Processing 'docs/test.md' -> 'docs/generated/test.svg'
Found 1 mermaid charts in Markdown input

✅ ./test-1.svg

7/10 追記: docker iamgeを使うようにした

公式のdocker imageがあることに気づいたので改修 いい加減latestのバージョンでもiconPacksオプション対応しているので変更 package.jsonとかpuppeteer-config.jsonなどの環境設定ファイルをリポジトリで管理する必要がなくなったのでスッキリした

acitons file

name: Generate Mermaid Diagrams
 
on:
  workflow_dispatch:
  pull_request:
    paths:
      - '**.mmd'
      - '**.md'
      - '.github/workflows/gen-svg.yml'
 
jobs:
  generate-diagrams:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    env:
      ICON_PACKAGES: '"@iconify-json/logos" "@iconify-json/mdi"'
      # 使用するDockerイメージ
      MERMAID_IMAGE: docker.io/minlag/mermaid-cli:latest
 
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
 
    - name: Get changed files
      id: changed-files
      uses: tj-actions/changed-files@v45
      with:
        files: |
          **/*.mmd
          **/*.md
 
    - name: Pull mermaid cli image
      if: steps.changed-files.outputs.any_changed == 'true'
      run: docker pull ${{ env.MERMAID_IMAGE }}
 
    - name: Generate diagrams
      if: steps.changed-files.outputs.any_changed == 'true'
      env:
        CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
      run: |
        echo "Generating diagrams for changed files: $CHANGED_FILES"
        echo "with icons for archtecture diagrams: ${{env.ICON_PACKAGES}}"
        for file in ${CHANGED_FILES}; do
          output_file=$(echo "$file" | sed 's/\.\(mmd\|md\)$/.svg/' | sed 's/^docs\//docs\/auto_generated\//')
 
          echo "Processing $file"
          docker run --rm -t \
              -v "${{ github.workspace }}:/data" \
              -w "/data" \
              ${{ env.MERMAID_IMAGE}} \
              -i "$file" \
              -o "$output_file" \
              --iconPacks ${{env.ICON_PACKAGES}} \
              --puppeteerConfigFile /puppeteer-config.json
 
        done
 
    - name: Auto commit
      uses: stefanzweifel/git-auto-commit-action@v5
      with:
        commit_message: Generate Mermaid diagrams for changed files
        file_pattern: '**/*.svg'

makefile

ローカルで試しに生成したいときのスクリプト

.PHONY: gen
 
gen:
	for file in docs/*.mmd docs/*.md; do \
		docker run --rm -v "$(PWD):/data" -w /data docker.io/minlag/mermaid-cli:latest \
		--input "/data/$$file" --output "/data/$${file%.*}.svg" \
		--iconPacks "@iconify-json/logos" "@iconify-json/mdi"; \
	done

1/29 追記:mermaid-cliにiconifyのアイコンを追加する機能が追加されている。リリースはまだっぽい

実装方針はあってたっぽいので。PRにすればよかったか 該当PR

該当packageの追加

npm install "git+https://github.com/merm
aid-js/mermaid-cli#8a45bb38cfa3bcd3752f4abfd1ea630891a655b5"

actions file

svgを生成、commitするgithub actions。envにて追加したいicon packagesを指定している

.mdファイルについては、mermaid記法の部分について抜き出して、各々別な画像ファイルにする

name: Generate Mermaid Diagrams
 
on:
  workflow_dispatch:
  pull_request:
    paths:
      - '**.mmd'
      - '**.md'
      - '.github/workflows/gen-svg.yml'
 
jobs:
  generate-diagrams:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    env:
      ICON_PACKAGES: '"@iconify-json/logos" "@iconify-json/mdi"'
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
    
    - name: Get changed files
      id: changed-files
      uses: tj-actions/changed-files@v45
      with:
        files: |
          **/*.mmd
          **/*.md
 
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
    
    - name: Install dependencies
      if: steps.changed-files.outputs.any_changed == 'true'
      run: npm ci
    
    - name: Generate Diagrams
      if: steps.changed-files.outputs.any_changed == 'true'
      env:
        CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
 
      run: |
        echo "Generating diagrams for changed files: $CHANGED_FILES"
        echo "with icons for archtecture diagrams: ${{env.ICON_PACKAGES}}"
        for file in ${CHANGED_FILES}; do
          output_file=$(echo "$file" | sed 's/\.\(mmd\|md\)$/.svg/' | sed 's/^docs\//docs\/auto_generated\//')
 
          echo "Processing $file"
          npx mmdc -i "$file" -o "$output_file" --iconPacks ${{env.ICON_PACKAGES}} --puppeteerConfigFile puppeteer-config.json
 
        done
 
    - name: Auto Commit
      uses: stefanzweifel/git-auto-commit-action@v5
      with:
        commit_message: Generate Mermaid diagrams for changed files
        file_pattern: '**/*.svg'

以下旧記事

  • 2024-12-19時点の記事

実装メモは残したいのでおいておくことにする

AWSの構成図を作ろうとしたところ、追加したアイコンがレンダリングされたファイルを保存する方法がキャプチャくらいしかなかったため、mermaid-cliを用いてコマンドから保存できるようにしてみた。ついでにgithub actionsで自動生成するのも試してみたのでその手順をかいておく

リポジトリがこれ

https://github.com/uni-3/mermaid-docs

設定

大本のmermaid-cli自体を改修するには全体から見直すような感じがしたので断念して、簡単に引数を追加してmermaid.registerIconPacks()を実行するようにした、forkしたリポジトリはこちら

—icons という引数を指定することで、追加したいicon packを取得してレンダリングするようにしてみている

入力

mermaid形式でかかれたファイル.mmdとしている。.mdでもいいが、mermaid-cliは.md拡張子のとき、複数箇所のmermaidの図をすべて別ファイルとしてで出力する。入力ファイル名と出力ファイル名を1対1で対応させたいので.mmd前提にしている

デフォルトではダウンロードされていないlogos、mdiのicon packを使っている

  • ファイル

test.mmdとして作成

```mermaid
architecture-beta
    group api(logos:aws-lambda)[API]

    service db(logos:aws-aurora)[Database] in api
    service disk1(logos:aws-glacier)[Storage] in api
    service disk2(logos:aws-s3)[Storage] in api
    service server(logos:aws-ec2)[Server] in api
    service alert(mdi:alert-octagram)[icon] in api

    db:L -- R:server
    disk1:T -- B:server
    disk2:T -- B:db
```
  • コマンド
# instal cli
node install github:uni-3/mermaid-cli#add-iconify-support
 
# generate mmd as svg with iconify
npx mmdc -i ./docs/*.mmd --icons logos mdi

出力

test.svgとして作成される

aws-arch

gihtub actionsでやるとこんな感じauto-commit系のactionsたくさんあったが、どれがいいかはよくわかってない

name: Generate Mermaid Diagrams
 
on:
  pull_request:
    paths:
      - '**.mmd'
 
jobs:
  generate-diagrams:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    env:
      ICON_PACKAGES: '["logos", "mdi"]'
    
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
    
    - name: Get changed files
      id: changed-files
      uses: technote-space/get-diff-action@v6
      with:
        PATTERNS: |
          **/*.mmd
 
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
    
    - name: Install dependencies
      run: npm ci
      if: env.GIT_DIFF_FILTERED
    
    - name: Generate Diagrams
      run: |
        ICONS=$(echo '${{ env.ICON_PACKAGES }}' | jq -r '. | join(" ")' | sed 's/^/--icons /')
        CHANGED_FILES=${{ env.GIT_DIFF_FILTERED }}
 
        if [ -n "CHANGED_FILES" ]; then
          echo "Generating diagrams for changed files: $CHANGED_FILES"
          for file in $CHANGED_FILES; do
            output_file=$(echo "$file" | sed 's/\.mmd$/.svg/' | sed 's/^docs\//docs\/auto_generated\//')
 
            echo "Processing $file"
            npx mmdc -i "$file" -o "$output_file" --icons $ICONS --puppeteerConfigFile puppeteer-config.json
          done
        else
          echo "No Mermaid files changed"
          exit 0
        fi
    
    - name: Auto Commit
      uses: stefanzweifel/git-auto-commit-action@v5
      with:
        commit_message: Generate Mermaid diagrams for changed files
        file_pattern: '**/*.svg'
        pull_style: rebase

puppeteer周りでエラーが出たので、リポジトリには以下のpuppeteer-config.jsonを追加している。chatGPTにきいて解決したので内容はよくわかってない

Error: Failed to launch the browser process!
[1222/055557.168688:FATAL:zygote_host_impl_linux.cc(128)] No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. Otherwise see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the (older) SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.
 
TROUBLESHOOTING: https://pptr.dev/troubleshooting
  • puppeteer-config.json
{
    "args": [
        "--no-sandbox"
    ]
}

ちなみにvscode上でプレビューをみながら編集したいときは Markdown Preview Enhancedのextensionを使う方法もある

ちゃんとicon packの追加もできる(ref. https://shd101wyy.github.io/markdown-preview-enhanced/#/ja-jp/diagrams?id=mermaid)

しかし、エディタからexportするとiconifyを考慮して出力できなかったので、プレビュー用として使った