Skip to content

Commit 80d7cf2

Browse files
Merge pull request silverstripe#84 from creative-commoners/pulls/5.3/licenses
MNT Check licenses
2 parents b19f0db + 5927ce4 commit 80d7cf2

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

.github/workflows/licenses.yml

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
name: Licenses
2+
3+
# This workflow will check the licences of any installed composer and NPM dependencies against a list of
4+
# allowed SPDX identifiers of open source licences. These are contained env variable $SPDX_ALLOWED_DELIMITED
5+
# If any installed non-dev dependencies are found that are not in the allowed list then the job will fail.
6+
# See https://spdx.org/licenses/ for a list of SPDX identifiers.
7+
# Note that the `Unlicense` is an SPDX identifier for an actual license and not a placeholder for a missing license.
8+
9+
on:
10+
# At 4 AM UTC, only on Saturday
11+
workflow_dispatch:
12+
schedule:
13+
- cron: '0 4 * * 6'
14+
15+
permissions: {}
16+
17+
jobs:
18+
checklicenses:
19+
name: Check licenses
20+
runs-on: ubuntu-latest
21+
22+
permissions:
23+
contents: read
24+
25+
env:
26+
SPDX_ALLOWED_DELIMITED: 'MIT;MIT-0;ISC;0BSD;BSD-2-Clause;BSD-3-Clause;Apache-2.0;Python-2.0;CC0-1.0;CC-BY-3.0;CC-BY-4.0;Public Domain;Unlicense'
27+
28+
steps:
29+
- name: Checkout code
30+
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
31+
32+
- name: Get PHP version
33+
id: phpversion
34+
run: |
35+
# Get the PHP version to use from composer.json
36+
PHP=$(jq -r '.require["php"]' composer.json)
37+
# Remove the leading caret
38+
PHP=${PHP//^/}
39+
echo "::set-output name=version::$PHP"
40+
41+
- name: Install PHP
42+
uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1
43+
with:
44+
php-version: ${{ steps.phpversion.outputs.version }}
45+
extensions: curl, dom, gd, intl, json, ldap, mbstring, mysql, tidy, zip
46+
tools: composer:v2
47+
48+
- name: Composer install
49+
run: composer install
50+
51+
- name: Composer licenses
52+
run: |
53+
# Validate licenses of all composer dependencies are allowed
54+
echo "Checking licenses of all dependencies"
55+
composer global require madewithlove/license-checker
56+
COMPOSER_GLOBAL_HOME=$(composer -q -n config --global home)
57+
# Update the licenses in installed.json file to be sorted so that allowed SPDX identifier
58+
# are at the top of the list. This is done because the license-checker will only check the first SPDX.
59+
SPDX_ALLOWED_DELIMITED=$SPDX_ALLOWED_DELIMITED php -r '
60+
$allowedSpdxDelimted = getenv("SPDX_ALLOWED_DELIMITED");
61+
$allowedSpdx = explode(";", $allowedSpdxDelimted);
62+
$filename = "vendor/composer/installed.json";
63+
$contents = file_get_contents("vendor/composer/installed.json");
64+
$json = json_decode($contents, true);
65+
foreach ($json["packages"] as &$package) {
66+
if (!isset($package["license"])) {
67+
throw new Exception("License field missing for package " . $package["name"]);
68+
}
69+
usort($package["license"], fn ($spdx) => in_array($spdx, $allowedSpdx) ? -1 : 1);
70+
}
71+
file_put_contents($filename, json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
72+
'
73+
# Translate " " to "_" (and back again later) for any SPDX that has a space in it, such as "Public Domain"
74+
# Otherwise the bash for loop will split on the space
75+
SPDX_ALLOWED_LIST=$(echo $SPDX_ALLOWED_DELIMITED | tr " " "_" | tr ";" "\n")
76+
SPDX_USED_LIST=$($COMPOSER_GLOBAL_HOME/vendor/bin/license-checker --no-dev used)
77+
for SPDX_USED in $SPDX_USED_LIST; do
78+
IS_ALLOWED=0
79+
for SPDX_ALLOWED in $SPDX_ALLOWED_LIST; do
80+
SPDX_ALLOWED=$(echo $SPDX_ALLOWED | tr "_" " ")
81+
if [[ $SPDX_USED == $SPDX_ALLOWED ]]; then
82+
IS_ALLOWED=1
83+
break
84+
fi
85+
done
86+
if [[ $IS_ALLOWED == 0 ]]; then
87+
echo "License $SPDX_USED found in composer dependencies is not allowed. Check vendor/composer/installed.json"
88+
exit 1
89+
fi
90+
done
91+
# Remove license-checker as its name will collide with the npm license checker
92+
composer global remove madewithlove/license-checker
93+
echo "All licenses are allowed"
94+
95+
- name: NPM licenses
96+
run: |
97+
# Set nvmdir explicitly before installation. Default dir doesn't work for some reason.
98+
export NVM_DIR="${HOME}/.nvm"
99+
# Installation fails if install dir is specified but doesn't exist
100+
if ! [[ -d "$NVM_DIR" ]]; then
101+
echo "NVM_DIR '$NVM_DIR' doesn't exist - creating it now"
102+
mkdir $NVM_DIR
103+
fi
104+
# Get install nvm script from gha-run-tests
105+
curl -s https://raw.githubusercontent.com/silverstripe/gha-run-tests/refs/heads/1/install-nvm.sh > install-nvm.sh
106+
chmod +x install-nvm.sh
107+
./install-nvm.sh
108+
if [[ $? != 0 ]]; then
109+
echo "Error while installing nvm"
110+
exit 1
111+
fi
112+
# This loads nvm
113+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
114+
115+
# Loop all package.json files that were previously installed by composer install
116+
BASEDIR=$(pwd)
117+
FILES=$(find . | grep package.json | grep -v node_modules | grep -v tinymce)
118+
for FILE in $FILES; do
119+
# remove trailing "/package.json"
120+
SUBDIR="${FILE/\/package.json/}"
121+
DIR="$BASEDIR/$SUBDIR"
122+
echo "Checking $DIR"
123+
cd $DIR
124+
if [[ ! -f .nvmrc ]]; then
125+
echo "Missing .nvmrc"
126+
exit 1
127+
fi
128+
nvm install
129+
nvm use
130+
if [[ -z $(which yarn) ]]; then
131+
npm install -g yarn;
132+
fi
133+
yarn install --network-concurrency 1
134+
DEPS=$(jq -r '.dependencies' package.json)
135+
if [[ $DEPS == "null" ]] || [[ $DEPS == "{}" ]]; then
136+
echo "No non-dev dependencies found in $DIR"
137+
continue
138+
fi
139+
if [[ -z $(which license-checker) ]]; then
140+
echo "Installing license-checker"
141+
npm install -g license-checker
142+
fi
143+
license-checker --production --unknown --out /dev/null --onlyAllow "$SPDX_ALLOWED_DELIMITED" --excludePackages "$EXCLUDE_PACKAGES"
144+
echo "All licenses are allowed for $DIR"
145+
done
146+
echo "Passed"

0 commit comments

Comments
 (0)