Skip to content

Check dependency licenses in CI - #27

Merged
mmlado merged 1 commit into
mainfrom
ci/dependency-license-check
Oct 9, 2026
Merged

mmlado merged 1 commit into
mainfrom
ci/dependency-license-check

Conversation

@mmlado

@mmlado mmlado commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

What and why

A CI job checks the licenses of every dependency the package installs, so a dependency under terms the project does not accept cannot land unnoticed.

  • Workflow Dependency licenses runs on pushes and pull requests to main. It installs the package into a clean virtual environment with pip install ., so the check sees what the package pulls in and nothing else on the runner, and then runs the check script with that environment's interpreter. Ubuntu, Python 3.12, actions pinned by commit as in ci.yml.
  • .github/scripts/check_licenses.py, standard library only, with an allowlist of accepted licenses. A dependency passes only if every license it declares is allowed: its License-Expression, each License :: classifier and its free-text License field. A dependency that declares none fails. Operators in an expression are not interpreted, so A OR B needs both allowed.
  • Reviewed exceptions are listed in the script together with the licenses they declared at review time; here that is pyscard alone. If a later release declares something else, the check fails again and the review is repeated. Exceptions that match no installed package, or that would pass without the exception, are reported so the list stays short.
  • The check reads package metadata, so it covers what pip installs. A PyInstaller bundle can contain more than that; the bundle is not checked here.

The same check is proposed for cryptnox-cli in cryptnox/cryptnox-cli#62; the script differs only in the project name and the exception list.

How it was tested

  • The script against the installed tree of this package at the current main: 12 distributions, all pass.
  • 39 cases against fake distributions in a temporary directory, in dist-info and egg-info form, each with an expected verdict: a license outside the list as expression, classifier or free text, one that is on the list next to one that is not, OR and WITH expressions, no metadata at all, bare OSI Approved, UNKNOWN, full license text in the field, and an excepted package that starts declaring a different license. All 39 give the expected verdict (run against the cryptnox-cli copy of the script; the checking code is identical).
  • The workflow run locally with act.
  • ruff check and ruff format --check with the repository configuration pass on the script.

Third-party and generated code

No third-party code. Substantial parts of this pull request were produced with Claude Code.

🤖 Generated with Claude Code

Add a workflow that installs the package into a clean environment and
checks every dependency it pulls in against a list of allowed licenses.
A dependency passes only if every license it declares, in its
License-Expression, its classifiers and its License field, is on the
list, so a package that declares two licenses needs both allowed. One
that declares none fails.

Dependencies reviewed by hand are listed as exceptions together with the
licenses they declared at the time of review. When a new release of one
of them declares something else, the check fails again and the review is
repeated. Exceptions that no longer match an installed package, or that
would pass without one, are reported so the list stays short.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mmlado mmlado self-assigned this Oct 9, 2026
@mmlado
mmlado merged commit 5b93c54 into main Oct 9, 2026
13 checks passed
@mmlado
mmlado deleted the ci/dependency-license-check branch October 9, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant