TeamCity build.counter parameter in build.xml - android

It seems that the TeamCity parameter ${build.counter} is not resolving in our ant build.xml. We have:
<replaceregexp
file="AndroidManifest.xml"
match='android:versionCode="(.*)"'
replace='android:versionCode="${build.counter}"'
/>
This throws the error:
String types not allowed (at 'versionCode' with value '${build.counter}')
It looks like it is taking the parameter "${build.counter}" as a literal string.
Using another TeamCity integer parameter in place of ${build.counter}, for example ${teamcity.build.id}, works fine.
Does anyone know why this might be?
Update
Thanks Biswajit_86 for the answer. Here also is my related discussion with JetBrains:

Your build files wont know the value of build.counter at all. They can only read system properties but build.counter is a config parameter.
To do this declare a system parameter named system.BUILD.COUNTER whoose value is %build.counter% and pass this into your target. If you change your abnt build.xml to read ${BUILD.COUNTER}, it will work fine
build parameters section
system.BUILD.COUNTER %build.counter%
build xml file
<replaceregexp
file="AndroidManifest.xml"
match='android:versionCode="(.*)"'
replace='android:versionCode="${BUILD.COUNTER}"'
/>

Ant won't read teamctiy varaibles directly. You'll need to create a similar build.counter property in your ant project like:
<property name="build.conuter" value=""/>
and pass its value from Teamcity build step like:

Related

Android Facebook App ID in AndroidManifest with ANT causes errors

Just read this question (Android facebook applicationId cannot be null) and really hoped it would fix my issue too.
It is similar, however, I'm working with ANT and added the App ID's in the build.xml.
The build runs fine, the logs don't show anything weird. I see that the somehow adding the App ID in the Manifest tricks Android into thinking it's an Integer, while it should actually be a String. And whatever I try, I still get the same error and the app keeps crashing.
applicationId cannot be null
I tried escaping the application id's when specifying them, like so:
<property
name="fb_app_id_a"
value="\ XXXXXXXXXXXX" />
But it resulted in the same error. So I tried to be smart and added the escaping later, but to no avail:
<replaceregexp
file="AndroidManifest.xml"
flags="g"
match="android:value="#string/app_id""
replace="android:value="\ ${fb_app_id_a}"" />
I try to replace the conventional implementation with the build.xml, because we have to use several app ID's. Although the logs of the build I ran look fine, still it's giving me hell to get the build automation done because of this issue. Am I doing something wrong, or should I be doing it differently?
Does anybody have experience with build automation and the use of multiple app ID's for Facebook?
Thanks a bunch!
What I use to change some value in the manifests file is:
<replaceregexp file="AndroidManifest.xml" match='android:label=".*"'
replace='android:label="my new value"'/>
With this, I will change android:label="some value" to android:label="my new value"
I guess that in your case will be:
<property name="fb_app_id_a" value="some value" />
<replaceregexp file="AndroidManifest.xml" match='property name="fb_app_id_a" value=".*"'
replace='property name="fb_app_id_a" value="your new value"'/>
Also, to decomple the apk and see the AndroidManifest.xml helped me a lot

Change application name through ant script in android

I am trying to change an application name on compilation through an ant script(which is in the build.xml). Application name is stored in strings.xml. Following is the piece of code,
<target name="changeName">
<property
name="applicationName"
value="30004" />
<replaceregexp
file="C:\Users\<user-name>\git\appname\res\values\strings.xml"
match='<string name="app_name"<test</string<'
replace="\1${applicationName}\2"
byline="true"/>
</target>
But it doesnt change the name in strings.xml. Can someone please correct me on what I am doing wrong? Also please let me know how I can achieve similar operation through relative paths.
Thanks
Edit:
Following is the xml that needs to be changed through the above mentioned ant script
<string name="app_name">Test Application</string>
The following replacement will change the "app-name" attribute for any <string> element that contains this attribute:
<replaceregexp
file="C:\Users\<user-name>\git\appname\res\values\strings.xml"
match="<string name=".+""
replace="<string name="${applicationName}""
/>
To save yourself from escape code hell, you might want to set some properties using CDATA before running the replacement. This way you can clearly see the regex patterns:
<property name="regex.match"><![CDATA[<string name=".+"]]></property>
<property name="regex.replace"><![CDATA[<string name="${applicationName}"]]></property>
<replaceregexp
file="C:\Users\<user-name>\git\appname\res\values\strings.xml"
match="${regex.match}"
replace="${regex.replace}"
/>

Xamarin.Android android:versionCode android:versionName - From Jenkins Build Server

We have a unique situation where we are deploying a Xamarin.Android app to China to 33 app stores. Hence, our solution has 33 application projects, and we setup Jenkins (running on Windows) to package and sign all our apks (otherwise it would be crazy to make builds).
We also need to modify android:versionCode and android:versionName in the manifest file, by using the ${SVN_REVISION} value from Jenkins. Is there a way to pass these values command line to MSBuild?
Normally we would hand edit this value, but it's not possible because of so many application projects.
Our build parameters right now look like this in Jenkins:
/p:Configuration=Release;AndroidKeyStore=True;AndroidSigningKeyStore=ourkeystore.keystore;AndroidSigningStorePass=ourpassword;AndroidSigningKeyAlias=ouralias;AndroidSigningKeyPass=ourpassword /t:SignAndroidPackage
Add this to the end of your *.csproj file, before the ending </Project> tag:
<Target Name="BeforeBuild" Condition=" '$(JENKINS)' == '1' ">
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="<Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' />" Query="manifest/#android:versionCode" Value="$(SVN_REVISION)" />
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml" Namespaces="<Namespace Prefix='android' Uri='http://schemas.android.com/apk/res/android' />" Query="manifest/#android:versionName" Value="2.0.$(SVN_REVISION)" />
</Target>
I have Jenkins configured to pass JENKINS=1 and SVN_REVISION. When it goes to build, it modifies AndroidManifest.xml before the build.
I don't know if this will work on xbuild on a Mac or not, depends on if XmlPoke is implemented. I should do a blog post on this.
No. You'll have to manipulate the android:versionCode and android:versionName yourself. Personally, I use a rake task to handle this particular detail.

How to Auto Increment versionCode when exporting Android apps in Eclipse?

I want to auto-increment the versionCode and versionName of the manifest file of the android app when I click on Export (to export a new version of the app)
I found the second answer here (Auto increment version code in Android app) extremely useful (comment include .exe programs to auto increment Android versionCode) , however, they made it run on Build, I want it to run when I click on File -> Export , see image please
You might consider modifying the File -> Export button to execute a builder to increment the version code (as shown in the post you mentioned) in addition to that button's usual functionality. The org.eclipse.ui.menus extension point seems like a good starting point. (Disclaimer: I haven't tried this.)
However, it might be good to keep the following xkcd in mind here:
I have done this with a ton of custom ant steps.
First, you need to extract the build number into a properties file. Let's call it version.properties
Then, the step to increment the version code is:
<target name="increment-version-code">
<propertyfile file="version.properties">
<entry key="versionCode" type="int" default="0" operation="+" value="1" />
</propertyfile>
</target>
This will read the entry versionCode, increment it and save it back to version.properties.
So far, so good. The last step is to get that versionCode into the AndroidManifest.xml file and unfortunately now it gets messy.
The way I solved it was to regenerate the manifest from a template on every build using the filtering functionality in ant.
<target name="generate-manifest">
<filter filtersfile="version.properties"/>
<copy todir="${source.dir}" overwrite="true" verbose="true" filtering="true">
<fileset dir="${source.dir}" casesensitive="false">
<include name="**/*.base"/>
</fileset>
<mapper type="glob" from="*.base" to="*" />
</copy>
</target>
Then, all you have left to do is move your AndroidManifest.xml to AndroidManifest.xml.base and replace your versionCode attribute to read android:versionCode="#versionCode#" . You can then run the increment-version-code target to bump the versionCode in version.properties and the generate-manifest target to convert the .base template into the final manifest.
These can then be easily added as build steps to your Eclipse project or as dependencies to exported ant builds. Unfortunately, there's no easy hook for the Export functionality (though, there is for "After Clean", which I find good enough).
Of course, with Gradle on the horizon, all of this would have to be rewritten soon. :(

How to set strings.xml values at build time?

I'm building my Android application with Ant, and would like to set one of the values in my strings.xml at build time. For example, I could use
<string name="app_name">MyApp-DEBUG</string>
with a debug build, or I could use
<string name="app_name">MyApp<string>
for a release build. Is this possible?
There are two tasks in Ant that can help:
First is the <replace>. You give it a file name that contains parameters that can be replaced, and you give the <replace> task the values for those parameters. It replaces them in the file. I don't like this task because it's used to replace stuff that is under version control, and if you're not careful, you can end up changing the file without meaning to.
settings.xml
<settings>
<properties>
<property name="server" value="#SERVER#"/>
</properties>'
</settings>
Replace Task
<replace file="settings.xml">
<replacetoken token="#SERVER#" value="google.com"/>
</replace>
I've seen plenty of version control repositories where revision #3 of the replaced file was an accidental checkin of the the file with the replaced parameters (and not realizing it until the next release when the parameters didn't get changed). Then version #4 is a duplicate of version #2 which had the replacement parameters. Followed by a bad version #5, followed by a version #6 which restores the file, and on and on.
My preferred method is to copy the file over to another directory, and use <filterset>/<filter> tokens to change the file while being copied:
<copy todir="${target.dir}"
file="settings.xml">
<filterset>
<filter token="SERVER" value="google"/>
</filterset>
</copy>
Both can use a property file instead of specifying individual tokens. The <copy>/<filterset> pair can take a fileset of files and replace a bunch of tokens at once. (Be careful not to pass it a binary file!).
try this code, it works for me
<target name="app-name-debug">
<replaceregexp file="res/values/strings.xml" match='name="app_name"(.*)'
replace='name="app_name">MyApp-DEBUG<\/string>'/>
</target>
<target name="app-name-release">
<replaceregexp file="res/values/strings.xml" match='name="app_name"(.*)'
replace='name="app_name">MyApp<\/string>'/>
</target>

Categories

Resources