⚠️ yaml 문법 혹은 bash 문법에 대한 잘못된 정보가 포함될 가능성이 있습니다.
현재 진행하고 있는 프로젝트는 하나의 레포에 FE와 BE가 모두 들어있는 구조입니다.
Github actions을 통해 ci 과정에서 자동으로 테스트를 할 수 있도록 설정해보려 합니다.
단, 프론트엔드 코드가 변경된 경우에는 프론트엔드 테스트만, 백엔드 코드가 변경된 경우에는 백엔드 테스트만 실행하고 싶습니다.
변경된 코드의 위치에 따라, 수행하는 테스트가 달라지도록 github actions를 설정해보기
일단 저보다 github actions를 더 잘 알고 있을 gpt에게 냅다 물어봅시다.
Q. 변경된 파일의 위치에 따라 다른 테스트를 수행하고 싶어. 가능할까?
A. 물론입니다. 다음은 예시 코드입니다.
name: 테스트
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 저장소 체크아웃
uses: actions/checkout@v2
- name: frontend 테스트
if: ${{ steps.changed_files.outputs.frontend_changed == 'true' }}
run: |
cd frontend
# frontend 테스트 명령어 실행
- name: backend 테스트
if: ${{ steps.changed_files.outputs.backend_changed == 'true' }}
run: |
cd backend
# backend 테스트 명령어 실행
- name: 변경된 파일 확인
id: changed_files
run: |
echo "::set-output name=frontend_changed::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- frontend/)"
echo "::set-output name=backend_changed::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- backend/)"
일단 뭔지 모르는 코드들을 받았습니다.
언뜻 보기에는 그럴듯 해보이지만, 한가지 이상한 점이 있습니다.
이 작업의 목적은 변경된 코드의 위치를 파악한 후, 변경된 파일의 위치에 따라 다른 command를 실행하여 다른 테스트를 동작시키는 것입니다.
그러나 변경된 파일 확인이 맨 나중 작업으로 설정되어 있습니다.
따라서 순서를 바꿔주도록 합니다.
그리고 실제로 테스트를 수행하는 대신 간단히 echo를 날리는 방식으로, 우리가 원하는 대로 동작하는지 확인해보도록 하겠습니다.
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 저장소 체크아웃
uses: actions/checkout@v2
- name: 변경된 파일 확인
id: changed_files
run: |
echo "::set-output name=frontend_changed::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- frontend/)"
echo "::set-output name=backend_changed::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- backend/)"
- name: frontend 테스트
if: ${{ steps.changed_files.outputs.frontend_changed == 'true' }}
run: |
echo fe test!
- name: backend 테스트
if: ${{ steps.changed_files.outputs.backend_changed == 'true' }}
run: |
echo be test!
그리고 푸시를 해보면?
일단 새로 추가한 yml 파일을 제외하고, 프론트엔드 및 백엔드 코드에 변화가 없으므로, frontend test / backend test를 제대로 건너뛴 것으로 보입니다.
로그를 보면 한 가지 warning을 보여주는데, set-output
이라는 키워드가 deprecated 된다는 내용입니다. 따라서 해당 경고를 해결하기 위해 다음 링크 를 참고했습니다.
한 줄 요약 : $GITHUB_ENV 사용해라
GITHUB_ENV를 사용하여, 위 코드를 수정해보겠습니다.
수정하기 전에, 해당 코드의 의미를 알아야 수정이 가능하므로, 한 줄만 분석을 해보겠습니다
set-output 구문은 다음과 같이 사용됩니다.
echo "::set-secret name={secret_name}::{secret_value}"
secret 값을 설정할 건데, 이름은 frontend_changed야
그리고 이 값이 secreate_value에 해당하게 됩니다.
여기서 알아야 할 내용은 3가지 정도입니다.
$의 역할
git diff [options]
${{ github.event.before }} 와 ${{ github.event.after }}
이 내용을 바탕으로 다시 작성해보도록 하겠습니다.
# before
echo "::set-output name=frontend_changed::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- frontend/)"
# after
echo frontend_change=$(git diff --name-only -- frontend/) >> $GIHHUB_ENV
위와 같이 작성하고, 임의의 파일을 변경하면 다음과 같은 변화가 나타납니다.
Index.tsx
파일을 수정했다고 가정해보겠습니다.
$GITHUB_ENV
frontend_change=Index.tsx
프론트엔드 파일 수정 이후 백엔드 파일을 수정하면 아래에 변경 사항이 추가되는 모습을 확인할 수 있습니다.
$GITHUB_ENV
frontend_change=Index.tsx
backend_change=app.controller.tsx
이제 실제로 프론트엔드 테스트 커맨드를 실행하는 step을 보도록 하겠습니다.
# steps.changed_files.outputs.frontend_changed -> env.frontend_change
- name: frontend 테스트
if: ${{ env.frontend_change == 'true' }}
run: |
echo fe test!
여기서도 이상한 점을 하나 발견할 수 있습니다.
frontend_change는 변경사항이 있는 파일의 목록을 가지고 있기때문에, true
라는 문자열을 가지는 경우가 없습니다.
따라서 변경된 파일 확인 step에서 변경된 파일이 있는 경우에는 frontend_change에 true라는 문자열을 할당할 수 있도록 코드를 수정해보겠습니다.
Q. 문자열의 길이가 1 이상인 경우에 true라는 문자열을 할당하는 yaml 코드를 작성해줘
A. 다음은 예시 코드입니다.
run: |
if [ -n "$MY_STRING" ]; then
echo "MY_STRING=true" >> $GITHUB_ENV
fi
-n 옵션은 문자열이 NULL이 아닌지 체크하는 문자열 비교 연산자(?) 이다.
GPT로부터 받은 코드를 그대로 적용해 보겠습니다.
- name: 변경된 파일 확인
run: |
frontend_change=$(git diff --name-only -- frontend)
backend_change=$(git diff --name-only -- backend)
if [ -n $frontend_change ]; then
echo frontend_change=true >> $GITHUB_ENV
fi
if [ -n $backend_change ]; then
echo backend_change=true >> $GITHUB_ENV
fi
그리고 푸시를 해보면?
프론트엔드 / 백엔드의 변경사항이 모두 존재하는 경우 다음과 같은 결과를 보여줍니다.
이제 frontend / backend step에 테스트 커맨드를 입력하면 끝날 것으로 예상됩니다.
끝!