A great butler can help you deal with lots of mundane tasks so that you have more time to do what you love and save the world.
So inspired by Batman’s Alfred, I found Jenkins. My goal of getting a butler is simple, to have a computer somewhere running unit tests for my app every time I push changes and report the results to me somehow (like via email).
Background (you may skip this ramble part)
Finding time to work on your side project app is one hurdle. Coping with platform updates is another big one. So I thought I needed help. I needed to up my game and speed up my development process. Then, I heard of CI/CD, Jenkins, DevOps, the idea of having your release process automated with some help from a tool like Jenkins. Finding out what they are wasn’t difficult. But getting one to work for my projects took me much longer than I expected. There are lots of great articles and tutorials out there, but I believe everyone’s journey is different. So I thought it would still be helpful anyway to share my story with others who are thinking about getting a butler to work for them.
Let’s get started
Table of Contents
- Creating an AWS ec2 server for Jenkins
- Installing tools: Git, Unzip, and android-sdk
- Configuring Jenkins
- set up Environment variables for android-sdk
- set up email notification to my gmail account
- Generate SSH Key from Jenkins to connect with GitHub
- Create the first Jenkins item
- A few more setups
- Test building a Jenkins item
- Set up a GitHub webhook to trigger Jenkins to build when a change is pushed
1. Creating an AWS ec2 server for Jenkins
There are a few steps here but this AWS doc is fairly straight forward. Here are some notes on how I did it
- I chose
Amazon Linux 2 AMI
as my choice of AMI
- When I ran
sudo service jenkins start
I got an error saying Java JRE is missing
- So I ran
sudo yum -y install java-1.8.0
to install Java JRE
- Running
sudo service jenkins start
again should be fine
In ec2 shell
- git:
sudo yum install git
- unzip:
sudo yum install unzip
- android-sdk
- Grab an android-sdk zip-file download link from here select a download link from under Command line tools only section (This is the one I grabbed https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip)
- Go to
/var/lib/jenkins
as we want to save the sdk here
- Download sdk:
sudo wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
- Create a folder:
sudo mkdir android-sdk
- Unzip the sdk into the folder:
sudo unzip sdk-tools-linux-4333796.zip -d android-sdk
- Accept android-sdk licenses:
yes |sudo android-sdk/tools/bin/sdkmanager --licenses
In Jenkins home page, go to Manage Jenkins > Configure System
- Section: Global properties, set up Environment variables for android-sdk
- Tick Environment variables and click add
- Name :
ANDROID_HOME
- Value :
/var/lib/jenkins/android-sdk
- Section: Jenkins Location
- System Admin e-mail address : your email address
- Section E-mail Notification, set up email notification to your gmail account
- Click on Advanced… to see all configs
- SMTP server :
smtp.gmail.com
- Tick on Use SMTP Authentication
- User Name : Your Gmail email address
- Password : Here is a little tricky, your Gmail password won’t do, you need to set up a dedicated App passwords for this Jenkins server in your Google Account
- Go to https://myaccount.google.com/apppasswords
- Select app : mail
- Select device : other, name it anything you want (I named it
Jenkins
)
- Then click
generate
and put the generated password into the Password box
- Test the connection
- Tick Test configuration by sending test e-mail
- Fill in Test e-mail recipient with your Gmail
- Click
Test configuration
, then check your inbox
4. Generate SSH Key from Jenkins to connect with GitHub
In ec2 shell, go to var/lib/jenkins
- Logging into jenkins shell
sudo su -s /bin/bash jenkins
- Generate dsa key pair:
ssh-keygen -t dsa
, generated key will be saved in .ssh
- Go to
.ssh
- Do
cat id_dsa.pub
to see the content of the key and copy everything.
- Go to your GitHub account and create a SSH key (https://github.com/settings/ssh/new)
5. Create your first Jenkins item
In Jenkins home page, go to New Item
- Give an item some name
- Choose Freestyle project, then click ok
- In Source Code Management, select Git
- Repository URL : an ssh link to a GitHub project (the same link you use to clone a project with
git clone <link>
)
- Copy the warning git command e.g.
git ls-remote -h git@github.com:landtanin/habit-tracking.git HEAD
- Go back to jenkins shell
- Paste the git command and run it in jenkins shell
- Re-paste your ssh link in Repository URL to make it update and make the error go away
- Set Branches to build to
**
if you want it to be triggered by pushes from any branch
- Ignore Build Triggers and Build Environment for now
- In Build section, add Invoke Gradle script
- select Use Gradle Wrapper
- tasks : This can be any Gradle task (e.g.
tasks
, build
, clean
)
- I tried
tasks
first to only test the build environment (leave your GitHub project untouched)
- in Post-build Actions, add E-mail Notification to get notified whenever a build fails
- Put in your Gmail address
6. A few more setups
Before actually running your first Jenkins item, there three more things we need to do (If you don’t, you’ll be prompted with loads of ambiguous errors which I have gone through, you’re welcome.)
- In Jenkins shell, create a file:
var/lib/jenkins/.android/repositories.cfg
exit
from jenkins shell back to ec2 shell, make android-sdk
in var/lib/jenkins
folder writeable: sudo chmod 777 android-sdk
- Install JDK to be able to build a Java project (your android app)
sudo yum install java-1.8.0-openjdk-devel
7. Test building a Jenkins item
Here comes the exciting part. In Jenkins home page
- Click on your item name to go into its own page
- Click Build Now on the left pane
- A new history item will pop up in the Build History pane on the lower left pane
- You can see a console output by clicking on the history item
- Then, click on Console Output on the left pane
If we have done it right, it shall passes.
- Then, try changing the Gradle task to something like
test
to run unit tests of your app
8. Set up a GitHub webhook to trigger Jenkins to build when a change is pushed
-
Grab a webhook url of your ec2
- In Jenkins home page, go to Configure System
- go to GitHub section
- click on
?
after the GitHub Servers option to see the github webhook url
- the url will look like
http://ec2..../github-webhook/
-
Configure a GitHub project
- On your GitHub repo, go to Settings tab
- Select Add webhook
- Paste the webhook url in Payload URL (make sure to include the last
/
)
- Select application/json in Content type
- Leave Secret blank (unless a secret has been created and configured in the Jenkins Configure System -> GitHub plugin section)
- Select Let me select individual events and enable
- Pushes event
- Pull requests event
- Scroll to bottom, make sure Active is checked
- Click Add webhook
-
Configure Build Triggers of the Jenkins task
- Go to the created Jenkins task
- Select
GitHub hook trigger for GITScm polling
That’s it for now. If you have done everything right, the task will be triggered to run all unit tests of your app every time you push or make a pull request.
Next Step
- You can play around with different the Gradle build tasks (more about Gradle task) to build the project, run UI Tests, and so on.
- The Post-build Actions settings in the Jenkins task can be set to automatically build an .apk file and upload it the your choice of cloud storage (see this article.)
Thanks for reading and happy coding 🎉
Refs