Cannot build specific AndroidVariant on GitHub Actions

I’m facing issues when running a SonarQube scan for a specific Android variant (envSandboxDebug ) in a multi-module Android project. The entire AndroidVariants in the project is built before the scan, significantly increasing build time.

app
├── build.gradle
feature
├── feature-1
│   └── build.gradle
├── feature-2
│   └── build.gradle
data
├── data-module-1
│   └── build.gradle
├── data-module-2
│   └── build.gradle
build.gradle (root)

My App structure roughly look like this

I’m using Gradle for build management and have configured the SonarQube Gradle plugin to target the desired variant:

The sonar config block is put inside root build.gradle file hoping to scan all the modules inside my project

root build.gralde
plugins {
    alias libs.plugins.sonarqube// version: "5.0.0.4638"
}
sonar {
    properties {
        androidVariant 'envSandboxDebug'
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://project_url.com"
    }
}

When I try to run the sonar scan via GitHub Actions, each AndroidVariant is built and takes hours to complete.

   ......
   ........
      # Install and configure Java 17 on the runner machine
      - name: Set up JDK 17
        uses: actions/setup-java@v2
        with:
          java-version: '17'
          distribution: 'adopt'

      # Cache SonarQube packages to speed up the build process
      - name: Cache SonarQube packages
        uses: actions/cache@v1
        with:
          path: ~/.sonar/cache
          key: ${{ runner.os }}-sonar
          restore-keys: ${{ runner.os }}-sonar

      # Cache Gradle packages to speed up the build process
      - name: Cache Gradle packages
        uses: actions/cache@v1
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
          restore-keys: ${{ runner.os }}-gradle

      # Download and unzip SonarQube scanner
      - name: Sonar-scanning
        run: sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-macosx.zip && sudo unzip sonar-scanner-cli-4.7.0.2747-macosx.zip -d /opt/

      # Run SonarQube analysis
      - run: |-
          ./gradlew buildEnvSandboxDebug sonar -Dsonar.host.url=https://host-url.com \
          -Dsonar.projectKey=project_key \
          -Dsonar.projectName=project_name \

How do we solve this issue?

1 Like

Hey there!

That’s weird. I swore we decoupled compiling/scanning and made that the default behavior in v5.0 of the gradle scanner.

  • Is there some [task dependency]) SonarScanner for Gradle) added in your config somewhere?
  • If you separate ./gradlew buildEnvSandboxDebug and ./gradlew sonar to different invocations. Does the behavior change?

I haven’t defined any task dependency.
Please find below the different combinations I have tried out until now

Combination 1:

In root build.gradle

plugins {
    alias libs.plugins.sonarqube //"5.0.0.4638"
}

sonar {
    properties {
        androidVariant 'envSandboxDebug'
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://host_url.com"
    }
}

In sonar-scan.yaml

      # Download and unzip SonarQube scanner
      - name: Sonar-scanning
        run: sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-macosx.zip && sudo unzip sonar-scanner-cli-4.7.0.2747-macosx.zip -d /opt/

      # Run SonarQube analysis
      - run: |-
          ./gradlew build sonar -Dsonar.host.url=https://host_url.com \
          -Dsonar.projectKey=project_key \
          -Dsonar.projectName=project_key \

Result →

The Sonar scan fails to pick up the androidVariant from the properties block. All the Android variants are attempted to be built before the scanning step, which took several hours and eventually resulted in an OutOfMemory error.

Combination 2:

In root build.gradle

plugins {
    alias libs.plugins.sonarqube
}

sonar {
    properties {
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://host_url.com"
    }
}

In sonar-scan.yaml

      # Run SonarQube analysis
      - run: |-
          ./gradlew buildEnvSandboxDebug sonar -Dsonar.host.url=https://host_url.com \
          -Dsonar.projectKey=project_key \
          -Dsonar.projectName=project_name \

Result:
The build variant is specified explicitly in the sonar scan step.
Execution failed for task ‘:sonar’.

Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.

Combination 3:

In root build.gradle

plugins {
    alias libs.plugins.sonarqube
}

sonar {
    properties {
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://host_url.com"
    }
}

in sonar-scan.yaml, ignore the build step.

      # Run SonarQube analysis
      - run: |-
          ./gradlew sonar -Dsonar.host.url=https://host_url.com \
          -Dsonar.projectKey=project_key \
          -Dsonar.projectName=project_name \

Result:
Execution failed for task ‘:sonar’.
You can use ‘–warning-mode all’ to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.
For more on this, please refer to Command-Line Interface in the Gradle documentation.

Combination 4:

In root build.gradle

plugins {
    alias libs.plugins.sonarqube
}

sonar {
    properties {
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://host_url.com"
    }
}

in sonar-scan.yaml, ignore the build step.

 in sonar-scan.yaml, use 'assemble'
    # Run SonarQube analysis
      - run: |-
          ./gradlew assemble sonar -Dsonar.host.url=https://sonar-internal.yougotagift.co \
          -Dsonar.projectKey=project_key \
          -Dsonar.projectName=project_name \

Result:
Execution failed for task ‘:sonar’.

Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.

Combination 5:

In root build.gradle

plugins {
    alias libs.plugins.sonarqube
}

sonar {
    properties {
        property "sonar.projectKey", "project_key"
        property "sonar.projectName", "project_name"
        property "sonar.host.url", "https://host_url.com"
    }
}

in sonar-scan.yaml

 # Download and unzip SonarQube scanner
 - name: Sonar-scanning
   run: sudo wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-macosx.zip && sudo unzip sonar-scanner-cli-4.7.0.2747-macosx.zip -d /opt/

 - name: Gradle build
   run: ./gradlew buildEnvSandboxDebug
 
 # Run SonarQube analysis
 - run: |-
     ./gradlew sonar -Dsonar.host.url=https://host_url.com \
     -Dsonar.projectKey=project_key \
     -Dsonar.projectName=project_name \

Result:
Execution failed for task ‘:sonar’.

Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property.

1 Like

I was Just wondering if you had a chance to look at the configuration files I just posted!

Not yet! But I’ve flagged an expert to have a look. Thanks for your patience.

1 Like

Hi Colin! I am eager to hear your team’s thoughts on this!

Any updates there?

I will follow-up.

Any hope?

Hello @Gopikrishnan_S,

Sorry for such a late reply.

Have you checked setting androidVariant property (docs) like here:

sonar {
    androidVariant 'buildEnvSandboxDebug'
}

By default, sonar will try to analyze all of them. And we have a requirement that you should first build before analyzing. So, if you run build sonar, you build everything and analyze everything, if you run buildEnvSandboxDebug sonar, you only build one variant but analyze everything. So for the modules that weren’t built, you will get such error:

Your project contains .java files. Please provide compiled classes with the sonar.java.binaries property or exclude them from the analysis with the sonar.exclusions property.

So you have to build the variant you need and specify it in the sonar task.

Let me know if that works for you, or share the logs if it doesn’t.

Another idea is to skip the modules you don’t want to analyze or exclude file patterns, if possible, depending on how your variants are configured.

Best,
Margarita

Where would you suggest keeping

sonar {
    androidVariant 'buildEnvSandboxDebug'
}

in a multi-module android project?
In the root build.gradle or app.build.gradle?

I am encountering this error while specifying the variant inside the sonar block as you suggested

Your project contains .java files. Please provide compiled classes with the sonar.java.binaries property or exclude them from the analysis with the sonar.exclusions property.