Image
CI\CD/GitHub Actions

[GitHub Actions] if문 사용해 Job 실패 제어하기

Step과 Job의 차이점

Step은 무조건 순차적으로 실행되는 반면, Job은 병렬적으로 실행될 수도 있고 순서대로 실행될 수도 있다. 이 말은 Step에서 실패를 제어하기 위해 사용했던 전제인 "먼저 실행된 Step은 이후 Step 시작 전에 끝난다"가 더이상 유효하지 않다는 뜻이다. 따라서 이 전제를 맞추기 위해 추가적인 설정을 해주어야 한다.

 

병렬적인 Job 간의 실패 제어

일단, 병렬적인 Job A와 Job B가 있다고 해보자. B가 A의 실패를 제어하는 것은 불가능하다. 이유는 B는 A에 대한 정보가 없기 때문이다. 하나의 Job이 다른 Job에 대한 정보를 알기 위해서는 needs Context를 사용해야 하는데, 병렬적인 Job 간에는 needs에 다른 Job의 정보가 없다.

 

공식 문서에는 아래와 같이 나와있다.

The needs context contains outputs from all jobs that are defined as a direct dependency of the current job.

needs Context는 현재 Job에 직접 의존성이 있다고 정의된 모든 Job에 대한 outputs 정보를 가진다.
 

Contexts - GitHub Docs

About contexts Contexts are a way to access information about workflow runs, runner environments, jobs, and steps. Each context is an object that contains properties, which can be strings or other objects. Contexts, objects, and properties will vary signif

docs.github.com

 

따라서 다른 Job이 실패했는지에 대해 필요한 정보가 없으므로, 병렬적인 Job 간의 실패 제어는 불가능하다.

*제어가 되어도 문제이다. Job A, B가 병렬적으로 실행되면 각 Job 실행 시점에 다른 Job이 성공했는지, 실패했는지는 랜덤이기 때문이다.

 

 

순차적인 Job 간의 실패 제어

순차적인 Job 간에는 실패 제어가 가능하다. 순차적인 Job은 앞서 실행된 Job이 성공했는지 실패했는지를 알 수 있기 때문이다. Step에서는 outputs.outcome을 통해 상태에 접근했지만 Job에서는 jobs.<job_id>.result 를 통해 상태에 접근할 수 있다.

 

Context Name Type Description
jobs.<job_id>.result string Job의 실행 결과 반환. 반환 값 : success, failure, cancelled, skipped

 

 

Contexts - GitHub Docs

About contexts Contexts are a way to access information about workflow runs, runner environments, jobs, and steps. Each context is an object that contains properties, which can be strings or other objects. Contexts, objects, and properties will vary signif

docs.github.com

 

하지만, Job에 의존성 있는 Job 객체 정보는 needs 객체에 관리되므로, needs.<job_id>.result 로 상태에 접근할 수 있다.

 

예를 들어 test Job과 handle-failure Job이 있다고 해보자.  handle-failure은 needs 로 test를 가지므로 test가 끝나고 수행된다. 따라서 handle-failure은 test가 성공했는지, 실패했는지에 대한 정보가 있다. 따라서 if 문을 통해 해당 정보로 이전 Job이 실패했는지 확인 후 수행하는 것이 가능하다.

handle-failure:
  runs-on: ubuntu-latest
  needs: [ test ]
  if: failure() && needs.test.result == 'failure'
  steps:
    - name: Print Report
      run: |
        echo "This runs when test fails"

 

 

전체 코드

전체 코드는 다음과 같다. test Job 을 수행 후 handle-failure Job을 수행한다.

name: Handle Job Failure - Handled - if

on:
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Check out Repository
        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

      - name: Test with Gradle
        id: exec-test
        run: ./gradlew :app::testDebug
        
  handle-failure:
    runs-on: ubuntu-latest
    needs: [ test ]
    if: failure() && needs.test.result == 'failure'
    steps:
      - name: Print Report
        run: |
          echo "This runs when test fails"

 

반응형

 

이 글의 저작권은 '조세영의 Kotlin World' 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com