Traditional CI/CD vs. GitOps
This document compares traditional CI/CD push-based deployment with GitOps pull-based deployment, and explains the deployment patterns we use. It provides visual context for the pipeline architecture described in our Intentional Release Workflow Guide.
Deployment Patterns
Before comparing CI/CD approaches, it helps to understand two common deployment patterns for getting code from main into production.
Streamlined Deployment

In a streamlined deployment, merging to main triggers a pipeline that builds, tests, and pushes a Docker image, then deploys directly through staging and production in sequence. This is simple and fast, but offers no gate between environments. A bad merge can reach production within minutes.
Scheduled Deployment

Scheduled deployment adds a buffer. The CI pipeline still builds and deploys to staging automatically, but production deployment is triggered on a schedule (e.g., daily). This creates a window for manual validation in staging, but the release itself is still whatever accumulated on main since the last push, not an intentional decision.
Both patterns deploy from main commits rather than tagged releases. Our Intentional Release Guidelines explain why we moved away from this approach.
Traditional CI/CD (Push-Based)

In a traditional CI/CD process, the pipeline has direct write access to the target environment. After building and pushing a Docker image to the registry, the pipeline generates Kubernetes manifests and applies them using kubectl. The CI/CD system is both the builder and the deployer.
Characteristics:
- Push-based: the pipeline pushes changes to the cluster
- CI/CD owns credentials: the pipeline needs cluster access (kubeconfig, service accounts) to deploy
- No drift detection: if someone manually modifies the cluster, the pipeline has no way of knowing until the next deployment
- Rollback = re-deploy: reverting means re-running a previous pipeline or manually applying old manifests
GitOps (Pull-Based)

GitOps inverts the deployment model. The CI/CD pipeline is responsible only for building and pushing artifacts. Deployment is handled by a GitOps operator (such as Argo CD or Flux) running inside the cluster. The operator continuously compares the desired state in Git against the current state of the cluster and reconciles any differences.
Characteristics:
- Pull-based: the cluster pulls desired state from Git, rather than having changes pushed to it
- Git is the source of truth: the Git repository defines what should be running; any manual cluster changes are automatically reverted
- Drift detection: the operator continuously monitors for divergence between the declared state and the actual state
- Separation of concerns: CI handles build and test; the GitOps operator handles deployment
- Reduced blast radius: the CI/CD pipeline no longer needs cluster credentials
GitOps with Promotion

A full GitOps workflow adds a promotion layer on top. A promotion controller (in our case, Kargo) monitors both the Docker registry for new image tags and the Git repository for manifest changes. When new artifacts appear, it creates a “freight” (a bundle of verified artifacts) and promotes it through environments (Dev, Staging, Production) based on defined policies.
The GitOps operator (Argo CD) still handles the actual cluster reconciliation, but Kargo controls when and what gets promoted to each environment.
This is the model we use. It combines the benefits of GitOps (pull-based, drift detection, Git as source of truth) with structured, environment-based promotion that supports our intentional release process.
Comparison Summary
| Aspect | Traditional CI/CD | GitOps | GitOps + Promotion |
|---|---|---|---|
| Deployment model | Push (pipeline applies to cluster) | Pull (operator syncs from Git) | Pull with controlled promotion |
| Source of truth | Pipeline config / scripts | Git repository | Git repository + promotion policies |
| Drift detection | None | Continuous | Continuous |
| Cluster credentials | Required by CI/CD | Only the in-cluster operator | Only the in-cluster operator |
| Rollback | Re-run pipeline or manual | Revert Git commit | Revert Git commit or re-promote previous freight |
| Environment promotion | Pipeline stages or manual | Manual Git changes per env | Automated, policy-driven |
| Audit trail | CI/CD logs | Git history | Git history + promotion records |