Im Laufe der Zeit sind wir auf viele kleine und größere Problemstellungen gestoßen, welche gelöst werden konnten.
Damit anderen diverse Fallstricke erspart bleiben hier nun ein paar Tutorials zu den entsprechenden Themen.
In einem Capacitor Projekt haben wir implementiert, dass der Web-App Teil davon von der Nativen Container App selbst upgedated wird und wollten daher meist nur den Web-Teil bauen und fürs Update verpacken.
Das bauen der App "verschlingt" relativ viel Build-Zeit, was wenn man im App teil nichts geändert hat relativ sinnlos ist.
Daher gabs folgendes Scenario - der Web Teil wird im CI Build automatisch getriggert - der App Teil mit dem Capacitor Build, anschließendem signieren und so aber nur per Parameter.
Dazu musste auch berücksichtigt werden, dass der Web teil damit auf einem einfachen (und viel schnelleren) ubuntu-latest vmImage Agent gebaut werden kann, während die App im macos-latest Image gebaut wird (sowohl Android als auch iOS).
Wie kann man das in einem Azure DevOps YAML Build lösen ?
Es hat mich ein wenig Zeit gekostet, daher wirds hier festgehalten 😉.
Zuerst brauch ma einen Parameter, welcher sagt ob die mobile App gebaut werden soll oder nicht:
parameters:
- name: BuildConfiguration
type: string
default: Release
values:
- Release
- Debug
- name: BuildMobileApp
type: boolean
default: false
und jetzt kommt der Trick:
Damit wir im Job das VM Image wechseln können brauchen wir vorab einen Job welcher das vmImage für den Build ermittelt:
jobs:
- job: Check_Vars
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: none
- script: if [ "${{ parameters.BuildMobileApp }}" == "True" ]; then echo "##vso[task.setvariable variable=buildVmImage;isoutput=true]macos-latest"; else echo "##vso[task.setvariable variable=buildVmImage;isoutput=true]ubuntu-latest"; fi
name: produceVar
Der Job macht nur ein kleines bash script welches schaut ob die der Parameter gesetzt ist und setzt eine Output-Variable für den nächsten Job mit dem namen vom Pool.
Wichtig ist noch das checkout: none
weil wir ja keinen ausgecheckten Code brauchen.
Das muss jetzt nochmal dem neuen Job gefüttert werden :
- job: Build_App
dependsOn: Check_Vars
variables:
buildVmImage: $[ dependencies.Check_Vars.outputs['produceVar.buildVmImage'] ]
pool:
vmImage: $(buildVmImage)
zuerst definieren wir dass der Build_App job den Check_Vars braucht. Dann lesen wir den Output des jetzten Jobs aus und setzten diese in eine Variable, welche dann in dem vmImage des Pools verwendet wird - direkt geht es leider nicht, da er dort die Auswertung der Expression nicht macht.
Fertig - es geht 😊
Zuletzt müssen jetzt nur mehr alle Tasks mit die zum Bauen der App gehören noch deaktivert werden, falls wir keine App bauen wollen.
- task: ios-bundle-version@1
displayName: 'set iOS app version'
condition: eq('${{ parameters.BuildMobileApp }}', true)
Vor kurzem hatte ich das Problem, dass mein Notebook - während eines NuGet updates - meinte wegen zu wenig Akku herunterzufahren...
Die Folge war ein halb heruntergeladenenes Package im Cache - genauer gesagt Xamarin.Forms - weches weiter zur Folge hatte, dass sich meine Xamarin.Forms
Projekte nicht Builden liesen. Stattdessen bekam ich lange NugetPackege Fehlermeldungen in mein Outputfenster...
Die Lösung ist aber recht einfach:
Die Ausgabe sollte dann in etwa so aussehen:
Wenn noch Fehler offen bleiben wie hier - so ist noch irgendein File lock vorhanden (durch ein Studio oder anderes laufendes Programm)
Damit für eine komplette Automatisierung des Buildprozesses für ein Android Projekt, braucht man egal ob nativ oder via Xamarin ein KeyStore-File um das File abschließend signieren zu können. Erst danach wird das apk-File von einem Gerät akzeptiert.
Gott sei Dank kann man sich recht leicht ein Keystore File machen, indem man sich des keytool.exe Programms bedient, welches beim JDK mitgeliefert wird.
Wenn man den Android SDK zusammen mit Android Studio oder aus einer anderen bestehenden Installation verwenden möchte so ist der Pfad den SDKs schnell in den Einstellungen geändert.
Allerdings kann es passieren, dass der "Visual Studio Emulator for Android" dann nicht mehr funktioniert.
Denn dieser verwendet auch den SDK und wenn die Versionen nicht mehr zusammen passen dann bootet der Emulator zwar, aber das Visual Studio hängt sich beim deployn aufs Gerät einfach auf.
Damit das wieder funktioniert einfach den Pfad auch hier in der Registry setzen:
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Android SDK Tools]
"Path"="D:\Android\android-sdk-windows"
Passt natürlich den Pfad an eure Installation an.
Ich bin auf folgendes Problem gestoßen, dass auftreten kann wenn man auf einem Gerät via USB debuggen möchte.
Der Fehler äußert sich beim Debuggen in dem Visual Studio 2015 zuerst kurz hängt und danach vollständig abstützt.
Seit einem der letzen Builds (genauer gesagt Windows 10, Version 1511) funktioniert das nämlich nur mehr nach Freigabe eines Sicherheitsschalters in den Einstellungen.
Beheben lässt sich das ganze allerdings relativ einfach mit dem Schalter "Geräte-Suche" unter den Entwickler-Optionen.
inzwischen gibt es dazu auch einen Windows Blog Eintrag dazu: https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal-mobile