diff --git a/.github/scripts/request_validation.py b/.github/scripts/request_validation.py index 7817de02..30b54f99 100644 --- a/.github/scripts/request_validation.py +++ b/.github/scripts/request_validation.py @@ -2,29 +2,29 @@ import os import sys -from utils.json_validation import request_validation, \ - get_errors_response +from utils.json_validation import request_validation, get_errors_response -# --------- # # Handling arguments -# --------- # dirname = sys.argv[1] curl_URL = sys.argv[2] -# - # # Hardcoded values -# - # extension = ".json" -# --------- # # Running validations -# --------- # error_dict = {} -# We iterate over the JSON documents to validate +validated_files = [] +total_files = 0 +files_with_errors = 0 + +# Iterate over the JSON documents to validate for file in os.scandir(dirname): if not file.path.endswith(extension): continue + total_files += 1 + validated_files.append(file.name) + request = request_validation( data_filepath=file, validator_url=curl_URL @@ -36,7 +36,17 @@ ) if val_error: error_dict[file.name] = val_error + files_with_errors += 1 # If the dictionary is not empty, fail the script returning it +summary = { + "n_total_files": total_files, + "n_files_with_errors": files_with_errors, + "error_files": error_dict, + "all_files": validated_files +} + if error_dict: - sys.exit(json.dumps(error_dict, sort_keys=True, indent=4)) + sys.exit(json.dumps(summary, sort_keys=True, indent=4)) +else: + print(json.dumps(summary, sort_keys=True, indent=4)) diff --git a/.github/scripts/requirements.txt b/.github/scripts/requirements.txt index 5360f418..ca1bfe69 100644 --- a/.github/scripts/requirements.txt +++ b/.github/scripts/requirements.txt @@ -2,7 +2,7 @@ argparse typing requests==2.26.0 pandas==1.5.3 -matplotlib==3.4.3 +matplotlib==3.9.0 jsonpath_ng jsonref jsonschema==3.2.0 diff --git a/.github/scripts/update_version_manifest.py b/.github/scripts/update_version_manifest.py index 2b9d34b3..f26a3eb1 100644 --- a/.github/scripts/update_version_manifest.py +++ b/.github/scripts/update_version_manifest.py @@ -14,7 +14,7 @@ from utils.json_validation import validate_json # Script used to update the version manifest (./docs/releases) with the versions of the JSON schemas. For further details, please check: -# https://github.com/EbiEga/ega-metadata-schema/tree/main/docs/biovalidator_benchmarks +# https://github.com/EbiEga/ega-metadata-schema/tree/main/docs/releases # --------- # # Handling arguments diff --git a/.github/scripts/utils/json_validation.py b/.github/scripts/utils/json_validation.py index 5b79c6c0..ced52da7 100644 --- a/.github/scripts/utils/json_validation.py +++ b/.github/scripts/utils/json_validation.py @@ -49,11 +49,15 @@ def get_errors_response( if not response.status_code == requests.codes.ok: error_message = ( f"The POST response was not successful: instead of {requests.codes.ok}," - f" the status code was '{response.status_code}' when validating file '{filename}'" + f" the status code was '{response.status_code}' when validating file '{filename}'." + f" Response content: {response.content.decode('utf-8')}" ) return error_message - val_response_list = response.json() + try: + val_response_list = response.json() + except ValueError: + return f"Invalid JSON response when validating file '{filename}'. Response content: {response.content.decode('utf-8')}" # If the list is empty "[]", the validation found no errors if not len(val_response_list) == 0: diff --git a/.github/workflows/check_project_version_change.yml b/.github/workflows/check_project_version_change.yml index cb581fd2..ca27e93f 100644 --- a/.github/workflows/check_project_version_change.yml +++ b/.github/workflows/check_project_version_change.yml @@ -43,11 +43,24 @@ jobs: # This bit is needed for running the following python script python-version: '3.x' + - name: Cache pip + uses: actions/cache@v4 + with: + # On subsequent runs, if the cache key matches (i.e., operating system and the hash of the requirements.txt file), + # the dependencies are restored from the cache instead of being downloaded and installed again. + path: ~/.cache/pip + # combines the OS type and a hash of the requirements.txt file: the cache is specific to the dependencies listed + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + # If there is no cache for this key, we create it at the end of the run, even if there was an error mid-way + save-always: true + - name: Install dependencies run: | pip install --upgrade pip requirements_f="./.github/scripts/requirements.txt" - if [ -f "$requirements_f" ]; then pip install -r "$requirements_f"; fi + if [ -f "$requirements_f" ]; then pip install -r "$requirements_f" --prefer-binary --verbose; fi - name: Run version modification check id: run-version-modification-check diff --git a/.github/workflows/json_validation_against_EGA_API.yml b/.github/workflows/json_validation_against_EGA_API.yml index 53e783cd..30efc17f 100644 --- a/.github/workflows/json_validation_against_EGA_API.yml +++ b/.github/workflows/json_validation_against_EGA_API.yml @@ -39,11 +39,24 @@ jobs: # This bit is needed for running the following python script python-version: '3.x' + - name: Cache pip + uses: actions/cache@v4 + with: + # On subsequent runs, if the cache key matches (i.e., operating system and the hash of the requirements.txt file), + # the dependencies are restored from the cache instead of being downloaded and installed again. + path: ~/.cache/pip + # combines the OS type and a hash of the requirements.txt file: the cache is specific to the dependencies listed + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + # If there is no cache for this key, we create it at the end of the run, even if there was an error mid-way + save-always: true + - name: Install dependencies run: | pip install --upgrade pip requirements_f="./.github/scripts/requirements.txt" - if [ -f "$requirements_f" ]; then pip install -r "$requirements_f"; fi + if [ -f "$requirements_f" ]; then pip install -r "$requirements_f" --prefer-binary --verbose; fi - name: Validate JSON examples # Validate all JSON documents against their corresponding schemas diff --git a/.github/workflows/json_validation_deploying_biovalidator.yml b/.github/workflows/json_validation_deploying_biovalidator.yml index 4c8b6c53..ba9e396a 100644 --- a/.github/workflows/json_validation_deploying_biovalidator.yml +++ b/.github/workflows/json_validation_deploying_biovalidator.yml @@ -27,7 +27,6 @@ name: | (json_validation_deploying_biovalidator.yml) on: - # Executes on any commit to a PR to the "main" branch pull_request: branches: [main] @@ -38,13 +37,32 @@ jobs: - name: Checkout code uses: actions/checkout@v3 with: - # Full git history fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + # We'll use the latest version of python from major 3 release + # This bit is needed for running the following python script + python-version: '3.x' + + - name: Cache pip + uses: actions/cache@v4 + with: + # On subsequent runs, if the cache key matches (i.e., operating system and the hash of the requirements.txt file), + # the dependencies are restored from the cache instead of being downloaded and installed again. + path: ~/.cache/pip + # combines the OS type and a hash of the requirements.txt file: the cache is specific to the dependencies listed + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + # If there is no cache for this key, we create it at the end of the run, even if there was an error mid-way + save-always: true + - name: Clone Biovalidator # See https://github.com/elixir-europe/biovalidator#installation # We want to test the "main" branch of the project run: git clone https://github.com/elixir-europe/biovalidator.git + - name: Install Biovalidator # We want to test with the latest Node.js version, but if not, we # could make use of action: https://github.com/actions/setup-node @@ -59,23 +77,28 @@ jobs: # changes. Therefore we specify the schemas at deployment level (-r) run: | schemas_dir="./schemas" + node biovalidator/src/biovalidator -r "$schemas_dir/*.json" > biovalidator.log 2>&1 & - node biovalidator/src/biovalidator -r "$schemas_dir/*.json" & - - # We stop for a few seconds to give the server time - sleep 3 - - - uses: actions/setup-python@v4 - with: - # We'll use the latest version of python from major 3 release - # This bit is needed for running the following python script - python-version: '3.x' + # Check if the server is up and running, and wait for a few seconds if not + for i in {1..10}; do + if curl --output /dev/null --silent --head --fail "http://localhost:3020/validate"; then + echo "Biovalidator server is up!" + break + fi + echo "Waiting ($i time(s)) for Biovalidator server to start..." + sleep 5 + done + if ! curl --output /dev/null --silent --head --fail "http://localhost:3020/validate"; then + echo "Biovalidator server failed to start" + cat biovalidator.log + exit 1 + fi - name: Install dependencies run: | pip install --upgrade pip requirements_f="./.github/scripts/requirements.txt" - if [ -f "$requirements_f" ]; then pip install -r "$requirements_f"; fi + if [ -f "$requirements_f" ]; then pip install -r "$requirements_f" --prefer-binary --verbose; fi - name: Validate JSON examples # Validate all JSON documents against their corresponding schemas @@ -86,5 +109,4 @@ jobs: # The following URL points to the locally deployed server of # Biovalidator url="http://localhost:3020/validate" - - python3 ./.github/scripts/request_validation.py "$json_ex_dir" "$url" \ No newline at end of file + python3 ./.github/scripts/request_validation.py "$json_ex_dir" "$url" diff --git a/.github/workflows/update_version_manifest.yml b/.github/workflows/update_version_manifest.yml index 0482662d..f56ab51e 100644 --- a/.github/workflows/update_version_manifest.yml +++ b/.github/workflows/update_version_manifest.yml @@ -40,11 +40,24 @@ jobs: # This bit is needed for running the following python script python-version: '3.x' + - name: Cache pip + uses: actions/cache@v4 + with: + # On subsequent runs, if the cache key matches (i.e., operating system and the hash of the requirements.txt file), + # the dependencies are restored from the cache instead of being downloaded and installed again. + path: ~/.cache/pip + # combines the OS type and a hash of the requirements.txt file: the cache is specific to the dependencies listed + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + # If there is no cache for this key, we create it at the end of the run, even if there was an error mid-way + save-always: true + - name: Install dependencies run: | pip install --upgrade pip requirements_f="./.github/scripts/requirements.txt" - if [ -f "$requirements_f" ]; then pip install -r "$requirements_f"; fi + if [ -f "$requirements_f" ]; then pip install -r "$requirements_f" --prefer-binary --verbose; fi - name: Update version manifest run: |