diff --git a/conda_forge_webservices/github_actions_integration/__main__.py b/conda_forge_webservices/github_actions_integration/__main__.py index 52b8e67f2..4ea13a0f5 100644 --- a/conda_forge_webservices/github_actions_integration/__main__.py +++ b/conda_forge_webservices/github_actions_integration/__main__.py @@ -21,7 +21,12 @@ ) from .api_sessions import create_api_sessions from .rerendering import rerender -from .linting import make_lint_comment, build_and_make_lint_comment, set_pr_status +from .linting import ( + make_lint_comment, + build_and_make_lint_comment, + set_pr_status, + get_recipes_for_linting, +) from .version_updating import update_version, update_pr_title @@ -144,7 +149,12 @@ def main_run_task(task, repo, pr_number, task_data_dir, requested_version): elif task == "lint": _pull_docker_image() try: - lints, hints = lint_feedstock(feedstock_dir, use_container=True) + res = lint_feedstock(feedstock_dir, use_container=True) + if len(res) == 2: + lints, hints = res + errors = {} + else: + lints, hints, errors = res lint_error = False except Exception as err: LOGGER.warning("LINTING ERROR: %s", repr(err)) @@ -156,6 +166,7 @@ def main_run_task(task, repo, pr_number, task_data_dir, requested_version): task_data["task_results"]["lint_error"] = lint_error task_data["task_results"]["lints"] = lints task_data["task_results"]["hints"] = hints + task_data["task_results"]["errors"] = errors else: raise ValueError(f"Task `{task}` is not valid!") @@ -395,6 +406,15 @@ def main_finalize_task(task_data_dir): ) sys.exit(1) elif task == "lint": + if task_results.get("errors"): + recipes_to_lint, _ = get_recipes_for_linting( + gh, gh_repo, pr.number, task_results["lints"], task_results["hints"] + ) + if any( + task_results["errors"].get(rec, False) for rec in recipes_to_lint + ): + task_results["lint_error"] = True + if task_results["lint_error"]: _message = dedent_with_escaped_continue( """ diff --git a/conda_forge_webservices/github_actions_integration/linting.py b/conda_forge_webservices/github_actions_integration/linting.py index f54c55554..10d4765b4 100644 --- a/conda_forge_webservices/github_actions_integration/linting.py +++ b/conda_forge_webservices/github_actions_integration/linting.py @@ -3,6 +3,24 @@ from .utils import dedent_with_escaped_continue +def get_recipes_for_linting(gh, repo, pr_id, lints, hints): + fnames = set(hints.keys()) | set(lints.keys()) + + if repo.name == "staged-recipes": + pr = repo.get_pull(pr_id) + recipes_to_lint = set(f.filename for f in pr.get_files()) + recipes_to_lint = set( + fname + for fname in recipes_to_lint + if fname + not in ["recipes/example/meta.yaml", "recipes/example-v1/recipe.yaml"] + ) + else: + recipes_to_lint = set(fnames) + + return recipes_to_lint, fnames + + def _is_mergeable(repo, pr_id): mergeable = None while mergeable is None: @@ -92,25 +110,15 @@ def build_and_make_lint_comment(gh, repo, pr_id, lints, hints): ) status = "merge_conflict" else: - fnames = set(hints.keys()) | set(lints.keys()) - - if repo.name == "staged-recipes": - pr = repo.get_pull(pr_id) - recipes_to_lint = set(f.filename for f in pr.get_files()) - recipes_to_lint = set( - fname - for fname in recipes_to_lint - if fname - not in ["recipes/example/meta.yaml", "recipes/example-v1/recipe.yaml"] - ) - else: - recipes_to_lint = set(fnames) + recipes_to_lint, all_recipes = get_recipes_for_linting( + gh, repo, pr_id, lints, hints + ) linted_recipes = [] all_pass = True messages = [] hints_found = False - for fname in fnames: + for fname in all_recipes: if fname not in recipes_to_lint: continue @@ -167,7 +175,7 @@ def build_and_make_lint_comment(gh, repo, pr_id, lints, hints): """.format("\n".join(messages)), ) - if not fnames: + if not all_recipes: message = dedent_with_escaped_continue( """ Hi! This is the friendly automated conda-forge-linting service.