diff --git a/tools/build b/tools/build index e6e1f94..aff20c4 100755 --- a/tools/build +++ b/tools/build @@ -94,7 +94,7 @@ METADATA_SCHEMA = { 'minlength': 1, 'schema': { 'type': 'string', - 'allowed': ['almalinux/el8', 'almalinux/el9'], + 'allowed': ['almalinux/el8', 'almalinux/el9', 'fedora/42', 'fedora/43', 'fedora/44'], 'empty': False } }, @@ -504,17 +504,39 @@ def normalize_version(version: str) -> str: return ''.join(normalized_parts) -def check_package_exists(package_name: str, version: str, release: str) -> bool: +def get_rpm_dist_suffix(distro: str) -> str: + """ + Map a distro path to the RPM dist tag suffix used in package filenames. + + Examples: + 'almalinux/el9' -> '.el9' + 'fedora/43' -> '.fc43' + """ + if distro.startswith('almalinux/'): + return '.' + distro.split('/', 1)[1] + if distro.startswith('fedora/'): + return '.fc' + distro.split('/', 1)[1] + return '' + + +def check_package_exists(package_name: str, version: str, release: str, distro: str = '') -> bool: """ Check if a package version exists in the Gitea package registry. + When distro is provided the check is distro-aware: it lists the files + attached to the package version and returns True only when a file whose + name contains the expected RPM dist suffix (e.g. '.el9', '.fc43') is + found. This prevents a package built for almalinux/el9 from being + mistaken for a fedora/43 build (and vice-versa). + Args: package_name: Name of the package version: Version string release: Release number + distro: Target distro path (e.g. 'almalinux/el9', 'fedora/43') Returns: - True if package exists, False otherwise + True if package exists for the given distro, False otherwise """ logger = logging.getLogger(__name__) @@ -543,10 +565,41 @@ def check_package_exists(package_name: str, version: str, release: str) -> bool: if response.status_code == 200: package_info = response.json() - # Package exists if we get package info back - exists = bool(package_info.get('id')) - logger.debug(f"Package {package_name}:{full_version} {'exists' if exists else 'not found'}") - return exists + if not package_info.get('id'): + logger.debug(f"Package {package_name}:{full_version} not found") + return False + + # No distro filter – treat any file as a match + if not distro: + logger.debug(f"Package {package_name}:{full_version} exists") + return True + + # Distro-aware check: inspect individual file names for the dist suffix + dist_suffix = get_rpm_dist_suffix(distro) + if not dist_suffix: + logger.debug(f"Package {package_name}:{full_version} exists (no dist suffix for {distro})") + return True + + files_url = f"{base_url}/api/v1/packages/{owner}/{package_type}/{package_name}/{full_version}/files" + logger.debug(f"Checking distro-specific files: {files_url}") + files_response = requests.get(files_url, headers=headers, timeout=30) + + if files_response.status_code == 200: + files = files_response.json() + for file_info in files: + if dist_suffix in file_info.get('name', ''): + logger.debug(f"Package {package_name}:{full_version} exists for {distro}") + return True + logger.debug(f"Package {package_name}:{full_version} not found for {distro} (no {dist_suffix} file)") + return False + else: + # If files endpoint fails fall back to treating version existence as a match + logger.warning( + f"Could not list files for {package_name}:{full_version}: " + f"{files_response.status_code} – assuming package exists" + ) + return True + elif response.status_code == 404: logger.debug(f"Package {package_name}:{full_version} not found (404)") return False @@ -1449,7 +1502,8 @@ class Builder: if check_package_exists( package_info.name, package_info.version, - package_info.release + package_info.release, + package_info.distro ): self.logger.info( f"Skipping {package_info} (already exists in repository)"