DEV Community

Viacheslav Poturaev
Viacheslav Poturaev

Posted on

Publishing Markdown to Confluence using GitHub Actions

TL;DR We're going to setup automated Markdown export from a GitHub repository to Confluence to benefit from knowledge locality in a centralized storage.

Markdown is a lightweight markup language for creating formatted text using a plain-text editor.

https://en.wikipedia.org/wiki/Markdown

With the growing popularity of GitHub and other code hosting services, Markdown has become widely used as a language for documentation. It is very convenient to keep nicely formatted documentation close to the code it describes.

While Markdown in code repositories may lack advanced features such as search index or rich web components, it has the advantages of simplicity, lower chance of becoming obsolete and clear versioning.

With the addition of support for mermaid diagrams in GitHub, Markdown has become a very powerful tool for versioned and accurate documentation.

In contrast, Atlassian Confluence acts as a centralized repository of information, often used by large organizations to share knowledge across people and departments. There are advantages to such an approach; access control and discoverability may be better. For example, access to code repositories is usually given to developers who work with it, not to people who support users of the product.

However, Confluence often becomes an information graveyard. As the codebase evolves, pages become obsolete or even misleading.

Could you have the best of both worlds? The answer is "Yes"!

We can organize the source of truth for code-related documents into Markdown files that live in code repositories, and then automatically sync changes to Confluence using GitHub Actions.

There is a markdown-confluence tool and a GitHub action around it that makes the export process much easier than it could have been.

Let's take an example repo and configure export of OpenAPI documentation and handwritten README.md into Confluence.

First thing to do is to get an API token. If you have enough permissions, you can create one at your profile page, otherwise you'll probably need to contact a person that manages your Confluence.

Confluence API token

Then you need to provide credentials to GitHub Actions with repository secrets, use email for ATLASSIAN_USERNAME and API token for ATLASSIAN_API_TOKEN.

GitHub Actions secrets

I have a toy service that I used for one of my previous posts. It has a GitHub Action workflow to keep the OpenAPI documentation up to date on a GitHub wiki page.

...
      - name: Checkout wiki
        uses: actions/checkout@v2
        with:
          repository: ${{github.repository}}.wiki
          path: wiki
      - name: Build openapi.json
        run: |
          make build
          ./bin/* -openapi > openapi.json
          cat ./openapi.json
      - name: Generate markdown docs
        uses: docker://swaggest/swac
        with:
          args: /bin/sh -c "swac markdown ./openapi.json --add-schema-url openapi.json --out ./wiki/API-Docs.md;mv -f ./openapi.json ./wiki/openapi.json"
      - name: Push to wiki
        run: |
          cd wiki
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git add .
          git diff-index --quiet HEAD || git commit -m "Add changes" && git push
Enter fullscreen mode Exit fullscreen mode

Let's upgrade this workflow to push a document to Confluence.

NOTE: Official doc has a misleading suggestion of markdown-confluence/publish@v1, workflow fails with
Error: Unable to resolve action markdown-confluence/publish, repository not found
markdown-confluence/publish-action@v5 works well.

      - name: Publish Markdown to Confluence
        uses: markdown-confluence/publish-action@v5
        with:
          confluenceBaseUrl: https://vearutop.atlassian.net
          confluenceParentId: 65538
          folderToPublish: wiki
          atlassianUserName: ${{ secrets.ATLASSIAN_USERNAME }}
          atlassianApiToken: ${{ secrets.ATLASSIAN_API_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Unfortunately, the result wasn't that great, Markdown flavors are different between GitHub and Confluence.

Broken Markdown rendering

Confluence doesn't allow manual anchoring with

## <a id="operations"></a> Operations
Enter fullscreen mode Exit fullscreen mode

Instead, it expects local anchors to be in form of urlencoded value with some filtering (spaces are replaced by hyphens, backticks are removed).

Also, headers within list items are not supported. Making a spoiler with <details> does not work either. These are the few things I found while experimenting with Confluence export.

Once I've updated OpenAPI Markdown generator to accommodate for these quirks, the result was much better. The list was rendered correctly, local links to schema definitions started working.

Better Markdown rendering

Now I'd like to publish a page with some images and diagrams. README.md of the repo is a good candidate. It has both images and mermaid diagrams.

Result is surprisingly good, images are displayed,

Image rendering

mermaid diagrams too (though rendered as PNG).

Mermaid rendering

Spoiler didn't work.

Spoiler rendering

GitHub Action to publish Markdown to Confluence accepts path to directory with .md files. If you need to publish under a different parent id, you'll probably need to build a directory structure and invoke publishing with different configurations as separate steps.

Here is a final example workflow.

Top comments (0)