From f85e88688aeb911ed8061176f528b2511f6cfd6c Mon Sep 17 00:00:00 2001 From: Sean Ernstes Date: Sat, 11 Jan 2025 13:20:01 -0500 Subject: [PATCH] Fix @mentions issue --- .github/scripts/check_vendordeps.py | 185 ++++++++++--------------- .github/workflows/check_vendordeps.yml | 22 +-- 2 files changed, 81 insertions(+), 126 deletions(-) diff --git a/.github/scripts/check_vendordeps.py b/.github/scripts/check_vendordeps.py index efd4e33..6f3e317 100644 --- a/.github/scripts/check_vendordeps.py +++ b/.github/scripts/check_vendordeps.py @@ -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.""" @@ -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: @@ -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: @@ -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 @@ -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: @@ -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, @@ -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() \ No newline at end of file + print("\nNo updates found.") + result = { + "has_updates": False, + "updates": [] + } + print(json.dumps(result)) \ No newline at end of file diff --git a/.github/workflows/check_vendordeps.yml b/.github/workflows/check_vendordeps.yml index fa68437..85497f5 100644 --- a/.github/workflows/check_vendordeps.yml +++ b/.github/workflows/check_vendordeps.yml @@ -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 { @@ -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
Release Notes\n\n'; - body += update.notes; - body += '\n
\n'; - } } body += '\n';