Stacktower Dependency Diff Action
June 25, 2026 · View on GitHub
Codecov for dependencies — Visualize dependency changes on every pull request with before/after tower diffs.
Most dependency updates are merged blind. You see a lockfile diff with 200 changed lines and hope nothing breaks. This Action makes dependency changes reviewable: it renders before/after tower visualizations, surfaces new vulnerabilities and license issues, and gives your team confidence to merge.
What It Does
On every PR that touches a dependency file:
- Detects which manifests changed (auto-detection or explicit path)
- Renders before and after dependency towers via the Stacktower Cloud API
- Computes a structured diff: added, removed, updated packages + vulnerability changes
- Posts a PR comment with health comparison, package changes, and side-by-side tower images
- Optionally fails the check on new vulnerabilities, license issues, or brittle dependencies
When multiple manifests change in the same PR (for example, package-lock.json and go.mod), the action processes each manifest and posts/updates a dedicated comment per manifest path.
Why
- Catch supply-chain risks before merge — new vulns, copyleft licenses, abandoned packages
- Replace unreadable lockfile diffs — see +3 added / -1 removed / 2 updated at a glance
- 5-minute setup, zero maintenance — auto-detects manifests across 7 languages
- Works with branch protection — fail gates integrate directly with required status checks
Usage
# .github/workflows/dependency-diff.yml
name: Dependency Diff
on:
pull_request:
paths:
- 'package.json'
- 'package-lock.json'
- 'yarn.lock'
- 'pnpm-lock.yaml'
- 'poetry.lock'
- 'pyproject.toml'
- 'uv.lock'
- 'requirements.txt'
- 'Cargo.toml'
- 'Cargo.lock'
- 'go.mod'
- 'Gemfile'
- 'Gemfile.lock'
- 'composer.json'
- 'composer.lock'
- 'pom.xml'
- 'build.gradle'
- 'build.gradle.kts'
jobs:
tower-diff:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: stacktower-io/stacktower-action@v1
with:
api-key: ${{ secrets.STACKTOWER_API_KEY }}
fail-on-vuln: true
Setup
Free to use with any Stacktower account — API keys, CI dependency diffs, before/after towers, PR comments, and fail gates are available on the free tier. Triage AI investigations (
investigate: true) require a Pro plan. Your key needsvisualizations:writeandvisualizations:readscopes. Addinvestigations:writeandinvestigations:readif usinginvestigate: true.
- Sign up at app.stacktower.io (free account, no credit card)
- Create an API key at Settings > API Keys
- Add the key as a repository secret named
STACKTOWER_API_KEY
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
api-key | Stacktower Cloud API key | Yes | — |
manifest | Path to manifest file (auto-detected if omitted) | No | — |
fail-on-vuln | Fail the check if new vulnerabilities are introduced | No | false |
fail-on-license | Fail the check if copyleft, proprietary, or unknown licenses are detected | No | false |
fail-on-brittle | Fail the check if brittle (archived/abandoned/undermaintained) deps are detected | No | false |
security-scan | Run vulnerability scan on dependencies | No | true |
investigate | Run Triage AI agent for health grade + recommendations (requires Pro) | No | false |
comment | Post a PR comment with the diff | No | true |
token | GitHub token for PR comments and investigation repo access | No | ${{ github.token }} |
api-base-url | Stacktower API base URL (override for testing/self-hosted) | No | https://api.stacktower.io/v1 |
app-base-url | Stacktower app base URL (used for links in PR comments) | No | https://app.stacktower.io |
Outputs
| Output | Description |
|---|---|
has-changes | Whether dependency changes were detected |
diff-json | JSON diff result |
new-vulns | Number of new vulnerabilities introduced |
license-issues | Number of license issues (copyleft + proprietary + unknown) |
brittle-deps | Number of brittle dependencies (archived/abandoned/undermaintained) |
before-render-id | Render ID for the before tower |
after-render-id | Render ID for the after tower |
before-url | URL to the before tower on app.stacktower.io |
after-url | URL to the after tower on app.stacktower.io |
health-grade | Dependency health grade (A-F) from the Triage AI investigation |
investigation-json | Full Triage AI investigation report as JSON |
Supported Languages
| Language | Manifests |
|---|---|
| JavaScript | package.json, package-lock.json, yarn.lock, pnpm-lock.yaml |
| Python | pyproject.toml, poetry.lock, uv.lock, requirements.txt |
| Rust | Cargo.toml, Cargo.lock |
| Go | go.mod |
| Ruby | Gemfile, Gemfile.lock |
| PHP | composer.json, composer.lock |
| Java | pom.xml, build.gradle, build.gradle.kts |
When both a lockfile and manifest change for the same language, the lockfile is preferred (it has fully resolved versions).
PR Comment
The action posts a comment with:
- Summary bar — counts of added, removed, updated, and unchanged dependencies
- Health comparison — before/after stats table (total deps, direct, transitive, max depth, vulnerabilities, licenses)
- Package changes — detailed lists of added, removed, and updated packages with version info
- New vulnerabilities — highlighted with severity badges
- License issues (when
fail-on-licenseis set) — copyleft, proprietary, and unknown licenses - Brittle dependencies (when
fail-on-brittleis set) — archived, abandoned, or undermaintained packages - Tower visualizations — side-by-side before/after tower images linking to the interactive viewer
- Investigation report (optional) — Triage AI health grade (A-F) and prioritized recommendations
Each manifest comment is automatically updated on subsequent pushes (no duplicate comments for the same manifest path).
Multi-language PR example
If a PR updates both JavaScript and Go dependencies:
frontend/package-lock.jsonbackend/go.mod
the action will post two Stacktower comments (one per manifest path), and each one is updated independently on later pushes.
Monorepo note: Auto-detection picks one manifest per language (the highest-priority lockfile). If your repo has multiple
package.jsonor lockfiles for the same language in different directories, use themanifestinput to target a specific file, or run the action multiple times with differentmanifestvalues via a matrix strategy.
Fail Gates
The action supports three fail gates that integrate with branch protection rules, letting you require clean dependency updates before merge. When multiple gates are enabled and triggered, all failures are reported together.
Fail on Vulnerabilities
Set fail-on-vuln: true to fail the check when new vulnerabilities are introduced in the PR diff.
Fail on License Issues
Set fail-on-license: true to fail the check when the after-PR dependency tree contains copyleft, proprietary, or unknown licenses.
Fail on Brittle Dependencies
Set fail-on-brittle: true to fail the check when the after-PR dependency tree contains archived, abandoned, or undermaintained packages.
- uses: stacktower-io/stacktower-action@v1
with:
api-key: ${{ secrets.STACKTOWER_API_KEY }}
fail-on-vuln: true
fail-on-license: true
fail-on-brittle: true
Triage AI Investigation
Set investigate: true to get an AI-powered dependency health grade directly in your PR comment. The Triage AI agent goes beyond static analysis — it clones your repository, understands how you use each dependency, and produces:
- Health grade (A-F) — an at-a-glance signal for reviewers
- Prioritized recommendations — Do Now / Should Do / Nice to Have
- Context-aware advice — knows whether a vulnerable package is in your hot path or an unused transitive dep
Note: Triage AI investigations require a Pro plan. The token input must have read access to the repository.
- uses: stacktower-io/stacktower-action@v1
with:
api-key: ${{ secrets.STACKTOWER_API_KEY }}
investigate: true
fail-on-vuln: true
The health grade is also available as an output:
- uses: stacktower-io/stacktower-action@v1
id: deps
with:
api-key: ${{ secrets.STACKTOWER_API_KEY }}
investigate: true
- run: echo "Health grade: ${{ steps.deps.outputs.health-grade }}"
More from Stacktower
- Web App — Interactive tower viewer, dependency history, team dashboards
- CLI — Open-source CLI for local parsing, rendering, and analysis
- Blog — The story behind tower visualizations and XKCD 2347
Development
Prerequisites
- Node.js >= 20
- act for local Docker-based testing (
brew install act)
Build & Test
make help # show all targets
make all # lint + unit tests + build (same as CI)
make build # compile & bundle with ncc
make test # run unit tests (vitest)
make lint # type-check
Local Integration Test (Docker)
Run the full action in a Docker container using act, no push required.
1. Create a secrets file:
cp test/.secrets.example test/.secrets
# Edit test/.secrets with your real STACKTOWER_API_KEY and GITHUB_TOKEN
2. Run against the default API:
make test-act
3. Point to a custom API (e.g. local dev server):
make test-act API_URL=http://localhost:8080/v1 APP_URL=http://localhost:3000
The test workflow (.github/workflows/test-local.yml) exercises the action in-repo using uses: ./ with comment: false (so it won't try to post to a real PR). It prints all outputs to stdout for verification.
Note:
test/.secretsis git-ignored. Never commit real API keys.
License
MIT