Keep your GitHub Actions up to date — interactively, safely, and fast.
actup is a version manager for GitHub Actions — like nvm is for Node or fvm for Flutter. Set and pin the versions your workflows use, keep a .actup.yaml manifest as the source of truth, and upgrade to the latest versions when you're ready — interactively via a terminal UI, or non-interactively in CI. It detects known breaking changes between major versions and warns you before upgrading.
# Bootstrap a manifest pinning the versions your workflows already use
actup init
# Set an action version across every workflow (and pin it in .actup.yaml)
actup use actions/checkout@v5
# Make workflows follow the manifest after editing it
actup sync
# Upgrade everything to the latest versions — pick in a TUI
actup
# Preview changes without touching files
actup --dry-run- Version manager commands —
use,pin/unpin,ls,init,sync, andoutdatedgive you nvm-style control over action versions - Vulnerability audit —
actup auditchecks every action version against the OSV.dev advisory database (GitHub Actions ecosystem); the TUI and non-interactive flows also warn inline - Manifest as source of truth —
.actup.yamldeclares your action versions;syncapplies it to every workflow - Workflow discovery — recursively finds
.yml/.yamlfiles under.github/workflows/ - Interactive TUI — Bubble Tea–powered checklist with select-all, per-action toggle, and breaking-change detail view
- Non-interactive mode —
--no-tuiupgrades everything; prompts on TTY for breaking changes (override with--force) - Breaking-change detection — embedded registry of known breaking changes between major versions
- Major-tag or full semver — default resolves
v5-style tags;--semveropts intov5.3.1pinning - Dry-run —
--dry-runpreviews a diff without touching files - Atomic writes — temp-file + rename prevents partial updates
- Concurrent API — up to 5 parallel GitHub requests with in-memory caching
- GitHub CLI fallback — auto-discovers tokens from
gh auth tokenwhen no env var is set
- Quick Start
- Installation
- Usage
- Version Manager
- AI Skill
- Configuration
- Pre-commit Hooks
- Breaking Changes
- Vulnerability Audit
- Roadmap
- Contributing
- License
- Acknowledgments
Homebrew (macOS & Linux):
brew tap lynicis/tap
brew install actupScoop (Windows):
scoop bucket add actup https://github.com/lynicis/scoop-bucket.git
scoop install actupGo install:
go install github.com/lynicis/actup@latestDebian / Ubuntu:
curl -LO https://github.com/lynicis/actup/releases/latest/download/actup_latest_linux_amd64.deb
sudo dpkg -i actup_latest_linux_amd64.debFedora / RHEL / CentOS:
curl -LO https://github.com/lynicis/actup/releases/latest/download/actup_latest_linux_amd64.rpm
sudo rpm -i actup_latest_linux_amd64.rpmReplace
amd64witharm64for ARM systems.
Images are published to ghcr.io/lynicis/actup for linux/amd64 and linux/arm64:
# Show help
docker run --rm ghcr.io/lynicis/actup:latest --help
# Scan current directory
docker run --rm -v "$PWD:/workdir" -w /workdir ghcr.io/lynicis/actup:latest
# With GitHub token for higher rate limits
docker run --rm -v "$PWD:/workdir" -w /workdir \
-e GITHUB_TOKEN \
ghcr.io/lynicis/actup:latestRequires Go 1.27 or later.
git clone https://github.com/lynicis/actup.git
cd actup
make build
make install # optional, installs to $GOPATH/binDownload binaries for Linux, macOS, or Windows from the Releases page.
Run actup from the root of any repository with GitHub Actions workflows:
# Interactive mode (default) — opens TUI to select upgrades
actup
# Non-interactive mode — upgrades all actions automatically
actup --no-tui
# Preview changes without writing files
actup --dry-run
# Use full semver tags instead of major tags (e.g., v5.3.1 instead of v5)
actup --semver
# Force upgrades past known breaking changes (non-interactive mode)
actup --no-tui --force
# Scan custom paths
actup -p ./my-workflows -p ./another-path
# Provide a GitHub token for higher rate limits (5,000 req/hr vs 60)
actup -t $GITHUB_TOKEN
# or set the environment variable
export GITHUB_TOKEN=ghp_xxx
actupactup treats .actup.yaml as the manifest of the action versions your repository declares — the same role .nvmrc plays for Node.
| Command | nvm / fvm equivalent | What it does |
|---|---|---|
actup init |
npm init |
Bootstrap .actup.yaml from the versions your workflows already use |
actup use <action>@<ref> |
nvm use / fvm use |
Set an action's version across all workflows and pin it in .actup.yaml |
actup pin <action>[@<ref>] |
nvm alias |
Record a pin in .actup.yaml without touching workflows |
actup unpin <action> |
— | Remove a pin from .actup.yaml |
actup sync |
fvm install |
Apply all .actup.yaml pins to your workflows |
actup ls |
nvm ls |
List actions in use, their versions, and pin status (--outdated adds latest versions) |
actup outdated |
nvm outdated |
List actions that can be upgraded (exits non-zero if any) |
actup audit |
npm audit |
Check action versions against known vulnerabilities (exits non-zero if any) |
actup |
nvm upgrade |
Interactively upgrade everything to the latest versions (TUI) |
| Argument | Behavior |
|---|---|
@v5 |
Written verbatim — the standard moving major tag |
@5 |
Resolved via the GitHub API to the latest tag within major v5 (e.g. v5.3.1) |
@latest / no @ref |
Resolved to the latest tag (major tag, or full semver with --semver) |
@v5.3.1, @master |
Written verbatim |
use saves the pin to .actup.yaml by default so your manifest stays the source of truth; pass --no-save to only update workflows, or --dry-run to change nothing.
actup init # 1. declare current versions
actup use actions/checkout@v5 # 2. switch an action everywhere
# 3. ...or edit .actup.yaml by hand, then apply it:
actup sync
actup ls --outdated # 4. review what could be upgraded
actup # 5. upgrade everything interactivelyYou can also use actup's workflow-upgrading logic as an Agent Skill in compatible AI coding agents (Claude Code, OpenCode, Cursor, etc.).
Via gh skill (agentskills.io):
gh skill install lynicis/actup github-actions-updaterVia npx skills (skills.sh):
npx skills add lynicis/actup --skill github-actions-updaterOnce installed, ask your agent:
"Update my GitHub Actions" "Which actions are out of date?" "Bump actions in my workflows"
The skill scans your .github/workflows/*.yml files, resolves the latest version of each action from GitHub, warns about known breaking changes, and produces a diff-style report with suggested upgrades. It does not edit files unless you explicitly ask.
actup resolves GitHub tokens in this order:
--tokenflagGITHUB_TOKENenvironment variablegh auth tokenfrom the GitHub CLI
Authenticated requests get 5,000 API calls/hour vs 60 for unauthenticated. To set up gh:
gh auth login.actup.yaml is your action version manifest — the declared source of truth that actup sync applies to your workflows. actup init generates it, actup use and actup pin keep it up to date, and actup outdated honor it. Editors supporting YAML language servers will provide autocomplete and validation if you add the $schema directive:
# yaml-language-server: $schema=https://raw.githubusercontent.com/lynicis/actup/main/schema.json
# Global default major version (overridden by --semver flag)
major: 4
# Per-action version pins
actions:
actions/checkout: 4 # pin to latest v4.x.x (resolved at sync/upgrade time)
actions/setup-go: v5.3.0 # pin to exact version
some-org/some-action: skip # exclude from upgradesPin semantics in sync and upgrade mode:
- Exact ref (
v5,v5.3.1,master) — applied verbatim - Major number (
4) — resolved to the latest tag within that major via the GitHub API skip— the action is excluded from upgrades and syncing
Precedence: CLI flags > config file > built-in defaults.
Catch stale action versions before they land in a commit — two options:
Installs a plain pre-commit hook that runs actup outdated on every commit:
actup install-hooks # install the hook
actup install-hooks --dry-run # preview before installing
actup install-hooks -f # overwrite existing hook
actup install-hooks --uninstall # remove the hookAdd to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/lynicis/actup
rev: v0.5.0
hooks:
- id: actup-checkThe hook runs
actup outdatedand fails the commit if any actions can be upgraded. Omitrevto trackmainfor the latest version.
actup includes an embedded registry of known breaking changes between major versions. When an upgrade involves breaking changes:
- TUI mode: Shows a
⚠ breaking changesbadge — pressifor details - Non-interactive mode: Prompts for confirmation on TTY, or use
--forceto skip prompts
The registry lives in internal/breakingchanges/registry.yaml. Contributions welcome — if you encounter a breaking change not in the registry, please open a PR.
actup audit checks every uses: reference in your workflows against the OSV.dev advisory database (GitHub Actions ecosystem). It reports the advisory ID, severity, and the first fixed version:
actup audit # human-readable output
actup audit --json # machine-readable output for CI- Exits
1when vulnerable action versions are found,2when the OSV database cannot be reached — the same convention asactup outdated. - Vulnerability matching happens client-side against OSV range data, so major-tag refs (e.g.
@v4) are matched correctly even though OSV only indexes full semver tags. - Actions marked
skipin.actup.yamlare excluded. - The interactive TUI and
--no-tuiupgrade flows also warn inline: the TUI shows a⚠ vulnerablebadge (pressifor details), and non-interactive runs print warnings before upgrading. actup use,actup sync, andactup outdatedsurface the same warnings, anduse/syncalso check the target version you're about to pin: if that version is itself affected by a known advisory, you'll see it before anything is written (interactivey/Nprompt on a TTY, notice + proceed in CI, auto-proceed with--force/--dry-run).
- Interactive TUI with checklist selection
- Non-interactive (
--no-tui) mode - Dry-run support
- Concurrent GitHub API calls with rate-limit awareness
- Cross-platform builds (Linux, macOS, Windows)
- Pre-commit hooks for CI integration
- Major version pinning (
--major) - Config file support (
.actup.yaml) - Breaking-change detection with embedded registry
- Full semver tag resolution (
--semver) - Vulnerability audit against OSV.dev (
actup audit) - Integration with
dependabot-style grouped updates - Pre-upgrade hooks / custom validation
See open issues for the full list of proposed features and known issues.
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and lint:
make test && make lint - Commit with a descriptive message (
git commit -m 'feat: add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a pull request
Please ensure your code passes existing tests and follows the project's style conventions.
Distributed under the MIT License. See LICENSE for details.
Built with these excellent libraries:
- Bubble Tea — TUI framework
- Cobra — CLI framework
- go-github — GitHub API client
- go-yaml — YAML parser
