Monedula
monedula-gitops docs menu

Validate and preview changes in CI

Run validate, diff and apply --dry-run in a CI pipeline so every pull request shows the exact Kafka changes before anything is applied.

How-to guides 10 of 18

3 min read

Updated 9 October 2026

Markdown

On this page

On every pull request, validate, diff and apply --dry-run fail the build on a broken manifest and show reviewers the exact operations a merge would run against Kafka. None of them changes the cluster.

Before you start

  • A way to run the CLI on your CI runner. Install monedula-gitops lists the methods, including go install and the Docker image ghcr.io/monedula-dev/monedula-gitops.
  • Your manifests and a cluster config file in the repository, manifests/ and cluster.yaml on this page.
  • For the preview steps, CI secrets that provide the credentials your cluster config reads with valueFrom.env, for a principal with describe rights on the kinds your manifests declare (Least-privilege connecting principal).

Steps

1. Validate the manifests

validate parses and checks the manifests without contacting any cluster, so it needs no credentials:

monedula-gitops validate -f ./manifests

A malformed manifest fails with exit code 2 and an error that names the resource and the rule. For example, this topic asks for zero partitions:

apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaTopic
metadata:
  name: bad-topic
spec:
  clusterRef:
    name: shared
  topicName: bad.topic
  partitions: 0

validate rejects it with:

KafkaTopic bad-topic: spec.partitions must be >= 1

Add the cluster config to also check that every clusterRef names a cluster defined in it:

monedula-gitops validate -f ./manifests --cluster-config-file ./cluster.yaml

If your manifests sit in subdirectories, add -R to read them recursively.

2. Preview the changes

diff compares the manifests with the live cluster and lists the operations needed to bring the cluster in line:

monedula-gitops diff -f ./manifests --cluster-config-file ./cluster.yaml

Each planned operation shows its risk and whether it needs approval, as a partition increase does. When the cluster already matches the manifests, diff prints No changes. It exits 0 with or without drift and 2 on a configuration or connection error, so it never fails the build on what it finds.

3. Render the plan as a document

apply --dry-run renders the plan that apply would execute, without running it. With -o json or -o yaml, the plan is a deterministic document that you can keep as a build artifact or feed to other tools:

monedula-gitops apply -f ./manifests --cluster-config-file ./cluster.yaml --dry-run -o json

Each entry in its changes list names the action, the resource and its target, the risk, and requiresApproval. apply --dry-run exits 0 even when the plan contains operations that need approval; the real apply reports those as Blocked and exits 3 until you approve them.

4. Add the steps to your pipeline

This GitHub Actions job runs the three commands on every pull request. Adapt the paths, the install step and the secret names, which must match the valueFrom.env names in your cluster config:

name: kafka-preview
on:
  pull_request:
jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.26'
      - name: Install monedula-gitops
        run: go install github.com/monedula-dev/monedula-gitops/cmd/monedula-gitops@latest
      - name: Validate
        run: monedula-gitops validate -f ./manifests --cluster-config-file ./cluster.yaml
      - name: Preview
        env:
          KAFKA_USER: ${{ secrets.KAFKA_USER }}
          KAFKA_PASSWORD: ${{ secrets.KAFKA_PASSWORD }}
        run: |
          monedula-gitops diff -f ./manifests --cluster-config-file ./cluster.yaml
          monedula-gitops apply -f ./manifests --cluster-config-file ./cluster.yaml --dry-run -o json > plan.json
  • go install builds the CLI with Go 1.26 or newer. To build a fixed release, replace @latest with its tag, such as @v1.0.0.
  • The Validate step runs without credentials. Only the Preview step receives them.
  • The diff appears in the job log. Save plan.json as a build artifact if reviewers or other jobs need the document.

On a pull request that changes a manifest, the job log of the Preview step lists the planned operations, and the Validate step fails the build if a manifest is invalid. The job that applies after the merge runs the same apply command without --dry-run.