Github Actions는 Github에서 제공하는 CI/CD 툴입니다. Github이 서버를 제공해주기 때문에 따로 CI/CD를 위한 서버를 구성해주지 않아도 되어 부담이 적고 간편하게 설정할 수 있다는 장점이 있습니다.
Github Repository에 특정 event가 일어났을 때 미리 정의한 Workflow들이 Github이 제공해주는 서버에서 실행됩니다. 저희는 Workflow에 어떤 event에 실행될 것인지, 어떤 동작들을 할 것인지, 어떤 결과물을 만들어낼 것인지 등을 적어주면 됩니다.
Workflow는 하나 이상의 작업을 실행시키는 자동화된 프로세스입니다. 앞에서 말했듯이 이벤트가 발생했을 때 자동으로 실행되며 그외에 수동으로 작동시킬 수도 있고 특정 시간마다 작동하게 할 수도 있습니다.
이벤트는 Workflow를 trigger하는 repository에서 일어나는 특정한 활동들을 말합니다. 예를 들면 push, pull request 등이 있습니다. 더 많은 Event는 여기를 참고해주시면 됩니다.
Job은 Workflow에서 실행하는 일련의 작업들입니다. 하나의 Job은 하나의 Runner에서 일어나며 여러개의 Step을 갖고 있습니다. 각 Step은 shell script 또는 Action이 될 수 있습니다. 각각의 Job들은 병렬적으로 실행되지만 순서대로 작동해야 하는 경우 순서관계를 정의해줄 수 있습니다.
Action은 복잡하고 반복적인 task들을 모아놓은 custom 가능한 application입니다. Input을 받고 Output을 낼 수 있는 미리 만들어놓은 Job들이라고 생각하면 됩니다. 직접 만들 수도 있고 다른 사람들이 만들어 놓은 Action을 사용할 수도 있습니다.
Runner는 Workflow를 실행하는 서버입니다. Github은 Ubuntu나 Windows 또는 macOS 운영체제를 갖고 있으며, 항상 사전에 설치된 여러 소프트웨어 이외에는 아무것도 설치되어 있지 않은 서버를 제공합니다. 어떤 소프트웨어들이 미리 설치되어 있는지 확인하고 싶다면 여기를 참고하면 됩니다.
Github Actions는 Workflow를 정의하기 위해 yml 문법을 사용합니다. Github Actions를 사용하려면 ci.yml과 같이 Workflow설정 파일을 만들고 .github/workflows 디렉토리를 만들어 저장하면 됩니다.
name: 'CI'
on:
push:
branches:
- 'main'
- 'develop'
pull_request:
branches:
- 'main'
- 'develop'
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: 11
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build
cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }}
- name: Upload Jacoco Report
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: jacoco-report
path: build/reports/jacoco/test/html
name: 'CI' # workflow의 이름
on: # event를 정의 하는 곳
push:
branches:
- 'main' # main에 push할 때
- 'develop' # develop에 push할 때
pull_request:
branches:
- 'main'
- 'develop'
jobs: # job들을 정의하는 곳
ci: # job의 id
runs-on: ubuntu-latest # 이 job을 수행하는 OS ex. windows-latest , macos-12
사용 가능한 OS들의 목록과 label은 여기를 확인하시면 됩니다.
steps: # job에서 수행하는 step들을 정의하는 곳
- uses: actions/checkout@v3 # Repository로부터 CI 수행 서버로 코드를 내려받는 Action
- name: Set up JDK 11 # step의 이름
uses: actions/setup-java@v3 # jdk를 다운 받고 캐싱해주는 Action
with: # Action에 전달하는 input을 정의하는 곳
java-version: 11
distribution: 'temurin' # jdk를 제공하는 vender사 이름 ex. zulu, adopt, microsoft
Action을 실행할 때는 uses 키워드를 사용하며 {소유자}/{저장소명}@{참조자}의 형태로 사용할 수 있습니다. 참조자는 보통 Action의 버전을 구분하기 위해 사용되며 위의 예시에서 v3 참조자는 Action의 버전 태그를 의미합니다. 참조자에는 Action의 version과 관련된 SHA 값이나 branch를 적어줄 수도 있습니다. 자세한 내용은 여기를 확인하시면 됩니다.
설정한 java -version과 vender사에 맞는 jdk를 다운받아줍니다. 또 Github 캐시에 캐싱하여 이후에는 더 빠르게 다운받을 수 있도록 해줍니다. 더 많은 벤더사는 여기서 확인할 수 있습니다.
Github은 Job을 매 번 새로운 서버에서 실행합니다. 따라서 매 Job마다 서버에 프로젝트에서 의존하는 라이브러리들을 새로 받아주어야 합니다. 이는 매우 비효율적이기 때문에 바뀌지 않는 라이브러리들은 Github에서 제공하는 cache에 보관하고 재사용하는 것이 CI 성능에 좋습니다.
actions/cache Action을 이용하면 캐싱할 수 있습니다.
Gradle을 이용하는 Java 프로젝트는 다음과 같이 캐싱할 수 있습니다.
- uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
key : Linux-gradle-3572877ee653b1cd606c473692133d05
gradle/gradle-build-action 이 Action은 gradle에서 제공하는 Action으로 Gradle을 사용해서 build하는데 도움을 주는 Action입니다. 이 Action은 build 이외에도 위에서 설명한 actions/cache를 이용하여 더 효율적이고 정교한 캐싱을 제공합니다. 따라서 저는 actions/cache를 직접 사용하지 않고 이 Action을 이용하였습니다.
- name: Grant execute permission for gradlew
run: chmod +x gradlew # gradlew를 실행할 수 있는 권한을 추가(리눅스의 명령어)
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build
cache-read-only: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }}
./gradlew build
어떤 key를 사용하여 어떤 파일들이 캐시되거나 복구되었는지는 Actions 탭에 Summary에서 확인하실 수 있습니다.
- name: Upload Jacoco Report
if: ${{ failure() }}
uses: actions/upload-artifact@v3
with:
name: jacoco-report # 결과물의 이름
path: build/reports/jacoco/test/html # upload하고자 하는 파일 또는 디렉토리 경로
Workflow에서 나온 결과물을 저장하거나 다른 job들과 공유하고 싶을 때 사용하는 Action입니다.
위 Action과 input을 사용하면 jacoco-report라는 이름으로 build/repots/jacoco/test/html을 저장합니다. 저장된 결과물은 마찬가지로 Actions 탭에 Summary에서 확인하실 수 있습니다.
사실 이 부분은 이미 Github Actions에서 제공하고 있습니다. Settings에 Notifications 탭에 들어가보면 기본적으로 workflow가 실패하는 경우에 Email로 알림이 오도록 자동으로 설정되어 있는 것을 확인할 수 있습니다. workflow가 실패하는 경우 Web에 체크하면 Github 알림으로도 알림을 받을 수 있습니다.
알림은 다음과 같이 옵니다.