Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d71d2df
cleaner PR
Aug 8, 2025
957a892
fix
Aug 8, 2025
5a17a45
test
Aug 8, 2025
ccc76ad
change eb loading
Aug 8, 2025
9d93837
change eb loading
Aug 8, 2025
8f86fa4
now add an installation
Aug 10, 2025
9e0475b
only get modified easystacks
Aug 14, 2025
3e22835
now without using gh
Aug 14, 2025
f4870dc
debugging purposes
Aug 14, 2025
8081eae
fixed typo
Aug 14, 2025
0191252
debugging purposes
Aug 14, 2025
b3e9508
debugging purposes
Aug 14, 2025
045163c
fixed commit hash
Aug 14, 2025
0baa570
debugging purposes
Aug 14, 2025
ad96592
debugging purposes
Aug 14, 2025
d98392d
rookie mistake
Aug 14, 2025
053c97f
indentation matters
Aug 14, 2025
9ee00dd
typo
Aug 14, 2025
4e7525b
debug & bugfix
Aug 18, 2025
4cbb842
debug & bugfix 2
Aug 18, 2025
a2d934b
making variables global
Aug 20, 2025
10dc7e3
making variables global part 2
Aug 20, 2025
370b78c
refining the puzzle
Aug 20, 2025
03547d7
another rookie mistake
Aug 20, 2025
3607f27
solving environment
Aug 20, 2025
cb1390f
solving incosistency
Aug 21, 2025
a34bc01
fixing typos
Aug 21, 2025
42b382c
fixes before testing
Aug 21, 2025
0a127de
fixing environment
Aug 22, 2025
3bb8032
missing file
Aug 22, 2025
31f4284
fix
Aug 22, 2025
3462e07
testing more things
Aug 22, 2025
2ce9ef5
Update .github/workflows/check_licenses.yml
hvelab Aug 26, 2025
4b26b2f
testing with matrix
Sep 2, 2025
91cb66c
checking if --robot makes a difference
Sep 3, 2025
c0fa34b
robot deleted, fail-fast added
Sep 4, 2025
a0e0a67
tiny fixes
Sep 4, 2025
f002228
yet another tiny fix
Sep 4, 2025
d13b1bd
rework on missing modules file
Sep 4, 2025
22c192a
typo fix
Sep 4, 2025
a0bf545
fixing format and adding .yaml files
Oct 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions .github/workflows/check_licenses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: Check and update licenses

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# types: [opened, synchronized]
permissions:
contents: read # we dont need to write

jobs:
license_update:

strategy:
fail-fast: false
matrix:
# we just do these two architectures for now as they are ones causing more discrepancies
include:
- runs_on: ubuntu-24.04-arm
EESSI_SOFTWARE_SUBDIR_OVERRIDE: aarch64/generic
- runs_on: ubuntu-24.04
EESSI_SOFTWARE_SUBDIR_OVERRIDE: x86_64/generic

runs-on: ${{ matrix.runs_on }}

steps:
- uses: actions/checkout@v4
- uses: eessi/github-action-eessi@v3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could consider something like
https://github.com/EESSI/software-layer-scripts/blob/99c82b562e243cc6f566e72fbcbbe1a23d568d0c/.github/workflows/test-eb-hooks.yml#L24-L27
here. That would mean you can just

module unload EESSI
export EESSI_SOFTWARE_SUBDIR_OVERRIDE=${{matrix.EESSI_SOFTWARE_SUBDIR_OVERRIDE}}
module load EESSI/${{matrix.EESSI_VERSION}}

Note that you can currently not creating any matrix (so your action is not quite correct yet). I wonder if you need to do an architecture override at all, it is probably enough to just do this on x86 and Arm since they sometimes have slightly different dependencies. An example of an OS matrix that does exactly that is https://github.com/EESSI/github-action-eessi/blob/main/.github/workflows/minimal-usage.yml

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't consider that different architectures would mean different dependencies, do we have any know example for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've checked in all easyconfigs and LAMMPS is the only one that adds dependencies depending on the arch, the rest just change some compilation options which is not relevant here, anyway i fixed the matrix (with only x86 and a64fx) and will add what you mentioned to add the EESSI version


- name: Check for missing installlations
env:
PR_NUMBER: ${{ github.event.number }}

run: |
export EESSI_SOFTWARE_SUBDIR_OVERRIDE=${{matrix.EESSI_SOFTWARE_SUBDIR_OVERRIDE}}
source /cvmfs/software.eessi.io/versions/${EESSI_VERSION}/init/bash

# set $EESSI_CPU_FAMILY to the CPU architecture that corresponds to $EESSI_SOFTWARE_SUBDIR_OVERRIDE (part before the first slash),
# to prevent issues with checks in the Easybuild configuration that use this variable
export EESSI_CPU_FAMILY=${EESSI_SOFTWARE_SUBDIR_OVERRIDE%%/*}
export EESSI_PREFIX=/cvmfs/software.eessi.io/versions/${EESSI_VERSION}
export EESSI_OS_TYPE=linux
env | grep ^EESSI | sort
module load EasyBuild

# create a temporary directory to store the output
LOCAL_TMPDIR=$(mktemp -d)
eb_missing_out=$LOCAL_TMPDIR/eb_missing.out
echo "eb_missing_out=$LOCAL_TMPDIR/eb_missing.out" >> $GITHUB_ENV
echo "Temporary directory created: ${eb_missing_out}"
file_list=$(curl -sS \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100" |
jq -r '.[].filename | select(test("easystack"))')
echo "Files to check:"
echo $file_list

for easystack_file in $file_list; do
eb_version=$(echo ${easystack_file} | sed 's/.*eb-\([0-9.]*\).*.yml/\1/g')
echo "check missing installations for ${easystack_file} with EasyBuild ${eb_version}..."
module purge
module load EasyBuild/${eb_version}
module load EESSI-extend/${EESSI_VERSION}-easybuild
which eb
${EB:-eb} --version
${EB:-eb} --missing --easystack ${easystack_file} 2>&1 | tee ${eb_missing_out}

exit_code=${PIPESTATUS[0]}
echo "exit code for eb --missing --easystack ${easystack_file} is ${exit_code}"
grep " required modules missing:" ${eb_missing_out} # > /dev/null
exit_code=$?

if [[ ${exit_code} -eq 0 ]]; then echo "missing installations found for ${easystack_file}!" >&2;
else
echo "no missing installations found for ${easystack_file}."
exit 0
fi
done

- name: Check for modules existing in licenses.json file
run: |
if [ -s licenses/licenses.json ]; then
echo "licenses.json file exists, checking for modules that are not in the file..."
echo "tmp file check: ${eb_missing_out}"
# cat ${eb_missing_out}
grep -oP '^\* \K[^ ]+' "${eb_missing_out}" | sort -u > missing.txt
echo "Modules to check"
cat missing.txt

# Check if module exists as key in JSON
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To understand this, you are using the full module name as a key? Isn't that too restrictive? Someone would have to add each new version to the file. I would have thought that you only check for the name.

How will this cover extensions? You may want to consider a different approach to this check. Take a look at what I have done in https://github.com/EESSI/software-layer/blob/main/.github/workflows/test_compare_stacks.yml, you could reuse https://github.com/EESSI/software-layer/blob/main/.github/workflows/scripts/compare_stacks.py#L44 to gather all modules and extensions and check for them in your json file. I think you still need what you have, as you do want to fail the CI check if anything is missing (this will force maintainers to rerun the check before they merge, which will retrigger the license check).

That seems like a decent design to me though then, we fail the CI if anything is missing. You can do a preliminary licence check based on eb_missing_out to give a first indication of what may need to be added. When CI is run and things are not missing that means they have been ingested and we can then do the full license check (which includes extensions).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's something I discussed with Pedro, if we use the full name it would mean that for every update of the software we are re-checking the licensing, it's very unlikely that a software will change its license but it could happen.

About extensions, it would go on a separate way and file (extension_licenses.json). We thought of maybe in the preliminary stages of the check, once we gathered the EasyConfig file, parse if there is an exts_list parameter and from there start a new CI for that software in particular as the logic is a bit different from a "normal" piece of software.

while read -r module; do
if ! jq -e --arg key "$module" 'has($key)' "licenses/licenses.json" > /dev/null; then
echo "$module" >> missing_modules.txt
fi
done < missing.txt

echo "Modules not in licenses.json: "
cat missing_modules.txt

else
echo "licenses.json file does not exist? what happened?"
exit 1
fi

- name : Search sources for missing modules
run: |
if [ -s missing_modules.txt ]; then
echo "Searching sources for missing modules..."
# Generates a "modules_results.json" file
module load Python-bundle-PyPI/2023.06-GCCcore-12.3.0
python licenses/parsing_easyconfigs.py missing_modules.txt
cat modules_results.json
fi

- name : Try to fetch the license
run: |
if [ -s modules_results.json ]; then
echo "modules_results.json file exists, trying to fetch the license..."
module load Python-bundle-PyPI/2023.06-GCCcore-12.3.0
module load BeautifulSoup/4.12.2-GCCcore-12.3.0
python licenses/parse_licenses.py modules_results.json
cat licenses_test.json
else
echo "modules_results.json file does not exist, skipping license fetch."
fi

- name: Check for missing licenses
run: |
grep -3 "not found" licenses_test.json
exit_code=$?
if [[ ${exit_code} -ne 0 ]]; then
echo "No missing licenses found."
else
echo "Missing licenses found, please check the licenses.json file."
#exit 1
fi


Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,12 @@ easyconfigs:
options:
# see https://github.com/easybuilders/easybuild-easyconfigs/pull/22469
from-commit: fc22841fef99cbb2a221c18029b15e692e78c27c
- Scalasca-2.6.1-gompi-2023b.eb:
options:
# see https://github.com/easybuilders/easybuild-easyconfigs/pull/21135
from-commit: c61e72465641ffb2852f60c5264386af690b2ea1
- LAMMPS-29Aug2024_update2-foss-2023b-kokkos-CUDA-12.4.0.eb:
options:
# testing purposes
from-commit: cb372c4e096030c0bd285346b6b897842c998b92

3 changes: 3 additions & 0 deletions licenses/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
see https://spdx.org/licenses

Python function to download SPDX list of licenses is available in `spdx.py`
Loading