D2 is a cool little DSL that allows you to generate diagrams from code.
It’s quite easy to learn, and can be a much better option for developers than using drag-and-drop diagramming software.
Running it locally is simple: d2 my-diagram.d2
will generate a SVG of your diagram.
However, if your D2 code embeds remote images, those links will be embedded in the SVGs, so those images will not show in contexts where doing that isn’t allowed.
While you can generate a PNG locally, d2
relies on playwright
to take a screenshot of the SVG.
For this reason, or any other, you might want to build your diagrams in CI using GitHub Actions.
Here’s a workflow that does just that, commented for clarity:
name: 'Generate PNG diagrams'
# Triggers on new version tags with filename suffix, e.g., dns.d2 -> v1.2.3-dns
on:
push:
tags:
- 'v*.*.*-*'
# softprops/action-gh-release@v1 needs these permissions
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
Using this basic workflow, your PNG diagrams will be available under the Release tab in GitHub.