mirror of
https://github.com/infiniteCable2/openpilot.git
synced 2026-09-06 00:03:42 +08:00
Merge branch 'master-new' of https://github.com/sunnypilot/sunnypilot into master-new
This commit is contained in:
@@ -97,6 +97,17 @@ jobs:
|
||||
headRefName
|
||||
title
|
||||
createdAt
|
||||
labels(last:10) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
headRepository {
|
||||
name
|
||||
nameWithOwner
|
||||
url
|
||||
isFork
|
||||
}
|
||||
commits(last: 1) {
|
||||
nodes {
|
||||
commit {
|
||||
|
||||
+1
-1
Submodule opendbc_repo updated: f3378b8a04...5d609a9199
@@ -7,6 +7,7 @@ import argparse
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
TRUST_FORK_LABEL = "trust-fork-pr"
|
||||
|
||||
def setup_argument_parser():
|
||||
parser = argparse.ArgumentParser(description='Process and squash GitHub PRs')
|
||||
@@ -37,43 +38,25 @@ def sort_prs_by_creation(pr_data):
|
||||
)
|
||||
|
||||
|
||||
def add_pr_comment(pr_number, comment):
|
||||
def add_pr_comments(pr_number, comments: list[str]):
|
||||
"""Adds or updates a comment with multiple comments to a PR using gh cli"""
|
||||
comment = "\n___\n".join(comments)
|
||||
_add_pr_comment(pr_number, comment)
|
||||
|
||||
|
||||
def _add_pr_comment(pr_number, comment):
|
||||
"""Add or update a comment to a PR using gh cli"""
|
||||
title = "## Squash and Merge"
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['gh', 'pr', 'view', str(pr_number), '--json', 'comments'],
|
||||
full_comment = f"{title}\n\n{comment}"
|
||||
subprocess.run(
|
||||
['gh', 'pr', 'comment', '--edit-last', '--create-if-none', f"#{pr_number}", '--body', full_comment],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
comments_data = json.loads(result.stdout)
|
||||
has_existing_comment = False
|
||||
|
||||
for pr_comment in comments_data['comments']:
|
||||
if pr_comment['body'].startswith(title):
|
||||
has_existing_comment = True
|
||||
break
|
||||
|
||||
full_comment = f"{title}\n\n{comment}"
|
||||
|
||||
if has_existing_comment:
|
||||
subprocess.run(
|
||||
['gh', 'pr', 'comment', '--edit-last', f"#{pr_number}", '--body', full_comment],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
else:
|
||||
subprocess.run(
|
||||
['gh', 'pr', 'comment', f"#{pr_number}", '--body', full_comment],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to add/update comment on PR #{pr_number}: {e.stderr}")
|
||||
except json.JSONDecodeError:
|
||||
@@ -104,8 +87,8 @@ def validate_pr(pr):
|
||||
if not merge_data.get('mergeable'):
|
||||
return False, "merge conflicts detected"
|
||||
|
||||
if (mergeStateStatus := merge_data.get('mergeStateStatus')) == "BEHIND":
|
||||
return False, f"branch is `{mergeStateStatus}`"
|
||||
# if (mergeStateStatus := merge_data.get('mergeStateStatus')) == "BEHIND":
|
||||
# return False, f"branch is `{mergeStateStatus}`"
|
||||
|
||||
return True, None
|
||||
|
||||
@@ -122,24 +105,43 @@ def process_pr(pr_data, source_branch, target_branch, squash_script_path):
|
||||
subprocess.run(['git', 'branch', target_branch, f'origin/{source_branch}'], check=True)
|
||||
success_count = 0
|
||||
for pr in nodes:
|
||||
pr_number = pr.get('number', 'UNKNOWN')
|
||||
branch = pr.get('headRefName', '')
|
||||
title = pr.get('title', '')
|
||||
is_valid, skip_reason = validate_pr(pr)
|
||||
|
||||
if not is_valid:
|
||||
print(f"Warning: {skip_reason} for PR #{pr_number}, skipping")
|
||||
add_pr_comment(pr_number,
|
||||
f"⚠️ This PR was skipped in the automated `{target_branch}` squash because **{skip_reason}**.")
|
||||
continue
|
||||
|
||||
pr_comments = []
|
||||
try:
|
||||
pr_number = pr.get('number', 'UNKNOWN')
|
||||
branch = pr.get('headRefName', '')
|
||||
title = pr.get('title', '')
|
||||
head_repository = pr.get('headRepository', {})
|
||||
pr_labels = pr.get('labels', {}).get('nodes', [])
|
||||
is_fork = head_repository.get('isFork', False)
|
||||
trust_fork = any(label.get('name') == TRUST_FORK_LABEL for label in pr_labels)
|
||||
is_valid, skip_reason = validate_pr(pr)
|
||||
origin = "origin" if not head_repository.get('isFork', False) else head_repository.get('nameWithOwner', 'origin')
|
||||
|
||||
if is_fork and trust_fork:
|
||||
print(f"Removing label `{TRUST_FORK_LABEL}` from PR #{pr_number} as it is being processed")
|
||||
subprocess.run(['gh', 'pr', 'edit', str(pr_number), '--remove-label', TRUST_FORK_LABEL], check=True)
|
||||
pr_comments.append(f"ℹ️️ This PR is from a fork. The `{TRUST_FORK_LABEL}` label was removed as it is being processed right now.")
|
||||
print(f"Adding remote {origin} for PR #{pr_number}")
|
||||
subprocess.run(['git', 'remote', 'add', origin, head_repository.get('url')], check=False)
|
||||
|
||||
if is_fork and not trust_fork:
|
||||
pr_comments.append(
|
||||
f"⚠️ This PR is from a fork. Please add the `{TRUST_FORK_LABEL}` label to include it in the squash." +
|
||||
"\n**Note**: The label is removed after the squash is done and must be added again for the next execution for security reasons."
|
||||
)
|
||||
continue
|
||||
|
||||
if not is_valid:
|
||||
print(f"Warning: {skip_reason} for PR #{pr_number}, skipping")
|
||||
pr_comments.append(f"⚠️ This PR was skipped in the automated `{target_branch}` squash because **{skip_reason}**.")
|
||||
continue
|
||||
|
||||
# Fetch PR branch
|
||||
subprocess.run(['git', 'fetch', 'origin', branch], check=True)
|
||||
subprocess.run(['git', 'fetch', origin, branch], check=True)
|
||||
# Delete branch if it exists (ignore errors if it doesn't)
|
||||
subprocess.run(['git', 'branch', '-D', branch], check=False)
|
||||
# Create new branch pointing to origin's branch
|
||||
subprocess.run(['git', 'branch', branch, f'origin/{branch}'], check=True)
|
||||
subprocess.run(['git', 'branch', branch, f'{origin}/{branch}'], check=True)
|
||||
|
||||
# Run squash script
|
||||
result = subprocess.run([
|
||||
@@ -160,13 +162,17 @@ def process_pr(pr_data, source_branch, target_branch, squash_script_path):
|
||||
print(f"Command failed with exit code {result.returncode}")
|
||||
output = result.stdout
|
||||
print(f"Error output: {output}")
|
||||
add_pr_comment(pr_number, f"⚠️ Error during automated `{target_branch}` squash:\n```\n{output}\n```")
|
||||
pr_comments.append(f"⚠️ Error during automated `{target_branch}` squash:\n```\n{output}\n```")
|
||||
subprocess.run(['git', 'reset', '--hard'], check=True)
|
||||
continue
|
||||
except Exception as e:
|
||||
print(f"Unexpected error processing PR #{pr_number}: {str(e)}")
|
||||
pr_comments.append(f"⚠️ Unexpected error during automated `{target_branch}` squash:\n```\n{str(e)}\n```")
|
||||
subprocess.run(['git', 'reset', '--hard'], check=True)
|
||||
continue
|
||||
finally:
|
||||
if pr_comments:
|
||||
add_pr_comments(pr_number, pr_comments) # This "commits" all the comments generated on this run before leaving loop on continue.
|
||||
|
||||
return success_count
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ def dmonitoringd_thread():
|
||||
|
||||
params = Params()
|
||||
pm = messaging.PubMaster(['driverMonitoringState'])
|
||||
sm = messaging.SubMaster(['driverStateV2', 'liveCalibration', 'carState', 'selfdriveState', 'modelV2'], poll='driverStateV2')
|
||||
sm = messaging.SubMaster(['driverStateV2', 'liveCalibration', 'carState', 'selfdriveState', 'modelV2',
|
||||
'selfdriveStateSP'], poll='driverStateV2')
|
||||
|
||||
DM = DriverMonitoring(rhd_saved=params.get_bool("IsRhdDetected"), always_on=params.get_bool("AlwaysOnDM"))
|
||||
|
||||
|
||||
@@ -403,13 +403,13 @@ class DriverMonitoring:
|
||||
driver_state=sm['driverStateV2'],
|
||||
cal_rpy=sm['liveCalibration'].rpyCalib,
|
||||
car_speed=sm['carState'].vEgo,
|
||||
op_engaged=sm['selfdriveState'].enabled
|
||||
op_engaged=sm['selfdriveState'].enabled or sm['selfdriveStateSP'].mads.enabled
|
||||
)
|
||||
|
||||
# Update distraction events
|
||||
self._update_events(
|
||||
driver_engaged=sm['carState'].steeringPressed or sm['carState'].gasPressed,
|
||||
op_engaged=sm['selfdriveState'].enabled,
|
||||
op_engaged=sm['selfdriveState'].enabled or sm['selfdriveStateSP'].mads.enabled,
|
||||
standstill=sm['carState'].standstill,
|
||||
wrong_gear=sm['carState'].gearShifter in [car.CarState.GearShifter.reverse, car.CarState.GearShifter.park],
|
||||
car_speed=sm['carState'].vEgo
|
||||
|
||||
@@ -122,7 +122,7 @@ class ModelCache:
|
||||
|
||||
class ModelFetcher:
|
||||
"""Handles fetching and caching of model data from remote source"""
|
||||
MODEL_URL = "https://docs.sunnypilot.ai/driving_models.json"
|
||||
MODEL_URL = "https://docs.sunnypilot.ai/driving_models_v2.json"
|
||||
|
||||
def __init__(self, params: Params):
|
||||
self.params = params
|
||||
|
||||
@@ -210,12 +210,25 @@ class BackupManagerSP:
|
||||
def _get_current_version(self) -> custom.BackupManagerSP.Version:
|
||||
"""Gets current sunnypilot version information."""
|
||||
version_obj = custom.BackupManagerSP.Version()
|
||||
version_parts = get_version().split('.')
|
||||
version_obj.major = int(version_parts[0]) if len(version_parts) > 0 else 0
|
||||
version_obj.minor = int(version_parts[1]) if len(version_parts) > 1 else 0
|
||||
version_obj.patch = int(version_parts[2]) if len(version_parts) > 2 else 0
|
||||
version_obj.build = int(version_parts[3]) if len(version_parts) > 3 else 0
|
||||
version_str = get_version()
|
||||
|
||||
version_parts = version_str.split('-') # For when version is like "1.2.3-456"
|
||||
version_nums = version_parts[0].split('.')
|
||||
|
||||
# Extract build number from hyphen format or as 4th version component
|
||||
build = 0
|
||||
if len(version_parts) > 1 and version_parts[1].isdigit():
|
||||
build = int(version_parts[1])
|
||||
elif len(version_nums) > 3 and version_nums[3].isdigit():
|
||||
build = int(version_nums[3])
|
||||
|
||||
# Set version components with safer defaults
|
||||
version_obj.major = int(version_nums[0]) if len(version_nums) > 0 and version_nums[0].isdigit() else 0
|
||||
version_obj.minor = int(version_nums[1]) if len(version_nums) > 1 and version_nums[1].isdigit() else 0
|
||||
version_obj.patch = int(version_nums[2]) if len(version_nums) > 2 and version_nums[2].isdigit() else 0
|
||||
version_obj.build = build
|
||||
version_obj.branch = get_branch()
|
||||
|
||||
return version_obj
|
||||
|
||||
async def main_thread(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user