Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build/ci/.azure-devops-stages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ stages:
README.md
README/**
build/**
src/Uno.Sdk/packages.json

- template: templates/gitversion-run.yml
- template: setup/.azure-devops-setup-commitsar.yml
- template: setup/.azure-devops-setup-validate-packages.yml
Comment thread
agneszitte marked this conversation as resolved.
- template: setup/.azure-devops-setup-doc-validations.yml
Comment thread
agneszitte marked this conversation as resolved.

- job: DetermineScope
Expand Down
154 changes: 154 additions & 0 deletions build/ci/scripts/validate-packages-json.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Validates that all package IDs and versions in src/Uno.Sdk/packages.json exist on NuGet.org.

.DESCRIPTION
Parses packages.json, skips groups with placeholder versions (e.g. "DefaultUnoVersion"),
and verifies each package ID + version (including versionOverride entries) against NuGet.org.
Exits with code 1 if any package/version is missing.

.PARAMETER PackagesJsonPath
Path to the packages.json file. Defaults to src/Uno.Sdk/packages.json relative to repo root.
#>
param(
[string]$PackagesJsonPath,
[switch]$WarningOnly
)

$ErrorActionPreference = 'Stop'

# Auto-detect: on release/* branches, switch to warning-only mode
# (stable builds test with versions not yet public on NuGet.org)
if (-not $WarningOnly) {
$branch = $env:BUILD_SOURCEBRANCH
$targetBranch = $env:SYSTEM_PULLREQUEST_TARGETBRANCH
if (($branch -and $branch -like 'refs/heads/release/*') -or
($targetBranch -and $targetBranch -like 'refs/heads/release/*')) {
$detected = if ($targetBranch -like 'refs/heads/release/*') { $targetBranch } else { $branch }
Write-Host "Detected release branch ($detected) - running in warning-only mode." -ForegroundColor Yellow
$WarningOnly = $true
}
}

# Resolve path
if (-not $PackagesJsonPath) {
$repoRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $PSScriptRoot))
$PackagesJsonPath = Join-Path $repoRoot 'src/Uno.Sdk/packages.json'
}

if (-not (Test-Path $PackagesJsonPath)) {
Write-Error "packages.json not found at: $PackagesJsonPath"
exit 1
}

Write-Host "Validating packages.json: $PackagesJsonPath" -ForegroundColor Cyan

$json = Get-Content $PackagesJsonPath -Raw | ConvertFrom-Json
$errors = @()
$checked = 0
$validatedPairs = @{} # De-duplicate package+version pairs across groups

# Placeholder versions that should not be validated against NuGet
$placeholderVersions = @('DefaultUnoVersion')

foreach ($group in $json) {
$groupName = $group.group
$baseVersion = $group.version
$packages = $group.packages

# Skip groups with placeholder versions
if ($placeholderVersions -contains $baseVersion) {
Write-Host " [SKIP] $groupName (placeholder version: $baseVersion)" -ForegroundColor DarkGray
continue
}

# Collect all version+package combinations to check
$versionsToCheck = @()

# Base version
$versionsToCheck += @{ Version = $baseVersion; Label = 'base' }

# Version overrides (TFM-specific)
if ($group.PSObject.Properties['versionOverride'] -and $null -ne $group.versionOverride) {
$overrides = $group.versionOverride
foreach ($prop in $overrides.PSObject.Properties) {
$versionsToCheck += @{ Version = $prop.Value; Label = "override($($prop.Name))" }
}
}

foreach ($pkg in $packages) {
foreach ($vEntry in $versionsToCheck) {
$version = $vEntry.Version
$label = $vEntry.Label

# Also skip overrides that reference a placeholder
if ($placeholderVersions -contains $version) {
continue
}

# De-duplicate: skip if we already validated this package+version
$pairKey = "$($pkg.ToLowerInvariant())|$($version.ToLowerInvariant())"
if ($validatedPairs.ContainsKey($pairKey)) {
Write-Host " [OK] $pkg $version ($label) - already validated" -ForegroundColor DarkGreen
continue
}
$validatedPairs[$pairKey] = $true

$checked++
$url = "https://api.nuget.org/v3-flatcontainer/$($pkg.ToLowerInvariant())/$($version.ToLowerInvariant())/$($pkg.ToLowerInvariant()).nuspec"

try {
$response = Invoke-WebRequest -Uri $url -Method Head -UseBasicParsing `
-TimeoutSec 30 -MaximumRetryCount 3 -RetryIntervalSec 2 -ErrorAction Stop
if ($response.StatusCode -eq 200) {
Write-Host " [OK] $pkg $version ($label)" -ForegroundColor Green
}
Comment thread
agneszitte marked this conversation as resolved.
}
catch {
$httpResponse = $_.Exception.Response
if ($null -ne $httpResponse) {
$statusCode = $httpResponse.StatusCode.value__
if ($statusCode -eq 404) {
Write-Host " [MISSING] $pkg $version ($label) - NOT FOUND on NuGet" -ForegroundColor Red
$errors += "Group '$groupName': $pkg $version ($label) does not exist on NuGet.org"
}
else {
Write-Host " [ERROR] $pkg $version ($label) - HTTP $statusCode" -ForegroundColor Yellow
$errors += "Group '$groupName': $pkg $version ($label) - HTTP error $statusCode"
}
}
else {
Write-Host " [ERROR] $pkg $version ($label) - $($_.Exception.Message)" -ForegroundColor Yellow
$errors += "Group '$groupName': $pkg $version ($label) - network error: $($_.Exception.Message)"
}
Comment thread
agneszitte marked this conversation as resolved.
}
}
}
}

Write-Host ""
Write-Host "Checked $checked package/version combinations." -ForegroundColor Cyan

if ($errors.Count -gt 0) {
Write-Host ""
if ($WarningOnly) {
Write-Host "VALIDATION WARNINGS - $($errors.Count) package(s) not found on NuGet.org (non-fatal):" -ForegroundColor Yellow
}
else {
Write-Host "VALIDATION FAILED - $($errors.Count) error(s):" -ForegroundColor Red
}
foreach ($err in $errors) {
Write-Host " - $err" -ForegroundColor $(if ($WarningOnly) { 'Yellow' } else { 'Red' })
}
if ($WarningOnly) {
Write-Host ""
Write-Host "Running in warning-only mode (stable branch) - not failing the build." -ForegroundColor Yellow
exit 0
}
exit 1
}
else {
Write-Host "All packages validated successfully." -ForegroundColor Green
exit 0
}
9 changes: 9 additions & 0 deletions build/ci/setup/.azure-devops-setup-validate-packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
steps:
- task: PowerShell@2
displayName: Validate packages.json (NuGet existence check)
inputs:
pwsh: true
filePath: build/ci/scripts/validate-packages-json.ps1
arguments: '-PackagesJsonPath "$(Build.SourcesDirectory)/src/Uno.Sdk/packages.json"'
env:
BUILD_SOURCEBRANCH: $(Build.SourceBranch)
2 changes: 1 addition & 1 deletion doc/articles/features/android-auto.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For projects using the `Uno.Sdk`, add the `AndroidAuto` feature to your project'
<UnoFeatures>$(UnoFeatures);AndroidAuto</UnoFeatures>
```

This automatically adds a reference to the `Xamarin.AndroidX.Car.App` package. New projects created from the Uno Platform templates with the **Android Auto** option enabled will also have the required manifest entries and the `automotive_app_desc.xml` resource stamped automatically.
This automatically adds a reference to the `Xamarin.AndroidX.Car.App.App` package. New projects created from the Uno Platform templates with the **Android Auto** option enabled will also have the required manifest entries and the `automotive_app_desc.xml` resource stamped automatically.

## What gets configured

Expand Down
2 changes: 1 addition & 1 deletion src/Uno.Sdk/Sdk/Sdk.props.buildschema.json
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@
"helpUrl": "https://aka.platform.uno/feature-android-tv"
},
"AndroidAuto": {
"description": "Configures the Android head for Android Auto / Automotive OS (adds Xamarin.AndroidX.Car.App).",
"description": "Configures the Android head for Android Auto / Automotive OS (adds Xamarin.AndroidX.Car.App.App).",
Comment thread
agneszitte marked this conversation as resolved.
"helpUrl": "https://aka.platform.uno/feature-android-auto"
},
"AndroidWear": {
Expand Down
8 changes: 4 additions & 4 deletions src/Uno.Sdk/packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@
"group": "AndroidXCarApp",
"version": "1.4.0.2",
"packages": [
"Xamarin.AndroidX.Car.App"
"Xamarin.AndroidX.Car.App.App"
],
Comment thread
agneszitte marked this conversation as resolved.
Comment thread
agneszitte marked this conversation as resolved.
"versionOverride": {
"net10.0": "1.4.0.3"
Expand All @@ -294,17 +294,17 @@
"Xamarin.AndroidX.Wear"
],
"versionOverride": {
"net10.0": "1.3.0.17"
"net10.0": "1.4.0.1"
}
},
{
"group": "AndroidXWearTiles",
"version": "1.4.0.2",
"version": "1.4.0.1",
"packages": [
"Xamarin.AndroidX.Wear.Tiles"
],
"versionOverride": {
"net10.0": "1.4.0.3"
"net10.0": "1.4.1"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</ItemGroup>

<ItemGroup Condition="$(UnoFeatures.Contains(';androidauto;'))">
<_UnoProjectSystemPackageReference Include="Xamarin.AndroidX.Car.App" ProjectSystem="true" />
<_UnoProjectSystemPackageReference Include="Xamarin.AndroidX.Car.App.App" ProjectSystem="true" />
</ItemGroup>

<ItemGroup Condition="$(UnoFeatures.Contains(';androidwear;'))">
Expand Down
Loading