GithubActions에서 java, 리액트(클라이언트) 동시빌드

이정연·2023년 4월 24일
0

project034

목록 보기
3/10

프로젝트의 배포를 위해 github action을 이용하여 무중단 배포를 하게되었다

오류발견

처음에는 백엔드쪽 서버 배포를 위해 다음과 같이 gradle.yml를 작성했다.

name: Java CI with Gradle

on:
  push:
    branches: [ "dev" ]
  pull_request:
    branches: [ "dev" ]

permissions:
  contents: read
  
env:
  S3_BUCKET_NAME: jungyeon222
  RESOURCE_PATH: ./Server/tripAdvisor/tripAdvisor/src/main/resources/application.yml
  
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        
    - name: Set yml file 
      uses: microsoft/variable-substitution@v1
      with:
        files: ${{ env.RESOURCE_PATH }} 
      env:
        spring.datasource.url: ${{ secrets.RDS_HOST }} 
        spring.datasource.username: ${{ secrets.RDS_USERNAME }} 
        spring.datasource.password: ${{ secrets.RDS_PASSWORD }} 
        jwt.key: ${{ secrets.JWT_KEY }}
        naver.map.client.id: ${{ secrets.NAVER_CLIENT_ID }}
        naver.map.client.secret: ${{ secrets.NAVER_CLIENT_SECRET }}
        
    - name: Add permission
      run: chmod +x gradlew
      working-directory: ./Server/tripAdvisor/tripAdvisor
    - name: Build with Gradle
      run : ./gradlew clean build --exclude-task test
      working-directory: ./Server/tripAdvisor/tripAdvisor
    
    # build한 후 프로젝트를 압축합니다.
    - name: Make zip file
      run: zip -r ./tripAdvisor.zip .
      shell: bash
    
    # Access Key와 Secret Access Key를 통해 권한을 확인합니다.
    # 아래 코드에 Access Key와 Secret Key를 직접 작성하지 않습니다.
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-region: ap-northeast-2
    
    # 압축한 프로젝트를 S3로 전송합니다.
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./tripAdvisor.zip s3://jungyeon222/tripAdvisor.zip
      
      
    # CodeDeploy에게 배포 명령을 내립니다.
    - name: Code Deploy
      run: >
        aws deploy create-deployment --application-name project034
        --deployment-config-name CodeDeployDefault.AllAtOnce
        --deployment-group-name project034-group
        --s3-location bucket=jungyeon222,bundleType=zip,key=tripAdvisor.zip

- name: Set yml file 
      uses: microsoft/variable-substitution@v1
      with:
        files: ${{ env.RESOURCE_PATH }} 
      env:
        spring.datasource.url: ${{ secrets.RDS_HOST }} 
        spring.datasource.username: ${{ secrets.RDS_USERNAME }} 
        spring.datasource.password: ${{ secrets.RDS_PASSWORD }} 
        jwt.key: ${{ secrets.JWT_KEY }}
        naver.map.client.id: ${{ secrets.NAVER_CLIENT_ID }}
        naver.map.client.secret: ${{ secrets.NAVER_CLIENT_SECRET }}

환경변수 설정을위해 위와 같이 yml file이 어디있는 지 path를 지정해주고, github secret 을 이용해 key설정을 해주었다.

  • 액션결과 성공적으로 S3에 올라간 것을 확인할 수 있었고

  • codedeploy를 이용한 배포까지 잘되었다.

  • 우리는 s3의 정적 호스팅을 이용한 배포였기 때문에 결국엔 s3의 엔드포인트에서 웹페이지 접속이 되어야 했다.

  • 무슨 이유인지 s3를 통한 접속 시 아래와 같은 페이지를 볼 수 있었다.

  • 보통의 경우 아래쪽의 key : index.html 이아니라 error.html로 나오고, 그것은 앞 글에서 다뤘던 s3의 정적웹사이트 호스팅 설정을 통해서 해결할 수 있는데, 나의 경우는 좀 달랐다.

생각해보기

  • 원인을 찾던 중 수동빌드할때의 과정이 생각나게 되었다.

  • 수동빌드 과정은 서버 배포 과정과 클라이언트 배포 과정으로 나뉜다.

  • 서버배포

    1. EC2에서 git을 불러온다.
    2. EC2상에서 수동 build를 진행한다.
    3. EC2에서 서버를 실행한다.
  • 클라이언트 배포

    1. 빌드전 의존성 모듈 설치
    2. 환경변수 설정(.env)
    3. 터미널 상에서 build(npm run build)
    4. build 결과물을 s3에 수동으로 업로드
  • 결국 위에 작성했던 gradle.yml 파일을 이용한 배포과정은 클라이언트 배포 과정이 없어서 브라우저에서 렌더링을 못하고 있던 것이었다.

  • 즉, 빌드를 통해 html로 바꿔줘야 UI를 볼 수 있었다.

  • 그런데, 클라이언트 빌드 과정을 github action으로 어떻게 진행해야하는 가...

  • 위의 파일을 보고 조금 힌트를 얻을 수 있었는데,

steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'

steps에서는 JDK 11 으로 set up을 해준 후 다음 단계들을 진행하기때문에, 클라이언트 빌드를 위해서는 다른 actions를 새로 만들던지, 하나의 gradle.yml파일에 합쳐서 빌드를 하던지 해야 할 것 같았다.

해결방법

  • 구글링 결과 gradle.yml 파일 내부에서 jobs를 두개로 나눠 서로 다른 과정을 빌드할 수 있다는 것을 알게되었다.
  • 위에 내가 작성한 gradle.yml 파일을 보면 아래와 같이 나오는데
jobs:
  build:
    runs-on: ubuntu-latest

현재 이 코드는 jobs의 아래에 build라는 이름의 작업을 추가한다는 뜻이다 즉, build1, build2 로 2개를 추가할 수도있다.

  • 결론적으로 build1에는 클라이언트 배포를 담당하게 해주고 build2에는 서버배포를 담당해서 순서만 정해주면 되었다.
  • 두가지 작업의 순서를 정할 때는 의존성을 추가해주면 되는데, 작업의 이름 바로 아래에 needs: build1 과같이 설정해주면된다.
  • 나의 경우 클라이언트 배포가 먼저필요했고, 그다음이 서버 배포 순서였다.
build2:
    needs: build1
    runs-on: ubuntu-latest

결과

name: Java CI with Gradle

on:
  push:
    branches: [ "dev" ]
  pull_request:
    branches: [ "dev" ]

permissions:
  contents: read
  
env:
  S3_BUCKET_NAME: jungyeon222
  RESOURCE_PATH: ./Server/tripAdvisor/tripAdvisor/src/main/resources/application.yml
 

jobs:
  build1:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code.
        uses: actions/checkout@v2
        
      - name: Install dependencies
        run: npm install
        working-directory: ./Client
        
      - name: Build
        run: npm run build
        working-directory: ./Client
        env:
          REACT_APP_HOST: ${{ secrets.REACT_APP_HOST }}
          REACT_APP_KAKAO_MAP_KEY: ${{ secrets.REACT_APP_KAKAO_MAP_KEY }}
          REACT_APP_GEOCODER_KEY: ${{ secrets.REACT_APP_GEOCODER_KEY }}
          
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
          aws-region: ap-northeast-2
      
      - name: Upload to S3
        run: |
          aws s3 sync \
            --region ap-northeast-2 \
            build s3://jungyeon222 \
            --delete
        working-directory: ./Client
  #----------------------------------------------------------------------------------------
  
  build2:
    needs: build1
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up JDK 11
      uses: actions/setup-java@v3
      with:
        java-version: '11'
        distribution: 'temurin'
        
    - name: Set yml file 
      uses: microsoft/variable-substitution@v1
      with:
        files: ${{ env.RESOURCE_PATH }} 
      env:
        spring.datasource.url: ${{ secrets.RDS_HOST }} 
        spring.datasource.username: ${{ secrets.RDS_USERNAME }} 
        spring.datasource.password: ${{ secrets.RDS_PASSWORD }} 
        jwt.key: ${{ secrets.JWT_KEY }}
        naver.map.client.id: ${{ secrets.NAVER_CLIENT_ID }}
        naver.map.client.secret: ${{ secrets.NAVER_CLIENT_SECRET }}
        
    - name: Add permission
      run: chmod +x gradlew
      working-directory: ./Server/tripAdvisor/tripAdvisor
    - name: Build with Gradle
      run : ./gradlew clean build --exclude-task test
      working-directory: ./Server/tripAdvisor/tripAdvisor
    
    # build한 후 프로젝트를 압축합니다.
    - name: Make zip file
      run: zip -r ./tripAdvisor.zip .
      shell: bash
    
    # Access Key와 Secret Access Key를 통해 권한을 확인합니다.
    # 아래 코드에 Access Key와 Secret Key를 직접 작성하지 않습니다.
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # 등록한 Github Secret이 자동으로 불려옵니다.
        aws-region: ap-northeast-2
    
    # 압축한 프로젝트를 S3로 전송합니다.
    - name: Upload to S3
      run: aws s3 cp --region ap-northeast-2 ./tripAdvisor.zip s3://jungyeon222/tripAdvisor.zip
      
    
    # CodeDeploy에게 배포 명령을 내립니다.
    - name: Code Deploy
      run: >
        aws deploy create-deployment --application-name project034
        --deployment-config-name CodeDeployDefault.AllAtOnce
        --deployment-group-name project034-group
        --s3-location bucket=jungyeon222,bundleType=zip,key=tripAdvisor.zip

jobs 하위에 build1, build2 로 해서 클라이언트빌드와 서버 빌드를 동시에 작성했고, build2에 build1이 선행되도록 의존성을 추가해주었다.

  • 이렇게하면 github actions 에서 다음과 같이 두 작업이 연결되어서 진행되는것을 볼 수 있다.

  • 또한, s3 버켓에도 서버 zip 파일 외에 클라이언트 빌드 파일이 잘 올라간것을 확인 할 수 있다.

ref :
https://zzsza.github.io/development/2020/06/06/github-action/
https://www.daleseo.com/github-actions-basics/
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-services-s3-commands.html
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/sync.html
https://velog.io/@zero-black/github-actions-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0

profile
반갑습니다.

0개의 댓글