I configure my TeamCity build agents (Windows Server 2012 VMs) using Chef, and I have a need to install Xamarin for an Visual Studio/Android build. For other installers I usually play around with invoking it with /h
, /help
, /?
, -?
, -h
and --help
until I get a usage dialog that tells me the command-line parameters. I have not been able to figure out the command-line parameters for the XamarinInstaller.exe
, however, and when I launch it like this:
XamarinInstaller.exe /quiet /norestart
since those are common conventions, it seems that it just sits there and doesn't do anything. It should be downloaded stuff (that's what it does when I launch it with the GUI) but when I look at the Ethernet usage in the task manager, nothing much is happening. I don't know where it writes it logs or how to know if it has failed. It doesn't seem to quit when it has failed.
Here is my Chef code:
xamarinTargets = 'C:\\Program Files (x86)\\MSBuild\\Xamarin\\Android\\Xamarin.Android.CSharp.targets'
xamarinInstaller = 'C:\\Repo\\Xamarin\\XamarinInstaller.exe'
execute "Xamarin" do
command "#{xamarinInstaller} /quiet /norestart"
not_if { ::File.exist?(xamarinTargets) }
end
How do I invoke the Xamarin installer headlessly? How do I install it with Chef?
Here's what I had to do, and some of it is kind of wonky.
android-sdk
and xamarin-visualstudio
via Chocolatey using the chocolatey_package
resource from the chocolatey
cookbook.android-sdk.zip
into $HOME\AppData\Local\Android
in order to get everything I need installed in the Android SDK*Here it is in Chef code:
xamarinTargets = 'C:\\Program Files (x86)\\MSBuild\\Xamarin\\Android\\Xamarin.Android.CSharp.targets'
chocolatey_package 'android-sdk'
chocolatey_package 'xamarin-visualstudio'
ruby_block "Verify Xamarin MSBuild targets exist" do
block do
if not ::File.exist?(xamarinTargets)
raise "Did not find #{xamarinTargets} which was supposed to have been created by the Xamarin install"
end
end
end
homeDir = "C:\\Users\\#{ENV['User']}"
androidDir = "#{homeDir}\\AppData\\Local\\Android"
androidSdk = "#{androidDir}\\android-sdk"
androidSdkZip = "C:\\Repo\\Android\\android-sdk.zip"
adbExe = "#{androidSdk}\\platform-tools\\adb.exe"
seven_zip_archive "Android SDK API level 15" do
path androidDir
source androidSdkZip
overwrite true
not_if { ::File.exist?(adbExe) }
end
ruby_block "Verify Android adb.exe exists" do
block do
if not ::File.exist?(adbExe)
raise "Did not find #{adbExe} which was supposed to have been created by the Android SDK install"
end
end
end
registry_key 'HKEY_USERS\\S-1-5-18\\Software\\Novell\\Mono\ for\ Android' do
values [{
:name => "AndroidSdkDirectory",
:type => :string,
:data => androidSdk
}]
recursive true
action :create
end
*I could not for the life of me get android update sdk
to work when invoked through Chef. It seems that the Android SDK Manager won't run even nongraphically unless it can detect that it is being run by a user?! Not sure, but finally in desperation, I ran the command manually to install the necessary SDK (I need API level 15) and build tools:
android update sdk --no-ui --all --filter "tools,platform-tools,build-tools-23.0.3,android-15"
I then took the resulting $HOME\AppData\Local\Android\android-sk
directory and zipped it to produce the "prefabbed android-sdk.zip
" mentioned above.