Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Using Continuous Integration with Xamarin Apps
Search
Greg Shackles
October 08, 2014
Technology
1
780
Using Continuous Integration with Xamarin Apps
Presented at Xamarin Evolve 2014
Greg Shackles
October 08, 2014
Tweet
Share
More Decks by Greg Shackles
See All by Greg Shackles
Building Modern Services with .NET Core 3 and gRPC
gshackles
0
150
Observability-Driven Development: What DevOps is Really About
gshackles
1
270
Monitoring Your Mobile Apps in the Wild
gshackles
1
79
Building Scalable Applications with the Actor Model
gshackles
0
570
Creating a Voice-Driven TV Remote with Azure and Alexa
gshackles
0
94
Build 2017 Recap for Xamarin Developers
gshackles
0
92
Going Serverless: Event-Driven Architecture Without The Infrastructure
gshackles
0
160
Evolve 2016 Redux
gshackles
0
130
Instrumenting Your Mobile Monitoring Strategy
gshackles
0
4.6k
Other Decks in Technology
See All in Technology
Goで実践するBFP
hiroyaterui
1
120
When Windows Meets Kubernetes…
pichuang
0
290
Fabric 移行時の躓きポイントと対応策
ohata_ds
1
150
iPadOS18でフローティングタブバーを解除してみた
sansantech
PRO
1
110
完全自律型AIエージェントとAgentic Workflow〜ワークフロー構築という現実解
pharma_x_tech
0
310
Accessibility Inspectorを活用した アプリのアクセシビリティ向上方法
hinakko
0
170
OPENLOGI Company Profile for engineer
hr01
1
18k
Oracle Base Database Service:サービス概要のご紹介
oracle4engineer
PRO
1
16k
[IBM TechXchange Dojo]Watson Discoveryとwatsonx.aiでRAGを実現!座学①
siyuanzh09
0
110
Formal Development of Operating Systems in Rust
riru
1
420
実践! ソフトウェアエンジニアリングの価値の計測 ── Effort、Output、Outcome、Impact
nomuson
0
2k
新しいスケーリング則と学習理論
taiji_suzuki
10
3.8k
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
98
18k
Making the Leap to Tech Lead
cromwellryan
133
9k
Embracing the Ebb and Flow
colly
84
4.5k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Statistics for Hackers
jakevdp
797
220k
A Tale of Four Properties
chriscoyier
157
23k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
Building Applications with DynamoDB
mza
93
6.2k
The Power of CSS Pseudo Elements
geoffreycrofte
74
5.4k
For a Future-Friendly Web
brad_frost
176
9.5k
Transcript
Using Continuous Integration with Xamarin Apps Senior Engineer, Olo @gshackles
[email protected]
Greg Shackles
Ship It A Cautionary Tale
None
None
None
None
None
None
None
The Worst by Vitruvius This app is just…the worst.
None
How can we deliver Continuous Awesomeness?
Continuous Integration Let your tools work for you on every
commit
What is Continuous Integration?
What is Continuous Integration? VCS
What is Continuous Integration? VCS CI Server
What is Continuous Integration? VCS CI Server CI Agent
What is Continuous Integration? VCS CI Server CI Agent
Options TFS Jenkins …and more
Delivery TestFlight HockeyApp …and more
CI with Xamarin Apps
Build Agent Setup
Build Agent Setup ▪ OS X machine for iOS builds
- Mac Mini works well
Build Agent Setup ▪ OS X machine for iOS builds
- Mac Mini works well ▪ OS X or Windows machine for Android
Build Agent Setup ▪ OS X machine for iOS builds
- Mac Mini works well ▪ OS X or Windows machine for Android ▪ Install platform SDKs
Build Agent Setup ▪ OS X machine for iOS builds
- Mac Mini works well ▪ OS X or Windows machine for Android ▪ Install platform SDKs ▪ Install Xamarin
Build Agent Setup ▪ OS X machine for iOS builds
- Mac Mini works well ▪ OS X or Windows machine for Android ▪ Install platform SDKs ▪ Install Xamarin ▪ Install agent software for chosen CI server
iOS: Build mdtool build -t:Build -c:AppStore MyAwesomeApp.sln /Applications/Xamarin Studio.app/Contents/MacOS/mdtool
iOS: Package zip -r -y MyAwesomeIosApp.zip path/to/MyAwesomeIosApp.app
Android: Build Windows: msbuild OS X: xbuild xbuild build /t:Build
/p:Configuration=Release MyAwesomeApp.sln
Android: Package (Part 1) Windows: msbuild OS X: xbuild xbuild
build /t:PackageForAndroid /p:Configuration=Release MyAwesomeAndroidApp.csproj
Android: Package (Part 2) jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore
<keystore file> -storepass <keystore password> -signedjar path/to/MyAwesomeAndroidApp-Signed.apk path/to/MyAwesomeAndroidApp.apk <keystore alias>
Android: Package (Part 2) jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore
<keystore file> -storepass <keystore password> -signedjar path/to/MyAwesomeAndroidApp-Signed.apk path/to/MyAwesomeAndroidApp.apk <keystore alias> zipalign -f -v 4 path/to/MyAwesomeAndroidApp-Signed.apk path/to/MyAwesomeAndroidApp-Aligned.apk
Package Restore NuGet mono NuGet.exe restore path/to/App.sln
Package Restore NuGet mono NuGet.exe restore path/to/App.sln Xamarin Components mono
xamarin-component.exe restore path/to/App.sln
Xamarin.UITest Run using any NUnit runner nunit-console4 path/to/TestAssembly.dll -xml testresults.xml
Pro Tip: Allow Build to Access UI jetbrains.teamcity.BuildAgent.plist
Pro Tip: Allow Build to Access UI jetbrains.teamcity.BuildAgent.plist ▪ Set
username <key>UserName</key> <string>your_user</string>
Pro Tip: Allow Build to Access UI jetbrains.teamcity.BuildAgent.plist ▪ Set
username <key>UserName</key> <string>your_user</string> ▪ Copy to /Library/LaunchAgents
TestCloud Run your UI tests on hundreds of devices test-cloud.exe
submit path/to/myapp.[ipa|apk] <TestCloud token> --devices <Device Set ID> --series "master" --locale "en_US" --assembly-dir “path/to/bin“ --nunit-xml testresults.xml
FAKE #r @"FAKE/tools/FakeLib.dll" #load "build-helpers/iOS.fsx" open Fake Target
"ios-build" (fun () -> iOS.build "Debug|iPhoneSimulator" ) Target "ios-adhoc" (fun () -> iOS.build "AdHoc|iPhone" ) Target "ios-testflight" (fun () -> iOS.publishToTestFlight() ) "ios-adhoc" ==> "ios-testflight" RunTarget()
FAKE #r @"FAKE/tools/FakeLib.dll" #load "build-helpers/iOS.fsx" open Fake Target
"ios-build" (fun () -> iOS.build "Debug|iPhoneSimulator" ) Target "ios-adhoc" (fun () -> iOS.build "AdHoc|iPhone" ) Target "ios-testflight" (fun () -> iOS.publishToTestFlight() ) "ios-adhoc" ==> "ios-testflight" RunTarget() TeamCityHelper.PublishArtifact "path/to/App.zip" Helpers
FAKE #r @"FAKE/tools/FakeLib.dll" #load "build-helpers/iOS.fsx" open Fake Target
"ios-build" (fun () -> iOS.build "Debug|iPhoneSimulator" ) Target "ios-adhoc" (fun () -> iOS.build "AdHoc|iPhone" ) Target "ios-testflight" (fun () -> iOS.publishToTestFlight() ) "ios-adhoc" ==> "ios-testflight" RunTarget() TeamCityHelper.PublishArtifact "path/to/App.zip" TeamCityHelper.sendTeamCityNUnitImport "results.xml" Helpers
FAKE #r @"FAKE/tools/FakeLib.dll" #load "build-helpers/iOS.fsx" open Fake Target
"ios-build" (fun () -> iOS.build "Debug|iPhoneSimulator" ) Target "ios-adhoc" (fun () -> iOS.build "AdHoc|iPhone" ) Target "ios-testflight" (fun () -> iOS.publishToTestFlight() ) "ios-adhoc" ==> "ios-testflight" RunTarget() TeamCityHelper.PublishArtifact "path/to/App.zip" TeamCityHelper.sendTeamCityNUnitImport "results.xml" TestFlight(fun p -> {p with File: "path/to/App.app" Notes: "Now with 42% more awesome!" }) Helpers
FAKE #r @"FAKE/tools/FakeLib.dll" #load "build-helpers/iOS.fsx" open Fake Target
"ios-build" (fun () -> iOS.build "Debug|iPhoneSimulator" ) Target "ios-adhoc" (fun () -> iOS.build "AdHoc|iPhone" ) Target "ios-testflight" (fun () -> iOS.publishToTestFlight() ) "ios-adhoc" ==> "ios-testflight" RunTarget() TeamCityHelper.PublishArtifact "path/to/App.zip" TeamCityHelper.sendTeamCityNUnitImport "results.xml" HipChatNotification(fun p -> {p with From = "App BuildBot" Message = "Published to TestFlight" Color = "green" }) TestFlight(fun p -> {p with File: "path/to/App.app" Notes: "Now with 42% more awesome!" }) Helpers
FAKE Helpers for Xamarin “path/to/MyApp.sln“ |> RestoreComponents (fun defaults ->
{defaults with ToolPath = “...” })
FAKE Helpers for Xamarin “path/to/MyApp.sln“ |> RestoreComponents (fun defaults ->
{defaults with ToolPath = “...” }) iOSBuild (fun defaults -> {defaults with ProjectPath = “path/to/MyApp.sln” Configuration = “AppStore” Target = “Build” })
FAKE Helpers for Xamarin iOSBuild (fun defaults -> {defaults with
ProjectPath = “path/to/MyApp.sln” Configuration = “AppStore” Target = “Build” }) “path/to/MyApp.sln“ |> RestoreComponents (fun defaults -> {defaults with ToolPath = “...” }) AndroidPackage (fun defaults -> {defaults with ProjectPath = “path/to/MyApp.csproj” }) |> AndroidSignAndAlign (fun defaults -> {defaults with KeystorePath = “...” KeystorePassword = “...” KeystoreAlias = “...” }) |> fun file -> TeamCityHelper.PublishArtifact file.FullName
How We Work At
None
None
None
Git / GitHub ▪ Feature branches ▪ Every app builds
on every branch ▪ Any branch can be pushed to TestFlight ▪ Pull Requests for code review
Test-Driven Core
UI Tests and Test Cloud
Deployment and Distribution
Deployment and Distribution
Deployment and Distribution
Continuous Monitoring
Demo github.com/gshackles/xamarin-ci-sample
Questions? @gshackles
[email protected]
! github.com/gshackles speakerdeck.com/u/gshackles