Skip to content
Open
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
14 changes: 7 additions & 7 deletions .github/skills/update-expected-app-size/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ Download updated expected app size files from Azure DevOps artifacts for the cur

The app size tests (`tests/dotnet/UnitTests/AppSizeTest.cs`) compare the built app's size and preserved APIs against expected files stored in `tests/dotnet/UnitTests/expected/`. When the test detects a difference and `WRITE_KNOWN_FAILURES` is not set, it writes the updated expected file to `$(Build.ArtifactStagingDirectory)/updated-expected-sizes/`, and a pipeline step publishes this directory as a build artifact.

The artifact name follows the pattern `updated-expected-sizes-{testPrefix}-{attempt}` (e.g., `updated-expected-sizes-dotnettests_ios-1`). Inside the artifact, files are named:
- `{Platform}-{Runtime}-size.txt` — e.g., `iOS-MonoVM-size.txt`
- `{Platform}-{Runtime}-preservedapis.txt` — e.g., `iOS-MonoVM-preservedapis.txt`
The artifact name follows the pattern `{uploadPrefix}updated-expected-sizes-{testPrefix}-{attempt}` (e.g., `updated-expected-sizes-dotnettests_ios-1`). Inside the artifact, files are named after the test variant:
- `{Platform}-{Variant}-size.txt` — e.g., `iOS-MonoVM-size.txt`, `iOS-MonoVM-interpreter-size.txt`, `iOS-NativeAOT-TrimmableStatic-size.txt`, `MacOSX-CoreCLR-Interpreter-size.txt`
- `{Platform}-{Variant}-preservedapis.txt` — e.g., `iOS-MonoVM-preservedapis.txt`, `MacCatalyst-MonoVM-interpreter-preservedapis.txt`

The expected files on disk are at:
- `tests/dotnet/UnitTests/expected/{Platform}-{Runtime}-size.txt`
- `tests/dotnet/UnitTests/expected/{Platform}-{Runtime}-preservedapis.txt`
- `tests/dotnet/UnitTests/expected/{Platform}-{Variant}-size.txt`
- `tests/dotnet/UnitTests/expected/{Platform}-{Variant}-preservedapis.txt`

## Workflow

Expand Down Expand Up @@ -111,8 +111,8 @@ After placing the files:
If automated download fails (auth issues, etc.), provide the user with:
1. The Azure DevOps build URL
2. Instructions to navigate to the build → Summary → Artifacts section
3. Look for individual artifacts whose names match the patterns above
4. Download each file and place it as `tests/dotnet/UnitTests/expected/{artifactName}.txt`
3. Look for individual artifacts whose names contain `updated-expected-sizes`
4. Download the artifact zip, extract it, and copy the `.txt` files (e.g., `iOS-MonoVM-interpreter-size.txt`) into `tests/dotnet/UnitTests/expected/`

## Fallback: Run Locally

Expand Down
18 changes: 13 additions & 5 deletions tests/dotnet/UnitTests/AppSizeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,16 @@ static void AssertAppSize (ApplePlatform platform, string name, string appPath,
Console.WriteLine ($" Updated expected file: {expectedSizeReportPath}");
} else if (hasDifferences) {
UploadUpdatedExpectedFile (expectedSizeReportPath, report.ToString ());
var updateHint = GetUpdateHint ();
if (hasFileDifferences) {
var details = new List<string> ();
foreach (var key in filesAdded)
details.Add ($"added: '{key}'");
foreach (var key in filesRemoved)
details.Add ($"removed: '{key}'");
Assert.Fail ($"The app bundle's file list changed ({string.Join (", ", details)}). The updated expected file is available as a build artifact (set WRITE_KNOWN_FAILURES=1 to update locally).");
Assert.Fail ($"The app bundle's file list changed ({string.Join (", ", details)}). {updateHint}");
}
Assert.Fail ($"{msg} The updated expected file is available as a build artifact (set WRITE_KNOWN_FAILURES=1 to update locally).");
Assert.Fail ($"{msg} {updateHint}");
}
}

Expand Down Expand Up @@ -251,9 +252,9 @@ void AssertAssemblyReport (ApplePlatform platform, string name, string appPath,
if (!update) {
if (addedAPIs.Count > 0 || removedAPIs.Count > 0) {
UploadUpdatedExpectedFile (expectedFile, string.Join ('\n', preservedAPIs) + "\n");
var updateMsg = " The updated expected file is available as a build artifact (set WRITE_KNOWN_FAILURES=1 to update locally).";
Assert.That (addedAPIs, Is.Empty, "No added APIs." + updateMsg);
Assert.That (removedAPIs, Is.Empty, "No removed APIs." + updateMsg);
var updateHint = " " + GetUpdateHint ();
Assert.That (addedAPIs, Is.Empty, "Unexpected APIs were added to the preserved set." + updateHint);
Assert.That (removedAPIs, Is.Empty, "APIs were unexpectedly removed from the preserved set." + updateHint);
}
}
}
Expand All @@ -274,6 +275,13 @@ static void UploadUpdatedExpectedFile (string expectedFilePath, string content)
Console.WriteLine ($" Updated expected file written to: {outputFile}");
}

static string GetUpdateHint ()
{
if (IsInCI)
return "The updated expected file is available as a build artifact (set WRITE_KNOWN_FAILURES=1 to update locally).";
return "Set WRITE_KNOWN_FAILURES=1 to update the expected files in-place.";
}

static string FormatBytes (long bytes, bool alwaysShowSign = false)
{
return $"{(alwaysShowSign && bytes > 0 ? "+" : "")}{bytes:N0} bytes ({bytes / 1024.0:N1} KB = {bytes / (1024.0 * 1024.0):N1} MB)";
Expand Down
9 changes: 8 additions & 1 deletion tools/devops/automation/templates/tests/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,20 @@ steps:
condition: succeededOrFailed()

# Upload updated expected app size files if the app size tests produced any.
- bash: |
if [ -d "$(Build.ArtifactStagingDirectory)/updated-expected-sizes" ]; then
echo "##vso[task.setvariable variable=HAS_UPDATED_EXPECTED_SIZES]true"
fi
displayName: 'Check for updated expected app size files'
condition: succeededOrFailed()

- task: PublishPipelineArtifact@1
displayName: 'Publish Artifact: Updated expected app size files'
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/updated-expected-sizes'
artifactName: '${{ parameters.uploadPrefix }}updated-expected-sizes-${{ parameters.testPrefix }}-$(System.JobAttempt)'
continueOnError: true
condition: succeededOrFailed()
condition: and(succeededOrFailed(), eq(variables['HAS_UPDATED_EXPECTED_SIZES'], 'true'))

- pwsh: |
$summaryName = "TestSummary-${{ parameters.testPrefix }}.md"
Expand Down
Loading