CI\CD/GitHub Actions

[GitHub Actions] Job 간에 파일 공유하기

서로 다른 가상 머신에서 동작하는 Job

build Job을 통해 ubuntu-latest 머신에 저장된 파일들은 다른 Job에서 접근이 불가능하다. 같은 이름의 머신이더라도 실제는 다른 가상 머신에서 돌아가기 때문이다. 따라서 build Job 다음에 실행되는 deploy Job을 추가한 다음 위에서 Apk를 Job Artifact로 만드는데 사용한 Path를 제공한다면 접근할 수 없다.

 

한 번 시도해 보자. 먼저 빌드를 하는 Job을 만든다.

build:
  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: Build with Gradle
      run: ./gradlew assembleRelease

 

./gradlew assembleRelease로 생성된 안드로이드 apk 파일은 app/build/outputs/apk/release 위치에 생성된다. 따라서 다른 Job에서 해당 폴더를 업로드 해보자.  Job은 기본적으로 병렬적으로 동작하기 때문에 앞의 Job이 완료 되었을 경우에 업로드를 실행하기 위해 needs: build를 넣어준다.

upload:
  needs: build
  runs-on: ubuntu-latest
  steps:
    - name: Upload Build File
      uses: actions/upload-artifact@v3
      with:
        name: android-artifact # Artifact 이름 지정
        path: app/build/outputs/apk/release # 폴더 지정 : 이 폴더 아래의 모든 파일들이 하나의 artifact로 저장된다.

 

전체 코드는 다음과 같다.

name: Job Artifacts Not Uploaded

on:
  workflow_dispatch:
  push:

jobs:
  build:
    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: Build with Gradle
        run: ./gradlew assembleRelease

  upload:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Upload Build File
        uses: actions/upload-artifact@v3
        with:
          name: android-artifact # Artifact 이름 지정
          path: app/build/outputs/apk/release # 폴더 지정 : 이 폴더 아래의 모든 파일들이 하나의 artifact로 저장된다.

 

위 코드를 실행하면 다음과 같은 결과가 나온다. upload Job에서 No files were found 경고가 뜨는 것을 볼 수 있다. 

 

 

이유는 앞에 말한대로 Job 간에 파일의 공유가 되지 않아서이다. 그러면 Job 간에 파일을 공유하려면 어떻게 해야할까? 아래에서 그 방법을 알아보자.

 

Job 간에 파일 공유하기

가상 머신 간에는 파일을 공유하지 않기 때문에 Job 간에 파일을 공유하기 위해서는 서버로 업로드 후 다운로드 하는 과정을 거쳐야 한다. 즉, upload-artifact와 download-artifact를 적절히 사용하면 된다.

 

upload-artifact Action은 파라미터로 name 을 받는데 이 name은 Job Artifact 출력 파일의 이름으로 설정될 뿐만 아니라,  download-artifact에서 업로드된 파일들을 다운로드하는데도 사용될 수 있다. 예를 들어 아래의 Upload Apk Step에서는 android-artifact라는 이름의 Job Artifact 생기게 된다.

- name: Upload Apk
  uses: actions/upload-artifact@v3
  with:
    name: android-artifact # Job Artifact의 이름으로 설정 및 Artifact를 가져오는데 사용
    path: app/build/outputs/apk/release # 폴더 지정 : 이 폴더 아래의 모든 파일들이 하나의 artifact로 저장된다.

 

따라서 위 Step이 실행되면 다음과 같은 Artifact가 나오게 된다.

 

 

이 Artifact는 다른 Job에서 다운로드 해서 사용하는 것이 가능하다. 예를 들어 다음과 같은 download Job을 통해 위에서 만든 Artifact를 download-artifact 액션을 사용해 다운로드 한다고 해보자. 그러면 위에서 업로드한 파일이 다운로드 된다.

download:
  needs: build
  runs-on: ubuntu-latest
  steps:
    - name: Download Apk
      uses: actions/download-artifact@v3
      with:
        name: android-artifact # 위의 upload-artifact에서 설정한 name

    - name: List Contents
      run: ls

 

주의할 점은 위 다운로드가 되었을 때 다운로드 파일의 경로는 최상위 경로라는 점이다. 따라서 최상위 경로에서 ls 명령어를 실행해 모든 파일들을 출력하면 업로드된 파일들이 곧바로 출력된다. 물론 경로를 바꿔서 다른 경로에 저장하는 방법도 있다. 이에 대해서는 아래에서 알아볼 것이다.

 

 

download-artifact 알아보기

download-artifact는 upload-artifact를 통해 업로드된 파일을 다운로드 하는 Action이다.

 

모든 Artifact 다운로드 하기

위에서는 download-artifact의 with을 통해 name을 넘겨 특정 Artifact만 다운로드 했지만, 다음과 같이 사용하면 만들어진 모든 Job Artifact들이 다운로드 된다.

- uses: actions/download-artifact@v3

 

특정한 위치에 다운로드하기

만약 위에서 다운로드한 Android 빌드 파일을 특정 위치에 저장하고 싶다면 path 파라미터를 통해 원하는 경로를 전달하면 된다. 예를 들어 최상위 경로/build/release 에 다운로드한 안드로이드 빌드 파일을 저장하고 싶다면 다음과 같이 작성하면 된다. 

- uses: actions/download-artifact@v3
  with:
    name: android-artifact
    path: build/release

 

반응형

 

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

 

 

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

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

open.kakao.com