PR을 올릴 때마다 자동으로 Build가 잘 되는지 체크했으면 좋겠다.
GitHub Action으로 이를 구현해보자.
Action 생성
GitHub Repository의 Actions 탭에 들어가면 여러가지 Action 예시가 나와있다.
나는 여기서 Java Spring 프로젝트를 빌드할 것이므로 'Java with Gradle'을 선택한다.
(github action 문법을 안다면 그냥 처음부터 새로 만들어도 된다.)
그리고 아래와 같이 입력한다.
name: Java Spring Build
on: [pull_request]
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
steps:
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
backend:
- 'server/spring/**'
build:
needs: changes
if: ${{ needs.changes.outputs.backend == 'true' }}
runs-on: ubuntu-latest
env:
working-directory: ./server/spring
steps:
- name: Checkout the code
uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
cache: 'gradle'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: ${{ env.working-directory }}
- name: Build with Gradle
run: ./gradlew clean build --debug
working-directory: ${{ env.working-directory }}
하나씩 어떤 의미인지 풀어 써보자면,
name: Java Spring Build
이건 Action workflow의 이름이다. workflow 목록에 이렇게 설정해 둔 이름으로 뜬다.
on: [pull_request]
on 은 해당 workflow의 trigger다.
나는 pull request를 올릴 때마다 실행하고 싶어서 위와 같이 지정했다.
branch명을 필터링 할 수도 있다.
jobs:
<job_id>:
step:
그 아래부터는 job과 step으로 이루어진다.
job_id는 여러개 지정할 수 있고, 각기 다른 이름을 설정할 수 있다.
나는 changes와 build job을 두었다.
jobs:
changes:
...
steps:
build:
...
steps:
그리고 각 job 하위에는 step들이 있는데 step이란 일련의 작업들(tasks)을 말한다.
즉, 이 job에서 어떤 작업을 할 것인지 일일히 지정해 주는 것이다.
문법에 대해 좀 더 자세히 알고 싶다면 GitHub Action 문서를 보면 된다.
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
Workflow syntax for GitHub Actions - GitHub Docs
About YAML syntax for workflows Workflow files use YAML syntax, and must have either a .yml or .yaml file extension. If you're new to YAML and want to learn more, see "Learn YAML in Y minutes." You must store workflow files in the .github/workflows directo
docs.github.com
changes Job
changes job은 특정 폴더에 변화가 있었는지 확인하기 위한 job이다.
jobs:
changes:
runs-on: ubuntu-latest
outputs:
backend: ${{ steps.filter.outputs.backend }}
steps:
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
backend:
- 'server/spring/**'
한 Repo에 client 폴더와 server 폴더를 둘 다 두고 작업하기 때문에 PR이 올라오면 관련 작업이 있었는지 판단할 수 있어야 한다. 이를 판단하기 위해 dorny/paths-filter를 사용했다. 이를 사용하면 특정 폴더에서 file changes가 있었는지 판단할 수 있다.
자세한 사용법 참고 : https://github.com/dorny/paths-filter
GitHub - dorny/paths-filter: Conditionally run actions based on files modified by PR, feature branch or pushed commits
Conditionally run actions based on files modified by PR, feature branch or pushed commits - GitHub - dorny/paths-filter: Conditionally run actions based on files modified by PR, feature branch or p...
github.com
build Job
build:
needs: changes
if: ${{ needs.changes.outputs.backend == 'true' }}
우선 build job에서는 changes job을 선행조건으로 요구하고 있다.
changes job에서 설정한 작업(지정한 폴더에 파일 변화가 있는가?)이 true 값이어야 build job이 실행된다.
# 실행 환경 지정
runs-on: ubuntu-latest
env:
# 어느 디렉토리에서 커맨드를 실행할 지 결정
working-directory: ./server/spring
Github Action에서는 workflow를 실행할 때 서버를 하나 빌려준다. 해당 서버의 실행 환경을 설정한다. (mac os도 된다고 한다.)
그리고 환경 변수로 working-directory를 지정해준다. 위에서 말했듯 한 Repo에 FE, BE 코드를 전부 두는 경우 뒤에 이어질 작업들을 그냥 실행하면 실행이 안된다. root directory가 달라서. 그래서 작업을 실행할 때마다 해당 디렉토리에서 하라고 지정해준다.
steps:
- name: Checkout the code
uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
cache: 'gradle'
# Gradle wrapper 파일 실행 권한주기
- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: ${{ env.working-directory }}
# Gradle Build 실행
- name: Build with Gradle
run: ./gradlew clean build --debug
working-directory: ${{ env.working-directory }}
그리고 이게 주요 작업들이다.
- actions/checkout@v3으로 코드를 가져오고
- actions/setup-java@v3으로 해당 프로젝트에 맞는 버전의 Java를 설치해준다. (v1은 상관없지만 v2부터는 distribution 이 필수값이다.)
- Gradle wrapper 파일에 실행 권한을 준다. (working-directory 지정할 것)
- Gradle Build를 실행한다. (working-directory 지정할 것)
마지막으로 commit을 해주면 적용된다.
PR 올리기
이후로 PR을 올리면 설정해 두었던 Github Action이 실행되면서 build가 된다.
Branch Protection Rule에 merge 조건으로 설정
build가 되지 않으면 merge를 못하게 막고 싶다. branch protection rule에서 다음과 같이 설정해주면 된다.
이러면 PR을 올렸을 때 반드시 build가 성공해야 merge를 할 수 있다.
'공부 > 기타' 카테고리의 다른 글
[Git - CLI] 버전 관리 (0) | 2020.06.05 |
---|---|
[Deno] 신생 JS & TS 런타임 데노(Deno) (0) | 2020.06.02 |