Skip to content

Commit 9ad6d53

Browse files
devin-ai-integration[bot]zfields@blues.com
authored andcommitted
NF-1014: Incorporate ScanCode into CI for OSS compliance
• Added ScanCode installation to Dockerfile • Created run_scancode.sh script for license compliance analysis • Added VSCode task for running license compliance check • Added GitHub Actions workflow job for license compliance check Co-Authored-By: [email protected] <[email protected]>
1 parent 1503daa commit 9ad6d53

File tree

5 files changed

+141
-3
lines changed

5 files changed

+141
-3
lines changed

.github/workflows/ci.yml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ jobs:
1616
- name: Checkout code
1717
uses: actions/checkout@v4
1818

19-
# TODO: This is a 3rd party GitHub action from some dude. Ideally, we'd
20-
# use something more "official".
19+
# TODO: This is a 3rd party GitHub action from "some dude".
20+
# Ideally, we'd use something more official.
2121
- name: Check if Dockerfile changed
2222
uses: dorny/paths-filter@v2
2323
id: filter
@@ -187,10 +187,29 @@ jobs:
187187
run: |
188188
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/run_cppcheck.sh ghcr.io/blues/note_c_ci:latest
189189
190+
run_scancode:
191+
runs-on: ubuntu-latest
192+
if: ${{ always() }}
193+
needs: [build_ci_docker_image]
194+
195+
steps:
196+
- name: Checkout code
197+
uses: actions/checkout@v4
198+
199+
- name: Load CI Docker image
200+
# Only load the Docker image artifact if build_ci_docker_image actually
201+
# ran (e.g. it wasn't skipped and was successful).
202+
if: ${{ needs.build_ci_docker_image.result == 'success' }}
203+
uses: ./.github/actions/load-ci-image
204+
205+
- name: Run license compliance check
206+
run: |
207+
docker run --rm --volume $(pwd):/note-c/ --workdir /note-c/ --entrypoint ./scripts/run_scancode.sh ghcr.io/blues/note_c_ci:latest
208+
190209
publish_ci_image:
191210
runs-on: ubuntu-latest
192211
# Make sure unit tests unit tests passed before publishing.
193-
needs: [build_ci_docker_image, run_unit_tests]
212+
needs: [build_ci_docker_image, run_unit_tests, run_scancode]
194213
# Only publish the image if this is a push event and the Docker image was rebuilt
195214
if: ${{ github.event_name == 'push' && needs.build_ci_docker_image.result == 'success' }}
196215

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ settings.json
1111

1212
# Development Artifacts
1313
cppcheck_output.txt
14+
scancode_console_output.txt

.vscode/tasks.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,19 @@
120120
],
121121
"group": "test"
122122
}
123+
,
124+
{
125+
"label": "Note-C: Run License Compliance Check",
126+
"type": "shell",
127+
"command": "${workspaceFolder}/scripts/run_scancode.sh",
128+
"options": {
129+
"cwd": "${workspaceFolder}",
130+
"env": {
131+
"LC_ALL": "C"
132+
}
133+
},
134+
"problemMatcher": [],
135+
"group": "test"
136+
}
123137
]
124138
}

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ RUN ["dash", "-c", "\
7070
&& pip install --break-system-packages \
7171
breathe \
7272
sphinx-rtd-theme \
73+
scancode-toolkit \
7374
&& apt-get clean \
7475
&& apt-get purge \
7576
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \

scripts/run_scancode.sh

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/bash
2+
set -eo pipefail
3+
4+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
5+
SRC_DIR="$SCRIPT_DIR/.."
6+
7+
echo "Running License Compliance Analysis..."
8+
echo
9+
10+
# Create a function to generate the summary
11+
generate_summary() {
12+
{
13+
# Initialize flag
14+
has_critical_issues=false
15+
16+
echo
17+
18+
# Always generate and display summary regardless of exit code
19+
echo "=== License Compliance Summary ==="
20+
echo
21+
22+
# Display license information
23+
echo "License Information:"
24+
echo "-------------------"
25+
jq -r '.summary.declared_license_expression' scancode_output.json || echo "None found"
26+
echo
27+
28+
# Display license clarity score
29+
echo "License Clarity Score:"
30+
echo "---------------------"
31+
jq -r '.summary.license_clarity_score.score' scancode_output.json || echo "Not available"
32+
echo
33+
34+
# Display other licenses found
35+
echo "Other Licenses Found:"
36+
echo "--------------------"
37+
jq -r '.summary.other_license_expressions[] | select(.value != null) | "\(.value): \(.count) occurrences"' scancode_output.json || echo "None found"
38+
echo
39+
40+
# Display copyright holders
41+
echo "Copyright Holders:"
42+
echo "-----------------"
43+
jq -r '.tallies.holders[] | select(.value != null) | "\(.value): \(.count) occurrences"' scancode_output.json || echo "None found"
44+
echo
45+
46+
# Check for non-compliant licenses
47+
echo "License Compliance Issues:"
48+
echo "-------------------------"
49+
# List of non-compliant or problematic licenses
50+
problematic_licenses=("gpl-2.0" "gpl-3.0" "agpl-3.0" "cc-by-nc" "proprietary")
51+
52+
found_problematic=false
53+
for license in "${problematic_licenses[@]}"; do
54+
count=$(jq -r ".summary.other_license_expressions[] | select(.value == \"$license\") | .count" scancode_output.json 2>/dev/null || echo "0")
55+
if [ "$count" != "0" ] && [ "$count" != "" ]; then
56+
echo "WARNING: Found $count occurrences of $license license, which may have compliance implications."
57+
found_problematic=true
58+
has_critical_issues=true
59+
fi
60+
done
61+
62+
if ! $found_problematic; then
63+
echo "No problematic licenses found."
64+
fi
65+
echo
66+
67+
# Display status and details
68+
if $has_critical_issues; then
69+
echo "Status: FAILED - License compliance issues found"
70+
echo
71+
echo "Review and fix license compliance issues before proceeding"
72+
else
73+
echo "Status: PASSED - No license compliance issues found"
74+
echo
75+
echo "Note: Review license information for potential improvements"
76+
fi
77+
}
78+
79+
# Return 1 if critical issues found, 0 otherwise
80+
if $has_critical_issues; then
81+
return 1
82+
else
83+
return 0
84+
fi
85+
}
86+
87+
# Run scancode and capture output and exit code
88+
scancode \
89+
--license \
90+
--copyright \
91+
--classify \
92+
--summary \
93+
--license-clarity-score \
94+
--tallies \
95+
--json-pp scancode_output.json \
96+
--timeout 120 \
97+
--processes 2 \
98+
. 2>&1 | tee scancode_console_output.txt
99+
100+
generate_summary
101+
102+
# Exit with scancode's status code
103+
exit $?

0 commit comments

Comments
 (0)