AppCenter post build script - Trying to build Xamarin.UITest before executing it

Viewed 2109

I've set up a CI for my both my iOS and droid xamarin project thru Visual Studio App Center. It was all good until I tried to set up my UI Test run. I created a post build script for both android and iOS which is currently under the folder along the solution file (appcenter-post-build.sh which is required in order for me to build the whole solution [including Xamarin.UITest project]).

I was successful with the iOS since app center allows me to select the solution for the build, but it wasn't allowed on Android (appcenter-post-build.sh which is under the same folder as the droid.csproj). So, my workaround is to create another appcenter post script specifically for Android. What I'm trying to do is to build the Xamarin.UITest after the Android build.

Whenever I execute this on my post build script where I try to build the Xamarin.UITest:

/Library/Frameworks/Mono.framework/Versions/5_12_0/bin/msbuild $APPCENTER_SOURCE_DIRECTORY/MyDirectory/UITests/Project.UITests.csproj /p:Configuration=Debug

This error is being returned on the build logs:

/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets: error : The specified iOS provisioning profile 'SampleProvisioningProfile' could not be found

It seems like it tries to build the iOS project as well, which it should. Any suggestions for this issue. I've been trying to make it work for the past week.

2 Answers

Here's the post-build script I use for this app: https://github.com/brminnick/FaceOff

For App Center Build, I recommend building just the specific .csproj file, because this post build script will build your UITest project.

iOS Post-Build Script

#!/usr/bin/env bash
if [ "$APPCENTER_XAMARIN_CONFIGURATION" == "Debug" ];then

    echo "Post Build Script Started"

    SolutionFile=`find "$APPCENTER_SOURCE_DIRECTORY" -name [Your Solution File].sln`
    SolutionFileFolder=`dirname $SolutionFile`

    UITestProject=`find "$APPCENTER_SOURCE_DIRECTORY" -name [Your UITest CSProj file].csproj`

    echo SolutionFile: $SolutionFile
    echo SolutionFileFolder: $SolutionFileFolder
    echo UITestProject: $UITestProject

    chmod -R 777 $SolutionFileFolder

    msbuild "$UITestProject" /property:Configuration=$APPCENTER_XAMARIN_CONFIGURATION

    UITestDLL=`find "$APPCENTER_SOURCE_DIRECTORY" -name "[Your UITest Output File Name].dll" | grep bin | head -1` 
    echo UITestDLL: $UITestDLL

    UITestBuildDir=`dirname $UITestDLL`
    echo UITestBuildDir: $UITestBuildDir

    UITestVersionNumber=`grep '[0-9]' $UITestProject | grep Xamarin.UITest|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'`
    echo UITestVersionNumber: $UITestVersionNumber

    TestCloudExe=`find ~/.nuget | grep test-cloud.exe | grep $UITestVersionNumber | head -1`
    echo TestCloudExe: $TestCloudExe

    TestCloudExeDirectory=`dirname $TestCloudExe`
    echo TestCloudExeDirectory: $TestCloudExeDirectory

    DSYMFile=`find "$APPCENTER_SOURCE_DIRECTORY" -name *.dsym | head -1`
    DSYMDirectory=`dirname $DSYMFile`

    npm install -g appcenter-cli@1.2.2

    appcenter login --token token

    appcenter test run uitest --app "[Your App Center App Name]" --devices "[Your App Center iOS Deivce List]" --app-path $IPAFile --test-series "master" --locale "en_US" --build-dir $UITestBuildDir --dsym-dir $DSYMDirectory --uitest-tools-dir $TestCloudExeDirectory --async
fi

Android Post-Build Script

#!/usr/bin/env bash
if [ "$APPCENTER_XAMARIN_CONFIGURATION" == "Debug" ];then

    echo "Post Build Script Started"

    SolutionFile=`find "$APPCENTER_SOURCE_DIRECTORY" -name [Your Solution File].sln`
    SolutionFileFolder=`dirname $SolutionFile`

    UITestProject=`find "$APPCENTER_SOURCE_DIRECTORY" -name [Your UITest CSProj File].csproj`

    echo SolutionFile: $SolutionFile
    echo SolutionFileFolder: $SolutionFileFolder
    echo UITestProject: $UITestProject

    chmod -R 777 $SolutionFileFolder

    msbuild "$UITestProject" /property:Configuration=$APPCENTER_XAMARIN_CONFIGURATION

    UITestDLL=`find "$APPCENTER_SOURCE_DIRECTORY" -name "[Your UITest Output DLL].dll" | grep bin | head -1` 
    echo UITestDLL: $UITestDLL

    UITestBuildDir=`dirname $UITestDLL`
    echo UITestBuildDir: $UITestBuildDir

    UITestVersionNumber=`grep '[0-9]' $UITestProject | grep Xamarin.UITest|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'`
    echo UITestVersionNumber: $UITestVersionNumber

    TestCloudExe=`find ~/.nuget | grep test-cloud.exe | grep $UITestVersionNumber | head -1`
    echo TestCloudExe: $TestCloudExe

    TestCloudExeDirectory=`dirname $TestCloudExe`
    echo TestCloudExeDirectory: $TestCloudExeDirectory

    APKFile=`find "$APPCENTER_SOURCE_DIRECTORY" -name *.apk | head -1`

    npm install -g appcenter-cli@1.2.2

    appcenter login --token token

    appcenter test run uitest --app "[Your App Center App Name]" --devices "[Your Appcenter Android Device List]" --app-path $APKFile --test-series "master" --locale "en_US" --build-dir $UITestBuildDir --uitest-tools-dir $TestCloudExeDirectory --async
fi

I realize this is coming some 18 months late, but I just ran into the exact same issue and I found a way to make things play nicely in App Center, even when you have project references to the platform specific projects in the UI test project.

  • This is only an issue in the Android project, where we have to specifically build the UI test project in order to run UI tests in Test Cloud.

@mindOfAI's original post noted using the appcenter-post-build.sh script (further info on App Center build scripts) to build the UI test project after building the Android project to prepare to run the UI tests for Android. The problem is that if you want to set your 'Test Apps' in Visual Studio for Mac for the UI test project, references get added to the UI test project for the platform specific projects.

Test apps added to UI tests

If the UI test project references the iOS project, then it will try to build the iOS project as a dependency of the UI test project. Building the iOS project requires a valid iOS certificate and provisioning profile, so the build fails.

Essentially, we want the references there so we can more easily run UI tests on our local machine, but we want them gone in App Center so we don't waste time building unnecessary projects, and most importantly, so that we won't need an iOS certificate and provisioning profile when building the UI test project for Android.

To solve this, I used the appcenter-pre-build.sh script and the dotnet remove reference command to remove the references in App Center before building the UI test project for Android:

Pseudo-code

dotnet remove "Path/To/UITest/Project.csproj" reference "path/to/iOS_project.csproj" "path/to/Android_project.csproj"

Sample appcenter-pre-build.sh for Android

#!/usr/bin/env bash

echo "**************************************************************************************************"
echo "**** Custom Pre Build Script -- Android Edition"
echo "**************************************************************************************************"

set -e # Exit immediately if a command exits with a non-zero status (failure)

# In order to run UI tests on local dev machines without manually installing the latest version of the app on each platform device
# you are using, the UI test project must contain references to the Android and iOS projects.
# However, in MS App Center, if the iOS reference is there for the Android build, the build will fail since there is no certificate
# nor provisioning profile to satisfy its build requirements. This next step removes the references before building for App Center
# so that we can have the best of both worlds:
echo "Removing project references to Android and iOS projects"
dotnet remove "$APPCENTER_SOURCE_DIRECTORY/MyCoolApp.UITests/MyCoolApp.UITests.csproj" reference "$APPCENTER_SOURCE_DIRECTORY/MyCoolApp.iOS/MyCoolApp.iOS.csproj" "$APPCENTER_SOURCE_DIRECTORY/MyCoolApp.Android/MyCoolApp.Android.csproj"
  • NOTE: $APPCENTER_SOURCE_DIRECTORY is a built-in environmental variable provided by app center.

Hope this helps someone get to a solution much faster than I did =)

Related