Dumont Digital logo

Generate D2 PNG diagrams in GitHub Actions

Published

D2 is a language that generates diagrams from code. It’s easy to learn, and presents a superior alternative for developers over traditional drag-and-drop diagramming tools.

Executing D2 locally is simple: d2 my-diagram.d2 produces an SVG of your diagram.

However, if your D2 code includes remote images, the links will be embedded directly into the SVGs, so images will not show in contexts where that isn’t allowed.

Although generating a PNG locally is equally trivial using d2 my-diagram.d2 my-diagram.png, doing so depends on playwright for capturing a screenshot of the SVG.

This necessity, among other reasons, may prompt the decision to automate diagram creation in CI using GitHub Actions.

Below is a commented workflow that does just that. Note that it assumes a repo setup where diagrams reside at the root, and are updated manually by pushing a version tag.

Customize it to fit your specific requirements.

name: 'Generate PNG diagrams'

# Triggers on new version tags with filename suffix, e.g., dns.d2 -> v1.2.3-dns
on:
  push:
    tags:
      - 'v*.*.*-*'

# Necessary permissions for softprops/action-gh-release@v1
permissions:
  contents: write

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Extracts the file name from the pushed tag
      - name: Extract filename
        run: echo "FILENAME=${GITHUB_REF#refs/tags/*-}" >> $GITHUB_ENV

      - name: Install d2
        run: curl -fsSL https://d2lang.com/install.sh | sh -s --

      # Caches playwright without relying on `package.json`.
      # If you want to force a playwright upgrade, delete the cache in the GitHub Actions UI.
      - name: Cache playwright binaries
        id: cache-playwright
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-cache

      # Installs playwright if it's not already cached
      - name: Install playwright
        if: steps.cache-playwright.outputs.cache-hit != 'true'
        run: npx playwright install --with-deps chromium

      # Assumes the diagram is located at the repo's root. Adjust according to your project structure.
      - name: Generate diagram
        run: d2 ${{ env.FILENAME }}.d2 ${{ env.FILENAME }}.png

      # Publishes the PNG under GitHub's Release tab
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          files: ${{ env.FILENAME }}.png

With this basic workflow, your D2-generated PNG diagrams will be available under the Releases section in GitHub.


© 2024 freddydumont