Deploy a Java app to Google Cloud App Engine auto by create git tag using GitHub Action
First, we need to create a Java base web application. We create a new application by using Quarkus.
How to install quarkus command
quarkus create app medium-demo-app
-----------
applying codestarts...
📚 java
🔨 maven
📦 quarkus
📝 config-properties
🔧 dockerfiles
🔧 maven-wrapper
🚀 resteasy-reactive-codestart
-----------
[SUCCESS] ✅ quarkus project has been successfully generated in:
--> /medium-demo-app
-----------
Next, open the medium-demo-app project, add a new class named “TopResource” and add the following code.
package org.acme;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/")
public class TopResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello, this is a demo website for medium story.";
}
}
And then, add the following code to application.properties file.
quarkus.package.type=uber-jar
Now, compile and access the page.
quarkus dev
After compile finished, open a browser and access http://localhost:8080 , then we should see the page just look like bellow.
Next, create a new GCP project, and create app engine application.
Next, enable the App Engine Admin API and IAM API.
Next, create a service account to deploy application. Go to the Service Accounts Page, and create a new service account.
Then add roles to the account.
The following role are needed.
- App Engine Admin
- Service Account User
- Storage Admin
- Cloud Build Editor
After create the service account, click the account’s email, select key tab to create a new key. Select the key type to JSON. Then it will download a JSON file.
Next, go to GitHub to create a new repository. And add the Quarkus app we created before to the repository and push to the remote.
After that, we need to create a new folder under project root named “.github/workflows”, then create new file named “google-deploy-app-engine-source.yml”.
In the yml file, we want to deploy after a tag is created, so we add the code below first. This means after we push a new tag to the remote which tag name like “v1.0.0” or any other tag name start with a “v”, it will run the jobs.
name: Deploy to App Engine from Source
on:
push:
tags:
- 'v*'
Next, we will define the jobs. First, we need to authorized the deploy account’s information. Create a new repository secret value named “GCP_SA_KEY”, and put the contents of the JSON file we download before into the secret, then add the code bellow to the yaml file.
jobs:
job_id:
permissions:
contents: 'read'
id-token: 'write'
runs-on: ubuntu-latest
steps:
- uses: 'actions/checkout@v3'
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v1'
with:
credentials_json: '${{ secrets.GCP_SA_KEY }}'
Because we will use gcloud command to deploy, so we need to setup gcloud command next.
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
Then build the Java application.
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build App
run: mvn clean package
And at last, deploy the app to the App Engine.
- name: Deploy to App Engine
id: deploy
run: gcloud app deploy ${{ github.workspace }}/target/medium-demo-app-1.0.0-SNAPSHOT-runner.jar
The whole yaml file is below.
name: Deploy to App Engine from Source
on:
push:
tags:
- 'v*'
jobs:
job_id:
permissions:
contents: 'read'
id-token: 'write'
runs-on: ubuntu-latest
steps:
- uses: 'actions/checkout@v3'
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v1'
with:
credentials_json: '${{ secrets.GCP_SA_KEY }}'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build App
run: mvn clean package
- name: Deploy to App Engine
id: deploy
run: gcloud app deploy ${{ github.workspace }}/target/medium-demo-app-1.0.0-SNAPSHOT-runner.jar
At last, create a new release tag on github to see the weather the GitHub action is working correct or not.