Github Action
Github 저장소를 기반으로 소프트웨어 개발 workflow를 자동화 할 수 있는 도구
장점
- 별도의 서버 설치가 필요 없다.
- 비동기 ci/cd가 가능하다.
- github 이벤트에 대한 작업을 제공해준다.
- yaml로 사용하기 때문에 개발자들에게 친숙하다.
- github 마켓 플레이스를 통해 공유 가능
단점
- 캐싱이 필요할 경우 자체 캐싱 메커니즘을 작성해야 함 (엔터프라이즈에선 actions/cache를 지원하지 않는다고 한다. 참고)
- 젠킨스에 비해 문서가 적다. (아무래도 출시 일자가 차이가 나기 때문인듯)
구성요소
workflow
- 프로젝트를 빌드, 테스트, 패키지, 릴리스 또는 배포하기 위한 전체적인 프로세스
- 여러개의 job으로 구성되며 디폴트로 병렬 실행한다.
- event 기반으로 동작한다.
- .github/workflows 폴더 아래에 yaml 파일로 저장된다.
event
- workflow를 실행하는 특정 활동이나 규칙
job
- 여러 step으로 구성되며, 가상 환경의 인스턴스에서 실행된다.
- 다른 job에 의존 관계를 가질 수 있고, 독립적으로 병렬 실행도 가능하다.
step
- 순차적으로 명령어를 수행한다.
- task들의 집합으로 커맨드를 날리거나 action을 실행할 수 있다.
action
- workflow의 가장 작은 블럭
- job을 만들기 위해 step들을 연결할 수 있다.
- 참고
Runner
- Github Action Runner 어플리케이션이 설치된 머신으로, workflow가 실행될 인스턴스
- github-hosted runner와 self-hosted runner가 있다.
- github-hosted runner는 Azure의 Standard_DS2_v2로 vCPU 2, 메모리 7GB, 임시 스토리지 14GB
전체코드
name: Java CI with Gradle
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Cache with Gradle
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew build
- name: Test with Gradle
run: ./gradlew test
간단하게 gradle로 java 코드를 build하는 코드를 작성해보자.
이벤트 정의
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow을 실행할 이벤트를 정의할 수 있다.
특정 브랜치에 push or pull request가 발생하였을때 workflow를 실행하게 된다.
여러 브랜치에 설정하는 것도 가능하고 "**" 키워드와 같이 모든 브랜치에 설정하는 방법도 있다.
job과 실행 환경 정의
jobs:
build:
runs-on: ubuntu-latest
수행해야 할 job 들을 설정한다. ci를 위한 job이므로 build 라는 이름을 가진 job을 생성했다.
runs-on을 통해 github action을 수행할 runnner의 os를 설정해준다. ubuntu, mac, window등 다양한 os를 지원한다.
checkout, jdk 설정
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
job은 여러 개의 step들로 이루어져 있다.
uses를 통해 이미 정의되어 있는 action들을 사용할 수 있다. 유용한 액션들이 마켓플레이스에 많이 정의되어 있다.
checkout action은 나의 workspace에 있는 repository들을 workflow가 접근할 수 있도록 해준다.
setup-java라고 정의되어 있는 action을 사용하며 java 11버전의 temurin openjdk를 사용할 것 이다.
구글링을 하다보면 distribution가 adopt인 곳이 많을텐데, adopt가 deprecated되고 temurin 으로 옮겨졌다. (참고)
gradlew 권한 설정
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
gradle을 실행시키기 위해 권한 설정을 먼저 해주어야 한다. Error: Gradle script '/~~~/gradlew' is not executable. 이라는 에러가 발생하며 workflow가 실패한다.
gradle cache
- name: Cache with Gradle
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
workflow를 작성하다 보면 1~2분이 넘어가는 경우가 굉장히 많다. 체감 속도가 굉장히 느리기 때문에 종속성 같은 부분을 캐싱하는 것도 좋은 방법이다. (민감한 정보들은 캐싱하지 않도록 주의하자)
~/.gradle/caches 와 ~/.gradle/wrapper 디렉토리를 캐싱하여 정의된 key값으로 저장한다.
key에 해당하는 값이 없으면 restore-keys에 해당하는 key가 있는지 찾는다.
데이터를 저장한다는 점에서 github action에서 제공하는 아티팩트와 유사하다고 생각할 수 있는데, 사용하는 목적이 다르다.
- 아티팩트: job에 의해 생성된 파일들을 저장할 때
- 캐싱: job과 workflow 실행 사이의 바뀌지 않는 파일들을 재사용 할 때
실행 결과
캐싱 전 후 실행 된 step을 비교하면 gradle 버전을 다운로드 받는 과정이 캐싱되어 생략되었다는 것을 알 수 있다. 무려 25초가 줄어들었다!
gradle build
- name: Build with Gradle
run: ./gradlew build
- name: Test with Gradle
run: ./gradlew test
이제 gradlew를 사용하여 step들을 정의해주면 된다. 간단하게 build와 test를 설정해주었다.
pull request를 올리면 정의해놓은 이벤트로 인해 ci가 실행된다. 에러가 발생한다면 details로 어느 부분에서 에러가 발생했는지 확인이 가능하다.
레포지토리의 actions를 확인하면 이전 workflow를 실행한 이력들을 볼 수 있다.
전체 코드
참고
https://insight-bgh.tistory.com/m/473
https://choseongho93.tistory.com/295
https://wookiist.dev/155
'Devops > CI' 카테고리의 다른 글
[AWS] LocalStack을 사용하여 S3 Bucket에 파일 업로드/다운로드 (0) | 2022.05.22 |
---|