@@ -43,61 +43,71 @@ jobs:
4343
4444 def get_spring_boot_versions():
4545 """Fetch all Spring Boot versions from Maven Central with retry logic"""
46- # Use the versions API instead of the general search
47- url = "https://search.maven.org/solrsearch/select"
48- params = {
49- "q": "g:org.springframework.boot AND a:spring-boot",
50- "core": "gav",
51- "rows": 500,
52- "wt": "json"
53- }
54-
46+
5547 max_retries = 3
56- timeout = 60 # Increased timeout
48+ timeout = 60
5749
5850 for attempt in range(max_retries):
5951 try:
6052 print(f"Fetching versions (attempt {attempt + 1}/{max_retries})...")
61- response = requests.get(url, params=params, timeout=timeout)
53+
54+ # Try the Maven Central REST API first
55+ rest_url = "https://repo1.maven.org/maven2/org/springframework/boot/spring-boot/maven-metadata.xml"
56+ response = requests.get(rest_url, timeout=timeout)
57+
58+ if response.status_code == 200:
59+ print("Using Maven metadata XML approach...")
60+ # Parse XML to extract versions
61+ import xml.etree.ElementTree as ET
62+ root = ET.fromstring(response.text)
63+ versions = []
64+ versioning = root.find('versioning')
65+ if versioning is not None:
66+ versions_element = versioning.find('versions')
67+ if versions_element is not None:
68+ for version_elem in versions_element.findall('version'):
69+ v = version_elem.text
70+ if v and not any(suffix in v for suffix in ['SNAPSHOT', 'RC', 'BUILD']):
71+ versions.append(v)
72+
73+ if versions:
74+ print(f"Found {len(versions)} versions via XML")
75+ print(f"Sample versions: {versions[-10:] if len(versions) > 10 else versions}")
76+ return sorted(versions, key=version.parse)
77+
78+ # Fallback to search API
79+ print("Trying search API fallback...")
80+ search_url = "https://search.maven.org/solrsearch/select"
81+ params = {
82+ "q": "g:\"org.springframework.boot\" AND a:\"spring-boot\"",
83+ "core": "gav",
84+ "rows": 1000,
85+ "wt": "json"
86+ }
87+
88+ response = requests.get(search_url, params=params, timeout=timeout)
6289 response.raise_for_status()
6390 data = response.json()
6491
6592 if 'response' not in data or 'docs' not in data['response']:
66- raise Exception(f"Unexpected API response structure: {data} ")
93+ raise Exception(f"Unexpected API response structure")
6794
6895 docs = data['response']['docs']
69- print(f"Found {len(docs)} documents in response")
96+ print(f"Found {len(docs)} documents in search response")
7097
7198 if docs and len(docs) > 0:
7299 print(f"Sample doc structure: {list(docs[0].keys())}")
73100
74101 versions = []
75102 for doc in docs:
76- # Try different possible version field names
77- version_field = None
78- if 'v' in doc:
79- version_field = doc['v']
80- elif 'version' in doc:
81- version_field = doc['version']
82- elif 'latestVersion' in doc:
83- # This might be a summary doc, skip it
84- print(f"Skipping summary doc with latestVersion: {doc.get('latestVersion')}")
85- continue
86- else:
87- print(f"Warning: No version field found in doc: {doc}")
88- continue
89-
90- # Only include release versions (no SNAPSHOT, RC, M versions for 2.x and 3.x)
91- if not any(suffix in version_field for suffix in ['SNAPSHOT', 'RC', 'BUILD']):
103+ version_field = doc.get('v') or doc.get('version')
104+ if version_field and not any(suffix in version_field for suffix in ['SNAPSHOT', 'RC', 'BUILD']):
92105 versions.append(version_field)
93106
94- print(f"Successfully fetched {len(versions)} versions")
95- return sorted(versions, key=version.parse)
96- except requests.exceptions.Timeout as e:
97- print(f"Attempt {attempt + 1} timed out: {e}")
98- if attempt < max_retries - 1:
99- print("Retrying...")
100- continue
107+ if versions:
108+ print(f"Successfully fetched {len(versions)} versions via search API")
109+ return sorted(versions, key=version.parse)
110+
101111 except Exception as e:
102112 print(f"Attempt {attempt + 1} failed: {e}")
103113 if attempt < max_retries - 1:
0 commit comments