2024-11-01T16:13:28.1486747Z Current runner version: '2.320.0' 2024-11-01T16:13:28.1509988Z ##[group]Operating System 2024-11-01T16:13:28.1510609Z Ubuntu 2024-11-01T16:13:28.1510949Z 22.04.5 2024-11-01T16:13:28.1511315Z LTS 2024-11-01T16:13:28.1511674Z ##[endgroup] 2024-11-01T16:13:28.1512070Z ##[group]Runner Image 2024-11-01T16:13:28.1512587Z Image: ubuntu-22.04 2024-11-01T16:13:28.1513594Z Version: 20241015.1.0 2024-11-01T16:13:28.1514622Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20241015.1/images/ubuntu/Ubuntu2204-Readme.md 2024-11-01T16:13:28.1516166Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20241015.1 2024-11-01T16:13:28.1517003Z ##[endgroup] 2024-11-01T16:13:28.1517404Z ##[group]Runner Image Provisioner 2024-11-01T16:13:28.1517964Z 2.0.384.1 2024-11-01T16:13:28.1518270Z ##[endgroup] 2024-11-01T16:13:28.1533668Z ##[group]GITHUB_TOKEN Permissions 2024-11-01T16:13:28.1535363Z Actions: read 2024-11-01T16:13:28.1536056Z Attestations: read 2024-11-01T16:13:28.1536533Z Checks: read 2024-11-01T16:13:28.1536965Z Contents: read 2024-11-01T16:13:28.1537353Z Deployments: read 2024-11-01T16:13:28.1537734Z Discussions: read 2024-11-01T16:13:28.1538183Z Issues: read 2024-11-01T16:13:28.1538560Z Metadata: read 2024-11-01T16:13:28.1538901Z Packages: read 2024-11-01T16:13:28.1539340Z Pages: read 2024-11-01T16:13:28.1539728Z PullRequests: read 2024-11-01T16:13:28.1540119Z RepositoryProjects: read 2024-11-01T16:13:28.1540681Z SecurityEvents: read 2024-11-01T16:13:28.1541099Z Statuses: read 2024-11-01T16:13:28.1541439Z ##[endgroup] 2024-11-01T16:13:28.1544785Z Secret source: Actions 2024-11-01T16:13:28.1545382Z Prepare workflow directory 2024-11-01T16:13:28.2439705Z Prepare all required actions 2024-11-01T16:13:28.2602129Z Uses: pytorch/pytorch/.github/workflows/_runner-determinator.yml@refs/heads/main (33dce10ece5b38aa0ab76739b658cd980a6e3d8f) 2024-11-01T16:13:28.2607140Z ##[group] Inputs 2024-11-01T16:13:28.2607753Z check_experiments: 2024-11-01T16:13:28.2608213Z triggering_actor: c00w 2024-11-01T16:13:28.2608665Z issue_owner: c00w 2024-11-01T16:13:28.2609181Z curr_branch: gh/c00w/2/head 2024-11-01T16:13:28.2609660Z curr_ref_type: branch 2024-11-01T16:13:28.2610093Z issue_number: 5132 2024-11-01T16:13:28.2610580Z ##[endgroup] 2024-11-01T16:13:28.2611356Z Complete job name: get-label-type / runner-determinator 2024-11-01T16:13:28.3481464Z ##[group]Run cat < runner_determinator.py 2024-11-01T16:13:28.3483321Z cat < runner_determinator.py 2024-11-01T16:13:28.3483936Z # flake8: noqa: G004 2024-11-01T16:13:28.3484486Z  2024-11-01T16:13:28.3485269Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-11-01T16:13:28.3486512Z # must be kept in sync. You can do it easily by running the following command: 2024-11-01T16:13:28.3487577Z # python .github/scripts/update_runner_determinator.py 2024-11-01T16:13:28.3488270Z  2024-11-01T16:13:28.3488648Z """ 2024-11-01T16:13:28.3489365Z This runner determinator is used to determine which set of runners to run a 2024-11-01T16:13:28.3490479Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-11-01T16:13:28.3491783Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-11-01T16:13:28.3492754Z of which runners should be used to run which job. 2024-11-01T16:13:28.3493413Z  2024-11-01T16:13:28.3494136Z The configuration has two parts, the settings and a list of opted-in users, 2024-11-01T16:13:28.3495221Z separated by a line containing "---". If the line is not present, the 2024-11-01T16:13:28.3496327Z settings are considered to be empty with only the second part, the user 2024-11-01T16:13:28.3497191Z list, defined. 2024-11-01T16:13:28.3497610Z  2024-11-01T16:13:28.3498254Z The first part is a YAML block that defines the rollout settings. This can be 2024-11-01T16:13:28.3499760Z used to define any settings that are needed to determine which runners to use. 2024-11-01T16:13:28.3500833Z It's fields are defined by the RolloutSettings class below. 2024-11-01T16:13:28.3501512Z  2024-11-01T16:13:28.3502258Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-11-01T16:13:28.3503386Z The user list is also a comma separated list of additional features or 2024-11-01T16:13:28.3504296Z experiments which the user could be opted in to. 2024-11-01T16:13:28.3504953Z  2024-11-01T16:13:28.3505402Z The user list has the following rules: 2024-11-01T16:13:28.3505955Z  2024-11-01T16:13:28.3506560Z - Users are GitHub usernames, which must start with the @ prefix 2024-11-01T16:13:28.3507628Z - Each user is also a comma-separated list of features/experiments to enable 2024-11-01T16:13:28.3508590Z - A "#" prefix opts the user out of all experiments 2024-11-01T16:13:28.3509258Z  2024-11-01T16:13:28.3509643Z Example config: 2024-11-01T16:13:28.3510210Z  # A list of experiments that can be opted into. 2024-11-01T16:13:28.3511087Z  # This defines the behavior they'll induce when opted into. 2024-11-01T16:13:28.3511823Z  # Expected syntax is: 2024-11-01T16:13:28.3512636Z  # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-11-01T16:13:28.3514222Z  # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-11-01T16:13:28.3515100Z  2024-11-01T16:13:28.3515461Z  experiments: 2024-11-01T16:13:28.3515977Z  lf: 2024-11-01T16:13:28.3516366Z  rollout_percent: 25 2024-11-01T16:13:28.3516894Z  all_branches: false 2024-11-01T16:13:28.3517485Z  default: true 2024-11-01T16:13:28.3517920Z  --- 2024-11-01T16:13:28.3518302Z  2024-11-01T16:13:28.3518721Z  # Opt-ins: 2024-11-01T16:13:28.3519433Z  # Users can opt into the LF fleet by adding their GitHub username to this list 2024-11-01T16:13:28.3520719Z  # and specifying experiments to enable in a comma-separated list. 2024-11-01T16:13:28.3521721Z  # Experiments should be from the above list. 2024-11-01T16:13:28.3522302Z  2024-11-01T16:13:28.3522695Z  @User1,lf,split_build 2024-11-01T16:13:28.3523260Z  @User2,lf 2024-11-01T16:13:28.3523662Z  @User3,split_build 2024-11-01T16:13:28.3524151Z """ 2024-11-01T16:13:28.3524574Z  2024-11-01T16:13:28.3524926Z import logging 2024-11-01T16:13:28.3525363Z import os 2024-11-01T16:13:28.3525840Z import random 2024-11-01T16:13:28.3526311Z from argparse import ArgumentParser 2024-11-01T16:13:28.3526917Z from logging import LogRecord 2024-11-01T16:13:28.3527824Z from typing import Any, Dict, FrozenSet, Iterable, List, NamedTuple, Tuple 2024-11-01T16:13:28.3528604Z  2024-11-01T16:13:28.3528961Z import yaml 2024-11-01T16:13:28.3529550Z from github import Auth, Github 2024-11-01T16:13:28.3530170Z from github.Issue import Issue 2024-11-01T16:13:28.3530661Z  2024-11-01T16:13:28.3531079Z  2024-11-01T16:13:28.3531542Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-11-01T16:13:28.3532347Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-11-01T16:13:28.3533487Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-11-01T16:13:28.3534313Z  2024-11-01T16:13:28.3534787Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-11-01T16:13:28.3535508Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-11-01T16:13:28.3536309Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-11-01T16:13:28.3536897Z  2024-11-01T16:13:28.3537277Z  2024-11-01T16:13:28.3537689Z SETTING_EXPERIMENTS = "experiments" 2024-11-01T16:13:28.3538245Z  2024-11-01T16:13:28.3538648Z LF_FLEET_EXPERIMENT = "lf" 2024-11-01T16:13:28.3539171Z CANARY_FLEET_SUFFIX = ".c" 2024-11-01T16:13:28.3539664Z  2024-11-01T16:13:28.3540032Z  2024-11-01T16:13:28.3540417Z class Experiment(NamedTuple): 2024-11-01T16:13:28.3540994Z  rollout_perc: float = ( 2024-11-01T16:13:28.3541818Z  0 # Percentage of workflows to experiment on when user is not opted-in. 2024-11-01T16:13:28.3542612Z  ) 2024-11-01T16:13:28.3543026Z  all_branches: bool = ( 2024-11-01T16:13:28.3543849Z  False # If True, the experiment is also enabled on the exception branches 2024-11-01T16:13:28.3544660Z  ) 2024-11-01T16:13:28.3545140Z  default: bool = ( 2024-11-01T16:13:28.3545909Z  True # If True, the experiment is enabled by default for all queries 2024-11-01T16:13:28.3546691Z  ) 2024-11-01T16:13:28.3547051Z  2024-11-01T16:13:28.3547477Z  # Add more fields as needed 2024-11-01T16:13:28.3548032Z  2024-11-01T16:13:28.3548372Z  2024-11-01T16:13:28.3548784Z class Settings(NamedTuple): 2024-11-01T16:13:28.3549310Z  """ 2024-11-01T16:13:28.3549859Z  Settings for the experiments that can be opted into. 2024-11-01T16:13:28.3550618Z  """ 2024-11-01T16:13:28.3550949Z  2024-11-01T16:13:28.3551383Z  experiments: Dict[str, Experiment] = {} 2024-11-01T16:13:28.3552040Z  2024-11-01T16:13:28.3552341Z  2024-11-01T16:13:28.3552785Z class ColorFormatter(logging.Formatter): 2024-11-01T16:13:28.3553967Z  """Color codes the log messages based on the log level""" 2024-11-01T16:13:28.3554630Z  2024-11-01T16:13:28.3554980Z  COLORS = { 2024-11-01T16:13:28.3555552Z  "WARNING": "\033[33m", # Yellow 2024-11-01T16:13:28.3556128Z  "ERROR": "\033[31m", # Red 2024-11-01T16:13:28.3556888Z  "CRITICAL": "\033[31m", # Red 2024-11-01T16:13:28.3557565Z  "INFO": "\033[0m", # Reset 2024-11-01T16:13:28.3558115Z  "DEBUG": "\033[0m", # Reset 2024-11-01T16:13:28.3558666Z  } 2024-11-01T16:13:28.3559095Z  2024-11-01T16:13:28.3559524Z  def format(self, record: LogRecord) -> str: 2024-11-01T16:13:28.3560484Z  log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-11-01T16:13:28.3561538Z  record.msg = f"{log_color}{record.msg}\033[0m" 2024-11-01T16:13:28.3562189Z  return super().format(record) 2024-11-01T16:13:28.3562762Z  2024-11-01T16:13:28.3563162Z  2024-11-01T16:13:28.3563534Z handler = logging.StreamHandler() 2024-11-01T16:13:28.3564400Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-11-01T16:13:28.3565275Z  2024-11-01T16:13:28.3565803Z log = logging.getLogger(os.path.basename(__file__)) 2024-11-01T16:13:28.3566461Z log.addHandler(handler) 2024-11-01T16:13:28.3567056Z log.setLevel(logging.INFO) 2024-11-01T16:13:28.3567568Z  2024-11-01T16:13:28.3567871Z  2024-11-01T16:13:28.3568457Z def set_github_output(key: str, value: str) -> None: 2024-11-01T16:13:28.3569118Z  """ 2024-11-01T16:13:28.3569701Z  Defines outputs of the github action that invokes this script 2024-11-01T16:13:28.3570494Z  """ 2024-11-01T16:13:28.3570912Z  if not GITHUB_OUTPUT: 2024-11-01T16:13:28.3572243Z  # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-11-01T16:13:28.3573872Z  log.warning( 2024-11-01T16:13:28.3574970Z  "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:28.3576172Z  ) 2024-11-01T16:13:28.3576662Z  print(f"::set-output name={key}::{value}") 2024-11-01T16:13:28.3577284Z  return 2024-11-01T16:13:28.3577788Z  2024-11-01T16:13:28.3578195Z  with open(GITHUB_OUTPUT, "a") as f: 2024-11-01T16:13:28.3578894Z  log.info(f"Setting output: {key}='{value}'") 2024-11-01T16:13:28.3579644Z  f.write(f"{key}={value}\n") 2024-11-01T16:13:28.3580143Z  2024-11-01T16:13:28.3580487Z  2024-11-01T16:13:28.3581158Z def _str_comma_separated_to_set(value: str) -> FrozenSet[str]: 2024-11-01T16:13:28.3581877Z  return frozenset( 2024-11-01T16:13:28.3582646Z  filter(lambda itm: itm != "", map(str.strip, value.strip(" \n\t").split(","))) 2024-11-01T16:13:28.3583521Z  ) 2024-11-01T16:13:28.3583848Z  2024-11-01T16:13:28.3584188Z  2024-11-01T16:13:28.3584651Z def parse_args() -> Any: 2024-11-01T16:13:28.3585314Z  parser = ArgumentParser("Get dynamic rollout settings") 2024-11-01T16:13:28.3586392Z  parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-11-01T16:13:28.3587372Z  parser.add_argument( 2024-11-01T16:13:28.3587908Z  "--github-issue-repo", 2024-11-01T16:13:28.3588426Z  type=str, 2024-11-01T16:13:28.3588934Z  required=False, 2024-11-01T16:13:28.3589470Z  default="pytorch/test-infra", 2024-11-01T16:13:28.3590109Z  help="GitHub repo to get the issue", 2024-11-01T16:13:28.3590752Z  ) 2024-11-01T16:13:28.3591146Z  parser.add_argument( 2024-11-01T16:13:28.3591634Z  "--github-repo", 2024-11-01T16:13:28.3592198Z  type=str, 2024-11-01T16:13:28.3592658Z  required=True, 2024-11-01T16:13:28.3593521Z  help="GitHub repo where CI is running", 2024-11-01T16:13:28.3594211Z  ) 2024-11-01T16:13:28.3594621Z  parser.add_argument( 2024-11-01T16:13:28.3595338Z  "--github-issue", type=int, required=True, help="GitHub issue number" 2024-11-01T16:13:28.3596161Z  ) 2024-11-01T16:13:28.3596571Z  parser.add_argument( 2024-11-01T16:13:28.3597336Z  "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-11-01T16:13:28.3598200Z  ) 2024-11-01T16:13:28.3598610Z  parser.add_argument( 2024-11-01T16:13:28.3599373Z  "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-11-01T16:13:28.3600254Z  ) 2024-11-01T16:13:28.3600661Z  parser.add_argument( 2024-11-01T16:13:28.3601483Z  "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-11-01T16:13:28.3602356Z  ) 2024-11-01T16:13:28.3602751Z  parser.add_argument( 2024-11-01T16:13:28.3603281Z  "--github-ref-type", 2024-11-01T16:13:28.3603831Z  type=str, 2024-11-01T16:13:28.3604299Z  required=True, 2024-11-01T16:13:28.3604904Z  help="Current GitHub ref type, branch or tag", 2024-11-01T16:13:28.3605580Z  ) 2024-11-01T16:13:28.3605973Z  parser.add_argument( 2024-11-01T16:13:28.3606520Z  "--eligible-experiments", 2024-11-01T16:13:28.3607184Z  type=_str_comma_separated_to_set, 2024-11-01T16:13:28.3607767Z  required=False, 2024-11-01T16:13:28.3608421Z  default="", 2024-11-01T16:13:28.3609559Z  help="comma separated list of experiments to check, if omitted all experiments marked with default=True are checked", 2024-11-01T16:13:28.3610671Z  ) 2024-11-01T16:13:28.3611024Z  2024-11-01T16:13:28.3611491Z  return parser.parse_args() 2024-11-01T16:13:28.3612027Z  2024-11-01T16:13:28.3612338Z  2024-11-01T16:13:28.3612867Z def get_gh_client(github_token: str) -> Github: 2024-11-01T16:13:28.3613571Z  auth = Auth.Token(github_token) 2024-11-01T16:13:28.3614112Z  return Github(auth=auth) 2024-11-01T16:13:28.3614665Z  2024-11-01T16:13:28.3615013Z  2024-11-01T16:13:28.3615540Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-11-01T16:13:28.3616361Z  repo = gh.get_repo(repo) 2024-11-01T16:13:28.3616989Z  return repo.get_issue(number=issue_num) 2024-11-01T16:13:28.3617541Z  2024-11-01T16:13:28.3617931Z  2024-11-01T16:13:28.3618324Z def get_potential_pr_author( 2024-11-01T16:13:28.3619077Z  github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-11-01T16:13:28.3619960Z ) -> str: 2024-11-01T16:13:28.3620636Z  # If the trigger was a new tag added by a bot, this is a ciflow case 2024-11-01T16:13:28.3621658Z  # Fetch the actual username from the original PR. The PR number is 2024-11-01T16:13:28.3622621Z  # embedded in the tag name: ciflow// 2024-11-01T16:13:28.3623284Z  2024-11-01T16:13:28.3623690Z  gh = get_gh_client(github_token) 2024-11-01T16:13:28.3624276Z  2024-11-01T16:13:28.3624799Z  if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-11-01T16:13:28.3625548Z  split_tag = ref_name.split("/") 2024-11-01T16:13:28.3626176Z  if ( 2024-11-01T16:13:28.3626624Z  len(split_tag) == 3 2024-11-01T16:13:28.3627212Z  and split_tag[0] == "ciflow" 2024-11-01T16:13:28.3627900Z  and split_tag[2].isnumeric() 2024-11-01T16:13:28.3628469Z  ): 2024-11-01T16:13:28.3629068Z  pr_number = split_tag[2] 2024-11-01T16:13:28.3629676Z  try: 2024-11-01T16:13:28.3630203Z  repository = gh.get_repo(repo) 2024-11-01T16:13:28.3630977Z  pull = repository.get_pull(number=int(pr_number)) 2024-11-01T16:13:28.3631766Z  except Exception as e: 2024-11-01T16:13:28.3632370Z  raise Exception( # noqa: TRY002 2024-11-01T16:13:28.3633686Z  f"issue with pull request {pr_number} from repo {repository}" 2024-11-01T16:13:28.3634542Z  ) from e 2024-11-01T16:13:28.3635041Z  return pull.user.login 2024-11-01T16:13:28.3635795Z  # In all other cases, return the original input username 2024-11-01T16:13:28.3636579Z  return username 2024-11-01T16:13:28.3637011Z  2024-11-01T16:13:28.3637345Z  2024-11-01T16:13:28.3637877Z def is_exception_branch(branch: str) -> bool: 2024-11-01T16:13:28.3638480Z  """ 2024-11-01T16:13:28.3639269Z  Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-11-01T16:13:28.3640240Z  """ 2024-11-01T16:13:28.3640912Z  return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-11-01T16:13:28.3641650Z  2024-11-01T16:13:28.3642052Z  2024-11-01T16:13:28.3642489Z def load_yaml(yaml_text: str) -> Any: 2024-11-01T16:13:28.3643016Z  try: 2024-11-01T16:13:28.3643559Z  data = yaml.safe_load(yaml_text) 2024-11-01T16:13:28.3644340Z  return data 2024-11-01T16:13:28.3644821Z  except yaml.YAMLError as exc: 2024-11-01T16:13:28.3645543Z  log.exception("Error loading YAML") 2024-11-01T16:13:28.3646134Z  raise 2024-11-01T16:13:28.3646507Z  2024-11-01T16:13:28.3646934Z  2024-11-01T16:13:28.3647626Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-11-01T16:13:28.3648443Z  """ 2024-11-01T16:13:28.3649314Z  Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-11-01T16:13:28.3650216Z  2024-11-01T16:13:28.3650843Z  If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:28.3651866Z  and the text below is the list of opted in users. 2024-11-01T16:13:28.3652500Z  2024-11-01T16:13:28.3653258Z  If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-11-01T16:13:28.3654077Z  """ 2024-11-01T16:13:28.3654595Z  rollout_state_parts = rollout_state.split("---") 2024-11-01T16:13:28.3655368Z  if len(rollout_state_parts) >= 2: 2024-11-01T16:13:28.3656063Z  return rollout_state_parts[0], rollout_state_parts[1] 2024-11-01T16:13:28.3656736Z  else: 2024-11-01T16:13:28.3657248Z  return "", rollout_state 2024-11-01T16:13:28.3657737Z  2024-11-01T16:13:28.3658102Z  2024-11-01T16:13:28.3658596Z class UserOptins(Dict[str, List[str]]): 2024-11-01T16:13:28.3659140Z  """ 2024-11-01T16:13:28.3659778Z  Dictionary of users with a list of features they have opted into 2024-11-01T16:13:28.3660606Z  """ 2024-11-01T16:13:28.3660937Z  2024-11-01T16:13:28.3661289Z  2024-11-01T16:13:28.3661940Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-11-01T16:13:28.3662682Z  """ 2024-11-01T16:13:28.3663597Z  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:28.3664672Z  2024-11-01T16:13:28.3665799Z  Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-11-01T16:13:28.3667042Z  - Example line: "@User1,lf,split_build" 2024-11-01T16:13:28.3667946Z  - A "#" prefix indicates the user is opted out of all experiments 2024-11-01T16:13:28.3668703Z  2024-11-01T16:13:28.3669007Z  2024-11-01T16:13:28.3669418Z  """ 2024-11-01T16:13:28.3669839Z  optins = UserOptins() 2024-11-01T16:13:28.3670417Z  for user in user_optin_text.split("\n"): 2024-11-01T16:13:28.3671141Z  user = user.strip("\r\n\t -") 2024-11-01T16:13:28.3671822Z  if not user or not user.startswith("@"): 2024-11-01T16:13:28.3672453Z  # Not a valid user. Skip 2024-11-01T16:13:28.3673271Z  continue 2024-11-01T16:13:28.3673942Z  2024-11-01T16:13:28.3674356Z  if user: 2024-11-01T16:13:28.3675026Z  usr_name = user.split(",")[0].strip("@") 2024-11-01T16:13:28.3675895Z  optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-11-01T16:13:28.3676642Z  2024-11-01T16:13:28.3677051Z  return optins 2024-11-01T16:13:28.3677494Z  2024-11-01T16:13:28.3677795Z  2024-11-01T16:13:28.3678431Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-11-01T16:13:28.3679152Z  """ 2024-11-01T16:13:28.3679877Z  Parse the experiments from the issue body into a list of ExperimentSettings 2024-11-01T16:13:28.3680737Z  """ 2024-11-01T16:13:28.3681156Z  try: 2024-11-01T16:13:28.3681772Z  if settings_text: 2024-11-01T16:13:28.3682745Z  # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-11-01T16:13:28.3683723Z  # for easy reading 2024-11-01T16:13:28.3684756Z  # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-11-01T16:13:28.3685913Z  # the backtick character in shell commands. 2024-11-01T16:13:28.3686673Z  backtick = chr(96) # backtick character 2024-11-01T16:13:28.3687504Z  settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-11-01T16:13:28.3688357Z  settings = load_yaml(settings_text) 2024-11-01T16:13:28.3688918Z  2024-11-01T16:13:28.3689642Z  # For now we just load experiments. We can expand this if/when we add more settings 2024-11-01T16:13:28.3690601Z  experiments = {} 2024-11-01T16:13:28.3691092Z  2024-11-01T16:13:28.3691745Z  for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-11-01T16:13:28.3692681Z  valid_settings = {} 2024-11-01T16:13:28.3693286Z  for setting in exp_settings: 2024-11-01T16:13:28.3693981Z  if setting not in Experiment._fields: 2024-11-01T16:13:28.3694713Z  log.warning( 2024-11-01T16:13:28.3695581Z  f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-11-01T16:13:28.3696379Z  ) 2024-11-01T16:13:28.3696952Z  else: 2024-11-01T16:13:28.3697585Z  valid_settings[setting] = exp_settings[setting] 2024-11-01T16:13:28.3698200Z  2024-11-01T16:13:28.3698807Z  experiments[exp_name] = Experiment(**valid_settings) 2024-11-01T16:13:28.3699577Z  return Settings(experiments) 2024-11-01T16:13:28.3700109Z  2024-11-01T16:13:28.3700574Z  except Exception: 2024-11-01T16:13:28.3701310Z  log.exception("Failed to parse settings") 2024-11-01T16:13:28.3701902Z  2024-11-01T16:13:28.3702353Z  return Settings() 2024-11-01T16:13:28.3702807Z  2024-11-01T16:13:28.3703120Z  2024-11-01T16:13:28.3703683Z def parse_settings(rollout_state: str) -> Settings: 2024-11-01T16:13:28.3704342Z  """ 2024-11-01T16:13:28.3704844Z  Parse settings, if any, from the rollout state. 2024-11-01T16:13:28.3705540Z  2024-11-01T16:13:28.3706173Z  If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:28.3707125Z  and the text below is the list of opted in users. 2024-11-01T16:13:28.3707803Z  2024-11-01T16:13:28.3708522Z  If it doesn't contain "---" then the settings are empty and the default values are used. 2024-11-01T16:13:28.3709418Z  """ 2024-11-01T16:13:28.3710080Z  settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:28.3711018Z  return parse_settings_from_text(settings_text) 2024-11-01T16:13:28.3711639Z  2024-11-01T16:13:28.3711997Z  2024-11-01T16:13:28.3712494Z def parse_users(rollout_state: str) -> UserOptins: 2024-11-01T16:13:28.3713587Z  """ 2024-11-01T16:13:28.3714111Z  Parse users from the rollout state. 2024-11-01T16:13:28.3714698Z  2024-11-01T16:13:28.3715055Z  """ 2024-11-01T16:13:28.3715711Z  _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:28.3716615Z  return parse_user_opt_in_from_text(users_text) 2024-11-01T16:13:28.3717399Z  2024-11-01T16:13:28.3717795Z  2024-11-01T16:13:28.3718510Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-11-01T16:13:28.3719382Z  """ 2024-11-01T16:13:28.3719959Z  Check if a user is opted into an experiment 2024-11-01T16:13:28.3720535Z  """ 2024-11-01T16:13:28.3721074Z  return experiment_name in user_optins.get(user, []) 2024-11-01T16:13:28.3721809Z  2024-11-01T16:13:28.3722112Z  2024-11-01T16:13:28.3722477Z def get_runner_prefix( 2024-11-01T16:13:28.3723049Z  rollout_state: str, 2024-11-01T16:13:28.3723569Z  workflow_requestors: Iterable[str], 2024-11-01T16:13:28.3724164Z  branch: str, 2024-11-01T16:13:28.3724826Z  eligible_experiments: FrozenSet[str] = frozenset(), 2024-11-01T16:13:28.3725479Z  is_canary: bool = False, 2024-11-01T16:13:28.3726006Z ) -> str: 2024-11-01T16:13:28.3726559Z  settings = parse_settings(rollout_state) 2024-11-01T16:13:28.3727214Z  user_optins = parse_users(rollout_state) 2024-11-01T16:13:28.3727818Z  2024-11-01T16:13:28.3728245Z  fleet_prefix = "" 2024-11-01T16:13:28.3728710Z  prefixes = [] 2024-11-01T16:13:28.3729483Z  for experiment_name, experiment_settings in settings.experiments.items(): 2024-11-01T16:13:28.3730692Z  if not experiment_settings.all_branches and is_exception_branch(branch): 2024-11-01T16:13:28.3731534Z  log.info( 2024-11-01T16:13:28.3732349Z  f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-11-01T16:13:28.3733302Z  ) 2024-11-01T16:13:28.3733738Z  continue 2024-11-01T16:13:28.3734152Z  2024-11-01T16:13:28.3734608Z  if eligible_experiments: 2024-11-01T16:13:28.3735321Z  if experiment_name not in eligible_experiments: 2024-11-01T16:13:28.3736077Z  exp_list = ", ".join(eligible_experiments) 2024-11-01T16:13:28.3736782Z  log.info( 2024-11-01T16:13:28.3737911Z  f"Skipping experiment '{experiment_name}', as it is not in the eligible_experiments list: {exp_list}" 2024-11-01T16:13:28.3738868Z  ) 2024-11-01T16:13:28.3739399Z  continue 2024-11-01T16:13:28.3739980Z  elif not experiment_settings.default: 2024-11-01T16:13:28.3740665Z  log.info( 2024-11-01T16:13:28.3741439Z  f"Skipping experiment '{experiment_name}', as it is not a default experiment" 2024-11-01T16:13:28.3742280Z  ) 2024-11-01T16:13:28.3742756Z  continue 2024-11-01T16:13:28.3743197Z  2024-11-01T16:13:28.3743751Z  # Is any workflow_requestor opted in to this experiment? 2024-11-01T16:13:28.3744539Z  opted_in_users = [ 2024-11-01T16:13:28.3745027Z  requestor 2024-11-01T16:13:28.3745585Z  for requestor in workflow_requestors 2024-11-01T16:13:28.3746485Z  if is_user_opted_in(requestor, user_optins, experiment_name) 2024-11-01T16:13:28.3747185Z  ] 2024-11-01T16:13:28.3747569Z  2024-11-01T16:13:28.3748021Z  enabled = False 2024-11-01T16:13:28.3748487Z  if opted_in_users: 2024-11-01T16:13:28.3748992Z  log.info( 2024-11-01T16:13:28.3749826Z  f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-11-01T16:13:28.3750642Z  ) 2024-11-01T16:13:28.3751037Z  enabled = True 2024-11-01T16:13:28.3751595Z  2024-11-01T16:13:28.3752055Z  elif experiment_settings.rollout_perc: 2024-11-01T16:13:28.3753340Z  # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-11-01T16:13:28.3754621Z  if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-11-01T16:13:28.3755389Z  log.info( 2024-11-01T16:13:28.3756423Z  f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-11-01T16:13:28.3757559Z  ) 2024-11-01T16:13:28.3758030Z  enabled = True 2024-11-01T16:13:28.3758550Z  2024-11-01T16:13:28.3758947Z  if enabled: 2024-11-01T16:13:28.3759465Z  label = experiment_name 2024-11-01T16:13:28.3760150Z  if experiment_name == LF_FLEET_EXPERIMENT: 2024-11-01T16:13:28.3761210Z  # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-11-01T16:13:28.3762343Z  # - If it's enabled, then we always list it's prefix first 2024-11-01T16:13:28.3763331Z  # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-11-01T16:13:28.3764163Z  if is_canary: 2024-11-01T16:13:28.3764776Z  label += CANARY_FLEET_SUFFIX 2024-11-01T16:13:28.3765415Z  fleet_prefix = label 2024-11-01T16:13:28.3766032Z  else: 2024-11-01T16:13:28.3766524Z  prefixes.append(label) 2024-11-01T16:13:28.3767066Z  2024-11-01T16:13:28.3767519Z  if len(prefixes) > 1: 2024-11-01T16:13:28.3768017Z  log.error( 2024-11-01T16:13:28.3769326Z  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:28.3770793Z  ) 2024-11-01T16:13:28.3771200Z  prefixes = prefixes[:1] 2024-11-01T16:13:28.3771721Z  2024-11-01T16:13:28.3772183Z  # Fleet always comes first 2024-11-01T16:13:28.3772690Z  if fleet_prefix: 2024-11-01T16:13:28.3773376Z  prefixes.insert(0, fleet_prefix) 2024-11-01T16:13:28.3774043Z  2024-11-01T16:13:28.3774509Z  return ".".join(prefixes) + "." if prefixes else "" 2024-11-01T16:13:28.3775153Z  2024-11-01T16:13:28.3775572Z  2024-11-01T16:13:28.3776251Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-11-01T16:13:28.3777151Z  """ 2024-11-01T16:13:28.3777931Z  Gets the first comment of the issue, which contains the desired rollout state. 2024-11-01T16:13:28.3778756Z  2024-11-01T16:13:28.3779399Z  The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-11-01T16:13:28.3780374Z  """ 2024-11-01T16:13:28.3780824Z  gh = get_gh_client(github_token) 2024-11-01T16:13:28.3781457Z  issue = get_issue(gh, repo, issue_num) 2024-11-01T16:13:28.3782302Z  return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-11-01T16:13:28.3782990Z  2024-11-01T16:13:28.3783302Z  2024-11-01T16:13:28.3783732Z def main() -> None: 2024-11-01T16:13:28.3784223Z  args = parse_args() 2024-11-01T16:13:28.3784670Z  2024-11-01T16:13:28.3785184Z  runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-11-01T16:13:28.3785792Z  2024-11-01T16:13:28.3786098Z  try: 2024-11-01T16:13:28.3786680Z  rollout_state = get_rollout_state_from_issue( 2024-11-01T16:13:28.3787557Z  args.github_token, args.github_issue_repo, args.github_issue 2024-11-01T16:13:28.3788413Z  ) 2024-11-01T16:13:28.3788883Z  2024-11-01T16:13:28.3789317Z  username = get_potential_pr_author( 2024-11-01T16:13:28.3789913Z  args.github_token, 2024-11-01T16:13:28.3790539Z  args.github_repo, 2024-11-01T16:13:28.3791081Z  args.github_actor, 2024-11-01T16:13:28.3791703Z  args.github_ref_type, 2024-11-01T16:13:28.3792252Z  args.github_branch, 2024-11-01T16:13:28.3792774Z  ) 2024-11-01T16:13:28.3793543Z  2024-11-01T16:13:28.3794070Z  is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-11-01T16:13:28.3794766Z  2024-11-01T16:13:28.3795297Z  runner_label_prefix = get_runner_prefix( 2024-11-01T16:13:28.3795891Z  rollout_state, 2024-11-01T16:13:28.3796491Z  (args.github_issue_owner, username), 2024-11-01T16:13:28.3797217Z  args.github_branch, 2024-11-01T16:13:28.3797774Z  args.eligible_experiments, 2024-11-01T16:13:28.3798355Z  is_canary, 2024-11-01T16:13:28.3798894Z  ) 2024-11-01T16:13:28.3799246Z  2024-11-01T16:13:28.3799628Z  except Exception as e: 2024-11-01T16:13:28.3800209Z  log.error( 2024-11-01T16:13:28.3801023Z  f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-11-01T16:13:28.3801934Z  ) 2024-11-01T16:13:28.3802377Z  2024-11-01T16:13:28.3802930Z  set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-11-01T16:13:28.3803687Z  2024-11-01T16:13:28.3804084Z  2024-11-01T16:13:28.3804424Z if __name__ == "__main__": 2024-11-01T16:13:28.3804937Z  main() 2024-11-01T16:13:28.3805386Z  2024-11-01T16:13:28.3805702Z EOF 2024-11-01T16:13:28.3806075Z  2024-11-01T16:13:28.3806527Z cat runner_determinator.py 2024-11-01T16:13:28.4177382Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:28.4178031Z env: 2024-11-01T16:13:28.4178634Z GITHUB_TOKEN: *** 2024-11-01T16:13:28.4179043Z ISSUE_NUMBER: 5132 2024-11-01T16:13:28.4179779Z TRIGGERING_ACTOR: c00w 2024-11-01T16:13:28.4180260Z ISSUE_OWNER: c00w 2024-11-01T16:13:28.4180663Z CHECK_EXPERIMENTS: 2024-11-01T16:13:28.4181169Z ##[endgroup] 2024-11-01T16:13:28.4598245Z # flake8: noqa: G004 2024-11-01T16:13:28.4598564Z 2024-11-01T16:13:28.4600275Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-11-01T16:13:28.4601451Z # must be kept in sync. You can do it easily by running the following command: 2024-11-01T16:13:28.4602381Z # python .github/scripts/update_runner_determinator.py 2024-11-01T16:13:28.4602993Z 2024-11-01T16:13:28.4603117Z """ 2024-11-01T16:13:28.4603769Z This runner determinator is used to determine which set of runners to run a 2024-11-01T16:13:28.4604745Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-11-01T16:13:28.4605950Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-11-01T16:13:28.4606871Z of which runners should be used to run which job. 2024-11-01T16:13:28.4607316Z 2024-11-01T16:13:28.4607772Z The configuration has two parts, the settings and a list of opted-in users, 2024-11-01T16:13:28.4608899Z separated by a line containing "---". If the line is not present, the 2024-11-01T16:13:28.4609887Z settings are considered to be empty with only the second part, the user 2024-11-01T16:13:28.4610642Z list, defined. 2024-11-01T16:13:28.4610936Z 2024-11-01T16:13:28.4611339Z The first part is a YAML block that defines the rollout settings. This can be 2024-11-01T16:13:28.4612408Z used to define any settings that are needed to determine which runners to use. 2024-11-01T16:13:28.4613398Z It's fields are defined by the RolloutSettings class below. 2024-11-01T16:13:28.4614240Z 2024-11-01T16:13:28.4614673Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-11-01T16:13:28.4615682Z The user list is also a comma separated list of additional features or 2024-11-01T16:13:28.4616532Z experiments which the user could be opted in to. 2024-11-01T16:13:28.4617057Z 2024-11-01T16:13:28.4617272Z The user list has the following rules: 2024-11-01T16:13:28.4617647Z 2024-11-01T16:13:28.4618023Z - Users are GitHub usernames, which must start with the @ prefix 2024-11-01T16:13:28.4619043Z - Each user is also a comma-separated list of features/experiments to enable 2024-11-01T16:13:28.4620027Z - A "#" prefix opts the user out of all experiments 2024-11-01T16:13:28.4620470Z 2024-11-01T16:13:28.4620615Z Example config: 2024-11-01T16:13:28.4621114Z # A list of experiments that can be opted into. 2024-11-01T16:13:28.4621985Z # This defines the behavior they'll induce when opted into. 2024-11-01T16:13:28.4622646Z # Expected syntax is: 2024-11-01T16:13:28.4623374Z # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-11-01T16:13:28.4624582Z # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-11-01T16:13:28.4625293Z 2024-11-01T16:13:28.4625435Z experiments: 2024-11-01T16:13:28.4625850Z lf: 2024-11-01T16:13:28.4626299Z rollout_percent: 25 2024-11-01T16:13:28.4626746Z all_branches: false 2024-11-01T16:13:28.4627216Z default: true 2024-11-01T16:13:28.4627719Z --- 2024-11-01T16:13:28.4627915Z 2024-11-01T16:13:28.4628075Z # Opt-ins: 2024-11-01T16:13:28.4628751Z # Users can opt into the LF fleet by adding their GitHub username to this list 2024-11-01T16:13:28.4629868Z # and specifying experiments to enable in a comma-separated list. 2024-11-01T16:13:28.4630653Z # Experiments should be from the above list. 2024-11-01T16:13:28.4631103Z 2024-11-01T16:13:28.4631265Z @User1,lf,split_build 2024-11-01T16:13:28.4631792Z @User2,lf 2024-11-01T16:13:28.4632198Z @User3,split_build 2024-11-01T16:13:28.4632581Z """ 2024-11-01T16:13:28.4633132Z 2024-11-01T16:13:28.4633300Z import logging 2024-11-01T16:13:28.4633720Z import os 2024-11-01T16:13:28.4634058Z import random 2024-11-01T16:13:28.4634780Z from argparse import ArgumentParser 2024-11-01T16:13:28.4635321Z from logging import LogRecord 2024-11-01T16:13:28.4636065Z from typing import Any, Dict, FrozenSet, Iterable, List, NamedTuple, Tuple 2024-11-01T16:13:28.4636802Z 2024-11-01T16:13:28.4636942Z import yaml 2024-11-01T16:13:28.4637343Z from github import Auth, Github 2024-11-01T16:13:28.4637836Z from github.Issue import Issue 2024-11-01T16:13:28.4638272Z 2024-11-01T16:13:28.4638277Z 2024-11-01T16:13:28.4638481Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-11-01T16:13:28.4639239Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-11-01T16:13:28.4640178Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-11-01T16:13:28.4640936Z 2024-11-01T16:13:28.4641149Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-11-01T16:13:28.4641819Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-11-01T16:13:28.4642362Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-11-01T16:13:28.4642856Z 2024-11-01T16:13:28.4642869Z 2024-11-01T16:13:28.4643042Z SETTING_EXPERIMENTS = "experiments" 2024-11-01T16:13:28.4643425Z 2024-11-01T16:13:28.4643577Z LF_FLEET_EXPERIMENT = "lf" 2024-11-01T16:13:28.4644135Z CANARY_FLEET_SUFFIX = ".c" 2024-11-01T16:13:28.4644427Z 2024-11-01T16:13:28.4644432Z 2024-11-01T16:13:28.4644599Z class Experiment(NamedTuple): 2024-11-01T16:13:28.4645100Z rollout_perc: float = ( 2024-11-01T16:13:28.4645962Z 0 # Percentage of workflows to experiment on when user is not opted-in. 2024-11-01T16:13:28.4646692Z ) 2024-11-01T16:13:28.4647060Z all_branches: bool = ( 2024-11-01T16:13:28.4647890Z False # If True, the experiment is also enabled on the exception branches 2024-11-01T16:13:28.4648826Z ) 2024-11-01T16:13:28.4649208Z default: bool = ( 2024-11-01T16:13:28.4649905Z True # If True, the experiment is enabled by default for all queries 2024-11-01T16:13:28.4650592Z ) 2024-11-01T16:13:28.4650831Z 2024-11-01T16:13:28.4650993Z # Add more fields as needed 2024-11-01T16:13:28.4651323Z 2024-11-01T16:13:28.4651329Z 2024-11-01T16:13:28.4651591Z class Settings(NamedTuple): 2024-11-01T16:13:28.4652036Z """ 2024-11-01T16:13:28.4652548Z Settings for the experiments that can be opted into. 2024-11-01T16:13:28.4653235Z """ 2024-11-01T16:13:28.4653431Z 2024-11-01T16:13:28.4653625Z experiments: Dict[str, Experiment] = {} 2024-11-01T16:13:28.4654076Z 2024-11-01T16:13:28.4654081Z 2024-11-01T16:13:28.4654273Z class ColorFormatter(logging.Formatter): 2024-11-01T16:13:28.4655025Z """Color codes the log messages based on the log level""" 2024-11-01T16:13:28.4655518Z 2024-11-01T16:13:28.4655701Z COLORS = { 2024-11-01T16:13:28.4656092Z "WARNING": "\033[33m", # Yellow 2024-11-01T16:13:28.4656687Z "ERROR": "\033[31m", # Red 2024-11-01T16:13:28.4657226Z "CRITICAL": "\033[31m", # Red 2024-11-01T16:13:28.4657728Z "INFO": "\033[0m", # Reset 2024-11-01T16:13:28.4658308Z "DEBUG": "\033[0m", # Reset 2024-11-01T16:13:28.4658829Z } 2024-11-01T16:13:28.4659044Z 2024-11-01T16:13:28.4659305Z def format(self, record: LogRecord) -> str: 2024-11-01T16:13:28.4660208Z log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-11-01T16:13:28.4661104Z record.msg = f"{log_color}{record.msg}\033[0m" 2024-11-01T16:13:28.4661708Z return super().format(record) 2024-11-01T16:13:28.4662108Z 2024-11-01T16:13:28.4662114Z 2024-11-01T16:13:28.4662348Z handler = logging.StreamHandler() 2024-11-01T16:13:28.4663186Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-11-01T16:13:28.4663788Z 2024-11-01T16:13:28.4664062Z log = logging.getLogger(os.path.basename(__file__)) 2024-11-01T16:13:28.4664752Z log.addHandler(handler) 2024-11-01T16:13:28.4665218Z log.setLevel(logging.INFO) 2024-11-01T16:13:28.4665526Z 2024-11-01T16:13:28.4665531Z 2024-11-01T16:13:28.4665848Z def set_github_output(key: str, value: str) -> None: 2024-11-01T16:13:28.4666512Z """ 2024-11-01T16:13:28.4667196Z Defines outputs of the github action that invokes this script 2024-11-01T16:13:28.4667899Z """ 2024-11-01T16:13:28.4668306Z if not GITHUB_OUTPUT: 2024-11-01T16:13:28.4669660Z # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-11-01T16:13:28.4670993Z log.warning( 2024-11-01T16:13:28.4672014Z "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:28.4673330Z ) 2024-11-01T16:13:28.4696246Z print(f"::set-output name={key}::{value}") 2024-11-01T16:13:28.4696998Z return 2024-11-01T16:13:28.4697238Z 2024-11-01T16:13:28.4697419Z with open(GITHUB_OUTPUT, "a") as f: 2024-11-01T16:13:28.4698191Z log.info(f"Setting output: {key}='{value}'") 2024-11-01T16:13:28.4698912Z f.write(f"{key}={value}\n") 2024-11-01T16:13:28.4699262Z 2024-11-01T16:13:28.4699274Z 2024-11-01T16:13:28.4699683Z def _str_comma_separated_to_set(value: str) -> FrozenSet[str]: 2024-11-01T16:13:28.4700350Z return frozenset( 2024-11-01T16:13:28.4701107Z filter(lambda itm: itm != "", map(str.strip, value.strip(" \n\t").split(","))) 2024-11-01T16:13:28.4701903Z ) 2024-11-01T16:13:28.4702095Z 2024-11-01T16:13:28.4702100Z 2024-11-01T16:13:28.4702288Z def parse_args() -> Any: 2024-11-01T16:13:28.4702960Z parser = ArgumentParser("Get dynamic rollout settings") 2024-11-01T16:13:28.4704010Z parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-11-01T16:13:28.4704820Z parser.add_argument( 2024-11-01T16:13:28.4705651Z "--github-issue-repo", 2024-11-01T16:13:28.4706137Z type=str, 2024-11-01T16:13:28.4706522Z required=False, 2024-11-01T16:13:28.4707135Z default="pytorch/test-infra", 2024-11-01T16:13:28.4707716Z help="GitHub repo to get the issue", 2024-11-01T16:13:28.4708227Z ) 2024-11-01T16:13:28.4708696Z parser.add_argument( 2024-11-01T16:13:28.4709198Z "--github-repo", 2024-11-01T16:13:28.4709598Z type=str, 2024-11-01T16:13:28.4710086Z required=True, 2024-11-01T16:13:28.4710567Z help="GitHub repo where CI is running", 2024-11-01T16:13:28.4711085Z ) 2024-11-01T16:13:28.4711534Z parser.add_argument( 2024-11-01T16:13:28.4712245Z "--github-issue", type=int, required=True, help="GitHub issue number" 2024-11-01T16:13:28.4713539Z ) 2024-11-01T16:13:28.4714074Z parser.add_argument( 2024-11-01T16:13:28.4714840Z "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-11-01T16:13:28.4715579Z ) 2024-11-01T16:13:28.4716021Z parser.add_argument( 2024-11-01T16:13:28.4716769Z "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-11-01T16:13:28.4717509Z ) 2024-11-01T16:13:28.4717952Z parser.add_argument( 2024-11-01T16:13:28.4718738Z "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-11-01T16:13:28.4719507Z ) 2024-11-01T16:13:28.4719939Z parser.add_argument( 2024-11-01T16:13:28.4720449Z "--github-ref-type", 2024-11-01T16:13:28.4720879Z type=str, 2024-11-01T16:13:28.4721361Z required=True, 2024-11-01T16:13:28.4721907Z help="Current GitHub ref type, branch or tag", 2024-11-01T16:13:28.4722465Z ) 2024-11-01T16:13:28.4722888Z parser.add_argument( 2024-11-01T16:13:28.4723415Z "--eligible-experiments", 2024-11-01T16:13:28.4723928Z type=_str_comma_separated_to_set, 2024-11-01T16:13:28.4724534Z required=False, 2024-11-01T16:13:28.4724987Z default="", 2024-11-01T16:13:28.4725908Z help="comma separated list of experiments to check, if omitted all experiments marked with default=True are checked", 2024-11-01T16:13:28.4727044Z ) 2024-11-01T16:13:28.4727252Z 2024-11-01T16:13:28.4727450Z return parser.parse_args() 2024-11-01T16:13:28.4727772Z 2024-11-01T16:13:28.4727956Z 2024-11-01T16:13:28.4728250Z def get_gh_client(github_token: str) -> Github: 2024-11-01T16:13:28.4728966Z auth = Auth.Token(github_token) 2024-11-01T16:13:28.4729494Z return Github(auth=auth) 2024-11-01T16:13:28.4729795Z 2024-11-01T16:13:28.4729800Z 2024-11-01T16:13:28.4730182Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-11-01T16:13:28.4730920Z repo = gh.get_repo(repo) 2024-11-01T16:13:28.4731435Z return repo.get_issue(number=issue_num) 2024-11-01T16:13:28.4731835Z 2024-11-01T16:13:28.4731840Z 2024-11-01T16:13:28.4732038Z def get_potential_pr_author( 2024-11-01T16:13:28.4732779Z github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-11-01T16:13:28.4733559Z ) -> str: 2024-11-01T16:13:28.4734152Z # If the trigger was a new tag added by a bot, this is a ciflow case 2024-11-01T16:13:28.4735117Z # Fetch the actual username from the original PR. The PR number is 2024-11-01T16:13:28.4736003Z # embedded in the tag name: ciflow// 2024-11-01T16:13:28.4736486Z 2024-11-01T16:13:28.4736704Z gh = get_gh_client(github_token) 2024-11-01T16:13:28.4737128Z 2024-11-01T16:13:28.4737448Z if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-11-01T16:13:28.4738129Z split_tag = ref_name.split("/") 2024-11-01T16:13:28.4738682Z if ( 2024-11-01T16:13:28.4739109Z len(split_tag) == 3 2024-11-01T16:13:28.4739622Z and split_tag[0] == "ciflow" 2024-11-01T16:13:28.4740193Z and split_tag[2].isnumeric() 2024-11-01T16:13:28.4740732Z ): 2024-11-01T16:13:28.4741127Z pr_number = split_tag[2] 2024-11-01T16:13:28.4741959Z try: 2024-11-01T16:13:28.4742459Z repository = gh.get_repo(repo) 2024-11-01T16:13:28.4743178Z pull = repository.get_pull(number=int(pr_number)) 2024-11-01T16:13:28.4743847Z except Exception as e: 2024-11-01T16:13:28.4744481Z raise Exception( # noqa: TRY002 2024-11-01T16:13:28.4745221Z f"issue with pull request {pr_number} from repo {repository}" 2024-11-01T16:13:28.4745947Z ) from e 2024-11-01T16:13:28.4746484Z return pull.user.login 2024-11-01T16:13:28.4747103Z # In all other cases, return the original input username 2024-11-01T16:13:28.4747749Z return username 2024-11-01T16:13:28.4748056Z 2024-11-01T16:13:28.4748061Z 2024-11-01T16:13:28.4748366Z def is_exception_branch(branch: str) -> bool: 2024-11-01T16:13:28.4748908Z """ 2024-11-01T16:13:28.4749683Z Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-11-01T16:13:28.4750655Z """ 2024-11-01T16:13:28.4751236Z return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-11-01T16:13:28.4751860Z 2024-11-01T16:13:28.4751865Z 2024-11-01T16:13:28.4752074Z def load_yaml(yaml_text: str) -> Any: 2024-11-01T16:13:28.4752681Z try: 2024-11-01T16:13:28.4753305Z data = yaml.safe_load(yaml_text) 2024-11-01T16:13:28.4753854Z return data 2024-11-01T16:13:28.4754402Z except yaml.YAMLError as exc: 2024-11-01T16:13:28.4754937Z log.exception("Error loading YAML") 2024-11-01T16:13:28.4755483Z raise 2024-11-01T16:13:28.4755779Z 2024-11-01T16:13:28.4755783Z 2024-11-01T16:13:28.4756321Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-11-01T16:13:28.4757135Z """ 2024-11-01T16:13:28.4757802Z Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-11-01T16:13:28.4758618Z 2024-11-01T16:13:28.4759055Z If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:28.4759930Z and the text below is the list of opted in users. 2024-11-01T16:13:28.4760377Z 2024-11-01T16:13:28.4760867Z If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-11-01T16:13:28.4761726Z """ 2024-11-01T16:13:28.4762397Z rollout_state_parts = rollout_state.split("---") 2024-11-01T16:13:28.4763038Z if len(rollout_state_parts) >= 2: 2024-11-01T16:13:28.4763760Z return rollout_state_parts[0], rollout_state_parts[1] 2024-11-01T16:13:28.4764411Z else: 2024-11-01T16:13:28.4764770Z return "", rollout_state 2024-11-01T16:13:28.4765209Z 2024-11-01T16:13:28.4765215Z 2024-11-01T16:13:28.4765397Z class UserOptins(Dict[str, List[str]]): 2024-11-01T16:13:28.4765955Z """ 2024-11-01T16:13:28.4766470Z Dictionary of users with a list of features they have opted into 2024-11-01T16:13:28.4767252Z """ 2024-11-01T16:13:28.4767494Z 2024-11-01T16:13:28.4767500Z 2024-11-01T16:13:28.4767906Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-11-01T16:13:28.4768674Z """ 2024-11-01T16:13:28.4769548Z 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:28.4770417Z 2024-11-01T16:13:28.4771214Z Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-11-01T16:13:28.4772478Z - Example line: "@User1,lf,split_build" 2024-11-01T16:13:28.4773258Z - A "#" prefix indicates the user is opted out of all experiments 2024-11-01T16:13:28.4773842Z 2024-11-01T16:13:28.4773847Z 2024-11-01T16:13:28.4773977Z """ 2024-11-01T16:13:28.4774437Z optins = UserOptins() 2024-11-01T16:13:28.4775017Z for user in user_optin_text.split("\n"): 2024-11-01T16:13:28.4775673Z user = user.strip("\r\n\t -") 2024-11-01T16:13:28.4776351Z if not user or not user.startswith("@"): 2024-11-01T16:13:28.4776971Z # Not a valid user. Skip 2024-11-01T16:13:28.4777639Z continue 2024-11-01T16:13:28.4777922Z 2024-11-01T16:13:28.4778126Z if user: 2024-11-01T16:13:28.4778604Z usr_name = user.split(",")[0].strip("@") 2024-11-01T16:13:28.4779340Z optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-11-01T16:13:28.4779932Z 2024-11-01T16:13:28.4780157Z return optins 2024-11-01T16:13:28.4780402Z 2024-11-01T16:13:28.4780406Z 2024-11-01T16:13:28.4780793Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-11-01T16:13:28.4781440Z """ 2024-11-01T16:13:28.4782164Z Parse the experiments from the issue body into a list of ExperimentSettings 2024-11-01T16:13:28.4782971Z """ 2024-11-01T16:13:28.4783286Z try: 2024-11-01T16:13:28.4783752Z if settings_text: 2024-11-01T16:13:28.4784575Z # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-11-01T16:13:28.4785452Z # for easy reading 2024-11-01T16:13:28.4786527Z # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-11-01T16:13:28.4787582Z # the backtick character in shell commands. 2024-11-01T16:13:28.4788220Z backtick = chr(96) # backtick character 2024-11-01T16:13:28.4789043Z settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-11-01T16:13:28.4789771Z settings = load_yaml(settings_text) 2024-11-01T16:13:28.4790170Z 2024-11-01T16:13:28.4790662Z # For now we just load experiments. We can expand this if/when we add more settings 2024-11-01T16:13:28.4791544Z experiments = {} 2024-11-01T16:13:28.4791884Z 2024-11-01T16:13:28.4792256Z for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-11-01T16:13:28.4793300Z valid_settings = {} 2024-11-01T16:13:28.4793911Z for setting in exp_settings: 2024-11-01T16:13:28.4794552Z if setting not in Experiment._fields: 2024-11-01T16:13:28.4795179Z log.warning( 2024-11-01T16:13:28.4795978Z f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-11-01T16:13:28.4796764Z ) 2024-11-01T16:13:28.4797371Z else: 2024-11-01T16:13:28.4797988Z valid_settings[setting] = exp_settings[setting] 2024-11-01T16:13:28.4798492Z 2024-11-01T16:13:28.4798775Z experiments[exp_name] = Experiment(**valid_settings) 2024-11-01T16:13:28.4799459Z return Settings(experiments) 2024-11-01T16:13:28.4799830Z 2024-11-01T16:13:28.4800073Z except Exception: 2024-11-01T16:13:28.4800561Z log.exception("Failed to parse settings") 2024-11-01T16:13:28.4801032Z 2024-11-01T16:13:28.4801176Z return Settings() 2024-11-01T16:13:28.4801431Z 2024-11-01T16:13:28.4801436Z 2024-11-01T16:13:28.4801836Z def parse_settings(rollout_state: str) -> Settings: 2024-11-01T16:13:28.4802434Z """ 2024-11-01T16:13:28.4802885Z Parse settings, if any, from the rollout state. 2024-11-01T16:13:28.4803315Z 2024-11-01T16:13:28.4803890Z If the issue body contains "---" then the text above that is the settings 2024-11-01T16:13:28.4804726Z and the text below is the list of opted in users. 2024-11-01T16:13:28.4805240Z 2024-11-01T16:13:28.4805754Z If it doesn't contain "---" then the settings are empty and the default values are used. 2024-11-01T16:13:28.4806666Z """ 2024-11-01T16:13:28.4807247Z settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:28.4808054Z return parse_settings_from_text(settings_text) 2024-11-01T16:13:28.4808604Z 2024-11-01T16:13:28.4808608Z 2024-11-01T16:13:28.4808885Z def parse_users(rollout_state: str) -> UserOptins: 2024-11-01T16:13:28.4809498Z """ 2024-11-01T16:13:28.4809868Z Parse users from the rollout state. 2024-11-01T16:13:28.4810353Z 2024-11-01T16:13:28.4810635Z """ 2024-11-01T16:13:28.4811209Z _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-11-01T16:13:28.4811981Z return parse_user_opt_in_from_text(users_text) 2024-11-01T16:13:28.4812509Z 2024-11-01T16:13:28.4812514Z 2024-11-01T16:13:28.4813050Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-11-01T16:13:28.4813891Z """ 2024-11-01T16:13:28.4814308Z Check if a user is opted into an experiment 2024-11-01T16:13:28.4814939Z """ 2024-11-01T16:13:28.4815403Z return experiment_name in user_optins.get(user, []) 2024-11-01T16:13:28.4815870Z 2024-11-01T16:13:28.4815875Z 2024-11-01T16:13:28.4816057Z def get_runner_prefix( 2024-11-01T16:13:28.4816537Z rollout_state: str, 2024-11-01T16:13:28.4817020Z workflow_requestors: Iterable[str], 2024-11-01T16:13:28.4817573Z branch: str, 2024-11-01T16:13:28.4818113Z eligible_experiments: FrozenSet[str] = frozenset(), 2024-11-01T16:13:28.4818780Z is_canary: bool = False, 2024-11-01T16:13:28.4819271Z ) -> str: 2024-11-01T16:13:28.4819731Z settings = parse_settings(rollout_state) 2024-11-01T16:13:28.4820372Z user_optins = parse_users(rollout_state) 2024-11-01T16:13:28.4820765Z 2024-11-01T16:13:28.4820943Z fleet_prefix = "" 2024-11-01T16:13:28.4821401Z prefixes = [] 2024-11-01T16:13:28.4822094Z for experiment_name, experiment_settings in settings.experiments.items(): 2024-11-01T16:13:28.4823128Z if not experiment_settings.all_branches and is_exception_branch(branch): 2024-11-01T16:13:28.4823936Z log.info( 2024-11-01T16:13:28.4824704Z f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-11-01T16:13:28.4825547Z ) 2024-11-01T16:13:28.4825961Z continue 2024-11-01T16:13:28.4826255Z 2024-11-01T16:13:28.4826414Z if eligible_experiments: 2024-11-01T16:13:28.4827003Z if experiment_name not in eligible_experiments: 2024-11-01T16:13:28.4827754Z exp_list = ", ".join(eligible_experiments) 2024-11-01T16:13:28.4828379Z log.info( 2024-11-01T16:13:28.4829325Z f"Skipping experiment '{experiment_name}', as it is not in the eligible_experiments list: {exp_list}" 2024-11-01T16:13:28.4830310Z ) 2024-11-01T16:13:28.4830831Z continue 2024-11-01T16:13:28.4831337Z elif not experiment_settings.default: 2024-11-01T16:13:28.4831979Z log.info( 2024-11-01T16:13:28.4832764Z f"Skipping experiment '{experiment_name}', as it is not a default experiment" 2024-11-01T16:13:28.4833822Z ) 2024-11-01T16:13:28.4834256Z continue 2024-11-01T16:13:28.4834541Z 2024-11-01T16:13:28.4834811Z # Is any workflow_requestor opted in to this experiment? 2024-11-01T16:13:28.4835502Z opted_in_users = [ 2024-11-01T16:13:28.4836028Z requestor 2024-11-01T16:13:28.4836469Z for requestor in workflow_requestors 2024-11-01T16:13:28.4837234Z if is_user_opted_in(requestor, user_optins, experiment_name) 2024-11-01T16:13:28.4837978Z ] 2024-11-01T16:13:28.4838186Z 2024-11-01T16:13:28.4838328Z enabled = False 2024-11-01T16:13:28.4838783Z if opted_in_users: 2024-11-01T16:13:28.4839311Z log.info( 2024-11-01T16:13:28.4840014Z f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-11-01T16:13:28.4840776Z ) 2024-11-01T16:13:28.4841269Z enabled = True 2024-11-01T16:13:28.4841550Z 2024-11-01T16:13:28.4841752Z elif experiment_settings.rollout_perc: 2024-11-01T16:13:28.4842841Z # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-11-01T16:13:28.4844014Z if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-11-01T16:13:28.4844705Z log.info( 2024-11-01T16:13:28.4845652Z f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-11-01T16:13:28.4846934Z ) 2024-11-01T16:13:28.4847315Z enabled = True 2024-11-01T16:13:28.4847670Z 2024-11-01T16:13:28.4847806Z if enabled: 2024-11-01T16:13:28.4848334Z label = experiment_name 2024-11-01T16:13:28.4848893Z if experiment_name == LF_FLEET_EXPERIMENT: 2024-11-01T16:13:28.4849832Z # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-11-01T16:13:28.4850997Z # - If it's enabled, then we always list it's prefix first 2024-11-01T16:13:28.4851958Z # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-11-01T16:13:28.4852685Z if is_canary: 2024-11-01T16:13:28.4853285Z label += CANARY_FLEET_SUFFIX 2024-11-01T16:13:28.4853866Z fleet_prefix = label 2024-11-01T16:13:28.4854347Z else: 2024-11-01T16:13:28.4854866Z prefixes.append(label) 2024-11-01T16:13:28.4855229Z 2024-11-01T16:13:28.4855415Z if len(prefixes) > 1: 2024-11-01T16:13:28.4855848Z log.error( 2024-11-01T16:13:28.4857264Z 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:28.4858561Z ) 2024-11-01T16:13:28.4858929Z prefixes = prefixes[:1] 2024-11-01T16:13:28.4859357Z 2024-11-01T16:13:28.4859514Z # Fleet always comes first 2024-11-01T16:13:28.4859998Z if fleet_prefix: 2024-11-01T16:13:28.4860438Z prefixes.insert(0, fleet_prefix) 2024-11-01T16:13:28.4860918Z 2024-11-01T16:13:28.4861159Z return ".".join(prefixes) + "." if prefixes else "" 2024-11-01T16:13:28.4861645Z 2024-11-01T16:13:28.4861651Z 2024-11-01T16:13:28.4862165Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-11-01T16:13:28.4863090Z """ 2024-11-01T16:13:28.4863687Z Gets the first comment of the issue, which contains the desired rollout state. 2024-11-01T16:13:28.4864353Z 2024-11-01T16:13:28.4864828Z The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-11-01T16:13:28.4865695Z """ 2024-11-01T16:13:28.4866347Z gh = get_gh_client(github_token) 2024-11-01T16:13:28.4866971Z issue = get_issue(gh, repo, issue_num) 2024-11-01T16:13:28.4867731Z return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-11-01T16:13:28.4868214Z 2024-11-01T16:13:28.4868219Z 2024-11-01T16:13:28.4868394Z def main() -> None: 2024-11-01T16:13:28.4868831Z args = parse_args() 2024-11-01T16:13:28.4869118Z 2024-11-01T16:13:28.4869450Z runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-11-01T16:13:28.4869863Z 2024-11-01T16:13:28.4870041Z try: 2024-11-01T16:13:28.4870456Z rollout_state = get_rollout_state_from_issue( 2024-11-01T16:13:28.4871292Z args.github_token, args.github_issue_repo, args.github_issue 2024-11-01T16:13:28.4872007Z ) 2024-11-01T16:13:28.4872218Z 2024-11-01T16:13:28.4872398Z username = get_potential_pr_author( 2024-11-01T16:13:28.4873871Z args.github_token, 2024-11-01T16:13:28.4874421Z args.github_repo, 2024-11-01T16:13:28.4874921Z args.github_actor, 2024-11-01T16:13:28.4875476Z args.github_ref_type, 2024-11-01T16:13:28.4876000Z args.github_branch, 2024-11-01T16:13:28.4876467Z ) 2024-11-01T16:13:28.4876704Z 2024-11-01T16:13:28.4877136Z is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-11-01T16:13:28.4877654Z 2024-11-01T16:13:28.4877889Z runner_label_prefix = get_runner_prefix( 2024-11-01T16:13:28.4878443Z rollout_state, 2024-11-01T16:13:28.4879004Z (args.github_issue_owner, username), 2024-11-01T16:13:28.4879616Z args.github_branch, 2024-11-01T16:13:28.4880101Z args.eligible_experiments, 2024-11-01T16:13:28.4880896Z is_canary, 2024-11-01T16:13:28.4881308Z ) 2024-11-01T16:13:28.4881502Z 2024-11-01T16:13:28.4881657Z except Exception as e: 2024-11-01T16:13:28.4882208Z log.error( 2024-11-01T16:13:28.4882976Z f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-11-01T16:13:28.4883793Z ) 2024-11-01T16:13:28.4884046Z 2024-11-01T16:13:28.4884442Z set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-11-01T16:13:28.4884989Z 2024-11-01T16:13:28.4885031Z 2024-11-01T16:13:28.4885179Z if __name__ == "__main__": 2024-11-01T16:13:28.4885638Z main() 2024-11-01T16:13:28.4885838Z 2024-11-01T16:13:28.5065562Z ##[group]Run python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-11-01T16:13:28.5066543Z python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-11-01T16:13:28.5123796Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:28.5124288Z env: 2024-11-01T16:13:28.5125011Z GITHUB_TOKEN: *** 2024-11-01T16:13:28.5125407Z ISSUE_NUMBER: 5132 2024-11-01T16:13:28.5125859Z TRIGGERING_ACTOR: c00w 2024-11-01T16:13:28.5126372Z ISSUE_OWNER: c00w 2024-11-01T16:13:28.5126755Z CHECK_EXPERIMENTS: 2024-11-01T16:13:28.5127180Z ##[endgroup] 2024-11-01T16:13:28.9082375Z Defaulting to user installation because normal site-packages is not writeable 2024-11-01T16:13:29.6169590Z Collecting urllib3==1.26.18 2024-11-01T16:13:29.6942964Z Downloading urllib3-1.26.18-py2.py3-none-any.whl (143 kB) 2024-11-01T16:13:29.7286010Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 143.8/143.8 KB 4.4 MB/s eta 0:00:00 2024-11-01T16:13:29.7664719Z Collecting PyGithub==2.3.0 2024-11-01T16:13:29.7804368Z Downloading PyGithub-2.3.0-py3-none-any.whl (354 kB) 2024-11-01T16:13:29.8007117Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 354.4/354.4 KB 18.7 MB/s eta 0:00:00 2024-11-01T16:13:29.8412991Z Collecting Deprecated 2024-11-01T16:13:29.8556107Z Downloading Deprecated-1.2.14-py2.py3-none-any.whl (9.6 kB) 2024-11-01T16:13:29.8587195Z 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:29.8851570Z Collecting typing-extensions>=4.0.0 2024-11-01T16:13:29.8994109Z Downloading typing_extensions-4.12.2-py3-none-any.whl (37 kB) 2024-11-01T16:13:29.9263881Z Collecting pyjwt[crypto]>=2.4.0 2024-11-01T16:13:29.9409521Z Downloading PyJWT-2.9.0-py3-none-any.whl (22 kB) 2024-11-01T16:13:30.0080391Z Collecting pynacl>=1.4.0 2024-11-01T16:13:30.0231606Z 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:30.0468994Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 KB 41.0 MB/s eta 0:00:00 2024-11-01T16:13:30.0662314Z 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:30.2789518Z Collecting cffi>=1.4.1 2024-11-01T16:13:30.2937575Z Downloading cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (446 kB) 2024-11-01T16:13:30.3022498Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 446.2/446.2 KB 72.0 MB/s eta 0:00:00 2024-11-01T16:13:30.4732171Z Collecting wrapt<2,>=1.10 2024-11-01T16:13:30.4880151Z 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:30.4920603Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.3/80.3 KB 31.9 MB/s eta 0:00:00 2024-11-01T16:13:30.5083414Z Collecting pycparser 2024-11-01T16:13:30.5226156Z Downloading pycparser-2.22-py3-none-any.whl (117 kB) 2024-11-01T16:13:30.5267937Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 117.6/117.6 KB 47.3 MB/s eta 0:00:00 2024-11-01T16:13:30.6979038Z Installing collected packages: wrapt, urllib3, typing-extensions, pyjwt, pycparser, Deprecated, cffi, pynacl, PyGithub 2024-11-01T16:13:31.1589933Z 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:31.2267614Z ##[group]Run curr_branch="gh/c00w/2/head" 2024-11-01T16:13:31.2268207Z curr_branch="gh/c00w/2/head" 2024-11-01T16:13:31.2268686Z curr_ref_type="branch" 2024-11-01T16:13:31.2269215Z echo "Current branch is '$curr_branch'" 2024-11-01T16:13:31.2269661Z  2024-11-01T16:13:31.2270019Z python3 runner_determinator.py \ 2024-11-01T16:13:31.2270523Z  --github-token "$GITHUB_TOKEN" \ 2024-11-01T16:13:31.2270987Z  --github-issue "$ISSUE_NUMBER" \ 2024-11-01T16:13:31.2271462Z  --github-branch "$curr_branch" \ 2024-11-01T16:13:31.2271955Z  --github-actor "$TRIGGERING_ACTOR" \ 2024-11-01T16:13:31.2272455Z  --github-issue-owner "$ISSUE_OWNER" \ 2024-11-01T16:13:31.2273208Z  --github-ref-type "$curr_ref_type" \ 2024-11-01T16:13:31.2273810Z  --github-repo "$GITHUB_REPOSITORY" \ 2024-11-01T16:13:31.2274495Z  --eligible-experiments "$CHECK_EXPERIMENTS" \ 2024-11-01T16:13:31.2332344Z shell: /usr/bin/bash -e {0} 2024-11-01T16:13:31.2332820Z env: 2024-11-01T16:13:31.2333501Z GITHUB_TOKEN: *** 2024-11-01T16:13:31.2333897Z ISSUE_NUMBER: 5132 2024-11-01T16:13:31.2334324Z TRIGGERING_ACTOR: c00w 2024-11-01T16:13:31.2334678Z ISSUE_OWNER: c00w 2024-11-01T16:13:31.2335014Z CHECK_EXPERIMENTS: 2024-11-01T16:13:31.2335422Z ##[endgroup] 2024-11-01T16:13:31.2412018Z Current branch is 'gh/c00w/2/head' 2024-11-01T16:13:32.3740690Z INFO : Skipping experiment 'awsa100', as it is not a default experiment 2024-11-01T16:13:32.3741554Z INFO : Setting output: label-type='' 2024-11-01T16:13:32.4132078Z Evaluate and set job outputs 2024-11-01T16:13:32.4142932Z Cleaning up orphan processes