Increment Build & Version Number of Android App using Azure DevOps & App Centre - azure-devops

I am using Azure DevOps and AppCenter(Distribution) for implementing my CICD. Based on the steps mentioned below I have implemented the both CI & CD tasks.
Thant means,
I will create the build using Azure Devops (VSTS) & Push that in to App Centre.
Steps I Follow
Here my doubt is,
How I can increment my Build and Version numbers while distributing these builds?

The easy way is to install Mobile App Tasks for iOS and Android extension for Azure DevOps. You get a task "Bump Version" (for Andriod and iOS).
The task change app's version name and code at build time.
Inputs:
sourcePath - Path to android manifest
versionCode - code number that must be an integer (put the build number variable, it's incremented automatically)
versionCodeOffset - a specific number to increment the version code
versionName- user visible name
printFile - output the file before and after changing variables
Another option is to install Colin's ALM Corner Build & Release Tools extension and use the Version Assemblies task following this detailed tutorial.
Check also this question & answer.

For anyone still looking for an alternative method, try modifying either the version number, version name or both in the module build.gradle file like below:
android {
defaultConfig {
applicationId 'com.sample.testapp'
minSdk 28
targetSdk 31
versionCode 2
versionName "2.2"
}
...
}

You can do almost anything with shell scripting, but I figured out to Automate Build numbering & App versioning for Android WITHOUT shell scripting while using Microsoft AppCenter CI/CD pipelines!
You can create 2 environment variables VERSION_CODE & VERSION_NAME and then use them in the build.gradle file like this:
versionCode System.getenv("VERSION_CODE") ? System.getenv("VERSION_CODE").toInteger() : 201
versionName System.getenv("VERSION_NAME") ? System.getenv("VERSION_NAME").toString() : "1.2.1"
More details in this article

Another option (if you don't want to install an extra plugin in Azure) is using the embedded counter function.
So basically you'll need to create the variable in the root of your pipeline, smth. like this:
versionCode: $[counter('Google_Play_version_offset', 100)]
Then it will autoincrement for each build - 100, 101, 102, etc.
In the gradle task you can pass this value with next:
- task: Gradle#2
inputs:
...
options: '-PversionCode=$(versionCode)'
...
Please also make sure to handle this option in the build.gradle file.

Related

How to auto increment the android app version name and version code using app center and azure devops

Is there any way to auto increment the android app version name and version code.
My app version name format-- major.minor.0.build (1.2.0.221)
Version code format -- number of commits (115)
my app manifest file, I have included these two variable
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mytest"
android:versionName="1.2.0.221" android:versionCode="115">
<uses-permission android:name="android.permission.INTERNET" />
In my azure devops i referred my app manifest file and declared the version code and name like below.
Version Code Format ----- User Defined/Build Id
Version Code (must be integer) ---- $(NUMBER_OF_COMMITS)
Version Code Offset-----1
Version Name --- $(MAJOR).$(MINOR).$(SNAP).$(BUILD)
and I placed by version bumping task above to the android build task. I have defined pipeline variables.
MAJOR ----1
MINOR-----2
NUMBER_OF_COMMITS ---115
SNAP ---- 0
BUILD-----221
And In options tab, I have defined build format like
Build number format ------$(MAJOR).$(MINOR).$(SNAP).$(NUMBER_OF_COMMITS)$(Rev:r)
When i run the pipeline, Through the version bumping taking, the version code was incremented to 116 and published to the APP center with the incremented value.
But, the next time the version code is not incremented from 116 , its again from 115. so, In app center, we can see each release with same version name and version code.
How to auto increment the version code and version name, Where I am doing mistake.

NuGet Packager with version using build number, adding -beta

My goal is to deploy NuGet packages (to in-house Nuget server) that auto-increment the version based on date and last Rev, and include a -beta tag.
I am using VSTS to build and package using cake, with a build number format of $(BuildDefinitionName)_2.0.$(Date:yyMMdd)$(Rev:.r).
I have a .nuspec manifest file that specifies: $version$, and a NuGet Packager as such:
This works great. But now, I want to have the option of a NuGet packager that produces a package that is tagged as beta, and therefor show in VS NuGet Package Manager as pre-release. I can do this if I hard code the version number with "-beta" appended in the NuGet Packager:
But how can I include the -beta tag AND the the build number? I think I need to include a variable in NuGet Arguments that will return $(BuildDefinitionName)_2.0.$(Date:yyMMdd)$(Rev:.r) plus "-beta", but I'm not sure how.
I tried creating a variable (under the Variables tab) with the Build Number Format as the value, then referencing the variable in NuGet Arguments (-Version theVariable), but received as error that the variable is not supported.
I may be going about this all wrong, however my searches have not turned up any hints on how to auto-increment versions from the date, and include a -beta tag.
NuGet Packager with version using build number, adding -beta
I could reproduce your scenario on my side. In my opinion, Nuget pack task with build number doesn't support character or numbers. You may check this task:
case "byBuildNumber":
tl.debug("Getting version number from build number")
if(tl.getVariable("SYSTEM_HOSTTYPE") === "release")
{
tl.setResult(tl.TaskResult.Failed, tl.loc("Error_AutomaticallyVersionReleases"));
return;
}
let buildNumber: string = tl.getVariable("BUILD_BUILDNUMBER");
tl.debug(`Build number: ${buildNumber}`);
let versionRegex = /\d+\.\d+\.\d+(?:\.\d+)?/;
let versionMatches = buildNumber.match(versionRegex);
if (!versionMatches)
{
tl.setResult(tl.TaskResult.Failed, tl.loc("Error_NoVersionFoundInBuildNumber"));
return;
}
if (versionMatches.length > 1)
{
tl.warning(tl.loc("Warning_MoreThanOneVersionInBuildNumber"))
}
version = versionMatches[0];
break;
That is the reason why the field $(BuildDefinitionName) and beta could not appear in our package version when we use them in our build number.
If we specify the nuget version in the nuget arguments, but this argument could not parsing predefined variables, like $(Rev:.r).
The limitations of these two situations have caused your current issue.
The workaround to resolve this issue, is using nuget custom task with parameter -version $(Build.BuildNumber) and move the field $(BuildDefinitionName) from our Build number format, otherwise, we still receive the error the version is invalid.
So, you nuget custom looks like:
And the Build number format:
Now, you can see it works fine:
Note:
You said you using VSTS to build and package using cake, but the images you posted shows that you are using NuGet Packagertask in TFS 2015. If you are sure using TFS 2015, I am afraid above workaround will not work for you. Because the custom nuget task is not support for TFS 2015.
Hope this helps.

Deploying .NET Core Application with Windows Compatibility Pack

I'm busy deploying a .NET Core 2.1 application into our testing environment, but I'm getting the following error.
Error:
An assembly specified in the application dependencies manifest (MyApp.deps.json) was not found:
package: 'System.Diagnostics.EventLog', version: '4.5.0'
path: 'runtimes/win/lib/netcoreapp2.1/System.Diagnostics.EventLog.dll'
We are using the Windows Compatibility Pack to access the Event Log.
I have the following item in the dependency Json file:
"System.Diagnostics.EventLog/4.5.0": {
"dependencies": {
"Microsoft.Win32.Registry": "4.5.0",
"System.Security.Permissions": "4.5.0",
"System.Security.Principal.Windows": "4.5.0",
"System.Threading.AccessControl": "4.5.0"
},
"runtime": {
"lib/netstandard2.0/System.Diagnostics.EventLog.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.26515.6"
}
},
"runtimeTargets": {
"runtimes/win/lib/netcoreapp2.0/System.Diagnostics.EventLog.dll": {
"rid": "win",
"assetType": "runtime",
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.26515.6"
}
}
}
Please advise how one should deploy these dependencies. Also, what is the root folder to this relative path runtimes/win/lib/netcoreapp2.0?
We actually found a solution for our scenario:
- Our situation was that we tried to run a netcoreapp based test project on our test agent
- dotnet test on the project file worked
- dotnet vstest sometimes worked on the project output directory (we are not sure why and on which setup)
- dotnet vstest did run into the above error when run into an other directory & downloaded from CI
- dotnet vstest did run into an AssemblyNotFoundException on the test agent (which didn't make any sense for us)
The solution was to use dotnet publish for our test project and use the "self-contained" output to run on the test agent. dotnet publish copied the required runtimes/win/lib/netcoreappX.X/*.dll files into the publish output directory.
After a lot of testing, the key issue seems to be the "RuntimeIdentifiers". There is a visible option for this when you publish, but in order to use it when just building you need to add a couple of tags to your .csproj file.
The first is:
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
This will cause NuGet to retrieve the correct dlls (change the value depending on your needs). For me I was compiling to platform x86. I don't know what NuGet was getting by default, but whatever it was had different file sizes for the same files.
You also should then add this tag:
<SelfContained>false</SelfContained>
or else your build will default to copying the entire framework.
Also note that using the RuntimeIdentifier tag will cause your default output folder to include the value you specified. For example my subfolder became:
Project\bin\x86\Debug\netcoreapp3.1\win-86\
For publishing you should be able to do something similar; the problem will be to match your RuntimeIdentifier to your platform. You shouldn't need to specify SelfContained unless you specifically need to.

How to specify output .apk file path when using fastlane gradle?

I have different product flavors of my app and I build them with fastlane. This is my fastfile:
default_platform(:android)
platform :android do
desc "Release apk with different urls"
lane :release do
gradle(
task: "assemble",
build_type: "release",
flavor: "flavorname",
print_command: true,
properties: {
"android.injected.signing.store.file" => "Key.jks",
"android.injected.signing.store.password" => "KeyPass",
"android.injected.signing.key.alias" => "KeyAlias",
"android.injected.signing.key.password" => "KeyPass"
}
)
end
end
The problem is apk files are created in project directory.
(projectname/app/build/outputs/apk/flavorname/release/app-flavorname-release.apk)
How to move this apk files to my Desktop automatically?
I use the following under my gradle call:
lane :release do
gradle(...)
APK_LOCATION = "#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}"
sh("mv #{APK_LOCATION} ~/Desktop/")
end
The advantage of using the variable is that you will be able to use the same code for release and debug apk.
Cheers.
It doesn't seem that gradle has an option to specify the output.
What I suggest you is to add a command line just after the gradle is done to move this .apk to the Desktop or wherever you want.
sh "mv ../app/build/outputs/apk/release/app-release.apk path/to/Desktop"
You can also use fastlane action copy_artifacts instead of mv
lane :release do
gradle(...)
copy_artifacts(
artifacts: ['*/build/outputs/apk/**/*.apk'],
target_path: '~/Desktop/'
)
end
Wilcard */build/outputs/apk/**/*.apk will work with any build types, flavors app module name.
Or as said #janpio above, you can use variable GRADLE_APK_OUTPUT_PATH:
lane :release do
gradle(...)
copy_artifacts(
artifacts: [lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]],
target_path: '~/Desktop/'
)
end

Get Artifact Alias BuildNumber from TFS 2015

referenced here already: How to access an artifact's BUILDNUMBER is Visual Studio Team Services Release management
and here:
https://learn.microsoft.com/en-us/vsts/build-release/concepts/definitions/release/variables?tabs=batch
I am using vanilla Visual Studio Team Foundation Server 2015 (Version 14.102.25423.0)
In my build I zip up an artifact with the buildnumber of the artifact. eg. 20171004.16.zip
I have two artifact sources defined in my release definition.
"QA - myproject - build"
"Prod - myproject - build"
One of my steps is to copy the buildnumber.zip file to my remote server.
in my configuration setting I have defined:
ProdBuildNumber = $(Release.Artifacts.Prod - myproject - build.BuildNumber)
The issue is that ProdBuildNumber just keeps getting set as that literally.
eg: from debug script:
...
2017-10-05T19:09:48.0651172Z [SYSTEM] --> [release]
2017-10-05T19:09:48.0651172Z [PRODBUILDNUMBER] --> [$(Release.Artifacts.Prod - myproject - build.BuildNumber)]
2017-10-05T19:09:48.0651172Z [RELEASE_RELEASEID] --> [114]
...
Can anyone see what I am doing incorrectly? Willing to try any ideas.
Try
ProdBuildNumber = $(Release.Artifacts.Prod) - myproject - $(build.BuildNumber)
The [Release.Artifacts.Alias.BuildNumber] variable is not available in TFS2015. Upgrade your server to TFS2017 if you want to use it and you can also check all the supported variables from the Release/Logs/Deploy. Following are the supported variables in TFS2015:
If you cannot upgrade the server for now, you can add a powershell script task in your release definition to get the detailed artifact information via Rest API.