# Updatecli describes version bumps as a YAML policy you review

> Updatecli is a Go binary that turns dependency updates into declarative policies with a source, optional conditions and a target, then opens a pull request through whichever forge you use. It ships more than 30 integrations, runs in any CI system, and defaults to a dry run so you see the change before it lands.

**updatecli/updatecli** — A Declarative Update Policy Engine

- Repository: https://github.com/updatecli/updatecli
- Website: https://www.updatecli.io
- Stars: 1,002 · Forks: 158
- Language: Go
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/updatecli-updatecli

## Every update is a policy with a source, a condition and a target

Updatecli is a declarative update policy engine, and the whole model fits in three stages that every policy file follows. Sources fetch the new value to apply, for example the latest Docker image tag, the newest Helm chart version or the latest GitHub release. Conditions verify that all prerequisites are met before any change is made, and the documentation marks that stage as optional but recommended. Targets apply the change to the right file or service, and open a pull request if an SCM is configured.

That third clause carries a lot of weight. The pull request is not the point of the tool, it is one of the possible outcomes of a target. A policy that writes into a file and a policy that opens a merge request differ only in configuration, and the same YAML structure covers both.

The policy itself is a YAML file, or a Go template if you need logic. The README describes the model as describing your update strategy in a policy and then enforcing it with Updatecli, and a run as detecting whether a file needs updating using a tailored policy and then applying the changes. The emphasis on detection before application is what makes the tool safe to schedule on a timer, and it is also what makes a policy worth reviewing: a policy that fails to detect a needed change fails silently, and nothing in the design will warn you about that.

The project is written in Go, the module is github.com/updatecli/updatecli, and the go.mod requires Go 1.27.2.

## Thirty integrations across files, images, registries and releases

The integration list is what separates Updatecli from a dependency bot for one ecosystem. The README states that Updatecli ships with more than 30 built-in integrations, grouped by what you are updating.

File formats are covered directly: values in YAML, JSON, TOML, XML, HCL, CSV, Dockerfiles and .tool-versions files, or any text file with pattern matching. Container images are tracked by tag and digest from Docker Hub or any OCI-compliant registry. Package registries include Helm charts including OCI, npm, PyPI, Maven, Cargo crates, Go modules, and Terraform providers and modules. Git and releases cover GitHub and GitLab releases, Git tags and branches. Runtimes include Jenkins LTS and weekly releases, Eclipse Temurin for the JDK, Go language versions, and Bazel modules and registry. Cloud coverage is AWS AMIs. And for everything else there are shell scripts and HTTP endpoints as custom logic, plus the option to contribute a new Go plugin.

The pattern-matching file support is the quiet workhorse. When an integration does not exist for a format, the tool can still find and replace a version string in a text file, which is how teams keep unusual manifests in scope without writing code.

The cost of breadth is the size of the dependency list. The go.mod pulls in the AWS SDK for EC2, the Gitea SDK, the GitHub client, the Azure DevOps API client, go-git, Helm controller and source controller APIs, HCL parsing, container registry tooling, Terraform registry address handling, sops, age and ProtonMail crypto, an extism SDK for plugins, and a semver library, among others. A single Go binary that talks to every forge and every registry carries every one of those clients along.

## The forge decides whether you get a pull request or a merge request

Updatecli talks to source control through plugins, and the support table in the README is worth reading because the naming differs by platform. GitHub is supported with clone, branch, commit, push, pull requests and releases. GitLab offers the same list with merge requests instead of pull requests. Gitea, Forgejo, Bitbucket Cloud, Bitbucket Server and Stash, and Azure DevOps are all supported, and a generic Git repository is supported for clone, branch, commit and push without any pull request capability.

The Forgejo line is a note about implementation rather than a separate implementation. The README says it is compatible through Gitea API support, and the plugin column confirms it, since Forgejo uses the gitea plugin.

This is where the design pays off for a team with more than one forge. A policy that references the same source and target can be run against GitHub for one repository and GitLab for another, with the change delivered as whichever review artefact that platform expects. The alternative, and the point the README makes in its why section, is that other projects in this space have an opinionated way of doing it and often want you to adopt a new platform. The stated goal of Updatecli is to work independently of the underlying dependencies to update, wherever you need it, and to combine with whatever workflow you are using.

## Install, verify the release, then preview with a dry run

Updatecli is a Go binary available for Linux, macOS and Windows from the release page, and it also ships as a container image on ghcr.io. The release page has an install page for other methods, and a quick start guide is published separately.

The verification instructions are unusually careful. Instead of signing every release asset, Updatecli signs the checksums file, and the README explains that you download the checksums file and its signature from the latest release and then run cosign to check the signature against the repository identity:

```bash
cosign verify-blob --certificate-identity-regexp "https://github.com/updatecli/updatecli" --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' --bundle checksums.txt.sig checksums.txt
```

A successful run prints Verified OK. Once the signature checks out, you can verify the binary itself against the checksums file with:

```bash
sha256sum --ignore-missing -c checksums.txt
```

The container image can be checked the same way, with the tag you actually intend to run:

```bash
cosign verify --certificate-identity-regexp "https://github.com/updatecli/updatecli" --certificate-oidc-issuer "https://token.actions.githubusercontent.com" ghcr.io/updatecli/updatecli:v0.122.1
```

Before applying anything, the recommended habit is a preview. The feature list names safety by default through a --dry-run flag that previews every change before it is applied, and the Makefile in the repository shows the same pattern in its smoke test targets, which run the diff and show subcommands against a configuration directory rather than applying anything.

A policy file is what you feed it, and the repository ships an updatecli-compose.yaml at the top level along with a compose setup, so the typical deployment is a scheduled CI job that runs the binary against policies kept in the repository.

## Detection depends on the source, and a quiet failure looks like success

The design has one soft spot, and it comes from the source stage. If the source cannot determine the new value, the policy has nothing to compare against, and the run ends without a change. That is correct behaviour, but it is indistinguishable in the logs from a situation where no update was needed, unless you read the output carefully.

The condition stage is the mitigation, and the documentation calls it optional but recommended. A condition verifies prerequisites before any change, so a policy can require that the current value is at least a given version, or that a companion file exists, before proposing anything. In a deployment where a source silently stops working, a condition that also stops the run makes the difference between a failed job and a quiet week of stale versions.

The second limitation is scope. Updatecli opens a pull request, it does not merge one, and it does not run your tests. The target stage applies a change to a file or a service and hands the rest to your review and CI process. That is a deliberate boundary for a tool that runs unattended on a schedule, and it is also the reason it fits teams that already have a review culture and the reason it disappoints teams looking for a bot that does everything.

The custom logic escape hatch closes the gap for formats without an integration. A shell script or an HTTP endpoint can compute or fetch anything the built-in sources cannot, at the cost of moving the failure modes into code you now maintain.

## A single binary that fits an existing CI, not a platform to adopt

The README's own argument for the project is worth quoting in shape if not in words. Building and distributing software is difficult and good practices constantly evolve, so a tool that keeps dependencies current has to keep working with whatever you already run. Updatecli is built to work independently of the underlying dependencies to update, wherever you need it, and to combine with whatever workflow you are using.

The evidence for that claim is in the shape of the repository. There is a single main.go and a cmd/ directory, a pkg/ tree, a Makefile driven by goreleaser with build, build.all, release, release.rc and release.snapshot targets, a docker/ directory, an e2e/ directory, and a .golangci.yml for linting. There is no service, no dashboard and no daemon. It is a binary you invoke.

That also means the operational model is yours. Updatecli will run in GitHub Actions, Jenkins, GitLab CI or any shell, and it will run in a cron job on a machine you control. What it will not do is give you a dashboard of what it changed across the estate, notify a team that a policy silently stopped detecting, or schedule runs for you. If you want a control plane, you have to build it around the binary, and the ADOPTERS.md and COMPATIBILITY.md files at the top level are where the compatibility surface is described.

The custom logic extension point and the Go plugin route both exist, so extending coverage is possible, but the plugin surface is Go code in a repository whose own release cadence is a few weeks apart, so a fork and a scheduled bump is the realistic path for anything custom.

## Apache-2.0, frequent releases, and a fast moving Go toolchain

The licence is Apache-2.0, which is permissive and includes an explicit patent grant, so there is no question about using Updatecli inside a commercial product or modifying it.

Release cadence is quick and consistent. The recent versions are v0.122.1 on 2026-10-03, v0.122.0 on 2026-09-26 and v0.121.0 on 2026-09-11, and the last push was on 2026-10-18 with the repository not archived. The project also runs a community over Matrix and carries a code of conduct, an OpenSSF scorecard badge and a best practices badge, which are the usual markers of a project that expects to be used in pipelines.

Two upgrade costs are worth planning for. First, the Go version requirement moves with the project, since the module already asks for Go 1.27.2, so your build environment has to keep pace. Second, a project at 0.x with a minor bump every few weeks can carry breaking changes in configuration or behaviour, which is another argument for keeping your policies small, explicit and covered by a dry run in your pipeline before you trust an automatic apply.

The go.mod also contains a retraction entry, retract v0.999.0 with the comment Published accidentally, which is a small sign of a project that cleans up its own release history.

## Conclusion

Updatecli suits a team with mixed dependency types, several forges, and a preference for reviewing version bumps in the same pull request flow as everything else, and it is a good fit for CI systems where adopting a dedicated dependency bot would mean changing platforms. It is the wrong tool when a hosted bot already covers your ecosystem, when you need the tool to merge or test the change itself, or when a 0.x to 1.x jump needs human judgement. Verify first that your policy's condition stage actually fails when a prerequisite breaks, that a dry run against your real repository shows the diff you expect, and that the checksums file you verify with cosign matches the release tag you installed.

## FAQ

### What is Updatecli and what does a policy file look like?

Updatecli is a declarative update policy engine written in Go. Every policy is a YAML file, or a Go template, that runs through three stages: sources fetch the new value, optional conditions check prerequisites, and targets apply the change to a file or service and open a pull request if an SCM is configured.

### How do I install Updatecli and verify the release?

It is a Go binary for Linux, macOS and Windows from the release page, and there is a container image on ghcr.io. The project signs the checksums file rather than each asset, so you verify that with cosign verify-blob against the repository identity, then check the binary with sha256sum --ignore-missing -c checksums.txt.

### Which source control platforms can Updatecli open pull requests on?

GitHub, GitLab with merge requests, Gitea, Forgejo through Gitea API support, Bitbucket Cloud, Bitbucket Server or Stash, and Azure DevOps, with a generic git plugin that can clone, branch, commit and push without pull request support.

### What does Updatecli update?

More than 30 built-in integrations: YAML, JSON, TOML, XML, HCL, CSV, Dockerfiles and .tool-versions or any text file by pattern, container image tags and digests, Helm charts, npm, PyPI, Maven, Cargo, Go modules, Terraform providers, GitHub and GitLab releases, Git tags, Jenkins, Temurin, Go, Bazel and AWS AMIs, plus shell scripts and HTTP endpoints for custom logic.

### How current is Updatecli and what licence does it use?

It is Apache-2.0 licensed, the repository is not archived, and the last push was on 2026-10-18, with releases v0.122.1 on 2026-10-03, v0.122.0 on 2026-09-26 and v0.121.0 on 2026-09-11. The go.mod requires Go 1.27.2 to build it.

## Sources

- [License: Apache-2.0](https://github.com/updatecli/updatecli/blob/main/LICENSE)
- [Project website](https://www.updatecli.io)
- [README](https://github.com/updatecli/updatecli/blob/main/README.md)
- [Releases](https://github.com/updatecli/updatecli/releases)
- [updatecli/updatecli on GitHub](https://github.com/updatecli/updatecli)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/updatecli-updatecli
