Repository navigation
Releases: OpusProjects/unified-gitops
Releases · OpusProjects/unified-gitops
Release list
v0.5.0
0.5.0 (2026-10-30)
⚠ BREAKING CHANGES
- webhooks lose
type,ascender:,awx:andprojects:and name oneproject.webhook.credentialsbecomes the item'scredential,webhook.signbecomeswebhook.signature,webhook.retriesbecomesretry.attempts, and{{field}}placeholders become$event.field. - the
applicationsandconnectorssections, config.yaml'sstateblock, the/api/v1/applications,/api/v1/connectorsand/api/v1/searchroutes, the application webhook events and theapplicationsfield of api_keys, LDAP access rules and webhooks are removed; restricted keys and access rules nameprojects.
Added
- call APIs with what a commit changed (#39) (65fb098)
- make webhooks generic HTTP requests with every common option (#38) (aa0f450)
- remove applications and connectors (10d55ab)
- run scripts when a commit changes what they watch (#40) (0248098)
Fixed
v0.4.0
Added
- A project's last pulls:
historyon each project inGET /api/v1/projects, newest first, up to 50, in memory since the process started, as an application's runs are. Each says when it started, how long it took, why (scheduled,manual,checkbefore an application's check or sync, kept only when it moved the commit or failed,startup), who asked a manual one (the API key's name or the signed-in user), how it ended, and the commit it found the checkout at and left it at (seedocs/projects.md). - Credentials name their environment variables in full with
env_vars: {<field>: <VAR>}(env_vars: {password: LDAP_PASSWORD}readsLDAP_PASSWORDaspassword), and API keys withenv_vars: {key: <VAR>};env_varsandenv_prefixon one credential,env_varsbeside avault_path,secret_fileorsecret_keys(a credential reads from one place), an API keyenv_varsfield other thankey, and an API key with both or neither ofenv_vars.keyandenvare refused at load (seedocs/secrets.md). - Every credential field also reaches the connector under its credential's id,
CREDENTIAL_<ID>_<FIELD>(the name without a leadingcred-/cred_, anything outsidea-z0-9made_:cred-portainer-ldap'spasswordisCREDENTIAL_PORTAINER_LDAP_PASSWORD), so an application can use two credentials with the same fields; a field no other credential has and already named after its own (portainer_urloncred-portainer) is not prefixed again, and two values that would still reach one variable fail the run naming both. - A Vault is a credential of
type: vault(address,mount,env_vars: {token: <VAR>}orkubernetes_role,timeout_seconds,cache_ttl_seconds), as AWX models a Vault lookup; a credential reads from it withvault: <its name>andvault_path, so several Vaults can coexist, each with its own login and cache. Naming a Vault credential as an application's, project's, webhook's or LDAP bind's credential, a Vault field on another type, and avault:that is not a Vault are refused at load;GET /api/v1/credentialsaddsvault,used_by.credentialson a Vault lists the credentials reading from it, andvault_connection(address, mount, auth, kubernetes_role, token_env, timeout_seconds, cache_ttl_seconds) describes each Vault, null for any other type (seedocs/secrets.md). - A project names its credential with
credentials:, a list as on every other item (at most one: a clone authenticates once); a project listing more than one, or setting both forms, is refused. - The web UI from unified-ui 0.6.0 (was 0.4.0): a History panel on a project's page, an Order menu on every list, cron schedules in words, counts with thousands separators, linked items as tables on each page, Overview cards that hold their place while they load, a Secrets card on Configuration with one row per Vault, and project cards that always show their Credentials (None for a public repository).
Changed
- Breaking (scripts reading a field two credentials share, and webhooks with several credentials):
CREDENTIAL_<FIELD>is delivered only when exactly one of the application's credentials has that field, instead of one credential silently overwriting the other; readCREDENTIAL_<ID>_<FIELD>. Two credentials one application or webhook would deliver under one id (cred-vc-aa1andcred_vc_aa1) are refused, a webhook whose credentials share a field it reads by its bare name is refused (token, orusernameandpassword, and the signing secret, as its auth and signature say; a shared field loses its bare name), andenv_varsbeside avault_path,secret_fileorsecret_keysis refused instead of one side being silently ignored. - Env and file credentials are read on every resolution instead of being reused for 60 seconds: a rotated mounted file is seen on the next check. Only a Vault caches, for its own
cache_ttl_seconds;GET /api/v1/settingsanswerssecrets.cache_ttl_secondsas null unlessconfig.yamlstill sets it.
Deprecated
- A credential's
env_prefix+secret_keysand an API key'senv: VARstill load, with a notice at startup and from--check-confignaming theenv_varsto write in their place; a later release refuses them. - The
secrets:block inconfig.yaml(cache_ttl_seconds, andvault:withtoken_env) still loads, with a notice saying to declare the Vault as atype: vaultcredential; while set, its cache still covers every credential and avault_pathwith novault:reads from it. A later release refuses it. - A project's singular
credential: <id>still loads, with a notice naming thecredentials: [<id>]to write; a later release refuses it.
Fixed
- A field shared by two credentials is never delivered under its bare name, even when it starts with its credential's id (
ssh_key_pathoncred-sshbesidecred-ssh-dc4); fields are compared as the variable they become (TOKENandtoken), and two values that would reach one variable fail the run naming both instead of one winning. - A credential reading from two places in the older forms too (
vault_path,env_prefix,secret_file) is refused instead of one being silently ignored; a project listing one credential twice is not refused; the deprecatedsecrets.vaultwithtimeout_seconds: 0is refused. - An explicit
secrets.cache_ttl_seconds: 0means no cache for every credential, Vaults included, as in 0.3.0;vault_connection.cache_ttl_secondsreports the cache in effect, andGET /api/v1/settingsaddssecrets.deprecated. A project'shistoryrows addage_seconds, measured on the server. - A webhook's shared-field check covers only the fields it reads by bare name (its auth's and its signature's), compared as the variable they become, so a shared field it never reads no longer fails the configuration and
Tokenbesidetokendoes;used_byonGET /api/v1/credentialsaddswebhooks, so a credential only a webhook sends with no longer looks unused. --check-config <dir>checks<dir>instead of ignoring it and readingCONFIG_DIRor./config, which could report OK about a directory it never read.- A configuration still on the deprecated
secrets.vaultkeeps its 60-second cache whensecrets.cache_ttl_secondsis absent, as 0.3.0 did by default, instead of reading Vault on every resolution; set, that outer cache replaces each Vault's own instead of stacking on it. - A field already named after its credential is recognised in any case (
AVAMAR_AA1_URLoncred-avamar-aa1) and not prefixed again. - A webhook send whose
token,username,passwordor signing field two of its credentials share says the field is shared instead of "the credential has no 'token' field", and a default auth fails the same way instead of silently sending noAuthorization. - A reload logs the same deprecation notices startup does; a Vault credential with
timeout_seconds: 0is refused. - Starting connector scripts retries briefly on "text file busy" (ETXTBSY) instead of failing the run: a script still open for writing elsewhere, such as one a project pull is rewriting, or a file another thread's child briefly held, now runs once the writer lets go.
v0.3.0
Added
- Project webhooks: a webhook's
projects:(all, or names) hears the projects' own events and those of every application reading from them, including applications added later, combined withapplications:; three project events,commit_pulled(the commits a pull brought, newest first with author and subject, whether history was rewritten, and the applications whose folders changed),pull_failedandpull_recovered, each sent once per change of state; application messages and the send history now name the project, andGET /api/v1/webhooksaddsall_projects,projectsandproject_applications(seedocs/webhooks.md). - The web UI from unified-ui 0.4.0: project webhooks on the Webhooks pages, and the Webhooks card always on the Overview.
v0.2.0
Added
- Webhooks: a
webhooksitem sends, forallapplications or the ones it names,drift_detected,out_of_sync,sync_succeeded,sync_failedandback_in_syncto a webhook (any receiver, with bearer, basic or header auth, a body template and optional HMAC signing) or to an Ascender or AWX job template (through the template's own webhook receiver, so no user is needed), one message per run, drift told apart from a commit by the application's own folder in git, queued and retried without one receiver holding up the others, its changes listed by name and never with a field's value;GET /api/v1/webhooksshows each one's last send,GET /api/v1/webhooks/{id}its last 50, andPOST /api/v1/webhooks/{id}/testsends a test (seedocs/webhooks.md). - Metrics
unified_gitops_git_requests_total{project,operation,outcome}andunified_gitops_git_request_duration_seconds: every clone, pull and rollback fetch this instance makes to a git server, asunified_gitops_connector_calls_totalcounts those to the systems. - The web UI from unified-ui 0.3.0: Webhooks pages, live ages, and requests to repositories on the Overview.
Changed
- Breaking (who runs the image): the image no longer bundles a demo configuration or connectors (
/app/config,/app/connectors); mount your configuration at/app/configor setCONFIG_DIR, and take connectors from a project such as unified-connectors, which now holds the SDK and thekvexample.
v0.1.0
First version: GitOps for anything with an API.
Added
- Applications: one live system each (a connector, its config and credentials) and a folder of desired state as YAML in a git project, checked on an interval and applied on demand or with
auto_sync. - A diff that belongs to the core: objects matched on each kind's key, only the fields git declares compared, kinds applied in
depends_onorder, and deletes only withprune. - Connectors as plain scripts with a small contract (
describe,list,apply) and a Python SDK; writes allowed only onapply. - Drift detection, a local copy of each system's settings, a plan before every apply, run history with diffs, and rollback to an older commit.
- Configuration as code, one item per file, validated strictly, reloadable live and pushable over the configuration API.
- API keys and LDAP sign-in, secrets from env or Vault, Prometheus metrics, and the web UI from unified-ui 0.2.0.