기술 이모저모/[Github] Workshop

[Github] Github Action Job output 출력하기

Kobby 2023. 1. 28. 18:18

처음부터 차근차근 공부하는 목적으로 작성한 글입니다.

일부 잘못된 내용이 있을 수도 있습니다. 잘못된 내용은 피드백 해주시면 적극 반영하도록 하겠습니다.

감사합니다 :)


최근 업무적으로 Github Action을 사용할 일이 있는데, 잘 모르는 분야이다 보니 Github Action Docs을 읽어보았다

그중에서 조금 헷갈리는 Github Action output 부분에 대해서 알아보도록 한다.

 

Defining outputs for jobs - GitHub Docs

Overview You can use jobs. .outputs to create a map of outputs for a job. Job outputs are available to all downstream jobs that depend on this job. For more information on defining job dependencies, see jobs. .needs . Outputs are Unicode strings, and can b

docs.github.com

 

Github Action Workflow

Github Action은 크게 Job 과 Job에 종속되어 있는 Step으로 구분한다. 그림으로 분류하면 아래와 같이 분류된다.

Workflow는 하나의 Github Action으로 생각하면 된다. Workflow에서 여러개의 Job으로 구분된다.

그리고 Job은 또 여러개의 Step으로 분류된다. 쉽게 말하면 Job = Function와 유사하다.

Github Action 구조

 

Github Action Output 사용 방법

      - name: save test
        id: test
        run: |
          echo "123" > test.txt
          values=`cat test.txt`
          echo "test2=$values" >> $GITHUB_OUTPUT

우선 $GITHUB_OUTPUT은 특정 Step에서 사용한 변수를 다른 Step 또는 Job에서 사용하는 것이다. Python과 비교하면 global 변수로 선언하는 것과 유사하다.

 

사용 방법은 위 코드와 같이 echo "변수=값" >> "GITHUB_OUTPUT"작성하면 된다.

근데 여기에서 중요한것은 반드시 echo를 통해 GITHUB_OUTPUT을 내보내야 한다는 점이다. 처음에는 values=`cat test.txt` >> $GITHUB_OUTPUT와 같이 작성했는데 동작하지 않아서 한참동안 헤매었다. 부디 나와 같은 실수를 하는 사람이 없도록 바란다 ㅜㅜ

 

 

그렇다면 Job에 따라서 GITHUB_OUTPUT을 사용하는 방법은 어떻게 다를까?

 

만약 동일한 Job에서 사용하는 경우

    steps:
      - name: fetch repo(default)
        uses: actions/checkout@v3
      - name: save test
        id: test
        run: |
          echo "123" > test.txt
          values=`cat test.txt`
          echo "test2=$values" >> $GITHUB_OUTPUT <<< key point
      - name: cat test
        run: |
          echo ${{ steps.test.outputs.test2 }}  <<< key point

같은 Job에서 다른 Step의 변수를 사용하는 경우는 먼저 >> $GITHUB_OUTPUT으로 선언해준다.

그리고 다른 step에서 echo $ {{ steps."id".outputs."변수" }} 와 같이 사용하면 된다. 크게 어렵지 않다.

 

만약 다른 Job에서 사용하는 경우

$GITHUB_OUTPUT은 Python global 변수를 선언하는것과 유사하다고 했다. 그렇기에 Job에서도 global 선언을 해줘야한다.

  job1:
    runs-on: ubuntu-22.04
    outputs:
      test3: ${{ steps.test.outputs.test2 }}  <<< key point
    steps:
      - name: fetch repo(default)
        uses: actions/checkout@v3
      - name: save test
        id: test
        run: |
          echo "123" > test.txt
          values=`cat test.txt`
          echo "test2=$values" >> $GITHUB_OUTPUT  <<< key point
      - name: cat test
        run: |
          echo ${{ steps.test.outputs.test2 }}
  job2:
    runs-on: ubuntu-22.04
    needs: job1
    steps:
      - name: cat test
        run: |
          echo ${{ needs.job1.outputs.test3 }}  <<< key point

job1.outputs.test3와 같이 작성하는 것이 global 변수로 선언하는 것이다.

동일한 Job에서는 outputs을 별도 선언한 필요는 없지만, 다른 Job에서는 동일한 변수가 사용될 수 있기에 global 선언을 해줘야한다.

그리고 변수는 job1에 종속적이기 때문에 종속선언인 needs를 한다.

 

job2을 보면 needs: job1이 있다. 이는 job2의 cat test step에서 사용할 변수가 job1의 결과에 종속적이기 때문에 종속여부를 선언하는 것이다. 그렇게 되면 job1이 모두 종료된 다음에 job2가 실행이 되고 cat test step에서 test3 output을 사용할 수 있다.

 

그리고 output을 사용할 때는 steps이 아닌 needs."job".outputs."outputs 변수"와 같이 작성하여 사용해야 한다.

 

만약 동일한 Job에서 사용하는것과 같이 사용하게 되면 어떻게 될까?

  job2:
    runs-on: ubuntu-22.04
    needs: job1
    steps:
      - name: cat test
        run: |
          echo ${{ steps.test.outputs.test2 }} <<< 잘못된 작성 방법

결론부터 말하면 값이 출력되지 않는다.

그 이유는 steps."id".outpus"변수"로 작성하게 되면 동일한 Job에서의 ."id"."변수"를 찾게된다.

동일한 Job에서는 해당 id, 변수가 없기 때문에 echo ""으로 출력이 되고 실제 값은 출력되지 않는다. 이점을 유의해야 한다.

 

 

아직 배울게 많은 세상이다. 보면 볼수록 새로운 지식이 많다. 끝!!!