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
3 changes: 2 additions & 1 deletion .github/instructions/gradle.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ az login # one-time, corp account with MFA satisfied
pwsh ./eng/gradle/mirror-dependencies.ps1 `
-ProjectDir <path-to-failing-gradle-project> `
-Task <gradle-task-CI-runs> `
-GradleWrapper <path-to-wrapper-CI-runs> `
-AndroidHome <path-to-Android-SDK> # required for any com.android.* project
```

The mirror must run in the project that actually needs the new package — a sibling project's build won't trigger a mirror for someone else's deps. Typical convergence is 2-5 iterations as the resolver walks the dep graph breadth-first.
The mirror must run in the project that actually needs the new package — a sibling project's build won't trigger a mirror for someone else's deps. If that project uses a different Gradle wrapper in CI, pass the same wrapper with `-GradleWrapper`; Kotlin and other plugins publish Gradle-version-specific variants. Typical convergence is 2-5 iterations as the resolver walks the dep graph breadth-first.

After it succeeds, just re-run the failed CI job. No PR edits needed — the packages are now anonymous-readable forever.

Expand Down
30 changes: 26 additions & 4 deletions eng/gradle/mirror-dependencies.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
Gradle task(s) to run. Should be one that resolves the new dependency
graph (e.g. 'assembleDebug', 'build', 'extractProguardFiles').

.PARAMETER GradleWrapper
Optional path to the Gradle wrapper used by CI for this project, relative
to the repository root or absolute. Defaults to build-tools/gradle/gradlew.
Use this when a subproject has its own wrapper so Gradle resolves the same
dependency variants that CI requests.

.PARAMETER AndroidHome
Optional path to the Android SDK. Required when the gradle build needs it
(any project using the com.android.* plugins). Defaults to the value of
Expand All @@ -47,6 +53,12 @@

.EXAMPLE
pwsh ./eng/gradle/mirror-dependencies.ps1 -ProjectDir src/proguard-android -Task extractProguardFiles

.EXAMPLE
pwsh ./eng/gradle/mirror-dependencies.ps1 `
-ProjectDir external/Java.Interop/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin-gradle `
-Task classes `
-GradleWrapper external/Java.Interop/build-tools/gradle/gradlew.bat
#>
[CmdletBinding()]
param(
Expand All @@ -56,6 +68,8 @@ param(
[Parameter(Mandatory=$true)]
[string] $Task,

[string] $GradleWrapper,

[string] $AndroidHome = $env:ANDROID_HOME,

[int] $MaxIterations = 15
Expand All @@ -64,12 +78,19 @@ param(
$ErrorActionPreference = 'Stop'
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '../..') | Select-Object -ExpandProperty Path
$projectDirAbs = Resolve-Path (Join-Path $repoRoot $ProjectDir) -ErrorAction Stop | Select-Object -ExpandProperty Path
$gradlew = if ($IsWindows -or $env:OS -eq 'Windows_NT') {
Join-Path $repoRoot 'build-tools/gradle/gradlew.bat'
$defaultGradleWrapper = if ($IsWindows -or $env:OS -eq 'Windows_NT') {
'build-tools/gradle/gradlew.bat'
} else {
'build-tools/gradle/gradlew'
}
$gradleWrapperPath = if ([string]::IsNullOrEmpty($GradleWrapper)) {
Join-Path $repoRoot $defaultGradleWrapper
} elseif ([IO.Path]::IsPathRooted($GradleWrapper)) {
$GradleWrapper
} else {
Join-Path $repoRoot 'build-tools/gradle/gradlew'
Join-Path $repoRoot $GradleWrapper
}
if (-not (Test-Path $gradlew)) { throw "gradlew not found at $gradlew" }
$gradlew = Resolve-Path $gradleWrapperPath -ErrorAction Stop | Select-Object -ExpandProperty Path

# Azure DevOps resource id — same for every AzDO tenant.
$azDevOpsResource = '499b84ac-1321-427f-aa17-267ca6975798'
Expand Down Expand Up @@ -107,6 +128,7 @@ function Invoke-Mirror($logPath) {
Write-Host "Repo root: $repoRoot"
Write-Host "Project: $projectDirAbs"
Write-Host "Task: $Task"
Write-Host "Gradle: $gradlew"
if ($AndroidHome) { Write-Host "ANDROID_HOME: $AndroidHome" }

# Verify az is available and authenticated up front so we fail fast.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
plugins {
kotlin("jvm") version "2.0.21"
kotlin("jvm") version "2.4.10"
}

// Don't pin a jvmToolchain -- it would force Gradle to auto-provision a
// matching JDK and fail in CI environments without download repositories
// configured. Use whatever JDK the caller already set in JAVA_HOME (the
// .NET build forwards $(JavaSdkDirectory) for consistency with the rest
// of the repo). Kotlin 2.0.21 targets JVM 11 by default, which is fine
// for the bytecode the tests inspect.
// of the repo). Pin the compiler output to JVM 11 so Kotlin plugin updates
// don't change the bytecode version the tests inspect.
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

// Emit compiled classes into a stable, predictable location so the
// .NET test harness can load them via ClassFileFixture without needing
// to know the Gradle build directory layout.
tasks.named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileKotlin") {
compilerOptions.jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
destinationDirectory.set(file((findProperty("kotlinClassesDir") as String?) ?: "$rootDir/classes"))
}
Loading