Skip to content
Connect an agent

CI/CD

Diagrams in GitLab CI/CD

How to fail a merge request whose diagram pictures are stale, or whose diagrams made from files have drifted, with the Plotwork CI/CD component for GitLab. It is for anyone who keeps Plotwork diagrams in a GitLab project.

For
  • GitLab

TL;DR

QuestionAnswer
What is the component?gitlab.com/plotwork/plotwork-component/plotwork, in the GitLab CI/CD catalog. One include adds one job.
Is it released?Not yet. The include below names its first version, 0.1.0, which the catalog lists once it is released. Until then, run the command line in a job of your own, as CI usage shows.
What does the job run?The pinned release of the command line, npx -y @buun_group/plotwork@0.3.0, in the image node:22. It is the same check you run on your machine.
Which modes are there?check fails on a stale picture under a diagram fence. drift fails when a diagram made from files differs from what its files make now. generate writes the diagrams again and keeps a patch in the job's artifacts.
How does a drift show in a merge request?As a failed test in the merge request's test report, one test per generated diagram.
Does it need a key?No. Only report-drift signs in to Plotwork: with an organisation key in the masked CI/CD variable PLOTWORK_API_KEY, or with no key at all through a trusted publisher and keyless: true.
Does it send my files anywhere?No. The command line reads the checkout and makes no request. report-drift sends a run's metadata, never a diagram or a file.
What if I cannot use the catalog?Run the command line in a job of your own, as CI usage shows.

1. Check every merge request

Add the component to .gitlab-ci.yml:

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      paths: 'README.md docs/**/*.md'
plotwork-diagrams:  rules:    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

The job is named by the input job-name, plotwork-diagrams by default, so a job of that name in your own file adds rules, tags, or needs to it. Without rules, the job runs in every pipeline.

A stale picture fails the job, and the log names the file and the line of the fence:

text
stale: docs/architecture.md needs sync  line 3: This diagram has no picture under it.

To fix it, run npx -y @buun_group/plotwork@0.3.0 sync on the same files and commit the Markdown and the SVGs it writes.

2. Fail a merge request on drift

When diagrams are made from Terraform, OpenAPI, Compose and other files, name them in sources of plotwork.config.json, as Diagrams as code describes. Then add the component a second time in drift mode:

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      job-name: diagrams-drift      mode: drift
diagrams-drift:  rules:    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

The job writes .plotwork/junit.xml and hands it to GitLab as a test report, so each generated diagram is a test in the merge request, failed when it drifted. The log names each change, such as Added 1 node (logs).

On a large project, check only the sources whose files changed on the branch:

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      job-name: diagrams-drift      mode: drift      since: origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
diagrams-drift:  variables:    GIT_DEPTH: 0

3. Write the diagrams again

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      job-name: diagrams-generate      mode: generate
diagrams-generate:  rules:    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

The job makes every diagram again in its workspace and keeps .plotwork/plotwork.patch in its artifacts for a week. Download it, run git apply plotwork.patch, and commit. The component holds no token and pushes nothing; a later job of your own can commit the patch with a project access token.

4. Send drift runs to the dashboard

An organisation on a plan with the drift dashboard can see every project's drift in one place. Make an organisation API key in the portal, add it to the project (or the group) as the CI/CD variable PLOTWORK_API_KEY, masked and protected, and set report-drift:

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      job-name: diagrams-drift      mode: drift      report-drift: true
What is sentWhat is never sent
The project path, the ref, the commit, the pipeline source, the job and merge request linksA diagram, a file, or a name of what changed
Per source: its name, out path, status, counts of what was added, removed, and changed, errors, and CODEOWNERS ownersThe key, which GitLab masks in the log

A refusal, such as a plan with no dashboard, is a line in the log and fails nothing. A protected variable reaches only protected branches and tags, so a merge request pipeline from another branch sends nothing unless the variable is unprotected.

The dashboard names a repository as group/project. A project in a subgroup, such as acme/platform/web, is not sent yet, and the log says so.

With no key

A trusted publisher lets the job report with no key in the project. An owner or admin adds the project under Keys and CI, CI/CD, Add GitLab, then the include sets keyless:

yaml
include:  - component: gitlab.com/plotwork/plotwork-component/plotwork@0.1.0    inputs:      job-name: diagrams-drift      mode: drift      report-drift: true      keyless: true

The job asks GitLab for an ID token with api-url as its audience, swaps it at the API for a token that lives 15 minutes, and sends the run with it. The ID token is taken out of the job's environment before the command line runs, and neither token is printed. A PLOTWORK_API_KEY that is set still wins. A refused swap is a line in the log and fails nothing.

5. Inputs

InputDefaultMeaning
job-nameplotwork-diagramsThe name of the job.
stagetestThe stage the job runs in.
modecheckcheck, generate, or drift.
paths**/*.mdcheck only: the Markdown files, separated by spaces, as globs, files, or folders.
configemptyThe settings file. Empty finds plotwork.config.json, then .plotwork/config.json.
working-directory.The folder to run in.
sinceemptydrift only: a git ref; only the sources whose files changed since it are checked.
report-driftfalsedrift only: send the run's metadata to the drift dashboard with PLOTWORK_API_KEY, or with no key when keyless is on.
keylessfalseSign in with the job's GitLab ID token through a trusted publisher when there is no PLOTWORK_API_KEY. The job always declares the ID token PLOTWORK_ID_TOKEN; with keyless: false it is removed from the environment unread.
organizationemptyThe organisation to report to. Empty is the organisation of the key.
api-urlhttps://api.plotwork.devThe Plotwork API that report-drift sends to, and the ID token's audience. Write its origin with no path or trailing slash.
cli-versionthe release the component was tested withThe release of @buun_group/plotwork the job runs.
imagenode:22The image: Node 22 or later, npx, git, and a POSIX shell.

The job keeps .plotwork/ as artifacts, on failure too: junit.xml (drift), report.json (drift with report-drift), and plotwork.patch (generate).

6. Versions and runners

Pin the component to a release, such as @0.1.0, and move the pin in a change you review. Each release of the component pins a stable release of the command line in cli-version, so a new release of either never changes your pictures by itself. To try a newer command line before the component moves, set cli-version, run sync with that release on your machine, and commit the pictures in the same change.

The job needs a runner that runs a container image (the Docker or Kubernetes executor) and can reach the npm registry. For a runner with no access to the registry, point npm at your own mirror with the CI/CD variable NPM_CONFIG_REGISTRY, and set image to an image of your registry.

See also

PageWhy
CI usageThe same check as a job of your own, on GitLab and every other CI
Diagrams as codeSources, overrides, and the drift check
Keep diagrams in sync in CIThe GitHub Action
Diagrams in Azure PipelinesThe same task for Azure DevOps
Trusted publishersReporting drift with no key
Markdown and GitHubWhat a sync writes, which GitLab shows the same way
Repository settingsDefaults for every header, and rules a merge request must pass