matrix Required job도 GitHub Actions에서 skip 하기
안녕하세요 😉
유유자적한 개발자 유로띠 입니다 😀
👏👏👏👏
이번 포스팅에서는
✅ GitHub Actions 실행 시 필수 체크 방법
✅ 기본적인 ci-skip 처리 방법
✅ matrix로 설정된 required job도 skip 하도록 하는 방법
에 대해서 알아보겠습니다
GitHub ci-skip
ci-test는 Pull Request 요청이나 병합 시 GitHub Actions를 통해 자동으로 build 체크 및 코드에 문제가 없는지 검증을 진행하도록 많이 사용합니다.
또한, 해당 테스트가 성공적으로 완료되어야 병합할 수 있도록 필수로 상태 체크 검증을 추가할 수 있습니다.
그럼 이러한 테스트를 skip 해야 하는 이유에는 어떤 것이 있을까요?
문서 수정이나 스크립트 수정 등 코드 수정 및 개선, 코드 품질과 관련 없는 부분을 수정할 때는 매번 Pull Request 때마다 검증할 필요는 없습니다.
그리고 테스트 코드가 적으면 상관없지만 테스트코드가 많다면 테스트 완료 될 때까지 많은 시간이 소비되며, 불필요한 자원도 낭비됩니다.
✅ GitHub Actions Required Job 설정
일단 required job 설정부터 해보겠습니다.
settings > Branches에서 Branch Protection rules 설정합니다.
저는 main이라는 protection rules을 만들었습니다.
새로 만들거나 수정을 통해 해당 규칙을 살펴보겠습니다.
Protect matching branches에서 ✅ Require status checks to pass before merging 부분을 체크하여 활성화합니다.
검색창에서 생성한 ci test를 검색하여 등록하면 병합 전 필수로 상태 체크 하도록 할 수 있습니다.
몇 가지 중요한 부분을 제거한 실제 서비스에 사용 중인 ci-test.yml 입니다.
name: API-TEST
on:
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
if: "! contains(toJSON(github.event.pull_request.labels.*.name), 'ci-skip')"
timeout-minutes: 10
strategy:
matrix:
node-version: [ 20.x ]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
...
ci-test:
runs-on: ubuntu-latest
needs: [ build ]
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
workspace: [
'action:test-01',
'action:test-02',
'action:test-03',
'action:test-04',
'action:test-05',
'action:test-06']
services:
redis:
image: redis
...
steps:
- name: Install npm packages
if: steps.cache.outputs.cache-hit != 'true'
run: npm ci --include dev
- name: API TEST ${{ matrix.workspace }}
run: |
npm run ${{ matrix.workspace }}
env:
CI: true
여기서 중요한 포인트는 저희는 서비스(action:test-01, action:test-02...)에 따라 테스트를 병렬적으로 처리하도록 matrix로 설정하였습니다.
matrix로 설정 시의 이점은 동시에 처리 때문에 테스트 검증 속도가 향상되었고 어떤 서비스에서 pass/fail 되는지도 알 수 있습니다.
요청한 pr을 보면 ci-test를 볼 수 있고 Required가 설정되어 있음을 알 수 있습니다.
Required 된 job을 모두 완료해야 병합할 수가 있습니다.
✅ 기본적인 ci skip 처리 방법
첫 번째, ci skip 커밋 메시지
커밋 메시지에 다음과 같은 값을 입력하는 경우 ci-skip이 진행됩니다.
[skip ci]
[ci skip]
[no ci]
[skip actions]
[actions skip]
자세한 내용은 여기를 참고하시면 됩니다.
두 번째, yml 파일에 ci-skip 라벨 설정하기
위에 yml 파일에도 설정되어 있듯이 ci-skip 라벨 여부에 따라 작동되도록 작성하였습니다.
ci-skip 라벨이 없을 때만 build가 실행되고 build가 실행되어야 ci-test가 진행되기 때문에 ci-skip 라벨이 있다면 ci-test도 중지됩니다.
jobs:
build:
runs-on: ubuntu-latest
# ci-skip이 없을 때만 실행
if: "! contains(toJSON(github.event.pull_request.labels.*.name), 'ci-skip')"
timeout-minutes: 10
ci-test:
runs-on: ubuntu-latest
needs: [ build ]
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
workspace: [
'action:test-01',
'action:test-02',
'action:test-03',
'action:test-04',
'action:test-05',
'action:test-06']
위에처럼 설정하면 test skip을 진행할 수 있습니다.
하지만, 문제없이 진행된다면 이 블로그를 작성할 필요도 없었죠...
이처럼 ci-test를 skip 하도록 하는 경우 중단(Waiting for status to be reported)되기 때문에 required job으로 설정된 것은 대기상태가 된 채 성공하지 못하여 병합할 수 없는 상태가 됩니다.
required 설정을 하지 않았다면 대기 상태가 안되기 때문에 skip이 가능합니다.
✅ matrix로 설정된 required job도 skip 하도록 하는 방법
필수로 설정된 ci-test를 해제하고 싶지는 않고 문서나, 스크립트 등 ci-skip을 진행하고 싶은 경우는 어떻게 해야 할까요?
아래처럼 ci-test skipped.yml 파일을 새롭게 생성합니다.
name: API-TEST-Skipped
on:
pull_request:
paths:
- '.github/**'
- 'dockerfile'
- '*.sh'
- 'README.md'
jobs:
ci-test:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
workspace: [
'action:test-01',
'action:test-02',
'action:test-03',
'action:test-04',
'action:test-05',
'action:test-06']
steps:
- run : 'echo "No Test Required"'
ci-test-skipped.yml 파일에 skip 할 path를 필터링하도록 하고 skip에 필요한 matrix job이 실행될 때, 단순히 통과만 하면 되기 때문에 메시지만 작성하여 통과하도록 만듭니다.
여기서 중요한점은 기존 코드가 matrix로 구성하였다면 기존 코드와 동일하게 matrix로 설정하여 모든 ci-test가 동일하게 실행되도록 하여 skip 할 수 있도록 합니다.
사실상 skip이라기 보다는 required job을 실행하도록 하고 다만 테스트가 아닌 단순 메시지를 출력하고 끝내게끔 하도록 하는 거죠
이처럼 Required job이지만 ci-test-skipped.yml 파일을 이용해 matrix으로 설정한 테스트를 모두 skip 하여 테스트 검증을 성공하도록 할 수 있습니다.
참고
Handling skipped but required checks
https://blog.outsider.ne.kr/1671