Getting project documentation done with Azure DevOps – Diagrams with PlantUML

No Comments

In our projects we rely on documentation, even if many people still assume that because of the Agile Manifesto documentation is no longer needed ;).
As far as tooling (in terms of documentation) is concerned, we very often use Confluence in projects. This tool provides a lot of possibilities for integration into the documentation process due to a large number of plugins. Whereby a wiki is actually always the last step in a documentation chain, since it is in the classic sense a knowledge base and not a real project-related living documentation. In recent years, the “docs-as-code” movement has become more and more popular. This is about keeping documentation close to the development sources and making it available based on lightweight markup languages, such as Markdown and Asciidoc(tor). And it is precisely this “docs-as-code” that is also increasingly becoming part of products and platforms such as Gitlab and Azure DevOps. Azure DevOps even takes a new approach here. A wiki is provided on the basis of a Git repository. The content can be created using Markdown. With this wiki, we now have a first possibility to establish “docs-as-code” in a project. Azure goes a small step further and extends “docs-as-code” with the integrated Mermaid by “diagrams-as-code”.
With “diagrams-as-code”, we are enabled to create diagrams within a repository and have them versioned with the help of a DSL.


    loop Daily query
        Alice->>Bob: Hello Bob, how are you?
        alt is sick
            Bob->>Alice: Not so good :(
        else is well
            Bob->>Alice: Feeling fresh like a daisy

        opt Extra response
            Bob->>Alice: Thanks for asking

Well, that is good so far. Unfortunately, Microsoft has not managed to update to the latest version of Mermaid for almost two years (Developer Community). So we can’t use the latest features of Mermaid, we only have the option of flowcharts, sequence charts or gant charts to choose from.


Since I regularly work with entity-relationship models in my current project and usually rely on PlantUML for the representation, I wanted to use this again.


' hide the spot
hide circle

' avoid problems with angled crows feet
skinparam linetype ortho

entity "Entity01" as e01 {
  *e1_id : number <<generated>>
  *name : text
  description : text

entity "Entity02" as e02 {
  *e2_id : number <<generated>>
  *e1_id : number <<FK>>
  other_details : text

entity "Entity03" as e03 {
  *e3_id : number <<generated>>
  e1_id : number <<FK>>
  other_details : text

e01 ||..o{ e02
e01 |o..o{ e03


Unfortunately, a direct integration into the Azure DevOps Wiki is currently not planned for PlantUML. We now need to find a solution that helps us to fully comply with the “docs-as-code” approach. Since “docs-as-code” is basically based on a pipeline, we will try to generate the graphics and diagrams in exactly this way. Since PlantUML is delivered as a JAR, we need to provide a corresponding runtime environment for the pipeline. This is done in the form of a Docker image which we then make available as a container within the pipeline. You can find the corresponding image in the Docker Hub. In the Git repo you can also find the following Dockerfile, which is the basis of the image:

LABEL maintainer="Daniel Kocot <>" \
      description="Internal Docker image for PlantUML"


RUN apk update
RUN apk add --no-cache graphviz openjdk8-jre curl ttf-droid
RUN mkdir /app
RUN curl -L${PLANTUML_VERSION}.jar/download -o /app/plantuml.jar
RUN apk del curl

ENTRYPOINT [ "java", "-jar", "/app/plantuml.jar" ]

Azure DevOps

Now we can create a repository in Azure DevOps that will contain the sources for graphics and diagrams. In this repository, there must be a plantuml folder. Now we need to create a pipeline for this repo, which basically converts all .puml files in the plantuml folder to PNG format on pushes to the repo. Subsequently, after moving the PNG files to a default build directory, they are published as an artifact using the UniversalPackages task as a package. In Azure DevOps, artifacts can be reused inside and outside projects by using a package feed.

- main

  vmImage: ubuntu-latest

- script: docker run -v $(Build.Repository.LocalPath)/plantuml:/plantuml --rm -i codecentric/plantuml-docker:1.2021.16 plantuml/*.puml -w /plantuml -o ./output
  displayName: Export PlantUML diagrams

- task: CopyFiles@2
  displayName: 'Copy generated PNGs by PlantUML'
    SourceFolder: './plantuml/output'
    Contents: '*.png'
    TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: UniversalPackages@0
  displayName: 'Publish PlantUML images'
    command: publish
    publishDirectory: '$(Build.ArtifactStagingDirectory)'
    vstsFeedPublish: '<NameofAzureDevOpsProject>/PlantUML-Images'
    vstsFeedPackagePublish: 'plantuml-images'
    packagePublishDescription: 'PlantUML Images'

At this point, we can use the feed to check in the automated PNG files to the wiki repository via git.

  vmImage: ubuntu-latest
- checkout: self
  persistCredentials: true
- task: CmdLine@2
    script:   git switch -c plantuml-images
- task: UniversalPackages@0
  displayName: 'Download PlantUML images'
    command: download
    downloadDirectory: '$(Build.SourcesDirectory)/plantuml-images'
    vstsFeed: '<NameofAzureDevOpsProject>/PlantUML-Images'
    vstsFeedPackage: 'plantuml-images'
    vstsPackageVersion: '*'
- task: CmdLine@2
    script: |
      git config --global <>
      git config --global "<>"
      git pull
      git add .
      git commit -m "added PNGs generated by PlantUML"
      git push --set-upstream origin plantuml-images
  displayName: Adding PNGs by using GIT

A new branch plantuml-images is being created by the push. Subsequently, this must be merged with the main branch via a pull request. This allows us to include the PNG files within the wiki supported by the Azure DevOps API (<organizationName>/<projectId>/_apis/git/repositories/<area>/items?path=/plantuml-images/<image-name>.png) and the img HTML tag.


This blog post describes a way to integrate PlantUML with the Azure DevOps Wiki. Even though the integration requires a lot of knowledge about Azure DevOps, it is still a very simple solution, but can also be extended in terms of linking build pipelines.

Daniel has been part of the codecentric team since October 2016. Since the beginning of 2022 he works as Senior Solution Architect at the Dortmund branch. Starting as a consultant with a focus on application lifecycle management, his focus shifted more and more towards APIs. In addition to numerous customer projects and his involvement in the open source world around APIs, our Head of API Experience & Operations is also a frequent speaker at conferences.


Your email address will not be published.