gitopsctr
gitopsctr is a local-first deployment reconciler. It materializes desired state from a source
revision, records deployment receipts in Git, promotes clean desired state between environments,
and creates forward-only rollback commits.
The command line is the complete operational interface. CI workflows and the reusable GitHub Action invoke the same commands that an operator can run locally.
Development
Requirements are managed with mise and uv.
mise install
mise run sync
mise run check
The project supports Python 3.12 and newer. Ruff formats and lints the code with a 120-character line length; ty checks the package.
CLI
Run gitopsctr --help for the complete command list. The CLI discovers the Git repository containing
the current directory. Use --repository PATH or GITOPSCTR_REPOSITORY to select one explicitly.
Important commands include:
create project|environment|unit: scaffold schema-valid authored resources.validate: validate files, environments, or the complete authored Project.advance-desired: materialize the next desired-state commit.reconcile --plan: run a speculative unit-driver plan without applying or publishing a receipt.reconcile: apply one unit and publish its receipt.converge: reconcile a dependency closure locally.list environmentsandlist units: inspect deployment summaries and unit status.status: show all environments, one environment, or one unit within an environment.show desiredandshow receipt: print a desired unit or observation receipt in the project's format.promote: promote a clean environment through its configured change gate.rollback: publish a forward desired-state commit from historical state.verify: ask supported drivers to check external state without writing receipts.
Human-readable progress output uses semantic ANSI colors on terminals and in CI logs. It stays plain when redirected
to a file or captured for automation. Set NO_COLOR=1 to disable styling or FORCE_COLOR=1 to enable it explicitly.
Machine-readable stdout remains uncolored.
Explore a project without changing state:
gitopsctr list environments
gitopsctr list units --environment dev
gitopsctr show desired --environment dev web
gitopsctr show receipt --environment dev web
gitopsctr show receipt --environment dev web --artifact containers
gitopsctr show receipt --environment dev web --artifacts
# Add --json or --yaml to override the project's preferred document format.
Demo
mise run demo creates an isolated local Git remote, builds and publishes a real OCI image to a local
registry, and deploys it as a Docker container through the Terraform driver. See demo/docker
for prerequisites, the reconciliation flow, and cleanup instructions.
Unit drivers
API kinds are discovered from the gitopsctr.apis Python entry-point group. Every full-GVK entry point loads a typed
ApiKind; unit APIs carry a UnitDriver specification implementing at least MaterializationCapability or
ReconciliationCapability, while artifact APIs carry their typed resource contract. Verification is an independent
optional driver capability. The built-in drivers live under gitopsctr.contrib.drivers, one module per driver.
The kubernetes-manifests unit driver renders Helm or plain YAML into the desired Git tree. It supports direct apply,
materialization-only external delivery, and read-only Argo CD observation. See the
available unit drivers for all built-ins and the
Kubernetes unit driver page for delivery modes and rollback behavior.
JSON Schemas
Built-in APIs publish Draft 2020-12 resource schemas for authored units, desired units, receipts, and artifacts at
https://niklasrosenstein.github.io/gitopsctr/schemas/.
Controller resource schemas are published alongside them.
Use gitopsctr schemas show API_VERSION KIND for one schema and gitopsctr schemas export DIRECTORY to generate the complete
catalog. Committed YAML specifications should use a pinned # yaml-language-server: $schema=... directive; JSON
specifications should use the same pinned URL in $schema. gitopsctr treats both forms as untrusted editor hints and
never fetches them.
GitHub Action
The repository's root composite action wraps reconciliation preparation, reconcile, advance-desired, promote,
and rollback. operation: prepare is action-only orchestration terminology: it selects an exact desired revision
by calling advance-desired for a supplied source revision or resolve-desired otherwise. It does not add a
CLI command or persisted controller state. The action can
install the CLI from PyPI, from the checked-out action revision, or from an explicit Git repository
and revision. Caller workflows retain responsibility for credentials, deployment tools, permissions,
concurrency, and follow-up scheduling.
Prepare one exact desired revision before fan-out reconciliation jobs:
- id: prepare
uses: NiklasRosenstein/gitopsctr@<commit-or-ref>
with:
operation: prepare
package-source: action
environment: dev
source-revision: ${{ github.sha }}
require-source-ref: main
The outputs are active, desired-revision, desired-changed, and advance-after-reconcile. Supplying an
exact desired-revision makes the run fixed (advance-after-reconcile=false); without one, later receipts may
continue materializing desired state. A source revision superseded through require-source-ref returns
active=false.
Publish a full-tree or targeted forward rollback through the same change-gate behavior as the CLI:
- id: rollback
uses: NiklasRosenstein/gitopsctr@<commit-or-ref>
with:
operation: rollback
package-source: action
environment: prod
rollback-revision: <historical-desired-sha>
units: aws-application,frontend
reason: Incident mitigation
An empty units input rolls back the full tree. The action exposes the standard change-revision,
change-status, change-url, candidate-ref, and target-ref outputs for direct publication or a gated pull
request.
Install the package bundled with the exact action revision while testing an unreleased change:
- uses: NiklasRosenstein/gitopsctr@<commit-or-ref>
with:
operation: reconcile
package-source: action
environment: dev
unit: application
Install the latest PyPI release (the default):
- uses: NiklasRosenstein/gitopsctr@v1
with:
operation: advance
environment: dev
source-revision: ${{ github.sha }}
Install from a separate Git revision:
- uses: NiklasRosenstein/gitopsctr@v1
with:
operation: promote
package-source: git
package-repository: NiklasRosenstein/gitopsctr
package-revision: <commit-or-ref>
from-environment: dev
to-environment: staging
The caller must check out its deployment repository before invoking the action. For gated changes,
grant contents: write and pull-requests: write; for reconciliation receipts, grant
contents: write. Pass any cloud credentials and required external tools in the caller workflow.
Releases
CI runs the mocked suite on Python 3.12, 3.13, and 3.14. Tags matching v* are accepted only when
the tag equals v plus the package version. After verification and an isolated package build, the
release workflow publishes through PyPI Trusted Publishing using the protected pypi environment.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gitopsctr-0.1.1.tar.gz.
File metadata
- Download URL: gitopsctr-0.1.1.tar.gz
- Upload date:
- Size: 210.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
410604cd1c3fd5aded2428b3b52d41052b2f0b324b228db3693b2b544ad19046
|
|
| MD5 |
82ac213e86b17c7e58cb7b04768d53f9
|
|
| BLAKE2b-256 |
e165c0efe1d1e71c83dbb11a984f76d8d62ee9e38857be67a14dba4e7d501c53
|
File details
Details for the file gitopsctr-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gitopsctr-0.1.1-py3-none-any.whl
- Upload date:
- Size: 101.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3886e1b2fe5280524c4d1a357b601ae084773b4657b0b06663eeb047f21eb225
|
|
| MD5 |
12940146b291ab67d5f8de06e26d87f8
|
|
| BLAKE2b-256 |
78c6c03b16b3a8a5142d338424062c7a59967cd3c58e947ef647e79bd0272c1c
|