“It worked on my machine.” If you have been a developer for a while, you probably have heard this. It is a lament for a bug that is hard to diagnose and points to some peculiar setup of the developer’s machine. You can fix this by including continuous integration in your tool arsenal. When you check in code to your code repository, a build happens automatically with an approved build system. Unit tests are run, and artifacts – the compiled code ready to run on the device and any logs – are uploaded to an accessible location.
A typical process using AWS services might be:
- Code is stored in AWS CodeCommit or GitHub.
- Continuous integration is coordinated with AWS CodePipeline.
- Builds are done with AWS CodeBuild.
- Testing is done with AWS Device Farm.
- The results are stored in Amazon S3.
At the end of the process, Android developers can download the APK from the S3 bucket and upload it to the Google Play Store Beta.
In this post, we set up an automated build that builds your Android app from source code located in GitHub. You can then integrate this AWS CodeBuild definition into a more fully fledged continuous integration process managed by CI tools like AWS CodePipeline or Jenkins.
Set up your GitHub repository
Each project needs its own GitHub repository. AWS CodeBuild relies on a buildspec.yml file to describe the build. There can only be one buildspec.yml file in the transferred source code, which means only one buildspec.yml per repository. It’s best if you are able to run the gradlew script from the root of your repository, although this is not required.
I’m using a copy of the MyNotes application stored in the aws-mobile-android-tutorials GitHub repository. My buildspec.yml file looks like this:
version: 0.2 phases: build: commands: - ./gradlew assembleDebug artifacts: files: - app/build/outputs/apk/app-debug.apk
The artifacts are transferred to the S3 bucket at the end of the build. It’s best to get a list of the artifacts that you want by running the build locally and looking at the outputs.
Set up the initial build
Before setting up the build, you can use a standard AWS CodeBuild template to build the application. Sign in to the AWS CodeBuild console and click Create project. Fill in the form as follows:
- Configure the project:
- Project name: Enter the repository name
- Source: What to build:
- Source provider: GitHub
- Connect to GitHub with your GitHub credentials
- Repository: Use a repository in my account
- Choose a repository: Select the repository name
- Environment: How to build:
- Environment image: Specify a Docker image
- Environment type: Linux
- Custom image type: Other
- Custom image ID: futurenda/android-sdk
- Use the buildspec.yml in the source code root directory
- Artifacts: Where to put the artifacts from this build project:
- Service role:
- Either choose an existing service role from your account, or Create a role. If you choose an existing service role, check Allow AWS CodeBuild to modify this service role.
The advanced settings are not required for this build. Note that you are not storing the artifacts yet. This will be adjusted later. We’re using a standard Docker image for this build. You can search Docker Hub for suitable images or you can create your own and store it in Amazon EC2 Container Registry. If you use a standard Docker image, you may need to execute a command before running the gradlew command, such as to accept the Android SDK license or initialize the environment. We recommend that you create your own Docker image. Docker images on Docker Hub can change in unexpected ways (such as upgrading the Android SDK version or a breaking change) without warning.
When you are ready:
- Click Continue.
- Click Save and Build.
- Click Start build.
The build is submitted and should complete in a few minutes. This is a build without outputs. It confirms that the build works, but nothing else. You next configure the build to store the artifacts in an S3 bucket.
Store artifacts in Amazon S3
In this step, you create an S3 bucket and allow AWS CodeBuild to write to it. You then adjust the build to store artifacts in the S3 bucket.
- Sign in to the Amazon S3 console.
- Click Create bucket.
- Enter a unique bucket name, then click Next.
- Select any properties you want. Versioning is useful for this activity.
- Click Next, then click Next again.
- Click Create bucket.
You can store the artifacts for multiple AWS CodeBuild definitions in the same bucket, as long as the artifacts themselves have different names. This affects your buildspec.yml file and the build.gradle files that control your Android build process. Ensure that the AWS CodeBuild definition and S3 bucket are created in the same region. Now, go back to the AWS CodeBuild console and adjust the build definition to store artifacts in Amazon S3:
- Select your AWS CodeBuild project.
- Click Edit project.
- Under Artifacts: Where to put the artifacts from this build project:
- Type: Amazon S3.
- Name: repository-name
- Path: app/build/outputs/app-debug.apk
- Namespace type: None.
- Bucket name: Your S3 bucket name.
- Click Update.
You must ensure that the Path value is identical to the artifacts value in the buildspec.yml file. You can repeat the build process by clicking Start Build. Make sure that the app-debug.apk file is generated within the S3 bucket.
This is only one part of the build process for a mobile application. AWS has the tools necessary to produce an automated build process that fits your work flow. We hope this introductory article helps you develop your own continuous integration workflow for your mobile app.