loading...
Cover image for How do I setup GitHub Actions for my Gradle or Android project?

How do I setup GitHub Actions for my Gradle or Android project?

jmfayard profile image Jean-Michel Fayard πŸ‡«πŸ‡·πŸ‡©πŸ‡ͺπŸ‡¬πŸ‡§πŸ‡ͺπŸ‡ΈπŸ‡¨πŸ‡΄ ・5 min read

Hello Human!

This tutorial is for you if

  • βœ… you have an Android or Kotlin or Java project built with Gradle
  • βœ… you write unit tests
  • ❌ you have no Continuous Integration system setup to run your tests on the server

Having the guarantee that your unit tests run on the build server is a keystone to establish a culture of testing withing your team - either at work or in an open-source project.

Perhaps you know that already, and have been told that you could setup Jenkins or Travis or CircleCi. But you don't even know which one to choose, let alone how to configure them.

My goal is to convince you that you can start today setting up a pipeline with GitHub Actions and Gradle.

My Workflow

  • Open your Android or Gradle project
  • Create a file called exactly .github/workflows/runOnGitHub.yml with this content
  • Commit and create a pull request

After a short while, you should see this:

image

The GitHub Action is failing.

That's progress: before it was not even running!

The next step is to follow the link "Details" to see what is going on.

Define the task ./gradlew runOnGitHub

Here is the error you will found in Details

Welcome to Gradle 6.6.1!

FAILURE: Build failed with an exception.

* What went wrong:
Task 'runOnGitHub' not found in root project '$YOUR_PROJECT'.

BUILD FAILED in 1m 31s

That makes a ton of sense, we didn't define the Gradle task runOnGitHub yet.

Next:

  • Open the root build.gradle.kts or build.gradle file
  • Register a Gradle task called runOnGitHub like this:
tasks.register("runOnGitHub") { // 1
    dependsOn(":app:lint", ":app:testDebugUnitTest")  // 2 ==> CUSTOMIZE THIS LINE
    group = "custom"      // 3
    description = "$ ./gradlew runOnGitHub # runs on GitHub Action" //3
}

There are three steps

  1. you register a new task called runOnGitHub
  2. you define via dependsOn() which tasks should be executed before runOnGitHub. In this example we run the linter and the unit tests in the app module. This is the crucial step that will depend from project to project. So be sure to customize it for your needs.
  3. you document what will appear when you run ./gradlew tasks

Push to GitHub and make the Action pass

Once you have defined the task:

  • Run locally the task ./gradlew runOnGitHub and check it does what you want.
  • Tip: Save time by running ./gradlew --dry-run runOnGitHub to see quickly what tasks would be executed without actually running them.
  • Push to GitHub
  • Open the Actions tab on GitHub and if you are lucky you will see this after a while:

image

  • Celebrate

https://media.giphy.com/media/duLHlK018ete6OsgaL/giphy.gif

Submission Category:

Maintainer Must-Haves

Additional Resources / Info

To know more about creating your own Gradle tasks, follow the gentle tutorial at https://guides.gradle.org/writing-gradle-tasks/

Read the docs about GitHub Actions

GitHub Actions Documentation

Read the docs about the Gradle Command Action

GitHub logo eskatos / gradle-command-action

Execute Gradle Command Github Action

Execute Gradle commands in GitHub Actions workflows

This GitHub Action can be used to run arbitrary Gradle commands on any platform supported by GitHub Actions.

You might also be interested by the related Gradle Plugin that allows your build to easily get GitHub Actions environment and tag Gradle Build Scans accordingly.

Usage

The following workflow will run ./gradlew build using the wrapper from the repository on ubuntu, macos and windows. The only prerequisite is to have Java installed, you can define the version you need to run the build using the actions/setup-java action.

# .github/workflows/gradle-build-pr.yml
name: Run Gradle on PRs
on: pull_request
jobs
  gradle
    strategy
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-java@v1
      with:
        java-version: 11
    - uses: eskatos/gradle-command-action@v1
      with:
        arguments: build

Gradle arguments

The arguments…

Personal Story

Using GitHub Action to publish libraries

I have used GitHub Actions in the past for more complex workflows to publish libraries.

If you are interested, have a look here:

https://github.com/jmfayard/refreshVersions/tree/master/.github/workflows

https://github.com/LouisCAD/Splitties/tree/main/.github/workflows

But instead of talking about those complex ad hoc workflows, I thought it would be more interesting to help all Gradle and Android projects to make the first step to have continuous integration with GitHub Action and Gradle.

Yaml File or Link to Code

The nice thing about my workflow is that it's pretty generic.

I submitted my workflow in two Pull Requests, one for a friend's project and the other for the Android app of DEV.to

πŸ— Setup a GitHub Action using Gradle to run the unit tests #2 #100

What type of PR is this? (check all applicable)

  • [ ] Refactor
  • [x] Feature
  • [ ] Bug Fix
  • [ ] Documentation Update

Description

A GitHub Action for Gradle that runs the unit test of this Android project

Related Tickets & Documents

GitHub Actions hackaton on DEV

https://dev.to/devteam/announcing-the-github-actions-hackathon-on-dev-3ljn

Screenshots/Recordings (if there are UI changes)

See https://github.com/jmfayard/DEV-Android/actions?query=workflow%3A%22Android+unit+tests%22

I added the build scan plugin for better reporting if there are tests failure

https://scans.gradle.com/s/2tzis4ikslecg/tests

Build_scan_for__DEV-Android__just_now___Gradle_Cloud_Services_and_DEV-Android____StudioProjects_DEV-Android__-_____app_src_test_java_to_dev_dev_android_view_main_view_MainActivityTest_kt__app_

[optional] What gif best describes this PR or how it makes you feel?

alt_text

πŸ— GitHub Action with ./gradlew runOnGitHub #12

If merged, a GitHub Action will be installed that runs ./gradlew runOnGitHub on each pull request

If you look at the pull-request, one thing I have done is to setup the Gradle build-scan for better reporting when tests are failing. I wrote abouit here already:

Is your Testing Pyramid Inverted?

A problem I encountered in the DEV-Android app is that it had very few unit tests

Something to keep in mind if you have an Android project is that my workflow allows you to run the unit tests on GitHub, but not the integration tests / automated GUI tests also called Android instrumentation tests.

There are good reasons for that.

Unit tests are fast, easier to write and lead faster to the discovery and fix of the bug when they fail.

This is why the recommended strategy is to have a testing pyramid where the emphasis is put on writing a lot of fast simple unit tests:

pyramid-ok

Unfortunately there is a common anti-pattern in the Android world where not enough emphasis is put on the unit tests. The testing pyramid looks like this and won't probably last as long as the ones in Egypt:

pyramid-ko

To understand why it's an anti-pattern, read the Google Testing blog:

Just Say No to More End-to-End Tests

Now if you want to start putting more emphasis on writing more unit tests, having this infrastructure in place with GitHub Action is a nice first step.

YAML is a terrible programming language

My biggest frustration by far was due to those YAML "configuration files".

I use quotes here because I think that "configuration file" here is a lie.

Look, we want to make a computer do stuff that are not trivial.

What we are doing is writing a programming script.

What happens here is that someone at GitHub just made up a terrible programming language disguised as YAML. There are hundred things that can go wrong, the IDE won't help you a bit, and it's a mmajor time waster.

The better alternative is to use an actual programming language.

Not Bash.

Just imagine how simpler it would be if the IDE could help you exactly as well as it helps you when you write your code.

Well you don't have to imagine because configuration as code is a thing in alternatives to GitHub Action for example in TeamCity from JetBrains

teamcity

I hope GitHub will provide us something like this.

Feedback?

I hope you will try setting up your first CI with GitHub Action + Gradle.

Copy the file .github/workflows/runOnGitHub.yml, define your Gradle task runOnGitHub and create your pull request.

Please leave a comment if that works for you. I usually only hear from what went wrong :)

Discussion

markdown guide