2024-10-08T19:50:03.1166443Z Current runner version: '2.320.0' 2024-10-08T19:50:03.1191201Z ##[group]Operating System 2024-10-08T19:50:03.1191863Z Ubuntu 2024-10-08T19:50:03.1192336Z 22.04.5 2024-10-08T19:50:03.1192642Z LTS 2024-10-08T19:50:03.1192989Z ##[endgroup] 2024-10-08T19:50:03.1193421Z ##[group]Runner Image 2024-10-08T19:50:03.1194062Z Image: ubuntu-22.04 2024-10-08T19:50:03.1194494Z Version: 20240922.1.0 2024-10-08T19:50:03.1195610Z Included Software: https://github.com/actions/runner-images/blob/ubuntu22/20240922.1/images/ubuntu/Ubuntu2204-Readme.md 2024-10-08T19:50:03.1197029Z Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20240922.1 2024-10-08T19:50:03.1197912Z ##[endgroup] 2024-10-08T19:50:03.1198375Z ##[group]Runner Image Provisioner 2024-10-08T19:50:03.1198836Z 2.0.384.1 2024-10-08T19:50:03.1199203Z ##[endgroup] 2024-10-08T19:50:03.1216552Z ##[group]GITHUB_TOKEN Permissions 2024-10-08T19:50:03.1218361Z Actions: read 2024-10-08T19:50:03.1219004Z Attestations: read 2024-10-08T19:50:03.1219539Z Checks: read 2024-10-08T19:50:03.1219936Z Contents: read 2024-10-08T19:50:03.1220293Z Deployments: read 2024-10-08T19:50:03.1220745Z Discussions: read 2024-10-08T19:50:03.1221158Z Issues: read 2024-10-08T19:50:03.1221490Z Metadata: read 2024-10-08T19:50:03.1221934Z Packages: read 2024-10-08T19:50:03.1222341Z Pages: read 2024-10-08T19:50:03.1222681Z PullRequests: read 2024-10-08T19:50:03.1223178Z RepositoryProjects: read 2024-10-08T19:50:03.1223821Z SecurityEvents: read 2024-10-08T19:50:03.1224215Z Statuses: read 2024-10-08T19:50:03.1224703Z ##[endgroup] 2024-10-08T19:50:03.1227911Z Secret source: Actions 2024-10-08T19:50:03.1228498Z Prepare workflow directory 2024-10-08T19:50:03.2164404Z Prepare all required actions 2024-10-08T19:50:03.2333120Z Uses: pytorch/pytorch/.github/workflows/_runner-determinator.yml@refs/pull/134247/merge (cbe39ffc96498585a83508a23de66f3eecb751d5) 2024-10-08T19:50:03.2338699Z ##[group] Inputs 2024-10-08T19:50:03.2339219Z triggering_actor: kwen2501 2024-10-08T19:50:03.2339756Z issue_owner: kwen2501 2024-10-08T19:50:03.2340302Z curr_branch: gh/kwen2501/47/head 2024-10-08T19:50:03.2340833Z curr_ref_type: branch 2024-10-08T19:50:03.2341290Z issue_number: 5132 2024-10-08T19:50:03.2341737Z ##[endgroup] 2024-10-08T19:50:03.2342911Z Complete job name: get-label-type / runner-determinator 2024-10-08T19:50:03.3249684Z ##[group]Run cat < runner_determinator.py 2024-10-08T19:50:03.3251508Z cat < runner_determinator.py 2024-10-08T19:50:03.3252212Z # flake8: noqa: G004 2024-10-08T19:50:03.3252660Z  2024-10-08T19:50:03.3253403Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-10-08T19:50:03.3254884Z # must be kept in sync. You can do it easily by running the following command: 2024-10-08T19:50:03.3255881Z # python .github/scripts/update_runner_determinator.py 2024-10-08T19:50:03.3256573Z  2024-10-08T19:50:03.3256991Z """ 2024-10-08T19:50:03.3257666Z This runner determinator is used to determine which set of runners to run a 2024-10-08T19:50:03.3258776Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-10-08T19:50:03.3260127Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-10-08T19:50:03.3261126Z of which runners should be used to run which job. 2024-10-08T19:50:03.3261793Z  2024-10-08T19:50:03.3262536Z The configuration has two parts, the settings and a list of opted-in users, 2024-10-08T19:50:03.3263737Z separated by a line containing "---". If the line is not present, the 2024-10-08T19:50:03.3264852Z settings are considered to be empty with only the second part, the user 2024-10-08T19:50:03.3265737Z list, defined. 2024-10-08T19:50:03.3266185Z  2024-10-08T19:50:03.3266826Z The first part is a YAML block that defines the rollout settings. This can be 2024-10-08T19:50:03.3268293Z used to define any settings that are needed to determine which runners to use. 2024-10-08T19:50:03.3269364Z It's fields are defined by the RolloutSettings class below. 2024-10-08T19:50:03.3270040Z  2024-10-08T19:50:03.3270791Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-10-08T19:50:03.3271924Z The user list is also a comma separated list of additional features or 2024-10-08T19:50:03.3272815Z experiments which the user could be opted in to. 2024-10-08T19:50:03.3273517Z  2024-10-08T19:50:03.3274204Z The user list has the following rules: 2024-10-08T19:50:03.3274826Z  2024-10-08T19:50:03.3275403Z - Users are GitHub usernames, which must start with the @ prefix 2024-10-08T19:50:03.3276457Z - Each user is also a comma-separated list of features/experiments to enable 2024-10-08T19:50:03.3277476Z - A "#" prefix opts the user out of all experiments 2024-10-08T19:50:03.3278115Z  2024-10-08T19:50:03.3278486Z Example config: 2024-10-08T19:50:03.3279104Z  # A list of experiments that can be opted into. 2024-10-08T19:50:03.3279936Z  # This defines the behavior they'll induce when opted into. 2024-10-08T19:50:03.3280685Z  # Expected syntax is: 2024-10-08T19:50:03.3281549Z  # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-10-08T19:50:03.3282817Z  # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-10-08T19:50:03.3283817Z  2024-10-08T19:50:03.3284258Z  experiments: 2024-10-08T19:50:03.3284712Z  lf: 2024-10-08T19:50:03.3285103Z  rollout_percent: 25 2024-10-08T19:50:03.3285668Z  2024-10-08T19:50:03.3286027Z  --- 2024-10-08T19:50:03.3286371Z  2024-10-08T19:50:03.3286918Z  # Opt-ins: 2024-10-08T19:50:03.3287692Z  # Users can opt into the LF fleet by adding their GitHub username to this list 2024-10-08T19:50:03.3288758Z  # and specifying experiments to enable in a comma-separated list. 2024-10-08T19:50:03.3289901Z  # Experiments should be from the above list. 2024-10-08T19:50:03.3290554Z  2024-10-08T19:50:03.3290920Z  @User1,lf,split_build 2024-10-08T19:50:03.3291487Z  @User2,lf 2024-10-08T19:50:03.3291935Z  @User3,split_build 2024-10-08T19:50:03.3292390Z """ 2024-10-08T19:50:03.3292798Z  2024-10-08T19:50:03.3293167Z import logging 2024-10-08T19:50:03.3293698Z import os 2024-10-08T19:50:03.3294169Z import random 2024-10-08T19:50:03.3294667Z from argparse import ArgumentParser 2024-10-08T19:50:03.3295256Z from logging import LogRecord 2024-10-08T19:50:03.3296097Z from typing import Any, Dict, Iterable, List, NamedTuple, Tuple 2024-10-08T19:50:03.3296870Z  2024-10-08T19:50:03.3297194Z import yaml 2024-10-08T19:50:03.3297717Z from github import Auth, Github 2024-10-08T19:50:03.3298396Z from github.Issue import Issue 2024-10-08T19:50:03.3298931Z  2024-10-08T19:50:03.3299294Z  2024-10-08T19:50:03.3299780Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-10-08T19:50:03.3300631Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-10-08T19:50:03.3301712Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-10-08T19:50:03.3302563Z  2024-10-08T19:50:03.3303036Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-10-08T19:50:03.3303888Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-10-08T19:50:03.3304488Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-10-08T19:50:03.3305065Z  2024-10-08T19:50:03.3305665Z  2024-10-08T19:50:03.3306057Z SETTING_EXPERIMENTS = "experiments" 2024-10-08T19:50:03.3306614Z  2024-10-08T19:50:03.3307068Z LF_FLEET_EXPERIMENT = "lf" 2024-10-08T19:50:03.3307580Z CANARY_FLEET_SUFFIX = ".c" 2024-10-08T19:50:03.3308075Z  2024-10-08T19:50:03.3308489Z  2024-10-08T19:50:03.3308850Z class Experiment(NamedTuple): 2024-10-08T19:50:03.3309428Z  rollout_perc: float = ( 2024-10-08T19:50:03.3310284Z  0 # Percentage of workflows to experiment on when user is not opted-in. 2024-10-08T19:50:03.3311070Z  ) 2024-10-08T19:50:03.3311490Z  all_branches: bool = ( 2024-10-08T19:50:03.3312341Z  False # If True, the experiment is also enabled on the exception branches 2024-10-08T19:50:03.3313115Z  ) 2024-10-08T19:50:03.3313504Z  2024-10-08T19:50:03.3314132Z  # Add more fields as needed 2024-10-08T19:50:03.3314642Z  2024-10-08T19:50:03.3315013Z  2024-10-08T19:50:03.3315446Z class Settings(NamedTuple): 2024-10-08T19:50:03.3315926Z  """ 2024-10-08T19:50:03.3316501Z  Settings for the experiments that can be opted into. 2024-10-08T19:50:03.3317237Z  """ 2024-10-08T19:50:03.3317584Z  2024-10-08T19:50:03.3318046Z  experiments: Dict[str, Experiment] = {} 2024-10-08T19:50:03.3318798Z  2024-10-08T19:50:03.3319129Z  2024-10-08T19:50:03.3319578Z class ColorFormatter(logging.Formatter): 2024-10-08T19:50:03.3320418Z  """Color codes the log messages based on the log level""" 2024-10-08T19:50:03.3321091Z  2024-10-08T19:50:03.3321453Z  COLORS = { 2024-10-08T19:50:03.3322010Z  "WARNING": "\033[33m", # Yellow 2024-10-08T19:50:03.3322604Z  "ERROR": "\033[31m", # Red 2024-10-08T19:50:03.3323199Z  "CRITICAL": "\033[31m", # Red 2024-10-08T19:50:03.3324003Z  "INFO": "\033[0m", # Reset 2024-10-08T19:50:03.3324590Z  "DEBUG": "\033[0m", # Reset 2024-10-08T19:50:03.3325091Z  } 2024-10-08T19:50:03.3325532Z  2024-10-08T19:50:03.3326155Z  def format(self, record: LogRecord) -> str: 2024-10-08T19:50:03.3327079Z  log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-10-08T19:50:03.3328134Z  record.msg = f"{log_color}{record.msg}\033[0m" 2024-10-08T19:50:03.3328837Z  return super().format(record) 2024-10-08T19:50:03.3329359Z  2024-10-08T19:50:03.3329765Z  2024-10-08T19:50:03.3330182Z handler = logging.StreamHandler() 2024-10-08T19:50:03.3331030Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-10-08T19:50:03.3331891Z  2024-10-08T19:50:03.3332408Z log = logging.getLogger(os.path.basename(__file__)) 2024-10-08T19:50:03.3333092Z log.addHandler(handler) 2024-10-08T19:50:03.3333806Z log.setLevel(logging.INFO) 2024-10-08T19:50:03.3334320Z  2024-10-08T19:50:03.3334647Z  2024-10-08T19:50:03.3335224Z def set_github_output(key: str, value: str) -> None: 2024-10-08T19:50:03.3335881Z  """ 2024-10-08T19:50:03.3336478Z  Defines outputs of the github action that invokes this script 2024-10-08T19:50:03.3337264Z  """ 2024-10-08T19:50:03.3337695Z  if not GITHUB_OUTPUT: 2024-10-08T19:50:03.3339070Z  # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-10-08T19:50:03.3340469Z  log.warning( 2024-10-08T19:50:03.3341585Z  "No env var found for GITHUB_OUTPUT, you must be running this code locally. Falling back to the deprecated print method." 2024-10-08T19:50:03.3342866Z  ) 2024-10-08T19:50:03.3343398Z  print(f"::set-output name={key}::{value}") 2024-10-08T19:50:03.3344181Z  return 2024-10-08T19:50:03.3344858Z  2024-10-08T19:50:03.3345318Z  with open(GITHUB_OUTPUT, "a") as f: 2024-10-08T19:50:03.3346044Z  log.info(f"Setting output: {key}='{value}'") 2024-10-08T19:50:03.3346727Z  f.write(f"{key}={value}\n") 2024-10-08T19:50:03.3347330Z  2024-10-08T19:50:03.3347639Z  2024-10-08T19:50:03.3348016Z def parse_args() -> Any: 2024-10-08T19:50:03.3348793Z  parser = ArgumentParser("Get dynamic rollout settings") 2024-10-08T19:50:03.3349826Z  parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-10-08T19:50:03.3350721Z  parser.add_argument( 2024-10-08T19:50:03.3351330Z  "--github-issue-repo", 2024-10-08T19:50:03.3351833Z  type=str, 2024-10-08T19:50:03.3352305Z  required=False, 2024-10-08T19:50:03.3352921Z  default="pytorch/test-infra", 2024-10-08T19:50:03.3353769Z  help="GitHub repo to get the issue", 2024-10-08T19:50:03.3354387Z  ) 2024-10-08T19:50:03.3354855Z  parser.add_argument( 2024-10-08T19:50:03.3355342Z  "--github-repo", 2024-10-08T19:50:03.3355857Z  type=str, 2024-10-08T19:50:03.3356366Z  required=True, 2024-10-08T19:50:03.3356915Z  help="GitHub repo where CI is running", 2024-10-08T19:50:03.3357542Z  ) 2024-10-08T19:50:03.3357994Z  parser.add_argument( 2024-10-08T19:50:03.3358719Z  "--github-issue", type=int, required=True, help="GitHub issue number" 2024-10-08T19:50:03.3359517Z  ) 2024-10-08T19:50:03.3359965Z  parser.add_argument( 2024-10-08T19:50:03.3360763Z  "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-10-08T19:50:03.3361541Z  ) 2024-10-08T19:50:03.3361985Z  parser.add_argument( 2024-10-08T19:50:03.3362806Z  "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-10-08T19:50:03.3363823Z  ) 2024-10-08T19:50:03.3364316Z  parser.add_argument( 2024-10-08T19:50:03.3365161Z  "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-10-08T19:50:03.3365959Z  ) 2024-10-08T19:50:03.3366403Z  parser.add_argument( 2024-10-08T19:50:03.3366942Z  "--github-ref-type", 2024-10-08T19:50:03.3367431Z  type=str, 2024-10-08T19:50:03.3367957Z  required=True, 2024-10-08T19:50:03.3368574Z  help="Current GitHub ref type, branch or tag", 2024-10-08T19:50:03.3369180Z  ) 2024-10-08T19:50:03.3369619Z  2024-10-08T19:50:03.3370033Z  return parser.parse_args() 2024-10-08T19:50:03.3370525Z  2024-10-08T19:50:03.3370946Z  2024-10-08T19:50:03.3371423Z def get_gh_client(github_token: str) -> Github: 2024-10-08T19:50:03.3372074Z  auth = Auth.Token(github_token) 2024-10-08T19:50:03.3372733Z  return Github(auth=auth) 2024-10-08T19:50:03.3373239Z  2024-10-08T19:50:03.3373669Z  2024-10-08T19:50:03.3374341Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-10-08T19:50:03.3375109Z  repo = gh.get_repo(repo) 2024-10-08T19:50:03.3375783Z  return repo.get_issue(number=issue_num) 2024-10-08T19:50:03.3376336Z  2024-10-08T19:50:03.3376678Z  2024-10-08T19:50:03.3377133Z def get_potential_pr_author( 2024-10-08T19:50:03.3377949Z  github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-10-08T19:50:03.3378865Z ) -> str: 2024-10-08T19:50:03.3379598Z  # If the trigger was a new tag added by a bot, this is a ciflow case 2024-10-08T19:50:03.3380623Z  # Fetch the actual username from the original PR. The PR number is 2024-10-08T19:50:03.3381584Z  # embedded in the tag name: ciflow// 2024-10-08T19:50:03.3382266Z  2024-10-08T19:50:03.3382679Z  gh = get_gh_client(github_token) 2024-10-08T19:50:03.3383246Z  2024-10-08T19:50:03.3383933Z  if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-10-08T19:50:03.3384709Z  split_tag = ref_name.split("/") 2024-10-08T19:50:03.3385304Z  if ( 2024-10-08T19:50:03.3385763Z  len(split_tag) == 3 2024-10-08T19:50:03.3386361Z  and split_tag[0] == "ciflow" 2024-10-08T19:50:03.3387010Z  and split_tag[2].isnumeric() 2024-10-08T19:50:03.3387591Z  ): 2024-10-08T19:50:03.3388075Z  pr_number = split_tag[2] 2024-10-08T19:50:03.3388631Z  try: 2024-10-08T19:50:03.3389169Z  repository = gh.get_repo(repo) 2024-10-08T19:50:03.3389965Z  pull = repository.get_pull(number=int(pr_number)) 2024-10-08T19:50:03.3390691Z  except Exception as e: 2024-10-08T19:50:03.3391379Z  raise Exception( # noqa: TRY002 2024-10-08T19:50:03.3392205Z  f"issue with pull request {pr_number} from repo {repository}" 2024-10-08T19:50:03.3392981Z  ) from e 2024-10-08T19:50:03.3393854Z  return pull.user.login 2024-10-08T19:50:03.3394584Z  # In all other cases, return the original input username 2024-10-08T19:50:03.3395303Z  return username 2024-10-08T19:50:03.3395832Z  2024-10-08T19:50:03.3396180Z  2024-10-08T19:50:03.3396651Z def is_exception_branch(branch: str) -> bool: 2024-10-08T19:50:03.3397346Z  """ 2024-10-08T19:50:03.3398120Z  Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-10-08T19:50:03.3399038Z  """ 2024-10-08T19:50:03.3399912Z  return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-10-08T19:50:03.3400686Z  2024-10-08T19:50:03.3401034Z  2024-10-08T19:50:03.3401531Z def load_yaml(yaml_text: str) -> Any: 2024-10-08T19:50:03.3402058Z  try: 2024-10-08T19:50:03.3402532Z  data = yaml.safe_load(yaml_text) 2024-10-08T19:50:03.3403167Z  return data 2024-10-08T19:50:03.3403807Z  except yaml.YAMLError as exc: 2024-10-08T19:50:03.3404432Z  log.exception("Error loading YAML") 2024-10-08T19:50:03.3405078Z  raise 2024-10-08T19:50:03.3405491Z  2024-10-08T19:50:03.3405826Z  2024-10-08T19:50:03.3406584Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-10-08T19:50:03.3407442Z  """ 2024-10-08T19:50:03.3408207Z  Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-10-08T19:50:03.3409160Z  2024-10-08T19:50:03.3409816Z  If the issue body contains "---" then the text above that is the settings 2024-10-08T19:50:03.3410730Z  and the text below is the list of opted in users. 2024-10-08T19:50:03.3411425Z  2024-10-08T19:50:03.3412134Z  If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-10-08T19:50:03.3412942Z  """ 2024-10-08T19:50:03.3413518Z  rollout_state_parts = rollout_state.split("---") 2024-10-08T19:50:03.3414354Z  if len(rollout_state_parts) >= 2: 2024-10-08T19:50:03.3415086Z  return rollout_state_parts[0], rollout_state_parts[1] 2024-10-08T19:50:03.3415945Z  else: 2024-10-08T19:50:03.3416405Z  return "", rollout_state 2024-10-08T19:50:03.3416924Z  2024-10-08T19:50:03.3417300Z  2024-10-08T19:50:03.3417737Z class UserOptins(Dict[str, List[str]]): 2024-10-08T19:50:03.3418322Z  """ 2024-10-08T19:50:03.3418984Z  Dictionary of users with a list of features they have opted into 2024-10-08T19:50:03.3419745Z  """ 2024-10-08T19:50:03.3420113Z  2024-10-08T19:50:03.3420488Z  2024-10-08T19:50:03.3421092Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-10-08T19:50:03.3421856Z  """ 2024-10-08T19:50:03.3422800Z  Parse the user opt-in text into a key value pair of username and the list of features they have opted into 2024-10-08T19:50:03.3423941Z  2024-10-08T19:50:03.3424943Z  Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-10-08T19:50:03.3426259Z  - Example line: "@User1,lf,split_build" 2024-10-08T19:50:03.3427069Z  - A "#" prefix indicates the user is opted out of all experiments 2024-10-08T19:50:03.3427832Z  2024-10-08T19:50:03.3428228Z  2024-10-08T19:50:03.3428544Z  """ 2024-10-08T19:50:03.3428971Z  optins = UserOptins() 2024-10-08T19:50:03.3429639Z  for user in user_optin_text.split("\n"): 2024-10-08T19:50:03.3430262Z  user = user.strip("\r\n\t -") 2024-10-08T19:50:03.3430944Z  if not user or not user.startswith("@"): 2024-10-08T19:50:03.3431668Z  # Not a valid user. Skip 2024-10-08T19:50:03.3432195Z  continue 2024-10-08T19:50:03.3432667Z  2024-10-08T19:50:03.3433076Z  if user: 2024-10-08T19:50:03.3433890Z  usr_name = user.split(",")[0].strip("@") 2024-10-08T19:50:03.3434785Z  optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-10-08T19:50:03.3435602Z  2024-10-08T19:50:03.3435958Z  return optins 2024-10-08T19:50:03.3436544Z  2024-10-08T19:50:03.3436957Z  2024-10-08T19:50:03.3437511Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-10-08T19:50:03.3438247Z  """ 2024-10-08T19:50:03.3439042Z  Parse the experiments from the issue body into a list of ExperimentSettings 2024-10-08T19:50:03.3439880Z  """ 2024-10-08T19:50:03.3440223Z  try: 2024-10-08T19:50:03.3440703Z  if settings_text: 2024-10-08T19:50:03.3441645Z  # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-10-08T19:50:03.3442719Z  # for easy reading 2024-10-08T19:50:03.3443958Z  # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-10-08T19:50:03.3445117Z  # the backtick character in shell commands. 2024-10-08T19:50:03.3445862Z  backtick = chr(96) # backtick character 2024-10-08T19:50:03.3446783Z  settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-10-08T19:50:03.3447587Z  settings = load_yaml(settings_text) 2024-10-08T19:50:03.3448257Z  2024-10-08T19:50:03.3448948Z  # For now we just load experiments. We can expand this if/when we add more settings 2024-10-08T19:50:03.3449856Z  experiments = {} 2024-10-08T19:50:03.3450429Z  2024-10-08T19:50:03.3451056Z  for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-10-08T19:50:03.3451932Z  valid_settings = {} 2024-10-08T19:50:03.3452790Z  for setting in exp_settings: 2024-10-08T19:50:03.3453457Z  if setting not in Experiment._fields: 2024-10-08T19:50:03.3454259Z  log.warning( 2024-10-08T19:50:03.3455208Z  f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-10-08T19:50:03.3456051Z  ) 2024-10-08T19:50:03.3456528Z  else: 2024-10-08T19:50:03.3457223Z  valid_settings[setting] = exp_settings[setting] 2024-10-08T19:50:03.3457884Z  2024-10-08T19:50:03.3458407Z  experiments[exp_name] = Experiment(**valid_settings) 2024-10-08T19:50:03.3459222Z  return Settings(experiments) 2024-10-08T19:50:03.3459801Z  2024-10-08T19:50:03.3460155Z  except Exception: 2024-10-08T19:50:03.3460804Z  log.exception("Failed to parse settings") 2024-10-08T19:50:03.3461494Z  2024-10-08T19:50:03.3461901Z  return Settings() 2024-10-08T19:50:03.3462445Z  2024-10-08T19:50:03.3462806Z  2024-10-08T19:50:03.3463310Z def parse_settings(rollout_state: str) -> Settings: 2024-10-08T19:50:03.3464143Z  """ 2024-10-08T19:50:03.3464703Z  Parse settings, if any, from the rollout state. 2024-10-08T19:50:03.3465299Z  2024-10-08T19:50:03.3465986Z  If the issue body contains "---" then the text above that is the settings 2024-10-08T19:50:03.3467383Z  and the text below is the list of opted in users. 2024-10-08T19:50:03.3468044Z  2024-10-08T19:50:03.3468791Z  If it doesn't contain "---" then the settings are empty and the default values are used. 2024-10-08T19:50:03.3469691Z  """ 2024-10-08T19:50:03.3470340Z  settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-10-08T19:50:03.3471281Z  return parse_settings_from_text(settings_text) 2024-10-08T19:50:03.3471931Z  2024-10-08T19:50:03.3472273Z  2024-10-08T19:50:03.3472779Z def parse_users(rollout_state: str) -> UserOptins: 2024-10-08T19:50:03.3473865Z  """ 2024-10-08T19:50:03.3474357Z  Parse users from the rollout state. 2024-10-08T19:50:03.3474983Z  2024-10-08T19:50:03.3475337Z  """ 2024-10-08T19:50:03.3475969Z  _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-10-08T19:50:03.3476896Z  return parse_user_opt_in_from_text(users_text) 2024-10-08T19:50:03.3477520Z  2024-10-08T19:50:03.3477891Z  2024-10-08T19:50:03.3478628Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-10-08T19:50:03.3479516Z  """ 2024-10-08T19:50:03.3480039Z  Check if a user is opted into an experiment 2024-10-08T19:50:03.3480718Z  """ 2024-10-08T19:50:03.3481233Z  return experiment_name in user_optins.get(user, []) 2024-10-08T19:50:03.3481911Z  2024-10-08T19:50:03.3482300Z  2024-10-08T19:50:03.3482646Z def get_runner_prefix( 2024-10-08T19:50:03.3483164Z  rollout_state: str, 2024-10-08T19:50:03.3483891Z  workflow_requestors: Iterable[str], 2024-10-08T19:50:03.3484450Z  branch: str, 2024-10-08T19:50:03.3484938Z  is_canary: bool = False, 2024-10-08T19:50:03.3485501Z ) -> str: 2024-10-08T19:50:03.3485964Z  settings = parse_settings(rollout_state) 2024-10-08T19:50:03.3486668Z  user_optins = parse_users(rollout_state) 2024-10-08T19:50:03.3487300Z  2024-10-08T19:50:03.3487653Z  fleet_prefix = "" 2024-10-08T19:50:03.3488140Z  prefixes = [] 2024-10-08T19:50:03.3488963Z  for experiment_name, experiment_settings in settings.experiments.items(): 2024-10-08T19:50:03.3489965Z  enabled = False 2024-10-08T19:50:03.3490444Z  2024-10-08T19:50:03.3491172Z  if not experiment_settings.all_branches and is_exception_branch(branch): 2024-10-08T19:50:03.3491980Z  log.info( 2024-10-08T19:50:03.3492833Z  f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-10-08T19:50:03.3493926Z  ) 2024-10-08T19:50:03.3494359Z  continue 2024-10-08T19:50:03.3494778Z  2024-10-08T19:50:03.3495390Z  # Is any workflow_requestor opted in to this experiment? 2024-10-08T19:50:03.3496150Z  opted_in_users = [ 2024-10-08T19:50:03.3496628Z  requestor 2024-10-08T19:50:03.3497258Z  for requestor in workflow_requestors 2024-10-08T19:50:03.3498081Z  if is_user_opted_in(requestor, user_optins, experiment_name) 2024-10-08T19:50:03.3498786Z  ] 2024-10-08T19:50:03.3499240Z  2024-10-08T19:50:03.3499616Z  if opted_in_users: 2024-10-08T19:50:03.3500085Z  log.info( 2024-10-08T19:50:03.3500919Z  f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-10-08T19:50:03.3501726Z  ) 2024-10-08T19:50:03.3502144Z  enabled = True 2024-10-08T19:50:03.3502788Z  elif experiment_settings.rollout_perc: 2024-10-08T19:50:03.3503952Z  # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-10-08T19:50:03.3505160Z  if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-10-08T19:50:03.3505938Z  log.info( 2024-10-08T19:50:03.3507000Z  f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-10-08T19:50:03.3508098Z  ) 2024-10-08T19:50:03.3508581Z  enabled = True 2024-10-08T19:50:03.3509090Z  2024-10-08T19:50:03.3509600Z  if enabled: 2024-10-08T19:50:03.3510152Z  label = experiment_name 2024-10-08T19:50:03.3510858Z  if experiment_name == LF_FLEET_EXPERIMENT: 2024-10-08T19:50:03.3511911Z  # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-10-08T19:50:03.3513081Z  # - If it's enabled, then we always list it's prefix first 2024-10-08T19:50:03.3514336Z  # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-10-08T19:50:03.3515163Z  if is_canary: 2024-10-08T19:50:03.3515841Z  label += CANARY_FLEET_SUFFIX 2024-10-08T19:50:03.3516467Z  fleet_prefix = label 2024-10-08T19:50:03.3517023Z  else: 2024-10-08T19:50:03.3517593Z  prefixes.append(label) 2024-10-08T19:50:03.3518121Z  2024-10-08T19:50:03.3518506Z  if len(prefixes) > 1: 2024-10-08T19:50:03.3519113Z  log.error( 2024-10-08T19:50:03.3520432Z  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-10-08T19:50:03.3521770Z  ) 2024-10-08T19:50:03.3522275Z  prefixes = prefixes[:1] 2024-10-08T19:50:03.3522809Z  2024-10-08T19:50:03.3523165Z  # Fleet always comes first 2024-10-08T19:50:03.3523945Z  if fleet_prefix: 2024-10-08T19:50:03.3524501Z  prefixes.insert(0, fleet_prefix) 2024-10-08T19:50:03.3525204Z  2024-10-08T19:50:03.3525776Z  return ".".join(prefixes) + "." if prefixes else "" 2024-10-08T19:50:03.3526430Z  2024-10-08T19:50:03.3526750Z  2024-10-08T19:50:03.3527524Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-10-08T19:50:03.3528406Z  """ 2024-10-08T19:50:03.3529109Z  Gets the first comment of the issue, which contains the desired rollout state. 2024-10-08T19:50:03.3529991Z  2024-10-08T19:50:03.3530690Z  The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-10-08T19:50:03.3531569Z  """ 2024-10-08T19:50:03.3531981Z  gh = get_gh_client(github_token) 2024-10-08T19:50:03.3532644Z  issue = get_issue(gh, repo, issue_num) 2024-10-08T19:50:03.3533461Z  return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-10-08T19:50:03.3534244Z  2024-10-08T19:50:03.3534615Z  2024-10-08T19:50:03.3535033Z def main() -> None: 2024-10-08T19:50:03.3535477Z  args = parse_args() 2024-10-08T19:50:03.3535972Z  2024-10-08T19:50:03.3536474Z  runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-10-08T19:50:03.3537052Z  2024-10-08T19:50:03.3537415Z  try: 2024-10-08T19:50:03.3537985Z  rollout_state = get_rollout_state_from_issue( 2024-10-08T19:50:03.3538821Z  args.github_token, args.github_issue_repo, args.github_issue 2024-10-08T19:50:03.3539586Z  ) 2024-10-08T19:50:03.3540020Z  2024-10-08T19:50:03.3540441Z  username = get_potential_pr_author( 2024-10-08T19:50:03.3541069Z  args.github_token, 2024-10-08T19:50:03.3541664Z  args.github_repo, 2024-10-08T19:50:03.3542202Z  args.github_actor, 2024-10-08T19:50:03.3542765Z  args.github_ref_type, 2024-10-08T19:50:03.3543406Z  args.github_branch, 2024-10-08T19:50:03.3544036Z  ) 2024-10-08T19:50:03.3544423Z  2024-10-08T19:50:03.3545035Z  is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-10-08T19:50:03.3545858Z  2024-10-08T19:50:03.3546333Z  runner_label_prefix = get_runner_prefix( 2024-10-08T19:50:03.3547039Z  rollout_state, 2024-10-08T19:50:03.3547638Z  (args.github_issue_owner, username), 2024-10-08T19:50:03.3548242Z  args.github_branch, 2024-10-08T19:50:03.3548847Z  is_canary, 2024-10-08T19:50:03.3549441Z  ) 2024-10-08T19:50:03.3549806Z  2024-10-08T19:50:03.3550222Z  except Exception as e: 2024-10-08T19:50:03.3550745Z  log.error( 2024-10-08T19:50:03.3551566Z  f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-10-08T19:50:03.3552526Z  ) 2024-10-08T19:50:03.3552915Z  2024-10-08T19:50:03.3553488Z  set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-10-08T19:50:03.3554530Z  2024-10-08T19:50:03.3554881Z  2024-10-08T19:50:03.3555236Z if __name__ == "__main__": 2024-10-08T19:50:03.3555789Z  main() 2024-10-08T19:50:03.3556203Z  2024-10-08T19:50:03.3556516Z EOF 2024-10-08T19:50:03.3556926Z  2024-10-08T19:50:03.3557337Z cat runner_determinator.py 2024-10-08T19:50:03.3749092Z shell: /usr/bin/bash -e {0} 2024-10-08T19:50:03.3749717Z env: 2024-10-08T19:50:03.3750590Z GITHUB_TOKEN: *** 2024-10-08T19:50:03.3751033Z ISSUE_NUMBER: 5132 2024-10-08T19:50:03.3751524Z TRIGGERING_ACTOR: kwen2501 2024-10-08T19:50:03.3751996Z ISSUE_OWNER: kwen2501 2024-10-08T19:50:03.3752547Z ##[endgroup] 2024-10-08T19:50:03.4170736Z # flake8: noqa: G004 2024-10-08T19:50:03.4171417Z 2024-10-08T19:50:03.4173069Z # Note: Copies of this script in runner_determinator.py and _runner-determinator.yml 2024-10-08T19:50:03.4174500Z # must be kept in sync. You can do it easily by running the following command: 2024-10-08T19:50:03.4175559Z # python .github/scripts/update_runner_determinator.py 2024-10-08T19:50:03.4176051Z 2024-10-08T19:50:03.4176177Z """ 2024-10-08T19:50:03.4176791Z This runner determinator is used to determine which set of runners to run a 2024-10-08T19:50:03.4177854Z GitHub job on. It uses the first comment of a GitHub issue (by default 2024-10-08T19:50:03.4178978Z https://github.com/pytorch/test-infra/issues/5132) to define the configuration 2024-10-08T19:50:03.4179872Z of which runners should be used to run which job. 2024-10-08T19:50:03.4180303Z 2024-10-08T19:50:03.4180868Z The configuration has two parts, the settings and a list of opted-in users, 2024-10-08T19:50:03.4181899Z separated by a line containing "---". If the line is not present, the 2024-10-08T19:50:03.4182879Z settings are considered to be empty with only the second part, the user 2024-10-08T19:50:03.4183907Z list, defined. 2024-10-08T19:50:03.4184145Z 2024-10-08T19:50:03.4184589Z The first part is a YAML block that defines the rollout settings. This can be 2024-10-08T19:50:03.4185626Z used to define any settings that are needed to determine which runners to use. 2024-10-08T19:50:03.4186696Z It's fields are defined by the RolloutSettings class below. 2024-10-08T19:50:03.4187190Z 2024-10-08T19:50:03.4187646Z The second part is a list of users who are explicitly opted in to the LF fleet. 2024-10-08T19:50:03.4188653Z The user list is also a comma separated list of additional features or 2024-10-08T19:50:03.4189527Z experiments which the user could be opted in to. 2024-10-08T19:50:03.4189956Z 2024-10-08T19:50:03.4190173Z The user list has the following rules: 2024-10-08T19:50:03.4190524Z 2024-10-08T19:50:03.4190916Z - Users are GitHub usernames, which must start with the @ prefix 2024-10-08T19:50:03.4191994Z - Each user is also a comma-separated list of features/experiments to enable 2024-10-08T19:50:03.4192917Z - A "#" prefix opts the user out of all experiments 2024-10-08T19:50:03.4193370Z 2024-10-08T19:50:03.4193704Z Example config: 2024-10-08T19:50:03.4194433Z # A list of experiments that can be opted into. 2024-10-08T19:50:03.4195308Z # This defines the behavior they'll induce when opted into. 2024-10-08T19:50:03.4195985Z # Expected syntax is: 2024-10-08T19:50:03.4196707Z # [experiment_name]: # Name of the experiment. Also used for the label prefix. 2024-10-08T19:50:03.4197869Z # rollout_perc: [int] # % of workflows to run with this experiment when users are not opted in. 2024-10-08T19:50:03.4198574Z 2024-10-08T19:50:03.4198753Z experiments: 2024-10-08T19:50:03.4199149Z lf: 2024-10-08T19:50:03.4199538Z rollout_percent: 25 2024-10-08T19:50:03.4199823Z 2024-10-08T19:50:03.4200014Z --- 2024-10-08T19:50:03.4200198Z 2024-10-08T19:50:03.4200422Z # Opt-ins: 2024-10-08T19:50:03.4201087Z # Users can opt into the LF fleet by adding their GitHub username to this list 2024-10-08T19:50:03.4202126Z # and specifying experiments to enable in a comma-separated list. 2024-10-08T19:50:03.4202930Z # Experiments should be from the above list. 2024-10-08T19:50:03.4203401Z 2024-10-08T19:50:03.4203763Z @User1,lf,split_build 2024-10-08T19:50:03.4204249Z @User2,lf 2024-10-08T19:50:03.4204712Z @User3,split_build 2024-10-08T19:50:03.4205083Z """ 2024-10-08T19:50:03.4205291Z 2024-10-08T19:50:03.4205428Z import logging 2024-10-08T19:50:03.4205870Z import os 2024-10-08T19:50:03.4206195Z import random 2024-10-08T19:50:03.4206605Z from argparse import ArgumentParser 2024-10-08T19:50:03.4207176Z from logging import LogRecord 2024-10-08T19:50:03.4207833Z from typing import Any, Dict, Iterable, List, NamedTuple, Tuple 2024-10-08T19:50:03.4208399Z 2024-10-08T19:50:03.4208536Z import yaml 2024-10-08T19:50:03.4208998Z from github import Auth, Github 2024-10-08T19:50:03.4209654Z from github.Issue import Issue 2024-10-08T19:50:03.4210017Z 2024-10-08T19:50:03.4210022Z 2024-10-08T19:50:03.4210227Z DEFAULT_LABEL_PREFIX = "" # use meta runners 2024-10-08T19:50:03.4211035Z WORKFLOW_LABEL_LF = "lf." # use runners from the linux foundation 2024-10-08T19:50:03.4211977Z WORKFLOW_LABEL_LF_CANARY = "lf.c." # use canary runners from the linux foundation 2024-10-08T19:50:03.4212648Z 2024-10-08T19:50:03.4212862Z GITHUB_OUTPUT = os.getenv("GITHUB_OUTPUT", "") 2024-10-08T19:50:03.4213751Z GH_OUTPUT_KEY_AMI = "runner-ami" 2024-10-08T19:50:03.4214327Z GH_OUTPUT_KEY_LABEL_TYPE = "label-type" 2024-10-08T19:50:03.4214748Z 2024-10-08T19:50:03.4214753Z 2024-10-08T19:50:03.4214925Z SETTING_EXPERIMENTS = "experiments" 2024-10-08T19:50:03.4215368Z 2024-10-08T19:50:03.4215529Z LF_FLEET_EXPERIMENT = "lf" 2024-10-08T19:50:03.4216010Z CANARY_FLEET_SUFFIX = ".c" 2024-10-08T19:50:03.4216287Z 2024-10-08T19:50:03.4216292Z 2024-10-08T19:50:03.4216457Z class Experiment(NamedTuple): 2024-10-08T19:50:03.4217002Z rollout_perc: float = ( 2024-10-08T19:50:03.4217787Z 0 # Percentage of workflows to experiment on when user is not opted-in. 2024-10-08T19:50:03.4218494Z ) 2024-10-08T19:50:03.4218905Z all_branches: bool = ( 2024-10-08T19:50:03.4219617Z False # If True, the experiment is also enabled on the exception branches 2024-10-08T19:50:03.4220336Z ) 2024-10-08T19:50:03.4220597Z 2024-10-08T19:50:03.4220760Z # Add more fields as needed 2024-10-08T19:50:03.4221088Z 2024-10-08T19:50:03.4221093Z 2024-10-08T19:50:03.4221287Z class Settings(NamedTuple): 2024-10-08T19:50:03.4221700Z """ 2024-10-08T19:50:03.4222231Z Settings for the experiments that can be opted into. 2024-10-08T19:50:03.4222868Z """ 2024-10-08T19:50:03.4223046Z 2024-10-08T19:50:03.4223237Z experiments: Dict[str, Experiment] = {} 2024-10-08T19:50:03.4223904Z 2024-10-08T19:50:03.4223910Z 2024-10-08T19:50:03.4224139Z class ColorFormatter(logging.Formatter): 2024-10-08T19:50:03.4224827Z """Color codes the log messages based on the log level""" 2024-10-08T19:50:03.4225296Z 2024-10-08T19:50:03.4225467Z COLORS = { 2024-10-08T19:50:03.4225903Z "WARNING": "\033[33m", # Yellow 2024-10-08T19:50:03.4226441Z "ERROR": "\033[31m", # Red 2024-10-08T19:50:03.4227119Z "CRITICAL": "\033[31m", # Red 2024-10-08T19:50:03.4227674Z "INFO": "\033[0m", # Reset 2024-10-08T19:50:03.4228177Z "DEBUG": "\033[0m", # Reset 2024-10-08T19:50:03.4228676Z } 2024-10-08T19:50:03.4228910Z 2024-10-08T19:50:03.4229178Z def format(self, record: LogRecord) -> str: 2024-10-08T19:50:03.4230019Z log_color = self.COLORS.get(record.levelname, "\033[0m") # Default to reset 2024-10-08T19:50:03.4230930Z record.msg = f"{log_color}{record.msg}\033[0m" 2024-10-08T19:50:03.4231572Z return super().format(record) 2024-10-08T19:50:03.4231949Z 2024-10-08T19:50:03.4231954Z 2024-10-08T19:50:03.4232131Z handler = logging.StreamHandler() 2024-10-08T19:50:03.4232966Z handler.setFormatter(ColorFormatter(fmt="%(levelname)-8s: %(message)s")) 2024-10-08T19:50:03.4233784Z 2024-10-08T19:50:03.4234082Z log = logging.getLogger(os.path.basename(__file__)) 2024-10-08T19:50:03.4234680Z log.addHandler(handler) 2024-10-08T19:50:03.4235157Z log.setLevel(logging.INFO) 2024-10-08T19:50:03.4235504Z 2024-10-08T19:50:03.4235508Z 2024-10-08T19:50:03.4235839Z def set_github_output(key: str, value: str) -> None: 2024-10-08T19:50:03.4236401Z """ 2024-10-08T19:50:03.4236938Z Defines outputs of the github action that invokes this script 2024-10-08T19:50:03.4237659Z """ 2024-10-08T19:50:03.4237998Z if not GITHUB_OUTPUT: 2024-10-08T19:50:03.4239340Z # See https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ for deprecation notice 2024-10-08T19:50:03.4240713Z log.warning( 2024-10-08T19:50:03.4241664Z "No env var found for GITHUB_OUTPUT, you must be running this code locally. Falling back to the deprecated print method." 2024-10-08T19:50:03.4242879Z ) 2024-10-08T19:50:03.4267121Z print(f"::set-output name={key}::{value}") 2024-10-08T19:50:03.4267763Z return 2024-10-08T19:50:03.4267981Z 2024-10-08T19:50:03.4268173Z with open(GITHUB_OUTPUT, "a") as f: 2024-10-08T19:50:03.4268952Z log.info(f"Setting output: {key}='{value}'") 2024-10-08T19:50:03.4269570Z f.write(f"{key}={value}\n") 2024-10-08T19:50:03.4269906Z 2024-10-08T19:50:03.4269912Z 2024-10-08T19:50:03.4270222Z def parse_args() -> Any: 2024-10-08T19:50:03.4270784Z parser = ArgumentParser("Get dynamic rollout settings") 2024-10-08T19:50:03.4271800Z parser.add_argument("--github-token", type=str, required=True, help="GitHub token") 2024-10-08T19:50:03.4272704Z parser.add_argument( 2024-10-08T19:50:03.4273163Z "--github-issue-repo", 2024-10-08T19:50:03.4273858Z type=str, 2024-10-08T19:50:03.4274355Z required=False, 2024-10-08T19:50:03.4274847Z default="pytorch/test-infra", 2024-10-08T19:50:03.4275413Z help="GitHub repo to get the issue", 2024-10-08T19:50:03.4276020Z ) 2024-10-08T19:50:03.4276352Z parser.add_argument( 2024-10-08T19:50:03.4276832Z "--github-repo", 2024-10-08T19:50:03.4277325Z type=str, 2024-10-08T19:50:03.4277692Z required=True, 2024-10-08T19:50:03.4278186Z help="GitHub repo where CI is running", 2024-10-08T19:50:03.4278697Z ) 2024-10-08T19:50:03.4279105Z parser.add_argument( 2024-10-08T19:50:03.4279834Z "--github-issue", type=int, required=True, help="GitHub issue number" 2024-10-08T19:50:03.4280511Z ) 2024-10-08T19:50:03.4280919Z parser.add_argument( 2024-10-08T19:50:03.4281660Z "--github-actor", type=str, required=True, help="GitHub triggering_actor" 2024-10-08T19:50:03.4282455Z ) 2024-10-08T19:50:03.4282776Z parser.add_argument( 2024-10-08T19:50:03.4283748Z "--github-issue-owner", type=str, required=True, help="GitHub issue owner" 2024-10-08T19:50:03.4284621Z ) 2024-10-08T19:50:03.4284948Z parser.add_argument( 2024-10-08T19:50:03.4285748Z "--github-branch", type=str, required=True, help="Current GitHub branch or tag" 2024-10-08T19:50:03.4286588Z ) 2024-10-08T19:50:03.4286911Z parser.add_argument( 2024-10-08T19:50:03.4287584Z "--github-ref-type", 2024-10-08T19:50:03.4288027Z type=str, 2024-10-08T19:50:03.4288517Z required=True, 2024-10-08T19:50:03.4289029Z help="Current GitHub ref type, branch or tag", 2024-10-08T19:50:03.4289580Z ) 2024-10-08T19:50:03.4289863Z 2024-10-08T19:50:03.4290037Z return parser.parse_args() 2024-10-08T19:50:03.4290384Z 2024-10-08T19:50:03.4290388Z 2024-10-08T19:50:03.4290668Z def get_gh_client(github_token: str) -> Github: 2024-10-08T19:50:03.4291355Z auth = Auth.Token(github_token) 2024-10-08T19:50:03.4291845Z return Github(auth=auth) 2024-10-08T19:50:03.4292172Z 2024-10-08T19:50:03.4292177Z 2024-10-08T19:50:03.4292539Z def get_issue(gh: Github, repo: str, issue_num: int) -> Issue: 2024-10-08T19:50:03.4293311Z repo = gh.get_repo(repo) 2024-10-08T19:50:03.4294161Z return repo.get_issue(number=issue_num) 2024-10-08T19:50:03.4294586Z 2024-10-08T19:50:03.4294591Z 2024-10-08T19:50:03.4294752Z def get_potential_pr_author( 2024-10-08T19:50:03.4295537Z github_token: str, repo: str, username: str, ref_type: str, ref_name: str 2024-10-08T19:50:03.4296318Z ) -> str: 2024-10-08T19:50:03.4296847Z # If the trigger was a new tag added by a bot, this is a ciflow case 2024-10-08T19:50:03.4297833Z # Fetch the actual username from the original PR. The PR number is 2024-10-08T19:50:03.4298708Z # embedded in the tag name: ciflow// 2024-10-08T19:50:03.4299155Z 2024-10-08T19:50:03.4299320Z gh = get_gh_client(github_token) 2024-10-08T19:50:03.4299717Z 2024-10-08T19:50:03.4300082Z if username == "pytorch-bot[bot]" and ref_type == "tag": 2024-10-08T19:50:03.4300756Z split_tag = ref_name.split("/") 2024-10-08T19:50:03.4301457Z if ( 2024-10-08T19:50:03.4301895Z len(split_tag) == 3 2024-10-08T19:50:03.4302399Z and split_tag[0] == "ciflow" 2024-10-08T19:50:03.4302931Z and split_tag[2].isnumeric() 2024-10-08T19:50:03.4303488Z ): 2024-10-08T19:50:03.4304072Z pr_number = split_tag[2] 2024-10-08T19:50:03.4304563Z try: 2024-10-08T19:50:03.4305059Z repository = gh.get_repo(repo) 2024-10-08T19:50:03.4305758Z pull = repository.get_pull(number=int(pr_number)) 2024-10-08T19:50:03.4306377Z except Exception as e: 2024-10-08T19:50:03.4306976Z raise Exception( # noqa: TRY002 2024-10-08T19:50:03.4307759Z f"issue with pull request {pr_number} from repo {repository}" 2024-10-08T19:50:03.4308432Z ) from e 2024-10-08T19:50:03.4308925Z return pull.user.login 2024-10-08T19:50:03.4309564Z # In all other cases, return the original input username 2024-10-08T19:50:03.4310177Z return username 2024-10-08T19:50:03.4310442Z 2024-10-08T19:50:03.4310447Z 2024-10-08T19:50:03.4310762Z def is_exception_branch(branch: str) -> bool: 2024-10-08T19:50:03.4311347Z """ 2024-10-08T19:50:03.4312097Z Branches that get opted out of experiments by default, until they're explicitly enabled. 2024-10-08T19:50:03.4313006Z """ 2024-10-08T19:50:03.4313737Z return branch.split("/")[0] in {"main", "nightly", "release", "landchecks"} 2024-10-08T19:50:03.4314335Z 2024-10-08T19:50:03.4314340Z 2024-10-08T19:50:03.4314596Z def load_yaml(yaml_text: str) -> Any: 2024-10-08T19:50:03.4315133Z try: 2024-10-08T19:50:03.4315545Z data = yaml.safe_load(yaml_text) 2024-10-08T19:50:03.4316077Z return data 2024-10-08T19:50:03.4316549Z except yaml.YAMLError as exc: 2024-10-08T19:50:03.4317091Z log.exception("Error loading YAML") 2024-10-08T19:50:03.4317630Z raise 2024-10-08T19:50:03.4317830Z 2024-10-08T19:50:03.4317834Z 2024-10-08T19:50:03.4318402Z def extract_settings_user_opt_in_from_text(rollout_state: str) -> Tuple[str, str]: 2024-10-08T19:50:03.4319202Z """ 2024-10-08T19:50:03.4319884Z Extracts the text with settings, if any, and the opted in users from the rollout state. 2024-10-08T19:50:03.4320582Z 2024-10-08T19:50:03.4321212Z If the issue body contains "---" then the text above that is the settings 2024-10-08T19:50:03.4322084Z and the text below is the list of opted in users. 2024-10-08T19:50:03.4322575Z 2024-10-08T19:50:03.4323086Z If it doesn't contain "---" then the settings are empty and the rest is the users. 2024-10-08T19:50:03.4324072Z """ 2024-10-08T19:50:03.4324536Z rollout_state_parts = rollout_state.split("---") 2024-10-08T19:50:03.4325196Z if len(rollout_state_parts) >= 2: 2024-10-08T19:50:03.4325881Z return rollout_state_parts[0], rollout_state_parts[1] 2024-10-08T19:50:03.4326471Z else: 2024-10-08T19:50:03.4326860Z return "", rollout_state 2024-10-08T19:50:03.4327175Z 2024-10-08T19:50:03.4327180Z 2024-10-08T19:50:03.4327442Z class UserOptins(Dict[str, List[str]]): 2024-10-08T19:50:03.4327934Z """ 2024-10-08T19:50:03.4328523Z Dictionary of users with a list of features they have opted into 2024-10-08T19:50:03.4329271Z """ 2024-10-08T19:50:03.4329450Z 2024-10-08T19:50:03.4329461Z 2024-10-08T19:50:03.4329871Z def parse_user_opt_in_from_text(user_optin_text: str) -> UserOptins: 2024-10-08T19:50:03.4330591Z """ 2024-10-08T19:50:03.4331533Z Parse the user opt-in text into a key value pair of username and the list of features they have opted into 2024-10-08T19:50:03.4332351Z 2024-10-08T19:50:03.4333206Z Users are GitHub usernames with the @ prefix. Each user is also a comma-separated list of features/experiments to enable. 2024-10-08T19:50:03.4334573Z - Example line: "@User1,lf,split_build" 2024-10-08T19:50:03.4335442Z - A "#" prefix indicates the user is opted out of all experiments 2024-10-08T19:50:03.4335965Z 2024-10-08T19:50:03.4336129Z 2024-10-08T19:50:03.4336303Z """ 2024-10-08T19:50:03.4336634Z optins = UserOptins() 2024-10-08T19:50:03.4337213Z for user in user_optin_text.split("\n"): 2024-10-08T19:50:03.4337866Z user = user.strip("\r\n\t -") 2024-10-08T19:50:03.4338413Z if not user or not user.startswith("@"): 2024-10-08T19:50:03.4339075Z # Not a valid user. Skip 2024-10-08T19:50:03.4339585Z continue 2024-10-08T19:50:03.4339826Z 2024-10-08T19:50:03.4339959Z if user: 2024-10-08T19:50:03.4340475Z usr_name = user.split(",")[0].strip("@") 2024-10-08T19:50:03.4341253Z optins[usr_name] = [exp.strip(" ") for exp in user.split(",")[1:]] 2024-10-08T19:50:03.4341799Z 2024-10-08T19:50:03.4341941Z return optins 2024-10-08T19:50:03.4342264Z 2024-10-08T19:50:03.4342268Z 2024-10-08T19:50:03.4342628Z def parse_settings_from_text(settings_text: str) -> Settings: 2024-10-08T19:50:03.4343292Z """ 2024-10-08T19:50:03.4344069Z Parse the experiments from the issue body into a list of ExperimentSettings 2024-10-08T19:50:03.4344896Z """ 2024-10-08T19:50:03.4345271Z try: 2024-10-08T19:50:03.4345648Z if settings_text: 2024-10-08T19:50:03.4346482Z # Escape the backtick as well so that we can have the settings in a code block on the GH issue 2024-10-08T19:50:03.4347390Z # for easy reading 2024-10-08T19:50:03.4348395Z # Note: Using ascii for the backtick so that the cat step in _runner-determinator.yml doesn't choke on 2024-10-08T19:50:03.4349455Z # the backtick character in shell commands. 2024-10-08T19:50:03.4350139Z backtick = chr(96) # backtick character 2024-10-08T19:50:03.4350880Z settings_text = settings_text.strip(f"\r\n\t{backtick} ") 2024-10-08T19:50:03.4351608Z settings = load_yaml(settings_text) 2024-10-08T19:50:03.4352030Z 2024-10-08T19:50:03.4352488Z # For now we just load experiments. We can expand this if/when we add more settings 2024-10-08T19:50:03.4353353Z experiments = {} 2024-10-08T19:50:03.4353809Z 2024-10-08T19:50:03.4354237Z for exp_name, exp_settings in settings.get(SETTING_EXPERIMENTS).items(): 2024-10-08T19:50:03.4354986Z valid_settings = {} 2024-10-08T19:50:03.4355680Z for setting in exp_settings: 2024-10-08T19:50:03.4356379Z if setting not in Experiment._fields: 2024-10-08T19:50:03.4356957Z log.warning( 2024-10-08T19:50:03.4357722Z f"Unexpected setting in experiment: {setting} = {exp_settings[setting]}" 2024-10-08T19:50:03.4358551Z ) 2024-10-08T19:50:03.4358954Z else: 2024-10-08T19:50:03.4359491Z valid_settings[setting] = exp_settings[setting] 2024-10-08T19:50:03.4360002Z 2024-10-08T19:50:03.4360324Z experiments[exp_name] = Experiment(**valid_settings) 2024-10-08T19:50:03.4360961Z return Settings(experiments) 2024-10-08T19:50:03.4361364Z 2024-10-08T19:50:03.4361508Z except Exception: 2024-10-08T19:50:03.4362161Z log.exception("Failed to parse settings") 2024-10-08T19:50:03.4362574Z 2024-10-08T19:50:03.4362718Z return Settings() 2024-10-08T19:50:03.4362994Z 2024-10-08T19:50:03.4363006Z 2024-10-08T19:50:03.4363298Z def parse_settings(rollout_state: str) -> Settings: 2024-10-08T19:50:03.4364095Z """ 2024-10-08T19:50:03.4364549Z Parse settings, if any, from the rollout state. 2024-10-08T19:50:03.4364980Z 2024-10-08T19:50:03.4365423Z If the issue body contains "---" then the text above that is the settings 2024-10-08T19:50:03.4366350Z and the text below is the list of opted in users. 2024-10-08T19:50:03.4366790Z 2024-10-08T19:50:03.4367349Z If it doesn't contain "---" then the settings are empty and the default values are used. 2024-10-08T19:50:03.4368144Z """ 2024-10-08T19:50:03.4368783Z settings_text, _ = extract_settings_user_opt_in_from_text(rollout_state) 2024-10-08T19:50:03.4369747Z return parse_settings_from_text(settings_text) 2024-10-08T19:50:03.4370164Z 2024-10-08T19:50:03.4370168Z 2024-10-08T19:50:03.4370466Z def parse_users(rollout_state: str) -> UserOptins: 2024-10-08T19:50:03.4371125Z """ 2024-10-08T19:50:03.4371514Z Parse users from the rollout state. 2024-10-08T19:50:03.4371895Z 2024-10-08T19:50:03.4372133Z """ 2024-10-08T19:50:03.4372647Z _, users_text = extract_settings_user_opt_in_from_text(rollout_state) 2024-10-08T19:50:03.4373437Z return parse_user_opt_in_from_text(users_text) 2024-10-08T19:50:03.4374142Z 2024-10-08T19:50:03.4374147Z 2024-10-08T19:50:03.4374777Z def is_user_opted_in(user: str, user_optins: UserOptins, experiment_name: str) -> bool: 2024-10-08T19:50:03.4375574Z """ 2024-10-08T19:50:03.4376013Z Check if a user is opted into an experiment 2024-10-08T19:50:03.4376618Z """ 2024-10-08T19:50:03.4377040Z return experiment_name in user_optins.get(user, []) 2024-10-08T19:50:03.4377527Z 2024-10-08T19:50:03.4377532Z 2024-10-08T19:50:03.4377698Z def get_runner_prefix( 2024-10-08T19:50:03.4378183Z rollout_state: str, 2024-10-08T19:50:03.4378611Z workflow_requestors: Iterable[str], 2024-10-08T19:50:03.4379159Z branch: str, 2024-10-08T19:50:03.4379606Z is_canary: bool = False, 2024-10-08T19:50:03.4380066Z ) -> str: 2024-10-08T19:50:03.4380504Z settings = parse_settings(rollout_state) 2024-10-08T19:50:03.4381173Z user_optins = parse_users(rollout_state) 2024-10-08T19:50:03.4381563Z 2024-10-08T19:50:03.4381707Z fleet_prefix = "" 2024-10-08T19:50:03.4382139Z prefixes = [] 2024-10-08T19:50:03.4382860Z for experiment_name, experiment_settings in settings.experiments.items(): 2024-10-08T19:50:03.4383734Z enabled = False 2024-10-08T19:50:03.4384057Z 2024-10-08T19:50:03.4384455Z if not experiment_settings.all_branches and is_exception_branch(branch): 2024-10-08T19:50:03.4385300Z log.info( 2024-10-08T19:50:03.4386062Z f"Branch {branch} is an exception branch. Not enabling experiment {experiment_name}." 2024-10-08T19:50:03.4386875Z ) 2024-10-08T19:50:03.4387300Z continue 2024-10-08T19:50:03.4387546Z 2024-10-08T19:50:03.4387880Z # Is any workflow_requestor opted in to this experiment? 2024-10-08T19:50:03.4388644Z opted_in_users = [ 2024-10-08T19:50:03.4389176Z requestor 2024-10-08T19:50:03.4389656Z for requestor in workflow_requestors 2024-10-08T19:50:03.4390358Z if is_user_opted_in(requestor, user_optins, experiment_name) 2024-10-08T19:50:03.4391097Z ] 2024-10-08T19:50:03.4391285Z 2024-10-08T19:50:03.4391468Z if opted_in_users: 2024-10-08T19:50:03.4391980Z log.info( 2024-10-08T19:50:03.4392779Z f"{', '.join(opted_in_users)} have opted into experiment {experiment_name}." 2024-10-08T19:50:03.4393530Z ) 2024-10-08T19:50:03.4394249Z enabled = True 2024-10-08T19:50:03.4394858Z elif experiment_settings.rollout_perc: 2024-10-08T19:50:03.4395845Z # If no user is opted in, then we randomly enable the experiment based on the rollout percentage 2024-10-08T19:50:03.4396906Z if random.uniform(0, 100) <= experiment_settings.rollout_perc: 2024-10-08T19:50:03.4397703Z log.info( 2024-10-08T19:50:03.4398656Z f"Based on rollout percentage of {experiment_settings.rollout_perc}%, enabling experiment {experiment_name}." 2024-10-08T19:50:03.4399634Z ) 2024-10-08T19:50:03.4400115Z enabled = True 2024-10-08T19:50:03.4400423Z 2024-10-08T19:50:03.4400606Z if enabled: 2024-10-08T19:50:03.4401017Z label = experiment_name 2024-10-08T19:50:03.4401673Z if experiment_name == LF_FLEET_EXPERIMENT: 2024-10-08T19:50:03.4402629Z # We give some special treatment to the "lf" experiment since determines the fleet we use 2024-10-08T19:50:03.4404029Z # - If it's enabled, then we always list it's prefix first 2024-10-08T19:50:03.4405213Z # - If we're in the canary branch, then we append ".c" to the lf prefix 2024-10-08T19:50:03.4405988Z if is_canary: 2024-10-08T19:50:03.4406492Z label += CANARY_FLEET_SUFFIX 2024-10-08T19:50:03.4407087Z fleet_prefix = label 2024-10-08T19:50:03.4407612Z else: 2024-10-08T19:50:03.4408031Z prefixes.append(label) 2024-10-08T19:50:03.4408383Z 2024-10-08T19:50:03.4408587Z if len(prefixes) > 1: 2024-10-08T19:50:03.4409045Z log.error( 2024-10-08T19:50:03.4410408Z 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-10-08T19:50:03.4411740Z ) 2024-10-08T19:50:03.4412138Z prefixes = prefixes[:1] 2024-10-08T19:50:03.4412451Z 2024-10-08T19:50:03.4412647Z # Fleet always comes first 2024-10-08T19:50:03.4413142Z if fleet_prefix: 2024-10-08T19:50:03.4413886Z prefixes.insert(0, fleet_prefix) 2024-10-08T19:50:03.4414261Z 2024-10-08T19:50:03.4414542Z return ".".join(prefixes) + "." if prefixes else "" 2024-10-08T19:50:03.4414979Z 2024-10-08T19:50:03.4414984Z 2024-10-08T19:50:03.4415632Z def get_rollout_state_from_issue(github_token: str, repo: str, issue_num: int) -> str: 2024-10-08T19:50:03.4416426Z """ 2024-10-08T19:50:03.4417051Z Gets the first comment of the issue, which contains the desired rollout state. 2024-10-08T19:50:03.4417676Z 2024-10-08T19:50:03.4418258Z The default issue we use - https://github.com/pytorch/test-infra/issues/5132 2024-10-08T19:50:03.4419008Z """ 2024-10-08T19:50:03.4419383Z gh = get_gh_client(github_token) 2024-10-08T19:50:03.4420002Z issue = get_issue(gh, repo, issue_num) 2024-10-08T19:50:03.4420643Z return str(issue.get_comments()[0].body.strip("\n\t ")) 2024-10-08T19:50:03.4421145Z 2024-10-08T19:50:03.4421150Z 2024-10-08T19:50:03.4421332Z def main() -> None: 2024-10-08T19:50:03.4421811Z args = parse_args() 2024-10-08T19:50:03.4422070Z 2024-10-08T19:50:03.4422272Z runner_label_prefix = DEFAULT_LABEL_PREFIX 2024-10-08T19:50:03.4422708Z 2024-10-08T19:50:03.4422840Z try: 2024-10-08T19:50:03.4423484Z rollout_state = get_rollout_state_from_issue( 2024-10-08T19:50:03.4424407Z args.github_token, args.github_issue_repo, args.github_issue 2024-10-08T19:50:03.4425070Z ) 2024-10-08T19:50:03.4425353Z 2024-10-08T19:50:03.4425543Z username = get_potential_pr_author( 2024-10-08T19:50:03.4426110Z args.github_token, 2024-10-08T19:50:03.4426580Z args.github_repo, 2024-10-08T19:50:03.4427104Z args.github_actor, 2024-10-08T19:50:03.4427596Z args.github_ref_type, 2024-10-08T19:50:03.4428060Z args.github_branch, 2024-10-08T19:50:03.4428567Z ) 2024-10-08T19:50:03.4428754Z 2024-10-08T19:50:03.4429156Z is_canary = args.github_repo == "pytorch/pytorch-canary" 2024-10-08T19:50:03.4429652Z 2024-10-08T19:50:03.4429853Z runner_label_prefix = get_runner_prefix( 2024-10-08T19:50:03.4430481Z rollout_state, 2024-10-08T19:50:03.4430991Z (args.github_issue_owner, username), 2024-10-08T19:50:03.4431536Z args.github_branch, 2024-10-08T19:50:03.4432052Z is_canary, 2024-10-08T19:50:03.4432470Z ) 2024-10-08T19:50:03.4432655Z 2024-10-08T19:50:03.4432816Z except Exception as e: 2024-10-08T19:50:03.4433363Z log.error( 2024-10-08T19:50:03.4434245Z f"Failed to get issue. Defaulting to Meta runners and no experiments. Exception: {e}" 2024-10-08T19:50:03.4435053Z ) 2024-10-08T19:50:03.4435331Z 2024-10-08T19:50:03.4435660Z set_github_output(GH_OUTPUT_KEY_LABEL_TYPE, runner_label_prefix) 2024-10-08T19:50:03.4436245Z 2024-10-08T19:50:03.4436250Z 2024-10-08T19:50:03.4436398Z if __name__ == "__main__": 2024-10-08T19:50:03.4436831Z main() 2024-10-08T19:50:03.4437232Z 2024-10-08T19:50:03.4638071Z ##[group]Run python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-10-08T19:50:03.4639062Z python3 -m pip install urllib3==1.26.18 PyGithub==2.3.0 2024-10-08T19:50:03.4663513Z shell: /usr/bin/bash -e {0} 2024-10-08T19:50:03.4664266Z env: 2024-10-08T19:50:03.4664885Z GITHUB_TOKEN: *** 2024-10-08T19:50:03.4665313Z ISSUE_NUMBER: 5132 2024-10-08T19:50:03.4665823Z TRIGGERING_ACTOR: kwen2501 2024-10-08T19:50:03.4666265Z ISSUE_OWNER: kwen2501 2024-10-08T19:50:03.4666710Z ##[endgroup] 2024-10-08T19:50:03.8462803Z Defaulting to user installation because normal site-packages is not writeable 2024-10-08T19:50:04.1415109Z Collecting urllib3==1.26.18 2024-10-08T19:50:04.1954504Z Downloading urllib3-1.26.18-py2.py3-none-any.whl (143 kB) 2024-10-08T19:50:04.2200171Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 143.8/143.8 KB 6.2 MB/s eta 0:00:00 2024-10-08T19:50:04.2525170Z Collecting PyGithub==2.3.0 2024-10-08T19:50:04.2616711Z Downloading PyGithub-2.3.0-py3-none-any.whl (354 kB) 2024-10-08T19:50:04.2926171Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 354.4/354.4 KB 12.0 MB/s eta 0:00:00 2024-10-08T19:50:04.3351063Z Collecting Deprecated 2024-10-08T19:50:04.3446506Z Downloading Deprecated-1.2.14-py2.py3-none-any.whl (9.6 kB) 2024-10-08T19:50:04.3481769Z Requirement already satisfied: requests>=2.14.0 in /usr/lib/python3/dist-packages (from PyGithub==2.3.0) (2.25.1) 2024-10-08T19:50:04.3817782Z Collecting pynacl>=1.4.0 2024-10-08T19:50:04.3912641Z Downloading PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (856 kB) 2024-10-08T19:50:04.4504622Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 856.7/856.7 KB 14.9 MB/s eta 0:00:00 2024-10-08T19:50:04.4968249Z Collecting pyjwt[crypto]>=2.4.0 2024-10-08T19:50:04.5059739Z Downloading PyJWT-2.9.0-py3-none-any.whl (22 kB) 2024-10-08T19:50:04.5358296Z Collecting typing-extensions>=4.0.0 2024-10-08T19:50:04.5453274Z Downloading typing_extensions-4.12.2-py3-none-any.whl (37 kB) 2024-10-08T19:50:04.5640317Z 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-10-08T19:50:04.7879164Z Collecting cffi>=1.4.1 2024-10-08T19:50:04.7971981Z Downloading cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (446 kB) 2024-10-08T19:50:04.8228092Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 446.2/446.2 KB 18.8 MB/s eta 0:00:00 2024-10-08T19:50:04.9915697Z Collecting wrapt<2,>=1.10 2024-10-08T19:50:05.0010968Z 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-10-08T19:50:05.0049815Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.3/80.3 KB 35.4 MB/s eta 0:00:00 2024-10-08T19:50:05.0216032Z Collecting pycparser 2024-10-08T19:50:05.0306340Z Downloading pycparser-2.22-py3-none-any.whl (117 kB) 2024-10-08T19:50:05.0403949Z ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 117.6/117.6 KB 14.4 MB/s eta 0:00:00 2024-10-08T19:50:05.2155632Z Installing collected packages: wrapt, urllib3, typing-extensions, pyjwt, pycparser, Deprecated, cffi, pynacl, PyGithub 2024-10-08T19:50:05.6845046Z 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-10-08T19:50:05.7788364Z ##[group]Run curr_branch="gh/kwen2501/47/head" 2024-10-08T19:50:05.7789062Z curr_branch="gh/kwen2501/47/head" 2024-10-08T19:50:05.7789478Z curr_ref_type="branch" 2024-10-08T19:50:05.7789948Z echo "Current branch is '$curr_branch'" 2024-10-08T19:50:05.7790447Z  2024-10-08T19:50:05.7790758Z python3 runner_determinator.py \ 2024-10-08T19:50:05.7791253Z  --github-token "$GITHUB_TOKEN" \ 2024-10-08T19:50:05.7791788Z  --github-issue "$ISSUE_NUMBER" \ 2024-10-08T19:50:05.7792223Z  --github-branch "$curr_branch" \ 2024-10-08T19:50:05.7792700Z  --github-actor "$TRIGGERING_ACTOR" \ 2024-10-08T19:50:05.7793429Z  --github-issue-owner "$ISSUE_OWNER" \ 2024-10-08T19:50:05.7794210Z  --github-ref-type "$curr_ref_type" \ 2024-10-08T19:50:05.7794676Z  --github-repo "$GITHUB_REPOSITORY" 2024-10-08T19:50:05.7818816Z shell: /usr/bin/bash -e {0} 2024-10-08T19:50:05.7819393Z env: 2024-10-08T19:50:05.7819984Z GITHUB_TOKEN: *** 2024-10-08T19:50:05.7820337Z ISSUE_NUMBER: 5132 2024-10-08T19:50:05.7820766Z TRIGGERING_ACTOR: kwen2501 2024-10-08T19:50:05.7821105Z ISSUE_OWNER: kwen2501 2024-10-08T19:50:05.7821443Z ##[endgroup] 2024-10-08T19:50:05.7868143Z Current branch is 'gh/kwen2501/47/head' 2024-10-08T19:50:07.1094153Z INFO : Setting output: label-type='' 2024-10-08T19:50:07.1484376Z Evaluate and set job outputs 2024-10-08T19:50:07.1495773Z Cleaning up orphan processes