Skip to content

Makefile Reference Guide

This comprehensive reference covers all Make targets available in the Neo4j Kubernetes Operator project, organized by purpose and workflow.

Table of Contents

Quick Start

Essential commands for getting started:

# Get help with all available targets
make help

# Create development environment
make dev-cluster          # Create Kind cluster
make operator-setup       # Deploy operator

# Run tests
make test-unit            # Fast unit tests (no cluster)
make test-integration     # Full integration tests (auto-creates cluster)

# Build and deploy
make build                # Build operator binary
make docker-build         # Build container image
make deploy-dev           # Deploy to development namespace

# Pre-release / sync (after touching API types or +kubebuilder markers)
make sync-all             # Regenerate all artifacts (CRDs, RBAC, helm chart, kustomize lists)
make ship-prep            # sync-all + bundle + helm lint + CSV coverage check
make install-confidence   # Pre-release gate: helm install/upgrade/uninstall matrix on Kind (~10-15 min)
make check-drift          # CI gate: fails if any generated file is stale
make bundle-release       # Bundle + real createdAt: timestamp (release workflow only)
make install-hooks        # One-time: install pre-commit hooks (runs check-drift before commit)

Target Categories

The Makefile is organized into logical categories:

Category Purpose Key Targets
General Help and basic tasks help, all
Code Generation Generate Kubernetes manifests manifests, generate
Packaging & Sync Keep Helm chart, kustomize, OperatorHub bundle in sync with sources sync-all, ship-prep, check-drift
Testing Unit and integration testing test-unit, test-integration
Build & Images Build binaries and containers build, docker-build
Deployment Install and deploy operator install, deploy-dev, deploy-prod
Development Environment Local development setup dev-cluster, operator-setup
Dependencies Download and manage tools kustomize, controller-gen, yq
Code Quality Linting, formatting, security fmt, lint, security

General Targets

make help

Description: Display a curated "Getting Started" list of the most common targets (dev-up, dev-down, deploy-dev-local, test-unit, test-one, smoke-test, dev-watch, operator-logs). Run make help-all for the complete list. Usage: make help Dependencies: None Example:

make help

make help-all

Description: Display every available target, grouped by ##@ category headers, with the inline ## description for each. Usage: make help-all Dependencies: None

make all

Description: Default target - builds the operator binary Usage: make all or just make Dependencies: build Example:

make         # Same as 'make all'
make all     # Explicit call

Code Generation

make manifests

Description: Generate ClusterRole and CustomResourceDefinition objects from code annotations Usage: make manifests Dependencies: controller-gen Output: Updates files in config/crd/bases/ and RBAC manifests Example:

make manifests
# Generates CRDs from api/v1beta1/*_types.go files
# Updates RBAC from controller annotations

make generate

Description: Generate DeepCopy, DeepCopyInto, and DeepCopyObject method implementations Usage: make generate Dependencies: controller-gen Output: Updates *_deepcopy.go files Example:

make generate
# Generates DeepCopy methods for all API types

Packaging & Sync

The operator ships through three channels: kustomize manifests (config/), a Helm chart (charts/neo4j-operator/), and an OperatorHub bundle (bundle/). Several files in those trees are generated from sources of truth elsewhere in the repo. The targets in this section regenerate them and verify they're in sync.

TL;DR for adding a new CRD:

# After editing api/v1beta1/*_types.go and adding +kubebuilder:rbac markers:
make ship-prep    # one command โ€” runs every regeneration step
git add -A
git commit -m "..."

make sync-all

Description: Run every code-generation and sync step (does not build the bundle). Chains: manifests โ†’ generate โ†’ sync-kustomize โ†’ sync-editor-viewer-roles โ†’ helm-sync-crds โ†’ helm-sync-rbac โ†’ helm-sync-artifacthub-crds. Usage: make sync-all When to run: after touching any api/v1beta1/*_types.go file, any controller +kubebuilder:rbac: marker, or any config/crd/bases/*.yaml directly.

make ship-prep

Description: Pre-release one-shot. Runs sync-all plus bundle, helm-lint, and check-csv-coverage. Usage: make ship-prep When to run: before tagging a release. Verifies the Helm chart lints, the OperatorHub bundle validates, and every CRD is registered in the CSV.

make install-confidence

Description: Pre-release confidence gate. Runs scripts/install-confidence.sh: builds the operator image from the working tree, creates a throwaway Kind cluster, and walks the five-leg install/upgrade/uninstall matrix โ€” helm install (cluster mode + smoke CR), helm install (namespaces mode + rbac.perNamespaceRoles, asserting no manager ClusterRole), helm upgrade from the previously published chart including the mandatory server-side CRD refresh, documented-order uninstall with a live CR, and the kubectl server-side-apply path. ~10โ€“15 minutes; needs kind, helm, kubectl, docker. Usage: make install-confidence (optionally PREV_CHART_VERSION=1.11.2 make install-confidence to pin the upgrade-from chart). When to run: before tagging a release. The same matrix runs automatically as a blocking job in release.yml, so a local run turns a would-be dead tag into a minutes-cheap local failure. Also dispatchable in CI via the Install Confidence workflow. See CI & Workflows โ†’ Install Confidence.

make check-drift

Description: Regenerate every artifact and git diff --exit-code to fail if anything is stale. Used as a CI gate (.github/workflows/ci.yml). Usage: make check-drift Notes: make bundle pins the CSV's createdAt: to a stable placeholder (see PINNED_CREATED_AT in the Makefile), so two consecutive runs produce byte-identical output and concurrent PRs no longer conflict on the timestamp. The -I '^ createdAt:' filter is kept as belt-and-braces in case someone bypasses make bundle and calls operator-sdk generate bundle directly. If check-drift fails locally, run make sync-all bundle and commit the result. The same check runs as a pre-commit hook locally once you've run make install-hooks โ€” see below.

make bundle-release

Description: Same as make bundle, but stamps the real current UTC timestamp into the CSV's createdAt: annotation (overriding the pinned placeholder). Run this from the release workflow before publishing to OperatorHub so the bundle ships with a meaningful createdAt: for end-user tooling. Usage: make bundle-release Notes: only run from release CI โ€” local invocations leave a real timestamp in bundle/ that will conflict with every other concurrent PR. If you run it by accident, make bundle resets it to the placeholder.

make install-hooks

Description: Install git pre-commit hooks (drift gate, fmt, lint, gitleaks, commitizen). Wraps pre-commit install and pre-commit install --hook-type commit-msg. Usage: make install-hooks (one-time per clone) Prerequisite: pre-commit on your PATH (uv tool install pre-commit, pip install pre-commit, or brew install pre-commit).

If it refuses to install: pre-commit will not write hooks while core.hooksPath is set, even when that value is .git/hooks โ€” git's own default, so clearing it changes nothing. Some GUI clients set it. git config --unset-all core.hooksPath, then re-run. What the drift hook does: when staged files match api/v1beta1/*.go, internal/controller/*_controller.go, scripts/{helm-sync-*,check-csv-coverage,update-alm-examples}*, config/manifests/bases/*.csv.yaml, config/{crd,rbac,samples,manifests}/, charts/neo4j-operator/, or bundle/, the hook runs make check-drift. On stale artifacts the regenerated files are left in your working tree; git add -u and recommit.

make helm-sync-crds

Description: Copy the kubebuilder-generated CRDs from config/crd/bases/ into charts/neo4j-operator/crds/ so the Helm install picks them up. Usage: make helm-sync-crds Source: config/crd/bases/*.yaml

make helm-sync-rbac

Description: Regenerate charts/neo4j-operator/templates/clusterrole.yaml from the kubebuilder-generated config/rbac/role.yaml so the Helm chart grants exactly the same permissions as the controller's +kubebuilder:rbac: markers request. Usage: make helm-sync-rbac Source: config/rbac/role.yaml (regenerated by make manifests)

make helm-sync-artifacthub-crds

Description: Regenerate the artifacthub.io/crds annotation in Chart.yaml from config/crd/bases/. Each CRD's user-facing description lives in a curated mapping in scripts/helm-sync-artifacthub-crds.sh โ€” the script exits non-zero if a CRD has no description, so adding a new CRD without updating the description map is impossible. Usage: make helm-sync-artifacthub-crds

make sync-kustomize

Description: Regenerate the resources: lists in config/crd/kustomization.yaml and config/samples/kustomization.yaml from on-disk filenames. Comments and other top-level keys preserved. Usage: make sync-kustomize

make sync-editor-viewer-roles

Description: Generate per-CRD editor and viewer ClusterRoles into config/rbac/<crd>_{editor,viewer}_role.yaml for every CRD in config/crd/bases/, and update config/rbac/kustomization.yaml. These are convenience cluster-roles end-users can bind to teams without granting cluster-admin; they're not used by the operator itself. Usage: make sync-editor-viewer-roles

make check-csv-coverage

Description: Verify that every CRD in config/crd/bases/ is registered in both the source CSV (config/manifests/bases/*.csv.yaml) and the bundle CSV (bundle/manifests/*.csv.yaml). Fails non-zero with a list of missing kinds. Usage: make check-csv-coverage Why: the CSV's customresourcedefinitions.owned list is hand-curated (display names, descriptions need human input) โ€” it's easy to forget to register a new CRD, which would silently ship a broken OperatorHub bundle.

make check-docs-release-pins

Description: Verify every documented install command names the current release. Quick-starts must install from releases/latest/download/ and pin nothing; pinned surfaces (Helm --version, the RELEASE_VERSION examples, the ArgoCD targetRevision, go install) must agree with each other and with the newest git tag. Usage: make check-docs-release-pins Why: README.md's quick-install pinned v1.13.0 two releases after v1.15.0 shipped. The line was correct when written, and no generator or drift check looks at it. Notes: docs ahead of the newest tag pass with a notice โ€” the docs bump lands on main before the tag is pushed, and strict equality would fail every PR in that window. Docs behind the newest tag fail. Currency needs tags; in a checkout without them the consistency half still runs. Bump the pins before pushing a release tag, or CI on main goes red until they catch up.

make check-examples-catalog

Description: Verify every examples/ subdirectory is listed in examples/README.md (and every listed directory exists), and that every example .yaml is named in its own directory's README or the top-level one. Usage: make check-examples-catalog Why: the directory list had been missing cross-cluster-replication/ since that capability shipped โ€” a whole capability's examples invisible to anyone browsing. The file-level half catches the other version of it: an example nobody links to is one nobody finds.

make check-docs-tables

Description: Verify every Markdown table under docs/ begins a new block, so Python-Markdown renders it as a table. Usage: make check-docs-tables Why: all five tables on the Fault Tolerance page shipped as literal rows of pipes. Written directly under a paragraph line, a table is swallowed as lazy continuation of that paragraph โ€” and the source looks correct in an editor and in GitHub's preview, which is lenient here. It only showed up on the published site, and a user reported it. Notes: a table directly under a heading is fine and is not flagged โ€” the heading closes the preceding block. That exception was checked against Python-Markdown with this site's extension set rather than assumed.

It also checks box diagrams: every line of a rectangle must be the same width with its right border in the same column. Only true rectangles (a block with a โ”Œโ”€โ”€โ”€โ” top edge) are checked โ€” tree listings and state-machine flows use the same characters with deliberately ragged edges, and 6 of the 8 diagrams under docs/ are one of those. That split was measured before the rule was written, so it starts with no false positives.

make check-apiref-drift

Description: Verify docs/api_reference/ has a page for every CRD and that each page documents every top-level spec field (go run ./scripts/check-apiref-drift). The hand-written reference has no generator. Usage: make check-apiref-drift

make check-crd-catalog

Description: Verify every CRD is listed on the docs landing page (docs/index.md), the README, the mkdocs.yml nav and docs/gitops/argocd-health-checks.yaml (go run ./scripts/check-crd-catalog). Usage: make check-crd-catalog

make check-cli-docs

Description: Verify every kubectl-neo4j command in cmd/kubectl-neo4j/main.go has a page under docs/user_guide/cli/ and every CLI page is in the mkdocs.yml nav. Usage: make check-cli-docs

make check-cli-asset-names

Description: Verify the kubectl-neo4j release-asset naming convention agrees everywhere it is pinned (scripts/check-cli-asset-names.sh). Usage: make check-cli-asset-names

Description: Verify every docs link in .github/release-notes-template.md points at the release's own docs version (__DOCS_VERSION__, which release.yml replaces with vX.Y), and that release.yml and pages-docs.yml derive that version the same way (scripts/check-release-notes-links.sh). The docs site has no unversioned pages, so a link without the version is a 404. Usage: make check-release-notes-links

make check-invariants, make check-knowledge-drift, make check-knowledge

Description: The advisory LLM-readiness guards. check-invariants runs scripts/check-invariants.sh (the five hard invariants โ€” webhooks, Kind-only, Enterprise images, V2_ONLY, server-based architecture); check-knowledge-drift runs scripts/check-knowledge-drift.sh (every test, path and Neo4j* identifier cited in docs/knowledge/ must still exist); check-knowledge runs both. Usage: make check-knowledge Notes: advisory โ€” the Invariant Guards (advisory) CI job runs them with continue-on-error, so they never block merge. See Agent guardrails.

make helm-lint, make helm-template, make helm-package

Standard helm chart targets. helm-package depends on helm-sync-crds, helm-sync-rbac, and helm-sync-artifacthub-crds, so packaging never ships stale rules or annotations. helm-template renders the chart into the neo4j-operator-system namespace.

make helm-install, make helm-upgrade, make helm-uninstall, make helm-install-test, make helm-docs

Helm lifecycle targets. helm-install installs the chart as release neo4j-operator into neo4j-operator-system (with --create-namespace); helm-upgrade / helm-uninstall manage that release. helm-install-test runs scripts/helm-install-test.sh to validate a chart install in the Kind test cluster. helm-docs regenerates chart docs via helm-docs if installed.

make bundle

Description: Generate the OperatorHub bundle (CRDs, CSV, ClusterRoles, metadata) under bundle/. Also runs operator-sdk bundle validate. Usage: make bundle Notes: invokes manifests first by default. Set SKIP_MANIFESTS=true in CI to reuse pre-generated CRDs from a prior job.

make yq

Description: Install yq (required by the sync scripts) into bin/. Pinned via YQ_VERSION in the Makefile. Usage: make yq Notes: invoked automatically by every sync target โ€” you rarely call it directly.

make fmt

Description: Format Go code using go fmt Usage: make fmt Dependencies: None Example:

make fmt
# Formats all Go files in the project

make vet

Description: Run go vet static analysis Usage: make vet Dependencies: None Example:

make vet
# Reports suspicious constructs

make lint

Description: Run golangci-lint with strict settings Usage: make lint Dependencies: golangci-lint Example:

make lint
# Runs comprehensive linting checks

make lint-lenient

Description: Run golangci-lint with relaxed settings (CI-friendly) Usage: make lint-lenient Dependencies: golangci-lint Example:

make lint-lenient
# More permissive linting for CI environments

Testing

Important: All testing requires Kind (Kubernetes in Docker). Install Kind before running tests.

Unit Testing

make test-unit

Description: Run fast unit tests without requiring a Kubernetes cluster Usage: make test-unit Dependencies: manifests, generate, fmt, vet, envtest Duration: ~30 seconds Test runner override: the recipe runs $(GO_TEST_CMD) (default go test). CI swaps in gotestsum for richer reporting:

make gotestsum
make test-unit GO_TEST_CMD="./bin/gotestsum --format=testname --junitfile=unit-junit.xml --jsonfile=unit-tests.json --"
Example:
make test-unit
# โœ… Fast tests for controller logic
# โœ… No cluster setup required
# โœ… Includes coverage reporting

make test-coverage

Description: Generate detailed coverage report Usage: make test-coverage Dependencies: manifests generate fmt vet envtest (auto-resolved) Env: KUBEBUILDER_ASSETS is set automatically from ENVTEST_K8S_VERSION โ€” the controller suite needs it to start envtest. Running go test -coverprofile ./... directly without make requires you to export it yourself. Output: coverage/coverage.html Example:

make test-coverage
# Generates HTML coverage report
# Opens coverage/coverage.html in browser

Integration Testing

make test-integration

Description: Run comprehensive integration tests with real Kubernetes API Usage: make test-integration [LABEL=<ginkgo label expression>] [INTEGRATION_TIMEOUT=<duration>] Dependencies: manifests generate test-cluster ginkgo kustomize โ€” the manifests/generate prereqs guarantee CRDs and RBAC deployed to the test cluster match the current controller source. Skipping manifests (e.g., by calling kustomize directly) silently deploys stale schemas. Variables:

Variable Default Effect
LABEL (empty) Passed to ginkgo --label-filter. Empty passes no filter and runs every spec (core and extended). Use core for the per-PR tier, extended for the heavy / release tier, or any expression such as 'core || extended'. Quote an expression that contains spaces or |. A filter that selects no spec fails the run (--fail-on-empty), so a typo such as LABEL=cor โ€” or an unrelated LABEL exported in your shell, which make lets override the default โ€” cannot pass as a green "Ran 0 of N Specs". test-one does the same for a TEST that matches nothing.
INTEGRATION_TIMEOUT 60m The whole-suite deadline passed to ginkgo --timeout (not the per-spec 300s). Raise it for a long tier, e.g. INTEGRATION_TIMEOUT=120m.

Duration: long โ€” with no LABEL it runs every spec (core and extended) with --procs=1 --timeout=60m; CI needs ~90โ€“150 min for both tiers on CalVer. LABEL=core is the quick pass. To iterate on one spec, use make test-one TEST="โ€ฆ"; to run a tier against a cluster you already set up, call ginkgo run --label-filter='core' ./test/integration/... directly (see Testing). Features:

  • Always recreates the neo4j-operator-test cluster (test-cluster deletes an existing one first)
  • Builds and deploys the operator in production mode (neo4j-operator-system)
  • Tests real Neo4j deployments
  • Leaves the cluster running afterwards for inspection โ€” clean up with make test-cluster-delete

Example:

make test-integration                  # every spec (core + extended)
make test-integration LABEL=core       # the per-PR tier, as CI runs it
make test-integration LABEL=extended   # the heavy / release tier
# ๐Ÿ”„ Recreates the neo4j-operator-test cluster
# ๐Ÿ“ฆ Builds and deploys operator
# ๐Ÿงช Runs the selected specs
# (cluster is left running โ€” make test-cluster-delete to remove it)

make test-one

Description: Run a single integration test by name (Ginkgo --focus). Exports the kubeconfig for neo4j-operator-test (falling back to neo4j-operator-dev), then runs ginkgo run --focus "$TEST" --timeout=300s --procs=1 -v ./test/integration/.... Usage: make test-one TEST="should create standalone" Dependencies: ginkgo Notes: assumes a cluster + operator already exist; errors out if TEST is empty.

make smoke-test

Description: Deploy a minimal standalone Neo4j instance (hack/smoke-test-standalone.yaml) and verify it reaches Ready within 5 minutes, then clean up the instance and the neo4j-smoke-secret. Usage: make smoke-test Notes: assumes a cluster + operator already exist.

Test Environment Management

make test-setup

Description: Setup test environment and prepare for testing Usage: make test-setup Dependencies: Test environment scripts Example:

make test-setup
# Prepares test environment
# Creates necessary directories
# Sets up test configurations

make test-cleanup

Description: Clean up test environment artifacts while keeping cluster Usage: make test-cleanup Features:

  • Removes test results and logs
  • Cleans coverage files
  • Preserves cluster for reuse Example:
    make test-cleanup
    # Removes test-results/ coverage/ logs/ tmp/
    # Cleans test-output.log and coverage files
    # Keeps cluster running
    

make test-cluster

Description: Create dedicated Kind cluster for testing Usage: make test-cluster Dependencies: Kind installed Cluster Name: neo4j-operator-test Variables (Makefile defaults, overridable via make VAR=...):

  • KIND_NODE_IMAGE ?= kindest/node:v1.34.0 โ€” pins the K8s version. Kept in sync with ENVTEST_K8S_VERSION so unit tests, dev cluster, and integration tests all run on the same K8s.
  • CERT_MANAGER_VERSION ?= v1.20.0 โ€” pins the cert-manager release.

Both are threaded into scripts/test-env.sh via environment variables; the script enforces them as required (no fallback) so direct invocations can't drift from the Makefile defaults.

Features:

  • Pre-configured with self-signed issuer
  • Optimized for testing workloads

Example:

make test-cluster
# Creates neo4j-operator-test cluster
# Installs cert-manager
# Sets up TLS certificates

make test-cluster-clean

Description: Remove operator resources from test cluster (keep cluster running) Usage: make test-cluster-clean Example:

make test-cluster-clean
# Removes operator deployment
# Removes test namespaces
# Keeps cluster running

make test-cluster-reset

Description: Delete and recreate test cluster Usage: make test-cluster-reset Dependencies: test-cluster-delete, test-cluster Example:

make test-cluster-reset
# Complete cluster refresh
# Preserves no state

make test-cluster-delete

Description: Delete test cluster completely Usage: make test-cluster-delete Example:

make test-cluster-delete
# Removes neo4j-operator-test cluster

make test-destroy

Description: Complete test environment cleanup Usage: make test-destroy Example:

make test-destroy
# Removes all test artifacts
# Deletes test cluster
# Cleans temporary files

Comprehensive Testing

make test

Description: Run complete test suite (unit + integration) Usage: make test Dependencies: test-unit, test-integration Duration: long โ€” the unit tests plus every integration spec (see test-integration) Example:

make test
# โœ… Unit tests
# โœ… Integration tests
# โœ… Full validation

make test-ci-local ๐Ÿ†•

Description: Emulate GitHub Actions CI workflow locally with comprehensive debug logging Usage: make test-ci-local Duration: long โ€” unit tests, then every integration spec under a 60-minute timeout Features:

  • Complete CI emulation: Uses CI=true GITHUB_ACTIONS=true environment
  • Resource constraints: CI=true makes the specs use the CI resource profile (1.5Gi memory limit, small CPU requests) instead of the local profile (2Gi limit)
  • Debug logging: Comprehensive logs saved to logs/ directory
  • Automatic troubleshooting: Provides debugging commands on failure
  • Self-contained: Creates, tests, and destroys environment

Output Files:

  • logs/ci-local-unit.log - Unit test output with environment info
  • logs/ci-local-integration.log - Integration test execution
  • logs/ci-local-cleanup.log - Environment cleanup

Example:

make test-ci-local
# ๐Ÿ”„ Phase 1: Unit tests with CI environment
# ๐Ÿ”— Phase 2: Integration tests with CI constraints
# ๐Ÿงน Phase 3: Complete cleanup
# ๐Ÿ“ Debug logs in logs/ directory

When to use:

  • Debugging CI failures locally
  • Testing resource-constrained scenarios
  • Validating changes before CI push
  • Reproducing CI-specific issues

Build & Images

make build

Description: Build the operator binary Usage: make build Dependencies: manifests, generate, fmt, vet Output: bin/manager Example:

make build
# Builds bin/manager executable
# Includes all code generation

make build-cli

Description: Build the kubectl-neo4j plugin into bin/kubectl-neo4j, stamping main.version from git describe. Put bin/ on your PATH to run it as kubectl neo4j โ€ฆ. Usage: make build-cli Output: bin/kubectl-neo4j

make docker-build

Description: Build Docker image with operator Usage: make docker-build [IMG=<image-name>] Dependencies: None Default Image: ghcr.io/priyolahiri/neo4j-kubernetes-operator:latest Notes: Passes VERSION, BUILD_DATE, and VCS_REF build-args into the Dockerfile. Example:

make docker-build
# Builds ghcr.io/priyolahiri/neo4j-kubernetes-operator:latest image

make docker-build IMG=my-operator:v1.0
# Builds custom image name

make docker-push

Description: Push Docker image to registry Usage: make docker-push [IMG=<image-name>] Dependencies: docker-build Example:

make docker-push IMG=ghcr.io/my-org/neo4j-operator:latest
# Pushes image to GitHub Container Registry

Deployment

Critical: The operator must run inside the Kubernetes cluster. Running outside the cluster causes DNS resolution failures.

CRD Management

make install

Description: Install CustomResourceDefinitions into cluster Usage: make install Dependencies: manifests, kustomize Example:

make install
# Installs all CRDs to current cluster context

make uninstall

Description: Remove CRDs from cluster Usage: make uninstall Dependencies: manifests, kustomize **โš ๏ธ Warning: This will delete all Neo4j instances Example:

make uninstall
# Removes all CRDs and instances

Operator Deployment

make deploy-dev

Description: Deploy operator with development configuration using local images Usage: make deploy-dev Dependencies: deploy-dev-local Namespace: neo4j-operator-dev Image: neo4j-operator:dev (built locally) Features:

  • Auto-loads image to Kind cluster
  • Development-friendly settings
  • Enhanced logging

Example:

make deploy-dev
# ๐Ÿ”จ Builds neo4j-operator:dev image
# ๐Ÿ“ฆ Loads to Kind cluster
# ๐Ÿš€ Deploys to neo4j-operator-dev namespace

make deploy-prod

Description: Deploy operator with production configuration using local images Usage: make deploy-prod Dependencies: deploy-prod-local Namespace: neo4j-operator-system Image: neo4j-operator:latest (built locally) Features:

  • Production-grade settings
  • Resource limits applied
  • Standard logging levels

Example:

make deploy-prod
# ๐Ÿ”จ Builds neo4j-operator:latest image
# ๐Ÿ“ฆ Loads to Kind cluster
# ๐Ÿš€ Deploys to neo4j-operator-system namespace

make deploy-dev-local

Description: Build and deploy controller with local dev image to Kind cluster Usage: make deploy-dev-local Dependencies: manifests, kustomize, docker-build Features:

  • Builds neo4j-operator:dev image locally
  • Auto-detects and loads to available Kind cluster
  • Deploys to neo4j-operator-dev namespace
  • Restarts an operator that was already running, then waits for the rollout. The tag never changes, so without the restart an unchanged manifest leaves the old pod โ€” and the old binary โ€” running Example:
    make deploy-dev-local
    # Explicit local build and deploy
    # Same as deploy-dev but more explicit
    

make deploy-prod-local

Description: Build and deploy controller with local prod image to Kind cluster Usage: make deploy-prod-local Dependencies: manifests, kustomize, docker-build Features:

  • Builds neo4j-operator:latest image locally
  • Auto-detects and loads to available Kind cluster
  • Deploys to production namespace
  • Restarts an operator that was already running, then waits for the rollout (see deploy-dev-local) Example:
    make deploy-prod-local
    # Explicit local build and deploy
    # Same as deploy-prod but more explicit
    

make deploy-dev-registry

Description: Deploy development configuration using registry image (applies config/overlays/dev) Usage: make deploy-dev-registry Dependencies: manifests, kustomize, check-rbac Image Source: Container registry (requires authentication) Example:

make deploy-dev-registry
# ๐Ÿ“ฅ Pulls from ghcr.io registry
# ๐Ÿš€ Deploys dev configuration

make deploy-prod-registry

Description: Deploy production configuration using registry image (applies config/overlays/prod-registry) Usage: make deploy-prod-registry Dependencies: manifests, kustomize, check-rbac Image Source: Container registry (requires authentication) Example:

make deploy-prod-registry
# ๐Ÿ“ฅ Pulls from ghcr.io registry
# ๐Ÿš€ Deploys production configuration

make deploy-namespace-scoped

Description: Deploy the controller with namespace-scoped permissions only (no ClusterRole). Applies config/overlays/namespace-scoped. Limited functionality โ€” only manages resources within the neo4j-operator-dev namespace. Usage: make deploy-namespace-scoped Dependencies: manifests, kustomize

make check-rbac

Description: Check and set up RBAC permissions if needed (runs scripts/setup-rbac.sh). A dependency of the registry deploy targets. Usage: make check-rbac

Deployment Removal

make undeploy-dev

Description: Remove development operator deployment Usage: make undeploy-dev Example:

make undeploy-dev
# Removes development operator
# Keeps CRDs and instances

make undeploy-prod

Description: Remove production operator deployment Usage: make undeploy-prod Example:

make undeploy-prod
# Removes production operator
# Keeps CRDs and instances

make undeploy-namespace-scoped

Description: Remove the namespace-scoped controller deployment (deletes config/overlays/namespace-scoped). Usage: make undeploy-namespace-scoped Dependencies: kustomize

Development Environment

Mandatory: This project exclusively uses Kind for development. Install Kind before using development targets.

One-Command Bootstrap

make check-prereqs

Description: Verify all required tools are installed (go, docker + running daemon, kubectl, kind, make). Fails non-zero listing any missing tool with install hints. Usage: make check-prereqs

make dev-up

Description: Bootstrap the complete dev environment in one command. Chains check-prereqs โ†’ dev-cluster โ†’ install (CRDs) โ†’ deploy-dev-local, then waits for the operator rollout (tries neo4j-operator-dev, falls back to neo4j-operator-system). Usage: make dev-up Dependencies: check-prereqs Cluster Name: neo4j-operator-dev

make dev-down

Description: Tear down the complete dev environment (delegates to dev-destroy: runs hack/cleanup-dev.sh and deletes the neo4j-operator-dev cluster). Usage: make dev-down

Cluster Management

make dev-cluster

Description: Create Kind cluster for development Usage: make dev-cluster Cluster Name: neo4j-operator-dev Dependencies: Kind installed Features:

  • Includes cert-manager v1.20.0
  • Self-signed ClusterIssuer for TLS
  • Development-optimized configuration

Example:

make dev-cluster
# Creates neo4j-operator-dev cluster
# Installs cert-manager
# Sets up development certificates

make dev-cluster-clean

Description: Remove operator resources from development cluster Usage: make dev-cluster-clean Example:

make dev-cluster-clean
# Removes operator deployment
# Removes CRDs and instances
# Keeps cluster running

make dev-cluster-reset

Description: Reset development cluster (delete and recreate) Usage: make dev-cluster-reset Dependencies: dev-cluster-delete, dev-cluster Example:

make dev-cluster-reset
# Complete cluster refresh
# Loses all state and data

make dev-cluster-delete

Description: Delete development cluster Usage: make dev-cluster-delete Example:

make dev-cluster-delete
# Removes neo4j-operator-dev cluster

make dev-cleanup

Description: Clean up development environment completely (keeps cluster) Usage: make dev-cleanup Dependencies: Development cleanup script Example:

make dev-cleanup
# Runs hack/cleanup-dev.sh
# Removes artifacts but keeps cluster
# Useful for resetting state

make dev-destroy

Description: Complete development environment destruction Usage: make dev-destroy Example:

make dev-destroy
# Removes all development artifacts
# Deletes development cluster
# Complete cleanup

Operator Management

make operator-setup

Description: Automated operator deployment to available Kind cluster Usage: make operator-setup Features:

  • Auto-detection: Finds available Kind cluster (dev or test)
  • Smart deployment: Chooses appropriate configuration
  • Status verification: Confirms successful deployment
  • Error handling: Provides troubleshooting guidance

Example:

make operator-setup
# ๐Ÿ” Detects available Kind cluster
# ๐Ÿ“ฆ Builds and loads appropriate image
# ๐Ÿš€ Deploys operator
# โœ… Verifies deployment status

make operator-setup-interactive

Description: Interactive operator deployment with user prompts Usage: make operator-setup-interactive Example:

make operator-setup-interactive
# ๐Ÿ’ฌ Interactive cluster selection
# ๐ŸŽ›๏ธ  Configuration options
# ๐Ÿ“‹ Detailed status reporting

make operator-status

Description: Display comprehensive operator status Usage: make operator-status Example:

make operator-status
# ๐Ÿ“Š Operator deployment status
# ๐Ÿ” Pod health and logs
# ๐Ÿ“ˆ Resource usage

make operator-logs

Description: Follow operator logs in real-time Usage: make operator-logs Example:

make operator-logs
# ๐Ÿ“‹ Real-time log streaming
# ๐Ÿ” Filtered for relevant events

make dev-watch

Description: File-watch dev loop โ€” on changes under api/, internal/, cmd/ re-runs manifests generate build deploy-dev-local. Uses watchexec if present, else fswatch; errors out with install hints if neither is available. Usage: make dev-watch Prerequisite: watchexec (recommended) or fswatch. For a richer loop, use tilt up instead.

Demo Environment

The demo deploys a TLS-enabled standalone instance and a 3-node TLS-enabled cluster, creates databases with sample data, and demonstrates external access.

make demo-setup

Description: Set up complete demo environment (Kind cluster + cert-manager + operator). Lists existing clusters that will be destroyed and asks for confirmation. Usage: make demo-setup

make demo

Description: Run interactive operator demo with full environment setup. Asks for confirmation before destructive steps (destroying existing clusters, deleting previous demo resources). At the end, prompts whether to clean up. Usage: make demo Includes: Environment setup (interactive)

make demo-fast

Description: Run automated demo without confirmations (includes setup) Usage: make demo-fast Includes: Environment setup (auto-confirmed)

make demo-release

Description: Fast automated demo against the published operator chart instead of a local build. Usage: make demo-release (pin a version with DEMO_VERSION=1.12.1 make demo-release)

make demo-only

Description: Run fast demo without environment setup (assumes cluster and operator exist) Usage: make demo-only

make demo-interactive

Description: Run interactive demo without environment setup (assumes cluster and operator exist) Usage: make demo-interactive

make demo-cleanup

Description: Clean up all demo resources (databases, standalone, cluster, admin secret) without running the demo Usage: make demo-cleanup

Demo script flags

The demo script (scripts/demo.sh) accepts these flags:

Flag Description
--skip-confirmations Skip all interactive prompts
--cleanup Automatically clean up demo resources after completion
--cleanup-only Only clean up resources from a previous demo run
--speed fast\|normal\|slow Control demo pacing
--namespace NAMESPACE Kubernetes namespace (default: default)
--password PASSWORD Admin password (default: demo123456)

Cross-cluster replication (CCDR) test rig

Used by Release Verification Phase 5 (Parts D and E).

make ccdr-lb

Description: Give a Kind cluster a working LoadBalancer (MetalLB L2 pool carved from the top of the shared kind Docker network) so the CCDR proxy Service gets a real address. Runs hack/metallb-setup.sh. Usage: make ccdr-lb (defaults to the neo4j-operator-dev cluster; CLUSTER=<name> targets another, POOL_OFFSET shifts the address pool)

make ccdr-e2e-up, ccdr-e2e-trust, ccdr-e2e-status, ccdr-e2e-down

Description: Stand up and drive the two-Kind-cluster rig (neo4j-operator-dev upstream with MetalLB, neo4j-dr downstream; TLS, cert-manager and the operator built from this tree on both). up builds the rig; once both Neo4jEnterpriseClusters are Ready, trust exchanges the clusters' CAs; status shows both sides' CCDR state; down deletes both Kind clusters. All call hack/ccdr-two-cluster.sh. Usage: make ccdr-e2e-up โ€ฆ make ccdr-e2e-down

Dependencies

The Makefile automatically manages tool dependencies:

Bundle and Catalog Management

make opm

Description: Download OPM (Operator Package Manager) tool Usage: make opm Location: bin/opm Example:

make opm
# Downloads opm for catalog management

make bundle

Description: Generate operator bundle manifests Usage: make bundle [VERSION=<version>] Dependencies: manifests, kustomize, operator-sdk Example:

make bundle VERSION=0.1.0
# Generates bundle for version 0.1.0

make bundle-build

Description: Build bundle image Usage: make bundle-build [BUNDLE_IMG=<image>] Example:

make bundle-build BUNDLE_IMG=my-bundle:v0.1.0
# Builds bundle container image

make bundle-push

Description: Push bundle image to registry Usage: make bundle-push [BUNDLE_IMG=<image>] Example:

make bundle-push BUNDLE_IMG=ghcr.io/org/bundle:v0.1.0
# Pushes bundle to registry

make catalog-build

Description: Build a catalog image for OLM Usage: make catalog-build [CATALOG_IMG=<image>] [BUNDLE_IMGS=<bundles>] Dependencies: opm Example:

make catalog-build CATALOG_IMG=my-catalog:v1.0
# Builds catalog with bundle images

make catalog-push

Description: Push catalog image to registry Usage: make catalog-push [CATALOG_IMG=<image>] Example:

make catalog-push CATALOG_IMG=ghcr.io/my-org/catalog:v1.0
# Pushes catalog to registry

make scorecard

Description: Run operator-sdk scorecard checks against the generated bundle. Usage: make scorecard

Core Tools

make kustomize

Description: Download kustomize for Kubernetes manifest management Version: v5.4.3 Location: bin/kustomize

make controller-gen

Description: Download controller-gen for code generation Version: v0.19.0 Location: bin/controller-gen

make envtest

Description: Download setup-envtest for testing Version: release-0.19 Location: bin/setup-envtest

make golangci-lint

Description: Download golangci-lint for code quality Version: v2.14.0 (GOLANGCI_LINT_VERSION; the Makefile builds it against the current Go toolchain) Location: bin/golangci-lint

make ginkgo

Description: Download Ginkgo BDD testing framework Version: v2.32.1 (GINKGO_VERSION) Location: bin/ginkgo

make operator-sdk

Description: Download Operator SDK for bundle management Version: v1.39.1 Location: bin/operator-sdk

make gotestsum

Description: Download gotestsum, a go test wrapper that prints a readable summary and emits JUnit XML + test2json reports. CI uses it for the Unit Tests job (see test-unit and the CI workflow). Version: v1.13.0 (v1.12.0 won't compile under Go 1.26) Location: bin/gotestsum

Code Quality

make security

Description: Run security analysis with gosec Usage: make security Features:

  • Auto-installs gosec if needed
  • Scans for security vulnerabilities
  • Reports potential issues

Example:

make security
# ๐Ÿ›ก๏ธ  Security vulnerability scan
# ๐Ÿ“‹ Detailed security report

make tidy

Description: Clean up Go module dependencies Usage: make tidy Example:

make tidy
# ๐Ÿงน Removes unused dependencies
# โœ… Verifies module integrity

make clean

Description: Clean all build artifacts and temporary files Usage: make clean Removes:

  • bin/, tmp/, and dist/ directories
  • cover.out, coverage.html
  • results.sarif, build-errors.log, .air.toml
  • Also invokes make test-cleanup to remove test artifacts

Example:

make clean
# ๐Ÿงน Complete cleanup
# ๐Ÿ—‘๏ธ  Removes all build artifacts

Environment Variables

Image Configuration

  • IMG: Container image name (default: ghcr.io/priyolahiri/neo4j-kubernetes-operator:latest)
  • IMAGE_TAG_BASE: Registry + image name for bundle/catalog images (default: ghcr.io/priyolahiri/neo4j-kubernetes-operator)
  • VERSION: Project version for the bundle (default: 0.0.1)
  • CONTAINER_TOOL: Container tool (default: docker)

Tool Configuration

  • KUBECONFIG: Kubernetes config file location
  • LOCALBIN: Local tool installation directory (default: bin/)
  • GOBIN: Go binary installation directory

Testing Configuration

  • CI: Enable CI mode (affects resource limits)
  • GITHUB_ACTIONS: Enable GitHub Actions mode
  • ENVTEST_K8S_VERSION: Kubernetes version for testing (1.34.0)

Bundle Configuration

  • CHANNELS: Bundle channels for OLM
  • DEFAULT_CHANNEL: Default bundle channel
  • BUNDLE_IMG: Bundle image name

Examples:

# Custom image build
make docker-build IMG=my-registry/neo4j-operator:v2.0

# CI-mode testing
CI=true make test-unit

# Custom tool location
LOCALBIN=/usr/local/bin make kustomize

Workflows

Complete Development Setup

# 1. Create development environment
make dev-cluster           # Create Kind cluster
make operator-setup        # Deploy operator

# 2. Develop and test
make test-unit            # Fast feedback loop
make build                # Build changes
make deploy-dev           # Update deployment

# 3. Comprehensive testing
make test-integration     # Full validation
make test-ci-local        # CI simulation

Production Deployment Workflow

# 1. Validate code quality
make fmt vet lint         # Code formatting and analysis
make security             # Security scanning

# 2. Test comprehensively
make test                 # Unit + integration tests
make test-coverage        # Verify coverage

# 3. Build and deploy
make docker-build         # Build production image
make deploy-prod          # Production deployment

CI/CD Emulation

# Reproduce CI failures locally
make test-ci-local        # Complete CI workflow
# Check logs/ci-local-*.log for detailed analysis

# Debug specific CI issues
CI=true GITHUB_ACTIONS=true make test-unit

Testing Workflow

# Quick development testing
make test-unit            # ~30 seconds

# Comprehensive validation (recreates the test cluster, runs every spec)
make test-integration     # long: core + extended, leaves the cluster running
make test-cluster-delete  # Remove the cluster when done

# CI preparation
make test-ci-local        # Full CI emulation

Cleanup Workflows

# Development cleanup
make dev-cluster-clean    # Remove operator only
make dev-destroy          # Complete destruction

# Test cleanup
make test-cluster-clean   # Remove test resources
make test-destroy         # Complete test cleanup

# Complete cleanup
make clean                # Remove build artifacts

Common Patterns

Error Recovery

# If cluster is in bad state
make dev-cluster-reset    # or test-cluster-reset
make operator-setup

# If operator is misbehaving
make undeploy-dev         # or undeploy-prod
make deploy-dev           # or deploy-prod

Development Iteration

# Fast iteration cycle
make test-unit            # Quick validation
make build                # Build changes
make docker-build         # Update image
make deploy-dev           # Deploy changes

# Full validation cycle
make fmt vet              # Code quality
make test                 # Comprehensive testing
make deploy-prod          # Production deployment

Troubleshooting

# Check operator status
make operator-status      # Deployment overview
make operator-logs        # Real-time logs

# Debug testing issues
make test-ci-local        # Reproduce CI environment
# Check logs/ci-local-*.log

# Clean slate approach
make dev-destroy          # Complete restart
make dev-cluster
make operator-setup

Best Practices

  1. Always use Kind: This project exclusively supports Kind for development
  2. Run tests before commits: Use make test-unit for fast feedback
  3. Test integration changes: Use make test-integration for comprehensive validation
  4. Emulate CI locally: Use make test-ci-local before pushing to CI
  5. Keep dependencies current: Tools are auto-managed and version-pinned
  6. Use appropriate deployment: deploy-dev for development, deploy-prod for production testing
  7. Clean up regularly: Use cleanup targets to prevent resource exhaustion
  8. Monitor operator logs: Use make operator-logs for real-time debugging

For additional help, run make help or consult the Contributing Guide.