Skip to content

Commit

Permalink
Fix @mentions issue
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanErn committed Jan 11, 2025
1 parent 8d100e6 commit f85e886
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 126 deletions.
185 changes: 74 additions & 111 deletions .github/scripts/check_vendordeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,20 @@

class VendorDepChecker:
def __init__(self):
self.github_sources = {
'PathplannerLib': 'https://api.github.com/repos/mjansen4857/pathplanner/releases',
'AdvantageKit': 'https://api.github.com/repos/Mechanical-Advantage/AdvantageKit/releases',
'photonlib': 'https://api.github.com/repos/PhotonVision/PhotonVision/releases',
'WPILib': 'https://api.github.com/repos/wpilibsuite/allwpilib/releases'
}
self.phoenix_urls = {
'version': 'https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest',
'json': 'https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2025-beta-latest.json'
}

self.github_token = os.getenv('GITHUB_TOKEN')
self.headers = {
'Accept': 'application/vnd.github.v3+json'
}
if self.github_token:
self.headers['Authorization'] = f'token {self.github_token}'
self.github_sources = {
'PathplannerLib': 'https://api.github.com/repos/mjansen4857/pathplanner/releases',
'AdvantageKit': 'https://api.github.com/repos/Mechanical-Advantage/AdvantageKit/releases',
'photonlib': 'https://api.github.com/repos/PhotonVision/PhotonVision/releases',
'WPILib': 'https://api.github.com/repos/wpilibsuite/allwpilib/releases',
'Phoenix6': 'https://api.github.com/repos/CrossTheRoadElec/Phoenix-Releases/releases'
}

self.github_token = os.getenv('GITHUB_TOKEN')
self.headers = {
'Accept': 'application/vnd.github.v3+json'
}
if self.github_token:
self.headers['Authorization'] = f'token {self.github_token}'

def parse_version(self, ver_str: str) -> version.Version:
"""Convert version string to comparable version object."""
Expand All @@ -35,6 +32,13 @@ def parse_version(self, ver_str: str) -> version.Version:
# Handle special cases like 'beta' or 'rc' if needed
return version.parse('0.0.0')

def sanitize_text(self, text: str) -> str:
"""Remove any @mentions from text content."""
import re
# Match @username or @org/repo style mentions
text = re.sub(r'@[\w-]+(?:/[\w-]+)?', '[mentioned]', text)
return text

def get_github_latest(self, repo_url: str, is_wpilib: bool = False) -> Optional[Dict]:
"""Get latest release version from GitHub, including betas."""
try:
Expand Down Expand Up @@ -62,8 +66,7 @@ def get_github_latest(self, repo_url: str, is_wpilib: bool = False) -> Optional[
'version': ver,
'tag': tag,
'is_beta': release.get('prerelease', False) or 'beta' in tag.lower(),
'url': release['html_url'],
'body': release.get('body', '')
'url': release['html_url']
})
print(f"Successfully parsed version: {tag} -> {ver}")
except version.InvalidVersion:
Expand All @@ -79,8 +82,7 @@ def get_github_latest(self, repo_url: str, is_wpilib: bool = False) -> Optional[
return {
'version': latest['tag'],
'is_beta': latest['is_beta'],
'url': latest['url'],
'notes': latest['body']
'url': latest['url']
}
print("No valid releases found")
return None
Expand All @@ -89,39 +91,6 @@ def get_github_latest(self, repo_url: str, is_wpilib: bool = False) -> Optional[
print(f"Error fetching from GitHub: {e}")
return None

except Exception as e:
print(f"Error fetching from GitHub: {e}")
return None

def get_phoenix_latest(self) -> Dict:
"""Get latest Phoenix version info from JSON."""
try:
json_data = requests.get(self.phoenix_urls['json']).json()
return {
'version': json_data.get('version'), # Get version directly from JSON
'data': json_data,
'is_beta': 'beta' in json_data.get('version', '').lower()
}
except Exception as e:
print(f"Error fetching Phoenix version: {e}")
return None

def get_current_version(self, file_path: Path) -> Dict:
"""Get current version from vendordep file."""
try:
with open(file_path) as f:
data = json.load(f)
current_ver = data.get('version')
if current_ver:
return {
'version': current_ver,
'is_beta': 'beta' in current_ver.lower()
}
return None
except Exception as e:
print(f"Error reading {file_path}: {e}")
return None

def get_current_version(self, file_path: Path) -> Dict:
"""Get current version from vendordep file."""
try:
Expand All @@ -145,10 +114,8 @@ def get_wpilib_current_version(self) -> Dict:

with open(gradle_props_path) as f:
content = f.read()
# Look for GradleRIO version in plugins block
for line in content.split('\n'):
if 'id "edu.wpi.first.GradleRIO"' in line and 'version' in line:
# Extract version from line like: id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-2"
version_str = line.split('version')[1].strip().strip('"').strip("'")
return {
'version': version_str,
Expand All @@ -164,87 +131,83 @@ def is_newer_version(self, current: Dict, latest: Dict) -> bool:
current_ver = self.parse_version(current['version'])
latest_ver = self.parse_version(latest['version'])

print(f"\nComparing versions:")
print(f"Current: {current['version']} (Beta: {current['is_beta']}) -> Parsed as: {current_ver}")
print(f"Latest: {latest['version']} (Beta: {latest['is_beta']}) -> Parsed as: {latest_ver}")

# If versions are equal, prefer beta over stable
if current_ver == latest_ver:
return latest['is_beta'] and not current['is_beta']
result = latest['is_beta'] and not current['is_beta']
print(f"Versions equal, checking beta status -> Update needed: {result}")
return result

return latest_ver > current_ver
result = latest_ver > current_ver
print(f"Comparing versions -> Update needed: {result}")
return result

def check_all_updates(self):
"""Check all vendordeps for updates."""
updates = []
vendordeps_dir = Path('vendordeps')

# Check GitHub-based vendordeps
print("Starting dependency check...")

# Check all GitHub-based vendordeps (including Phoenix6)
for name, url in self.github_sources.items():
print(f"\nChecking {name}...")

if name == 'WPILib':
current = self.get_wpilib_current_version()
latest = self.get_github_latest(url, is_wpilib=True)
else:
current_file = next(vendordeps_dir.glob(f"{name}*.json"), None)
if not current_file:
print(f"No vendordep file found for {name}")
continue
print(f"Found vendordep file: {current_file}")
current = self.get_current_version(current_file)
latest = self.get_github_latest(url)

if current and latest and self.is_newer_version(current, latest):
updates.append({
'name': name,
'current': current['version'],
'current_is_beta': current['is_beta'],
'latest': latest['version'],
'latest_is_beta': latest['is_beta'],
'source': 'GitHub',
'url': latest.get('url'),
'notes': latest.get('notes') if name == 'WPILib' else None
})

# Check Phoenix
phoenix_file = next(vendordeps_dir.glob("Phoenix6*.json"), None)
if phoenix_file:
current = self.get_current_version(phoenix_file)
latest = self.get_phoenix_latest()

if current and latest and self.is_newer_version(current, latest):
updates.append({
'name': 'Phoenix6',
'current': current['version'],
'current_is_beta': current['is_beta'],
'latest': latest['version'],
'latest_is_beta': latest['is_beta'],
'source': 'CTRE Maven'
})
if current and latest:
print(f"Current version: {current['version']}")
print(f"Latest version: {latest['version']}")

if self.is_newer_version(current, latest):
print(f"Update available for {name}")
updates.append({
'name': name,
'current': current['version'],
'current_is_beta': current['is_beta'],
'latest': latest['version'],
'latest_is_beta': latest['is_beta'],
'source': 'GitHub',
'url': latest.get('url')
})
else:
print(f"Failed to get version info for {name}")

return updates

def main():
if __name__ == "__main__":
checker = VendorDepChecker()
updates = checker.check_all_updates()

# Set output for GitHub Actions
if updates:
print("\n=== Updates Available ===")
print("\nFound updates:")
for update in updates:
print(f"\n{update['name']}:")
print(f" Current: {update['current']} ({'beta' if update['current_is_beta'] else 'stable'})")
print(f" Latest: {update['latest']} ({'beta' if update['latest_is_beta'] else 'stable'})")
print(f" Source: {update['source']}")
if 'url' in update and update['url']:
print(f" URL: {update['url']}")
if update.get('notes'):
print(f" Release Notes Preview: {update['notes'][:200]}...")

# Set GitHub Actions output if running in GHA
if os.getenv('GITHUB_OUTPUT'):
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write(f"has_updates=true\n")
# Properly escape the JSON string for GitHub Actions
updates_json = json.dumps(updates).replace('%', '%25').replace('\n', '%0A').replace('\r', '%0D')
f.write(f"updates={updates_json}\n")
print(f"- {update['name']}: {update['current']} -> {update['latest']}")

# GitHub Actions output syntax
result = {
"has_updates": True,
"updates": updates
}
print(json.dumps(result))
else:
print("\nAll dependencies are up to date!")
if os.getenv('GITHUB_OUTPUT'):
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
f.write("has_updates=false\n")
f.write("updates=[]\n")
if __name__ == "__main__":
main()
print("\nNo updates found.")
result = {
"has_updates": False,
"updates": []
}
print(json.dumps(result))
22 changes: 7 additions & 15 deletions .github/workflows/check_vendordeps.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
name: Check Dependencies

on:
schedule:
- cron: '0 12 */2 * *' # Run at noon UTC every other day
workflow_dispatch: # Allow manual triggers

jobs:
check-updates:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Install dependencies
run: pip install requests packaging

- name: Check for updates
id: check
run: python .github/scripts/check_vendordeps.py
run: |
echo "UPDATES_OUTPUT=$(python .github/scripts/check_vendordeps.py)" >> $GITHUB_OUTPUT
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Handle Update Issues
if: steps.check.outputs.has_updates == 'true'
if: fromJSON(steps.check.outputs.UPDATES_OUTPUT).has_updates
uses: actions/github-script@v6
env:
UPDATES_JSON: ${{ steps.check.outputs.updates }}
UPDATES_JSON: ${{ fromJSON(steps.check.outputs.UPDATES_OUTPUT).updates }}
with:
script: |
try {
Expand Down Expand Up @@ -58,16 +53,13 @@ jobs:
body += `- Source: ${update.source}\n`;
if (update.url) {
body += `- [View Release](${update.url})\n`;
// Sanitize URL just in case there are any fragments with @mentions
const sanitizedUrl = update.url.replace(/@[\w-]+(?:\/[\w-]+)?/g, '[mentioned]');
body += `- [View Release](${sanitizedUrl})\n`;
}
if (update.name === 'WPILib') {
body += '\n⚠️ **Note**: Please use WPILib VS Code tools for actual updates\n';
if (update.notes) {
body += '\n<details><summary>Release Notes</summary>\n\n';
body += update.notes;
body += '\n</details>\n';
}
}
body += '\n';
Expand Down

0 comments on commit f85e886

Please sign in to comment.