Github actions로 테스트 추가하기 (feat. chat gpt)

In9_9yu·2023년 6월 2일
0

mobae

목록 보기
5/9

⚠️ 주의

⚠️ yaml 문법 혹은 bash 문법에 대한 잘못된 정보가 포함될 가능성이 있습니다.

상황 및 목표

현재 진행하고 있는 프로젝트는 하나의 레포에 FE와 BE가 모두 들어있는 구조입니다.

my repo

Github actions을 통해 ci 과정에서 자동으로 테스트를 할 수 있도록 설정해보려 합니다.

단, 프론트엔드 코드가 변경된 경우에는 프론트엔드 테스트만, 백엔드 코드가 변경된 경우에는 백엔드 테스트만 실행하고 싶습니다.

최종 목표

변경된 코드의 위치에 따라, 수행하는 테스트가 달라지도록 github actions를 설정해보기

GDD (Gpt Driven Development)

일단 저보다 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!

그리고 푸시를 해보면?

warn

일단 새로 추가한 yml 파일을 제외하고, 프론트엔드 및 백엔드 코드에 변화가 없으므로, frontend test / backend test를 제대로 건너뛴 것으로 보입니다.

로그를 보면 한 가지 warning을 보여주는데, set-output이라는 키워드가 deprecated 된다는 내용입니다. 따라서 해당 경고를 해결하기 위해 다음 링크 를 참고했습니다.

한 줄 요약 : $GITHUB_ENV 사용해라

GITHUB_ENV를 사용하여, 위 코드를 수정해보겠습니다.
수정하기 전에, 해당 코드의 의미를 알아야 수정이 가능하므로, 한 줄만 분석을 해보겠습니다

::set-output name=frontend_changed

set-output 구문은 다음과 같이 사용됩니다.

echo "::set-secret name={secret_name}::{secret_value}"

secret 값을 설정할 건데, 이름은 frontend_changed야

::$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} -- frontend/)

그리고 이 값이 secreate_value에 해당하게 됩니다.

여기서 알아야 할 내용은 3가지 정도입니다.

  • $의 역할

    • 여러가지 방식이 있지만 뒤에 괄호를 가지고 있으므로, 괄호 안의 결과값을 가져오는 역할입니다.
  • git diff [options]

    • git diff는 변경된 코드를 보여주는 명령어입니다.
    • --name-only는 변경된 코드 대신, 변경된 파일 목록을 반환합니다.
    • -- frontend/는 해당 디렉토리에서의 변경만 추적하도록 합니다.
  • ${{ github.event.before }} 와 ${{ github.event.after }}

    • github actions에서 이전 commit과 비교할 commit의 hash를 자동으로 할당합니다.
    • 그러나,force push를 하는 경우에 해당 hash를 찾을 수 없다는 오류를 발생시켜서 이 부분은 나중에 삭제했습니다.

이 내용을 바탕으로 다시 작성해보도록 하겠습니다.

# 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에 테스트 커맨드를 입력하면 끝날 것으로 예상됩니다.

끝!

profile
FE 임니다

0개의 댓글