Skip to content

stacktower-io/stacktower-action

Repository files navigation

Stacktower Dependency Diff Action

Dependencies

Codecov for dependencies — Visualize dependency changes on every pull request with before/after tower diffs.

Dependency Tower

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:

  1. Detects which manifests changed (auto-detection or explicit path)
  2. Renders before and after dependency towers via the Stacktower Cloud API
  3. Computes a structured diff: added, removed, updated packages + vulnerability changes
  4. Posts a PR comment with health comparison, package changes, and side-by-side tower images
  5. 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 needs visualizations:write and visualizations:read scopes. Add investigations:write and investigations:read if using investigate: true.

  1. Sign up at app.stacktower.io (free account, no credit card)
  2. Create an API key at Settings > API Keys
  3. 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-license is set) — copyleft, proprietary, and unknown licenses
  • Brittle dependencies (when fail-on-brittle is 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.json
  • backend/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.json or lockfiles for the same language in different directories, use the manifest input to target a specific file, or run the action multiple times with different manifest values 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/.secrets is git-ignored. Never commit real API keys.

License

MIT

About

Codecov for dependencies — Visualize dependency changes on every pull request with before/after tower diffs, vulnerability scanning, and health grading. GitHub Action for the Stacktower API.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors