1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#!/usr/bin/env python
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import argparse, os
from typing import List
from ci_tools.ci_interactions import set_ci_variable, output_ci_warning
from ci_tools.build import discover_targeted_packages
from ci_tools.environment_exclusions import is_check_enabled
FULL_BUILD_SET = [
"whl",
"sdist",
"depends",
"latestdependency",
"mindependency",
"whl_no_aio",
]
PR_BUILD_SET = ["whl", "sdist", "mindependency"]
def resolve_devops_variable(var_value: str) -> List[str]:
if var_value:
if var_value.startswith("$("):
return []
else:
return [tox_env.strip() for tox_env in var_value.split(",") if tox_env.strip()]
def set_devops_value(resolved_set: List[str]) -> None:
string_value = ",".join(resolved_set)
set_ci_variable("toxenv", string_value)
def remove_unsupported_values(selected_set: List[str], unsupported_values: List[str]):
for unsupported_tox_env in unsupported_values:
if unsupported_tox_env in selected_set:
selected_set.remove(unsupported_tox_env)
def process_ci_skips(glob_string: str, service: str ) -> None:
checks_with_global_skip = ["pylint", "verifywhl", "verifysdist" "bandit", "mypy", "pyright", "verifytypes"]
root_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", ".."))
if service and service != "auto":
target_dir = os.path.join(root_dir, "sdk", service)
else:
target_dir = root_dir
targeted_packages = discover_targeted_packages(glob_string, target_dir)
for check in checks_with_global_skip:
packages_running_check = []
for pkg in targeted_packages:
if is_check_enabled(pkg, check, True):
packages_running_check.append(pkg)
if len(packages_running_check) == 0:
all_packages = set([os.path.basename(pkg) for pkg in targeted_packages])
set_ci_variable(f"Skip.{check[0].upper()}{check[1:]}", "true")
output_ci_warning(
f"All targeted packages {all_packages} skip the {check} check. Omitting step from build.",
"set_tox_environment.py",
)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="This script is used to resolve a set of arguments (that correspond to devops runtime variables) and determine which tox environments should be run for the current job. "
+ "When running against a specific service directory, attempts to find entire analysis steps that can be skipped. EG if pylint is disabled for every package in a given service directory, that "
+ "step should never actually run."
)
parser.add_argument(
"glob_string",
nargs="?",
help=(
"A comma separated list of glob strings that will target the top level directories that contain packages. "
'Examples: All == "azure-*", Single = "azure-keyvault"'
),
)
parser.add_argument("-t", "--team-project", dest="team_project", help="", required=True)
parser.add_argument(
"-o",
"--override",
dest="override_set",
help="If you have a set of tox environments that should override the defaults, provide it here. In CI this is runtime variable $(Run.ToxCustomEnvs). EG: \"whl,sdist\".",
)
parser.add_argument(
"-u",
"--unsupported",
dest="unsupported",
help="A list of unsupported environments. EG: \"pylint,sdist\"",
)
parser.add_argument(
"-s",
"--service",
dest="service",
help='If provided, activates secondary capability of this script. If each package in service "A" skips check "pylint", that entire STEP will be skipped.'
+ "If a check is only individually skipped, but still active in other packages of the service, then the step will run and the individual skip logic will apply.",
)
args = parser.parse_args()
team_project = resolve_devops_variable(args.team_project)
override_set = resolve_devops_variable(args.override_set)
unsupported = resolve_devops_variable(args.unsupported)
# by default, we should always start with the default set
selected_set = PR_BUILD_SET
# however if we are internal, use the full set
if "internal" in team_project:
selected_set = FULL_BUILD_SET
# if there is an override present, that will win ALWAYS
if override_set:
selected_set = override_set
# however we never run unsupported values
if unsupported:
remove_unsupported_values(selected_set, unsupported)
# and finally set the output variable
set_devops_value(selected_set)
if args.service:
process_ci_skips(args.glob_string, args.service)
|