0

I am not able to get any field that can fetch the App version name in configuring bitbucket pipelines.

Tried Following Approaches: Defining the value in Repository variables but it causes manual efforts in updating the version every time.

setting variable in project level build.gradle and accessing in pipeline - does not work

project.ext.set("my_lib_version", "2.1.0")

// in pipeline

script:
          - echo $my_lib_version
Anchit Mittal
  • 3,412
  • 4
  • 28
  • 48

2 Answers2

1

If the versionName is hard-coded in your app/build.gradle file, then you can extract the string using bash/shell commands like awk and perl, which are available on Linux Docker machines:

1. app/build.gradle contains a hard-coded versionName:

android {
    defaultConfig {
        ...
        versionName "2.1.0"
        ...
    }
}

In the yml file, extract the versionName string from app/build.gradle using awk or perl:

script:
 - export APP_VERSION_NAME=$(awk '/versionName .*"/{gsub(/\"/,"",$2);print $2}' "app/build.gradle")
 - echo "APP_VERSION_NAME = $APP_VERSION_NAME" # This prints: 2.1.0

 - export APP_VERSION_NAME2=$(perl -nle 'print $& while m{(?<=versionName ").*?(?=")}g' "app/build.gradle")
 - echo "APP_VERSION_NAME2 = $APP_VERSION_NAME2" # This prints: 2.1.0

If the versionName is auto-generated using an environment variable or other string templates, then you must build the code first, and then extract the string from the automatically-generated BuildConfig.java file:

2. app/build.gradle contains string templates:

project.ext.my_lib_version = "2.1.0"

android {
    defaultConfig {
        ...
        versionName "${project.ext.my_lib_version}-debug"
        ...
    }
}

After building the code, the auto-generated BuildConfig.java file will contain the real string:

public final class BuildConfig {
  ...
  public static final String VERSION_NAME = "2.1.0-debug";
  ...
}

In the yml file, extract the versionName string from BuildConfig.java using awk or perl:

script:
 # Build the Android app
 - ./gradlew assembleDebug

 # There may be multiple 'BuildConfig.java' files. Get the path of the
 # the first 'BuildConfig.java' file which is closest to the root folder
 - BUILD_CONFIG_FILE_PATH=$(find "$(pwd -P)" -name BuildConfig.java | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2- | head -1)
 - echo "BUILD_CONFIG_FILE_PATH = $BUILD_CONFIG_FILE_PATH"

 - export APP_VERSION_NAME=$(awk '/VERSION_NAME/{gsub(/\"/,"",$7) ; gsub(/;/,"",$7) ; print $7}' $BUILD_CONFIG_FILE_PATH)
 - echo "APP_VERSION_NAME = $APP_VERSION_NAME" # This prints: 2.1.0-debug

 - export APP_VERSION_NAME2=$(perl -nle 'print $& while m{(?<=VERSION_NAME = ").*?(?=")}g' $BUILD_CONFIG_FILE_PATH)
 - echo "APP_VERSION_NAME2 = $APP_VERSION_NAME2" # This prints: 2.1.0-debug

3. More info and references about these commands and how they work:

Mr-IDE
  • 7,051
  • 1
  • 53
  • 59
0

Defining the value in Repository variables but it causes manual efforts in updating the version every time.

Sure, albeit this might technically work, it does not practically.

Sometimes setting the variable via the REST Api can do the trick.


setting variable in project level build.gradle and accessing in pipeline - does not work

project.ext.set("my_lib_version", "2.1.0")

Yes, it does not work. The reason is that the build manager (gradle?) can only set an environment variable for the current build - not for the parenting pipeline script.

Instead you need to write into into some file and then export the file as a pipeline artifact.

Afterwards you set the scripts environment variable from the files content. This has been covered in the existing Q&A material Make variable visible across steps in Bitbucket pipelines?


If the value already exists in a file within the repository (or within git, e.g. a tag or a commit message), the same principle as reading from file applies, but just using command substitution. Also as the value is already part of the repository, no artifact is necessary.


Personally I prefer workflows where the revision related information comes out of the repository revision itself, so that the build is reproducible or at least stable (the build environment does not easily change the outcome). E.g. release by creating and pushing a git tag, pipeline variables then have the value as $BITBUCKET_TAG.

The typical example is to use the version number as tag name, e.g. 2.1.0 in your case. The releasing developer then can sign and push the tag, the pipeline that handles the tag is required to have a green build for the revision that has been tagged already. It then only needs to publish the revisions' artifact.

For more information on working with tags in git, see the git-tag(1) manpage.

hakre
  • 193,403
  • 52
  • 435
  • 836