Like dependabot, but in bash for local execution. This tool helps you identify and update outdated GitHub Actions in workflow and composite-action files.
- 🔍 Scans workflow and composite-action files for outdated GitHub Actions
- 📍 Shows exact line numbers where actions are used
- 🚀 Shows compatibility scores between versions
- 💾 Caches API responses for faster subsequent runs (24h TTL)
- 🔄 Can automatically create PRs to update actions
- 🤖 Can ask an optional authenticated provider CLI to investigate low or unknown compatibility scores before updating
- ☑️ Indicates GitHub Marketplace verified creators
- 🎨 Cute color-coded output with status badges
- 🏃 Fast local execution
- 🔒 Handles private/internal actions gracefully
gh(GitHub CLI)jqyqcurlgit
AI-assisted updates additionally require an authenticated, supported provider CLI. The interactive setup detects these exact executable names:
| Provider | Executable | Non-interactive interface |
|---|---|---|
| OpenAI Codex | codex |
codex exec with an output schema |
| Claude Code | claude |
claude -p with a JSON schema |
| Cursor Agent | agent (cursor-agent compatibility alias) |
Print mode with JSON output |
| Gemini CLI | gemini |
Headless mode with JSON output |
| OpenCode | opencode |
opencode run with JSON events |
| GitHub Copilot CLI | copilot |
Prompt mode with JSON events |
| Google Antigravity | agy |
Print mode with a JSON schema |
- Clone this repository
- Add the
bindirectory to your PATH or create a symlink tobin/actions-snitchin a directory that's in your PATH
actions-snitch [-c] [-u] [-s] [-f] [-p] [-b branch] [-o format] [-t] [-v] [-h]-cInteractively create the config file and exit (use alone)-uUpdate outdated actions in-place-sPin proposed updates to full commit SHAs; combine with-uor-pto apply-fForce updates regardless of compatibility score (requires -u or -p)-pCommit, push, and create a pull request after updating actions (implies -u)-bBranch to update or create before applying changes (requires -u or -p)-oOutput findings asjson,md, oryaml-tOnly update actions from GitHub Marketplace verified creators (requires -u or -p)-vVerbose output - show skipped actions and debug info-hDisplay help message
actions-snitch -s # Preview updates as full SHA pins
actions-snitch -u -s # Apply updates as full SHA pins
actions-snitch -u # Preserve each reference's existing tag/SHA style| Current reference | -u |
-u -s |
|---|---|---|
| Release tag | Updated tag (major-only tags stay major-only) | Latest release's full commit SHA |
| Full commit SHA | Updated full commit SHA | Updated full commit SHA |
-s also converts already-current release tags to SHA pins. Branch references such as main and master remain skipped. Existing compatibility, AI, and verified-creator gates still apply.
SHA findings show the current SHA's exact matching tag, the latest release, and its resolved commit SHA. All tag pages are searched; when multiple tags match, the lowest full stable semantic version is preferred over moving major/minor aliases. This is an exact commit match, not a claim about the first release containing an ancestor commit.
Current: <40-character current SHA>
Current SHA matches tag: v3.11.1
Latest: 4.4.1
Latest SHA: <40-character latest SHA>
If no tag matches, Commits since: N replaces the tag line. The count comes from GitHub's compare API, including counts beyond one page of commits. With no release, the default branch's SHA is the target. Only a target strictly ahead of the current SHA is an update: identical, behind, and diverged histories are never automatically rewritten. Failed SHA resolution or comparison emits a warning and skips the update. A tag lookup failure is reported separately from a successful lookup with no matches.
Create .snitchignore in the directory where you run actions-snitch. This repository includes .test/ to exclude local fixture checkouts from both findings and updates.
# Paths are relative to the scan directory.
.test/
fixtures with spaces/
.github/workflows/example-*.yml
!.github/workflows/example-maintained.yml
Patterns are Bash globs, not full .gitignore syntax: *, ?, and character classes are supported, * can span /, a trailing / matches all descendants, and a leading / or ./ is optional. Blank lines and lines beginning with # are ignored. ! re-includes a matching path; the last matching rule wins. .gitignore does not control scanning.
Findings in .github/workflows/build.yml:
❗ actions/checkout is outdated:
Line: 52
Current: 2
Latest: 4
🤖compatibility: 79%
Release Notes: https://github.com/actions/checkout/releases/tag/v4
Use -o json, -o md, or -o yaml to print only findings in a machine-readable or report-friendly format. Structured output is grouped under the name of the scanned repository and prints nothing when there are no findings.
SHA metadata is included in JSON, YAML, and Markdown: current_tag, latest_sha, commits_since, and the exact proposed update_ref. Unavailable SHA metadata is null in JSON/YAML.
Actions from GitHub Marketplace verified creators are marked with ☑️ in human and Markdown output. JSON and YAML output keep the action name unchanged and include a verified_creator boolean.
Use -t with -u or -p to update only actions from verified creators. This gate is stricter than -f; forced updates still skip unverified creators when -t is set.
Markdown output links the repository heading to the origin remote when one is configured.
AI analysis is opt-in and only runs during -u or -p when an action's compatibility score is below the configured threshold. The model receives redacted workflow context and both action definitions. Release notes, changelogs, compare commits, and a bounded upstream issue search provide additional evidence when available. Scores below 80 still require AI approval or -f; lowering the AI threshold does not permit automatic updates between that threshold and 80. Unknown or invalid compatibility scores also require AI approval or -f, so a missing score never authorizes an update by itself. The model must return a schema-validated allow, review, or block decision.
For composite actions, evidence also includes up to four files per version that run steps reference through github.action_path. Each file is limited to 12,000 characters, and evidence marks missing files, truncation, and omitted files. actions-snitch reads this source without executing it.
An allow decision may include narrowly scoped remediation for the affected action step's with: inputs. Before making any change, actions-snitch verifies the workflow file, exact action line and full action path, current action version, input name, and current scalar value. Sensitive inputs, arbitrary YAML patches, permissions, triggers, environment variables, shell commands, and changes outside the affected action step are rejected. All proposed input changes are validated and applied to temporary copies first, so an invalid proposal cannot partially modify the repository. Missing local usage evidence or either action definition, backend errors, and invalid responses fail closed; -f remains the explicit version-update override and never applies an unvalidated remediation.
Forced updates with -f bypass AI assessment, send no workflow evidence to an AI provider, and require neither a provider CLI nor a model. They update action references without applying AI remediation.
Run the interactive setup:
actions-snitch -cIt asks whether to enable AI, which detected provider and model to use, the provider effort level when discoverable, the compatibility threshold, and the upstream issue search policy. The provider prompt lists only supported executables found on PATH. Codex supplies its visible model IDs through codex debug models, and its selected model's supported_reasoning_levels populate the effort picker. Cursor, OpenCode, and Antigravity also expose non-interactive model lists. Claude and Copilot offer their documented effort levels. Antigravity model IDs encode the effort, so setup skips its effort picker and saves no separate effort override. Providers without a model catalog use manual model entry. AI stays disabled by default.
When Codex returns a catalog, update mode checks the configured model and effort against that catalog before collecting workflow evidence. Invalid IDs produce a configuration error. If the catalog is unavailable, Codex uses its provider-default effort; an explicit effort requires a readable catalog. Assessment results also print their summary, including a failure reason when the provider could not complete the investigation.
Setup creates ~/.config/actions-snitch/config.yaml (or $XDG_CONFIG_HOME/actions-snitch/config.yaml) with owner-only permissions. ACTIONS_SNITCH_CONFIG can select a different file. Existing files are never overwritten; edit them directly to change settings. Press Ctrl-C to cancel before writing. Setup only requires jq and yq, and does not scan or modify a repository.
The generated file has this shape:
ai:
enabled: false
provider: codex
model: your-provider-model-id
# Optional when the selected provider and model support it.
# effort: high
threshold: 80
issue_search: autoThe selected CLI uses its existing login session, so the actions-snitch configuration does not store provider credentials. Authenticate with that CLI before enabling AI. For example:
codex login
ACTIONS_SNITCH_AI=true actions-snitch -uEnvironment variables override the corresponding defaults:
ACTIONS_SNITCH_AI=true|falseACTIONS_SNITCH_AI_PROVIDER=codex|claude|cursor|gemini|opencode|copilot|antigravityACTIONS_SNITCH_AI_MODEL=model-idACTIONS_SNITCH_AI_EFFORT=provider-supported-levelACTIONS_SNITCH_AI_THRESHOLD=0..100ACTIONS_SNITCH_CONFIG=/path/to/config.yaml
Each assessment runs non-interactively in a temporary directory. Codex, Claude, and Antigravity receive the actions-snitch JSON schema directly. Cursor, Gemini, OpenCode, and Copilot return machine-readable envelopes, from which actions-snitch extracts and validates the final JSON response against the same schema. Every backend error, missing response, parse failure, or schema violation fails closed. The request sends redacted workflow evidence to the selected provider through its authenticated CLI session.
Codex, Claude, Gemini, OpenCode, Copilot, and Antigravity receive the complete assessment prompt through stdin. The Cursor adapter requires a command argument, so prompts above 32 KiB require manual review without invoking the CLI. This limit counts bytes and preserves the complete workflow evidence.
The integration suite uses stored model catalogs and promci fixtures with mocked CLI and GitHub responses. You can also test an authenticated model against the promci fixture in a temporary repository:
bash .github/scripts/test-live-ai codex gpt-6.1-solThis live test uses the selected provider's credentials and may consume model usage. It checks an actual AI-approved update without -f and removes its temporary repository when it exits.
With -p, actions-snitch pushes to origin and opens the PR in the repository selected by origin's push URL, targeting that repository's default branch. When origin pushes to your fork, the PR stays in your fork instead of GitHub CLI's inferred upstream repository. The destination is checked before any branch or workflow changes.
PRs created with -p use a Dependabot-inspired body: a summary of the GitHub Actions updates, one section per unique action/version update, links to the action repositories, collapsible release notes/changelog/commit details, Dependabot compatibility badges, and a small actions-snitch footer. Repeated references to the same action update are collapsed into one section with a workflow-entry count. AI-approved updates also include the model's validated compatibility investigation; successfully applied input remediations are listed in that same collapsible section.
- Scans
.ymland.yamlfiles in.github/workflows/, plusaction.ymlandaction.yamlcomposite actions - For each GitHub Action found:
- Records the exact line number where it's used
- Checks the current version against the latest release
- Fetches compatibility score from dependabot
- Shows detailed information for outdated actions
- Optionally updates workflow and composite-action files in-place
- Optionally commits the updates, pushes them, and creates a PR
- Skips internal/private actions and docker references
The tool caches API responses in ~/.cache/actions-snitch/ (or $XDG_CACHE_HOME/actions-snitch/) to:
- Reduce API calls to GitHub
- Speed up subsequent runs
- Avoid rate limiting
Cache entries expire after 24 hours.
Contributions are welcome! Please feel free to submit a Pull Request.