2024-11-01T16:13:31.9256445Z Current runner version: '2.320.0' 2024-11-01T16:13:31.9279283Z ##[group]Operating System 2024-11-01T16:13:31.9279929Z Ubuntu 2024-11-01T16:13:31.9280241Z 22.04.5 2024-11-01T16:13:31.9280683Z LTS 2024-11-01T16:13:31.9280998Z ##[endgroup] 2024-11-01T16:13:31.9281384Z ##[group]Runner Image 2024-11-01T16:13:31.9281920Z Image: ubuntu-22.04 2024-11-01T16:13:31.9282323Z Version: 20241015.1.0 2024-11-01T16:13:31.9283280Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20241015.1/images/ubuntu/Ubuntu2204-Readme.md 2024-11-01T16:13:31.9284811Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20241015.1 2024-11-01T16:13:31.9285684Z ##[endgroup] 2024-11-01T16:13:31.9286052Z ##[group]Runner Image Provisioner 2024-11-01T16:13:31.9286626Z 2.0.384.1 2024-11-01T16:13:31.9286973Z ##[endgroup] 2024-11-01T16:13:31.9301590Z ##[group]GITHUB_TOKEN Permissions 2024-11-01T16:13:31.9303225Z Contents: read 2024-11-01T16:13:31.9304074Z Metadata: read 2024-11-01T16:13:31.9304935Z Packages: read 2024-11-01T16:13:31.9305730Z ##[endgroup] 2024-11-01T16:13:31.9308816Z Secret source: Actions 2024-11-01T16:13:31.9309397Z Prepare workflow directory 2024-11-01T16:13:32.0213903Z Prepare all required actions 2024-11-01T16:13:32.0377282Z Uses: pytorch/pytorch/.github/workflows/_runner-determinator.yml@refs/heads/main (33dce10ece5b38aa0ab76739b658cd980a6e3d8f) 2024-11-01T16:13:32.0382339Z ##[group] Inputs 2024-11-01T16:13:32.0382833Z check_experiments: 2024-11-01T16:13:32.0383398Z triggering_actor: pytorch-bot[bot] 2024-11-01T16:13:32.0383951Z issue_owner: 2024-11-01T16:13:32.0384363Z curr_branch: ciflow/trunk/138766 2024-11-01T16:13:32.0385059Z curr_ref_type: tag 2024-11-01T16:13:32.0385476Z issue_number: 5132 2024-11-01T16:13:32.0385838Z ##[endgroup] 2024-11-01T16:13:32.0386760Z Complete job name: get-label-type / runner-determinator 2024-11-01T16:13:32.1264755Z ##[group]Run cat < runner_determinator.py 2024-11-01T16:13:32.1266642Z cat < runner_determinator.py 2024-11-01T16:13:32.1267297Z # flake8: noqa: G004 2024-11-01T16:13:32.1267733Z  2024-11-01T16:13:32.1268581Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-11-01T16:13:32.1269833Z # must be kept in sync. You can do it easily by running the following command: 2024-11-01T16:13:32.1270825Z # python .github/scripts/update_runner_determinator.py 2024-11-01T16:13:32.1271596Z  2024-11-01T16:13:32.1271971Z """ 2024-11-01T16:13:32.1272619Z This runner determinator is used to determine which set of runners to run a 2024-11-01T16:13:32.1273825Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-11-01T16:13:32.1275039Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-11-01T16:13:32.1276009Z of which runners should be used to run which job. 2024-11-01T16:13:32.1276731Z  2024-11-01T16:13:32.1277399Z The configuration has two parts, the settings and a list of opted-in users, 2024-11-01T16:13:32.1278481Z separated by a line containing "---". If the line is not present, the 2024-11-01T16:13:32.1279615Z settings are considered to be empty with only the second part, the user 2024-11-01T16:13:32.1280422Z list, defined. 2024-11-01T16:13:32.1280920Z  2024-11-01T16:13:32.1281551Z The first part is a YAML block that defines the rollout settings. This can be 2024-11-01T16:13:32.1282700Z used to define any settings that are needed to determine which runners to use. 2024-11-01T16:13:32.1283830Z It's fields are defined by the RolloutSettings class below. 2024-11-01T16:13:32.1284498Z  2024-11-01T16:13:32.1285176Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-11-01T16:13:32.1286360Z The user list is also a comma separated list of additional features or 2024-11-01T16:13:32.1287761Z experiments which the user could be opted in to. 2024-11-01T16:13:32.1288883Z  2024-11-01T16:13:32.1289459Z The user list has the following rules: 2024-11-01T16:13:32.1290043Z  2024-11-01T16:13:32.1290618Z - Users are GitHub usernames, which must start with the @ prefix 2024-11-01T16:13:32.1291753Z - Each user is also a comma-separated list of features/experiments to enable 2024-11-01T16:13:32.1292736Z - A "#" prefix opts the user out of all experiments 2024-11-01T16:13:32.1293335Z  2024-11-01T16:13:32.1293799Z Example config: 2024-11-01T16:13:32.1294389Z  # A list of experiments that can be opted into. 2024-11-01T16:13:32.1295192Z  # This defines the behavior they'll induce when opted into. 2024-11-01T16:13:32.1295999Z  # Expected syntax is: 2024-11-01T16:13:32.1296827Z  # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-11-01T16:13:32.1298059Z  # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-11-01T16:13:32.1298988Z  2024-11-01T16:13:32.1299377Z  experiments: 2024-11-01T16:13:32.1299815Z  lf: 2024-11-01T16:13:32.1300268Z  rollout_percent: 25 2024-11-01T16:13:32.1300811Z  all_branches: false 2024-11-01T16:13:32.1301338Z  default: true 2024-11-01T16:13:32.1301824Z  --- 2024-11-01T16:13:32.1302206Z  2024-11-01T16:13:32.1302563Z  # Opt-ins: 2024-11-01T16:13:32.1303352Z  # Users can opt into the LF fleet by adding their GitHub username to this list 2024-11-01T16:13:32.1304627Z  # and specifying experiments to enable in a comma-separated list. 2024-11-01T16:13:32.1305520Z  # Experiments should be from the above list. 2024-11-01T16:13:32.1306211Z  2024-11-01T16:13:32.1306588Z  @User1,lf,split_build 2024-11-01T16:13:32.1307102Z  @User2,lf 2024-11-01T16:13:32.1307585Z  @User3,split_build 2024-11-01T16:13:32.1308057Z """ 2024-11-01T16:13:32.1308448Z  2024-11-01T16:13:32.1308834Z import logging 2024-11-01T16:13:32.1309272Z import os 2024-11-01T16:13:32.1309695Z import random 2024-11-01T16:13:32.1310223Z from argparse import ArgumentParser 2024-11-01T16:13:32.1310823Z from logging import LogRecord 2024-11-01T16:13:32.1311653Z from typing import Any, Dict, FrozenSet, Iterable, List, NamedTuple, Tuple 2024-11-01T16:13:32.1312491Z  2024-11-01T16:13:32.1312849Z import yaml 2024-11-01T16:13:32.1313384Z from github import Auth, Github 2024-11-01T16:13:32.1314050Z from github.Issue import Issue 2024-11-01T16:13:32.1314563Z  2024-11-01T16:13:32.1314918Z  2024-11-01T16:13:32.1315445Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-11-01T16:13:32.1316270Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-11-01T16:13:32.1317323Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-11-01T16:13:32.1318208Z  2024-11-01T16:13:32.1318702Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-11-01T16:13:32.1319320Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-11-01T16:13:32.1319993Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-11-01T16:13:32.1320575Z  2024-11-01T16:13:32.1320878Z  2024-11-01T16:13:32.1321350Z SETTING_EXPERIMENTS = "experiments" 2024-11-01T16:13:32.1321930Z  2024-11-01T16:13:32.1322270Z LF_FLEET_EXPERIMENT = "lf" 2024-11-01T16:13:32.1322892Z CANARY_FLEET_SUFFIX = ".c" 2024-11-01T16:13:32.1323374Z  2024-11-01T16:13:32.1323676Z  2024-11-01T16:13:32.1324387Z class Experiment(NamedTuple): 2024-11-01T16:13:32.1324937Z  rollout_perc: float = ( 2024-11-01T16:13:32.1325704Z  0 # Percentage of workflows to experiment on when user is not opted-in. 2024-11-01T16:13:32.1326596Z  ) 2024-11-01T16:13:32.1326999Z  all_branches: bool = ( 2024-11-01T16:13:32.1327746Z  False # If True, the experiment is also enabled on the exception branches 2024-11-01T16:13:32.1329025Z  ) 2024-11-01T16:13:32.1329450Z  default: bool = ( 2024-11-01T16:13:32.1330173Z  True # If True, the experiment is enabled by default for all queries 2024-11-01T16:13:32.1331028Z  ) 2024-11-01T16:13:32.1331394Z  2024-11-01T16:13:32.1331762Z  # Add more fields as needed 2024-11-01T16:13:32.1332367Z  2024-11-01T16:13:32.1332706Z  2024-11-01T16:13:32.1333076Z class Settings(NamedTuple): 2024-11-01T16:13:32.1333665Z  """ 2024-11-01T16:13:32.1334212Z  Settings for the experiments that can be opted into. 2024-11-01T16:13:32.1334861Z  """ 2024-11-01T16:13:32.1335311Z  2024-11-01T16:13:32.1335766Z  experiments: Dict[str, Experiment] = {} 2024-11-01T16:13:32.1336305Z  2024-11-01T16:13:32.1336706Z  2024-11-01T16:13:32.1337162Z class ColorFormatter(logging.Formatter): 2024-11-01T16:13:32.1337938Z  """Color codes the log messages based on the log level""" 2024-11-01T16:13:32.1338684Z  2024-11-01T16:13:32.1339051Z  COLORS = { 2024-11-01T16:13:32.1339540Z  "WARNING": "\033[33m", # Yellow 2024-11-01T16:13:32.1340176Z  "ERROR": "\033[31m", # Red 2024-11-01T16:13:32.1340941Z  "CRITICAL": "\033[31m", # Red 2024-11-01T16:13:32.1341559Z  "INFO": "\033[0m", # Reset 2024-11-01T16:13:32.1342196Z  "DEBUG": "\033[0m", # Reset 2024-11-01T16:13:32.1342735Z  } 2024-11-01T16:13:32.1343094Z  2024-11-01T16:13:32.1343604Z  def format(self, record: LogRecord) -> str: 2024-11-01T16:13:32.1344529Z  log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-11-01T16:13:32.1345484Z  record.msg = f"{log_color}{record.msg}\033[0m" 2024-11-01T16:13:32.1346218Z  return super().format(record) 2024-11-01T16:13:32.1346763Z  2024-11-01T16:13:32.1347105Z  2024-11-01T16:13:32.1347561Z handler = logging.StreamHandler() 2024-11-01T16:13:32.1348406Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-11-01T16:13:32.1349234Z  2024-11-01T16:13:32.1349807Z log = logging.getLogger(os.path.basename(__file__)) 2024-11-01T16:13:32.1350455Z log.addHandler(handler) 2024-11-01T16:13:32.1350982Z log.setLevel(logging.INFO) 2024-11-01T16:13:32.1351547Z  2024-11-01T16:13:32.1351846Z  2024-11-01T16:13:32.1352356Z def set_github_output(key: str, value: str) -> None: 2024-11-01T16:13:32.1353072Z  """ 2024-11-01T16:13:32.1353652Z  Defines outputs of the github action that invokes this script 2024-11-01T16:13:32.1354399Z  """ 2024-11-01T16:13:32.1354861Z  if not GITHUB_OUTPUT: 2024-11-01T16:13:32.1356181Z  # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-11-01T16:13:32.1357577Z  log.warning( 2024-11-01T16:13:32.1358720Z  "No env var found for GITHUB_OUTPUT, you must be running this code locally. Falling back to the deprecated print method." 2024-11-01T16:13:32.1359857Z  ) 2024-11-01T16:13:32.1360329Z  print(f"::set-output name={key}::{value}") 2024-11-01T16:13:32.1361179Z  return 2024-11-01T16:13:32.1361607Z  2024-11-01T16:13:32.1361992Z  with open(GITHUB_OUTPUT, "a") as f: 2024-11-01T16:13:32.1362766Z  log.info(f"Setting output: {key}='{value}'") 2024-11-01T16:13:32.1363500Z  f.write(f"{key}={value}\n") 2024-11-01T16:13:32.1363993Z  2024-11-01T16:13:32.1364418Z  2024-11-01T16:13:32.1364985Z def _str_comma_separated_to_set(value: str) -> FrozenSet[str]: 2024-11-01T16:13:32.1365689Z  return frozenset( 2024-11-01T16:13:32.1366545Z  filter(lambda itm: itm != "", map(str.strip, value.strip(" \n\t").split(","))) 2024-11-01T16:13:32.1367354Z  ) 2024-11-01T16:13:32.1367682Z  2024-11-01T16:13:32.1368097Z  2024-11-01T16:13:32.1368816Z def parse_args() -> Any: 2024-11-01T16:13:32.1369492Z  parser = ArgumentParser("Get dynamic rollout settings") 2024-11-01T16:13:32.1370687Z  parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-11-01T16:13:32.1371584Z  parser.add_argument( 2024-11-01T16:13:32.1372074Z  "--github-issue-repo", 2024-11-01T16:13:32.1372686Z  type=str, 2024-11-01T16:13:32.1373158Z  required=False, 2024-11-01T16:13:32.1373774Z  default="pytorch/test-infra", 2024-11-01T16:13:32.1374402Z  help="GitHub repo to get the issue", 2024-11-01T16:13:32.1374981Z  ) 2024-11-01T16:13:32.1375455Z  parser.add_argument( 2024-11-01T16:13:32.1375929Z  "--github-repo", 2024-11-01T16:13:32.1376410Z  type=str, 2024-11-01T16:13:32.1376935Z  required=True, 2024-11-01T16:13:32.1377633Z  help="GitHub repo where CI is running", 2024-11-01T16:13:32.1378261Z  ) 2024-11-01T16:13:32.1378741Z  parser.add_argument( 2024-11-01T16:13:32.1379476Z  "--github-issue", type=int, required=True, help="GitHub issue number" 2024-11-01T16:13:32.1380276Z  ) 2024-11-01T16:13:32.1380729Z  parser.add_argument( 2024-11-01T16:13:32.1381470Z  "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-11-01T16:13:32.1382278Z  ) 2024-11-01T16:13:32.1382726Z  parser.add_argument( 2024-11-01T16:13:32.1383477Z  "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-11-01T16:13:32.1384297Z  ) 2024-11-01T16:13:32.1384747Z  parser.add_argument( 2024-11-01T16:13:32.1385575Z  "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-11-01T16:13:32.1386362Z  ) 2024-11-01T16:13:32.1386825Z  parser.add_argument( 2024-11-01T16:13:32.1387368Z  "--github-ref-type", 2024-11-01T16:13:32.1387852Z  type=str, 2024-11-01T16:13:32.1388362Z  required=True, 2024-11-01T16:13:32.1388989Z  help="Current GitHub ref type, branch or tag", 2024-11-01T16:13:32.1389589Z  ) 2024-11-01T16:13:32.1390035Z  parser.add_argument( 2024-11-01T16:13:32.1390599Z  "--eligible-experiments", 2024-11-01T16:13:32.1391184Z  type=_str_comma_separated_to_set, 2024-11-01T16:13:32.1391822Z  required=False, 2024-11-01T16:13:32.1392324Z  default="", 2024-11-01T16:13:32.1393374Z  help="comma separated list of experiments to check, if omitted all experiments marked with default=True are checked", 2024-11-01T16:13:32.1394552Z  ) 2024-11-01T16:13:32.1394900Z  2024-11-01T16:13:32.1395298Z  return parser.parse_args() 2024-11-01T16:13:32.1395892Z  2024-11-01T16:13:32.1396199Z  2024-11-01T16:13:32.1396672Z def get_gh_client(github_token: str) -> Github: 2024-11-01T16:13:32.1397586Z  auth = Auth.Token(github_token) 2024-11-01T16:13:32.1398124Z  return Github(auth=auth) 2024-11-01T16:13:32.1398637Z  2024-11-01T16:13:32.1399039Z  2024-11-01T16:13:32.1399557Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-11-01T16:13:32.1400314Z  repo = gh.get_repo(repo) 2024-11-01T16:13:32.1400983Z  return repo.get_issue(number=issue_num) 2024-11-01T16:13:32.1401527Z  2024-11-01T16:13:32.1401875Z  2024-11-01T16:13:32.1402316Z def get_potential_pr_author( 2024-11-01T16:13:32.1403069Z  github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-11-01T16:13:32.1403873Z ) -> str: 2024-11-01T16:13:32.1404598Z  # If the trigger was a new tag added by a bot, this is a ciflow case 2024-11-01T16:13:32.1405616Z  # Fetch the actual username from the original PR. The PR number is 2024-11-01T16:13:32.1406508Z  # embedded in the tag name: ciflow// 2024-11-01T16:13:32.1407246Z  2024-11-01T16:13:32.1407672Z  gh = get_gh_client(github_token) 2024-11-01T16:13:32.1408177Z  2024-11-01T16:13:32.1409079Z  if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-11-01T16:13:32.1409877Z  split_tag = ref_name.split("/") 2024-11-01T16:13:32.1410428Z  if ( 2024-11-01T16:13:32.1410936Z  len(split_tag) == 3 2024-11-01T16:13:32.1411538Z  and split_tag[0] == "ciflow" 2024-11-01T16:13:32.1412127Z  and split_tag[2].isnumeric() 2024-11-01T16:13:32.1412745Z  ): 2024-11-01T16:13:32.1413378Z  pr_number = split_tag[2] 2024-11-01T16:13:32.1413907Z  try: 2024-11-01T16:13:32.1414520Z  repository = gh.get_repo(repo) 2024-11-01T16:13:32.1415269Z  pull = repository.get_pull(number=int(pr_number)) 2024-11-01T16:13:32.1416005Z  except Exception as e: 2024-11-01T16:13:32.1416687Z  raise Exception( # noqa: TRY002 2024-11-01T16:13:32.1417509Z  f"issue with pull request {pr_number} from repo {repository}" 2024-11-01T16:13:32.1418267Z  ) from e 2024-11-01T16:13:32.1418843Z  return pull.user.login 2024-11-01T16:13:32.1419562Z  # In all other cases, return the original input username 2024-11-01T16:13:32.1420276Z  return username 2024-11-01T16:13:32.1420758Z  2024-11-01T16:13:32.1421094Z  2024-11-01T16:13:32.1421678Z def is_exception_branch(branch: str) -> bool: 2024-11-01T16:13:32.1422323Z  """ 2024-11-01T16:13:32.1423107Z  Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-11-01T16:13:32.1424044Z  """ 2024-11-01T16:13:32.1424764Z  return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-11-01T16:13:32.1425502Z  2024-11-01T16:13:32.1425849Z  2024-11-01T16:13:32.1426328Z def load_yaml(yaml_text: str) -> Any: 2024-11-01T16:13:32.1426848Z  try: 2024-11-01T16:13:32.1427310Z  data = yaml.safe_load(yaml_text) 2024-11-01T16:13:32.1427965Z  return data 2024-11-01T16:13:32.1428452Z  except yaml.YAMLError as exc: 2024-11-01T16:13:32.1429080Z  log.exception("Error loading YAML") 2024-11-01T16:13:32.1429730Z  raise 2024-11-01T16:13:32.1430120Z  2024-11-01T16:13:32.1430470Z  2024-11-01T16:13:32.1431233Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-11-01T16:13:32.1432060Z  """ 2024-11-01T16:13:32.1432992Z  Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-11-01T16:13:32.1433968Z  2024-11-01T16:13:32.1434559Z  If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:32.1435489Z  and the text below is the list of opted in users. 2024-11-01T16:13:32.1436217Z  2024-11-01T16:13:32.1436859Z  If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-11-01T16:13:32.1437697Z  """ 2024-11-01T16:13:32.1438298Z  rollout_state_parts = rollout_state.split("---") 2024-11-01T16:13:32.1439011Z  if len(rollout_state_parts) >= 2: 2024-11-01T16:13:32.1439707Z  return rollout_state_parts[0], rollout_state_parts[1] 2024-11-01T16:13:32.1440463Z  else: 2024-11-01T16:13:32.1440887Z  return "", rollout_state 2024-11-01T16:13:32.1441370Z  2024-11-01T16:13:32.1441787Z  2024-11-01T16:13:32.1442208Z class UserOptins(Dict[str, List[str]]): 2024-11-01T16:13:32.1442761Z  """ 2024-11-01T16:13:32.1443448Z  Dictionary of users with a list of features they have opted into 2024-11-01T16:13:32.1444195Z  """ 2024-11-01T16:13:32.1444536Z  2024-11-01T16:13:32.1444942Z  2024-11-01T16:13:32.1445540Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-11-01T16:13:32.1446275Z  """ 2024-11-01T16:13:32.1447232Z  Parse the user opt-in text into a key value pair of username and the list of features they have opted into 2024-11-01T16:13:32.1448245Z  2024-11-01T16:13:32.1449717Z  Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-11-01T16:13:32.1450962Z  - Example line: "@User1,lf,split_build" 2024-11-01T16:13:32.1451820Z  - A "#" prefix indicates the user is opted out of all experiments 2024-11-01T16:13:32.1452619Z  2024-11-01T16:13:32.1452929Z  2024-11-01T16:13:32.1453292Z  """ 2024-11-01T16:13:32.1453757Z  optins = UserOptins() 2024-11-01T16:13:32.1454323Z  for user in user_optin_text.split("\n"): 2024-11-01T16:13:32.1454985Z  user = user.strip("\r\n\t -") 2024-11-01T16:13:32.1455699Z  if not user or not user.startswith("@"): 2024-11-01T16:13:32.1456331Z  # Not a valid user. Skip 2024-11-01T16:13:32.1456910Z  continue 2024-11-01T16:13:32.1457415Z  2024-11-01T16:13:32.1457755Z  if user: 2024-11-01T16:13:32.1458306Z  usr_name = user.split(",")[0].strip("@") 2024-11-01T16:13:32.1459215Z  optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-11-01T16:13:32.1459944Z  2024-11-01T16:13:32.1460305Z  return optins 2024-11-01T16:13:32.1460805Z  2024-11-01T16:13:32.1461137Z  2024-11-01T16:13:32.1461697Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-11-01T16:13:32.1462487Z  """ 2024-11-01T16:13:32.1463204Z  Parse the experiments from the issue body into a list of ExperimentSettings 2024-11-01T16:13:32.1464054Z  """ 2024-11-01T16:13:32.1464505Z  try: 2024-11-01T16:13:32.1464914Z  if settings_text: 2024-11-01T16:13:32.1465801Z  # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-11-01T16:13:32.1466839Z  # for easy reading 2024-11-01T16:13:32.1467855Z  # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-11-01T16:13:32.1468931Z  # the backtick character in shell commands. 2024-11-01T16:13:32.1469957Z  backtick = chr(96) # backtick character 2024-11-01T16:13:32.1470773Z  settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-11-01T16:13:32.1471578Z  settings = load_yaml(settings_text) 2024-11-01T16:13:32.1472185Z  2024-11-01T16:13:32.1472895Z  # For now we just load experiments. We can expand this if/when we add more settings 2024-11-01T16:13:32.1473806Z  experiments = {} 2024-11-01T16:13:32.1474330Z  2024-11-01T16:13:32.1474974Z  for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-11-01T16:13:32.1475849Z  valid_settings = {} 2024-11-01T16:13:32.1476508Z  for setting in exp_settings: 2024-11-01T16:13:32.1477196Z  if setting not in Experiment._fields: 2024-11-01T16:13:32.1477873Z  log.warning( 2024-11-01T16:13:32.1478805Z  f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-11-01T16:13:32.1479604Z  ) 2024-11-01T16:13:32.1480107Z  else: 2024-11-01T16:13:32.1480798Z  valid_settings[setting] = exp_settings[setting] 2024-11-01T16:13:32.1481439Z  2024-11-01T16:13:32.1481957Z  experiments[exp_name] = Experiment(**valid_settings) 2024-11-01T16:13:32.1482780Z  return Settings(experiments) 2024-11-01T16:13:32.1483322Z  2024-11-01T16:13:32.1483691Z  except Exception: 2024-11-01T16:13:32.1484478Z  log.exception("Failed to parse settings") 2024-11-01T16:13:32.1485070Z  2024-11-01T16:13:32.1485442Z  return Settings() 2024-11-01T16:13:32.1485981Z  2024-11-01T16:13:32.1486288Z  2024-11-01T16:13:32.1486781Z def parse_settings(rollout_state: str) -> Settings: 2024-11-01T16:13:32.1487501Z  """ 2024-11-01T16:13:32.1487989Z  Parse settings, if any, from the rollout state. 2024-11-01T16:13:32.1488917Z  2024-11-01T16:13:32.1489684Z  If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:32.1490618Z  and the text below is the list of opted in users. 2024-11-01T16:13:32.1491222Z  2024-11-01T16:13:32.1492029Z  If it doesn't contain "---" then the settings are empty and the default values are used. 2024-11-01T16:13:32.1492897Z  """ 2024-11-01T16:13:32.1493525Z  settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:32.1494526Z  return parse_settings_from_text(settings_text) 2024-11-01T16:13:32.1495142Z  2024-11-01T16:13:32.1495465Z  2024-11-01T16:13:32.1496013Z def parse_users(rollout_state: str) -> UserOptins: 2024-11-01T16:13:32.1496648Z  """ 2024-11-01T16:13:32.1497082Z  Parse users from the rollout state. 2024-11-01T16:13:32.1497717Z  2024-11-01T16:13:32.1498060Z  """ 2024-11-01T16:13:32.1498657Z  _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:32.1499609Z  return parse_user_opt_in_from_text(users_text) 2024-11-01T16:13:32.1500244Z  2024-11-01T16:13:32.1500567Z  2024-11-01T16:13:32.1501344Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-11-01T16:13:32.1502227Z  """ 2024-11-01T16:13:32.1502718Z  Check if a user is opted into an experiment 2024-11-01T16:13:32.1503354Z  """ 2024-11-01T16:13:32.1503907Z  return experiment_name in user_optins.get(user, []) 2024-11-01T16:13:32.1504787Z  2024-11-01T16:13:32.1505166Z  2024-11-01T16:13:32.1505551Z def get_runner_prefix( 2024-11-01T16:13:32.1506055Z  rollout_state: str, 2024-11-01T16:13:32.1506635Z  workflow_requestors: Iterable[str], 2024-11-01T16:13:32.1507239Z  branch: str, 2024-11-01T16:13:32.1507836Z  eligible_experiments: FrozenSet[str] = frozenset(), 2024-11-01T16:13:32.1508576Z  is_canary: bool = False, 2024-11-01T16:13:32.1509094Z ) -> str: 2024-11-01T16:13:32.1509585Z  settings = parse_settings(rollout_state) 2024-11-01T16:13:32.1510335Z  user_optins = parse_users(rollout_state) 2024-11-01T16:13:32.1510917Z  2024-11-01T16:13:32.1511283Z  fleet_prefix = "" 2024-11-01T16:13:32.1511818Z  prefixes = [] 2024-11-01T16:13:32.1512577Z  for experiment_name, experiment_settings in settings.experiments.items(): 2024-11-01T16:13:32.1513719Z  if not experiment_settings.all_branches and is_exception_branch(branch): 2024-11-01T16:13:32.1514638Z  log.info( 2024-11-01T16:13:32.1515454Z  f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-11-01T16:13:32.1516364Z  ) 2024-11-01T16:13:32.1516848Z  continue 2024-11-01T16:13:32.1517262Z  2024-11-01T16:13:32.1517671Z  if eligible_experiments: 2024-11-01T16:13:32.1518421Z  if experiment_name not in eligible_experiments: 2024-11-01T16:13:32.1519170Z  exp_list = ", ".join(eligible_experiments) 2024-11-01T16:13:32.1519828Z  log.info( 2024-11-01T16:13:32.1520986Z  f"Skipping experiment '{experiment_name}', as it is not in the eligible_experiments list: {exp_list}" 2024-11-01T16:13:32.1521942Z  ) 2024-11-01T16:13:32.1522417Z  continue 2024-11-01T16:13:32.1523075Z  elif not experiment_settings.default: 2024-11-01T16:13:32.1523695Z  log.info( 2024-11-01T16:13:32.1524452Z  f"Skipping experiment '{experiment_name}', as it is not a default experiment" 2024-11-01T16:13:32.1525356Z  ) 2024-11-01T16:13:32.1525787Z  continue 2024-11-01T16:13:32.1526206Z  2024-11-01T16:13:32.1526815Z  # Is any workflow_requestor opted in to this experiment? 2024-11-01T16:13:32.1527547Z  opted_in_users = [ 2024-11-01T16:13:32.1528020Z  requestor 2024-11-01T16:13:32.1529405Z  for requestor in workflow_requestors 2024-11-01T16:13:32.1530278Z  if is_user_opted_in(requestor, user_optins, experiment_name) 2024-11-01T16:13:32.1530971Z  ] 2024-11-01T16:13:32.1531476Z  2024-11-01T16:13:32.1531848Z  enabled = False 2024-11-01T16:13:32.1532315Z  if opted_in_users: 2024-11-01T16:13:32.1532920Z  log.info( 2024-11-01T16:13:32.1533672Z  f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-11-01T16:13:32.1534528Z  ) 2024-11-01T16:13:32.1534940Z  enabled = True 2024-11-01T16:13:32.1535416Z  2024-11-01T16:13:32.1535922Z  elif experiment_settings.rollout_perc: 2024-11-01T16:13:32.1536956Z  # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-11-01T16:13:32.1538145Z  if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-11-01T16:13:32.1538992Z  log.info( 2024-11-01T16:13:32.1540009Z  f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-11-01T16:13:32.1541247Z  ) 2024-11-01T16:13:32.1541805Z  enabled = True 2024-11-01T16:13:32.1542274Z  2024-11-01T16:13:32.1542634Z  if enabled: 2024-11-01T16:13:32.1543211Z  label = experiment_name 2024-11-01T16:13:32.1543881Z  if experiment_name == LF_FLEET_EXPERIMENT: 2024-11-01T16:13:32.1544874Z  # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-11-01T16:13:32.1546046Z  # - If it's enabled, then we always list it's prefix first 2024-11-01T16:13:32.1547040Z  # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-11-01T16:13:32.1547833Z  if is_canary: 2024-11-01T16:13:32.1548502Z  label += CANARY_FLEET_SUFFIX 2024-11-01T16:13:32.1549152Z  fleet_prefix = label 2024-11-01T16:13:32.1549717Z  else: 2024-11-01T16:13:32.1550245Z  prefixes.append(label) 2024-11-01T16:13:32.1550794Z  2024-11-01T16:13:32.1551178Z  if len(prefixes) > 1: 2024-11-01T16:13:32.1551710Z  log.error( 2024-11-01T16:13:32.1553007Z  f"Only a fleet and one other experiment can be enabled for a job at any time. Enabling {prefixes[0]} and ignoring the rest, which are {', '.join(prefixes[1:])}" 2024-11-01T16:13:32.1554373Z  ) 2024-11-01T16:13:32.1554853Z  prefixes = prefixes[:1] 2024-11-01T16:13:32.1555395Z  2024-11-01T16:13:32.1555794Z  # Fleet always comes first 2024-11-01T16:13:32.1556373Z  if fleet_prefix: 2024-11-01T16:13:32.1557078Z  prefixes.insert(0, fleet_prefix) 2024-11-01T16:13:32.1557662Z  2024-11-01T16:13:32.1558198Z  return ".".join(prefixes) + "." if prefixes else "" 2024-11-01T16:13:32.1558870Z  2024-11-01T16:13:32.1559211Z  2024-11-01T16:13:32.1559947Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-11-01T16:13:32.1560841Z  """ 2024-11-01T16:13:32.1561548Z  Gets the first comment of the issue, which contains the desired rollout state. 2024-11-01T16:13:32.1562447Z  2024-11-01T16:13:32.1563083Z  The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-11-01T16:13:32.1564015Z  """ 2024-11-01T16:13:32.1564541Z  gh = get_gh_client(github_token) 2024-11-01T16:13:32.1565146Z  issue = get_issue(gh, repo, issue_num) 2024-11-01T16:13:32.1565927Z  return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-11-01T16:13:32.1566681Z  2024-11-01T16:13:32.1566984Z  2024-11-01T16:13:32.1567365Z def main() -> None: 2024-11-01T16:13:32.1567904Z  args = parse_args() 2024-11-01T16:13:32.1568544Z  2024-11-01T16:13:32.1569162Z  runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-11-01T16:13:32.1569867Z  2024-11-01T16:13:32.1570199Z  try: 2024-11-01T16:13:32.1570738Z  rollout_state = get_rollout_state_from_issue( 2024-11-01T16:13:32.1571672Z  args.github_token, args.github_issue_repo, args.github_issue 2024-11-01T16:13:32.1572375Z  ) 2024-11-01T16:13:32.1572775Z  2024-11-01T16:13:32.1573285Z  username = get_potential_pr_author( 2024-11-01T16:13:32.1573865Z  args.github_token, 2024-11-01T16:13:32.1574423Z  args.github_repo, 2024-11-01T16:13:32.1575035Z  args.github_actor, 2024-11-01T16:13:32.1575607Z  args.github_ref_type, 2024-11-01T16:13:32.1576140Z  args.github_branch, 2024-11-01T16:13:32.1576909Z  ) 2024-11-01T16:13:32.1577312Z  2024-11-01T16:13:32.1577822Z  is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-11-01T16:13:32.1578597Z  2024-11-01T16:13:32.1579052Z  runner_label_prefix = get_runner_prefix( 2024-11-01T16:13:32.1579640Z  rollout_state, 2024-11-01T16:13:32.1580309Z  (args.github_issue_owner, username), 2024-11-01T16:13:32.1580938Z  args.github_branch, 2024-11-01T16:13:32.1581488Z  args.eligible_experiments, 2024-11-01T16:13:32.1582137Z  is_canary, 2024-11-01T16:13:32.1582593Z  ) 2024-11-01T16:13:32.1582942Z  2024-11-01T16:13:32.1583408Z  except Exception as e: 2024-11-01T16:13:32.1583922Z  log.error( 2024-11-01T16:13:32.1584716Z  f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-11-01T16:13:32.1585697Z  ) 2024-11-01T16:13:32.1586076Z  2024-11-01T16:13:32.1586621Z  set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-11-01T16:13:32.1587434Z  2024-11-01T16:13:32.1587772Z  2024-11-01T16:13:32.1588119Z if __name__ == "__main__": 2024-11-01T16:13:32.1588682Z  main() 2024-11-01T16:13:32.1589077Z  2024-11-01T16:13:32.1589399Z EOF 2024-11-01T16:13:32.1589820Z  2024-11-01T16:13:32.1590204Z cat runner_determinator.py 2024-11-01T16:13:32.2040703Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:32.2041227Z env: 2024-11-01T16:13:32.2042028Z GITHUB_TOKEN: *** 2024-11-01T16:13:32.2042450Z ISSUE_NUMBER: 5132 2024-11-01T16:13:32.2043166Z TRIGGERING_ACTOR: pytorch-bot[bot] 2024-11-01T16:13:32.2043826Z ISSUE_OWNER: 2024-11-01T16:13:32.2044201Z CHECK_EXPERIMENTS: 2024-11-01T16:13:32.2044653Z ##[endgroup] 2024-11-01T16:13:32.2470067Z # flake8: noqa: G004 2024-11-01T16:13:32.2470383Z 2024-11-01T16:13:32.2472097Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-11-01T16:13:32.2473219Z # must be kept in sync. You can do it easily by running the following command: 2024-11-01T16:13:32.2474157Z # python .github/scripts/update_runner_determinator.py 2024-11-01T16:13:32.2474623Z 2024-11-01T16:13:32.2474862Z """ 2024-11-01T16:13:32.2475429Z This runner determinator is used to determine which set of runners to run a 2024-11-01T16:13:32.2476431Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-11-01T16:13:32.2477595Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-11-01T16:13:32.2478488Z of which runners should be used to run which job. 2024-11-01T16:13:32.2478921Z 2024-11-01T16:13:32.2479373Z The configuration has two parts, the settings and a list of opted-in users, 2024-11-01T16:13:32.2480481Z separated by a line containing "---". If the line is not present, the 2024-11-01T16:13:32.2481450Z settings are considered to be empty with only the second part, the user 2024-11-01T16:13:32.2482157Z list, defined. 2024-11-01T16:13:32.2482477Z 2024-11-01T16:13:32.2482881Z The first part is a YAML block that defines the rollout settings. This can be 2024-11-01T16:13:32.2483932Z used to define any settings that are needed to determine which runners to use. 2024-11-01T16:13:32.2484864Z It's fields are defined by the RolloutSettings class below. 2024-11-01T16:13:32.2485451Z 2024-11-01T16:13:32.2485858Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-11-01T16:13:32.2486868Z The user list is also a comma separated list of additional features or 2024-11-01T16:13:32.2487669Z experiments which the user could be opted in to. 2024-11-01T16:13:32.2488155Z 2024-11-01T16:13:32.2488561Z The user list has the following rules: 2024-11-01T16:13:32.2488999Z 2024-11-01T16:13:32.2489624Z - Users are GitHub usernames, which must start with the @ prefix 2024-11-01T16:13:32.2490623Z - Each user is also a comma-separated list of features/experiments to enable 2024-11-01T16:13:32.2491598Z - A "#" prefix opts the user out of all experiments 2024-11-01T16:13:32.2492057Z 2024-11-01T16:13:32.2492208Z Example config: 2024-11-01T16:13:32.2492672Z # A list of experiments that can be opted into. 2024-11-01T16:13:32.2493514Z # This defines the behavior they'll induce when opted into. 2024-11-01T16:13:32.2494182Z # Expected syntax is: 2024-11-01T16:13:32.2494867Z # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-11-01T16:13:32.2496023Z # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-11-01T16:13:32.2496746Z 2024-11-01T16:13:32.2496897Z experiments: 2024-11-01T16:13:32.2497266Z lf: 2024-11-01T16:13:32.2497715Z rollout_percent: 25 2024-11-01T16:13:32.2498142Z all_branches: false 2024-11-01T16:13:32.2498596Z default: true 2024-11-01T16:13:32.2499079Z --- 2024-11-01T16:13:32.2499259Z 2024-11-01T16:13:32.2499423Z # Opt-ins: 2024-11-01T16:13:32.2500074Z # Users can opt into the LF fleet by adding their GitHub username to this list 2024-11-01T16:13:32.2501165Z # and specifying experiments to enable in a comma-separated list. 2024-11-01T16:13:32.2501898Z # Experiments should be from the above list. 2024-11-01T16:13:32.2502344Z 2024-11-01T16:13:32.2502495Z @User1,lf,split_build 2024-11-01T16:13:32.2502978Z @User2,lf 2024-11-01T16:13:32.2503312Z @User3,split_build 2024-11-01T16:13:32.2503730Z """ 2024-11-01T16:13:32.2503962Z 2024-11-01T16:13:32.2504135Z import logging 2024-11-01T16:13:32.2504463Z import os 2024-11-01T16:13:32.2504823Z import random 2024-11-01T16:13:32.2505440Z from argparse import ArgumentParser 2024-11-01T16:13:32.2505974Z from logging import LogRecord 2024-11-01T16:13:32.2506677Z from typing import Any, Dict, FrozenSet, Iterable, List, NamedTuple, Tuple 2024-11-01T16:13:32.2507347Z 2024-11-01T16:13:32.2507514Z import yaml 2024-11-01T16:13:32.2507873Z from github import Auth, Github 2024-11-01T16:13:32.2508371Z from github.Issue import Issue 2024-11-01T16:13:32.2508735Z 2024-11-01T16:13:32.2508740Z 2024-11-01T16:13:32.2508978Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-11-01T16:13:32.2509694Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-11-01T16:13:32.2510633Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-11-01T16:13:32.2511447Z 2024-11-01T16:13:32.2511717Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-11-01T16:13:32.2512353Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-11-01T16:13:32.2512868Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-11-01T16:13:32.2513324Z 2024-11-01T16:13:32.2513335Z 2024-11-01T16:13:32.2513536Z SETTING_EXPERIMENTS = "experiments" 2024-11-01T16:13:32.2513870Z 2024-11-01T16:13:32.2514061Z LF_FLEET_EXPERIMENT = "lf" 2024-11-01T16:13:32.2514484Z CANARY_FLEET_SUFFIX = ".c" 2024-11-01T16:13:32.2514872Z 2024-11-01T16:13:32.2514878Z 2024-11-01T16:13:32.2515046Z class Experiment(NamedTuple): 2024-11-01T16:13:32.2515520Z rollout_perc: float = ( 2024-11-01T16:13:32.2516226Z 0 # Percentage of workflows to experiment on when user is not opted-in. 2024-11-01T16:13:32.2517032Z ) 2024-11-01T16:13:32.2517384Z all_branches: bool = ( 2024-11-01T16:13:32.2518013Z False # If True, the experiment is also enabled on the exception branches 2024-11-01T16:13:32.2518819Z ) 2024-11-01T16:13:32.2519168Z default: bool = ( 2024-11-01T16:13:32.2519729Z True # If True, the experiment is enabled by default for all queries 2024-11-01T16:13:32.2520517Z ) 2024-11-01T16:13:32.2520684Z 2024-11-01T16:13:32.2520880Z # Add more fields as needed 2024-11-01T16:13:32.2521184Z 2024-11-01T16:13:32.2521189Z 2024-11-01T16:13:32.2521458Z class Settings(NamedTuple): 2024-11-01T16:13:32.2521860Z """ 2024-11-01T16:13:32.2522460Z Settings for the experiments that can be opted into. 2024-11-01T16:13:32.2523146Z """ 2024-11-01T16:13:32.2523321Z 2024-11-01T16:13:32.2523509Z experiments: Dict[str, Experiment] = {} 2024-11-01T16:13:32.2523914Z 2024-11-01T16:13:32.2523919Z 2024-11-01T16:13:32.2524125Z class ColorFormatter(logging.Formatter): 2024-11-01T16:13:32.2524838Z """Color codes the log messages based on the log level""" 2024-11-01T16:13:32.2525301Z 2024-11-01T16:13:32.2525435Z COLORS = { 2024-11-01T16:13:32.2525855Z "WARNING": "\033[33m", # Yellow 2024-11-01T16:13:32.2526458Z "ERROR": "\033[31m", # Red 2024-11-01T16:13:32.2526922Z "CRITICAL": "\033[31m", # Red 2024-11-01T16:13:32.2527438Z "INFO": "\033[0m", # Reset 2024-11-01T16:13:32.2527975Z "DEBUG": "\033[0m", # Reset 2024-11-01T16:13:32.2528631Z } 2024-11-01T16:13:32.2528873Z 2024-11-01T16:13:32.2529152Z def format(self, record: LogRecord) -> str: 2024-11-01T16:13:32.2530153Z log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-11-01T16:13:32.2530986Z record.msg = f"{log_color}{record.msg}\033[0m" 2024-11-01T16:13:32.2531615Z return super().format(record) 2024-11-01T16:13:32.2531944Z 2024-11-01T16:13:32.2531985Z 2024-11-01T16:13:32.2532225Z handler = logging.StreamHandler() 2024-11-01T16:13:32.2533037Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-11-01T16:13:32.2533613Z 2024-11-01T16:13:32.2533848Z log = logging.getLogger(os.path.basename(__file__)) 2024-11-01T16:13:32.2534545Z log.addHandler(handler) 2024-11-01T16:13:32.2535005Z log.setLevel(logging.INFO) 2024-11-01T16:13:32.2535277Z 2024-11-01T16:13:32.2535281Z 2024-11-01T16:13:32.2535560Z def set_github_output(key: str, value: str) -> None: 2024-11-01T16:13:32.2536206Z """ 2024-11-01T16:13:32.2536896Z Defines outputs of the github action that invokes this script 2024-11-01T16:13:32.2537531Z """ 2024-11-01T16:13:32.2537983Z if not GITHUB_OUTPUT: 2024-11-01T16:13:32.2539304Z # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-11-01T16:13:32.2540548Z log.warning( 2024-11-01T16:13:32.2541578Z "No env var found for GITHUB_OUTPUT, you must be running this code locally. Falling back to the deprecated print method." 2024-11-01T16:13:32.2542622Z ) 2024-11-01T16:13:32.2565418Z print(f"::set-output name={key}::{value}") 2024-11-01T16:13:32.2566112Z return 2024-11-01T16:13:32.2566377Z 2024-11-01T16:13:32.2566561Z with open(GITHUB_OUTPUT, "a") as f: 2024-11-01T16:13:32.2567257Z log.info(f"Setting output: {key}='{value}'") 2024-11-01T16:13:32.2568020Z f.write(f"{key}={value}\n") 2024-11-01T16:13:32.2568603Z 2024-11-01T16:13:32.2568627Z 2024-11-01T16:13:32.2569037Z def _str_comma_separated_to_set(value: str) -> FrozenSet[str]: 2024-11-01T16:13:32.2569752Z return frozenset( 2024-11-01T16:13:32.2570538Z filter(lambda itm: itm != "", map(str.strip, value.strip(" \n\t").split(","))) 2024-11-01T16:13:32.2571271Z ) 2024-11-01T16:13:32.2571499Z 2024-11-01T16:13:32.2571505Z 2024-11-01T16:13:32.2571698Z def parse_args() -> Any: 2024-11-01T16:13:32.2572332Z parser = ArgumentParser("Get dynamic rollout settings") 2024-11-01T16:13:32.2573317Z parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-11-01T16:13:32.2574131Z parser.add_argument( 2024-11-01T16:13:32.2574679Z "--github-issue-repo", 2024-11-01T16:13:32.2575136Z type=str, 2024-11-01T16:13:32.2575519Z required=False, 2024-11-01T16:13:32.2576065Z default="pytorch/test-infra", 2024-11-01T16:13:32.2576608Z help="GitHub repo to get the issue", 2024-11-01T16:13:32.2577137Z ) 2024-11-01T16:13:32.2577569Z parser.add_argument( 2024-11-01T16:13:32.2578010Z "--github-repo", 2024-11-01T16:13:32.2578421Z type=str, 2024-11-01T16:13:32.2579098Z required=True, 2024-11-01T16:13:32.2579547Z help="GitHub repo where CI is running", 2024-11-01T16:13:32.2580084Z ) 2024-11-01T16:13:32.2580511Z parser.add_argument( 2024-11-01T16:13:32.2581177Z "--github-issue", type=int, required=True, help="GitHub issue number" 2024-11-01T16:13:32.2581876Z ) 2024-11-01T16:13:32.2582317Z parser.add_argument( 2024-11-01T16:13:32.2583004Z "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-11-01T16:13:32.2583725Z ) 2024-11-01T16:13:32.2584155Z parser.add_argument( 2024-11-01T16:13:32.2584845Z "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-11-01T16:13:32.2585598Z ) 2024-11-01T16:13:32.2586016Z parser.add_argument( 2024-11-01T16:13:32.2586738Z "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-11-01T16:13:32.2587510Z ) 2024-11-01T16:13:32.2587917Z parser.add_argument( 2024-11-01T16:13:32.2588359Z "--github-ref-type", 2024-11-01T16:13:32.2588817Z type=str, 2024-11-01T16:13:32.2589261Z required=True, 2024-11-01T16:13:32.2589719Z help="Current GitHub ref type, branch or tag", 2024-11-01T16:13:32.2590306Z ) 2024-11-01T16:13:32.2590715Z parser.add_argument( 2024-11-01T16:13:32.2591166Z "--eligible-experiments", 2024-11-01T16:13:32.2591703Z type=_str_comma_separated_to_set, 2024-11-01T16:13:32.2592302Z required=False, 2024-11-01T16:13:32.2592678Z default="", 2024-11-01T16:13:32.2593626Z help="comma separated list of experiments to check, if omitted all experiments marked with default=True are checked", 2024-11-01T16:13:32.2594715Z ) 2024-11-01T16:13:32.2594884Z 2024-11-01T16:13:32.2595064Z return parser.parse_args() 2024-11-01T16:13:32.2595400Z 2024-11-01T16:13:32.2595550Z 2024-11-01T16:13:32.2595829Z def get_gh_client(github_token: str) -> Github: 2024-11-01T16:13:32.2596516Z auth = Auth.Token(github_token) 2024-11-01T16:13:32.2597055Z return Github(auth=auth) 2024-11-01T16:13:32.2597343Z 2024-11-01T16:13:32.2597348Z 2024-11-01T16:13:32.2597702Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-11-01T16:13:32.2598466Z repo = gh.get_repo(repo) 2024-11-01T16:13:32.2598966Z return repo.get_issue(number=issue_num) 2024-11-01T16:13:32.2599336Z 2024-11-01T16:13:32.2599341Z 2024-11-01T16:13:32.2599496Z def get_potential_pr_author( 2024-11-01T16:13:32.2600261Z github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-11-01T16:13:32.2601014Z ) -> str: 2024-11-01T16:13:32.2601529Z # If the trigger was a new tag added by a bot, this is a ciflow case 2024-11-01T16:13:32.2602587Z # Fetch the actual username from the original PR. The PR number is 2024-11-01T16:13:32.2603450Z # embedded in the tag name: ciflow// 2024-11-01T16:13:32.2603890Z 2024-11-01T16:13:32.2604084Z gh = get_gh_client(github_token) 2024-11-01T16:13:32.2604502Z 2024-11-01T16:13:32.2604820Z if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-11-01T16:13:32.2605478Z split_tag = ref_name.split("/") 2024-11-01T16:13:32.2606006Z if ( 2024-11-01T16:13:32.2606412Z len(split_tag) == 3 2024-11-01T16:13:32.2606901Z and split_tag[0] == "ciflow" 2024-11-01T16:13:32.2607458Z and split_tag[2].isnumeric() 2024-11-01T16:13:32.2608005Z ): 2024-11-01T16:13:32.2608588Z pr_number = split_tag[2] 2024-11-01T16:13:32.2609121Z try: 2024-11-01T16:13:32.2609596Z repository = gh.get_repo(repo) 2024-11-01T16:13:32.2610260Z pull = repository.get_pull(number=int(pr_number)) 2024-11-01T16:13:32.2610916Z except Exception as e: 2024-11-01T16:13:32.2611492Z raise Exception( # noqa: TRY002 2024-11-01T16:13:32.2612232Z f"issue with pull request {pr_number} from repo {repository}" 2024-11-01T16:13:32.2612938Z ) from e 2024-11-01T16:13:32.2613590Z return pull.user.login 2024-11-01T16:13:32.2614225Z # In all other cases, return the original input username 2024-11-01T16:13:32.2614862Z return username 2024-11-01T16:13:32.2615154Z 2024-11-01T16:13:32.2615159Z 2024-11-01T16:13:32.2615427Z def is_exception_branch(branch: str) -> bool: 2024-11-01T16:13:32.2615988Z """ 2024-11-01T16:13:32.2616737Z Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-11-01T16:13:32.2617619Z """ 2024-11-01T16:13:32.2618211Z return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-11-01T16:13:32.2618775Z 2024-11-01T16:13:32.2618816Z 2024-11-01T16:13:32.2619020Z def load_yaml(yaml_text: str) -> Any: 2024-11-01T16:13:32.2619601Z try: 2024-11-01T16:13:32.2619968Z data = yaml.safe_load(yaml_text) 2024-11-01T16:13:32.2620478Z return data 2024-11-01T16:13:32.2620979Z except yaml.YAMLError as exc: 2024-11-01T16:13:32.2621475Z log.exception("Error loading YAML") 2024-11-01T16:13:32.2622010Z raise 2024-11-01T16:13:32.2622268Z 2024-11-01T16:13:32.2622274Z 2024-11-01T16:13:32.2622809Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-11-01T16:13:32.2623553Z """ 2024-11-01T16:13:32.2624213Z Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-11-01T16:13:32.2624943Z 2024-11-01T16:13:32.2625417Z If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:32.2626210Z and the text below is the list of opted in users. 2024-11-01T16:13:32.2626674Z 2024-11-01T16:13:32.2627142Z If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-11-01T16:13:32.2627986Z """ 2024-11-01T16:13:32.2628580Z rollout_state_parts = rollout_state.split("---") 2024-11-01T16:13:32.2629233Z if len(rollout_state_parts) >= 2: 2024-11-01T16:13:32.2629921Z return rollout_state_parts[0], rollout_state_parts[1] 2024-11-01T16:13:32.2630514Z else: 2024-11-01T16:13:32.2630904Z return "", rollout_state 2024-11-01T16:13:32.2631309Z 2024-11-01T16:13:32.2631315Z 2024-11-01T16:13:32.2631491Z class UserOptins(Dict[str, List[str]]): 2024-11-01T16:13:32.2631998Z """ 2024-11-01T16:13:32.2632519Z Dictionary of users with a list of features they have opted into 2024-11-01T16:13:32.2633255Z """ 2024-11-01T16:13:32.2633429Z 2024-11-01T16:13:32.2633434Z 2024-11-01T16:13:32.2633880Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-11-01T16:13:32.2634537Z """ 2024-11-01T16:13:32.2635467Z Parse the user opt-in text into a key value pair of username and the list of features they have opted into 2024-11-01T16:13:32.2636269Z 2024-11-01T16:13:32.2637114Z Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-11-01T16:13:32.2638248Z - Example line: "@User1,lf,split_build" 2024-11-01T16:13:32.2639109Z - A "#" prefix indicates the user is opted out of all experiments 2024-11-01T16:13:32.2639686Z 2024-11-01T16:13:32.2639691Z 2024-11-01T16:13:32.2639814Z """ 2024-11-01T16:13:32.2640242Z optins = UserOptins() 2024-11-01T16:13:32.2640708Z for user in user_optin_text.split("\n"): 2024-11-01T16:13:32.2641335Z user = user.strip("\r\n\t -") 2024-11-01T16:13:32.2641961Z if not user or not user.startswith("@"): 2024-11-01T16:13:32.2642507Z # Not a valid user. Skip 2024-11-01T16:13:32.2643014Z continue 2024-11-01T16:13:32.2643240Z 2024-11-01T16:13:32.2643466Z if user: 2024-11-01T16:13:32.2643869Z usr_name = user.split(",")[0].strip("@") 2024-11-01T16:13:32.2644646Z optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-11-01T16:13:32.2645178Z 2024-11-01T16:13:32.2645416Z return optins 2024-11-01T16:13:32.2645635Z 2024-11-01T16:13:32.2645640Z 2024-11-01T16:13:32.2646163Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-11-01T16:13:32.2646818Z """ 2024-11-01T16:13:32.2647505Z Parse the experiments from the issue body into a list of ExperimentSettings 2024-11-01T16:13:32.2648252Z """ 2024-11-01T16:13:32.2648854Z try: 2024-11-01T16:13:32.2649347Z if settings_text: 2024-11-01T16:13:32.2650132Z # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-11-01T16:13:32.2651012Z # for easy reading 2024-11-01T16:13:32.2652081Z # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-11-01T16:13:32.2653106Z # the backtick character in shell commands. 2024-11-01T16:13:32.2653729Z backtick = chr(96) # backtick character 2024-11-01T16:13:32.2654515Z settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-11-01T16:13:32.2655230Z settings = load_yaml(settings_text) 2024-11-01T16:13:32.2655608Z 2024-11-01T16:13:32.2656044Z # For now we just load experiments. We can expand this if/when we add more settings 2024-11-01T16:13:32.2656953Z experiments = {} 2024-11-01T16:13:32.2657234Z 2024-11-01T16:13:32.2657639Z for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-11-01T16:13:32.2658359Z valid_settings = {} 2024-11-01T16:13:32.2658970Z for setting in exp_settings: 2024-11-01T16:13:32.2659579Z if setting not in Experiment._fields: 2024-11-01T16:13:32.2660124Z log.warning( 2024-11-01T16:13:32.2660962Z f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-11-01T16:13:32.2661722Z ) 2024-11-01T16:13:32.2662303Z else: 2024-11-01T16:13:32.2662894Z valid_settings[setting] = exp_settings[setting] 2024-11-01T16:13:32.2663385Z 2024-11-01T16:13:32.2663650Z experiments[exp_name] = Experiment(**valid_settings) 2024-11-01T16:13:32.2664327Z return Settings(experiments) 2024-11-01T16:13:32.2664677Z 2024-11-01T16:13:32.2664884Z except Exception: 2024-11-01T16:13:32.2665382Z log.exception("Failed to parse settings") 2024-11-01T16:13:32.2665779Z 2024-11-01T16:13:32.2665955Z return Settings() 2024-11-01T16:13:32.2666190Z 2024-11-01T16:13:32.2666195Z 2024-11-01T16:13:32.2666550Z def parse_settings(rollout_state: str) -> Settings: 2024-11-01T16:13:32.2667152Z """ 2024-11-01T16:13:32.2667583Z Parse settings, if any, from the rollout state. 2024-11-01T16:13:32.2668046Z 2024-11-01T16:13:32.2668578Z If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:32.2669409Z and the text below is the list of opted in users. 2024-11-01T16:13:32.2669870Z 2024-11-01T16:13:32.2670381Z If it doesn't contain "---" then the settings are empty and the default values are used. 2024-11-01T16:13:32.2671274Z """ 2024-11-01T16:13:32.2671820Z settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:32.2672613Z return parse_settings_from_text(settings_text) 2024-11-01T16:13:32.2673020Z 2024-11-01T16:13:32.2673025Z 2024-11-01T16:13:32.2673415Z def parse_users(rollout_state: str) -> UserOptins: 2024-11-01T16:13:32.2673961Z """ 2024-11-01T16:13:32.2674336Z Parse users from the rollout state. 2024-11-01T16:13:32.2674684Z 2024-11-01T16:13:32.2674918Z """ 2024-11-01T16:13:32.2675416Z _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:32.2676191Z return parse_user_opt_in_from_text(users_text) 2024-11-01T16:13:32.2676704Z 2024-11-01T16:13:32.2676710Z 2024-11-01T16:13:32.2677232Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-11-01T16:13:32.2678044Z """ 2024-11-01T16:13:32.2678428Z Check if a user is opted into an experiment 2024-11-01T16:13:32.2679236Z """ 2024-11-01T16:13:32.2679685Z return experiment_name in user_optins.get(user, []) 2024-11-01T16:13:32.2680122Z 2024-11-01T16:13:32.2680127Z 2024-11-01T16:13:32.2680290Z def get_runner_prefix( 2024-11-01T16:13:32.2680780Z rollout_state: str, 2024-11-01T16:13:32.2681225Z workflow_requestors: Iterable[str], 2024-11-01T16:13:32.2681722Z branch: str, 2024-11-01T16:13:32.2682276Z eligible_experiments: FrozenSet[str] = frozenset(), 2024-11-01T16:13:32.2682895Z is_canary: bool = False, 2024-11-01T16:13:32.2683346Z ) -> str: 2024-11-01T16:13:32.2683831Z settings = parse_settings(rollout_state) 2024-11-01T16:13:32.2684427Z user_optins = parse_users(rollout_state) 2024-11-01T16:13:32.2684829Z 2024-11-01T16:13:32.2684974Z fleet_prefix = "" 2024-11-01T16:13:32.2685448Z prefixes = [] 2024-11-01T16:13:32.2686111Z for experiment_name, experiment_settings in settings.experiments.items(): 2024-11-01T16:13:32.2687077Z if not experiment_settings.all_branches and is_exception_branch(branch): 2024-11-01T16:13:32.2687893Z log.info( 2024-11-01T16:13:32.2689248Z f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-11-01T16:13:32.2690073Z ) 2024-11-01T16:13:32.2690522Z continue 2024-11-01T16:13:32.2690756Z 2024-11-01T16:13:32.2690985Z if eligible_experiments: 2024-11-01T16:13:32.2691527Z if experiment_name not in eligible_experiments: 2024-11-01T16:13:32.2692269Z exp_list = ", ".join(eligible_experiments) 2024-11-01T16:13:32.2692875Z log.info( 2024-11-01T16:13:32.2693813Z f"Skipping experiment '{experiment_name}', as it is not in the eligible_experiments list: {exp_list}" 2024-11-01T16:13:32.2694761Z ) 2024-11-01T16:13:32.2695308Z continue 2024-11-01T16:13:32.2695793Z elif not experiment_settings.default: 2024-11-01T16:13:32.2696401Z log.info( 2024-11-01T16:13:32.2697155Z f"Skipping experiment '{experiment_name}', as it is not a default experiment" 2024-11-01T16:13:32.2697926Z ) 2024-11-01T16:13:32.2698335Z continue 2024-11-01T16:13:32.2698599Z 2024-11-01T16:13:32.2698869Z # Is any workflow_requestor opted in to this experiment? 2024-11-01T16:13:32.2699504Z opted_in_users = [ 2024-11-01T16:13:32.2699985Z requestor 2024-11-01T16:13:32.2700445Z for requestor in workflow_requestors 2024-11-01T16:13:32.2701180Z if is_user_opted_in(requestor, user_optins, experiment_name) 2024-11-01T16:13:32.2701866Z ] 2024-11-01T16:13:32.2702084Z 2024-11-01T16:13:32.2702221Z enabled = False 2024-11-01T16:13:32.2702660Z if opted_in_users: 2024-11-01T16:13:32.2703148Z log.info( 2024-11-01T16:13:32.2703849Z f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-11-01T16:13:32.2704598Z ) 2024-11-01T16:13:32.2705014Z enabled = True 2024-11-01T16:13:32.2705312Z 2024-11-01T16:13:32.2705514Z elif experiment_settings.rollout_perc: 2024-11-01T16:13:32.2706462Z # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-11-01T16:13:32.2707562Z if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-11-01T16:13:32.2708263Z log.info( 2024-11-01T16:13:32.2709200Z f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-11-01T16:13:32.2710253Z ) 2024-11-01T16:13:32.2710601Z enabled = True 2024-11-01T16:13:32.2710936Z 2024-11-01T16:13:32.2711076Z if enabled: 2024-11-01T16:13:32.2711555Z label = experiment_name 2024-11-01T16:13:32.2712109Z if experiment_name == LF_FLEET_EXPERIMENT: 2024-11-01T16:13:32.2713021Z # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-11-01T16:13:32.2714308Z # - If it's enabled, then we always list it's prefix first 2024-11-01T16:13:32.2715232Z # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-11-01T16:13:32.2715967Z if is_canary: 2024-11-01T16:13:32.2716555Z label += CANARY_FLEET_SUFFIX 2024-11-01T16:13:32.2717083Z fleet_prefix = label 2024-11-01T16:13:32.2717571Z else: 2024-11-01T16:13:32.2718056Z prefixes.append(label) 2024-11-01T16:13:32.2718404Z 2024-11-01T16:13:32.2718552Z if len(prefixes) > 1: 2024-11-01T16:13:32.2718978Z log.error( 2024-11-01T16:13:32.2720364Z f"Only a fleet and one other experiment can be enabled for a job at any time. Enabling {prefixes[0]} and ignoring the rest, which are {', '.join(prefixes[1:])}" 2024-11-01T16:13:32.2721620Z ) 2024-11-01T16:13:32.2721998Z prefixes = prefixes[:1] 2024-11-01T16:13:32.2722421Z 2024-11-01T16:13:32.2722580Z # Fleet always comes first 2024-11-01T16:13:32.2723046Z if fleet_prefix: 2024-11-01T16:13:32.2723450Z prefixes.insert(0, fleet_prefix) 2024-11-01T16:13:32.2723927Z 2024-11-01T16:13:32.2724171Z return ".".join(prefixes) + "." if prefixes else "" 2024-11-01T16:13:32.2724604Z 2024-11-01T16:13:32.2724609Z 2024-11-01T16:13:32.2725150Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-11-01T16:13:32.2725926Z """ 2024-11-01T16:13:32.2726628Z Gets the first comment of the issue, which contains the desired rollout state. 2024-11-01T16:13:32.2727236Z 2024-11-01T16:13:32.2727735Z The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-11-01T16:13:32.2728700Z """ 2024-11-01T16:13:32.2729321Z gh = get_gh_client(github_token) 2024-11-01T16:13:32.2729889Z issue = get_issue(gh, repo, issue_num) 2024-11-01T16:13:32.2730539Z return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-11-01T16:13:32.2731118Z 2024-11-01T16:13:32.2731124Z 2024-11-01T16:13:32.2731307Z def main() -> None: 2024-11-01T16:13:32.2731726Z args = parse_args() 2024-11-01T16:13:32.2731978Z 2024-11-01T16:13:32.2732284Z runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-11-01T16:13:32.2732674Z 2024-11-01T16:13:32.2732799Z try: 2024-11-01T16:13:32.2733236Z rollout_state = get_rollout_state_from_issue( 2024-11-01T16:13:32.2734044Z args.github_token, args.github_issue_repo, args.github_issue 2024-11-01T16:13:32.2734675Z ) 2024-11-01T16:13:32.2734910Z 2024-11-01T16:13:32.2735092Z username = get_potential_pr_author( 2024-11-01T16:13:32.2735699Z args.github_token, 2024-11-01T16:13:32.2736131Z args.github_repo, 2024-11-01T16:13:32.2736609Z args.github_actor, 2024-11-01T16:13:32.2737139Z args.github_ref_type, 2024-11-01T16:13:32.2737590Z args.github_branch, 2024-11-01T16:13:32.2738056Z ) 2024-11-01T16:13:32.2738240Z 2024-11-01T16:13:32.2738684Z is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-11-01T16:13:32.2739163Z 2024-11-01T16:13:32.2739363Z runner_label_prefix = get_runner_prefix( 2024-11-01T16:13:32.2739944Z rollout_state, 2024-11-01T16:13:32.2740486Z (args.github_issue_owner, username), 2024-11-01T16:13:32.2741032Z args.github_branch, 2024-11-01T16:13:32.2741529Z args.eligible_experiments, 2024-11-01T16:13:32.2742093Z is_canary, 2024-11-01T16:13:32.2742467Z ) 2024-11-01T16:13:32.2742683Z 2024-11-01T16:13:32.2742841Z except Exception as e: 2024-11-01T16:13:32.2743364Z log.error( 2024-11-01T16:13:32.2744072Z f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-11-01T16:13:32.2744890Z ) 2024-11-01T16:13:32.2745110Z 2024-11-01T16:13:32.2745498Z set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-11-01T16:13:32.2746204Z 2024-11-01T16:13:32.2746209Z 2024-11-01T16:13:32.2746389Z if __name__ == "__main__": 2024-11-01T16:13:32.2746779Z main() 2024-11-01T16:13:32.2747015Z 2024-11-01T16:13:32.2922533Z ##[group]Run python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-11-01T16:13:32.2923461Z python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-11-01T16:13:32.2981406Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:32.2981857Z env: 2024-11-01T16:13:32.2982601Z GITHUB_TOKEN: *** 2024-11-01T16:13:32.2983054Z ISSUE_NUMBER: 5132 2024-11-01T16:13:32.2983577Z TRIGGERING_ACTOR: pytorch-bot[bot] 2024-11-01T16:13:32.2984064Z ISSUE_OWNER: 2024-11-01T16:13:32.2984476Z CHECK_EXPERIMENTS: 2024-11-01T16:13:32.2984953Z ##[endgroup] 2024-11-01T16:13:32.7337670Z Defaulting to user installation because normal site-packages is not writeable 2024-11-01T16:13:33.1061071Z Collecting urllib3==1.26.18 2024-11-01T16:13:33.1849293Z Downloading urllib3-1.26.18-py2.py3-none-any.whl (143 kB) 2024-11-01T16:13:33.2184268Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 143.8/143.8 KB 4.6 MB/s eta 0:00:00 2024-11-01T16:13:33.2500294Z Collecting PyGithub==2.3.0 2024-11-01T16:13:33.2640623Z Downloading PyGithub-2.3.0-py3-none-any.whl (354 kB) 2024-11-01T16:13:33.2840314Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 354.4/354.4 KB 19.1 MB/s eta 0:00:00 2024-11-01T16:13:33.3267348Z Collecting Deprecated 2024-11-01T16:13:33.3411262Z Downloading Deprecated-1.2.14-py2.py3-none-any.whl (9.6 kB) 2024-11-01T16:13:33.3695304Z Collecting typing-extensions>=4.0.0 2024-11-01T16:13:33.3835349Z Downloading typing_extensions-4.12.2-py3-none-any.whl (37 kB) 2024-11-01T16:13:33.4224348Z Collecting pynacl>=1.4.0 2024-11-01T16:13:33.4372298Z Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) 2024-11-01T16:13:33.4588275Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 KB 43.7 MB/s eta 0:00:00 2024-11-01T16:13:33.4655387Z Requirement already satisfied: requests>=2.14.0 in /usr/lib/python3/dist-packages (from PyGithub==2.3.0) (2.25.1) 2024-11-01T16:13:33.4890916Z Collecting pyjwt[crypto]>=2.4.0 2024-11-01T16:13:33.5031196Z Downloading PyJWT-2.9.0-py3-none-any.whl (22 kB) 2024-11-01T16:13:33.5164906Z Requirement already satisfied: cryptography>=3.4.0 in /usr/lib/python3/dist-packages (from pyjwt[crypto]>=2.4.0->PyGithub==2.3.0) (3.4.8) 2024-11-01T16:13:33.7326203Z Collecting cffi>=1.4.1 2024-11-01T16:13:33.7470438Z Downloading cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (446 kB) 2024-11-01T16:13:33.7543674Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 446.2/446.2 KB 81.8 MB/s eta 0:00:00 2024-11-01T16:13:33.9272984Z Collecting wrapt<2,>=1.10 2024-11-01T16:13:33.9419112Z Downloading wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (80 kB) 2024-11-01T16:13:33.9462160Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.3/80.3 KB 30.3 MB/s eta 0:00:00 2024-11-01T16:13:33.9623491Z Collecting pycparser 2024-11-01T16:13:33.9815079Z Downloading pycparser-2.22-py3-none-any.whl (117 kB) 2024-11-01T16:13:33.9861507Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 117.6/117.6 KB 44.8 MB/s eta 0:00:00 2024-11-01T16:13:34.1718799Z Installing collected packages: wrapt, urllib3, typing-extensions, pyjwt, pycparser, Deprecated, cffi, pynacl, PyGithub 2024-11-01T16:13:34.6683841Z Successfully installed Deprecated-1.2.14 PyGithub-2.3.0 cffi-1.17.1 pycparser-2.22 pyjwt-2.9.0 pynacl-1.5.0 typing-extensions-4.12.2 urllib3-1.26.18 wrapt-1.16.0 2024-11-01T16:13:34.7381479Z ##[group]Run curr_branch="ciflow/trunk/138766" 2024-11-01T16:13:34.7382063Z curr_branch="ciflow/trunk/138766" 2024-11-01T16:13:34.7382618Z curr_ref_type="tag" 2024-11-01T16:13:34.7383078Z echo "Current branch is '$curr_branch'" 2024-11-01T16:13:34.7383483Z  2024-11-01T16:13:34.7383912Z python3 runner_determinator.py \ 2024-11-01T16:13:34.7384600Z  --github-token "$GITHUB_TOKEN" \ 2024-11-01T16:13:34.7385063Z  --github-issue "$ISSUE_NUMBER" \ 2024-11-01T16:13:34.7385599Z  --github-branch "$curr_branch" \ 2024-11-01T16:13:34.7386072Z  --github-actor "$TRIGGERING_ACTOR" \ 2024-11-01T16:13:34.7386584Z  --github-issue-owner "$ISSUE_OWNER" \ 2024-11-01T16:13:34.7387123Z  --github-ref-type "$curr_ref_type" \ 2024-11-01T16:13:34.7387643Z  --github-repo "$GITHUB_REPOSITORY" \ 2024-11-01T16:13:34.7388236Z  --eligible-experiments "$CHECK_EXPERIMENTS" \ 2024-11-01T16:13:34.7446184Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:34.7446680Z env: 2024-11-01T16:13:34.7447415Z GITHUB_TOKEN: *** 2024-11-01T16:13:34.7447782Z ISSUE_NUMBER: 5132 2024-11-01T16:13:34.7448216Z TRIGGERING_ACTOR: pytorch-bot[bot] 2024-11-01T16:13:34.7448902Z ISSUE_OWNER: 2024-11-01T16:13:34.7449242Z CHECK_EXPERIMENTS: 2024-11-01T16:13:34.7449648Z ##[endgroup] 2024-11-01T16:13:34.7526111Z Current branch is 'ciflow/trunk/138766' 2024-11-01T16:13:36.7806206Z INFO : Skipping experiment 'awsa100', as it is not a default experiment 2024-11-01T16:13:36.7807610Z INFO : Setting output: label-type='' 2024-11-01T16:13:36.8185726Z Evaluate and set job outputs 2024-11-01T16:13:36.8196905Z Cleaning up orphan processes