Thursday, August 5, 2010

Hudson build by email

Although this is pretty well documented by the Hudson wiki (see Builds by e-mail (sendmail) and Builds by e-mail (qmail)):

http://wiki.hudson-ci.org/display/HUDSON/Building+a+software+project

we're running against Windows machines and I wanted to try a proof of concept for that. So the following is a non-scalable proof of concept, but does show the idea works:

1. Hudson has a configuration choice to pass tokens to an URL that will automatically initiate and on demand build remotely, so it's possible to do this by email

2. In the Hudson configuration for the build, there's a section named 'Build Triggers' and a checkbox 'Trigger builds remotely (e.g., from scripts)'. Check this box, then enter a value for the Authentication Token

3. In this proof of concept design an exe was created on a client that had these lines:
start iexplore http://server:port/hudson/job/job_name/build?token=authentication_token
ping -n 20 127.0.0.1
taskkill /im iexplore.exe

4. Then an Outlook email rule was set up on the client with these parameters: When a message arrives with 'Run job_name' in the subject, start remote_test.exe

5. Now when you send a mail to this client it will open a browser, pass the token in the URL and begin the build

Wednesday, August 4, 2010

Hudson deploys and Linux/Tomcat

One of the problems we had running on for a very long time was Tomcat stopping on a deploy to a Linux server once the deploy job had completed. This was working fine on the Windows servers so I was stumped as to the issue.
A little searching on the net led to these links and solution:

http://wiki.hudson-ci.org/display/HUDSON/Spawning+processes+from+build

http://wiki.hudson-ci.org/display/HUDSON/Post+build+task

The bottom line of this is that when you configure a build or deploy that is experiencing this issue, just choose 'Post build task' from the 'Post-build Actions' section in the job configuration.
To get the Tomcat server started on the dev Linux boxes I then just needed this in the 'Script' box:
/opt/apache-tomcat-6.0.20/bin/startup_nohup.sh
Now the Tomcat service stays running when the Hudson job completes

Thursday, July 8, 2010

Building from terminal with more than one Xcode version

It's possible to build against more than one Xcode version from terminal.
First step is to install Xcode versions alongside each other instead of as an Update. When you download the latest Xcode from Apple, just choose to install to a directory that's parallel to your current Xcode install. In this case we had Xcode 3.2.2 installed in the /Developer directory, so I installed Xcode 3.2.3 in a directory named /Developer323.
One of the tricky things I ran into after the 3.2.3 install was that it defaulted to this for all builds. I found this out when I tried to build existing iPhoneOS 3.1.3 builds and got the error:

=== BUILD NATIVE TARGET Mobile OF PROJECT Mobile WITH CONFIGURATION Release ===Check dependencies
No architectures to compile for (ARCHS=, VALID_ARCHS=i386 ppc ppc64 ppc7400 ppc970 x86_64).
[BEROR]No architectures to compile for (ARCHS=, VALID_ARCHS=i386 ppc ppc64 ppc7400 ppc970 x86_64).

Since we actually wanted to use 3.2.2 as the default I needed to know how to set this from terminal.
Apple gives several options for calling Xcode version from terminal:
http://developer.apple.com/mac/library/documentation/Xcode/Conceptual/XcodeCoexistence/Contents/Resources/en.lproj/Details/Details.html

Since the installs are sitting in parallel it became as easy as adding this line before the xcodebuild section in the build:
export DEVELOPER_DIR="/Developer"
and when we're ready to build iPhoneOS4 against 3.2.3 this line will become:
export DEVELOPER_DIR="/Developer323"

Android dx.bat causing out of memory errors

The Android SDK contains a file name dx.bat whose purpose is to convert class files to dex files. Embedded in the file is a JAVA_OPTS setting that is commented out by default.
When you build Android you may see an error like this:

-dex: [echo] Converting compiled files and external libraries into D:\Androidproject\bin\classes.dex...
[apply]
[apply] UNEXPECTED TOP-LEVEL ERROR:
[apply] java.lang.OutOfMemoryError: Java heap space....

First determine which SDK you are building against since all may be installed in the Android SDK location by default. In this case I see the failure:
BUILD FAILED
D:\ProgramFiles\Java\android-sdk-windows\platforms\android-1.6...

You need to edit the dx.bat file that sits in the tools directory for the SDK you're using (ex. D:\ProgramFiles\Java\android-sdk-windows\platforms\android-1.6\tools). There's a 'set javaOpts=' setting that has no value by default, and below in the file a commented section with the value set to -Xmx256M. Either remove the comment from the commented one, or add the value to the empty one.

Friday, July 2, 2010

Hudson connectivity issues with security enabled

We ran into issues with Hudson dropping off connections to slaves once security was enabled on the Hudson server.
We took the following steps to reconnect the servers as a Windows service and they have remained connected with no issues so far:
Verify that the node has Hudson Slave installed as a service. If not, or if the validity of the installed one is in question, follow these steps. Otherwise skip to step g:
a. Configure the node as jnlp on the main Hudson server.
b. Login to the slave machine and open a browser
c. Paste the URL from the jnlp configuration into a browser in the node (ex. http://servername/hudson/computer/slavename/slave-agent.jnlp)
d. If the 'Connected' page doesn't come up, you may need to add the URL to the 'Trusted Sites' in IE security configuration
e.The 'Connected' browser window will have a 'File' - 'Install as a Windows Service' option. Choose this.
f. After installed, stop the Hudson Slave service. Change the login to an account with rights to run the slave service
g. Open the hudson-slave.xml in the Hudson home directory on the slave machine, usually someplace like D:\Hudson
h. In the line with the jnlp URL, add the following after the URL: -jnlpCredentials hudsonusername:password (an account they you have configured in your Hudson security setup)
i. In the Hudson UI, change the slave configuration to use Windows service to connect. Enter user with password as the account to connect.
j. Start the Hudson Slave service on the slave and make sure it's set to 'Automatic' for startup

Tuesday, June 15, 2010

iPhone/iPad arguments from terminal for Hudson

When we started building iPad I realized some of the existing iPhone builds had possibly been calling values like SDKROOT incorrectly, but since there was only one sdk installed it failed silently and fell back to the default sdk. But building iPad and iPhone there's a need to call these values out correctly. From the Apple site, requirements are (quoting):

"To configure Universal apps that run on both iPad and iPhone, in Build Settings:
- set Base SDK in the Architectures section to “iPhone SDK 3.2”
- set iPhone OS Deployment Target to iPhone OS 3.1.3 or earlier
• For iPad-only development, use iPhone SDK 3.2 and target iPhone OS 3.2
• For iPhone-only, use iPhone SDK 3.1.3 and target iPhone OS 3.1.3 or earlier
• Be sure to set Targeted Device Family to iPad, iPhone, or iPhone/iPad"

But what are those values from terminal so we can pass them with Hudson?
Since we aren't building a universal app we currently have this configured in the iPhone build:
SDKROOT=iphoneos3.1.3 IPHONEOS_DEPLOYMENT_TARGET=3.1.3 TARGETED_DEVICE_FAMILY=1
and this in the iPad:
SDKROOT=iphoneos3.2 IPHONEOS_DEPLOYMENT_TARGET=3.2 TARGETED_DEVICE_FAMILY=2

Tuesday, June 8, 2010

iPhone Distribution code signing from Hudson

iPhone code signing for Distribution is a task in itself, but when adding in the need to do it in a hands off way it gets even more complex.
1) First you want to create and download a Distribution profile to your build machine and install in the correct spot. This is a whole topic in itself and I might create a separate post on this.
2) Open the xcodeproj for the build you want to create in Xcode.
3) Click on the Project name and then click on the Info icon at the top of the Xcode window.
4) This opens the Project Info window, then click on the Configurations tab.
5) Click on your Release build (if you don't have one yet, create one), and then choose the Duplicate button at the bottom of the window
6) Name the new Configuration 'Distribution'
7) Go back to the Configurations tab in the Project Info window and scroll down to find the Code Signing Identity choice
8) Click on the Value drop down and choose the Distribution profile for the Code Signing Identity. You can then close the Project Info window
9) The important point now!!: if you don't have version control save of the xcodeproj location to a safe backup location. If you have version control, check the xcodeproj location back in. What you should see is that the pbxproj file has changed and has been updated with the Distribution profile
10) From a Hudson build you can now call the build using this pbxproj and use '-configuration Distribution' in the xcodebuild line, and you'll have a Distribution build created!