Skip to content

Commit aaef6dd

Browse files
committed
Add CI workflow to check for unapproved npm dependency licenses
A task and GitHub Actions workflow are provided here for checking the license types of npm-managed project dependencies. On every push and pull request that affects relevant files, the CI workflow will check: - If the dependency licenses cache is up to date - If any of the project's dependencies have an unapproved license type. Approval can be based on: - Universally allowed license type - Individual dependency
1 parent 148baf5 commit aaef6dd

File tree

6 files changed

+283
-2
lines changed

6 files changed

+283
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-npm-dependencies-task.md
2+
name: Check npm Dependencies
3+
4+
env:
5+
# See: https://github.com/actions/setup-node/#readme
6+
NODE_VERSION: 16.x
7+
8+
# See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
9+
on:
10+
create:
11+
push:
12+
paths:
13+
- ".github/workflows/check-npm-dependencies-task.ya?ml"
14+
- ".licenses/**"
15+
- ".licensed.json"
16+
- ".licensed.ya?ml"
17+
- "Taskfile.ya?ml"
18+
- "**/.gitmodules"
19+
- "**/package.json"
20+
- "**/package-lock.json"
21+
pull_request:
22+
paths:
23+
- ".github/workflows/check-npm-dependencies-task.ya?ml"
24+
- ".licenses/**"
25+
- ".licensed.json"
26+
- ".licensed.ya?ml"
27+
- "Taskfile.ya?ml"
28+
- "**/.gitmodules"
29+
- "**/package.json"
30+
- "**/package-lock.json"
31+
schedule:
32+
# Run periodically to catch breakage caused by external changes.
33+
- cron: "0 8 * * WED"
34+
workflow_dispatch:
35+
repository_dispatch:
36+
37+
jobs:
38+
run-determination:
39+
runs-on: ubuntu-latest
40+
outputs:
41+
result: ${{ steps.determination.outputs.result }}
42+
steps:
43+
- name: Determine if the rest of the workflow should run
44+
id: determination
45+
run: |
46+
RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x"
47+
# The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead.
48+
if [[
49+
"${{ github.event_name }}" != "create" ||
50+
"${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX
51+
]]; then
52+
# Run the other jobs.
53+
RESULT="true"
54+
else
55+
# There is no need to run the other jobs.
56+
RESULT="false"
57+
fi
58+
59+
echo "::set-output name=result::$RESULT"
60+
61+
check-cache:
62+
needs: run-determination
63+
if: needs.run-determination.outputs.result == 'true'
64+
runs-on: ubuntu-latest
65+
66+
steps:
67+
- name: Checkout repository
68+
uses: actions/checkout@v3
69+
with:
70+
submodules: recursive
71+
72+
- name: Install licensed
73+
uses: jonabc/setup-licensed@v1
74+
with:
75+
github_token: ${{ secrets.GITHUB_TOKEN }}
76+
version: 3.x
77+
78+
- name: Setup Node.js
79+
uses: actions/setup-node@v3
80+
with:
81+
node-version: ${{ env.NODE_VERSION }}
82+
83+
- name: Install Task
84+
uses: arduino/setup-task@v1
85+
with:
86+
repo-token: ${{ secrets.GITHUB_TOKEN }}
87+
version: 3.x
88+
89+
- name: Update dependencies license metadata cache
90+
run: task --silent general:cache-dep-licenses
91+
92+
- name: Check for outdated cache
93+
id: diff
94+
run: |
95+
git add .
96+
if ! git diff --cached --color --exit-code; then
97+
echo
98+
echo "::error::Dependency license metadata out of sync. See: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-dependencies-task.md#metadata-cache"
99+
exit 1
100+
fi
101+
102+
# Some might find it convenient to have CI generate the cache rather than setting up for it locally
103+
- name: Upload cache to workflow artifact
104+
if: failure() && steps.diff.outcome == 'failure'
105+
uses: actions/upload-artifact@v3
106+
with:
107+
if-no-files-found: error
108+
name: dep-licenses-cache
109+
path: .licenses/
110+
111+
check-deps:
112+
needs: run-determination
113+
if: needs.run-determination.outputs.result == 'true'
114+
runs-on: ubuntu-latest
115+
116+
steps:
117+
- name: Checkout repository
118+
uses: actions/checkout@v3
119+
with:
120+
submodules: recursive
121+
122+
- name: Install licensed
123+
uses: jonabc/setup-licensed@v1
124+
with:
125+
github_token: ${{ secrets.GITHUB_TOKEN }}
126+
version: 3.x
127+
128+
- name: Setup Node.js
129+
uses: actions/setup-node@v3
130+
with:
131+
node-version: ${{ env.NODE_VERSION }}
132+
133+
- name: Install Task
134+
uses: arduino/setup-task@v1
135+
with:
136+
repo-token: ${{ secrets.GITHUB_TOKEN }}
137+
version: 3.x
138+
139+
- name: Check for dependencies with unapproved licenses
140+
run: task --silent general:check-dep-licenses

.licensed.yml

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# See: https://github.com/github/licensed/blob/master/docs/configuration.md
2+
sources:
3+
npm: true
4+
5+
shared_cache: true
6+
cache_path: .licenses/
7+
8+
apps:
9+
- source_path: ./
10+
11+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies/GPL-3.0/.licensed.yml
12+
allowed:
13+
# The following are based on: https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses
14+
- gpl-1.0-or-later
15+
- gpl-1.0+ # Deprecated ID for `gpl-1.0-or-later`
16+
- gpl-2.0-or-later
17+
- gpl-2.0+ # Deprecated ID for `gpl-2.0-or-later`
18+
- gpl-3.0-only
19+
- gpl-3.0 # Deprecated ID for `gpl-3.0-only`
20+
- gpl-3.0-or-later
21+
- gpl-3.0+ # Deprecated ID for `gpl-3.0-or-later`
22+
- lgpl-2.0-or-later
23+
- lgpl-2.0+ # Deprecated ID for `lgpl-2.0-or-later`
24+
- lgpl-2.1-only
25+
- lgpl-2.1 # Deprecated ID for `lgpl-2.1-only`
26+
- lgpl-2.1-or-later
27+
- lgpl-2.1+ # Deprecated ID for `lgpl-2.1-or-later`
28+
- lgpl-3.0-only
29+
- lgpl-3.0 # Deprecated ID for `lgpl-3.0-only`
30+
- lgpl-3.0-or-later
31+
- lgpl-3.0+ # Deprecated ID for `lgpl-3.0-or-later`
32+
- fsfap
33+
- apache-2.0
34+
- artistic-2.0
35+
- clartistic
36+
- sleepycat
37+
- bsl-1.0
38+
- bsd-3-clause
39+
- cecill-2.0
40+
- bsd-3-clause-clear
41+
# "Cryptix General License" - no SPDX ID (https://github.com/spdx/license-list-XML/issues/456)
42+
- ecos-2.0
43+
- ecl-2.0
44+
- efl-2.0
45+
- eudatagrid
46+
- mit
47+
- bsd-2-clause # Subsumed by `bsd-2-clause-views`
48+
- bsd-2-clause-netbsd # Deprecated ID for `bsd-2-clause`
49+
- bsd-2-clause-views # This is the version linked from https://www.gnu.org/licenses/license-list.html#FreeBSD
50+
- bsd-2-clause-freebsd # Deprecated ID for `bsd-2-clause-views`
51+
- ftl
52+
- hpnd
53+
- imatix
54+
- imlib2
55+
- ijg
56+
# "Informal license" - this is a general class of license
57+
- intel
58+
- isc
59+
- mpl-2.0
60+
- ncsa
61+
# "License of Netscape JavaScript" - no SPDX ID
62+
- oldap-2.7
63+
# "License of Perl 5 and below" - possibly `Artistic-1.0-Perl` ?
64+
- cc0-1.0
65+
- cc-pddc
66+
- psf-2.0
67+
- ruby
68+
- sgi-b-2.0
69+
- smlnj
70+
- standardml-nj # Deprecated ID for `smlnj`
71+
- unicode-dfs-2015
72+
- upl-1.0
73+
- unlicense
74+
- vim
75+
- w3c
76+
- wtfpl
77+
- lgpl-2.0-or-later with wxwindows-exception-3.1
78+
- wxwindows # Deprecated ID for `lgpl-2.0-or-later with wxwindows-exception-3.1`
79+
- x11
80+
- xfree86-1.1
81+
- zlib
82+
- zpl-2.0
83+
- zpl-2.1
84+
# The following are based on individual license text
85+
- eupl-1.2
86+
- liliq-r-1.1
87+
- liliq-rplus-1.1

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/.licenses/
12
/dist/
23
/lib/
34
/node_modules/

CONTRIBUTING.md

+14
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ Everything is now ready to make your contribution to the project, so commit it t
6161

6262
Thanks!
6363

64+
## Dependency license metadata
65+
66+
Metadata about the license types of all dependencies is cached in the repository. To update this cache, run the following command from the repository root folder:
67+
68+
```
69+
task general:cache-dep-licenses
70+
```
71+
72+
The necessary **Licensed** tool can be installed by following [these instructions](https://github.com/github/licensed#as-an-executable).
73+
74+
Unfortunately, **Licensed** does not have support for being used on the **Windows** operating system.
75+
76+
An updated cache is also generated whenever the cache is found to be outdated by the by the "Check Go Dependencies" CI workflow and made available for download via the `dep-licenses-cache` [workflow artifact](https://docs.github.com/actions/managing-workflow-runs/downloading-workflow-artifacts).
77+
6478
## Enable verbose logging for a pipeline
6579

6680
Additional log events with the prefix ::debug:: can be enabled by setting the secret `ACTIONS_STEP_DEBUG` to `true`.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
[![Check Markdown status](https://github.com/arduino/setup-task/actions/workflows/check-markdown-task.yml/badge.svg)](https://github.com/arduino/setup-task/actions/workflows/check-markdown-task.yml)
1111
[![Spell Check status](https://github.com/arduino/setup-task/actions/workflows/spell-check-task.yml/badge.svg)](https://github.com/arduino/setup-task/actions/workflows/spell-check-task.yml)
1212
[![Check License status](https://github.com/arduino/setup-task/actions/workflows/check-license.yml/badge.svg)](https://github.com/arduino/setup-task/actions/workflows/check-license.yml)
13+
[![Check npm Dependencies status](https://github.com/arduino/setup-task/actions/workflows/check-npm-dependencies-task.yml/badge.svg)](https://github.com/arduino/setup-task/actions/workflows/check-npm-dependencies-task.yml)
1314

1415
A [GitHub Actions](https://docs.github.com/en/actions) action that makes the [Task](https://taskfile.dev/#/) task runner / build tool available to use in your workflow.
1516

Taskfile.yml

+40-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,32 @@ tasks:
3939
# This is an "umbrella" task used to call any documentation generation processes the project has.
4040
# It can be left empty if there are none.
4141

42+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml
43+
general:cache-dep-licenses:
44+
desc: Cache dependency license metadata
45+
deps:
46+
- task: general:install-deps
47+
cmds:
48+
- |
49+
if ! which licensed &>/dev/null; then
50+
if [[ {{OS}} == "windows" ]]; then
51+
echo "Licensed does not have Windows support."
52+
echo "Please use Linux/macOS or download the dependencies cache from the GitHub Actions workflow artifact."
53+
else
54+
echo "licensed not found or not in PATH. Please install: https://github.com/github/licensed#as-an-executable"
55+
fi
56+
exit 1
57+
fi
58+
- licensed cache
59+
60+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml
61+
general:check-dep-licenses:
62+
desc: Check for unapproved dependency licenses
63+
deps:
64+
- task: general:cache-dep-licenses
65+
cmds:
66+
- licensed status
67+
4268
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check-task/Taskfile.yml
4369
general:check-spelling:
4470
desc: Check for commonly misspelled words
@@ -61,6 +87,12 @@ tasks:
6187
cmds:
6288
- npx prettier --write .
6389

90+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-npm-dependencies-task/Taskfile.yml
91+
general:install-deps:
92+
desc: Install project dependencies
93+
deps:
94+
- task: npm:install-deps
95+
6496
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-markdown-task/Taskfile.yml
6597
markdown:check-links:
6698
desc: Check for broken links
@@ -118,6 +150,12 @@ tasks:
118150
cmds:
119151
- npx markdownlint-cli "**/*.md"
120152

153+
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/npm-task/Taskfile.yml
154+
npm:install-deps:
155+
desc: Install dependencies managed by npm
156+
cmds:
157+
- npm install
158+
121159
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml
122160
poetry:install-deps:
123161
desc: Install dependencies managed by Poetry
@@ -141,8 +179,8 @@ tasks:
141179

142180
ts:install-deps:
143181
desc: Install TypeScript dependencies
144-
cmds:
145-
- npm install
182+
deps:
183+
- task: npm:install-deps
146184

147185
ts:lint:
148186
desc: Lint TypeScript code

0 commit comments

Comments
 (0)