santosr2/uptool
Universal, manifest-first dependency updater
uptool combines the ecosystem breadth of Topgrade, the precision of Dependabot, and the flexibility of Renovate — but with a manifest-first philosophy that works across ANY project toolchain defined in configuration files.
Unlike traditional dependency updaters that focus on lockfiles, uptool updates manifest files directly (package.json, Chart.yaml, .tf files, etc.), preserving your intent while keeping dependencies current.
Why uptool?
Modern projects span multiple ecosystems—npm, Helm, Terraform, pre-commit, runtime managers. Each has its own update mechanism. uptool provides a unified interface to scan, plan, and update all dependencies from one tool.
Manifest-First Philosophy
- Update manifests (package.json, Chart.yaml, *.tf) first
- Use native commands only when they update manifests
- Then run lockfile updates (npm install, terraform init)
This ensures declared dependencies stay current, not just resolved versions.
Features
- Multi-Ecosystem Support: npm, Helm, Terraform, tflint, pre-commit, GitHub Actions, Docker, asdf, mise — all in one tool
- Manifest-First Updates: Updates configuration files directly, preserving formatting and comments
- Dual Usage Modes: Use as a CLI tool locally or as a GitHub Action in CI/CD
- Intelligent Version Resolution: Queries upstream registries (npm, Terraform Registry, Helm repos, GitHub Releases)
- Organization Policies: Enforce governance, security, and compliance requirements with pluggable guard system
- Auto-Merge Guards: Extensible plugin system for custom approval workflows (CI checks, security scans, custom integrations)
- Safe by Default: Dry-run mode, diff generation, validation
- Concurrent Execution: Parallel scanning and planning with worker pools
- Flexible Filtering: Run specific integrations with
--onlyor exclude with--exclude - Automated Versioning: Commit-based semantic versioning with GitHub Actions
- Clean Integration Interface: Easy to add support for new ecosystems
Supported Integrations
| Integration | Status | Manifest Files | Update Strategy | Registry |
|---|---|---|---|---|
| npm | ✅ Stable | package.json |
Custom JSON rewriting | npm Registry API |
| Helm | ✅ Stable | Chart.yaml |
YAML rewriting | Helm chart repositories |
| Terraform | ✅ Stable | *.tf |
HCL parsing/rewriting | Terraform Registry API |
| tflint | ✅ Stable | .tflint.hcl |
HCL parsing/rewriting | GitHub Releases |
| pre-commit | ✅ Stable | .pre-commit-config.yaml |
Native pre-commit autoupdate |
GitHub Releases |
| GitHub Actions | ✅ Stable | .github/workflows/*.yml |
YAML text rewriting | GitHub Releases |
| Docker | ✅ Stable | Dockerfile, docker-compose.yml |
Text rewriting | Docker Hub API |
| asdf | .tool-versions |
Detection only (updates not implemented) | GitHub Releases (per tool) | |
| mise | mise.toml, .mise.toml |
Detection only (updates not implemented) | GitHub Releases (per tool) |
Roadmap
- Python (
pyproject.toml,requirements.txt,Pipfile) - Go modules (
go.mod) - Generic version matcher (custom YAML/TOML/JSON/HCL patterns)
Quick Start
Installation
Docker (Recommended)
# Pull the latest stable image
docker pull ghcr.io/santosr2/uptool:latest
# Run uptool (use an alias for convenience)
alias uptool='docker run --rm -v "$PWD:/workspace" ghcr.io/santosr2/uptool'
# Verify installation
uptool versionPre-built Binaries
# Download the latest release for your platform
# Linux (AMD64)
curl -LO https://github.com/santosr2/uptool/releases/latest/download/uptool-linux-amd64
chmod +x uptool-linux-amd64
sudo mv uptool-linux-amd64 /usr/local/bin/uptool
# macOS (Apple Silicon)
curl -LO https://github.com/santosr2/uptool/releases/latest/download/uptool-darwin-arm64
chmod +x uptool-darwin-arm64
sudo mv uptool-darwin-arm64 /usr/local/bin/uptool
# Verify installation
uptool versionGo Install
# Install from source (requires Go 1.25+)
go install github.com/santosr2/uptool/cmd/uptool@latestBuild from Source
git clone https://github.com/santosr2/uptool.git
cd uptool
mise run build # Binary will be in dist/uptoolCLI Usage
# 1. Scan your repository for updateable dependencies
$ uptool scan
Type Path Dependencies
--------------------------------------------------------------------------------
npm package.json 4
helm charts/app/Chart.yaml 3
terraform infra/terraform 2
precommit .pre-commit-config.yaml 2
mise mise.toml 7
Total: 5 manifests
# 2. Generate an update plan
$ uptool plan
package.json (npm):
Package Current Target Impact
--------------------------------------------------------
express ^4.18.0 ^4.19.2 minor
lodash ^4.17.20 ^4.17.21 patch
charts/app/Chart.yaml (helm):
Package Current Target Impact
--------------------------------------------------------
postgresql 12.0.0 18.1.8 major
redis 17.0.0 23.2.12 major
mise.toml (mise):
Tool Current Target Impact
--------------------------------------------------------
go 1.23 1.25 minor
node 20 22 major
Total: 7 updates across 3 manifests
# 3. Preview changes with dry-run
$ uptool update --dry-run --diff
# 4. Apply updates
$ uptool update --diff
# 5. Run specific integrations
$ uptool update --only=npm,helm
# 6. Exclude integrations
$ uptool update --exclude=terraform
# 7. Use custom config file
$ uptool scan --config /path/to/custom-uptool.yamlGitHub Action Usage
Create .github/workflows/dependency-updates.yml:
name: Dependency Updates
on:
schedule:
- cron: '0 9 * * 1' # Every Monday at 9 AM UTC
workflow_dispatch: # Manual trigger
permissions:
contents: write
pull-requests: write
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update dependencies
uses: santosr2/uptool@v0 # Pin to major version (recommended)
with:
command: update
create-pr: 'true'
pr-title: 'chore(deps): update dependencies'
pr-branch: 'uptool/updates-${{ github.run_number }}'
token: ${{ secrets.GITHUB_TOKEN }}Commands
Global flags: -v/--verbose, -q/--quiet, --config, --help
| Command | Purpose | Key Flags |
|---|---|---|
uptool scan |
Discover manifest files | --only, --exclude, --format, --config |
uptool plan |
Generate update plan | --only, --exclude, --out, --config |
uptool update |
Apply updates | --dry-run, --diff, --only, --config |
uptool list |
List integrations | --category, --experimental |
uptool check-policy |
Validate org policies and guards | --verbose, --config |
See CLI Reference for complete documentation.
GitHub Action
See docs/action-usage.md for comprehensive GitHub Action documentation.
Version Pinning
uptool supports mutable tags for convenient version pinning:
# Recommended: Pin to major version (gets latest minor/patch updates)
- uses: santosr2/uptool@v0
# Pin to minor version (gets latest patch updates only)
- uses: santosr2/uptool@v0.2
# Pin to exact version (no automatic updates)
- uses: santosr2/uptool@v0.2.0-alpha20251130How it works:
@v0- Automatically updated to latestv0.x.xrelease@v0.2- Automatically updated to latestv0.2.xpatch@v0.2.0- Fixed to exact release (never changes)
Pre-release tags (for testing):
@v0-alpha- Latest alpha release in v0@v0.2-alpha- Latest alpha release in v0.2@v0.2.0-alpha20251130- Exact pre-release (immutable)
Inputs
| Input | Description | Default | Required |
|---|---|---|---|
command |
Command to run: scan, plan, or update |
plan |
No |
format |
Output format: table or json |
table |
No |
only |
Comma-separated integrations to include | '' |
No |
exclude |
Comma-separated integrations to exclude | '' |
No |
config |
Path to uptool config file | '' (uses uptool.yaml) |
No |
dry-run |
Show changes without applying (update only) | false |
No |
diff |
Show diffs of changes (update only) | true |
No |
create-pr |
Create a pull request with updates | false |
No |
pr-title |
Title for the pull request | chore: update dependencies |
No |
pr-branch |
Branch name for the PR | uptool/dependency-updates |
No |
create-issue |
Create an issue when updates are available | false |
No |
issue-title |
Title for the issue | Dependency Updates Available |
No |
issue-labels |
Comma-separated labels for the issue | dependencies,automated |
No |
token |
GitHub token for API access and PR creation | ${{ github.token }} |
No |
skip-install |
Skip uptool installation (use when already in PATH) | false |
No |
Outputs
| Output | Description |
|---|---|
updates-available |
Whether updates were found (true/false) |
manifests-updated |
Number of manifests with updates applied |
dependencies-updated |
Total number of dependencies updated |
Required Permissions
permissions:
contents: write # To push commits
pull-requests: write # To create PRsIntegration Details
See docs/integrations/ for detailed guides.
Quick examples:
- npm: Updates
package.json, preserves constraints (^,~) - Helm: Updates
Chart.yamldependencies - Terraform: Updates module versions in
*.tffiles - tflint: Updates plugin versions in
.tflint.hcl - pre-commit: Uses native
pre-commit autoupdate - GitHub Actions: Updates action versions in workflow files
- Docker: Updates image tags in Dockerfiles and docker-compose
- asdf/mise: Updates runtime tool versions (experimental)
Architecture
uptool uses a clean integration interface:
type Integration interface {
Name() string
Detect(ctx context.Context, repoRoot string) ([]*Manifest, error)
Plan(ctx context.Context, manifest *Manifest, planCtx *PlanContext) (*UpdatePlan, error)
Apply(ctx context.Context, plan *UpdatePlan) (*ApplyResult, error)
Validate(ctx context.Context, manifest *Manifest) error
}Workflow: Detect manifests → Query registries → Plan updates (with policy context) → Apply changes → Validate
See docs/architecture.md for complete system design.
Configuration
Optional uptool.yaml in your repository root (or specify a custom path with --config):
version: 1
integrations:
- id: npm
enabled: true
policy:
update: minor # none, patch, minor, major
allow_prerelease: false
org_policy:
# Require signoff from team members
require_signoff_from:
- "@security-team"
- "@platform-leads"
# Verify artifact signatures
signing:
cosign_verify: true
# Auto-merge when guards pass
auto_merge:
enabled: true
guards:
- "ci-green" # All CI checks must pass
- "codeowners-approve" # CODEOWNERS must approve
- "security-scan" # Security scans must pass
- "custom-guard" # Your custom guard pluginSee docs/configuration.md, docs/policy.md, and examples/ for complete reference.
Version Management
Automated semantic versioning via conventional commits:
feat:→ minor bump (0.1.0 → 0.2.0)fix:→ patch bump (0.1.0 → 0.1.1)BREAKING CHANGE:→ major bump (0.1.0 → 1.0.0)
GitHub Actions handle releases with approval gates. See docs/versioning.md.
Development
Prerequisites: Go 1.25+, mise
# Build
mise run build
# Test
mise run test
# Quality checks
mise run check # fmt + vet + lint + testSee CONTRIBUTING.md for detailed guidelines and .vscode/README.md for VS Code setup.
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Quick start: Fork → Create branch → Add tests → Run mise run check → Open PR
Use conventional commits: feat:, fix:, docs:, chore:
Security & Governance
- Security: Report vulnerabilities via GitHub Security Advisories, not public issues
- Governance: Trunk-based development. See GOVERNANCE.md
License
This project is licensed under the MIT License. See LICENSE for details.
Documentation & Support
Docs: Overview • Quick Start • Configuration • Organization Policy • Guard Plugins • Integrations • Examples
Community: Issues • Discussions • Changelog
Built with Go, inspired by Topgrade, Dependabot, and Renovate.