From f30950615f2ee73d4520ca9e204a6f2205efdb96 Mon Sep 17 00:00:00 2001 From: Uno-Takashi Date: Mon, 22 Jun 2026 23:24:27 +0000 Subject: [PATCH 1/2] ci: externalize license allow-list to license-whitelist-python.txt Move the inline pip-licenses --allow-only list out of the workflow into license-whitelist-python.txt (one license per line, # comments ignored). The workflow now builds the allow-list from that file, matching the Node submodules' license-whitelist-node.txt convention. Behaviour is unchanged: same entries, still --with-system --partial-match. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/license-check.yml | 35 +++-------------- license-whitelist-python.txt | 60 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 license-whitelist-python.txt diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml index 635f9ba..c981fde 100644 --- a/.github/workflows/license-check.yml +++ b/.github/workflows/license-check.yml @@ -14,36 +14,13 @@ jobs: - name: install dependencies run: uv sync --frozen - name: check licenses - # --partial-match: many modern packages report SPDX expressions such as - # "Apache-2.0 OR BSD-3-Clause" or "BSD-3-Clause AND 0BSD AND MIT ...". - # Exact matching rejects those even when every component is permissive, - # so match an allowed license as a substring of the reported string. + # Allow-list lives in license-whitelist-python.txt (one license per line, + # # comments / blank lines ignored). --partial-match: many modern packages + # report SPDX expressions such as "Apache-2.0 OR BSD-3-Clause" or + # "BSD-3-Clause AND 0BSD AND MIT ...". Exact matching rejects those even when + # every component is permissive, so match an allowed license as a substring. run: > uv run pip-licenses --with-system --partial-match - --allow-only=" - Apache Software License; - Apache-2.0; - BSD License;BSD; - BSD-3-Clause;BSD-2-Clause;0BSD; - Zlib;CC0-1.0; - Freeware; - GNU General Public License (GPL); - GNU Lesser General Public License v3 or later (LGPLv3+); - LGPL-3.0-only;LGPL-3.0-or-later; - MIT License; - MIT; - Mozilla Public License 2.0 (MPL 2.0); - MPL-2.0; - Python Software Foundation License; - PSF-2.0;Python-2.0; - Public Domain; - UNKNOWN; - The Unlicense (Unlicense); - Unlicense; - Zope Public License; - ZPL; - ISC License (ISCL); - ISC; - " + --allow-only="$(grep -v '^[[:space:]]*#' license-whitelist-python.txt | grep -v '^[[:space:]]*$' | paste -sd ';')" diff --git a/license-whitelist-python.txt b/license-whitelist-python.txt new file mode 100644 index 0000000..a504f12 --- /dev/null +++ b/license-whitelist-python.txt @@ -0,0 +1,60 @@ +# License whitelist for backend (Python) dependencies. +# One license name per line. Blank lines and lines starting with # are ignored. +# Consumed by the License Check CI workflow (uv run pip-licenses --allow-only=...). +# +# pip-licenses runs with --partial-match, so each entry is matched as a substring +# of the reported license string. This covers SPDX expressions such as +# "Apache-2.0 OR BSD-3-Clause" where every component is permissive. +# Both the classifier-style names ("MIT License") and SPDX ids ("MIT") are listed +# because packages report licenses in either form. +# +# Policy: never add AGPL / SSPL here. + +# Apache +Apache Software License +Apache-2.0 + +# BSD +BSD License +BSD +BSD-3-Clause +BSD-2-Clause +0BSD + +# Misc permissive +Zlib +CC0-1.0 +Freeware + +# (L)GPL +GNU General Public License (GPL) +GNU Lesser General Public License v3 or later (LGPLv3+) +LGPL-3.0-only +LGPL-3.0-or-later + +# MIT +MIT License +MIT + +# MPL +Mozilla Public License 2.0 (MPL 2.0) +MPL-2.0 + +# Python / PSF +Python Software Foundation License +PSF-2.0 +Python-2.0 + +# Public domain / unlicense +Public Domain +UNKNOWN +The Unlicense (Unlicense) +Unlicense + +# Zope +Zope Public License +ZPL + +# ISC +ISC License (ISCL) +ISC From 5417ee1f2195a563dc17b74881057afb21d1e159 Mon Sep 17 00:00:00 2001 From: Uno-Takashi Date: Mon, 22 Jun 2026 23:36:14 +0000 Subject: [PATCH 2/2] ci: disallow GPL (keep LGPL) in Python license whitelist Remove the "GNU General Public License (GPL)" entry so strong-copyleft GPL (and AGPL) dependencies fail the license check. LGPL stays allowed: used as a library it imposes no source-disclosure obligation on the application. Verified: current tree (LGPL psycopg) still passes; GPL/AGPL packages are rejected under pip-licenses --partial-match. Co-Authored-By: Claude Opus 4.8 --- license-whitelist-python.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/license-whitelist-python.txt b/license-whitelist-python.txt index a504f12..6f26c0b 100644 --- a/license-whitelist-python.txt +++ b/license-whitelist-python.txt @@ -8,7 +8,11 @@ # Both the classifier-style names ("MIT License") and SPDX ids ("MIT") are listed # because packages report licenses in either form. # -# Policy: never add AGPL / SSPL here. +# Policy: permissive + LGPL (weak copyleft) only. +# Never add GPL / AGPL / SSPL here — strong copyleft would force disclosure of +# our application source. Replace such a dependency with a permissive/LGPL +# alternative instead. LGPL is allowed because, used as a library, it does not +# impose source-disclosure obligations on the application. # Apache Apache Software License @@ -26,8 +30,7 @@ Zlib CC0-1.0 Freeware -# (L)GPL -GNU General Public License (GPL) +# LGPL (weak copyleft only — GPL/AGPL deliberately excluded) GNU Lesser General Public License v3 or later (LGPLv3+) LGPL-3.0-only LGPL-3.0-or-later