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
- Target Categories
- General Targets
- Code Generation
- Packaging & Sync
- Testing
- Build & Images
- Deployment
- Development Environment
- Dependencies
- Code Quality
- Environment Variables
- Workflows
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-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:
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:
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
make check-release-notes-links¶
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 vet¶
Description: Run go vet static analysis
Usage: make vet
Dependencies: None
Example:
make lint¶
Description: Run golangci-lint with strict settings
Usage: make lint
Dependencies: golangci-lint
Example:
make lint-lenient¶
Description: Run golangci-lint with relaxed settings (CI-friendly)
Usage: make lint-lenient
Dependencies: golangci-lint
Example:
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 --"
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:
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-testcluster (test-clusterdeletes 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-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 withENVTEST_K8S_VERSIONso 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-delete¶
Description: Delete test cluster completely
Usage: make test-cluster-delete
Example:
make test-destroy¶
Description: Complete test environment cleanup
Usage: make test-destroy
Example:
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-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=trueenvironment - Resource constraints:
CI=truemakes 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 infologs/ci-local-integration.log- Integration test executionlogs/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-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 uninstall¶
Description: Remove CRDs from cluster
Usage: make uninstall
Dependencies: manifests, kustomize
**โ ๏ธ Warning: This will delete all Neo4j instances
Example:
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:devimage locally - Auto-detects and loads to available Kind cluster
- Deploys to
neo4j-operator-devnamespace - 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-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:latestimage 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-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-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-prod¶
Description: Remove production operator deployment
Usage: make undeploy-prod
Example:
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-delete¶
Description: Delete development cluster
Usage: make dev-cluster-delete
Example:
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 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 bundle¶
Description: Generate operator bundle manifests
Usage: make bundle [VERSION=<version>]
Dependencies: manifests, kustomize, operator-sdk
Example:
make bundle-build¶
Description: Build bundle image
Usage: make bundle-build [BUNDLE_IMG=<image>]
Example:
make bundle-push¶
Description: Push bundle image to registry
Usage: make bundle-push [BUNDLE_IMG=<image>]
Example:
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-push¶
Description: Push catalog image to registry
Usage: make catalog-push [CATALOG_IMG=<image>]
Example:
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 tidy¶
Description: Clean up Go module dependencies
Usage: make tidy
Example:
make clean¶
Description: Clean all build artifacts and temporary files
Usage: make clean
Removes:
bin/,tmp/, anddist/directoriescover.out,coverage.htmlresults.sarif,build-errors.log,.air.toml- Also invokes
make test-cleanupto remove test artifacts
Example:
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 locationLOCALBIN: 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 modeENVTEST_K8S_VERSION: Kubernetes version for testing (1.34.0)
Bundle Configuration¶
CHANNELS: Bundle channels for OLMDEFAULT_CHANNEL: Default bundle channelBUNDLE_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¶
- Always use Kind: This project exclusively supports Kind for development
- Run tests before commits: Use
make test-unitfor fast feedback - Test integration changes: Use
make test-integrationfor comprehensive validation - Emulate CI locally: Use
make test-ci-localbefore pushing to CI - Keep dependencies current: Tools are auto-managed and version-pinned
- Use appropriate deployment:
deploy-devfor development,deploy-prodfor production testing - Clean up regularly: Use cleanup targets to prevent resource exhaustion
- Monitor operator logs: Use
make operator-logsfor real-time debugging
For additional help, run make help or consult the Contributing Guide.