From 8616411691c0309bc6cf0b9d65680ee34412a049 Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 8 May 2024 12:12:37 +0200 Subject: [PATCH 1/4] handle request errors more gracefully --- nf_core/lint/actions_schema_validation.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nf_core/lint/actions_schema_validation.py b/nf_core/lint/actions_schema_validation.py index fa4471d98c..386b63eccf 100644 --- a/nf_core/lint/actions_schema_validation.py +++ b/nf_core/lint/actions_schema_validation.py @@ -19,6 +19,7 @@ def actions_schema_validation(self): """ passed = [] failed = [] + warned = [] # Only show error messages from schema logging.getLogger("nf_core.schema").setLevel(logging.ERROR) @@ -28,6 +29,12 @@ def actions_schema_validation(self): # Load the GitHub workflow schema r = requests.get("https://json.schemastore.org/github-workflow", allow_redirects=True) + # handle "Service Unavailable" error + if r.status_code not in [200, 301]: + warned.append( + f"Failed to fetch schema: Response code for `https://json.schemastore.org/github-workflow` was {r.status_code}" + ) + return {"passed": passed, "failed": failed, "warned": warned} schema = r.json() # Validate all workflows against the schema @@ -55,4 +62,4 @@ def actions_schema_validation(self): except Exception as e: failed.append(f"Workflow validation failed for {wf}: {e}") - return {"passed": passed, "failed": failed} + return {"passed": passed, "failed": failed, "warned": warned} From dcfcd4ddad5db856e41282dcf3e904001215141b Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 8 May 2024 12:17:45 +0200 Subject: [PATCH 2/4] add type hints --- nf_core/lint/actions_schema_validation.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/nf_core/lint/actions_schema_validation.py b/nf_core/lint/actions_schema_validation.py index 386b63eccf..7e878a1af8 100644 --- a/nf_core/lint/actions_schema_validation.py +++ b/nf_core/lint/actions_schema_validation.py @@ -1,13 +1,14 @@ import glob import logging import os +from typing import Any, Dict, List import jsonschema import requests import yaml -def actions_schema_validation(self): +def actions_schema_validation(self) -> Dict[str, List[str]]: """Checks that the GitHub Action workflow yml/yaml files adhere to the correct schema nf-core pipelines use GitHub actions workflows to run CI tests, check formatting and also linting, among others. @@ -17,9 +18,9 @@ def actions_schema_validation(self): To pass this test, make sure that all your workflows contain the required properties ``on`` and ``jobs`` and that all other properties are of the correct type, as specified in the schema (link above). """ - passed = [] - failed = [] - warned = [] + passed: List[str] = [] + failed: List[str] = [] + warned: List[str] = [] # Only show error messages from schema logging.getLogger("nf_core.schema").setLevel(logging.ERROR) @@ -35,7 +36,7 @@ def actions_schema_validation(self): f"Failed to fetch schema: Response code for `https://json.schemastore.org/github-workflow` was {r.status_code}" ) return {"passed": passed, "failed": failed, "warned": warned} - schema = r.json() + schema: Dict[str, Any] = r.json() # Validate all workflows against the schema for wf_path in action_workflows: @@ -53,7 +54,7 @@ def actions_schema_validation(self): try: wf_json["on"] = wf_json.pop(True) except Exception: - failed.append("Missing 'on' keyword in {}.format(wf)") + failed.append(f"Missing 'on' keyword in {wf}") # Validate the workflow try: From bd8e46e680f71a6e6ea3eec08eed9b402cc0855f Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 8 May 2024 12:21:05 +0200 Subject: [PATCH 3/4] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ba5d53f3c..a7eea54dd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Include test for presence of versions in snapshot ([#2888](https://github.com/nf-core/tools/pull/2888)) - Components: set correct sha before running component lint tests ([#2952](https://github.com/nf-core/tools/pull/2952)) - Less strict logo comparison ([#2956](https://github.com/nf-core/tools/pull/2956)) +- Handle request errors more gracefully for actions validation ([#2959](https://github.com/nf-core/tools/pull/2959)) ### Download From bda8d42627618d566f731e685f8d0e9f08512cd5 Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 8 May 2024 13:49:35 +0200 Subject: [PATCH 4/4] fix linting test --- tests/lint/actions_schema_validation.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/lint/actions_schema_validation.py b/tests/lint/actions_schema_validation.py index ad65d90018..e202b3b1ce 100644 --- a/tests/lint/actions_schema_validation.py +++ b/tests/lint/actions_schema_validation.py @@ -1,4 +1,4 @@ -import os +from pathlib import Path import yaml @@ -9,10 +9,11 @@ def test_actions_schema_validation_missing_jobs(self): """Missing 'jobs' field should result in failure""" new_pipeline = self._make_pipeline_copy() - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml")) as fh: + awstest_yml_path = Path(new_pipeline) / ".github" / "workflows" / "awstest.yml" + with open(awstest_yml_path) as fh: awstest_yml = yaml.safe_load(fh) awstest_yml.pop("jobs") - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml"), "w") as fh: + with open(awstest_yml_path, "w") as fh: yaml.dump(awstest_yml, fh) lint_obj = nf_core.lint.PipelineLint(new_pipeline) @@ -27,10 +28,11 @@ def test_actions_schema_validation_missing_on(self): """Missing 'on' field should result in failure""" new_pipeline = self._make_pipeline_copy() - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml")) as fh: + awstest_yml_path = Path(new_pipeline) / ".github" / "workflows" / "awstest.yml" + with open(awstest_yml_path) as fh: awstest_yml = yaml.safe_load(fh) awstest_yml.pop(True) - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml"), "w") as fh: + with open(awstest_yml_path, "w") as fh: yaml.dump(awstest_yml, fh) lint_obj = nf_core.lint.PipelineLint(new_pipeline) @@ -38,7 +40,7 @@ def test_actions_schema_validation_missing_on(self): results = lint_obj.actions_schema_validation() - assert results["failed"][0] == "Missing 'on' keyword in {}.format(wf)" + assert results["failed"][0] == "Missing 'on' keyword in awstest.yml" assert "Workflow validation failed for awstest.yml: 'on' is a required property" in results["failed"][1] @@ -46,10 +48,11 @@ def test_actions_schema_validation_fails_for_additional_property(self): """Missing 'jobs' field should result in failure""" new_pipeline = self._make_pipeline_copy() - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml")) as fh: + awstest_yml_path = Path(new_pipeline) / ".github" / "workflows" / "awstest.yml" + with open(awstest_yml_path) as fh: awstest_yml = yaml.safe_load(fh) awstest_yml["not_jobs"] = awstest_yml["jobs"] - with open(os.path.join(new_pipeline, ".github", "workflows", "awstest.yml"), "w") as fh: + with open(awstest_yml_path, "w") as fh: yaml.dump(awstest_yml, fh) lint_obj = nf_core.lint.PipelineLint(new_pipeline)