GAE + Github Actions + Spring(Gradle) 3개를 동시에 사용하여 CI/CD 파이프라인을 구축하는 예시를 쉽게 찾기 어려웠기 때문에 이 글을 작성하게 되었습니다.
빌드/테스트 자동화 과정
지속적인 통합이라는 뜻을 가지고 있습니다. 앱의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트 되어 공유 레포지토리에 통합되는 것을 의미합니다.
소스 코드의 빌드와 배포뿐만 아니라, 소스 코드를 검증할 수 있는 방법이 필요합니다.
요약 :
소스코드 관리→정적 코드 분석→자동 빌드→자동 테스트→CD

지속적인 서비스 제공 또는 지속적인 배포라는 뜻을 가지고 있습니다. Continuous Delivery와 Continuous Deployment 모두 CD로 축약되는데, 비슷한 의미를 가지고 있지만 약간의 뉘앙스 차이가 존재합니다.

자동으로 프로덕션 환경에 배포합니다.요약 :
CI→배포 자동화→모니터링 & 알림
이번 프로젝트에서 CI/CD를 구축할 때 git actions를 활용하여 단순한 CI/CD를 구축했습니다.
Platform: GCP App Engine
CI tool: Github Actions
Application: Spring boot(Gradle)
GCP 계정 및 프로젝트는 이미 생성되어 있다고 가정합니다.
표준 환경 선택서울(asia-northeast3) 선택gcloud components updategcloud components install app-engine-javaApp Engine Admin api 사용우선 GAE에 스프링부트 프로젝트가 배포될 수 있도록 app.yaml 및 build.gradle 파일을 구성해야 합니다. src/main/appengine/app.yaml 경로에 다음과 같은 app.yaml 파일을 추가합니다.
# app.yaml
runtime: java11
entrypoint: 'java -jar ./build/libs/yeon-0.0.1-SNAPSHOT.jar'
handlers:
- url: /.*
script: this field is required, but ignored
manual_scaling:
instances: 1
runtime : java 11 버전인 경우 java11entrypoint : 진입점 경로, jar 파일 위치. 옵션 항목이지만 이번 ci/cd 구축 시 필수 항목입니다.(생략할 경우 빌드된 jar 파일을 찾지 못합니다.)env : 앱 엔진 표준 환경 또는 가변 환경, 옵션 항목이며, 사용하지 않을 경우 표준 환경입니다.runtime_config : 런타임 세부 설정. 옵션 항목이며, 작성하지 않았습니다.handlers : 필수 항목입니다. 없으면 에러가 발생하는데, 이유는 찾지 못했습니다.manual_scaling : 오케스트레이션 관련 설정입니다. 인스턴스를 1개로 유지하도록 하였습니다.build.gradle에는 다음과 같은 코드를 추가합니다.
// build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.2.0'
}
}
...
apply plugin: 'com.google.cloud.tools.appengine'
appengine { // App Engine tasks configuration
deploy { // deploy configuration
projectId = '[PROJECT_ID]' // gcloud config set project
version = '1' // gcloud to generate a version
}
}
...
다음의 글을 참고하여 build.gradle을 수정했습니다.
Deploying a Spring Boot Gradle app to App Engine Standard Java 11
[PROJECT_ID] : GCP 프로젝트 IDGradle을 CI 서버에 깔지 않고, 프로젝트에 함께 포함시켜 배포할 수 있도록 gradle-wrapper.jar를 사용합니다.
IntellJ 환경terminal 환경gradle-wrapper.jar 위치 : root/gradle/wrapper
GAE 설정이 완료되었다면, develop 브랜치에 코드가 push되었을 때 CI가 동작하도록 github actions과 관련된 부분을 설정해야합니다.

set up a workflow yourself → 를 클릭해줍니다.
.github/workflows/main.yaml이 생성됩니다. main.yaml 파일은 아래와 같이 구성했습니다.# main.yaml
name: deploy GAE
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ develop ]
#pull_request:
# branches: [ develop ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Auth to GCP
uses: 'google-github-actions/auth@v1'
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Deploy to App Engine
uses: 'google-github-actions/deploy-appengine@v1'
with:
deliverables: build.gradle
project_id: ${{ secrets.PROJECT_ID }}
name : CI 이름 설정on : CI trigger 설정push : 어떤 branch에서 push 이벤트를 받았을 때 CI를 실행할지 적습니다.pull_request : 어떤 branch에서 PR 이벤트를 받았을 때 CI를 실행할지 적습니다.workflow_dispatch : 수동 CI 실행 관련인 듯 하나, 정확히는 확인하지 못했습니다.jobs : CI/CD 파이프라인 설정, 하위 build는 job의 이름입니다.runs-on : 실행 될 환경, ubuntu-latest 고정입니다. ubuntu-18.04는 지원 하지 않습니다.steps- 단위로 pipeline 단계 구성 할 수 있습니다.uses : 사용할 액션, git repo 형식. Marketplace에서 여러 액션을 찾을 수 있습니다.google-github-actions/auth@v1를 사용했으며,google-github-actions/deploy-appengine@v1을 사용했습니다.name : 파이프라인 단계의 이름입니다.with : 액션의 파라미터run : 특정 명령어를 실행할 수 있습니다.즉, 현재 파이프라인 구성은 다음과 같습니다.
repo checkout→gradle 권한 수정→gradle로 spring 프로젝트 빌드(gradle-wrapper 이용)→GCP에 로그인(Auth)→GAE에 빌드 된 jar 파일 배포
다음으로는 main.yaml에 써있는 secrets.GCP_SA_KEY와 secrets.PROJECT_ID를 등록해주어야 합니다.

Settings → Secrets and variables → Actions 에서 New repository secret을 눌러 추가합니다.
PROJECT_ID

PROJECT_ID는 GCP의 프로젝트 ID를 말합니다. 다음과 같이 ID를 찾을 수 있습니다.

GCP_SA_KEY

먼저 IAM 및 관리자 → 서비스 계정에 들어가, 새로운 서비스 계정을 만들어줍니다.
그 후 서비스 계정 세부 정보를 입력하고, 역할을 선택해줍니다. 추가해야 할 역할은 다음과 같습니다.
불필요한 권한이 있을 수 있습니다. 자세한 권한은 다음 링크를 확인해주세요.
https://cloud.google.com/iam/docs/understanding-roles?hl=ko#cloud-storage-roles

그 다음, 생성된 서비스 계정에 들어가 키 → 키 추가를 눌러 새로운 키를 발급 받습니다.
키 유형은 JSON으로 발급 받습니다. 발급 받은 키는 유출되지 않도록 유의해주세요.

마지막으로 발급 받은 키가 있는 위치에서 쉘을 실행시킨 후, 다음과 같이 입력합니다.
$ cat [본인의 키].json | base64
여기서 나온 base64가 GCP_SA_KEY입니다.
여기까지 완료했다면, develop 브랜치에 코드가 push 되었을 때 자동으로 app engine에 배포되는 단순한 CI/CD 파이프라인을 확인할 수 있습니다.