Metadata-Version: 2.5
Name: depdelta-cli
Version: 0.2.0
Summary: DepDelta for CI: review a change's dependency updates on Gerrit or GitLab.
Project-URL: Homepage, https://depdelta.com
Project-URL: Documentation, https://depdelta.com/ci
Project-URL: Source, https://github.com/mbobiosio/depdelta-cli
Project-URL: Issues, https://github.com/mbobiosio/depdelta-cli/issues
Author: Mbuodile Obiosio
License-Expression: MIT
License-File: LICENSE
Keywords: breaking-changes,ci,dependencies,gerrit,gitlab,renovate
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# depdelta-cli

[![PyPI](https://img.shields.io/pypi/v/depdelta-cli)](https://pypi.org/project/depdelta-cli/)
[![CI](https://github.com/mbobiosio/depdelta-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/mbobiosio/depdelta-cli/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)

Know what a dependency update breaks before you merge, on Gerrit and GitLab.

[DepDelta](https://depdelta.com) reads every release's notes, security
advisories and published API between two versions of a package, and says
what changed and what will break: see
[eslint 8.57.0 → 9.0.0](https://depdelta.com/npm/eslint/compare/8.57.0...9.0.0)
for an example. `depdelta` brings that review to your CI. On every change that
updates a dependency (from Renovate or anyone) it posts the breaking changes,
security fixes, removed APIs and where your code uses them, right on the
change.

On GitHub, the [DepDelta GitHub app](https://depdelta.com/github-app) does
this with no CI job. Setup guide, example review and FAQ:
**[depdelta.com/ci](https://depdelta.com/ci)**.

## How it works

On every change that touches a manifest or lockfile, `depdelta`:

1. sends the changed manifests and lockfiles (both ends) to DepDelta. Source
   code is never sent;
2. gets back each update's verdict and, for npm and Maven, the declarations
   it removes or changes;
3. looks for those declarations in the checkout, and sends only the hits
   (path, line, symbol);
4. posts the review: a Gerrit change message (no vote), or one GitLab merge
   request note that later pipelines edit in place. Each update links to its
   full comparison on depdelta.com.

Beyond each update, the review says what the change does to your lockfiles:
packages before and after, new and removed direct dependencies (dev or
production, and what each pulls in), and packages that newly run code at
install time (an npm install script, a Python package built from source, a
Composer plugin, a Cargo build script).

Nine ecosystems: npm, PyPI, Maven, Composer, Cargo, RubyGems, pub.dev,
NuGet and Go. For Android and other Gradle builds that means
`build.gradle(.kts)`, `settings.gradle(.kts)`, version catalogs
(`gradle/libs.versions.toml`, libraries and plugins) and
`gradle.lockfile`; plugins count as updates too (AGP, Kotlin, KSP, Hilt).
Needs Python 3.11+ and git, nothing else.

```
docker pull ghcr.io/mbobiosio/depdelta-cli:latest
# or
pip install depdelta-cli
```

## API key

Sign in at [depdelta.com](https://depdelta.com) with GitHub or Google,
make a key in [Settings → API keys for CI](https://depdelta.com/settings),
and store it in your CI's secrets as `DEPDELTA_API_KEY`. Each key gets 240
reviews an hour, waiting on release notes included.

## Jenkins with Gerrit Trigger

The job runs on `patchset-created`. Gerrit Trigger sets `GERRIT_PROJECT`,
`GERRIT_CHANGE_NUMBER`, `GERRIT_PATCHSET_REVISION` and `GERRIT_CHANGE_URL`.
The review is posted with a Gerrit account's HTTP password: a service
account works best.

The checkout needs the patch set's parent: don't clone with depth 1 (or let
`depdelta` fetch it; it does when the parent is missing).

```groovy
pipeline {
  agent { docker { image 'ghcr.io/mbobiosio/depdelta-cli:latest' } }
  stages {
    stage('DepDelta') {
      steps {
        withCredentials([
          string(credentialsId: 'depdelta-api-key', variable: 'DEPDELTA_API_KEY'),
          usernamePassword(credentialsId: 'gerrit-http',
                           usernameVariable: 'GERRIT_HTTP_USER',
                           passwordVariable: 'GERRIT_HTTP_PASSWORD'),
        ]) {
          // A DepDelta outage shouldn't fail the build.
          catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
            sh 'depdelta'
          }
        }
      }
    }
  }
}
```

Without Docker: `pip install depdelta-cli` on the agent, then the same
`sh 'depdelta'`.

`DEPDELTA_GERRIT_URL` overrides Gerrit's address when `GERRIT_CHANGE_URL`
isn't the REST root (a proxy, a different host name for agents).

Messages carry the tag `autogenerated:depdelta`, so Gerrit folds older patch
sets' reviews away, and notify only the change owner.

## GitLab CI

Runs in merge request pipelines. `CI_JOB_TOKEN` can't write notes: give the
job a project access token with the `api` scope (Reporter role is enough) as
`GITLAB_TOKEN`.

```yaml
depdelta:
  image: ghcr.io/mbobiosio/depdelta-cli:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      changes:
        - "**/package.json"
        - "**/package-lock.json"
        - "**/pom.xml"
        - "**/requirements*.txt"
        - "**/pyproject.toml"
        - "**/*.lock"
        - "**/go.mod"
  variables:
    GIT_DEPTH: 0
  script:
    - depdelta
  allow_failure: true
```

Uses link to the files at the merge request's head commit.

## Options

```
depdelta [--repo .] [--base REV --head REV] [--print]
         [--format markdown|text] [--wait 300]
         [--fail-on never|breaking|review|unknown|safe]
         [--api-url URL]
```

- `--print` prints the review instead of posting it. With `--base` and
  `--head` (outside CI) it always prints:
  `depdelta --base origin/main --head HEAD`.
- `--wait` is how long to wait for DepDelta to read release notes it hasn't
  seen yet. After that the review posts as it stands, saying what is still
  being read.
- `--fail-on breaking` exits 1 when an update is breaking, to fail the job.

Exit status: 0 posted (or nothing to review), 1 the `--fail-on` verdict was
met or `.depdelta.yml` blocks new install-time code, 2 it couldn't review or
post.

## .depdelta.yml

An optional file at the repository root, read at the change's head commit.
The GitHub app reads the same file.

```yaml
install_scripts: warn        # off | warn (default) | block
allow_install_scripts:       # never flagged
  - esbuild
  - sharp
```

- `warn` flags each package that newly runs code at install.
- `block` flags them too, and `depdelta` exits 1, so the job fails until the
  package is allowed or removed.
- `off` leaves install-time code out of the review.

`depdelta` sends the file as it is; DepDelta reads it. A file it can't read
falls back to the defaults, and the review says why.

## Privacy

Only the changed manifests and lockfiles leave CI, plus, for updates with
removed or changed APIs, the path, line and symbol of each use found. The
source code stays in CI. Gerrit and GitLab credentials are sent only to your
Gerrit or GitLab. The [privacy policy](https://depdelta.com/privacy) has the
details.

## Links

- Website: [depdelta.com](https://depdelta.com)
- CI setup guide: [depdelta.com/ci](https://depdelta.com/ci)
- GitHub app: [depdelta.com/github-app](https://depdelta.com/github-app)
- Check a whole project's dependencies: [depdelta.com/report](https://depdelta.com/report)
- Issues: [github.com/mbobiosio/depdelta-cli/issues](https://github.com/mbobiosio/depdelta-cli/issues)

## Development

```
uv sync
make check format test
```

`src/depdelta_cli/usage.py` is the same usage matcher the DepDelta service
and GitHub app run, and `manifests.py` uses the same manifest names: changes
to either start in the service, then are copied here.

Releases: bump `version` in `pyproject.toml`, then tag `v<version>` and
push the tag. GitHub Actions publishes to PyPI and GHCR.

## License

MIT
